-
Notifications
You must be signed in to change notification settings - Fork 1
Description
Bug
When using orchestrator with Claude as default provider, the write tool is called via native tool_use path but Claude omits the content parameter, causing repeated execution failed: missing required parameter: content errors.
Investigation
- Orchestrator correctly routes
chat_with_toolsto Claude (default = "claude") - Claude
supports_tool_use() -> true, so native tool_use path is used - Tool schema is generated via
schemars::schema_for!(WriteParams)and serialized withserde_json::to_value(&def.schema)which produces aRootSchemawrapper (includes$schema,title,definitionsmetadata) - Claude API
input_schemaexpects a clean JSON Schema object withtype,properties,requiredat the top level - The extra schemars wrapper may confuse Claude into not recognizing required fields
Likely root cause
tool_def_to_definition() in streaming.rs:757 passes the full RootSchema as parameters, but Claude API expects just the schema body. The schemars RootSchema has a nested structure:
{
"$schema": "...",
"title": "WriteParams",
"type": "object",
"properties": { "path": {...}, "content": {...} },
"required": ["path", "content"]
}If the extra fields cause Claude to misinterpret the schema, it may not enforce required parameters properly.
Proposed fix
- Verify the actual JSON being sent to Claude API (add trace logging for tool definitions)
- If schemars wrapper is the issue: extract
.schemafromRootSchemaor strip$schema/titlefields before passing to Claude - Add a test that validates the tool definition JSON structure matches what Claude API expects
Secondary issue
TUI header shows Model: glm-4.7-flash:latest instead of the actual Claude model because main.rs:267 sets model_name from config.llm.model (Ollama model) rather than from the orchestrator's active provider. This is cosmetic but misleading.
Steps to reproduce
- Configure orchestrator with Claude as default and Ollama model in
[llm] - Start TUI, ask agent to write a file
- Observe repeated
missing required parameter: contenterrors