Commit Graph

3455 Commits

Author SHA1 Message Date
Luis Pater
745fb38dbb chore(models): update GPT-5.6 context limits in registry metadata
- Raise GPT 5.6 Sol/Terra/Luna `context_length` values to `921000` in `internal/registry/models/models.json`.
- Update matching Codex client model settings to `context_window: 272000` and `max_context_window: 921000` in `internal/registry/models/codex_client_models.json`.
2026-08-17 12:48:09 +08:00
Luis Pater
b8fbe70b37 fix(auth): stop old selectors when replacing manager selector and harden cache stop concurrency
- Add `isSameSelector` using type-aware comparable checks to avoid unnecessary selector replacement.
- Update `Manager.SetSelector` to:
  - serialize swaps with a dedicated selector mutex,
  - no-op when replacing with the same selector instance/type,
  - stop the previous selector when it implements `StoppableSelector`.
- Protect `SessionCache.Stop()` with `sync.Once` and nil-check to make repeated/concurrent stops safe and idempotent.

Closes: #5018
v7.2.134
2026-08-16 22:28:45 +08:00
Luis Pater
75e2454e72 docs(readme): remove obsolete ecosystem links for PPAP and Alex
- Remove the **Playful Proxy API Panel (PPAP)** and **Alex** entries from `README.md`, `README_CN.md`, and `README_JA.md`.
- Keep the remaining project list and note section unchanged.
2026-08-16 22:03:00 +08:00
Luis Pater
00c4377a21 fix(auth): share session affinity across model variant suffixes
- Canonicalize model IDs when building session-affinity cache/fallback keys so variant suffixes (for example thinking modes) map to the same binding.
- Normalize model values from result metadata/on-result release paths to release and rebind bindings consistently across canonical model keys.

Closes: #5016
2026-08-16 21:55:50 +08:00
Luis Pater
aa10847e12 feat(auth): add request-scoped error action handling in conductor
- Add request-scoped error rule extraction from auth metadata or runtime provider config (including OpenAI compatibility fallback)
- Match rules by HTTP/status-code plus error body substring or regex patterns
- Support `stop`, `stop-and-cooldown`, `continue`, `continue-and-cooldown` actions with normalized validation
- Apply matched actions to execution results via request-scoped vs force-cooldown error codes and stop/continue flow control
- Introduce request-stop error wrappers/helpers for matching and unwrapping scoped stop state

Closes: #5006
2026-08-16 21:39:38 +08:00
Luis Pater
361fe95799 Merge pull request #5008 from shengyy/fix/antigravity-schema-semantics
fix(antigravity): preserve response and tool schema semantics
2026-08-16 14:45:15 +08:00
shengyy
7d55d0da0d fix(antigravity): preserve schema semantics 2026-08-16 13:00:59 +08:00
shengyy
e23395a92b test(antigravity): cover schema sanitizer semantics 2026-08-16 13:00:50 +08:00
Luis Pater
7eefab98b8 feat(claude): map OpenAI service_tier to Claude speed in responses requests
- Translate `service_tier: "priority"` to `speed: "fast"` in `ConvertOpenAIResponsesRequestToClaude`.
- Leave `speed` unset for default/absent/standard/unsupported `service_tier` values.

Closes: #5003
2026-08-16 05:36:42 +08:00
Luis Pater
92f03e68e3 fix(claude,gemini,openai): preserve upstream stream errors when no data payload is emitted
- Return buffered pending stream errors from `errChan` when the data channel closes in streaming handlers.
- Emit error response instead of silently falling back to normal SSE completion paths.
- Replace Claude’s local `pendingClaudeStreamError` usage with shared `handlers.PendingStreamError`.

