For downstream websocket with CPA-mediated HTTP/SSE upstream (non-passthrough),
always merge the full conversation transcript instead of sending incremental
previous_response_id turns. Release pinned websocket auths after timeout and
gateway failures, and after WS bootstrap failover pin the successful SSE
credential so the next turn keeps merged context instead of retrying a
suspended websocket auth.
Fixes#4048
Force-mapping rewrites streaming OpenAI Responses SSE through StreamRewriter before the /v1/responses websocket forwarder. Antigravity/Gemini and Codex emit frames without reliable trailing newlines, so buffered chunks glued as ...}event:..., ...}data:..., or event:/data: without separators. The rewriter dropped pending tails and downstream WS synthesized 408 without response.completed even when upstream returned HTTP 200.
- safeReplaceGlued for }event: and }data: when data JSON is complete\n- Finish flush with glue normalization and line-wise fallback\n- Newline between pending event: and next data: line (Codex scanner lines)\n- Regression tests: Antigravity sim, Codex data lines, force-map WS forward
Use the aidev_client parenthetical suffix for default Antigravity UA and
route loadCodeAssist through the short UA. Keep onboardUser on the long UA
with google-api-nodejs-client.
Recognize model-visible output_text even when message.role is user, accept
assistant string content, and preserve raw merged text without trimming.
Always merge the adjacent visible item into native Gemini reasoning turns so
trailing output is not dropped by prefill stripping.
Build Gemini-native model contents for reasoning items when the routed model
uses the Gemini signature provider: thought summary on a thought part and the
replay signature on the adjacent visible part. Merge following assistant
visible text when it is not trailing prefill, and keep reasoning history when
stripping trailing model-authored prefill.
Extend Responses translator tests for signature compatibility and Antigravity
wrapper coverage; clarify stale replay signature expectations in executor tests.
- Added Manifest struct to encapsulate plugin metadata and installation details.
- Implemented ManifestFromRelease and ManifestFromPlugin functions for creating manifests from releases and plugins.
- Enhanced Plugin struct to include Versions and InstallPlan for direct installations.
- Introduced validation for direct install type, ensuring artifacts are correctly specified.
- Updated registry validation to support new schema version and direct install requirements.
- Added tests for parsing and validating direct install plugins, ensuring correct artifact handling.
- Introduced `disable-cooling` field in OpenAI compatibility configurations.
- Updated `PatchOpenAICompat` to handle `disable-cooling` updates.
- Refined response structure in compatibility handlers to include `disable-cooling`.
- Added unit test to validate `disable-cooling` propagation in API responses.
Closes: #4023
- Updated display names and descriptions of existing Gemini 3.5 Flash variants for better clarity.
- Introduced a new "Gemini 3.5 Flash (Medium)" variant with distinct configuration.
- Renamed "Low" tier to "Extra Low" for improved naming consistency.
Closes: #3949
Universal Chat Provider is a VS Code extension that surfaces Claude,
ChatGPT/Codex, Antigravity, Grok, and Kimi subscriptions as native
language models in GitHub Copilot Chat, using CLIProxyAPI as a fully
managed background server.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Introduced `activeRecords` and `activeRecordsFromSnapshot` to filter current plugin records more efficiently.
- Updated all instances of `Snapshot().records` across code and tests to use `activeRecords`.
- Added additional checks for `recordCurrent` and plugin identity validation in several plugin capability calls.
- Enhanced test logic to validate `activeRecords` usage and ensure consistent behavior.
* fix(oauth): force-map responses to config alias not request suffix
Rewrite client-visible model fields using oauth-model-alias Alias from config
(e.g. gpt-5.4-fast) instead of mirroring the requested model string when the
client adds thinking suffixes (e.g. gpt-5.4-fast(high)). Upstream routing
still preserves suffixes on the resolved upstream model.
* test(oauth): gate response rewrite on ForceMapping and document OriginalAlias
- Document that OriginalAlias is only applied when ForceMapping is true
- Set OriginalAlias to config alias only when force-mapping is enabled
- Add tests: no non-stream/stream payload rewrite when ForceMapping is false
* test(oauth): assert disabled force mapping response
- Introduced `model` field in `videoAuthBinding` for model tracking.
- Enhanced binding store with `setWithModel` and `getBinding` methods for binding models.
- Updated handlers to propagate execution models during video processing.
- Added tests to verify model binding, retrieval, and propagation logic.
Add OAuthModelAlias.ForceMapping to rewrite client-visible model fields in non-stream and SSE stream responses while leaving request-log upstream payloads unchanged.
- Wire config, watcher diff, and conductor execute/stream paths
- Rewrite force-mapped responses in Antigravity credits fallback paths
- Prevent buffered SSE chunks from being emitted by line-wise fallback
- Preserve thinking suffixes for same-base force-mapping aliases
- Cover codex, antigravity, kimi, and xai with live-derived fixtures and regression tests
- Document a conservative antigravity-only force-mapping example in config.example.yaml
Direct OpenAI image calls can inherit downstream User-Agent values from the Gin request context, which may trigger upstream Cloudflare 1010 blocks.
Clone inbound Codex headers for direct image requests and remove only User-Agent before applying defaults. This keeps Version, X-Codex-Turn-Metadata, X-Client-Request-Id, and Originator forwarding intact.
Expand direct image regression coverage for downstream identity headers and align edit endpoint expectations with /images/edits.
- Moved `reportHomePluginStatus` from `cmd/server` to `internal/home` as `ReportPluginStatus`.
- Updated interface and variable names for consistency.
- Adjusted imports and references in `main.go` and test files to align with the changes.
- Improved code structure for better modularity and reuse.
- Introduced `AuthKind` and `AuthSourceKind` methods for improved credential type and source classification.
- Replaced legacy fallback logic with normalized attribute-based handling in `AuthKind`.
- Consolidated metadata inspection for both API key and OAuth attributes.
- Updated calls to replace direct `AccountInfo` usage with `AuthKind` and `AuthSourceKind`.
- Enhanced unit tests to validate explicit and fallback credential resolution scenarios.
- Added NodeID field to HomeConfig for better identification.
- Updated ConfigFromJWT to populate NodeID from claims.
- Introduced new Redis keys for managing plugin status and tasks.
- Implemented RPushPluginStatus and GetPluginTasks methods in the client for handling plugin-related data.
- Enhanced Sync functionality to include detailed reporting on plugin installation and deletion tasks.
- Added error handling and reporting for plugin synchronization failures.
- Created tests for new plugin synchronization and management features.
- Improved the overall structure and readability of the plugin synchronization logic.
Add Grok-native reasoning replay for Claude-sourced xAI Responses requests. Replay state is scoped by model and session, normalized to reasoning/function_call/custom_tool_call items, and injected with the same tool-call alignment semantics used by Codex.
Include the minimal Grok encrypted_content validator needed on upstream/dev so replay cache entries cannot accept Codex/GPT, Gemini, or Claude signature shapes. Cache completed output items from HTTP, streaming, and WebSocket xAI responses.
Cover two-turn Claude replay, tool_result continuity, valid Grok cache storage, and rejection of Codex-shaped encrypted_content.
* Drop foreign encrypted_content before xAI Grok upstream
xAI Grok accepts provider-native encrypted_content as opaque replay state, but GPT/Codex reasoning signatures, Gemini thoughtSignature blobs, and Claude thinking signatures can all travel through OpenAI Responses-style reasoning.encrypted_content while remaining incompatible with xAI. Forwarding those foreign blobs to Grok causes upstream validation failures, especially when the foreign value is high-entropy enough to look ciphertext-like.
Add a Grok encrypted_content transport validator that stays conservative and shape-oriented:
- require unpadded standard base64 with no foreign characters
- reject obvious GPT/Codex gAAAA reasoning signatures before decode
- reject strict Claude thinking signatures in both official E-form and Antigravity R-form
- reject known Gemini thoughtSignature envelopes by reusing the central Gemini validator, covering Gemini 2.5 field-1 and Gemini 3.x field-2 shapes
- require decoded payloads to be long enough and high-entropy enough to look like native Grok ciphertext
- avoid decrypting, protobuf-parsing, or otherwise interpreting native Grok payloads on the hot path
Wire the validator into the xAI Responses request preparation path for reasoning and compaction input items. Invalid encrypted_content fields are deleted before the request is sent upstream, while the surrounding item is preserved and debug logging records only redacted metadata.
Extend coverage with native Grok corpus preservation, Gemini field-1/field-2 rejection, Claude E-form and R-form rejection, invalid-blob sanitizer tests, and compact/websocket replay preservation. The foreign-provider checks are deliberately narrow so high-entropy Grok blobs are not rejected merely because they look random.
* fix(xai): harden encrypted content sanitizer
- Added `ClaudeMessageSystemReminderText` to convert system content into user-readable reminder text.
- Updated translators (Antigravity, Gemini, Codex, OpenAI) to wrap `system` roles as reminders with `<system-reminder>` tags.
- Adjusted related test cases to validate reminder wrapping logic.
- Introduced `ClaudeCodeSessionID` resolution logic, preferring headers over payload metadata.
- Added `ClaudeCodePromptCache` to map sessions to stable prompt cache keys.
- Refactored existing logic to integrate `ClaudeCodePromptCache` for session-based handling.
- Included extensive unit tests to validate session ID extraction, cache reuse, and header prioritization.