Commit Graph

3212 Commits

Author SHA1 Message Date
Supra4E8C
e8e39526b3 feat(auth): add support for credential weight parsing in auth file handling v7.2.108 2026-07-30 07:36:58 +08:00
Luis Pater
b4d94d58ef fix(cliproxy): refine Codex model resolution and credential validation
- Adjusted `resolveConfigCodexStyleKey` to include `validateIndexCredentials` for stricter credential checks.
- Enhanced logic in `buildCodexConfigModels` to handle empty model lists more effectively.
- Standardized credential matching with helper functions for improved maintainability.
v7.2.107
2026-07-30 06:53:46 +08:00
Luis Pater
1c1d8efdd5 fix(translator): correct handling of json_schema and json_object response formats
- Adjusted `responseSchema` logic to only set schema for `json_schema` type while ensuring it is excluded for `json_object`.
- Updated tests to reflect changes in `responseSchema` handling, ensuring correct validation for both response formats.
- Renamed test function for better clarity regarding `json_object` behavior.

Closes: #4667
2026-07-30 05:57:06 +08:00
Luis Pater
a2ff6914bb feat(store): enhance repository handling and corruption recovery logic
- Added safeguards against repository corruption with improved recovery mechanisms, including remote re-cloning and worktree restoration.
- Introduced fine-grained repository integrity checks and missing file restoration logic.
- Centralized repository locking with `ensureRepositoryLocked` to standardize synchronization.
- Enhanced conflict resolution during pulls with automated reconciliation of remote and local changes.
- Improved worktree and index reset workflows to handle dirty and missing paths gracefully.
- Increased robustness for garbage collection with extended grace period and recovery paths.

Closes: #4629
2026-07-30 05:46:44 +08:00
Luis Pater
2b63d6bcda refactor(util): use structured options for JSON schema cleaning
- Replaced boolean parameters with a `jsonSchemaCleanOptions` struct in `cleanJSONSchema` to improve readability and scalability.
- Updated `CleanJSONSchemaForAntigravity` and related methods to utilize the new options struct.
- Enhanced flexibility for schema transformations with fine-grained control over operations like union flattening, enum type enforcement, and metadata removal.
- Added comprehensive tests to verify correct handling of unions and enum types in schemas.

Closes: #4666
v7.2.106
2026-07-30 03:40:04 +08:00
lzt404
8cdd3f1d36 Merge pull request #4659 from router-for-me/fix/codex-api-configured-models-only
fix(codex-api): stop force-injecting built-in model IDs
2026-07-30 01:14:13 +08:00
lzt404
2c8e5ba463 fix(codex-api): stop force-injecting built-in model IDs 2026-07-30 01:03:04 +08:00
Luis Pater
4a2eb54dc6 feat(translator): group consecutive tool results in Claude request conversion
- Added logic to merge consecutive tool responses into a single user message for better grouping.
- Updated `ConvertOpenAIRequestToClaude` to track previous roles and adjust message blocks accordingly.
- Introduced a comprehensive test to validate tool result grouping behavior and content preservation.

Closes: #4656
v7.2.105
2026-07-29 23:47:37 +08:00
Luis Pater
fecebcca59 refactor(translator): overhaul function call handling in Codex response conversion
- Replaced `pendingCodexFunctionCall` with `codexFunctionCallStream` for enhanced function call tracking.
- Introduced `DeferredStreamEvents` to handle deferred event processing.
- Simplified and standardized codex function call state management with consolidated methods.
- Enhanced reasoning and thinking block handling to ensure proper closure and new block initiation.
- Removed redundant methods, improving maintainability.

Closes: #4655
2026-07-29 23:33:11 +08:00
Luis Pater
74d38e0999 feat(translator): add support for cached_creation_tokens in usage details
- Updated `OpenAIUsage` to include `cachedCreationTokens` for improved token tracking.
- Adjusted token calculations and usage mapping to incorporate `cachedCreationTokens`.
- Expanded tests to verify inclusion of `cachedCreationTokens` in usage details.
2026-07-29 22:07:24 +08:00
Luis Pater
5dedb303f1 feat(util, executor, translator): enhance Antigravity schema handling and response formatting
- Introduced `CleanJSONSchemaForAntigravityResponse` to process schemas without adding tool-specific placeholders.
- Updated `cleanJSONSchema` with `removeGeminiMetadata` parameter for improved schema control.
- Refactored Antigravity schema sanitization to handle declaration and generation paths independently.
- Mapped OpenAI `response_format` to Antigravity settings, ensuring proper response schema cleaning.
- Expanded tests to verify proper placeholder-free response schema handling and metadata preservation.