Closes: #4710
2026-08-16 04:29:51 +08:00
Luis Pater
7efe0a7c11 pref(claude): keep raw Claude tool IDs for deduplication in request translation
- Use original `call_id` / `tool_call_id` values as keys for tool-result/message caches and emitted-id tracking in Claude OpenAI request translators.
- Avoid mixed sanitized-vs-raw ID lookups that could cause duplicate or missed deduplication of repeated tool outputs.
v7.2.133
2026-08-16 03:06:44 +08:00
Luis Pater
8b3b304952 perf(translator): switch response translators to batched raw-array insertion via SetRawArrayItems 2026-08-16 01:53:27 +08:00
Luis Pater
0c58c3c83d perf(translator): batch assemble translation arrays before writing JSON
- Refactor Gemini/OpenAI/Codex/Claude/Antigravity interaction and response translators to collect `parts`, `content`, `steps`, `tool_calls`, and `output` items in slices, then set each array once via `translatorcommon` helpers.
- Replace repeated incremental `sjson.SetRawBytes(..., ".-1", ...)` mutations with single-shot raw-array updates to avoid repeated rewrites.
- Keep existing step/content semantics while reducing ordering/overwrite risks when merging multi-fragment data (including thought/signature and web-search/function-call blocks).
2026-08-16 01:25:28 +08:00
Luis Pater
a581838082 fix(gemini): simplify OpenAI chat response content and choices serialization
- Emit plain text directly for Gemini→OpenAI chat responses when the message contains only one text part and no reasoning/tool/image content.
- Replace `choices` assignment via `JoinRawArray` with `translatorcommon.SetRawArrayItems` for direct raw-array insertion.
2026-08-16 00:23:47 +08:00
Luis Pater
124dab6cc1 perf(translator): batch assemble response arrays and merge multi-choice parts
- Refactor multiple OpenAI/Gemini/Codex/Claude/Antigravity/Interactions response translators to collect output elements in slices and set arrays once via `translatorcommon.JoinRawArray`.
- Fix non-stream OpenAI→Gemini part handling so fields (`reasoning`, `content`, `functionCall`) from multiple choices overlay correctly on shared parts instead of being overwritten.
- Preserve explicit empty message fields in Gemini→OpenAI chat-completion conversion (`content`/`reasoning_content`) and add tests covering empty-text and cross-choice overlay cases.
2026-08-15 23:15:50 +08:00
Luis Pater
616d1b11e5 fix(claude,gemini,antigravity): centralize tool-call ID generation and harden signature sanitization
- Add shared `GenerateClaudeToolCallID` in `common` and replace duplicated local `toolu_` generators across Claude request translators for consistent, uniform ID generation.
- Replace `bufio.Scanner`-based SSE line handling with manual newline parsing and use `JoinRawArray` for array assembly to avoid scanner buffer limits and extra wrapping allocations.
- Improve carrier/thought signature scrubbing to safely strip internal metadata only when present and detect spoofed/duplicate `thoughtSignature` keys (including raw/unicode-escaped forms) during sanitized JSON traversal.
2026-08-15 21:21:02 +08:00
Luis Pater
1ecb7df228 fix(claude): deduplicate duplicate tool outputs in OpenAI-to-Claude request conversion
- Precompute the last tool message/output per `tool_call_id` in chat-completions and responses requests, then emit only one `tool_result` per call ID at its first position.
- Use the final payload for each duplicate tool call/output and preserve attachment of cache-control metadata from the final tool item.

Closes: #4997
2026-08-15 19:34:03 +08:00
Luis Pater
c1ff55fc2f chore(models): remove GPT-5.6 Sol Work Mode registrations from model registry config 2026-08-15 19:13:39 +08:00
Luis Pater
10afcc8c77 fix(openai): propagate environment context and sanitize antigravity generation config in interaction adapters
- Normalize conversation-context fields across OpenAI↔Interactions request/response translation by mapping both `previous_response_id`/`previous_interaction_id` and resolving `environment_id` (including nested `environment.id`) in both directions.
- Forward `agent_config` through translation and, for antigravity models, route output-token limits to `agent_config.max_total_tokens` while removing antigravity-incompatible `generation_config` knobs from emitted requests.
- Preserve `environment_id` through stream state so chat-completions and responses (stream/non-stream) outputs consistently carry it in final payloads.

