Agent & Session¶
The main user-facing API. See Concepts for the mental model and Sessions for usage.
Agent¶
Agent
¶
Agent(provider: str | list[str] | None = None, data_dir: str | None = None, system_prompt: str | None = None, model: str | ModelTier | None = None, reasoning: str | None = None, tools: ToolGroup | None = None, tool_servers: list[Any] | None = None, stateless_tools: list[Any] | None = None, name: str = '', description: str = '', logger: AgentLogger | None = None, **kwargs: Any)
Coding agent wrapper — unified interface across providers.
The provider argument may be:
- a single name (e.g.
"claude") — pinned to that provider; - a list (e.g.
["claude", "codex", "opencode"]) — a fallback order; "auto"(or omitted) — use the global order fromcaw.set_provider_order, elseCAW_PROVIDER(which may be a comma-separated list), else the default provider.
With a fallback order, the agent selects the first installed provider and, on the first send, transparently moves to the next provider if that one fails or is rate-limited — no exception handling needed by the caller.
Source code in caw/agent.py
provider
property
¶
provider: Provider
The resolved provider instance (lazily created).
For an auto/fallback order, this is the first provider in the order whose CLI is installed (a fast, no-network check).
metadata
property
¶
Mutable metadata dict carried onto every session's trajectory.
set_provider
¶
add_tool_server
¶
Register a custom HTTP tool server (MCPServerHandle or ToolKit).
If handle is a ToolKit instance, as_server()
is called automatically. The handle's lifecycle (start/stop) is managed
by the session.
Source code in caw/agent.py
set_reasoning
¶
set_system_prompt
¶
get_spec
¶
get_spec() -> AgentSpec
Return an AgentSpec snapshot of this agent's current configuration.
Source code in caw/agent.py
check_limit
¶
Check if the provider's usage limit is currently active.
Sends a minimal test prompt to detect whether the configured
provider and model are currently rate-limited. Returns the
estimated number of minutes until the limit resets, or None
if no limit is detected.
This incurs a small token cost for the probe request.
Source code in caw/agent.py
check_health
¶
Report raw health signals for this agent's provider.
Fast by default (CLI installed + credential introspection, no token
cost). Pass live=True to additionally probe whether the provider
responds and is currently rate-limited. See
caw.health.ProviderHealth.
Source code in caw/agent.py
interactive
¶
interactive(initial_prompt: str, capture_bytes: int = 0, *, select_provider: bool = False, **kwargs: Any) -> InteractiveResult
Launch the provider binary interactively with an initial prompt.
The user interacts with the agent directly in their terminal. A copy of stdout is captured via a pty. MCP tool servers are started before launch and stopped after the process exits.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
initial_prompt
|
str
|
The first message sent to the agent. |
required |
capture_bytes
|
int
|
Maximum bytes of terminal output to keep (tail).
|
0
|
select_provider
|
bool
|
When |
False
|
Returns:
| Type | Description |
|---|---|
InteractiveResult
|
An |
InteractiveResult
|
output. |
Source code in caw/agent.py
completion
¶
completion(message: str, **kwargs: Any) -> Trajectory
Send a single message and return the complete trajectory.
Convenience wrapper for simple use cases where you don't need to maintain a multi-turn session:
traj = agent.completion("Explain this code")
print(traj.result)
Source code in caw/agent.py
start_session
¶
start_session(traj_path: str | Path | None = None, **kwargs: Any) -> Session
Start a new interactive session with the agent.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
traj_path
|
str | Path | None
|
If set, the trajectory is saved to this path after each
step and when |
None
|
Additional keyword arguments are forwarded to the session. Passing a
logger (any object with info/warn/error string methods)
makes every major event — user message, tool call, tool result,
assistant text, thinking, turn-end stats — also emit a one-line summary
through it, in addition to the console Display. See caw.logger.
Source code in caw/agent.py
resume_session
¶
resume_session(resume_handle: str, **kwargs: Any) -> Session
Resume a session from a handle produced by Session.resume_handle.
Returns a live Session whose next Session.send
continues the original conversation.
- Without
data_dir(or if the session isn't on disk): the backend conversation is resumed using the key embedded in the handle, but caw's trajectory starts empty (no prior turns restored). - With the original
data_dir: the full trajectory is restored and new turns are appended to the original session directory.
A bare session id is also accepted in place of a full handle, but only
when data_dir is set (the resume key is then read from disk).
Source code in caw/agent.py
901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 | |
Session¶
Session
¶
Session(provider_session: ProviderSession, store: SessionStore | None = None, subagent_traj_dir: str | None = None, tool_handles: list[Any] | None = None, auto_wait: bool = True, metadata: dict[str, Any] | None = None, logger: AgentLogger | None = None, fallback_build: Callable[[], ProviderSession | None] | None = None)
A live interaction session with a coding agent.
Source code in caw/agent.py
trajectory
property
¶
trajectory: Trajectory
Accumulated trajectory (available during and after the session).
resume_handle
property
¶
Opaque string for resuming this session later, possibly in another process.
Store it anywhere (a database, a file, …) and pass it to
Agent.resume_session. The handle is self-contained: it carries
the backend resume key, so resuming works even without the original
data_dir (you just won't get the prior trajectory restored). If
the resuming Agent does share the same data_dir, the
full history is restored and new turns are appended.
Raises if the backend has not yet assigned a resume key — send at least one message first.
session_dir
property
¶
Path to the session's data directory, or None if persistence is disabled.
send_async
async
¶
send_async(message: str) -> Turn
Async version of send — runs in a thread.
Messages are processed in FIFO order: if multiple send_async
calls overlap, each waits for the previous one to finish before
starting. This lets you fire-and-forget multiple messages:
tasks = [asyncio.create_task(session.send_async(m)) for m in msgs]
turns = await asyncio.gather(*tasks) # executed in order
You can also do async work while a send is in progress:
task = asyncio.create_task(session.send_async(prompt))
while not task.done():
source = await asyncio.wait_for(queue.get(), timeout=0.5)
yield source
turn = await task
Source code in caw/agent.py
send
¶
send(message: str) -> Turn
Send a message and get the agent's response turn.
When auto-wait is enabled and the provider reports a usage limit, this method sleeps until the limit resets and then automatically resumes the conversation — transparently to the caller.
When the session was created with an auto-provider fallback order, the first send transparently moves to the next provider if the current one fails (CLI missing, auth error) or is rate-limited — the caller never sees the exception. Once a provider has produced the first turn the session is committed to it (conversation context cannot be moved across CLIs), so later failures propagate normally.
Source code in caw/agent.py
end
¶
end() -> Trajectory
End the session and return the complete trajectory.
Source code in caw/agent.py
save_trajectory
¶
Save the trajectory to a JSON file at the given path.