State¶
Concepts: State.
State
¶
State(task: str)
One run's record: everything that happened (history) and what the model sees next (context).
Pass a State to agent.run to keep it after the run, or to continue it after Ctrl+C. Every method is
thread-safe, so tools may call them from worker threads.
Example
state = State("Find the bug in this repo")
agent.run(state)
print(state.answer, state.stopped_by, state.usage.cost)
Start a run with one user message.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
task
|
str
|
What the agent should do. The first user message the model sees. |
required |
Raises:
| Type | Description |
|---|---|
TypeError
|
|
ValueError
|
|
answer
property
¶
answer: Any
The run's answer.
The value given to finish(answer) if there is one, otherwise the text of the latest model reply
without tool calls, otherwise None. A think that fails does not change it.
turn
property
¶
turn: int
Number of turns so far: each think adds 1, and a think that fails does not count.
usage
property
¶
usage: Usage
Total tokens, requests and cost of every think, ask and compact on this State.
pending_calls
property
¶
pending_calls: tuple[ToolCall, ...]
Tool calls the model requested this turn that have no result yet, in request order.
A call leaves this tuple when it gets a result, is denied with deny, or is closed by an exception.
context_tokens
property
¶
context_tokens: int
Estimated token count of the context, including the system prompt and tool definitions.
context_used
property
¶
context_used: float
Fraction of the model's context window in use: context_tokens / context_window.
0.0 before the first run or think (the window size is unknown until then). Can go above 1.0.
stopped_by
property
¶
stopped_by: str | None
Why the last loop stopped: "finish", "limit", or the name of the until function that returned
true (e.g. "is_answered"). None while running, or if the run ended with an exception.
stopped_limit
property
¶
stopped_limit: int | None
The limit the loop reached if stopped_by == "limit", otherwise None.
history
property
¶
history: tuple[HistoryEntry, ...]
Everything that happened in this run, oldest first: messages, replies, tool results, errors and context changes. Entries are only ever added, so shrinking the context never removes anything from here.
Returns a copy.
context
property
¶
context: tuple[Message, ...]
The messages the model will see at the next think. Returns a copy.
Results of this turn's tool calls go in together once the last call has a result. Messages added in the
meantime, or while think waits on the model, go in after them.
data
property
¶
data: dict[str, Any]
A dict for your own data. The model never sees it.
Single reads and writes (d[k], d[k] = v, get, setdefault, pop) are thread-safe. For
an update that takes several steps, or to loop over it, hold state.lock.
Example
with state.lock:
state.data["calls"] = state.data.get("calls", 0) + 1
lock
property
¶
lock: RLock
The reentrant lock (threading.RLock) every State method uses. Hold it to make several changes as one.
is_answered
¶
is_answered() -> bool
Whether the model's last reply is a final answer.
True when the last message in the context is a model reply without tool calls. A message added after it (a notice, a user message) makes it false, and so do pending calls.
Use it as a stop condition: @loop(until=State.is_answered, limit=50).
wants_tools
¶
wants_tools() -> bool
Whether the model requested tool calls that have not run yet (pending_calls is not empty).
is_finished
¶
is_finished() -> bool
Whether finish() was called. A finished State stops its loop before the next turn.
add_user_message
¶
add_user_message(text: str) -> None
Add a message from the human, for example the next request in a chat loop.
While tool calls are pending, or while think waits on the model, the message is held and goes into
the context right after the results or the reply. is_answered() is false until the model answers it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
The message. |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
|
add_notice
¶
add_notice(text: str) -> None
Tell the model something from your loop or a tool, for example "The tests failed".
The model sees it as a user message starting with "[notice] " (added if missing). It is held while
calls are pending, like add_user_message.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
The notice. |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
|
finish
¶
finish(answer: Any = None) -> None
End the run. The loop stops before its next turn with stopped_by == "finish".
Tools may call it (a submit tool, for example), even while other calls are pending. Calling it again
is allowed; the last answer given wins.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
answer
|
Any
|
If not |
None
|
deny
¶
deny(call: ToolCall, reason: str) -> None
Refuse a pending tool call. The model gets reason as that call's error result.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
call
|
ToolCall
|
One of |
required |
reason
|
str
|
What the model is told, for example |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
|
Example
for call in state.pending_calls:
if call.name == "delete_file":
state.deny(call, "Deleting files is not allowed")
agent.use_tools(state)
start_from
¶
start_from(summary: str) -> None
Replace the context with two messages: the original task and summary. History is kept.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
summary
|
str
|
What the model should know about the work so far. |
required |
Raises:
| Type | Description |
|---|---|
TypeError
|
|
ValueError
|
Tool calls are pending, or |
clear_tool_results
¶
clear_tool_results(keep_last: int = 5) -> None
Shrink the context by blanking old tool results. History keeps the full results.
Every tool result except the last keep_last is replaced with "(cleared: kept in history)".
Results that are already cleared still count toward keep_last.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
keep_last
|
int
|
How many of the most recent tool results to keep. |
5
|
Raises:
| Type | Description |
|---|---|
ValueError
|
Tool calls are pending, or |