Closes: #4995
2026-08-15 19:09:58 +08:00
Luis Pater
f53a2b6e80 fix(gemini): merge conditional schema branches during JSON schema cleanup
- Add a cleanup pass to hoist `then`/`else` properties into the containing schema path (including nested and `allOf` cases).
- Remove `if`/`then`/`else` from the unsupported keyword list so sanitized schemas no longer retain conditional keywords.

Closes: #4984
2026-08-15 17:24:48 +08:00
Chén Mù
48d021813b Merge pull request #4994 from router-for-me/models
feat(models): add max_completion_tokens to model definitions and responses
2026-08-15 16:39:30 +08:00
Luis Pater
9169ad56e1 fix(auth): make session-affinity updates safe for rebound sessions
- Propagate session-affinity provider/model metadata through selection and execution results so affinity cleanup uses the same namespace/model keys as selection.
- Forward execution `Options` in `Result` across normal, home, and stream paths, then hook manager cooldown handling to notify the affinity selector.
- Add `Touch`/`CompareAndDelete` to session cache and switch affinity release logic to compare-and-delete semantics, preventing stale failures from deleting a session already rebound to another auth.

Closes: #4989
2026-08-15 16:37:49 +08:00
hkfires
046b59ecc5 feat(models): add max_completion_tokens to model definitions and responses 2026-08-15 16:27:57 +08:00
Luis Pater
dd214445ef feat(models): add GPT-5.6 Sol Work Mode model registrations and Codex client config updates 2026-08-15 15:34:11 +08:00
Luis Pater
e0b4956242 fix(openai): ensure Responses usage includes token detail fields
- add shared `EnsureResponsesUsageDetails` helper to patch `usage` objects with:
  - `output_tokens_details.reasoning_tokens = 0`
  - `input_tokens_details.cached_tokens = 0`
  - for both plain JSON and SSE `data:` frames, including multi-line frames
- apply the helper to OpenAI Response format outputs in non-stream and stream paths across executors/plugins so translated payloads consistently include required usage details
- update websocket/completion payload builders to emit default `usage` detail fields for prewarm/finish responses

Closes: #4985
2026-08-15 15:00:19 +08:00
Luis Pater
ac82bedfaf fix(claude): add Anthropic unified rate-limit parsing helpers
- Add new Claude rate-limit helper utilities to detect unified header-based quota rejections (5h/7d), handling case-insensitive headers and missing canonical forms.
- Compute deterministic retry duration from `Retry-After` and header reset timestamps, preferring the longest applicable unified window so cooldowns can be applied consistently.
- Introduce reusable rate-limit classification logic to distinguish header-authoritative rejections from request-scoped errors (e.g. fast-mode entitlement failures) for correct credential/model cooldown behavior.

Closes: #4874
2026-08-15 14:08:16 +08:00
mardausdennis
297139cc8d fix(claude): keep tool_result blocks first when injecting currentDate
injectClaudeCodeCurrentDate inserted the reminder at index 0 of the first user message. Anthropic requires the message after an assistant tool_use turn to lead with its tool_result blocks, so the request was rejected with 400. Advance the insert index past leading tool_result blocks, matching the existing guard in prependClaudeSystemRemindersToFirstUserMessage. Every other content shape keeps the current index-0 placement.
2026-08-15 11:45:49 +08:00
Luis Pater
203f5b1a1d fix(auth): avoid cooldown for request-scoped 401 request-faults
- Treat request-invalid/invalid-parameter 401 faults as request-scoped so auth/model cooldown is skipped.
- Export request-scoped/connection-lifecycle error codes and add helpers to explicitly create or mark request-scoped `Error`s.
- Improve request-fault detection by checking the raw message body when `Error.Code` formatting hides JSON payloads.

