| name | agent-builder |
| description | Build and configure AI agents with ya-agent-sdk and Pydantic AI. Covers capability-first create_agent(), stream_agent(), AgentSpec, AgentContext, ResumableState, portable subagents, environments, native steering, and deferred HITL. Use when implementing agent applications, composing capabilities, restoring sessions, configuring child-agent plans, adding approval flows, or working with ya-agent-sdk runtime APIs. |
Building Agents with ya-agent-sdk
Build agents with the 2.0 capability-first runtime. Pydantic AI capabilities are the
only public behavior-composition surface. Do not pass SDK tools= or toolsets= to
create_agent(), slice toolsets for children, or use removed MessageBus/generated
subagent APIs.
Start Here
- Construct an unentered runtime with
create_agent().
- Put every agent behavior in the ordered
capabilities= list.
- Validate durable static specs with
validate_agent_spec_capabilities() before
fingerprinting or persistence; runtime entry still validates dynamic contributions.
- Enter
AgentRuntime before accessing runtime.agent or resolved capabilities.
- Use
stream_agent() for SDK lifecycle events, native steering, and recovery.
- Persist both Pydantic AI message history and
runtime.ctx.export_state().
- Use native
AgentSpec for declarative agent fields.
- Use
SubagentSpec, SubagentPlanResolver, SubagentRegistry, and
SubagentExecutionService for delegation.
- Use
DeferredInteractionResolver for approvals and external deferred calls.
Read the focused references before changing the corresponding subsystem:
Installation
pip install 'ya-agent-sdk[all]'
uv add 'ya-agent-sdk[all]'
Use selective extras such as docker, web, document, s3, tool-proxy,
oauth, or rs when a smaller installation is needed.
Core Workflows
Create and enter a runtime
from ya_agent_sdk.agents.main import create_agent
from ya_agent_sdk.capabilities import RuntimeFoundationCapability
runtime = create_agent(
"anthropic:claude-sonnet-4",
capabilities=[RuntimeFoundationCapability()],
)
async with runtime:
result = await runtime.agent.run("Summarize this project", deps=runtime.ctx)
print(result.output)
create_agent() returns an unentered AgentRuntime. Runtime entry first enters the
Environment and context, collects their contribution groups, validates capability
ordering and singleton constraints, and then constructs the Pydantic AI Agent.
Compose SDK features
from ya_agent_sdk.agents.main import create_agent
from ya_agent_sdk.capabilities import (
FilesystemCapability,
RuntimeFoundationCapability,
ShellCapability,
ToolApprovalCapability,
ToolObservationCapability,
ToolSupersessionCapability,
ToolTimeoutCapability,
ToolVisibilityCapability,
)
runtime = create_agent(
"anthropic:claude-sonnet-4",
capabilities=[
RuntimeFoundationCapability(),
FilesystemCapability(),
ShellCapability(),
ToolSupersessionCapability(),
ToolVisibilityCapability(),
ToolApprovalCapability(tools=frozenset({"shell_exec"})),
ToolObservationCapability(),
ToolTimeoutCapability(),
],
)
Capabilities own tools, instructions, request/history hooks, and run-local state as one
coherent feature. RuntimeFoundationCapability is explicit; create_agent() does not
inject it.
Stream responses
from ya_agent_sdk.agents.main import create_agent, stream_agent
from ya_agent_sdk.capabilities import RuntimeFoundationCapability
runtime = create_agent(
"openai-chat:gpt-4o",
capabilities=[RuntimeFoundationCapability()],
)
async with stream_agent(runtime, "Hello") as streamer:
async for event in streamer:
print(event)
streamer.raise_if_exception()
Use the SDK stream driver instead of manually advancing Pydantic AI graph nodes when
you need SDK lifecycle events, logical-run input routing, usage snapshots, or recovery.
Persist and restore sessions
from ya_agent_sdk.agents.main import create_agent
async with create_agent("openai-chat:gpt-4o") as runtime:
result = await runtime.agent.run("Remember this", deps=runtime.ctx)
messages = result.all_messages()
state = runtime.ctx.export_state()
restored = create_agent("openai-chat:gpt-4o", state=state)
ResumableState stores SDK context state, not canonical Pydantic AI message history.
Hosts persist both.
Add deferred host interaction
from pydantic_ai import DeferredToolRequests
from ya_agent_sdk.agents.main import create_agent
from ya_agent_sdk.capabilities import (
RuntimeFoundationCapability,
ToolApprovalCapability,
UserInteractionCapability,
)
runtime = create_agent(
"anthropic:claude-sonnet-4",
capabilities=[
RuntimeFoundationCapability(),
UserInteractionCapability(),
ToolApprovalCapability(tools=frozenset({"shell_exec"})),
],
output_type=[str, DeferredToolRequests],
)
The host must present every deferred request and resume with matching
DeferredToolResults. Use the typed DeferredInteractionResolver; do not inspect a
runtime-private toolset.
Add portable subagents
Define each child with native AgentSpec inside the thin YA SubagentSpec envelope,
resolve it against one immutable capability catalog, register the resulting plan, and
inject one DelegationCapability backed by a store and driver. See
./subagent.md for a complete example and durability boundaries.
Public Boundary Checklist
capabilities= is the sole public composition plane.
- Plugin entry points only add explicitly selected types to one immutable catalog;
they never grant behavior or load ambiently.
- A plugin manifest may append root grants, but named children and self forks receive
only their own explicit native grants.
AgentSpec owns model, settings, instructions, output schema, and serialized
capability definitions.
SubagentSpec adds only delegation policy.
- Named children receive only capabilities declared in their own native spec.
- Self forks rebuild an explicit policy and bounded history snapshot; they never clone
live parent capabilities.
ToolVisibilityCapability is the final child execution-boundary defense.
- Steering uses Pydantic AI
AgentRun.enqueue() through LogicalRunInputRouter.
- Durable hosts persist input before acknowledgement and keep canonical delivery in
their inbox/store. SDK lifecycle events and UI projections are notifications only.
- There is no MessageBus, generated delegate class, implicit tool inheritance, or
runtime compatibility layer in 2.0.
Reference Routing
| Topic | Local path | Read when |
|---|
| Context and sessions | ./context.md | Persisting context, history, or custom context fields |
| Streaming and hooks | ./streaming.md | Streamed UX, recovery, or lifecycle extensions |
| Events | ./events.md | Consuming SDK or feature lifecycle events |
| Tools and policies | ./toolset.md | Writing BaseTool adapters or execution-policy capabilities |
| Capability plugins | ./plugins.md | Packaging plugins or adding file-based loading to a host |
| Structured input | ./user-input.md | Approval or external deferred continuation |
| Native Tool Search | ./tool-search.md | Deferred native capabilities and large tool libraries |
| Subagents | ./subagent.md | Child specs, resolution, services, stores, or drivers |
| Environment | ./environment.md | Filesystem, shell, resources, and lifecycle authority |
| Resumable resources | ./resumable-resources.md | Reconstructing long-lived external resources |
| Skills | ./skills.md |
Runnable Examples
The paths below point to repository sources. Installed and bundled skill artifacts carry
the same files under ./examples/.
../../examples/general.py: capability composition, streaming, typed HITL,
persistence, named delegation, and self fork.
../../examples/deepresearch.py: autonomous capability-first research agent with
structured output.
../../examples/capability_plugin/: installable custom capability package with
metadata-only discovery, explicit catalog selection, AgentSpec reconstruction, and
a credential-free smoke run.
After editing this canonical skill, run scripts/sync-skills.sh to update YAACLI's
bundled copy.