v1.2.0

Tool Dispatch

Last updated

How one round of tool calls is checked, run, and recorded: the three passes, deferred schemas, which tools run concurrently, and how repeated calls are deduplicated.

Three-pass tool concurrency

toolCall.go splits each round's tool calls into three serial passes; only Pass 2 fans out:

Pass Mode Work
1 — pre-flight Serial Unwrap run_tool into the named tool; refuse a tool called directly that is not in the loaded set (with a hint to fetch its schema with find_tools and call run_tool); duplicate-call dedupe (tool|args hash); return the schema, and ask for a re-invoke, when a tool is called before its schema was fetched; existence check, so a name with no registered handler never runs (since v1.2.0); confirm gate; JSON-schema validation
2 — execute Concurrent for IsConcurrent-tagged tools, at most 5 at a time (MAX_CONCURRENT_TOOLS, v1.0.20) with the rest queued; serial otherwise tools.Execute
3 — commit Serial Land sessionData.Tools and ToolHistories, update the dedupe map, write the result cache, emit EventToolResult

Since v1.2.0 tool schemas are deferred. For every provider except claude-code, the request's tools array holds only find_tools and run_tool (plus client tools); every other tool is listed by name in the turn context, its schema is fetched with find_tools, and it is called as run_tool(name, args). claude-code gets every tool except run_tool, but all of them except find_tools and client tools start unmarked, so the first call to each returns its schema instead of running. The per-tool AlwaysLoad flag was removed; use find_tools to load a schema. Removed in v1.2.0.

Concurrent-tagged built-in tools (18): read_files, find_files, find_tools, file_history, chat_history, error_history, fetch_page, search_web, http_request, download_file, test_tool, calculate, subagents, list_chatbot, send_to_chatbot, reasoning_guide, html_template, write_todo (since v1.0.26; find_note left the set when it was removed in v1.0.23). generate_audio and generate_image do not carry the flag. api_* / script_* / ext_* tools run concurrently only when their own definition declares it. edit_file, run_command, interactive tools, and MCP tools always run serially — the parallel run_command_readonly tool added in v1.0.23 was removed in v1.0.25.

Dedupe is per run, not per session: a repeated tool|args pair returns the earlier result instead of executing again, and edit_file invalidates the read_files entries covering the paths it touched. A separate 30-minute result cache in ToriiDB (db_0) covers fetch_page, search_web, and http_request GET calls only.

中文