Closes: #4976
2026-08-15 05:46:10 +08:00
Luis Pater
810d4dddb3 Merge pull request #4360 from router-for-me/perf/skip-inactive-request-interceptors 2026-08-15 05:12:18 +08:00
Luis Pater
8b02fedec2 Merge pull request #4928 from ramapitecusment/codex/websocket-transcript-allocations-v2
perf(openai): reduce websocket transcript merge allocations
2026-08-15 04:58:38 +08:00
Luis Pater
61c4fd87f5 fix(gemini): preserve additionalProperties:false for Antigravity response schemas
- Add a sanitizer option to keep `additionalProperties: false` in response paths instead of converting it to description hints.
- Skip dropping `additionalProperties: false` in `removeUnsupportedKeywords` when response mode is enabled, while still removing non-false `additionalProperties`.
- Keep tool-schema behavior unchanged by continuing to remove `additionalProperties` and emit compatibility hints for non-response conversions.

Closes: #4961
2026-08-15 04:48:42 +08:00
Luis Pater
78f0c4079e fix(openai): mark truncated/filtered responses as incomplete and avoid finalizing partial tool calls
- Update OpenAI Responses conversion to map finish reasons (`length`/`max_tokens`/`content_filter`) to `response.incomplete` with proper `incomplete_details`.
- Propagate `incomplete` status to response, message, and function/custom tool items in both streaming and non-stream paths.
- Prevent premature completion of tool-call items when a stream ends without a terminal finish reason or with incomplete/partial tool arguments.

Closes: #4873
v7.2.132
2026-08-15 04:28:55 +08:00
Luis Pater
98c98d66be fix(codex): cache multi-agent spawn-agent model data and invalidate on updates
- Add registry generation tracking and a Codex catalog revision accessor to provide stable cache keys.
- Cache parsed model templates and rendered spawn-agent markdown, and reuse them across requests when revision/generation are unchanged.
- Invalidate/recompute caches when model registrations or catalog content change, and separate rewrite handling for spawn tool descriptions vs. message encryption stripping.

Closes: #4967
2026-08-15 03:49:56 +08:00
Luis Pater
fab077a04b fix(claude): map refusal and sensitive stop reasons to content_filter
- Map Anthropic `refusal`/`sensitive` stop reasons to OpenAI `content_filter` in Claude→OpenAI chat completion response conversion.

Closes: #4958
2026-08-15 01:19:12 +08:00
Luis Pater
6edf9c4821 fix(translator): strip nested prompt_cache_breakpoint from Codex Responses payloads
- Remove `prompt_cache_breakpoint` from `input[].content[]` items during OpenAI Responses → Codex request conversion to avoid unsupported-field rejection.
- Keep message contents and existing `system`→`developer` role conversion behavior unchanged while applying the cleanup.

Closes: #4951
2026-08-15 00:37:09 +08:00
Luis Pater
b90d8ee9eb fix(auth): preserve custom auth-file metadata during token refresh and relogin
- Added metadata merge helpers in `sdk/cliproxy/auth` to retain existing auth-file settings while excluding token lifecycle fields.
- Applied merge before saving in management handler and `sdk/auth.Manager.Login` so re-login overwrites credentials without discarding user-configured fields.
- Updated token save paths for Claude, Codex, Kimi, XAI, and Vertex to persist merged metadata payloads when writing auth files.

Closes: #4945
2026-08-15 00:07:27 +08:00
Luis Pater
8d670b98ff fix(translator): make Gemini tool call IDs deterministic and robustly match responses
- Replaced random tool-call ID generation with deterministic `call_<sha256>` IDs for stable, repeatable Gemini→OpenAI conversion.
- Switched response matching from global ordering to per-function-name queues, so same-name and interleaved tool calls are paired correctly, while honoring explicit IDs (`id`/`call_id`/`callId`) when provided.
- Added deterministic fallback IDs for orphan tool responses when no matching pending call exists.

Closes: #4939
2026-08-14 23:11:22 +08:00
sususu
bdde638c27 fix(claude): pass through caller MCP tools on alias server collision
The word-based virtual server spans only ~2048^2 names, and plausible
real MCP server names such as file_system or web_search are valid BIP-39
word pairs. When a caller's own server matched the derived one, its tools
stopped passing through and entered alias recovery instead: they were
silently restored to an unrelated proxied tool, or failed the request
with a 500 when no semantic suffix matched.

