Commit Graph

3527 Commits

Author SHA1 Message Date
lzt404
b232394018 Merge pull request #5210 from router-for-me/apimart-sponsor
Apimart sponsor
2026-08-24 16:11:39 +08:00
lzt404
cef351a464 docs(readme): add APIMart sponsor 2026-08-24 16:03:05 +08:00
Luis Pater
9d0a60bfc3 fix(gemini,antigravity): preserve function/tool results as raw strings
- Keep `functionResponse.response.result` as a string in Gemini responses translation instead of JSON-parsing tool output.
- Apply the same string-preserving behavior for antigravity tool responses to avoid upstream 400 errors from parsed payloads.
2026-08-23 15:09:34 +08:00
Luis Pater
3faf70957f Merge pull request #5184 from HuiCheng/fix/xai-image-generation-tool-choice-required
fix(xai): map image_generation tool_choice to required
2026-08-23 13:34:19 +08:00
程辉
6f4b6dc5f5 fix(xai): keep forced image_generation from other tools
Rewriting {type: image_generation} to string required would let later
x_search injection or leftover web_search satisfy the choice. Reduce
the tools list to image_generation for that forced case, and skip
x_search injection while the remaining tools are image-only.

Closes: #5183
2026-08-23 12:22:14 +08:00
程辉
fba1ff24ac fix(xai): preserve auto when rewriting image-only allowed_tools
An allowed_tools list that only names image_generation cannot be sent
to chat-proxy. Map that empty remainder to the original mode so
mode=auto stays optional instead of becoming required.

Closes: #5183
2026-08-23 12:03:46 +08:00
程辉
d2742c5f37 fix(xai): map image_generation tool_choice to required
chat-proxy rejects allowed_tools lists that name image_generation.
Rewrite a forced image_generation choice, and an allowed_tools list
that only names that hosted tool, to the string "required". Mixed
allowed_tools lists drop the image_generation entry. Prune orphans
before this rewrite so older models still lose the leftover choice.

Closes: #5183
2026-08-23 10:12:52 +08:00
Luis Pater
a7e3596b7e fix(gemini): normalize malformed schema nodes before cleanup
- Added a preprocessing pass to repair malformed MCP-style JSON schemas.
- Wraps bare property maps as object schemas, promotes `required: true` flags to parent `required` arrays, and removes boolean `required` from properties.
- Recurses through nested schema containers and skips known API request envelopes to avoid rewriting non-schema docs.
- Switched schema decoding/serialization path to preserve large numeric values and avoid HTML-escaping side effects.

