Repository navigation
chore: sync 140 upstream commits while preserving Pinable runtime contracts - #6
Conversation
- Preserve explicit `output_config.effort` when `thinking.type` is enabled without budget tokens - Map output config effort to reasoning effort when translating Claude requests to OpenAI Closes: router-for-me#6183
- Add `isClaudeSonnet55Model` helper and prevent Sonnet 5 matching on Sonnet 5.5 prefixes - Include Claude Sonnet 5.5 in progress display checks Closes: router-for-me#6193
…esult - Insert the most recent thinking block between assistant web search tool results and subsequent tool use parts - Prevent upstream rejection when tool use immediately follows server tool results Closes: router-for-me#6195
…l execution - Add `Path` field to model execution requests and plugin interceptor responses - Propagate custom request paths through execution metadata - Allow image models during execution when entry or exit protocol is `openai-image` Closes: router-for-me#6196
- Log warning when credential persistence fails during registration, update, or refresh - Add `auth_id` to log field ordering and quoted fields Closes: router-for-me#6197
- Register GPT-6.1 Sol model configuration with reasoning levels and instructions
…tion - Track auto-refresh jobs with registration epochs to prevent stale or phantom pending states - Enforce bounded timeouts for Antigravity token refresh and project discovery - Manage Antigravity credits refresh tasks with epoch validation and lifecycle cancellation Closes: router-for-me#6199
…stream executor - Translate `response.failed` and `interaction.failed` events across Claude, Gemini, OpenAI Chat, and Responses formats - Lazily emit `interaction.created` in Devin executor to allow clean HTTP error status propagation on immediate Closes: router-for-me#6204
- Forward unmapped Claude OAuth MCP tool aliases unchanged instead of returning an error - Log a warning when no request-local tool match is found to prevent stream termination Closes: router-for-me#6208
- Map OpenAI Responses tool identities to valid Claude tool names within the 64-character limit - Resolve naming collisions and truncate long tool names using deterministic SHA-256 hashes - Maintain bidirectional tool mapping across declarations, tool choices, history, and response decoding Closes: router-for-me#6209
…optimization - Enable multi-agent input rewriting when model compatibility mode is active, even if `optimize-multi-agent-v2` is disabled - Ensure `agent_message` items are converted into portable user messages for third-party endpoints under API key configurations Closes: router-for-me#6233
…x clients - Detect Codex client requests via User-Agent and convert target numeric parameters to integer types - Support schemas across OpenAI functions, Claude input schema, Gemini declarations, and namespace tools - Apply normalization during executor payload processing, multi-agent request translation, and WebSocket streaming Closes: router-for-me#6237
- Defer plugin load marking until status push finalization - Allow home config worker to dequeue and apply the latest queued payload during retry loops Closes: router-for-me#6225
- Convert `true` boolean subschemas to empty object schemas `{}` for OpenAPI upstream compatibility
- Preserve boolean `false` schemas and boolean `additionalProperties` values
Closes: router-for-me#6230
- Defer intervening non-tool messages until all batch tool outputs are emitted to keep outputs contiguous - Apply responses input normalization across standard and streaming executor execution paths Closes: router-for-me#6231
- Select HTTP/2 or HTTP/1.1 transport dynamically based on TLS ALPN negotiation - Route empty ALPN and HTTP/1.1 requests through a dedicated non-pooled transport reusing the handshaken connection - Ensure uTLS connections are cleanly closed upon response completion or request failure Closes: router-for-me#6223
…tor targets - Skip normalizing tool parameter number types to integer when the target executor is Codex or Codex WebSocket - Remove tool integer type normalization from schema cleanup in native Codex execution paths to preserve reserved tool schemas - Apply tool integer type normalization only for non-Codex upstream targets with Codex client User-Agents Closes: router-for-me#6244
…dentity - Base tool integer normalization checks strictly on target executor identity rather than protocol - Add executor-aware translation helpers to pass target executor identity during request translation - Ensure non-Codex executors normalize tool integer types for Codex clients regardless of protocol
… bad gateway - Return Bad Gateway error when Codex upstream stream closes before emitting any payload - Allow failover to subsequent credentials on premature stream disconnect before output - Map HTTP 408 Request Timeout status to server_error in base error response handlers Closes: router-for-me#6247
…en counting - Pass target executor identity during Codex token counting and xAI request translation - Skip tool integer normalization when target executor is Codex during compatibility translation - Preserve number types in tool parameter schemas during token counting requests
xAI raised the minimum accepted x-grok-client-version on
cli-chat-proxy.grok.com, so every xAI OAuth chat request through the CLI
chat-proxy failed with HTTP 426 ("Your Grok CLI version (0.2.120) is
outdated"). /v1/models is not gated, so discovery looked healthy while
inference was dead.
Bump the pin to the current stable Grok CLI version (1.0.44) and record
the observed server floor in the constant's comment. Both
x-grok-client-version and the derived User-Agent ship from this one
constant.
Regression tests lock three things: the pinned version meets the known
server floor (red against 0.2.120), the two identity headers stay
derived from the same constant, and the per-auth `header:*` custom
header override still wins over the pin - the documented operator
escape hatch when xAI ratchets the floor again.
Closes router-for-me#6249
Generated-by: GLM-5.3-Flash (ZCode)
…-version-bump fix(xai): bump pinned grok client version to 1.0.44 for chat-proxy
…tion - Handle apply_patch custom tool call streaming deltas and snapshots for Responses API translation - Track and resolve step indexes, function call identities, and error states across stream events - Propagate apply_patch tool input errors and upstream failure states in stream and non-stream responses
- Add `ClientConfig` and `CodexClientConfig` structs to `SDKConfig` - Move `optimize-multi-agent-v2` and add `enable-apply-patch` under `client.codex`
…uter-for-me#6118) * docs(readme): refresh provider models and add Muse Code and Devin * docs(readme): update GPT-6.1 Sol and Claude Sonnet 5.5 --------- Co-authored-by: kdcokenny <kdcokenny@users.noreply.github.com>
…ests - Relocate caller system prompts into conversation messages when using OAuth to prevent triggering Anthropic's third-party classifier - Apply the same relocation policy to token counting requests Closes: router-for-me#6432
- Compact valid upstream JSON error response payloads to single-line formatting to ensure compatibility with SSE streams while preserving error data Closes: router-for-me#6434
…ssing thread errors - Extend `IsClaudeThreadNotFound` to identify missing thread errors from plain-text error messages in addition to JSON payloads - Implement `ResponseBody` on executor `claudeThreadNotFoundError` to supply structured JSON error payloads Closes: router-for-me#6443
…github-token feat: add global server GitHub token configuration
…y with fallback - Fetch latest @xai-official/grok client version from npm registry on startup - Periodically refresh Grok CLI version every 3 hours without multiple retries - Update hardcoded fallback version to 1.0.50 if npm registry is unreachable - Dynamically inject active version into x-grok-client-version and User-Agent headers
…arts fix(translator): stop dropping attachments and empty turns
…sponses to interactions - Track dropped attachments and reject emptied user turns during OpenAI Responses to Interactions translation - Register checked request translator for OpenAI Responses to Interactions format conversion
…dynamic-version feat(xai): dynamically fetch latest Grok CLI version from npm registry with fallback
- Pass configured proxy URL to the npm registry updater client - Validate fetched versions against strict semver and minimum server version floor (`1.0.13`) - Update default fallback client version to `1.0.46` - Manage background updater lifecycle and context via service lifecycle initialization
…rs to return errors - Update OpenAI and OpenAI Responses to Interactions request converters to return `([]byte, error)` - Register request converters directly in internal translator registry instead of sdktranslator checked requests
- Extract shared Gemini Interactions helpers for payload translation, input sanitization, thinking, and SSE streaming - Add `interactions` configuration option to Vertex credentials - Support native non-streaming and streaming Interactions API execution in Gemini Vertex executor Closes: router-for-me#6445
…requests - Introduce `sanitizeOpenAIResponsesReasoningEncryptedContentKeepForeign` to retain unknown-format reasoning signatures - Update Meta executor to preserve foreign reasoning encrypted payloads for third-party models like Muse Closes: router-for-me#6450
…v8 api - Export `NormalizeCollectionNodeStyles` to traverse document nodes and clear double quotes from string mapping keys - Apply collection style normalization before YAML marshaling in the v8 management config handler Closes: router-for-me#6451
…egistration - Use latest auth state in model registration to prevent applying stale snapshots - Reconcile and re-register auths with updated generations after batch registration tasks complete Closes: router-for-me#6453
- Intercept and process `response.interrupt` control frames immediately on the downstream websocket reader - Forward interrupts to active upstream Codex websocket sessions without starting a new turn or rewriting payload fields - Support canceling in-flight HTTP turns via local interrupt handling - Allow session-staged Home credentials to authorize interrupts Closes: router-for-me#6456
…okens - Add `thoughtsTokenCount` to `candidatesTokenCount` when calculating `usage.completion_tokens` for Antigravity OpenAI response translation Closes: router-for-me#6463
- Ignore unified reset timestamps matching overage reset boundaries to prevent cooling down credentials until monthly billing reset - Filter candidate rate limit deadlines exceeding the 7-day window limit - Treat rejected overage claims with absent or healthy shared utilization as model-scoped rejections Closes: router-for-me#6465
- Handle compaction trigger requests by generating summaries and sealing antigravity compaction capsules - Expand replayed compaction capsules into message history before translation and filter foreign compaction items - Preserve tool definitions with `tool_choice: none` or flatten tool blocks when tool definitions are missing - Support streaming compaction execution and map cache creation and read token usage Closes: router-for-me#6466
…max tokens - Use registered model `MaxCompletionTokens` limit when `max_output_tokens` is omitted, allowing limits above the 32k default - Preserve conservative ceiling for Fable models Closes: router-for-me#6468
- Automatically detach and shut down plugins that are disabled or unselected during configuration reload - Unload all active plugins when the plugin system is globally disabled Closes: router-for-me#6471
… baseline Extend existing PR path filters to cmd/server, internal, sdk, dependency manifests and smoke-helper tests so future upstream changes cannot bypass packaged-executable checks. Preserve every quality gate, platform, permission and manual-only release policy. Pin ancestry checks to fork fa10525 and upstream 6746588 after the maintained sync tool passed the server build, complete Go suite and 52 Python regressions. Final PR CI must validate this head before merge.
Remove the temporary reviewed patch transport and workflows after the maintained sync tool successfully prepared the independent candidate branch. The maintenance branch returns to its original source tree; no temporary drivers are included in PR #6 or main.
Native macOS arm64 smoke exposed an existing host-contract race: WriteHeaderNow can leave 202 buffered while the asynchronous callback immediately closes the HTTP connection. Finish the empty response with Content-Length: 0 and flush before invoking shutdown. Keep the same status, asynchronous callback, authentication, actual-loopback restriction and upstream immediate-close policy. Add deterministic IPv4/IPv6 flush-barrier tests and a real TCP immediate-close regression that prevents implicit end-of-handler flushing from hiding the bug. Repeat these regressions 50 times under the race detector in existing read-only CI. Preserve all previous smoke assertions; do not retry shutdown requests or ignore disconnected responses. Full current-head and six-platform checks must pass before merge.
The full runtime quality suite exposed TestResponsesInterruptStopsHTTPUpstream checking an atomic flag before its observing goroutine ran. Upstream intentionally writes response.incomplete before invoking cancellation; receiving that frame is not a synchronization barrier for the fixture. Signal after the executor actually observes ctx.Done, then retain the original cancellation flag, response shape and same-socket follow-up assertions. No production interruption behavior, test assertion or existing deadline is removed or relaxed. Repeat the test 100 times in the existing upstream gate and document both validation-discovered ordering fixes. This candidate must pass the complete current-head PR regression, native runtime and monolith checks before merge.
|
Latest candidate is d21ac84, tree a7371631fbd82eadfd0d9fb9b23b032859c6240d. Main remains fa10525, and the upstream recheck still resolves to 6746588. The shutdown acknowledgement fix passed both deterministic negative controls: the old implementation fails the flush-barrier and real-TCP tests, while the exact fix passes 50 repetitions under the race detector. The previously failing native macOS arm64 shutdown probe also passed. Evidence: https://github.com/PinableAgents/CLIProxyAPI/actions/runs/37891374544 A separate full-suite run on the preceding candidate exposed The current Linux amd64 artifact was independently downloaded, its ZIP digest, source commit and manifest checked, and its actual binary passed the full runtime smoke outside Actions, including v8 migration, ephemeral-key isolation/reload/non-persistence, authenticated shutdown and parent death. Binary SHA256: fcb3d5fe5e70e6db12ab222d6992f0e5afc6c3580198631767ac3cf9c7308c79. This is not live provider API validation. Final checks are still running on the latest head and must finish successfully before merge:
The temporary read-only negative-control driver has been removed from its separate maintenance branch. No temporary workflow is included in this PR. No Release, deployment, force update, permission change or historical credential use. |
Completed: upstream synchronized and merged into main
Merged using Create a merge commit as 474c2fa. Post-merge reads confirm this is
PinableAgents/CLIProxyAPI:main, whilerouter-for-me/CLIProxyAPI:mainstill resolves to 6746588. The final comparison reports behind_by=0, with that exact upstream commit as the merge base.This integrates 140 upstream commits since a270e7b, retaining original fork main fa10525 and all 32 original fork-only commits, including the preceding monolith deployment patch. The maintained sync script created real integration commit 054e75b, with the original fork and upstream as its two ordered parents.
The merge operation was bound to verified head d21ac84. Main and upstream were rechecked immediately before merging. Final main has no file differences from that head; its tree a7371631fbd82eadfd0d9fb9b23b032859c6240d matches the actual tested PR merge result 346d2c4. No squash/rebase, force push, reset, permission expansion or protection bypass.
Conflict resolution and preserved contracts
One file had two textual conflicts: cmd/server/main.go. Keep upstream's new local-model help text and registry.SetLocalModelCatalogs(localModel) initialization, plus Pinable's --parent-pid flag and hostOptions passed to the service startup. Do not restore the removed global catalog-updater helper. A separate formatting group reduces collisions around the host-only flag; no blanket ours/theirs selection was used.
Preserved host contract 1, configuration-free --version/-version probes, parent-process supervision, authenticated runtime-info/runtime-shutdown with actual-loopback checking, service-scoped in-memory ephemeral API keys, reload survival, non-persistence and non-secret principals. The isolated host_runtime.go/host_runtime_test.go and builder_runtime.go remain unchanged. Keep upstream SDK discovery initialization, provider login paths, plugin hooks, all automatically merged upstream features, and the original monolith patch and security guidance.
Two validation-discovered ordering issues resolved
Host shutdown acknowledgement: native macOS arm64 smoke exposed the existing handler closing a connection before its 202 acknowledgement arrived. WriteHeaderNow could leave the response buffered while the asynchronous shutdown callback closed active connections. Set Content-Length: 0 and flush the empty response before starting that callback. The status, asynchronous cancellation, authentication, real-loopback restriction and upstream immediate-close behavior are unchanged. No shutdown retry or ignored disconnection was added to smoke tests.
Added deterministic IPv4/IPv6 blocked-flush tests and a real TCP immediate-close regression. A separate negative-control run proved the old implementation fails both tests, while the exact fix passes 50 repetitions under the race detector: https://github.com/PinableAgents/CLIProxyAPI/actions/runs/37891374544 . The final CI repeats those regressions too.
Upstream HTTP-interrupt fixture: a full-suite run exposed TestResponsesInterruptStopsHTTPUpstream checking its executor flag before the observing goroutine ran. The production path sends response.incomplete before invoking cancellation; receiving that frame does not synchronize the fixture. Signal through a channel only after the executor actually observes ctx.Done(), then retain the original cancellation flag, response shape and same-socket follow-up assertions. No production interruption behavior or existing deadline changes. Final CI repeats the test 100 times.
Failed/superseded candidates were not accepted for merge. No assertions were deleted or weakened and no new skips were introduced.
Small regression-prevention improvement
Expand native-runtime PR path filters to core Go code, dependency manifests and smoke-helper tests so changes under cmd/server, internal or sdk cannot miss the six-platform packaged-executable checks. Existing test gates, platform matrix, permissions and manual-only release publication remain intact. Pin current ancestry checks and update docs/pinable/upstream-sync.md with the resolution and catalog behavior.
Upgrade note: Go module remains /v8 and required toolchain remains Go 1.26.0. --local-model defaults to embedded catalogs, but explicit models.catalog, models.codex-catalog or models.devin-catalog sources override that default. It is not a global no-network switch; the smoke fixtures leave overrides unset.
Completed final-head verification before merge
All four applicable PR workflows completed successfully on d21ac84 or its byte-identical actual PR merge tree:
The original upstream-only translator contribution policy remains scoped to the upstream repository; it was not newly disabled to pass these checks.
Independently downloaded the final-head Linux amd64 runtime, verified archive ZIP digest b1f48cb560837289a6c16185a185871d0f6d0ee898ebba6b3b9f0ab128e255a3, source SHA and manifest, then ran the actual binary through all runtime smoke checks outside Actions: passed. Binary SHA256 fcb3d5fe5e70e6db12ab222d6992f0e5afc6c3580198631767ac3cf9c7308c79. Checks include both version flags, discovery JSON, v8 migration, separated authentication, ephemeral-key reload/non-persistence, acknowledged loopback shutdown and parent death.
Scope boundary and cleanup
Only the fork was modified. No Release, tag, image publication, production deployment, Desktop component-lock update, user-server access or historical conversation credential use. Monolith integration used disposable local CI resources and generated test credentials. No live provider API, arbitrary third-party plugin or Wails/Desktop end-to-end certification is claimed.
All temporary inspection/preparation/negative-control workflows and patch transport were removed from their isolated maintenance branch and are absent from this PR/main. The completed CI above is the pre-merge final-head validation; any main-push rebuild is a separate run and is not claimed complete here.