Closes: #4652
2026-07-29 17:35:29 +08:00
Luis Pater
a432d76305 feat(models): remove Gemini 3.5 Flash Lite entry from models.json
- Deleted the `gemini-3.5-flash-lite` model specification from `models.json`.

Closes: #4636
2026-07-29 16:53:33 +08:00
Luis Pater
f32291436a refactor(executor): consolidate thinking.ApplyThinking into helps.ApplyRequestThinking
- Replaced instances of `thinking.ApplyThinking` with `helps.ApplyRequestThinking` across all executors for consistency.
- Updated `applyGeminiInteractionsThinking` to accept `cliproxyexecutor.Request` and `Options`.
- Centralized logic for request thinking application to `helps` package for improved maintainability.

Closes: #4618
2026-07-29 14:14:18 +08:00
sususu98
39031ef392 Merge pull request #4645 from router-for-me/fix/home-cas-command
fix(home): use Home's CAS command instead of EVAL for replay compare-and-swap
2026-07-29 09:48:41 +08:00
sususu
20784c67ff fix(home): use Home's CAS command instead of EVAL for replay compare-and-swap
Client.KVCompareAndSwap sent Redis EVAL with a Lua script, but the Home RESP
subset does not implement EVAL, so Home replied "ERR unknown command 'eval'".
That broke the Antigravity and Codex reasoning replay caches in Home mode.

Switch the transport to Home's dedicated CAS command:

    CAS <key> <expected-exists 0|1> <expected-value> <new-value> [PX <ttl-ms>]

The semantics match the old script argument for argument, so KVCompareAndSwap's
signature and all its callers are unchanged. Omitting PX when ttl <= 0 mirrors
the script's SET-without-PX branch, which clears the TTL.

Deployments that predate CAS reject the command. Detect that by matching the
unsupported-command error, latch ErrCompareAndSwapUnsupported for the client
lifetime so later calls skip the round trip, and warn exactly once. The latch is
deliberately not carried across NewLifetime, so a Home upgrade takes effect on
the next reconnect rather than requiring a CPA restart.

Also stop replay-state failures from failing the request. A bare replay error has
no HTTP status, so resultErrorFromError does not classify it as request-scoped and
MarkResult marks the credential unavailable for that model, walking every
candidate credential until alias resolution has nothing left and returns 503. A
ledger miss is already a tolerated outcome, so degrade to "no replay this turn"
instead. The pairing failure still returns its 400.

Verified end to end against a real Home over RESP/mTLS on PostgreSQL with
Antigravity OAuth credentials: patched Home recreates the replay row through CAS
with its TTL, while a pre-CAS Home latches once, keeps returning 200 instead of
503, and records no credential error attributable to the replay path.

Refs router-for-me/CLIProxyAPIHome#79
2026-07-29 09:44:05 +08:00
Luis Pater
1778e8ce69 Merge pull request #4596 from rdself/coder/claude-stream-accept-header-v2
fix(claude): align headers with upstream streaming / 修复 Claude 请求头与上游流式模式不一致
2026-07-28 23:44:46 +08:00
Luis Pater
c9417c8ae9 feat(logging): add client request metadata extraction and propagation
- Added `ClientRequestMetadata` struct to capture client IP, `X-Forwarded-For` headers, and user agent.
- Implemented metadata extraction in HTTP handlers and propagation through context.
- Updated Redis queue plugin to include client request metadata in payloads.
- Added tests to validate metadata extraction and inclusion in request contexts.
v7.2.104
2026-07-28 16:34:15 +08:00
Luis Pater
5dcca50fd9 feat(auth): introduce weighted round-robin scheduler and credential weight validation
- Added support for weighted round-robin authentication scheduling strategy.
- Implemented credential weight validation for attributes and metadata, with strict error handling for invalid weights.
- Enhanced scheduler with smooth weighted state handling and proportional selection logic.
- Introduced tests for credential weight parsing, validation, and weighted round-robin behavior.
- Updated configuration to include `weight` field for credentials with range validation.