Closes: #5178
v7.2.140
2026-08-22 22:39:03 +08:00
Luis Pater
1be84170e6 Merge pull request #5177 from YogaSakti/fix/antigravity-fallback-version
fix(antigravity): raise the fallback client version to 2.9.1 (#5175)
2026-08-22 21:32:28 +08:00
Luis Pater
7d5b23f177 Merge pull request #5174 from HuiCheng/fix/xai-keep-image-generation-grok-46
fix(xai): keep image_generation on grok-4.6+ conversation requests
2026-08-22 21:20:00 +08:00
Luis Pater
4d68ca8a63 fix(codex): convert Grok client keepalive SSE frames to comments
- Add Grok client detection via User-Agent (including Gin context fallback) in a new `grokbuild` helper.
- Transform keepalive SSE `event`/`data` frames into `: keepalive` comments when streaming to Grok clients.
- Keep keepalive frames untouched for non-Grok clients while preserving existing stream translation behavior.

Closes: #5171
2026-08-22 20:58:35 +08:00
Luis Pater
d5b57a2d8a fix(openai): validate and filter thought signatures in responses conversion
Closes: #5166
2026-08-22 17:30:26 +08:00
Luis Pater
eeaa2e1830 Merge pull request #5176 from router-for-me/auth
Normalize credential metadata and enhance registry interactions
2026-08-22 17:13:39 +08:00
hkfires
ebda750911 feat(auth): enhance key deletion and patching with base URL validation 2026-08-22 16:53:30 +08:00
Luis Pater
ab8f00dbd9 fix(claude): derive stable request-scoped metadata.user_id for converters
Closes: #5153
2026-08-22 16:01:25 +08:00
Luis Pater
b3f72cef65 fix(gemini): normalize Claude thinking signatures in Gemini request and response conversion
Closes: #5151
2026-08-22 15:35:54 +08:00
Yoga Sakti
a834917e87 fix(antigravity): raise the fallback client version to 2.9.1 (#5175)
Cloud Code resolves newer Antigravity models only for clients reporting
at least 2.9.0; below that it answers 404 Requested entity was not found.
The offline fallback still reported 2.9.0's predecessor 2.2.1, so every
request sent before the hub manifest is first fetched — or from a
deployment that cannot reach the manifest at all — asked for models such
as gemini-3.7-flash-high with a version the backend rejects.

The hub manifest the updater already polls currently publishes 2.9.1, so
this only aligns the offline floor with what the online path resolves.
The test now asserts the floor rather than a literal, so a future
downgrade below 2.9.0 fails instead of silently reintroducing the 404.
2026-08-22 13:19:24 +07:00
Luis Pater
65071f7c47 test(claude): expand OpenAI conversion tests for reasoning_content and stream/non-stream parity
Closes: #5148
2026-08-22 13:20:00 +08:00
Luis Pater
d9869ed908 test(openai): expand reasoning fallback coverage in OpenAI responses non-stream conversion tests
Closes: #5147
2026-08-22 13:08:11 +08:00
程辉
87fb01b237 fix(xai): drop orphaned tool_choice after compact strips tools
Compact deletes tools after prepareResponsesRequestTo. On grok-4.6+
image_generation is now kept and rewritten to allowed_tools, so the
leftover choice would be sent without tools. Reuse the existing
normalizer to drop that orphaned selection.

Closes: #5173
2026-08-22 12:47:57 +08:00
程辉
dfdf183fcf fix(xai): keep image_generation on grok-4.6+ conversation requests
normalizeXAITool still strips Codex hosted image tools on older Grok
conversation models. grok-4.6 and later accept xAI native Imagine
tool, so keep client-supplied image_generation there and rewrite a
forced choice into allowed_tools. grok-4.20-* stays on the old strip
because that product line is not comparable to grok-4.6.

Closes: #5173
2026-08-22 12:38:30 +08:00
hkfires
71c3c144a0 fix(registry): detect gemini interactions changes 2026-08-22 12:20:53 +08:00
hkfires
e04d620cc1 feat(auth): normalize credential metadata keys
Canonicalize legacy config-style credential keys across stores,
management handlers, plugin auth, and file synthesis while preserving
explicit canonical values. Expose per-auth request_retry in auth file
management and add max-retry-credentials management routes.
2026-08-22 12:01:06 +08:00
hkfires
0a14eb70ce feat(auth): add retry round credential filtering v7.2.139 2026-08-22 01:20:02 +08:00
hkfires
601ca43090 feat(auth): add credential retry round contract
Redefine request-retry as additional credential retry rounds and
enforce max-retry-credentials per round. Home dispatch now carries
excluded and pinned auth constraints, supports remote retry limits, and
propagates cooldown retry-after metadata across exhausted rounds.

Move Antigravity upstream retries under conductor ownership to avoid
double-consuming retry attempts. Update configuration comments and add
coverage for Home retry rounds, cooldown handling, pinned credentials,
and legacy dispatcher compatibility.
2026-08-22 01:19:58 +08:00
Luis Pater
85e7add6ad feat(models): add Gemini 3.7 Flash model registrations to model registry
Closes: #5137 #5046
2026-08-21 22:51:45 +08:00
Luis Pater
1d5b7612c6 fix(cliproxy): add protocol-aware plugin executor usage parsing for response and streaming payloads
Closes: #5122
v7.2.138
2026-08-21 13:05:54 +08:00
W ARELIK
4053c026e7 fix(executor): sanitize thought signatures in Gemini and Gemini Vertex executors (#5110)
Ensure all Gemini and Gemini Vertex execution and token count pathways invoke SanitizeGeminiRequestThoughtSignatures before dispatching upstream requests. This prevents raw non-Gemini (e.g. Claude CAIS) thought signatures from leaking to upstream Gemini endpoints while preserving valid native protobuf signatures and setting appropriate validator bypass sentinels for function calls.

Co-authored-by: W ARELIK <warelik@WARELIK-MB.local>
2026-08-21 10:57:03 +08:00
Luis Pater
b1c000590b fix(gemini): include empty annotations/logprobs in response.output_item.done message content
Closes: #5116
2026-08-21 04:16:08 +08:00
Luis Pater
a8693c70eb Merge pull request #5124 from YogaSakti/fix/xai-response-incomplete
fix(xai): treat response.incomplete as terminal success (#5113)
2026-08-21 04:05:56 +08:00
Luis Pater
68e96c2716 fix(openai): map max_completion_tokens to Antigravity maxOutputTokens
- Add `max_completion_tokens` fallback handling in OpenAI→Antigravity request conversion.
- Keep `max_tokens` as the preferred source when both fields are present.

Closes: #5108
2026-08-21 03:52:26 +08:00
Luis Pater
5b232e3e98 fix(gemini): generate deterministic sequential IDs for Gemini tool call pairing in Codex/Claude conversions
Closes: #5107
2026-08-21 03:21:55 +08:00
Luis Pater
3db591eecd fix(gemini): preserve Gemini thought signatures in non-stream Claude conversion
Closes: #5106
2026-08-21 03:04:12 +08:00
Luis Pater
8eb3ac2e03 fix(openai): fallback to reasoning when reasoning_content is missing in response conversion
Closes: #5105
2026-08-21 02:41:37 +08:00
Luis Pater
aa5dccc236 fix(claude): use message.reasoning_content for converted thinking output
Closes: #5104
2026-08-21 02:16:01 +08:00
Luis Pater
42d8e746e5 fix(claude): avoid long global cooldowns for Fable-only 7d_oi rate limits
Closes: #5101
2026-08-21 02:02:46 +08:00
Yoga Sakti
9d6b5cdd16 fix(xai): treat response.incomplete as terminal success (#5113)
The xAI executor only switched on response.completed, so any turn that
ended with the spec-correct response.incomplete terminal event fell out
of the loop. Non-streaming requests were reported to the client as a 408
("stream disconnected before response.completed") even though the
upstream request succeeded, and because 408 is retryable it burned
credential rotations against a healthy pool. Streaming requests forwarded
the terminal event without patching the collected output items or
publishing usage.

Accept response.incomplete alongside response.completed in both paths,
mirroring the Codex executor, and keep the reasoning replay cache gated
on response.completed since a truncated turn has no replayable state.
2026-08-20 23:52:09 +07:00
sususu98
4b9d404fb0 feat(codex): add opt-in stream bootstrap buffering and overload failover (#5115)
* feat(codex): add opt-in stream bootstrap buffering

The upstream smuggles capacity rejections into an HTTP 200 stream. The
handshake events arrive normally and only a later event carries
{"error":{"type":"service_unavailable_error","code":
"server_is_overloaded"}}. By then the executor has already handed the
first chunk downstream, the response is committed, and the conductor can
no longer retry on another credential, so the request fails even though
other credentials were available.

When codex.stream-bootstrap-buffering is enabled the executor holds back
the handshake events until it can tell whether the stream carries real
output or a rejection. An overload rejection then fails the attempt
before any chunk is delivered, letting the conductor retry on another
credential; every other terminal failure is flushed in order and
delivered in-stream exactly as before.

Detection uses an event-type allow-list rather than a fixed count. On the
websocket transport codex.rate_limits and codex.response.metadata arrive
before response.created, making the first generated event the fifth
frame, so a small counter would release the stream before the rejection
is visible. Buffering is bounded and hitting the bound degrades to the
original unbuffered behaviour.

Two details are load-bearing. The error must be returned synchronously:
delivering it as the first stream chunk makes ExecuteStream downgrade it
into a committed 200 and the status is lost. And the websocket path must
not signal an upstream disconnect for a rejection it intends to retry,
because the downstream handler closes the client connection on that
signal and the retry would have nowhere to deliver.

The 503 status is produced only on this path rather than in the shared
codexTerminalFailureStatus mapping, so disabling the feature restores the
previous behaviour exactly, including cooldown classification and
retry-after parsing.

Defaults to false: response headers are withheld until generation
starts, which can trip client or reverse-proxy read timeouts.

* test(codex): pin bootstrap overload failover through the conductor

Executor-level tests cannot show what the client finally receives. These
exercise ExecuteStream end to end to pin three properties that are easy
to regress:

- consecutive overloaded credentials are skipped until one serves the
  request, and retries are capped by max-retry-credentials rather than
  multiplying with request-retry
- exhausting the pool surfaces the upstream status instead of a
  committed 200 stream
- with buffering disabled the rejection stays an in-stream error on a
  committed stream, which is the behaviour the feature must preserve

The third case also documents why the executor returns its error
synchronously: an error arriving as the first stream chunk is wrapped and
downgraded into a committed 200, silently losing the status.
2026-08-20 21:31:53 +08:00
Luis Pater
92d96e0b72 fix(cliproxy): support base_URL-only config credentials and skip stale auth headers
- Preserve API key entries with empty `api_key` when `base_url` is configured, and extend config dedupe/ID logic to include base URL, proxy, prefix, and headers so identities are stable.
- Update config/auth handling so `auth_kind=apikey` is treated as config API-key auth even without an `api_key` field, enabling base_url-only credential records.
- Ensure Gemini/Codex/XAI request path clears `Authorization`/provider auth headers when token is empty to avoid leaking unrelated auth state.
2026-08-20 15:19:07 +08:00
Luis Pater
556328c122 feat(gemini): add namespace-aware OpenAI Responses tool resolution and custom tool call conversion
- Add shared tool descriptor collection and winner selection for Responses tools (top-level vs `additional_tools`, direct vs namespace child, and ordering rules).
- Introduce sanitized Gemini function name mapping with collision disambiguation and 64-char-safe truncation.
- Build forward/reverse tool identity maps for restoring original tool identity (`name`, `namespace`, `custom`) during translation.
- Update Gemini→Responses streaming conversion to emit proper custom tool call events and identity-aware function call events.
- Add helpers for translating `tool_choice` to Gemini config and unwrapping custom tool input payloads.

Closes: #5088
2026-08-20 13:47:15 +08:00
Luis Pater
4874971764 fix(cliproxy): add warn-level diagnostics for auth cooldown and upstream execution failures
Closes: #5085
2026-08-20 03:40:46 +08:00
Luis Pater
9dc51b1f87 feat(cliproxy): add OAuth request-scoped error rules support
- Add `oauth-request-scoped-errors` configuration with normalization, sanitization, and YAML management persistence/hot-reload hooks.
- Route request-scoped error classification to use per-provider rules only for OAuth auth entries.
- Add config diff reporting and management CRUD endpoints for `oauth-request-scoped-errors` (get/put/patch/delete) with input sanitization.

Closes: #5085
2026-08-20 02:55:49 +08:00
sususu98
85d2faddd1 fix(claude): preserve native subagent and environment headers (#4982) (#5084) v7.2.137 2026-08-20 00:30:41 +08:00
sususu98
8aa6868d0d fix(claude): support setup-tokens and gracefully handle 403 OAuth profile errors (#4983) (#5083) 2026-08-20 00:15:31 +08:00
sususu98
788e9b7928 fix(claude): restore tool_search_tool_result references and recognize advisor/agent server tools (#5044) (#5082)
- Add bidirectional remapping for nested tool_references inside tool_search_tool_result across non-stream, SSE stream, and multi-turn message history.
- Add advisor_ and agent_toolset_ to IsClaudeServerToolType to prevent schema stripping and MCP aliasing on native Anthropic server tools.
- Wrap MCP alias restoration errors in claudeMCPAliasRestoreError with IsRequestScoped() bool to avoid cooling down healthy OAuth credentials.
- Add unit tests for tool_search_tool_result remapping, error variants, server tool recognition, and error scoping.
2026-08-19 22:29:51 +08:00
Luis Pater
ec105dac94 fix(cliproxy): handle responses/compact auth cooldowns and fallback semantics
- Add compact-specific error classification to mark transient/non-credential failures as availability-neutral instead of triggering cooldown penalties.
- Stop auth fallback immediately on compact request-fault errors (e.g., bad/not-found/unsupported request errors) and return the upstream compact error.
- Preserve existing cooldown behavior for auth/credential faults (`401`, `403`, `429`) while allowing non-auth compact failures to fail fast without tainting normal traffic routing.

Closes: #5031
2026-08-19 22:05:28 +08:00
Luis Pater
2005788fc3 fix(codex): filter out prompt_cache_retention in OpenAI→Codex responses request conversion
Closes: #5068
2026-08-19 21:29:03 +08:00
sususu
ac0d1888c0 fix(gemini): strip 'encrypted' metadata from tool parameters schemas (#5065) 2026-08-19 19:13:56 +08:00
sususu
5fef17e2ec fix(claude): pass incoming headers when applying custom headers in caller-owned mode 2026-08-19 18:58:47 +08:00
sususu
0f69f09a70 fix(logging): exclude HTTP 499 and client cancellations from forced error logs 2026-08-19 18:58:47 +08:00