Skip to main content
ChatCLI supports tool calls via native API for OpenAI, Anthropic, ZAI (Zhipu AI), MiniMax, Moonshot (Kimi), and OpenRouter, replacing the XML-embedded-in-prompt approach with structured API calls. This improves accuracy, reduces token consumption, and enables cache optimizations.

Why Native Tool Use?


Architecture

ToolAwareClient Interface

The ToolAwareClient interface extends the base LLMClient with tool support:

Automatic Detection

Detection is done via type assertion, with no configuration required:
Providers that do not implement ToolAwareClient continue to work normally via SendPrompt.

Provider Tool Use Support

Not all providers implement native tool use. Features like /coder mode and multi-agent orchestration work best with providers that support SendPromptWithTools:
When using providers without native tool use, the agent and coder modes still function but rely on XML-based tool call parsing from the LLM’s text output. This is less reliable than native tool calling and may occasionally require format correction retries (up to 3 attempts). For production /coder workflows, OpenAI, Claude, ZAI, MiniMax, or OpenRouter are recommended.

Data Types

Defines a tool available to the model:
Represent a tool call by the model and its result:
The IsError field (aligned with Anthropic’s Messages API) is emitted natively as is_error: true in Claude’s tool_result block. For OpenAI-compatible providers (OpenAI, Moonshot, MiniMax, ZAI, OpenRouter), the models.Message also carries ErrorCode (ENOENT, Timeout, ExitCode:N, InvalidArgs, …) and the adapter prepends content with [ERROR:<code>] — the model gets the signal even without a native error field.
Unified response that can contain text and/or tool calls:

Provider Implementations

Uses the tools field in the Chat Completions API:
  • Sends tools as a tools array with tool_choice: "auto"
  • Processes tool_calls in choices[0].message
  • tool messages in the history link results to the tool_call_id

Tool result with is_error / ErrorCode (provider-agnostic)

Tool results carry two orthogonal signals that travel to the model:
  • IsError bool — true when the tool executed but reported a business-level failure (non-zero exit, HTTP 4xx, file not found, invalid args schema). False = success.
  • ErrorCode string — locale-independent classification: ENOENT, EACCES, EISDIR, EEXIST, Timeout, Canceled, ExitCode:N, NetworkError, DNSError, InvalidArgs, etc. Empty when IsError=false.
The model pattern-matches on [ERROR:<code>] to decide retry/recovery without parsing English — InvalidArgs means “fix the schema”, Timeout means “try again”, ENOENT means “wrong file”.

ContentBlock with Cache Control

For Anthropic, the system prompt is split into blocks with cache control:
The cache_control:ephemeral tells Anthropic that the system prompt block can be cached between requests, significantly reducing latency and cost in long conversations.

Fallback Integration

The fallback chain (llm/fallback) supports SendPromptWithTools automatically. Providers without native tool use support are skipped in the tool call chain but remain available for plain text requests.