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_DEFINITIONSinsrc/tools/* - MCP tools — discovered from MCP servers configured by the user
- Plugin tools — registered by plugins on load (each plugin can declare a
tools_modulein itsplugin.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:
- Resolves the tool by name
- Validates arguments against its JSON schema
- Invokes the handler (sync handlers run in a worker thread; async are awaited)
- Marshals the result back into the conversation
Errors during execution are surfaced to the agent so it can react instead of crashing the run.