- Added `CountClaudeInputTokens` for estimating token usage with O200kBase tokenizer.
- Enhanced `ClaudeExecutor` to handle token counting locally, reducing dependency on upstream services.
- Introduced validation for token count requests for improved error handling.
- Updated tests to cover local token counting behavior and invalid request handling.
Closes: #4103
`prependToFirstUserMessage` always inserted the `<system-reminder>` text block at
index 0 of the first user message's content array. When a client sends a history
that begins with an assistant `tool_use` turn, that first user message is the
`tool_result` carrier, and Anthropic requires those blocks to stay at the head of
the message. Prepending pushed them out of first position, so the upstream
rejected the whole request with:
messages.N: `tool_use` ids were found without `tool_result` blocks
immediately after: <id>
Append the reminder instead when the content array already leads with a
`tool_result` block; behaviour is unchanged for every other message shape.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- Added an `incomingHeaders` argument to `applyClaudeHeaders` to enable external header injection for flexibility.
- Updated Kimi executor to delegate header support to Claude executor, facilitating upstream request logging and beta header forwarding.
- Introduced tests for delegated configuration, header handling, and upstream request/response logging to improve coverage.
- Updated `normalizeClaudeSamplingForUpstream` to delete `top_p` from payloads.
- Adjusted test to validate the removal of both `temperature` and `top_p`.
Closes: #4383
- Introduced `AttachCacheControl` and `AttachMessageCacheControl` utilities for consistent cache control injection in content parts and messages.
- Updated Claude translator modules to preserve and apply cache control metadata for responses, messages, tools, and parts.
- Added unit tests to validate proper cache control behavior across multiple scenarios.
Closes: #4146
- Verified proper chunking and streaming of SSE events in `ExecuteStream`.
- Refactored executor to ensure complete SSE event delivery without partial fragments.
Closes: #4121
- Introduced `RebuildMidSystemMessage` field in config to move system messages into the top-level Claude system field.
- Updated executor to handle mid-system message rebuilding when enabled via config or auth attributes.
- Added unit tests to verify rebuilding behavior and default behavior when disabled.
- Updated configuration example and API handlers to support the new field.
Closes: #3792
- Added `sanitizeClaudeWebSearchDomains` to remove empty `allowed_domains` and `blocked_domains` fields for built-in web_search tools, addressing ambiguity errors from Anthropic.
- Integrated domain sanitization into the Claude message preparation pipeline.
- Added test cases to validate correct handling of empty and non-empty domain fields across various tool types.
Closes: #2681
- Updated Antigravity Credits fallback to handle KV store unavailability as a service error.
- Enhanced signature caching mechanisms with request-time KV access and sliding expiration.
- Added and improved tests for KV client interactions, including error handling and expiration behaviors.
- Introduced `CacheSignatureBestEffort` for non-critical signature caching and clarified function flows with required context.
- Ensured consistent error reporting for missing or unavailable KV stores in various scenarios.
- Replaced direct `homekv` calls with injectable KV client interfaces for `antigravity` and `codex_reasoning_replay` modules.
- Improved error reporting and handling for KV operations, including `KVGet`, `KVSet`, `KVDel`, and `KVExpire`.
- Introduced dedicated fake KV clients for expanded and granular test coverage.
- Added new unit tests to validate KV client behaviors and error scenarios, ensuring robustness and sliding expiration functionality.
- Updated all references from v6 to v7 for `github.com/router-for-me/CLIProxyAPI`.
- Ensured consistency in imports within core libraries, tests, and integration tests.
- Added missing tests for new features in Redis Protocol integration.
- Implemented `validateClaudeStreamingResponse` to ensure upstream streaming data integrity.
- Added new tests to verify response validation, including empty streams, error events, incomplete streams, and valid streams.
- Integrated validation logic into the Claude executor's streaming handler, returning detailed errors for malformed upstream data.
Fixed: #2193
remapOAuthToolNames renames lowercase client-sent tools (e.g. `glob` →
`Glob`) to Claude Code equivalents on OAuth requests to avoid tool-name
fingerprinting. The reverse pass previously ran against a *global*
reverse map and rewrote every tool_use block whose name matched any
value in oauthToolRenameMap — regardless of what the client actually
sent.
For clients that send mixed casing (notably Amp CLI — `Bash`, `Read`,
`Grep`, `Task` alongside `glob`, `skill`, etc.) this corrupted the
response. Any forward rename in the request set the "renamed" flag,
which then unconditionally lowercased every `Bash` in the response to
`bash`. Amp's tool registry has `Bash`, not `bash`, so it rejected the
tool_use with `tool "bash" is not allowed for smart mode` and tool
execution failed.
Fix: `remapOAuthToolNames` now returns a per-request map keyed on the
upstream (TitleCase) name valued with the original client-sent name.
The reverse functions take this map and only touch entries in it.
Names the client sent in TitleCase pass through untouched in both
directions.
- Change remapOAuthToolNames signature from `([]byte, bool)` to
`([]byte, map[string]string)`; populate at every rename site
(tools[], tool_choice.name, message tool_use, tool_reference,
nested tool_reference inside tool_result).
- Change reverseRemapOAuthToolNames and
reverseRemapOAuthToolNamesFromStreamLine to accept and consume the
per-request map; remove the global oauthToolRenameReverseMap.
- Update all three executor call sites (Execute, ExecuteStream direct
passthrough, ExecuteStream translated) + count_tokens.
- Add regression tests for the mixed-case scenario in both the
non-streaming and SSE code paths.
Added comprehensive tests to ensure key order is maintained when modifying payloads in `normalizeCacheControlTTL` and `enforceCacheControlLimit` functions. Removed unused helper functions and refactored implementations for better readability and efficiency.
The review asked for the builtin tool registry helper to live with the rest
of executor support utilities. This moves the registry code into the helps
package, exports the minimal surface executor needs, and keeps behavior tests
with the executor while leaving registry-focused checks with the helper.
Constraint: Requested layout keeps executor helper utilities centralized under internal/runtime/executor/helps
Rejected: Keep the files in executor and reply with rationale | conflicts with requested package organization
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep executor behavior tests near applyClaudeToolPrefix and keep pure registry tests in helps
Tested: go test ./internal/runtime/executor/helps ./internal/runtime/executor -run 'Claude|Builtin|Tool'; go test ./test/...; go test ./...
Not-tested: End-to-end Claude Code direct-connect/session runtime behavior
normalizeCacheControlTTL unconditionally re-serializes the entire request
body through json.Unmarshal/json.Marshal even when no TTL normalization
is needed. Go's json.Marshal randomizes map key order and HTML-escapes
<, >, & characters (to \u003c, \u003e, \u0026), producing different raw
bytes on every call.
Anthropic's prompt caching uses byte-prefix matching, so any byte-level
difference causes a cache miss. This means the ~119K system prompt and
tools are re-processed on every request when routed through CPA.
The fix adds a bool return to normalizeTTLForBlock to indicate whether
it actually modified anything, and skips the marshal step in
normalizeCacheControlTTL when no blocks were changed.
- Set Accept-Encoding: identity for SSE streams; upstream must not compress
line-delimited SSE bodies that bufio.Scanner reads directly
- Re-enforce identity after ApplyCustomHeadersFromAttrs to prevent auth
attribute injection from re-enabling compression on the stream path
- Add peekableBody type wrapping bufio.Reader for non-consuming magic-byte
inspection of the first 4 bytes without affecting downstream readers
- Detect gzip (0x1f 0x8b) and zstd (0x28 0xb5 0x2f 0xfd) by magic bytes
when Content-Encoding header is absent, covering misbehaving upstreams
- Remove if-Content-Encoding guard on all three error paths (Execute,
ExecuteStream, CountTokens); unconditionally delegate to decodeResponseBody
so magic-byte detection applies consistently to all response paths
- Add 10 tests covering stream identity enforcement, compressed success bodies,
magic-byte detection without headers, error path decoding, and
auth attribute override prevention
Default to generating a fresh random user_id per request instead of
reusing cached IDs. Add cache-user-id config option to opt in to the
previous caching behavior.
- Add CacheUserID field to CloakConfig
- Extract user_id cache logic to dedicated file
- Generate fresh user_id by default, cache only when enabled
- Add tests for both paths