Repository navigation
chore: sync upstream through ad8bdd3f - #8
Merged
Merged
Conversation
- Populate Detail.ResponseServiceTier from usage.speed in parseClaudeUsageNode so non-streaming and streaming Claude usage records carry the billed response speed tier. - Add regression tests verifying non-streaming usage.speed extraction and retention across message_start and message_delta stream events. Closes: router-for-me#6884
…cancel tests - Add a loadCleanupDoneHook callback in pluginhost.Host so canceled plugin load tests wait until the in-flight load token is cleared after client shutdown. - Drain dataChan after canceling the context in TestHandlerPluginExecutorPublishesStreamCancellation before closing the chunk channel to avoid racing ctx.Done() against normal stream EOF. Closes: router-for-me#6885
- Add DecodedBody to FrontendAuthRequest and populate it on routes decoded by ReadRequestBody while preserving raw Body and Headers. - Enforce pre-auth zstd window, decoded size, coding layer, and concurrency bounds, keeping decode slots held until guarded RPC calls complete. - Add regression tests covering zstd decoding, route filtering, size limits, RPC marshaling, and canceled RPC slot lifecycle. Closes: router-for-me#6886
… and function tools - Set toolConfig.includeServerSideToolInvocations to true in the Gemini OpenAI Chat Completions and Responses request translators when built-in tools are emitted alongside functionDeclarations. - Strip includeServerSideToolInvocations in the Antigravity Responses request translator where it reuses ConvertOpenAIResponsesRequestToGemini so Antigravity requests never carry the unsupported parameter. Closes: router-for-me#6892
…ex client requests - Add request-aware helper functions (`IsCodexClientRequest`, `IsCodexUseSIWCForRequest`, `codexCredsForRequest`, etc.) to detect Codex client user agents and bypass `use_siwc` settings accordingly. - Update Codex HTTP, streaming, WebSocket, and conductor execution flows to evaluate credentials and routing rules against the incoming request context and headers. - Add comprehensive regression tests (`TestCodexExecutorCodexClientIgnoresUseSIWC`) covering client identification, credential isolation, default URL resolution, and WebSocket session reuse. Closes: router-for-me#6833
Negotiate the cpa_latency_swap_v1 capability during cluster balance registration to support latency-aware node swaps. Sample active subscription RTT with tagged PING frames without extending heartbeat deadlines, report smoothed latency history to Home, and probe candidate nodes with per-cycle budgets and failure backoff. Snapshot TLS settings under lock so probe certificate loading does not block client operations.
feat(home): add cluster latency telemetry and probing
…e response translator - Translate streaming and non-streaming Codex message output items with phase "commentary" into unsigned Claude thinking blocks while keeping final_answer and phaseless messages as text blocks. - Reset HasTextDelta across message output item boundaries so done-only message fallbacks are not skipped after earlier streamed message items. - Preserve pending reasoning signatures when closing commentary thinking blocks so encrypted_content remains isolated to reasoning items. Closes: router-for-me#6895
… schemas - Restrict whole-object empty argument normalization and parameterless classification to schemas that explicitly forbid additional properties. - Defer emitting empty tool_use input deltas in Gemini and Antigravity streaming translators until tool completion so continuation chunks do not concatenate duplicate or empty objects. Closes: router-for-me#6898
- Reset parallel function-call group tracking in SanitizeGeminiRequestThoughtSignatures and geminiContentsThoughtSignaturesNeedSanitize when a non-thought part intervenes so the next functionCall retains its compatible signature or receives the bypass sentinel. - Align ValidateGeminiThoughtSignatures with the same parallel-group boundary rule and add regression tests for tool calls separated by text parts. Closes: router-for-me#6911
- Populate inputTokenLimit and outputTokenLimit in Home Gemini model responses when positive token limits are available, and backfill missing metadata across duplicate Home catalog entries. - Fall back to ContextLength and MaxCompletionTokens when converting registry models for the Gemini handler so catalog entries using generic limit fields expose Gemini token limits. Closes: router-for-me#6914
…rompt blocks Map Gemini and Antigravity safety/filter/malformed finishReason values (SAFETY, RECITATION, BLOCKLIST, PROHIBITED_CONTENT, SPII, IMAGE_SAFETY, MALFORMED_RESPONSE, MALFORMED_FUNCTION_CALL) to non-normal terminal states across OpenAI Chat Completions, OpenAI Responses, and Claude translators, and ensure Gemini OpenAI streaming emits cached finish reasons even when usageMetadata arrives separately or is absent. Also surface candidate-less promptFeedback.blockReason responses in Gemini and Vertex executors as explicit 502 errors while preserving usage reporting, and enforce finishReason truncation checks for OpenAI streams. Fixes router-for-me#6906
- Preserve root and nested reference conjunctions without changing sibling evaluation scope. - Prevent JSON Schema cleanup from weakening retained conjunctions. - Add regression coverage for reference constraints and Gemini translation paths. Closes: router-for-me#6897
…covery - Add explicit bulk string length, array count, and line length limits to prevent integer overflows and buffer exhaustion. - Enforce cumulative byte budgets on incoming RESP arrays and frame payloads. - Protect protocol multiplexer and Redis command readers with panic recovery and graceful error handling.
… usage - Preserve separate-reasoning and subset token breakdown semantics in MergeStreamUsageDetail instead of unconditionally rebuilding merged stream usage with independent cache and inclusive reasoning rules. - Add regression tests covering cumulative, identical, and partial Interactions stream usage merges as well as end-to-end plugin executor stream usage reporting. Closes: router-for-me#6925
…wrap Redis connections with cancelable dialer - Expand repository corruption checks in gitstore to recognize missing index files and packhandle errors. - Wrap Redis client dialers in cluster latency and balance probes to return cancelable plugin sync connections.
…eam call indices - Use stream-wide tool call indices in Gemini OpenAI chat response translation and preserve explicit upstream tool call IDs across stream and non-stream responses. - Bind preceding turn thought signatures to unsigned function calls, mark completed non-stream candidate payloads as terminal, and clone request payloads before envelope mutation. - Fall back to context API keys for reasoning replay caller isolation when explicit caller scope metadata is absent. Closes: router-for-me#6825
- Strip standard and credential-like headers from plugin HTTP callback requests whenever a redirect chain changes scheme, host, or port across both default and wire-profile client paths. - Normalize default HTTP/HTTPS ports when comparing redirect origins and delete matching header map keys directly to handle non-canonical header casing across multi-hop redirects. Closes: router-for-me#6936
- Route cross-format plugin executor count_tokens responses through sdktranslator.TranslateTokenCount when a valid token count and registered token-count transformer exist. - Add sdktranslator.HasTokenCountTransformer and fallback handling so same-format replies, unrecognized payloads, and custom response translators retain existing behavior. Closes: router-for-me#6938
- Add optional retry_after_seconds to pluginabi.Error and preserve it in rpcError and structured stream error callbacks. - Expose RetryAfter and SafeResponseHeaders on rpcError with duration overflow clamping so auth cooldowns and HTTP responses honor upstream retry hints. - Allow auth.SafeResponseHeaders to extract Retry-After headers from errors implementing SafeResponseHeaders. Closes: router-for-me#6937
…balance RPCs - Replace the select-based cancellation goroutine in pluginSyncCancelableConn with context.AfterFunc and close the underlying transport before outer Close when the context is canceled. - Abort newly dialed rebalance and latency probe connections immediately if the context expires during dialing. Closes: router-for-me#6946
- Apply helps.NewPayloadFinalizer once in prepareExecutorCall after translating requests to the plugin input format so Execute, ExecuteStream, and CountTokens honor configured payload rules. - Match rules on the suffix-free model name while preserving the plugin request model, canonicalize source format aliases, and use the request root for Antigravity envelopes. Closes: router-for-me#6939
- Apply canonical thinking normalization, suffix stripping, and plugin model metadata fallback in prepareExecutorCall across Execute, ExecuteStream, and CountTokens. - Resolve plugin-registered ThinkingApplier by provider key before format fallback and validate unknown thinking suffixes on non-native-Responses models. - Run thinking normalization before NewPayloadFinalizer so user payload rules act as the final host-side mutation. Closes: router-for-me#6940
…ilenames - Sanitize backslashes and parent-directory sequences in request log filenames to prevent directory traversal attacks on Windows. - Add strict validation in `createUniqueLogFile` to reject invalid or unsafe filenames. - Ensure all generated log files remain strictly within the designated logs directory.
- Remove Claude Proxy VSCode and ZeroLimit references from README.md, README_CN.md, and README_JA.md.
…m v8.0.42 - Defer context cancellation in TestCancelableConnClosesUnderlyingTransportWhenCloseRacesCancel to satisfy go vet lostcancel across all control flow paths. - Remove the unused streamBridgeStream.close wrapper left behind after the closeWithError refactor in internal/pluginhost. - Annotate shared "gin" string context keys in TestIssue6825SDKCallerReplayIsolation with nolint:staticcheck directives. Closes: router-for-me#6953
…er interceptor rewrites - Resolve the bound duplex turn model from request metadata (`RequestedModelMetadataKey`) before falling back to the initial payload and upstream model so request interceptors that strip or rewrite `model` do not alter per-turn authorization. - Match explicit continuation models against the bound client model in `processCreatePayload` so continuations naming the client alias proceed in place without triggering replay. Closes: router-for-me#6952
… enforce bound principal - Guard gin.Context identity writes in authenticateResponsesWebsocketTurn behind updateRequestContext so executor-side duplex turn checks do not mutate a shared or recycled gin.Context. - Return the authenticated principal and reject duplex turns in WithWebsocketTurnAuthorizer with 401 when the re-authenticated principal differs from the stream's bound principal. Closes: router-for-me#6949
- Retain file snapshot bindings on cached and queued copies in dispatchPersistedAuthUpdateWithRevision so delayed login snapshots stay fenced against concurrent disk updates and match discarded-snapshot rereads. - Track persisted auth update revisions in the watcher so full scans still reread file-backed auths persisted during an in-flight scan even when their snapshot binding is retained. - Add regression tests for delayed login hooks racing operator disables, subsequent config reloads on incomplete files, and bound login snapshots persisted during a scan. Closes: router-for-me#6951
- Fall back to schema prompts for Antigravity Claude 5.5 while preserving unrelated request settings. - Normalize unsupported forced tool choices before thinking preparation in direct Claude execution and token-count paths. - Add regression coverage for schema integrity, model boundaries, retries, and final payload rule precedence. Closes: router-for-me#7000
- Route bare text and media blocks in a top-level interactions input array through the existing user content converter so images and files are no longer dropped on the Antigravity path. - Keep envelope and explicit-role items on the step dispatch so step-form requests, native parts, and system/developer turn accounting stay unchanged. Closes: router-for-me#7008
Validate draft TXT values and RFC 3986 paths without legacy schema mixing; preserve first-key-wins and legacy base-path compatibility. Validate RFC 6335 names, filter unusable addresses, and display scoped IPv6 and WebSocket URLs. Replace the single-packet browser with per-interface RR caching, source validation, TTL and cache-flush handling, PTR maintenance and known-answer suppression. Add deterministic split-order, capacity, expiry, scope and schema regression tests.
…wn and failover - Tag locally synthesized missing-finishReason failures as stream-truncated in the Gemini and Vertex executors, and carry that classification through the auth manager so it skips credential cooldown and stops cross-credential replay while the public 502 and partial usage are preserved. - Carry the truncation classification through usage reporting and the Home queue payload so Home-side schedulers also skip the spurious cooldown, and add regression coverage for both the manager and usage paths. Closes: router-for-me#7005
…tf-draft feat(discovery): align LAN discovery with IETF AI gateway draft
Vertex serve paths emit the Tink primitive output directly as the whole thoughtSignature (0x01 prefix + 4-byte key id + ciphertext) instead of the protobuf field-2 wrapper used by AI Studio and Antigravity, so every Vertex Gemini signature was misclassified and rewritten to skip_thought_signature_validator (router-for-me#7007). - add GeminiThoughtSignatureEnvelopeBareTink with a bounded structural check (prefix byte + key id + 16-byte auth-tag floor) - register the 0x01-derived 'A' first char in the self-describing prefilter - cover detection, replay preservation, floor rejection and cross-family non-claims with synthetic fixtures - document envelope precedence in the Kimi ordering test; move the xAI cache seed off the 0x01-colliding seed 14
Live replay showed Antigravity (cloudcode-pa) and AI Studio (generativelanguage) reject Vertex bare-Tink thought signatures with 400 "Corrupted thought signature", while Vertex accepts them natively. After recognizing bare-Tink as a Gemini envelope, history issued by Vertex and routed to those endpoints was replayed verbatim and failed. - add SanitizeNonVertexGeminiRequestThoughtSignatures, which treats bare-Tink as incompatible: the first functionCall in a group gets the bypass sentinel and other parts drop the signature - use it in the Antigravity, Gemini API and AI Studio executors; the Vertex executor keeps the preserving sanitizer - cover the endpoint split in the signature package and with mocked upstream bodies for the Gemini API and Antigravity executors
- Remove APIMart sponsor entries from README.md, README_CN.md, and README_JA.md. - Delete associated sponsor image assets for APIMart.
…delete-missing-nocopy perf(thinking): skip document copies when deleting absent fields
… retry hint - Classify Codex turn-rate and model-capacity 429s as transient per-model rate limits via a new executor contract, honour upstream Retry-After headers behind quota resets, and cool only the reporting model without quota labelling or exponential backoff. - Carry the trusted retry deadline to terminal clients and retry scheduling across direct, streaming, bootstrap, and Home paths, keeping Home aggregated deadlines authoritative over per-attempt hints. Closes: router-for-me#7017
…to client models - Add `allow_only_codex_cloud_agent_orchestrator` and `allow_only_chatgpt_workspace_executor` configuration fields to Codex client model definitions.
Without a protobuf wrapper, the ciphertext after the Tink prefix byte is indistinguishable from uniform random bytes. Matching only the 0x01 prefix byte claimed about 1/256 of unenveloped payloads as Gemini: xAI encrypted_content starting with 0x01 was then rejected by the Grok validator and dropped from replay, and Kimi signatures were misclassified. - require the observed Vertex key id (8f3d6b5f) in addition to the prefix byte; a rotated key falls back to the bypass sentinel, which is the behavior before bare-Tink recognition - expose IsGeminiVertexBareTinkSignature and scope the Gemini Interactions sanitizer: the public endpoint drops bare-Tink thought steps, the Vertex Interactions endpoint keeps them - restore the xAI seed and Kimi ordering tests that had been adjusted around the false positive, and add regressions for a 0x01-leading Grok payload and an unknown key id
…-thought-signature-7007 fix(signature): recognize and scope Vertex bare-Tink Gemini thought signatures
- Strip SSE data prefixes and ignore control lines before initializing stream state. - Cover translated content, usage, and completion across vertex authentication paths. Closes: router-for-me#7025
…aqs-channel-id fix(signature): do not reject Antigravity CAQS signatures by channel ID
…fix registration - Rewrite non-empty ModelInfo.Name values in applyModelPrefixes using rewriteModelInfoName so Gemini model listings and detail lookups include configured channel prefixes. - Add regression tests covering prefixed model name rewriting and end-to-end Gemini model list and detail endpoints. Closes: router-for-me#7038
…r model catalogs - Add on-demand model catalog refresh functions in internal/registry with generation and sequence fencing, policy boundary checks, and immediate provider refresh notifications. - Expose POST /v8/management/routing/model-definitions/refresh and POST /v8/management/models/refresh to trigger catalog refreshes and report resolved sources and changed providers. Closes: router-for-me#7039
…isconnect Keep the client's /v1/responses websocket open when an upstream Codex websocket drops during or between turns, report correlated non-closing error frames without replaying in-flight turns, fence pre-loss queued input across handler and executor boundaries, and preserve pinned credential affinity across Home turn releases. Closes: router-for-me#7028
…e bare patches - Attach content-free log diagnostics to Devin apply_patch 502 rejections with fixed reason categories, argument byte counts, prefix shapes, and parse error classes. - Buffer and recover complete, well-framed bare Codex patches from Devin invalid_json_str arguments via applypatch.WrapInput after a clean EOS trailer in streaming and non-streaming execution. - Keep truncated streams, trailer errors, mixed argument sources, and malformed patches fail-closed without exposing patch content. Closes: router-for-me#7046
- Build un-defaulted original request payloads for xAI image generation and edit handlers and propagate them via execution context so payload default rules can distinguish omitted client fields from built-in defaults. - Pass normalized original requests into the xAI image executor payload finalizer and report finalized response_format values back to handlers via metadata callbacks across streaming and non-streaming responses. - Add unit and handler regression tests covering payload default, default-raw, and override rules for xAI image endpoints. Closes: router-for-me#7048
…onversion Convert structured Vertex functionCall.partialArgs fragments into OpenAI Chat Completions, OpenAI Responses, and Claude Messages streaming tool argument deltas while preserving call identity, nested JSONPath assembly, string continuations, thought signatures, placeholder argument cleaning, and incomplete-stream guards. Fixes router-for-me#7043
…losing downstream When an upstream Codex WebSocket returns an early 429 usage_limit_reached (via an error or response.failed frame) before any downstream payload chunk is emitted, notifying UpstreamDisconnectChan caused the Responses WebSocket handler to close the client connection and cancel the request context before the conductor could fail over to another eligible credential. Suppress downstream disconnect notification on pre-output upstream WebSocket errors and treat bootstrap usage-limit terminal failures as failover-eligible while bootstrap buffering is active, allowing the conductor to retry another credential on the same downstream WebSocket connection. Fixes router-for-me#7051
…usting descriptors Defer eager request body reads and temporary file creation until after authentication or over the 1 MiB in-memory threshold, expire read deadlines and close connections when responses finish with unconsumed request bodies, bound HTTP header and unauthenticated RESP setup reads, and retry transient EMFILE/ENFILE accept errors with exponential backoff. Fixes GHSA-j4xx-x47j-7h54
…t logging - Cap captured request body zstd decompression to max-request-body-bytes or 32 MiB when no smaller limit is configured, and remove the unbounded decode helpers. - Restrict the request-log zstd decoder to concurrency 1 and an 8 MiB maximum window so frames declaring oversized windows fall back to logging raw bytes. - Add regression tests covering unconfigured limits, single-segment window bombs, and oversized zstd windows. Closes: GHSA-4w5v-m7vx-jpmh
…sponse compression
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Merges 82 upstream commits from router-for-me/CLIProxyAPI through ad8bdd3 into the fork. They include response compression, LAN discovery, Devin and Codex catalog updates, request-logging hardening, and OAuth session proxy fixes.
The fork's audio transcription, live dictation, quota dashboard, and README additions are preserved. There were two conflicts:
internal/api/middleware/request_logging.go: upstream replaced the request-body capture logic. The fork's audio exclusion now lives in anisAudioTranscriptionRequesthelper. Upstream also added a deferred error-only capture path, so that path now skips audio routes too. A regression test covers it.internal/store/gitstore_test.go: upstream landed its own fix for the packfile-corruption test, so this takes upstream's version and drops the fork copy.One follow-up: upstream's new response-compression middleware writes response headers after the handler chain returns, so
TestTranscriptionHTTPStackTraceno longer saw the auth middleware frame. The test now sendsAccept-Encoding: identity, which keeps its originalAuthMiddlewareassertion. Response compression has its own tests.Reviewed independently by Opus 5.5 and GPT 6.1 Sol. Neither found a defect in the conflict resolutions or a path that logs audio. Opus 5.5 also ran an end-to-end log check with full and error-only logging and 100 B and 3 MiB audio. The only finding was that a test check was too weak, which is fixed in d3868c8.
Validation:
go build -o test-output ./cmd/servergo test ./...: every package passes except 10 tests that fail the same way on pureupstream/main, so this merge doesn't cause them. They are stale codex/devin catalog expectations after upstream's catalog refresh, an unreviewed translator write in the nocopy invariant test, a Devin apply_patch diagnostic test, and Windows-only mDNS discovery./v1/audio/transcriptionsreturns 401 without a key, returns validation errors with a key, and returns 503 when no Codex OAuth is available. No audio bytes showed up in the error logs.Land with a merge commit to preserve upstream ancestry for future syncs.