trading_agent.subagents.subagent_runner
¶
Runs the tasks a desk delegates to its subagents.
Each task gets a fresh model router over the subagent's backends (or the desk's, for "inherit"), its own tool registry from the toolbox, and a system prompt built from its definition. Tasks run side by side; each has its own time limit, and one that fails, times out or crashes never stops the others. Afterwards the task's bash session and any Claude Code process are closed.
Every task publishes subagent_started and subagent_finished, and its tool calls carry the task's trigger id, so the journal shows what each subagent did.
Typical usage example:
runner = SubagentRunner(desk_name, mode, library, toolbox, runner_factory, ['claude', 'qwen'], backends, event_bus, 3) reports = await runner.run_all([SubagentTask('news_reader', 'What moved INFY today?')])
SubagentTask
dataclass
¶
One task for one subagent.
Attributes:
| Name | Type | Description |
|---|---|---|
subagent |
str
|
The subagent's name. |
task |
str
|
What it should do, with everything it needs to know. |
SubagentReport
dataclass
¶
How one task ended.
Attributes:
| Name | Type | Description |
|---|---|---|
subagent |
str
|
The subagent's name. |
outcome |
str
|
"answered", "timed out", "failed" or "unknown subagent". |
text |
str
|
The subagent's report, or why there is none. |
backend_name |
str | None
|
The backend that answered, or None. |
seconds |
float
|
How long the task took. |
notes |
tuple[str, ...]
|
Remarks about the definition, such as tools it may not have. |
SubagentRunner
¶
SubagentRunner(desk_name, mode, library, toolbox, runner_factory, desk_backend_order, backends, event_bus, maximum_identical_tool_calls, permission_gate=None)
Runs one desk's subagent tasks.
Creates the runner.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
desk_name
|
str
|
The desk the subagents work for. |
required |
mode
|
str
|
"dry_run" or "live". |
required |
library
|
SubagentLibrary
|
The definitions. |
required |
toolbox
|
SubagentToolbox
|
Builds each task's tools. |
required |
runner_factory
|
RunnerFactory
|
Builds a turn runner from a backend name, its settings, an executor, a prompt builder and a round limit. |
required |
desk_backend_order
|
Sequence[str]
|
The desk's backends, for subagents that inherit them. |
required |
backends
|
Mapping[str, BackendConfiguration]
|
Every configured backend. |
required |
event_bus
|
EventBus
|
Where each task's events are published. |
required |
maximum_identical_tool_calls
|
int
|
The loop guard's limit for each task. |
required |
permission_gate
|
PermissionGate | None
|
Holds the tasks' calls that need the user's permission, or None when none do. |
None
|
Source code in src/trading_agent/subagents/subagent_runner.py
run_all
async
¶
Runs the tasks side by side.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tasks
|
Sequence[SubagentTask]
|
The tasks. |
required |
Returns:
| Type | Description |
|---|---|
list[SubagentReport]
|
One report per task, in the order given. |
Source code in src/trading_agent/subagents/subagent_runner.py
run_one
async
¶
Runs one task from start to finish.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
task
|
SubagentTask
|
The task. |
required |
Returns:
| Type | Description |
|---|---|
SubagentReport
|
How it ended. |
Source code in src/trading_agent/subagents/subagent_runner.py
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 | |