Record untouched caller MCP tool names as identity entries in the reverse
map, skip those entries when collecting virtual servers and recovery
candidates, and forward them unchanged on an exact hit. Recording is
skipped when nothing was aliased, so an untouched request still keeps an
empty reverse map and a no-op restore path.

Also warn instead of silently forwarding an original name when the alias
space is exhausted, report an empty embedded wordlist, trace the
semantic-suffix fallback because it guesses rather than fails, and build
both alias entry points through one shared constructor so the exhaustion
tests cannot drift away from the production path.

Refs #4916
2026-08-14 22:45:09 +08:00
sususu
f6f03e4de9 fix(claude): use BIP-39 words for OAuth MCP tool aliases
Replace high-entropy Base32 alias IDs with request-local BIP-39 English
words so weaker models are less likely to drift tool names. Keep a
two-word virtual server plus one-word tool ID, linearly probe wordlist
space on collision without self-overlap, and fall through to unambiguous
longest semantic-suffix recovery after a successful but wrong parse.

Fixes #4916
2026-08-14 22:45:09 +08:00
Luis Pater
7cf92793c1 fix(gemini): skip zero-token usage placeholders and always finalize stream reporters
- Add `defer reporter.EnsurePublished(ctx)` to Gemini, Gemini Vertex, and AI Studio streaming goroutines so stream reporting is always finalized on exit.
- Update Gemini usage parsing to reject all-zero `usageMetadata` frames, preventing placeholder usage events from being accepted.

Closes: #4964
2026-08-14 22:38:56 +08:00
Luis Pater
f2d272da81 fix(claude): recover OAuth tool aliases for repeated prefixes and malformed IDs
- Normalize repeated `mcp__<server>__` alias prefixes during reverse remapping to resolve stacked aliases.
- Add a semantic-suffix fallback when parsing fails, allowing unambiguous recovery from malformed tool IDs.

Closes: #4916
2026-08-14 13:52:08 +08:00
Luis Pater
7ea9c670ea feat(registry): add Gemini 3.7 Flash High model definition
- Added `gemini-3.7-flash-high` to `internal/registry/models/models.json` with completion/context limits, multimodal input/output metadata, and supported thinking levels.
2026-08-14 03:19:35 +08:00
Supra4E8C
d757063c96 fix(docs): update RunAPI registration links in README files 2026-08-13 15:21:29 +08:00
Supra4E8C
a40d0e6e9d fix(docs): update FennoAI sponsorship details and links in README files 2026-08-13 15:20:13 +08:00
Luis Pater
323b7276bc feat(registry): add model modality metadata to registry definitions
- Added `supportedInputModalities` and `supportedOutputModalities` across model entries in `internal/registry/models/models.json`.
- Filled capability metadata for text/image/audio/video-aware models (mainly Claude/Gemini-family and related provider routes), including Gemini image variants and image-generation models.
- Standardized modality descriptors for multimodal compatibility checks in model routing/validation without changing existing token or generation settings.
v7.2.131
2026-08-13 14:39:05 +08:00
Luis Pater
db35b91e2a feat(openai): add xAI Grok Imagine Image 2.0 image model support
- Added `grok-imagine-image-2.0` as a first-class xAI image base model across validation, canonicalization, and routing checks.
- Registered the model in built-in model definitions so it appears in model metadata.
- Updated image model allowlists and request validation error messaging to include the new model.
- Marked the new model as hidden in client visibility override handling.
2026-08-13 14:37:29 +08:00
Luis Pater
6f2cea9484 feat(config): add per-credential request-retry override support
Closes: #4931
2026-08-13 01:50:47 +08:00
Luis Pater
8b54db36ae fix(translator): drop Gemini hidden thought parts during request conversion
Closes: #4914
2026-08-13 01:10:04 +08:00
Luis Pater
75d2c4a4b4 fix(openai): avoid JSON copies in websocket responses tool-call repair path
Closes: #4925
2026-08-12 20:32:10 +08:00
Ramapitecus
baa11ed6dd fix(openai): match websocket item metadata case-insensitively 2026-08-12 16:52:16 +05:00