Agent¶
Concepts: Agent.
Agent
¶
Agent(model: str | Model, *, system: str | None = None, tools: Iterable[Any] = (), skills: Iterable[str] = (), loop: Any = None, reporter: Reporter | None = DEFAULT, human: Human | None = DEFAULT, name: str | None = None, description: str | None = None)
An agent's settings, and the actions that need a model, tools or a human.
Settings do not change after creation. Use copy to get an Agent with different settings.
The history of a run lives in a State, and the order of steps is decided by the loop.
Example
agent = Agent(model="claude-sonnet-5", system="You are a coding assistant", tools=[read_file])
answer = agent.run("Find the bug in main.py")
Creates an Agent. Mistakes in the settings are reported here, with how to fix them.
Creating an Agent uses no network and needs no API key.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
str | Model
|
A model name such as |
required |
system
|
str | None
|
The system prompt. |
None
|
tools
|
Iterable[Any]
|
|
()
|
skills
|
Iterable[str]
|
Not implemented yet. A non-empty value raises |
()
|
loop
|
Any
|
The loop |
None
|
reporter
|
Reporter | None
|
Receives progress notifications. Defaults to the shared |
DEFAULT
|
human
|
Human | None
|
Answers |
DEFAULT
|
name
|
str | None
|
The Agent's name. |
None
|
description
|
str | None
|
What the Agent does. |
None
|
Raises:
| Type | Description |
|---|---|
TypeError
|
A setting has the wrong type, for example a function without |
ValueError
|
Two tools share a name, or the model string is ambiguous. |
model
property
¶
model: Model
The Model object. A model string given to Agent(model=...) is already turned into one.
reporter
property
¶
reporter: Reporter | None
The Reporter that receives progress notifications, or None. Defaults to the shared Terminal.
human
property
¶
human: Human | None
The Human that answers ask_human, or None. Defaults to the shared Terminal.
run
¶
run(task: str | State) -> Any
Runs the loop on a task and returns what the loop returns, usually the answer.
MCP servers in tools= connect for the run and disconnect after it, unless with agent: keeps
them open. If an exception leaves the run, it is recorded in state.history, tool calls still
waiting for a result are closed ((interrupted by user) after Ctrl+C), and the exception is
raised as is. After Ctrl+C you can call run again with the same State.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
task
|
str | State
|
A task string, which starts a new |
required |
Returns:
| Type | Description |
|---|---|
Any
|
What the loop returns. The default loop returns |
Raises:
| Type | Description |
|---|---|
TypeError
|
The loop is async (use |
ValueError
|
The State was already ended with |
Example
state = State("Find the bug in this repo")
answer = agent.run(state)
print(state.stopped_by, state.usage.cost)
arun
async
¶
arun(task: str | State) -> Any
The async version of run.
Uses this Agent's loop if it is async, or adefault_loop if the Agent uses the default loop.
Cancelling the task follows the same rules as Ctrl+C in run.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
task
|
str | State
|
A task string, which starts a new |
required |
Returns:
| Type | Description |
|---|---|
Any
|
What the loop returns. The default loop returns |
Raises:
| Type | Description |
|---|---|
TypeError
|
The loop is a sync loop other than |
ValueError
|
The State was already ended with |
think
¶
think(state: State, tools: Iterable[Any] | None = None) -> None
Sends the context to the model once and records its reply in the State.
The reply may ask for tool calls. Check state.wants_tools() and run them with use_tools.
If anything fails, the context goes back to how it was before this call, and the error is raised.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
State
|
The State to continue. The first Agent that thinks on a State owns it. |
required |
tools
|
Iterable[Any] | None
|
Which of this Agent's tools the model may see this turn. |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
The State is finished, still has tool calls waiting for results, belongs to another
Agent, or |
ProviderError
|
The model provider failed ( |
athink
async
¶
athink(state: State, tools: Iterable[Any] | None = None) -> None
The async version of think. Cancelling it rolls the context back like any other failure.
use_tools
¶
use_tools(state: State) -> None
Runs the tool calls from the last reply and records their results in the State.
Calls to tools made with parallel=True (the default) run at the same time, then the rest run one
by one. Does nothing if there are no calls. A tool that raises does not become an error result:
results of the calls that finished are recorded, and the exception is raised as is. Invalid arguments
and unknown tool names go back to the model as (input error: ...) results.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
State
|
The State whose |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
The State is finished or belongs to another Agent. |
ause_tools
async
¶
ause_tools(state: State) -> None
The async version of use_tools.
async def tools run as tasks on the running event loop, other tools on worker threads.
Cancelling it follows the same rules as Ctrl+C.
ask
¶
ask(state: State, prompt: str, returns: Any = str, *, retries: int = 2) -> Any
Asks the model a question about the current context and returns the answer in the returns format.
The question and answer are recorded in state.history but do not enter the context, so the run
continues as if the question was never asked. The model cannot call tools while answering. Any Agent
can ask about a State, not only the one running it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
State
|
The State whose context the model reads. |
required |
prompt
|
str
|
The question. |
required |
returns
|
Any
|
The answer format: |
str
|
retries
|
int
|
How many more times to ask when the answer does not fit |
2
|
Returns:
| Type | Description |
|---|---|
Any
|
The answer, converted to |
Raises:
| Type | Description |
|---|---|
TypeError
|
|
ValueError
|
The State is finished. |
OutputError
|
The answer still did not fit |
ProviderError
|
The model provider failed. |
Example
@dataclass
class Review:
approved: bool
reason: str
review = agent.ask(state, "Is this change safe to merge?", returns=Review)
aask
async
¶
aask(state: State, prompt: str, returns: Any = str, *, retries: int = 2) -> Any
The async version of ask.
ask_human
¶
ask_human(state: State, prompt: str, returns: Any = str) -> Any
Asks the person through human and returns the answer in the returns format.
The question and answer are recorded in state.history. The context does not change.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
State
|
The State of the current run. |
required |
prompt
|
str
|
The question. |
required |
returns
|
Any
|
The answer format: |
str
|
Returns:
| Type | Description |
|---|---|
Any
|
The answer, converted to |
Raises:
| Type | Description |
|---|---|
NoHumanError
|
The Agent was created with |
TypeError
|
|
Example
choice = agent.ask_human(state, "Run the command?", returns=Literal["yes", "no", "always"])
aask_human
async
¶
aask_human(state: State, prompt: str, returns: Any = str) -> Any
The async version of ask_human.
Awaits human.aask when the Human has it, and otherwise runs human.ask on a worker thread.
compact
¶
compact(state: State, instructions: str | None = None) -> None
Asks the model to summarize the context, then replaces the context with the task and that summary.
state.history keeps everything. If anything fails, the context is left unchanged.
In a loop, compact_if_full calls this only when the context is getting full.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
State
|
The State to compact. |
required |
instructions
|
str | None
|
What the summary should keep, for example |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
The State still has tool calls waiting for results, or belongs to another Agent. |
OutputError
|
The model returned an empty summary. |
ProviderError
|
The model provider failed. |
acompact
async
¶
acompact(state: State, instructions: str | None = None) -> None
The async version of compact.
copy
¶
copy(**changes: Any) -> Agent
Returns a new Agent with some settings changed. The original Agent does not change.
The new Agent goes through the same checks as Agent(...).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
**changes
|
Any
|
Settings to change, by the same names as the |
{}
|
Returns:
| Type | Description |
|---|---|
Agent
|
The new Agent. |
Raises:
| Type | Description |
|---|---|
TypeError
|
A name in |
Example
quiet = agent.copy(model=FakeModel(["Done"]), reporter=None)