Commit Graph

3975 Commits

Author SHA1 Message Date
Luis Pater
b4ff581daf fix(management): reconcile expired cooldowns to active status in auth files
- Reconcile expired credential and model cooldown states when building auth file entries
- Preserve error status and unavailability for persistent auth or token expiration failures
- Clear expired retry deadlines and restore active availability when cooldowns elapse

Closes: #5964
2026-09-19 22:24:40 +08:00
Luis Pater
b532db9c4b fix(translator): preserve constraints and additionalProperties in gemini parametersJsonSchema
- Add `CleanJSONSchemaForGeminiJSONSchema` to retain standard JSON schema constraints and `additionalProperties`
- Use the new schema cleaner for `parametersJsonSchema` across OpenAI and Claude Gemini translators

Closes: #5959
2026-09-19 16:37:28 +08:00
Luis Pater
f247e2b017 feat(translator): support strict tool mode mapping for gemini and claude
- Map strict tools to `VALIDATED` function calling mode in Gemini translators when tool choice is auto or omitted
- Preserve tool `strict` setting when translating OpenAI requests to Claude

Closes: #5958
2026-09-19 16:18:14 +08:00
Luis Pater
49eec664f4 fix(translator): align tool choice mapping and enforce fail-closed handling
- Fail closed to `none` mode on unrecognized tool choices, missing function names, or sanitized name collisions
- Support `allowed_tools` in OpenAI tool choice to filter function declarations and set function calling modes for Gemini
- Map Claude `disable_parallel_tool_use` to OpenAI `parallel_tool_calls: false` and preserve explicit `none` choices

