Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- **plugins/ai-proxy**: tool-use translation for the Anthropic provider on both Chat Completions and the Responses API. Previously the Anthropic translation dropped the client's `tools`/`tool_choice` entirely (the model never saw the tools, so it could never call them) and ignored `tool_use` blocks in the response (a tool-calling turn came back malformed, with `finish_reason: "tool_calls"` but no `tool_calls`). Now: `tools` and `tool_choice` are mapped to Anthropic's `tools`/`tool_choice` (`parameters` → `input_schema`, `"required"` → `any`, `parallel_tool_calls: false` → `disable_parallel_tool_use`); assistant `tool_calls` and `role:"tool"` history messages are translated to `tool_use`/`tool_result` blocks; and Anthropic `tool_use` responses are translated back to OpenAI `tool_calls` / Responses `function_call`. Codex freeform `custom` tools (e.g. `apply_patch`), `local_shell`, and hosted server tools have no Anthropic representation and are now rejected on the Responses path with `400 custom_tools_not_supported_for_provider` instead of being dropped silently. Shared mapping lives in a new `protocols::tools` module. OpenAI/Ollama remain passthrough.
- **plugins/ai-proxy**: configurable credential attachment via a new `auth` field on targets, routes, and the flat config. `auth` is orthogonal to `provider` (which selects the wire protocol): `bearer` → `Authorization: Bearer`, `api_key` → `x-api-key`, `{ header: "Name" }` → an arbitrary credential header, `{ query: "param" }` → key in the query string. When omitted it defaults to the provider's convention (bearer for OpenAI/Ollama, `x-api-key` for Anthropic), so existing configs are unchanged. This lets OpenAI-compatible endpoints with non-standard credential headers (e.g. Brave AI Grounding's `X-Subscription-Token`, Azure OpenAI's `api-key`) be configured without a dedicated provider type. Internally, the three previously hardcoded auth call sites (OpenAI transport, Anthropic transport, `/v1/models` aggregator) now share a single `apply_auth` implementation.

## [0.8.1] - 2026-07-15
Expand Down
9 changes: 9 additions & 0 deletions docs/guide/dispatchers.md
Original file line number Diff line number Diff line change
Expand Up @@ -913,6 +913,15 @@ OpenAI-compatible providers (OpenAI, Ollama) stream natively via `host_http_stre

Anthropic streaming is buffered: the dispatcher waits for the full response and returns it non-streamed (a warning is logged). True SSE translation is deferred per ADR-0024 / ADR-0030 §2.

#### Tool use (Anthropic translation)

For OpenAI/Ollama the tool surface is passthrough. For the **Anthropic** provider the dispatcher translates tools in both directions on Chat Completions and Responses:

- **Request:** the client's `tools` are mapped to Anthropic's `tools` (`function.parameters` / flat `parameters` → `input_schema`), and `tool_choice` is mapped (`"auto"`/`"none"` → same, `"required"` → `any`, `{function:{name}}`/`{name}` → `{type:"tool", name}`); `parallel_tool_calls: false` becomes `disable_parallel_tool_use: true`.
- **Response:** Anthropic `tool_use` blocks become OpenAI `tool_calls` (Chat Completions) / `function_call` items (Responses); the assistant `content` is `null` on a tool-only turn, and `finish_reason` is `tool_calls`.
- **History:** an assistant `tool_calls` message → `tool_use` blocks, and `role:"tool"` messages → `tool_result` blocks (consecutive results merged into one user turn).
- **Unsupported tool types:** Codex freeform `custom` tools (e.g. `apply_patch`), `local_shell`, and hosted server tools have no Anthropic representation. On the Responses path they are rejected with `400 custom_tools_not_supported_for_provider` rather than dropped silently. Route those to OpenAI.

#### Responses API specifics

`POST /v1/responses` is **stateless-only** (ADR-0030 §2):
Expand Down
Loading