Agents¶
Auto-generated from source docstrings (mkdocstrings). The complete public contract is agentmaker.__all__ plus each subpackage __all__.
agentmaker.agents: Agent base + execution primitive + the strategies.
BaseAgent (base.py): the unified run / resume template (guardrails + persistence + HITL resume) plus the
three sub-agent delegation methods.
Single-loop Agent (agent.py): the one "model calls tools in a loop" execution primitive (native
function-calling); the spec menu's "chat" maps to it and "react" is its preset.
Orchestration recipes (workflows subpackage): PlanAgent / ReflectionAgent, strategies whose control
flow is in code, driving an internal Agent for each step's work.
Multi-agent orchestration (multi_agent subpackage): AgentTool, wrapping one Agent as a Tool
(orchestrator-worker).
Agent is the single-loop class (agent.py); to write a new strategy, inherit BaseAgent (base.py).
BaseAgent
¶
Shared base for all agents. Subclasses must implement at least one of _arun (async-native) or _run (synchronous).
__init__(name, llm, system_prompt=None, *, session_store=None, scope=None, checkpoint_store=None, input_guardrails=None, output_guardrails=None, hooks=None, run_policy=None, harness_config=None, prompts=None, on_pending='error', as_child=False)
¶
Store the agent's core dependencies and initialize conversation history (loading and resuming from session_store if one is attached).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Agent name, used for identification / debugging. |
required |
llm
|
LLMClient
|
LLM client the agent uses to call the model. |
required |
system_prompt
|
Optional[str]
|
System prompt defining the agent's persona and behavior; optional. |
None
|
session_store
|
Optional[SessionStore]
|
Optional session persistence store. When attached, history is persisted per scope and loaded per scope at each run to resume (the store is the single source of truth and supports cross-process access), so a long-running daemon does not lose conversations on restart. When absent, history is per-scope and in-process (lost on restart). |
None
|
scope
|
Optional[Scope]
|
The default scope the session belongs to (identifies session / user via retrieval.Scope); run / resume can override it per call, so one Agent instance can serve multiple sessions (history is isolated per scope). Defaults to an empty scope. |
None
|
checkpoint_store
|
Optional[CheckpointStore]
|
Optional execution-state checkpoint store (CheckpointStore,
agentmaker.runtime.execution). Attaching one enables execution-state persistence,
shared across three use cases: (1) HITL async approval (high-risk tools suspend, run
returns an Interrupt, resume(decision) continues); (2) crash recovery / (3) long-task
resume (a checkpoint is saved each step, resume() continues after a process restart).
Strategies that support resume implement |
None
|
input_guardrails
|
Optional[list[Guardrail]]
|
Optional list of input guardrails. Checked against user input before run; a tripped guardrail raises GuardrailTripwireError. |
None
|
output_guardrails
|
Optional[list[Guardrail]]
|
Optional list of output guardrails. Checked against the final output before persisting history; a trip raises (the blocked turn is not recorded). The rules are app business logic. |
None
|
hooks
|
Optional[list[Hook]]
|
Optional list of lifecycle hooks (Hook, agentmaker.runtime.hooks); observe-only. Run-level events (run start / end, guardrail, suspend, error, etc.) are fired by this base; model/tool-level events (calling the model / executing tools) are fired by each strategy's Harness. Zero overhead when none are attached. |
None
|
run_policy
|
Optional[RunPolicy]
|
Optional run governance (RunPolicy, agentmaker.runtime.execution). When attached, a single run is bounded by wall-time / LLM-call count / tool-call count / token limits plus cooperative cancellation (gated at each call site in the Harness); exceeding a limit / cancellation raises RunLimitExceeded / RunCancelled to abort the turn. Counted independently per run (resume is a new turn). Unbounded when absent. Warning: nested runs (delegated via AgentTool, or a Plan / Reflection sub-executor) inherit the outermost policy's global counters; a run_policy attached to a sub-agent does not take effect within the parent run (a warning is emitted). To bound sub-tasks, set the global limits on the parent Agent's run_policy. |
None
|
prompts
|
Optional prompt registry (PromptRegistry). If not passed, a copy of DEFAULT_PROMPTS is made at construction (isolated per instance, so update_prompts only affects this agent and its harness / sub-agents, without mutating the global registry / other agents). |
None
|
|
on_pending
|
str
|
Policy for running again when the same scope already has a pending-approval checkpoint (requires checkpoint_store): "error" (default) raises SessionError to prevent a new run silently overwriting the pending action (making the approval request vanish); "discard" drops the old pending action and continues the new run. |
'error'
|
as_child
|
bool
|
Set True when acting as an internal sub-agent of an orchestration strategy (Plan
/ Reflection, etc.). It declares two semantics at once:
(1) run-level hooks do not fire at the child layer (the parent strategy fires them
once, avoiding repetition on every sub-step); the passed hooks are still forwarded via
|
False
|
__init_subclass__(**kwargs)
¶
Definition-time check: a subclass (including multi-level inheritance) must override at least one of _run or _arun (resolved via MRO, so intermediate bases are unconstrained).
arun(input_text, *, scope=None, trace_carrier=None, **kwargs)
async
¶
Process one input and return a reply (template method: the run boundary shared by all strategies):
input guardrails -> strategy logic _arun -> output guardrails -> persist history.
Subclasses only implement _arun (pure generation); this method funnels the "run boundary"
cross-cutting concerns (guardrails and history persistence) so every strategy gets them for
free, mirroring the OpenAI Agents SDK where guardrails are declared on the agent and enforced
by a single execution layer (rather than reimplemented in each strategy). The return type
matches _arun (usually str; a validated model instance when output_schema is passed; an
Interrupt on HITL suspend, in which case history is not persisted, the state has already been
saved into the CheckpointStore by the strategy, awaiting resume).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_text
|
str
|
The user's raw input text. |
required |
scope
|
The session identifier for this call; defaults to self.scope. History is loaded / saved by it (one instance can serve multiple sessions). |
None
|
|
trace_carrier
|
Optional upstream W3C trace carrier (e.g. {"traceparent": request-header}). Useful only when an OTelExporter(carrier_provider=...) is attached, letting this run's spans join the app's cross-service trace. When absent, spans are attributed by the OTel current context (no regression). |
None
|
|
**kwargs
|
Passed through to |
{}
|
run(input_text, *, scope=None, trace_carrier=None, **kwargs)
¶
Synchronous facade over arun (driven by aio.run_sync). In environments with a running event loop (async / Jupyter / FastAPI), await arun instead.
aresume(decision=None, *, scope=None, trace_carrier=None, **kwargs)
async
¶
Resume an unfinished run from a checkpoint: reload the execution state -> (for HITL) inject the decision -> continue from the breakpoint.
Two kinds of resume share this entry:
- HITL: decision is a bool. Approve (True) executes the suspended high-risk action / reject
(False) skips it and feeds the result back so the model reroutes.
- Crash recovery / long-task resume: decision is omitted (None). No decision is injected;
it simply continues from the last checkpoint (a suspended high-risk action re-suspends and
returns an Interrupt awaiting approval again, rather than being mistaken for a rejection).
Funneled in the base: reload ExecutionState -> (as needed) inject the decision -> call the
strategy's _adrive to continue -> teardown (on completion: output guardrails + persist
history + clear checkpoint; on re-suspend: return a new Interrupt). Input guardrails are not
re-checked (the first run already checked them); it does not go through _scaffold, so resume
continues the run_id / step from before the suspend and does not re-fire on_run_start.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
decision
|
Optional[bool]
|
The HITL decision. A bool (True approve / False reject) decides all pending actions of this turn uniformly; a dict {call_id: bool} decides per call_id (used when one suspend has multiple pending actions, see Interrupt.pendings); None is a crash-recovery resume (no decision injected). |
None
|
scope
|
The session identifier; defaults to self.scope. |
None
|
|
trace_carrier
|
Optional upstream W3C trace carrier (the traceparent of this resume request); not persisted with the checkpoint, passed by the app on each resume. |
None
|
|
**kwargs
|
Passed through to the strategy's |
{}
|
Returns:
| Type | Description |
|---|---|
|
str (the final reply, and history persisted) or Interrupt (a high-risk action is still |
|
|
awaiting approval during resume, re-suspended). |
resume(decision=None, *, scope=None, trace_carrier=None, **kwargs)
¶
Synchronous facade over aresume (driven by aio.run_sync).
clear_checkpoint(scope=None)
async
¶
Explicitly clear a scope's checkpoint (ignoring the defer flag), and cascade-clear the internal sub-agents' derived child-scope checkpoints.
For a parent strategy to clean up sub-agent checkpoints after committing its own progress, and
for a user to manually clear a stuck suspended task: cascading ensures it does not clear only
the parent and leave child checkpoints orphaned (the next sub-agent arun / delegation hitting
_guard_pending permanently jams). A sub-agent without a checkpoint_store is a no-op each.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
scope
|
The session identifier to clear; defaults to self.scope. |
None
|
add_message(message, scope=None)
async
¶
Append one message to the conversation history by scope (a single-message convenience over add_messages).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message
|
Message
|
The message to append. |
required |
scope
|
The session identifier; defaults to self.scope. |
None
|
add_messages(messages, scope=None)
async
¶
Append multiple messages to the conversation history by scope atomically; with a session_store it goes through its aappend_many (single transaction, avoiding a half-turn), otherwise the in-process dict[scope] is extended once. This is the single funnel point for session persistence (the async real body, using a* so as not to block the event loop).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
messages
|
list[Message]
|
The list of messages to append. |
required |
scope
|
The session identifier; defaults to self.scope. |
None
|
clear_history(scope=None)
¶
Clear a scope's conversation history; with a session_store, clear its persisted record, otherwise clear the in-process dict[scope].
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
scope
|
The session identifier; defaults to self.scope. |
None
|
get_history(scope=None)
¶
Return a deep copy of a scope's conversation history, so external mutations (including changing a Message's content / metadata) do not affect internal state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
scope
|
The session identifier; defaults to self.scope. |
None
|
Returns:
| Type | Description |
|---|---|
list[Message]
|
list[Message]: A deep copy of the history message list (Message is a mutable dataclass, so |
list[Message]
|
a shallow copy would not prevent field mutation). |
The synchronous public facade (funneling to the async real body _history_for via run_sync): in
environments with a running event loop (async / Jupyter / FastAPI), use
await agent._history_for(scope) instead (same limitation as the run/resume synchronous facades).
get_prompts()
¶
List all built-in prompts this agent currently uses, as {key: text} (from the shared self.prompts).
For inspection / export: first see which prompts the framework builds in, what their keys are called, and what they look like, then decide which to override (see agentmaker/doc/prompts.md).
update_prompts(updates)
¶
Override built-in prompts: updates may be {key: new-text} (per key) or another PromptRegistry (a whole swap, e.g. changing language).
Modifies self.prompts in place: this agent's harness and internal sub-agents share the same
copy, so one change takes effect across the whole chain. Each override is validated to ensure
"the placeholders + protocol tokens are still present", raising PromptError if any is missing.
It is isolated per instance by default (a copy of DEFAULT_PROMPTS is made at construction when
prompts= is not passed), so this method only changes this agent's chain and does not affect
other agents / independently constructed tools / the process-wide global. To change language /
wording process-wide, explicitly call DEFAULT_PROMPTS.override(pack) before creating any component.
Boundaries: (1) an already-created tool's overall description is a construction-time snapshot and does not change with this override (the parameter descriptions do change live), so changing language / tool-related prompts should be done before creating tools (use packs' chinese_registry(), or override first then build tools), otherwise the same tool's schema shows a half-mixed state of "overall intro in the old language, parameter descriptions in the new". (2) After the default isolation, a tool constructed separately (not passed the same prompts) has its wording determined by the tool's own prompts and does not change with this agent's update_prompts: to keep the tool and agent in sync, pass the same PromptRegistry to both, or use a global override.
__str__()
¶
Let print(agent) show "Agent(name, provider)" for debugging.
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
Of the form "Agent(name=assistant, provider=deepseek)". |
Agent
¶
Bases: BaseAgent
Single-loop Agent: one input -> model-tool loop -> reply; with no tools it is plain question-answering. Automatically maintains multi-turn history per scope.
__init__(name, llm, system_prompt=None, *, tools=None, tool_registry=None, max_turns=10, compactor=None, confirm=None, permissions=None, reducer=None, tool_retriever=None, context_builder=None, sources=None, window_budget=None, token_counter=count_tokens, tracer=None, hooks=None, run_policy=None, session_store=None, scope=None, checkpoint_store=None, input_guardrails=None, output_guardrails=None, prompts=None, on_pending='error', as_child=False)
¶
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Agent name. |
required |
llm
|
LLMClient
|
LLM client. |
required |
system_prompt
|
Optional[str]
|
System prompt defining the persona; optional (if omitted, no system message is sent). |
None
|
tools
|
Convenience entry point: a list[Tool] (including @tool-decorated function objects) or a ToolRegistry, normalized into a registry internally via ToolRegistry.from_tools. Use it for a one-line start in simple cases; mutually exclusive with tool_registry (passing both raises ValueError). |
None
|
|
tool_registry
|
Optional[ToolRegistry]
|
Tool registry (advanced case: reuse the same registry or customize prompts). Passing it enables the tool loop; omitting it means plain question-answering. |
None
|
max_turns
|
int
|
The maximum number of model turns in the loop, to prevent repeated calls from spinning into an infinite loop (must be a positive integer, default 10, since tool tasks often need multiple turns). |
10
|
compactor
|
Optional[HistoryCompactor]
|
Optional history compactor (HistoryCompactor); once attached, cross-turn session history is automatically summarized and compacted when it exceeds a threshold. |
None
|
confirm
|
Optional[ConfirmCallback]
|
Confirmation callback for high-risk tools (tool, params) -> bool; if omitted, it safely refuses (returns a readable error fed back to the model, without blocking on stdin). In CLI / teaching scenarios pass agentmaker.runtime.cli_confirm explicitly for command-line y/n; in server scenarios configure HITL (checkpoint_store). |
None
|
permissions
|
Optional tool permissions (ToolPermissions, allow/deny lists); denied tools are rejected directly at the execution gate. |
None
|
|
reducer
|
Optional[ReducerConfig]
|
Optional trajectory-trimming knob (ReducerConfig); when this turn's tool trajectory overflows the window, keep recent units and summarize the earlier ones. |
None
|
tool_retriever
|
Optional[ToolRetriever]
|
Optional Tool-RAG (ToolRetriever); selects only the relevant subset of tools for this turn's input (saves tokens when there are many tools). |
None
|
context_builder + sources
|
Optional memory/RAG injection; each turn retrieves by input and assembles a guardrailed system block for injection. |
required | |
window_budget
|
Optional window-budgeting knob (WindowBudgetConfig); unifies budgeting across retrieval blocks, trajectory, and output reservation. |
None
|
|
token_counter
|
TokenCounter
|
Pluggable token counter (default count_tokens); the harness uses it to estimate tool overhead and to trim trajectories. For consistent accounting throughout, pass the same token_counter to your ContextBuilder / HistoryCompactor as well (the Agent does not silently override the counters they already carry). |
count_tokens
|
session_store / scope
|
Session persistence (see BaseAgent); once attached, history is resumed per scope and persisted automatically. |
required | |
checkpoint_store
|
Optional checkpoint store; once attached, enables HITL suspend/resume plus crash recovery (saved at every step). |
None
|
|
input_guardrails / output_guardrails / hooks / run_policy / prompts / on_pending
|
see BaseAgent. |
required | |
as_child
|
bool
|
Set True when acting as an orchestration recipe's internal sub-agent (see BaseAgent: run-level hooks do not fire and checkpoint cleanup is left to the parent). |
False
|
astream_run(input_text, *, scope=None, buffer_output=False, trace_carrier=None, **kwargs)
async
¶
Streaming question-answering (the real async implementation): yields reply text piece by piece.
Shares the base _scaffold (run context with scope + run-level hooks + exception routing). The
output-side duties run inside the generator body only after the stream drains naturally: output
guardrails -> one atomic history save -> on_run_end. If the consumer breaks early (break / aclose),
none of the three happen (GeneratorExit is a BaseException and does not reach on_error), but the
harness-level finally accounting always runs.
Tool loop: when the agent has registered tools, this runs the same model-tool loop as arun but with every model turn streamed -- text deltas are yielded as they arrive (including text preceding a tool call, matching common chat UIs), tools execute between turns (before_tool/after_tool hooks fire as usual), and the final no-tool-call turn's text is the answer. Unlike arun, the streaming loop does NOT support HITL suspend/resume or checkpoints: a tool that requires confirmation uses its synchronous confirm (ApprovalRequired propagates as an error in persistent setups) -- use arun when you need suspend semantics. History save matches arun: one atomic user + final-assistant turn (tool trajectories are not persisted to session history).
Output guardrail vs. streaming trade-off (buffer_output):
- Default buffer_output=False: yield as it generates, check the guardrail on the final answer only
after the stream drains. Content already emitted cannot be recalled (a tripped guardrail can only
raise after the fact, it cannot stop text that already reached the consumer).
- buffer_output=True: accumulate the full output first, run the output guardrail, and only after it
passes release it piece by piece. With a tool loop this buffers ALL streamed text across turns and
releases it only after the final answer passes the guardrail (tools still execute live in between).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_text
|
str
|
User input (str, or a multimodal content-part list). |
required |
scope
|
This session's identifier; defaults to self.scope. |
None
|
|
buffer_output
|
bool
|
See above; default False (immediate streaming, guardrail checked after the fact). |
False
|
trace_carrier
|
Optional upstream W3C trace carrier (see the same-named arg on arun); only useful when an OTelExporter(carrier_provider=...) is attached. |
None
|
|
**kwargs
|
Passed through to the LLM streaming interface. |
{}
|
stream_run(input_text, *, scope=None, **kwargs)
¶
Synchronous facade for astream_run (pumped via aio.iter_sync): returns a sync generator that yields piece by piece. Drain it explicitly or close it (e.g. contextlib.closing); in an async environment use astream_run instead.
RunResult
dataclass
¶
Unified return envelope for run / arun / resume / aresume: bundles final output + whether a human-approval interrupt occurred + usage + new messages this turn into one object (rather than returning a bare string), turning a suspension from a silent accident into an explicitly checkable state.
Consumption template
r = agent.run("...") if r.interrupted: handle(r.interrupt) # HITL: take the suspended state to resume else: use(r.final_output) # completed: take the final output (str or structured instance)
Attributes:
| Name | Type | Description |
|---|---|---|
final_output |
Any
|
the completed state's final output (str, or a structured instance when output_schema was passed); None when suspended. |
status |
RunStatus
|
"completed" or "interrupted". |
interrupt |
Optional[Interrupt]
|
the suspended state's Interrupt (the pending action + the resume scope); None when completed. |
usage |
RunUsage
|
usage snapshot of this run (RunUsage). |
new_messages |
tuple[Message, ...]
|
messages newly added and stored in history this turn (user + assistant); empty when suspended. |
run_id |
Optional[str]
|
this run's trace correlation id. |
interrupted
property
¶
Whether this is a HITL suspended state (status == "interrupted").
__str__()
¶
Let print(result) / f"{result}" show the final output text directly (eases migration: old code that used it as a string still gets the answer); a suspended state shows a readable note rather than a bare None.
RunUsage
dataclass
¶
Usage snapshot of a single run (for cost accounting / limit observability).
Attributes:
| Name | Type | Description |
|---|---|---|
llm_calls |
int
|
total LLM calls accumulated over this run. |
tool_calls |
int
|
tool calls actually executed during this run. |
total_tokens |
int
|
total tokens accumulated over this run (sum of usage.total_tokens across each LLM response). |
PlanAgent
¶
Bases: BaseAgent
Plan-and-Solve orchestration recipe: plan (structured step breakdown) -> delegate step-by-step execution to an internal Agent -> synthesize the answer.
__init__(name, llm, system_prompt=None, *, tool_registry=None, max_turns=3, confirm=None, tracer=None, permissions=None, hooks=None, run_policy=None, session_store=None, scope=None, checkpoint_store=None, input_guardrails=None, output_guardrails=None, tool_retriever=None, context_builder=None, sources=None, reducer=None, window_budget=None, token_counter=count_tokens, prompts=None)
¶
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
system_prompt
|
Optional[str]
|
Optional extra persona for the planning stage (third positional arg, aligned with Agent / ReflectionAgent). |
None
|
tool_registry
|
Optional[ToolRegistry]
|
If passed, every execution step can call tools; without it, execution is pure reasoning (keyword-only). |
None
|
max_turns
|
int
|
Upper bound on the tool-loop turns for each sub-step executor (the internal single-loop Agent), default 3 (not the number of plan steps). |
3
|
tool_retriever / context_builder / sources
|
Context engineering, passed through to each step's executor; the Plan's own planning and synthesis calls also inject a memory/RAG block. |
required | |
confirm / permissions / checkpoint_store
|
Passed through to the executor; with a checkpoint_store attached, high-risk tools during a step suspend/resume via HITL (the Plan main loop catches and propagates the Interrupt upward). |
required | |
reducer / window_budget
|
Window-governance knobs, given to Plan's own Harness (when history overflows the window it is trimmed against the window budget) and also passed through to each step's executor (whose tool-trajectory trimming is likewise bound by these two knobs). |
required |
ReflectionAgent
¶
Bases: BaseAgent
Reflection orchestration recipe: draft -> (reflect -> refine) xN, until the critique signals "best reached" or max_turns is hit. Optionally verifies with tools in the critique step.
__init__(name, llm, system_prompt=None, *, max_turns=3, tracer=None, hooks=None, run_policy=None, session_store=None, scope=None, input_guardrails=None, output_guardrails=None, tool_registry=None, confirm=None, permissions=None, checkpoint_store=None, tool_retriever=None, context_builder=None, sources=None, reducer=None, window_budget=None, token_counter=count_tokens, prompts=None)
¶
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
max_turns
|
int
|
Maximum number of "reflect-refine" rounds (must be a positive integer; the same name across Agent / PlanAgent / AgentSpec denotes the loop cap). |
3
|
tool_registry
|
Optional[ToolRegistry]
|
Optional tool table; if passed, the critique step can call tools to verify facts / arithmetic. Without it, critique is pure self-reflection. |
None
|
confirm / permissions / checkpoint_store
|
Passed through to the critique-executor; with a checkpoint_store attached, critique's high-risk tools suspend/resume via HITL (the Reflection main loop propagates the Interrupt upward). |
required | |
tool_retriever
|
Passed through to the critique-executor (selects a relevant subset when critique has many tools). |
None
|
|
context_builder + sources
|
memory/RAG injection; splices the retrieval block into the prompt in the draft / refine steps (the generation step benefits most). |
required | |
reducer / window_budget
|
Window-governance knobs, given to Reflection's own Harness (when the reflection trajectory overflows the window it is trimmed against the window budget, keeping the latest answer plus the critique's key points) and also passed through to the critique-executor (whose verification trajectory is likewise bound). |
required |
AgentSpec
dataclass
¶
Declaratively aggregates every configurable point of an agent; strategy picks the paradigm, build_agent constructs from it.
The fields are a superset across strategies: common fields (including the memory/RAG injection
context_builder+sources and the Tool-RAG tool_retriever) apply to the relevant strategies,
while strategy-specific fields (compactor is chat-only, the single-loop Agent) only take effect
on strategies that support them. Setting one on an unsupported strategy is rejected by
build_agent (fail loud).
AgentTool
¶
Bases: Tool
Adapt an agent into a Tool: the main agent calls it to delegate one subtask and gets the result back (the main agent keeps control).
__init__(agent, *, name=None, description=None, scope=None, prompts=None)
¶
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agent
|
BaseAgent
|
The wrapped sub-agent (any strategy). |
required |
name
|
Optional[str]
|
Tool name, defaults to agent.name; set it explicitly to disambiguate sub-agents that share a name. |
None
|
description
|
Optional[str]
|
Tool description telling the orchestrating LLM what this sub-agent is good at and when to delegate to it; defaults to a value generated from agent.name. |
None
|
scope
|
Optional[Scope]
|
The session ownership used when delegating to the sub-agent (advanced override: pin the sub-agent to a fixed scope). Defaults to None, in which case the parent agent's current run scope is picked up automatically (propagated through the run context, see _effective_scope), so that even when "one AgentTool instance serves multiple parent sessions" the sub-agent's history / memory stays isolated per parent session and never bleeds across them; if the parent has no run context (rare, calling the tool bare) it falls back to the sub-agent's own default scope. Pass this explicitly only when you genuinely need to pin the sub-agent to a specific scope. |
None
|
get_parameters()
¶
Declare parameters: a single task string (the self-contained subtask handed to the sub-agent).
run(parameters)
¶
Synchronous delegation: hand the task to the sub-agent, run it, and return its reply (normalized into a ToolResponse via _textualize).
arun(parameters)
async
¶
Native async delegation: await the sub-agent's arun (a truly async strategy runs async, otherwise its arun auto-dispatches to a thread pool).
build_agent(spec)
¶
Construct the matching strategy agent based on spec.strategy.
str -> "provider:model" (e.g. "deepseek:deepseek-v4-flash", split into
LLMClient(provider, model=right_half)); a bare provider name (no colon, e.g. "deepseek")
is still treated as a provider (using the .env key + the provider's default model); an
LLMClient instance -> used directly (lets you pin model / key / base_url); None ->
LLMClient() default.
tools: list[Tool] -> build a new ToolRegistry and register them / ToolRegistry -> used as-is
/ None -> no tools.
A field unsupported by the strategy that is set to a non-default value raises ValueError
(avoids the silent "set but had no effect" trap).
Returns:
| Name | Type | Description |
|---|---|---|
BaseAgent |
BaseAgent
|
the constructed strategy instance (single-loop Agent (chat/react) / ReflectionAgent / PlanAgent). |