Closes: #4470
2026-07-28 14:23:23 +08:00
sususu98
1161a4f15f Merge pull request #4626 from sususu98/fix/4599-tool-provenance-degradation
fix(antigravity): stop killing sessions on unresolved tool provenance (#4599)
2026-07-28 12:39:49 +08:00
Chén Mù
31106e2a43 Merge pull request #4627 from router-for-me/home
feat(home): enhance membership protocol handling
2026-07-28 12:39:08 +08:00
hkfires
7f2f4a5bb8 feat(home): enhance membership protocol handling 2026-07-28 12:31:00 +08:00
sususu
a06e21b439 fix(antigravity): replay text thought signatures across context drift
A cached text signature is pinned to its part by that part's own content
fingerprint. Gemini validates a signature's own integrity and never its
binding to the surrounding history, so drift elsewhere in the conversation
cannot invalidate it. Gating the fingerprinted lookup on the context hash
only discarded reasoning the model then had to redo. The legacy positional
fallback has no such proof and stays gated.
2026-07-28 12:29:31 +08:00
sususu
d2c0c58b75 fix(antigravity): keep thought signatures when replay context drifts
Reasoning replay treated a changed history as proof that a cached thought
signature had become invalid, so a drifted context or a ledger miss dropped the
signature and left the call on the bypass sentinel. Once that happened the
damage cascaded: every later ledger item verifies its contextHash against the
restored bytes of all preceding contents, so one broken link cost the whole tail
of the conversation its reasoning.

Testing the assumption directly against daily-cloudcode-pa.googleapis.com shows
it does not hold. Gemini validates a thought signature's own integrity and
nothing else -- corrupting one byte returns "Corrupted thought signature", while
changing the system instruction, adding a tool, rewriting an earlier call's
args, rewriting a tool result, or swapping two turns' signatures are all
accepted. Only the newest functionCall group has to carry a signature at all,
and the bypass sentinel satisfies that.

Keeping the signature is worth doing rather than merely harmless: on an
otherwise identical request, replacing every signature with the sentinel raises
thoughtsTokenCount from 11-15 to 41-53, so a broken chain makes the model
re-reason from scratch.

Restore the signature on the identity-only path, and stop deleting the client's
in-band signature while degrading unresolved provenance IDs. Argument integrity
is unaffected: that is the opaque digest ID's job, not the signature's.
2026-07-28 12:29:31 +08:00
sususu
e47c43650c fix(antigravity): recover tool provenance instead of failing closed (#4599)
Since #4525 a Claude Code session against Antigravity Gemini could die
permanently with HTTP 400 "missing Claude tool provenance". The reserved
cpa_gemini_<digest> IDs live in the client transcript forever, so once the
replay ledger cannot resolve them every later request fails the same way and
the request never reaches upstream.

Live testing against gemini-3.6-flash-high confirmed four independent ways the
ledger lookup breaks, all producing the same 400:

  A  contents mutated earlier in the history  -> contextHash rejects an exact
     opaque-ID match, so proven identity is discarded along with the signature
  B  one extra system block                   -> the session key embeds the
     system lane, so the whole ledger bucket switches and comes back empty
  C  process restart or TTL expiry            -> empty bucket
  D  one mid-stream client abort              -> that turn never commits

D needs nothing but a single interrupted stream and kills the session from its
very first tool turn, which matches the reported symptom most closely. Parallel
tool calls are not the trigger; they only lengthen the history.

Split tool identity recovery from context-bound signature replay:

- antigravityFunctionCallProvenanceLocation resolves a call when the payload ID
  equals the opaque digest derived from a ledger item. That digest is
  sha256(call_id, name, args), so an exact match already proves the identity and
  the context hash adds nothing to it. Such a call is restored to its native
  id/name/args with its paired functionResponse, but deliberately stays
  unsigned - the cached signature belongs to a different history.
- Unresolved reserved IDs are now rewritten to deterministic neutral IDs rather
  than aborting the request. Pairing is preserved, untrusted signatures are
  dropped, and only genuinely malformed histories still error.
- antigravityRepairUnsignedFirstFunctionCalls re-asserts the leading-call
  signature invariant after replay, because the request-level sanitizer runs
  before it. Native signatures are never touched.

Also fixes a corruption the fail-closed check was masking: when a client changed
a call's arguments, replay inserted a duplicate native functionCall next to the
mutated one, leaving more calls than responses.

Adds forensic debug logging (hashed session keys and counts only) that
distinguishes a ledger miss from a context-hash rejection.

Verified live: happy path unchanged over 20 upstream requests and 100 parallel
call groups (0 residual reserved IDs, every group 1 native-signed + 4 unsigned);
all four failure modes now return 200; and a session survives a mid-stream abort
plus 5 further requests that previously died.
2026-07-28 12:29:31 +08:00
sususu98
f894317e90 Merge pull request #4624 from sususu98/feat/claude-cais-signature-validation
feat(signature): validate Claude CAIS reasoning signatures
2026-07-28 09:34:22 +08:00
sususu
5b2890b38c feat(signature): validate Claude CAIS reasoning signatures 2026-07-28 09:18:49 +08:00
Chén Mù
fbd77b4698 Merge pull request #4621 from router-for-me/home
feat(home): add membership takeover eligibility handling and update related tests
2026-07-28 09:00:22 +08:00
hkfires
bb43b7a30f feat(home): add membership takeover eligibility handling and update related tests 2026-07-28 08:34:43 +08:00
Randi
c405398a48 fix: align Claude headers with upstream streaming 2026-07-27 19:07:57 -04:00
Luis Pater
cade44b9cd refactor(translator): rename system_instruction to systemInstruction for consistency
Closes: #4583
v7.2.103
2026-07-28 03:44:05 +08:00
Luis Pater
20f83cae91 feat(translator): map OpenAI response_format to Gemini structured output settings
- Added `applyOpenAIResponseFormatToGemini` for translating OpenAI Chat Completions `response_format` to Gemini configuration.
- Supported automatic mapping of `json_object` and `json_schema` types to Gemini `responseMimeType` and `responseJsonSchema`.
- Updated structured output handling to pass schemas through and clean unsupported fields.

Closes: #4582
2026-07-28 03:36:30 +08:00
Luis Pater
30efd7c4fd feat(plugin): add request lifecycle plugin with interception and termination capabilities
- Implemented a Go-based dynamic library plugin for request lifecycle management.
- Added concurrency controls, keyword-based request termination, and response handling.
- Supported optional capabilities for request interception and active lifecycle termination.
- Included tests for schema compatibility, concurrency limits, and policy-based termination.
- Added build instructions and configuration details in README.
- Updated host support for lifecycle plugin RPC methods.

Closes: #4568
2026-07-28 03:22:18 +08:00
Luis Pater
61a6f08d18 feat(models): add metadata for Gemini 3.1 Pro Preview, 3.5 Flash Lite, and 3.6 Flash models
- Added detailed specifications for `Gemini 3.1 Pro Preview`, `Gemini 3.5 Flash Lite`, and `Gemini 3.6 Flash` models, including token limits, generation methods, and thought levels.
- Updated `models.json` to include entries for all three versions.

Closes: #4555
2026-07-28 02:14:23 +08:00
Luis Pater
7b233fa316 test(server): add minimal reasoning level in Codex-supported levels test 2026-07-28 01:55:34 +08:00
Luis Pater
3d5ec8628e feat(models): add minimal reasoning level to Codex client models
- Introduced a new reasoning level, `minimal`, to the `codexClientAllowedReasoningLevels` map.
- Updated response-building logic to include descriptive messaging for the `minimal` level.

Closes: #4542
2026-07-28 01:54:16 +08:00
Luis Pater
3073dab0b6 feat(models): add metadata for Gemini 3.5 Flash Lite and Gemini 3.6 Flash models
- Added detailed specifications for `Gemini 3.5 Flash Lite` and `Gemini 3.6 Flash` models, including token limits, generation methods, and thought levels.
- Updated `models.json` to include entries for both versions across relevant segments.

Closes: #4521
2026-07-28 01:21:47 +08:00
hkfires
f943926fca feat(home): improve error handling in cluster discovery and enhance GetConfig tests 2026-07-27 22:37:27 +08:00
Luis Pater
27b4660633 refactor(translator): simplify token usage metadata extraction in OpenAI responses
Closes: #4498
2026-07-27 22:07:45 +08:00
hkfires
3b4f4cf1f8 feat(home): update concurrency release logic to include takeover eligibility state in error handling 2026-07-27 21:38:44 +08:00
hkfires
8eed5f1bf8 feat(home): enhance client recovery and dispatch handling with new state management and error reporting 2026-07-27 21:10:41 +08:00
Luis Pater
6914478562 feat(config): add support for disabling model list cloaking in Claude Code
- Introduced `DisableCloakingModelList` in `ClaudeCodeConfig` to control model ID cloaking in Anthropic model list responses.
- Updated relevant APIs and handlers to respect the new configuration.
- Added comprehensive tests for enabling/disabling cloaking behavior and config-driven hot reload scenarios.
- Extended example configuration and documentation to include the new setting.

Closes: #4473
2026-07-27 18:16:41 +08:00
Luis Pater
181242b1c0 feat(translator): enhance tool output parsing with support for input_image types
- Added handling for `input_image` in `toolOutputContentPart` and updated related parsing logic.
- Introduced `hasToolOutputImagePart` to check content for image-related types.
- Improved `setToolCallOutputContent` to handle structured content with image parts recursively.
- Refined detail extraction and type mapping for `input_image` and `image_url` cases.

Closes: #4458
2026-07-27 17:54:50 +08:00
sususu98
02f15e3ca0 Merge pull request #4554 from yinkev/fix/session-affinity-native-signals
fix(auth): prefer native client session signals for affinity
2026-07-27 16:21:41 +08:00
kyinhub
c1f16b706e fix(session): reject edge control characters 2026-07-27 16:18:18 +08:00
kyinhub
c702c9ac21 fix(auth): preserve live home alias groups 2026-07-27 16:18:18 +08:00
kyinhub
a97b1ae622 fix(auth): prefer native client session signals for affinity 2026-07-27 16:18:18 +08:00
Luis Pater
e49b1cc76f feat(store): add guard for watcher-originated auth file deletions
- Implemented `guardWatcherAuthRemovalLocked` to prevent unauthorized watcher-triggered deletions of tracked auth files.
- Updated `PersistAuthFiles` to handle redundant watcher events safely after intentional deletions.
- Improved error handling for git tree and repository inspections during watcher removal validation.
- Enhanced `commitAndPushLocked` logic to perform additional checks before committing changes.
- Added comprehensive tests to validate watcher-originated deletion safeguards and correct behavior for explicit deletions.

Closes: #4438
2026-07-27 07:05:19 +08:00
Luis Pater
59aa35a434 feat(util): add NormalizeClaudeToolInputSchema for input schema normalization
- Introduced `NormalizeClaudeToolInputSchema` in `util` package to standardize tool input schemas for compatibility with Claude.
- Replaced local `normalizeClaudeToolInputSchema` implementations in translator functions with the new utility method.
- Improved handling of schema validation, union elimination, and property merging.
- Removed redundant code in response and chat-completions translators, streamlining schema normalization logic.

Closes: #4428
2026-07-27 06:06:26 +08:00
Luis Pater
8423cce2d1 feat(executor): add configurable injection of x_search tool for xAI requests
- Introduced `InjectXSearch` in `XAIConfig` to enable automatic injection of the native `x_search` tool when not explicitly declared.
- Updated `XAIExecutor` to honor the `InjectXSearch` configuration, ensuring consistent tool availability.
- Enhanced configuration handling with support for dynamic diffing to track changes in `InjectXSearch`.
- Added comprehensive tests to validate `InjectXSearch` behavior, including preparation and tool choice synchronization.
- Updated example config and documentation to outline `InjectXSearch` usage.

Closes: #4339
v7.2.102
2026-07-27 04:41:24 +08:00
Luis Pater
f329b9d10c feat(store): add PostgreSQL-backed cooldown state persistence
- Introduced `PostgresCooldownStateStore` for saving and loading cooldown states in a PostgreSQL database.
- Supported runtime cooldown state management with efficient upsert and deletion.
- Added configurable integration via `PostgresStoreConfig` and updated schema management to include cooldown-related tables.
- Included tests to validate persistence, normalization, and concurrent handling of cooldown state records.
- Enabled overriding cooldown state stores via service builder and SDK configuration.

Closes: #4254
2026-07-27 03:46:55 +08:00