Closes: #5957
2026-09-19 15:42:42 +08:00
Luis Pater
12773e7469 Merge pull request #5962 from router-for-me/fix/issue-5956-cache-write-deduction
fix(translator): deduct cache_write_tokens from input_tokens in openai/codex to claude (#5956)
2026-09-19 15:06:19 +08:00
sususu
883660fb81 fix(translator): deduct cache_write_tokens from input_tokens in openai/codex to claude (#5956)
Deduct cache_write_tokens and cache_creation_tokens from gross prompt/input tokens
when translating OpenAI Chat Completions and Codex Responses API to Anthropic Claude
Messages format to prevent downstream double-counting.

Include defensive guards against int64 overflow, clamp negative input_tokens to 0,
and support <= 0 fallback to cache_creation_tokens alias.
2026-09-19 13:31:17 +08:00
Luis Pater
c93978c4ea fix(schema): normalize true boolean subschemas and strip unsupported keywords
- Normalize boolean `true` subschemas across root, properties, items, definitions, and dependencies into empty object schemas `{}`
- Include `dependencies` in schema definition traversal and normalization
- Strip unsupported schema keywords including `additionalItems`, `unevaluatedProperties`, `unevaluatedItems`, and `contentSchema`

Closes: #3551
v7.3.8
2026-09-19 03:07:33 +08:00
Luis Pater
b6d1f050af fix(executor): buffer post-tool text to order devin tool calls before assistant response
- Buffer text deltas arriving after tool calls in streaming execution and flush them after closing active tool slots
- Prioritize tool call deltas over content text deltas during Connect frame processing
- Separate pre-tool and post-tool text parts in non-streaming responses to preserve step ordering
- Correct thought step index resolution when closing thoughts during content chunk emission

Closes: #5951
2026-09-19 02:41:17 +08:00
Luis Pater
22392c537d fix(executor): restore hybrid passthrough mcp tool names in claude oauth
- Track declared passthrough MCP tools in `claudeMCPAliasResolver`
- Recover hybrid tool names when the model prepends a virtual server prefix or replaces the caller's server with the virtual server
- Ensure client-tool alias matches take precedence over passthrough recovery and reject ambiguous passthrough tool matches

Closes: #5949
2026-09-19 02:13:11 +08:00
Luis Pater
690f4f3116 feat(executor): support use-max-completion-tokens for openai compatibility models
- Add `use-max-completion-tokens` setting to OpenAI compatibility model configuration
- Provide token normalization between `max_tokens` and `max_completion_tokens` based on model preference

Closes: #5939
2026-09-19 01:54:05 +08:00
Luis Pater
f4852170ee test(config): verify claude cloak persistence and update behavior
- Add tests for Claude cloak YAML persistence, comment preservation, and pruning of false/empty fields
- Cover partial PATCH and PUT updates, switch toggling, and credential identity isolation for Claude keys

Closes: #5935
2026-09-19 00:41:10 +08:00
Luis Pater
f86a33f721 fix(executor): restrict claude advisor tool check to server tool use
- Only detect `server_tool_use` for advisor tool invocations in Claude conversation history
- Prevent client-side tools named `advisor` using standard `tool_use` from improperly triggering advisor cloaking restrictions

Closes: #5934
2026-09-18 23:32:00 +08:00
Luis Pater
c2ea268409 fix(translator): scope tool responses per turn to handle repeated tool call IDs
- Scope tool response collection to the corresponding assistant turn instead of relying on global ID maps
- Prevent function names and tool results from being overwritten in multi-turn conversations with repeated tool call IDs
- Ensure proper function call and response pairing for Gemini and Antigravity translators

Closes: #5933
2026-09-18 23:25:16 +08:00
Luis Pater
cb62a6748b fix(openai): classify stream request timeout as server error
- Consolidate stream error code and error type derivations into paired error classes
- Map `StatusRequestTimeout` to `server_error` instead of `invalid_request_error` so interrupted streams remain retryable by clients

Closes: #5931
2026-09-18 23:10:19 +08:00
Luis Pater
81d6ba7746 fix(codex): preserve reasoning content and IDs for compat models in responses
- Resolve model `is_compat` status via model info, config index, or model entries in Codex executor
- Skip wiping `reasoning.content` and stripping reasoning IDs during Responses sanitization when `is_compat` is enabled
- Pass resolved compat flag across standard, streaming, compact, and WebSocket Codex request flows

Closes: #5930
2026-09-18 23:02:54 +08:00
Luis Pater
e84e248c51 fix(executor): record expected Devin upstream model and bound stream observer memory
- Set expected upstream model for Devin in both streaming and non-streaming paths to avoid false positive substitution warnings on intentional mappings
- Account for line overhead and enforce max lines per stream event in StreamResponseModelObserver, dropping overflowed events until the event boundary
- Add unit tests for Devin intentional mappings and stream observer bounded memory behavior
2026-09-18 22:08:35 +08:00
Luis Pater
cde7d57e44 fix(executor): robust response model observability across meta, kimi, and openai-compat streams
- observe response model from terminal sourceEvent in Meta non-stream multi-event SSE responses
- record expected upstream model in UsageReporter to prevent false substitution warnings on Kimi canonical mappings
- use bounded stream observer to extract response models across image stream chunk boundaries
- add regression tests for Meta SSE non-stream, Kimi model mappings, and chunked image streams
2026-09-18 21:53:19 +08:00
Luis Pater
f8467f07dc fix(executor): record authentic Devin and Gemini Interactions response models
- Devin: extract authentic upstream model name from parsed Usage.ModelName
  instead of synthesized interactions JSON or binary Connect frames. Keep
  response model empty when upstream does not report one.
- Gemini: support interaction.model and event_type terminal semantics
  in response model extractors for Gemini Interactions streaming.
- Add unit tests for Devin and Gemini Interactions response model observability.
2026-09-18 21:32:59 +08:00
Luis Pater
e9463ff5a7 feat(executor): extend response model recording and substitution warnings to all providers 2026-09-18 21:22:43 +08:00
Luis Pater
cd5af08e31 Merge pull request #5928 from Viggo95/feat/codex-response-model-observability 2026-09-18 21:05:35 +08:00
Luis Pater
05391d7b72 Merge pull request #5919 from Fesaluo/feat/xai-imagine-aspect-ratio-9-20
feat(xai): allow grok imagine aspect_ratio 9:20 and 20:9
2026-09-18 12:49:11 +08:00
Supra4E8C
0b9a91fb78 feat: add FluxA 2026-09-18 12:41:08 +08:00
Supra4E8C
784285a485 feat: add PatewayAI 2026-09-18 12:35:11 +08:00
Luis Pater
cc545cbf90 fix(openai): align tool call messages and preserve ordering on ambiguous outputs
- Add `AlignOpenAIToolCallMessages` to reorder tool results immediately after the matching assistant tool calls while preserving original content and numeric precision.
- Prevent deferred message reordering and call ID guessing when tool outputs are incomplete, duplicate, or missing IDs.
- Normalize translated requests after applying summary configuration in Codex multi-agent execution.

Closes: #5925
2026-09-18 12:32:21 +08:00
Viggo95
25f40d8cf8 feat(codex): record upstream response model and warn on silent model substitution
Codex upstreams can silently serve a different model than the one requested
(HTTP 200, with response.model naming the substitute). The proxy kept no record
of it: nothing logged, nothing reported, only the pass-through response body.

- Add Record.ResponseModel to sdk/cliproxy/usage, aligned with the existing
  ResponseServiceTier field, and emit it from the redis usage queue as the
  optional response_model payload field alongside response_service_tier. Only
  the record for the requested model carries it: additional-model records
  (image generation tool usage) describe a side model the upstream response
  never refers to, and would otherwise look like a substitution downstream.
- Add internal/runtime/executor/helps/response_model.go with
  extractCodexResponseModelEvent (SSE frames and raw JSON, restricted to the events
  that embed the authoritative response object, rejecting non-string and
  oversized upstream model names) and IsCodexModelSubstituted (both sides
  trimmed, lower-cased and stripped of thinking suffixes, dated aliases such as
  gpt-5.6-terra-2026-05-13 accepted in either direction).
- UsageReporter records the served model on the event path and emits the WARN
  when the attempt publishes its usage record, so no logging work happens
  before the first event is forwarded. Repeats are throttled per
  (auth id, requested model, served model) with a 10 minute window, because on
  an affected credential every request is substituted and an unthrottled
  warning would mirror the whole request volume into the logs. The credential
  is labelled auth_index=<index> only: codex credential file names embed the
  account e-mail, which must not be written to the logs at request rate.

Coverage, by entry point. The served model is observed on the HTTP streaming
path (both the bootstrap-buffered handshake and the streaming goroutine), the
HTTP non-streaming Execute loop, the websocket streaming and non-streaming
paths, and the two /responses-shaped image entry points. The remaining codex
entry points cannot report it and are therefore left alone: executeCompact
(/responses/compact answers with a compaction object that has no event type and
no response.model), the two direct image endpoints (/images/generations and
/images/edits answer in the Images API shape and stream image_generation.*
events), and CountTokens (counts locally with tiktoken, never reaching an
upstream).

TokenAccountingSchemaVersion is not bumped: it versions the token accounting
contract (token breakdown semantics), and this change only adds an optional
non-token field that leaves existing consumers and all token math untouched.

Note: response_model ships with the usage record and is the counting source;
the WARN is a throttled alerting signal and must not be used to count
substitutions.

Tests: table-driven unit tests for both helpers over real model ids, reporter
tests covering the published record, the single throttled warning, the absence
of account identifiers in it, concurrent observation and publishing under
-race, the throttle window and its entry bound, an executor-level guard for the
observeCodexTokenEvent wiring and the per-model records, plus a redisqueue
payload assertion for response_model. gofmt, go vet, go test -race on the
touched packages and go test ./... are clean.
2026-09-18 12:31:52 +08:00
Luis Pater
859c486512 fix(codex): normalize and support ultrafast service tier
- Normalize `service_tier` by trimming whitespace and matching case-insensitively.
- Map `fast` to `priority` and preserve `ultrafast` service tier.
- Strip unsupported service tier values and non-string types before forwarding.

Closes: #5924
2026-09-18 11:21:55 +08:00
Luis Pater
28743473c1 feat(codex): append (Devin) suffix to Devin model display names
- Detect Devin models by ID prefix, type, ownership, model registry metadata, or provider.
- Append `(Devin)` to model display names in Codex client responses when not already present.
- Set model `type` to `devin` in home Codex model formatting when served by the Devin provider.
2026-09-18 10:37:52 +08:00
Luis Pater
660a5800e7 fix(xai): restore aliased client web search tool name in responses
- Restore client-defined `web_search` tool names from their alias across SSE, websocket, and buffered execution responses.
- Preserve namespaced tool calls when matching and restoring tool names.

Closes: #5923
2026-09-18 09:57:06 +08:00
Luis Pater
3662d1535a fix(codex): strip item-level and tool output prompt cache breakpoints
- Strip `prompt_cache_breakpoint` from `output` arrays in function call outputs.
- Remove item-level `prompt_cache_breakpoint` fields from input items.

Closes: #5922
2026-09-18 09:29:06 +08:00
Luis Pater
1cce932573 fix(claude): skip retry-after header on overage-only rejections
- Skip parsing the `Retry-After` header when a rate limit rejection is overage-only to prevent global credential cooldowns.
- Allow exponential backoff to handle model recovery while keeping shared subscription windows available for other models.

Closes: #5920
2026-09-18 09:15:48 +08:00
Fesaluo
f049e00b76 feat(xai): also allow grok imagine aspect_ratio 20:9
Grok Imagine already supports the 20:9 wide phone ratio. Accept it
from aspect_ratio and from size, matching the 9:20 whitelist change.
2026-09-18 04:04:24 +08:00
Fesaluo
75bd6a60eb feat(xai): allow grok imagine aspect_ratio 9:20
Grok Imagine already supports the 9:20 phone ratio, but the OpenAI image
handler whitelist dropped it and fell back to 1:1. Accept 9:20 from
aspect_ratio and from size, and keep unknown ratios on the existing
fallback.
2026-09-18 03:58:11 +08:00
Luis Pater
b773607e3e fix(ci): replace go-cross/cgo-actions with direct FreeBSD sysroot cross-compilation
- Remove unmaintained go-cross/cgo-actions@v1 which hardcoded a 404 URL for FreeBSD 14.3-RELEASE
- Download base.txz directly with automatic mirror and archive fallback (download.freebsd.org -> archive.freebsd.org)
- Cross-compile with clang and lld directly in bash step
v7.3.7
2026-09-18 03:17:06 +08:00
Luis Pater
c616193a6c fix(xai): unify forced hosted tool choice normalization
- Generalize forced hosted tool choice handling across both image generation and web search.
- Normalize forced web search tool choices to string mode and isolate the target tool in the tools list.
- Strip hosted web search from mixed `allowed_tools` definitions.
- Skip native `x_search` injection when a hosted tool is exclusively required.

Closes: #5916
2026-09-18 02:20:41 +08:00
Luis Pater
44eaef0009 feat(claude): support model-level cooling and scope overage rate limits
- Add `claude.model-level-cooling` configuration to scope rate limit cooldowns to the requested model.
- Treat overage-only and spend cap rejections as model-scoped when shared subscription windows remain healthy.
- Propagate model-level cooling settings into streaming, token counting, and direct execution error classifiers.

Closes: #5915
2026-09-18 01:55:36 +08:00
Luis Pater
b6fe4f20c4 fix(devin): handle orphaned tool results and normalize function result payloads
- Match tool results against pending tool calls and downgrade unmatched results to user messages.
- Prevent downgraded orphaned tool results from consuming images intended for user turns.
- Unwrap protocol wrapper envelopes and extract structured text parts while preserving arbitrary business JSON.
- Provide a placeholder for empty or whitespace-only tool results.

Closes: #5911
2026-09-18 01:34:38 +08:00
Luis Pater
9e10db53ad fix(devin): aggregate tool calls by id and track cache write tokens
- Track and aggregate tool calls by call ID instead of slot index in streaming and buffered execution.
- Support raw arguments from invalid JSON fields for custom tool calls.
- Parse usage field 4 as cache write tokens instead of adding to prompt tokens.
- Align client metadata with the default client name and drop deprecated tag 28.

Closes: #5910
2026-09-18 01:04:43 +08:00
Luis Pater
0b55053944 fix(management): reject unresolved token placeholders in api-call
- Return an error when the `$TOKEN$` placeholder cannot be resolved or the credential for `auth_index` is missing.
- Ensure `$TOKEN$` substitutions in headers and request payloads fail fast instead of proceeding with empty values.
- Support resolving and refreshing provider OAuth tokens for API calls.

Closes: #5838
2026-09-17 23:43:04 +08:00
Luis Pater
b715526add feat(plugin): support scheduling across priorities
- Add `SchedulerAcrossPriorities` capability to allow plugin schedulers to receive candidates across all priority tiers.
- Propagate scheduler priority preferences through the plugin host and RPC capabilities.
- Update auth manager selection logic to supply candidates across all priorities when the scheduler opts in.

Closes: #5894
2026-09-17 21:21:56 +08:00
Luis Pater
afba07ba26 fix(config): preserve plugin configurations when saving yaml
- Replace the plugin configs subtree directly instead of merging to prevent zero values, booleans, and empty collections from being pruned as defaults.
- Ensure stale plugin keys and removed configuration entries are properly cleaned up while preserving comments.

Closes: #5907
2026-09-17 21:01:31 +08:00
Luis Pater
64c9433fd2 fix(devin): support images in tool results
- Extract and attach images from tool results to corresponding tool prompts by call ID.
- Preserve structured business JSON and raw objects in function result content.
- Prepend image headers to tool prompt content when images are present.

Closes: #5893
2026-09-17 20:00:46 +08:00
Luis Pater
46d4baff9a Merge pull request #5897 from camy-x/feat/auth-files-pagination
feat(management): paginate auth file listings
2026-09-17 19:28:04 +08:00
camy-x
76ac75e68a feat(management): paginate auth file listings 2026-09-17 14:37:36 +08:00
Luis Pater
8c664b2fed Merge pull request #5896 from router-for-me/translator
feat(translator): preserve model metadata in requests
v7.3.6
2026-09-17 13:52:35 +08:00
Luis Pater
ad088a8795 fix(devin): filter automation update tools and sanitize tool descriptions
- Filter out `automation_update` tools and sanitize tool descriptions in Devin wire requests and logs.
- Strip additional Codex prompt directives from system messages.
- Support `children` field fallback when collecting namespace tools.
2026-09-17 13:51:26 +08:00
hkfires
a9e92b8145 feat(translator): preserve model metadata in requests 2026-09-17 13:10:47 +08:00
hkfires
46f6cb0197 docs: document CLIProxyAPIHome integration areas 2026-09-17 13:09:36 +08:00
Luis Pater
1bb88959f6 Merge pull request #5889 from kinka/docs/add-cc-status-line
docs: add cc-status-line to community projects
2026-09-17 10:52:11 +08:00
huangqinjia
4516037820 docs: add cc-status-line to community projects
List the Claude Code status line for CLIProxyAPI quotas in the English,
Chinese, and Japanese READMEs.
2026-09-17 10:49:13 +08:00
Luis Pater
f668ac417d fix(schema): strip unsupported schema identifier keywords
- Remove `id`, `$anchor`, `$vocabulary`, `$dynamicRef`, and `$dynamicAnchor` when cleaning JSON schemas for Gemini.

Closes: #5888
2026-09-17 10:10:50 +08:00