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
973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 | |
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
1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 | |
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, on_usage_limit: Callable[[UsageLimit, int], None] | None = None, max_usage_wait: int | 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.