Skip to content

trading_agent.subagents.subagent_toolbox

Chooses and builds the tools one subagent task may use.

A subagent gets tools from its desk:

  • Without a tools list, a safe read-only set: market data, the web, the knowledge base, past sessions, skills and MCP tools.
  • With a list, exactly the tools named. Order tools are given only this way, and they still go through the desk's risk engine under the desk's name.
  • The bash tools get a fresh bash session for each task, in the desk's sandbox, so tasks running side by side never type into the same shell.
  • delegate_task is never given, so a subagent cannot start subagents. The browser tools are never given, because each desk has one Chrome profile, which two tasks cannot drive at once.

Typical usage example:

toolbox = SubagentToolbox(desk_tools, bash_session_factory, 60.0) prepared = toolbox.prepare(definition)

DEFAULT_TOOL_NAMES module-attribute

DEFAULT_TOOL_NAMES = ('get_time', 'read_file', 'web_search', 'web_fetch', 'search_instruments', 'get_quote', 'get_candles', 'get_portfolio', 'get_orders', 'search_sessions', 'search_knowledge', 'load_skill', 'tool_search', 'call_mcp_tool')

PreparedTools dataclass

PreparedTools(registry, bash_session, refused, unknown)

The tools of one subagent task.

Attributes:

Name Type Description
registry ToolRegistry

The task's tool registry.

bash_session BashSession | None

The fresh bash session made for the task, to close afterwards, or None.

refused list[str]

Tools the definition asked for that subagents may never have.

unknown list[str]

Tools the definition asked for that the desk does not have.

SubagentToolbox

SubagentToolbox(desk_tools, bash_session_factory, tool_timeout_seconds)

Builds subagent tool registries from a desk's tools.

Creates the toolbox.

Parameters:

Name Type Description Default
desk_tools Sequence[Tool]

The desk's tools, shared with its subagents.

required
bash_session_factory Callable[[], BashSession]

Makes a new bash session in the desk's sandbox.

required
tool_timeout_seconds float

The default time limit of one tool call.

required
Source code in src/trading_agent/subagents/subagent_toolbox.py
def __init__(
    self,
    desk_tools: Sequence[tool_module.Tool],
    bash_session_factory: Callable[[], bash_session_module.BashSession],
    tool_timeout_seconds: float,
):
    """Creates the toolbox.

    Args:
        desk_tools (Sequence[tool_module.Tool]): The desk's tools, shared with its subagents.
        bash_session_factory (Callable[[], bash_session_module.BashSession]): Makes a new bash session in the desk's sandbox.
        tool_timeout_seconds (float): The default time limit of one tool call.
    """
    self._desk_tools = {}
    for desk_tool in desk_tools:
        self._desk_tools[desk_tool.name] = desk_tool
    self._bash_session_factory = bash_session_factory
    self._tool_timeout_seconds = tool_timeout_seconds

prepare

prepare(definition)

Builds the registry for one task.

Parameters:

Name Type Description Default
definition SubagentDefinition

The subagent.

required

Returns:

Type Description
PreparedTools

The registry and what was left out.

Source code in src/trading_agent/subagents/subagent_toolbox.py
def prepare(
    self,
    definition: definition_module.SubagentDefinition,
) -> PreparedTools:
    """Builds the registry for one task.

    Args:
        definition (definition_module.SubagentDefinition): The subagent.

    Returns:
        PreparedTools: The registry and what was left out.
    """
    names = definition.tool_names
    if names is None:
        names = DEFAULT_TOOL_NAMES
    tools = []
    refused = []
    unknown = []
    bash_session = None
    for name in names:
        if name == _DELEGATE_TOOL_NAME or name.startswith(_BROWSER_PREFIX):
            refused.append(name)
            continue
        if name in _BASH_TOOL_NAMES:
            if bash_session is None:
                bash_session = self._bash_session_factory()
            tools.append(self._bash_tool(name, bash_session))
            continue
        desk_tool = self._desk_tools.get(name)
        if desk_tool is None:
            if definition.tool_names is not None:
                unknown.append(name)
            continue
        tools.append(desk_tool)
    return PreparedTools(
        registry=tool_registry.ToolRegistry(
            tools,
            timeout_seconds=self._tool_timeout_seconds,
        ),
        bash_session=bash_session,
        refused=refused,
        unknown=unknown,
    )