Skip to main content

Tool system

Tools are functions the agent can call. The tool system is data-driven: each module under src/tools/ exports a TOOL_DEFINITIONS list, and controller_tools.py aggregates them all.

Three providers, one manager

ToolManager (src/tools/providers/tool_manager.py, extends BaseToolProvider) merges three sources behind a single dispatch interface:

  • Controller tools — built-ins shipped with Youkore, defined as TOOL_DEFINITIONS in src/tools/*
  • MCP tools — discovered from MCP servers configured by the user
  • Plugin tools — registered by plugins on load (each plugin can declare a tools_module in its plugin.json)

Definition shape

A definition is a dict in a TOOL_DEFINITIONS list:

TOOL_DEFINITIONS = [
{
"name": "web_search",
"description": "Search the web",
"parameters": { ... JSON schema ... },
"controller_key": "web", # optional: bind to a controller instance
"method_name": "search", # optional: method on the controller
# ... plus flags: terminal, markers, confirm, status, ...
},
...
]

Tools that need stateful resources (HTTP clients, DB connections) declare a controller_key; the matching controller instance is wired in at registration time. Stateless tools can be StandaloneTool instances.

Per-agent toolset

The tools list in an agent's frontmatter is the agent's allowlist. Empty list ⇒ 0 tools, NOT "all tools" (deliberately strict default).

Each entry can carry per-tool flags:

tools:
- {name: bash, core: true, confirm: true} # required + asks before running
- {name: web_browse} # default flags

Dispatch

When the LLM emits a tool call, ToolManager:

  1. Resolves the tool by name
  2. Validates arguments against its JSON schema
  3. Invokes the handler (sync handlers run in a worker thread; async are awaited)
  4. Marshals the result back into the conversation

Errors during execution are surfaced to the agent so it can react instead of crashing the run.