Repository navigation
fix(stream): accept the buffer size glm.ts has been passing since #12179 - #12925
Merged
diegosouzapw merged 3 commits intoSep 10, 2026
Merged
diegosouzapw merged 3 commits into
diegosouzapw merged 3 commits into
Conversation
This was referenced Sep 7, 2026
Merged
…aper-inference#12179 createSSETransformStreamWithLogger, which takes 15. Two things followed. The visible one: `open-sse/executors/glm.ts(244,5) TS2554` fails the API Route Typecheck gate, and that gate is "reject new errors not in the frozen baseline" -- so it fails on every open PR in the repo, not only on changes that touch this file. The quiet one: the argument was dropped, and createSSEStream hard-coded `{ highWaterMark: 16384 }` on both queues. The 64 KB the call site asks for never reached the stream, so the perf change that hunk describes has not been in effect at all. Adds `streamBufferBytes` to StreamOptions, defaulting to the 16384 every provider used before it was configurable, threads it through the convenience wrapper as a 16th parameter, and uses it for both queues. glm.ts is unchanged: its existing call now compiles and takes effect. The default is a parameter default, not `|| DEFAULT`, so a deliberate 0 -- a queue that applies backpressure immediately -- is honoured rather than silently replaced.
…le exit Two follow-ups on the rebased branch. glm.ts now passes the budget. The tip had already cleared the TS2554 by deleting the 16th argument, leaving a comment saying the highWaterMark stays at the helper default — so the queue budget cheaper-inference#12179 asked for was still not applied, and this PR's new parameter had no caller. Wiring the call site is what turns the capability into the fix. The test file also no longer hangs. Every stream it builds arms a 10s idle watchdog via setInterval in createSSEStream's start, and nothing cancelled them, so node:test kept waiting on a non-empty event loop long after the assertions passed. Cancelling each readable in an after hook runs the TransformStream's cancel handler, which clears the timer: the file reports in ~7s instead of running until the runner is killed.
diegosouzapw
force-pushed
the
fix/glm-stream-buffer-arity
branch
from
September 10, 2026 21:25
5324bc0 to
6824c48
Compare
diegosouzapw
merged commit Sep 10, 2026
af49d49
into
cheaper-inference:release/v3.8.51
3 of 7 checks passed
This was referenced Sep 11, 2026
diegosouzapw
added a commit
that referenced
this pull request
Sep 11, 2026
Four base-reds that appeared on the tip today, none owned by any open PR: - providers-constants-split / provider-node-reserved-prefix: GreenPT (#13024) and EURouter (#13025) move the totals 238 -> 240 and 408 -> 410. - provider-translate-path-golden: same two providers, regenerated with UPDATE_GOLDEN=1; the snapshot delta is purely additive. - glm-sse-transform-arity: #12925 declared the buffer-size slot GLM had been filling since #12179. The invariant is unchanged — the value must land in a real parameter, never a dropped positional — so the guard now checks it from the helper side and requires the named constant at the call site instead of a magic literal. - injection-guard-scan-bound-3932: #13104 split the 16 KB budget between head and tail, so 'outside the window' is now the middle of an oversized body, not its end. The 16 KB ceiling these cases protect is untouched. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
7 tasks done
diegosouzapw
added a commit
to initguru/OmniRoute
that referenced
this pull request
Sep 16, 2026
…ng parameter createSSETransformStreamWithLogger gained a new requestedThinking parameter inserted before customToolNames. glm.ts's translateSseResponse still called it with the pre-existing positional argument list, so the new parameter silently absorbed the old customToolNames slot, and the GLM_STREAM_BUFFER_BYTES tuning value (cheaper-inference#12925) landed on requestToolIdentityMap instead of streamBufferBytes — a TS2345 (number is not assignable to Map<...> | null) caught by check:open-sse-typecheck, and a real loss of GLM's 64KB stream buffer budget. Insert an explicit `undefined` for requestedThinking to restore the original alignment. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
diegosouzapw
added a commit
that referenced
this pull request
Sep 17, 2026
…ive thinking (#12905) * fix(thinking): recognize adaptive thinking + parse/scrub DSML tool-call markers Two defects combined to break DeepSeek-V4-Flash turns and raise 502 empty_response on Claude Code autocompact. Defect 1 — DSML tool-call markers leaked as visible content: DeepSeek-V4-Flash occasionally emits tool calls in a non-standard DSML text format using full-width pipes instead of the OpenAI tool_calls JSON. Two shapes appear in production call logs: - complete block: <|DSML|:Read><path>...</path></|DSML|:Read> - stray closers (truncated call): </|DSML|parameter></|DSML|invoke> </|DSML|tool_calls>, sometimes trailing a system-prompt echo The openai-compatible path never parsed these, so the markers leaked to the client as visible content and the turn ended incomplete. Fix: add open-sse/utils/dsmlToolCalls.ts — parseDsmlToolCalls() converts complete DSML blocks into OpenAI tool_calls and strips stray closing markers from content (streaming-safe via a holdback for partial openers). Wire it into the response translator before extractXmlInvokeBlocks so DSML and XML invoke tool calls share the same pending queue. Defect 2 — adaptive thinking silently suppressed: A prior inline === 'enabled' check on body.thinking.type silently suppressed adaptive (the intent Claude Code actually sends), so reasoning was dropped. The model then emitted DSML tool-call markers as plain text, producing an incomplete stop finish. Fix: use hasActiveClaudeThinking() (which recognizes enabled AND adaptive) to set requestedThinking, thread it through stream.ts and translator state, and gate thinking block emission on state.requestedThinking so upstream reasoning_content only relays when the client opted in. Tests: 29/29 (6 dsml-tool-calls, 5 thinking-active-claude-adapter, 3 translator-resp-dsml-integration, 15 translator-resp-openai-to-claude incl. requestedThinking suppression regression). typecheck:core clean. * fix(sse): strip echoed system-prompt preamble + preserve large analysis/summary blocks DeepSeek-V4 and similar models echo the OMNIROUTE_SYSTEM_INSTRUCTION_APPEND directive (appended to the system tail by claude-to-openai.ts) and whole chunks of the system prompt (<analysis>/<system-reminder>/<summary> blocks, prose reproductions of the superpowers skill section) verbatim at the START of their reply — the 'system message leak' persisting after the request-side fix. Add two streaming-safe preamble strippers in directivePreambleStripper.ts: - createDirectivePreambleStripper(directive): drops a leading reproduction of the exact configured directive across arbitrary SSE chunk boundaries. - createSystemPreambleStripper(): removes <analysis>/<system-reminder>/ <summary> echo blocks and known prose heads (Phase B) from the very start of a stream, only while the stream is still a preamble. Wire both into openai-to-claude.ts content-delta path: chain the exact-directive stripper then the system-echo stripper before DSML/XML-invoke parsing, so a leading system echo is dropped before it reaches the client. Preserve large blocks (>= SYSTEM_ECHO_THRESHOLD=1000 chars) and blocks with no trailing content — these are the model's real response (e.g. a Claude Code autocompact summary), not a short system-echo. Stops the autocompact empty-response regression where a whole-summary <analysis> block was stripped to empty (3a8515). Regression: origin's markdown-boundary feature (bufferedPrefix / splitMarkdownBoundary, commit 1b39873) is preserved — preamble strip runs before the markdown buffer rehydration, and the scrubbed content flows into the existing DSML/XML-invoke/markdown pipeline unchanged. TDD: tests/unit/directive-preamble-strip.test.ts (7 cases), system-preamble-strip.test.ts (12 cases incl. 3a8515 regression), system-preamble-wiring.test.ts (3 integration cases); group F regression 24/24 green; typecheck:core 0 errors. * fix(sse): gate thinking block on requestedThinking + synthesize text block for reasoning-only responses Reasoning-content (thinking) blocks were emitted unconditionally to Claude-format clients, leaking reasoning to thinking-opt-out clients (Claude Code sends thinking:{type:"disabled"}) — the operator reported 'reasoning is exposed'. On reasoning-only upstream responses (GLM-5.2 autocompact pattern), the unconditional thinking block also caused either a 502 'no content block' at flush, or — after a text-block fallback — an autocompact 'empty response' rejection that looped the session forever. Streaming translator (openai-to-claude.ts): - Compute hasReasoning outside the emission gate; accumulate into state._reasoningAccum always (so fix B can fire). - Gate only the thinking-block EMISSION on requestedThinking === true. - FIX B at finish: when no text block was started and requestedThinking !== true, synthesize a text content block from _reasoningAccum so autocompact can extract the summary (no 502, compact applies). - Skip fix B when requestedThinking === true to avoid double-exposure (thinking block + text block both carrying reasoning). Non-streaming translator (responseTranslator.ts): - Thread requestedThinking through translateNonStreamingResponse into convertOpenAINonStreamingToClaude. - suppressThinking = requestedThinking === false: drop the thinking block when content is present (no leak); relay reasoning as a text block when the response is reasoning-only (no 502). requestedThinking === undefined keeps the legacy 'always a thinking block' relay. chatCore.ts: pass hasActiveClaudeThinking(body) to the non-stream translate call (inline, since the shared const is in the stream branch's temporal dead zone here). Tests: 25/25 (5 gate-restore, 1 gate-502-repro, 4 nonstream-leak, 15 resp-openai-to-claude incl. requestedThinking suppression regression). Group E (22) + F (14) regression-free. typecheck:core clean. * fix(sse): restore requestToolIdentityMap in the Codex CLI responses-translation path The needsResponsesTranslation branch (openai-responses -> openai, used when the client also speaks Responses) silently dropped the requestToolIdentityMap argument to createSSETransformStreamWithLogger when the requestedThinking parameter was added, reverting the #7936 tool-identity round-trip fix for that branch. The sibling needsTranslation branch was updated correctly; restore the same argument here. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * docs(changelog): add the 3 fragments documented in the PR body The PR body already writes out the changelog.d/ entries for the DSML parser (Group F), the directive-preamble stripper (Group E), and the reasoning-gate thinking-leak fix (Group G), but none of the files existed in the diff. Add them so the release aggregator picks them up. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * fix(sse): realign GLM's positional call after the new requestedThinking parameter createSSETransformStreamWithLogger gained a new requestedThinking parameter inserted before customToolNames. glm.ts's translateSseResponse still called it with the pre-existing positional argument list, so the new parameter silently absorbed the old customToolNames slot, and the GLM_STREAM_BUFFER_BYTES tuning value (#12925) landed on requestToolIdentityMap instead of streamBufferBytes — a TS2345 (number is not assignable to Map<...> | null) caught by check:open-sse-typecheck, and a real loss of GLM's 64KB stream buffer budget. Insert an explicit `undefined` for requestedThinking to restore the original alignment. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * fix(sse): make the system-preamble stripper opt-in and flush it at stream end `createSystemPreambleStripper()` was wired DEFAULT-ON and unconditional in the openai→claude streaming translator, unlike the exact-directive stripper right above it, which only runs when the operator configured OMNIROUTE_SYSTEM_INSTRUCTION_APPEND. Cause: the system-echo stripper recognises its openers by English-prose heuristics ("# Skill usage", "# Verification Process", <analysis>/<summary>/<system-reminder>), so leaving it always-on made it mutate the response payload of EVERY openai→claude stream. A legitimate reply opening with "# Skill usage: how to write one\n\nHere is the guide." lost that whole section. It is now gated on OMNIROUTE_STRIP_SYSTEM_PREAMBLE=1, mirroring the directive stripper's opt-in. Second cause, same feature: neither stripper was ever flushed. Both buffer while a construct is still undecided — a directive prefix that never completes, an <analysis> block that never closes — and nothing released that buffer at the end of the stream. A reply consisting of an unterminated echo block therefore reached the client as an EMPTY message: the answer was held in the buffer and discarded with the stripper. Both strippers now expose flush(), the finish handler calls it for both, and the released text is emitted as a text block. A construct that WAS finally classified as an echo is not resurrected (the drop is final). Tests: tests/unit/system-preamble-gate-and-flush.test.ts pins the default-off contract, the opted-in behaviour, the flush for both strippers (unit + wiring), and the no-resurrection guard. system-preamble-wiring.test.ts now opts in explicitly, since it exercises the stripping path. * fix(sse): thread the client's thinking intent into the non-streaming path The streaming and non-streaming translators disagreed on the default meaning of `requestedThinking`, so the SAME request produced different shapes depending on `stream`. Cause: chatCore computes the client's intent (hasActiveClaudeThinking) and threads it into the SSE translator, which relays reasoning as a thinking block only when it is explicitly `true` — but NO caller ever passed it to translateNonStreamingResponse(). The non-streaming OpenAI→Claude conversion therefore only ever saw `undefined`, its legacy "always relay a thinking block" default, and leaked reasoning to a client that had opted out with `thinking: {"type":"disabled"}`. The streaming plumbing also coerced an omitted value into an explicit `false`, hiding the divergence behind two different spellings of "no intent". Fix (least destructive of the options): do NOT flip either gate — both encode a deliberate, regression-tested contract — but give the non-streaming path the same input the streaming path already has. runNonStreamingProviderLeg owns the client body (`sourceBody`), so it computes the intent with the very same helper and passes it down through translateNonStreamingClientResponse. `undefined` keeps its documented back-compat relay for callers that cannot express intent (issue-7856 / issue-6623), and stream.ts no longer defaults the parameter to `false`, so "absent" now means the same thing in both signatures. No content is lost by the suppression: a reasoning-ONLY response is still relayed as an ordinary text block (no empty response, no 502) — exactly what the streaming finish handler does. Tests: tests/unit/nonstream-requested-thinking-parity.test.ts drives the real provider leg with thinking disabled / enabled / adaptive. --------- Co-authored-by: Jihyun Son <jihyun.son@sk.com> Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
muhamadgalihsaputra
pushed a commit
to niyatna/NiyatnaRoute
that referenced
this pull request
Sep 27, 2026
…aper-inference#12179 (cheaper-inference#12925) Rebased onto the tip and completed, per the maintainer's call to finish the wiring rather than merge the capability alone. What changed since your version: The tip had already cleared the TS2554 by deleting the 16th argument, leaving a comment that the highWaterMark stays at the helper default. So the base-red you found is gone, but the 64 KB cheaper-inference#12179 asked for was still not applied and your new parameter had no caller. glm.ts now passes it, which is what turns the capability into the fix. Your test file also hung the runner: every stream createSSEStream builds arms a 10s idle watchdog via setInterval in start, and nothing cancelled them, so node:test waited on a non-empty event loop long after the assertions passed. Cancelling each readable in an after hook runs the cancel handler that clears the timer — the file now reports in about 7 seconds. Worth knowing for future stream tests. Your five assertions are unchanged and all pass. Reading the writable's desiredSize to measure the queue budget the stream was actually built with, rather than standing in for it, is the detail that makes this testable at all — and the 0-budget case pinning `??` against `||` is the kind of thing that silently rots otherwise. Thank you also for separating your own red checks from the base's and reporting what you found there. That is how cheaper-inference#12919's identical failures got explained instead of chased.
muhamadgalihsaputra
pushed a commit
to niyatna/NiyatnaRoute
that referenced
this pull request
Sep 27, 2026
…ive thinking (cheaper-inference#12905) * fix(thinking): recognize adaptive thinking + parse/scrub DSML tool-call markers Two defects combined to break DeepSeek-V4-Flash turns and raise 502 empty_response on Claude Code autocompact. Defect 1 — DSML tool-call markers leaked as visible content: DeepSeek-V4-Flash occasionally emits tool calls in a non-standard DSML text format using full-width pipes instead of the OpenAI tool_calls JSON. Two shapes appear in production call logs: - complete block: <|DSML|:Read><path>...</path></|DSML|:Read> - stray closers (truncated call): </|DSML|parameter></|DSML|invoke> </|DSML|tool_calls>, sometimes trailing a system-prompt echo The openai-compatible path never parsed these, so the markers leaked to the client as visible content and the turn ended incomplete. Fix: add open-sse/utils/dsmlToolCalls.ts — parseDsmlToolCalls() converts complete DSML blocks into OpenAI tool_calls and strips stray closing markers from content (streaming-safe via a holdback for partial openers). Wire it into the response translator before extractXmlInvokeBlocks so DSML and XML invoke tool calls share the same pending queue. Defect 2 — adaptive thinking silently suppressed: A prior inline === 'enabled' check on body.thinking.type silently suppressed adaptive (the intent Claude Code actually sends), so reasoning was dropped. The model then emitted DSML tool-call markers as plain text, producing an incomplete stop finish. Fix: use hasActiveClaudeThinking() (which recognizes enabled AND adaptive) to set requestedThinking, thread it through stream.ts and translator state, and gate thinking block emission on state.requestedThinking so upstream reasoning_content only relays when the client opted in. Tests: 29/29 (6 dsml-tool-calls, 5 thinking-active-claude-adapter, 3 translator-resp-dsml-integration, 15 translator-resp-openai-to-claude incl. requestedThinking suppression regression). typecheck:core clean. * fix(sse): strip echoed system-prompt preamble + preserve large analysis/summary blocks DeepSeek-V4 and similar models echo the OMNIROUTE_SYSTEM_INSTRUCTION_APPEND directive (appended to the system tail by claude-to-openai.ts) and whole chunks of the system prompt (<analysis>/<system-reminder>/<summary> blocks, prose reproductions of the superpowers skill section) verbatim at the START of their reply — the 'system message leak' persisting after the request-side fix. Add two streaming-safe preamble strippers in directivePreambleStripper.ts: - createDirectivePreambleStripper(directive): drops a leading reproduction of the exact configured directive across arbitrary SSE chunk boundaries. - createSystemPreambleStripper(): removes <analysis>/<system-reminder>/ <summary> echo blocks and known prose heads (Phase B) from the very start of a stream, only while the stream is still a preamble. Wire both into openai-to-claude.ts content-delta path: chain the exact-directive stripper then the system-echo stripper before DSML/XML-invoke parsing, so a leading system echo is dropped before it reaches the client. Preserve large blocks (>= SYSTEM_ECHO_THRESHOLD=1000 chars) and blocks with no trailing content — these are the model's real response (e.g. a Claude Code autocompact summary), not a short system-echo. Stops the autocompact empty-response regression where a whole-summary <analysis> block was stripped to empty (3a8515). Regression: origin's markdown-boundary feature (bufferedPrefix / splitMarkdownBoundary, commit f03d99a) is preserved — preamble strip runs before the markdown buffer rehydration, and the scrubbed content flows into the existing DSML/XML-invoke/markdown pipeline unchanged. TDD: tests/unit/directive-preamble-strip.test.ts (7 cases), system-preamble-strip.test.ts (12 cases incl. 3a8515 regression), system-preamble-wiring.test.ts (3 integration cases); group F regression 24/24 green; typecheck:core 0 errors. * fix(sse): gate thinking block on requestedThinking + synthesize text block for reasoning-only responses Reasoning-content (thinking) blocks were emitted unconditionally to Claude-format clients, leaking reasoning to thinking-opt-out clients (Claude Code sends thinking:{type:"disabled"}) — the operator reported 'reasoning is exposed'. On reasoning-only upstream responses (GLM-5.2 autocompact pattern), the unconditional thinking block also caused either a 502 'no content block' at flush, or — after a text-block fallback — an autocompact 'empty response' rejection that looped the session forever. Streaming translator (openai-to-claude.ts): - Compute hasReasoning outside the emission gate; accumulate into state._reasoningAccum always (so fix B can fire). - Gate only the thinking-block EMISSION on requestedThinking === true. - FIX B at finish: when no text block was started and requestedThinking !== true, synthesize a text content block from _reasoningAccum so autocompact can extract the summary (no 502, compact applies). - Skip fix B when requestedThinking === true to avoid double-exposure (thinking block + text block both carrying reasoning). Non-streaming translator (responseTranslator.ts): - Thread requestedThinking through translateNonStreamingResponse into convertOpenAINonStreamingToClaude. - suppressThinking = requestedThinking === false: drop the thinking block when content is present (no leak); relay reasoning as a text block when the response is reasoning-only (no 502). requestedThinking === undefined keeps the legacy 'always a thinking block' relay. chatCore.ts: pass hasActiveClaudeThinking(body) to the non-stream translate call (inline, since the shared const is in the stream branch's temporal dead zone here). Tests: 25/25 (5 gate-restore, 1 gate-502-repro, 4 nonstream-leak, 15 resp-openai-to-claude incl. requestedThinking suppression regression). Group E (22) + F (14) regression-free. typecheck:core clean. * fix(sse): restore requestToolIdentityMap in the Codex CLI responses-translation path The needsResponsesTranslation branch (openai-responses -> openai, used when the client also speaks Responses) silently dropped the requestToolIdentityMap argument to createSSETransformStreamWithLogger when the requestedThinking parameter was added, reverting the cheaper-inference#7936 tool-identity round-trip fix for that branch. The sibling needsTranslation branch was updated correctly; restore the same argument here. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * docs(changelog): add the 3 fragments documented in the PR body The PR body already writes out the changelog.d/ entries for the DSML parser (Group F), the directive-preamble stripper (Group E), and the reasoning-gate thinking-leak fix (Group G), but none of the files existed in the diff. Add them so the release aggregator picks them up. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * fix(sse): realign GLM's positional call after the new requestedThinking parameter createSSETransformStreamWithLogger gained a new requestedThinking parameter inserted before customToolNames. glm.ts's translateSseResponse still called it with the pre-existing positional argument list, so the new parameter silently absorbed the old customToolNames slot, and the GLM_STREAM_BUFFER_BYTES tuning value (cheaper-inference#12925) landed on requestToolIdentityMap instead of streamBufferBytes — a TS2345 (number is not assignable to Map<...> | null) caught by check:open-sse-typecheck, and a real loss of GLM's 64KB stream buffer budget. Insert an explicit `undefined` for requestedThinking to restore the original alignment. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * fix(sse): make the system-preamble stripper opt-in and flush it at stream end `createSystemPreambleStripper()` was wired DEFAULT-ON and unconditional in the openai→claude streaming translator, unlike the exact-directive stripper right above it, which only runs when the operator configured OMNIROUTE_SYSTEM_INSTRUCTION_APPEND. Cause: the system-echo stripper recognises its openers by English-prose heuristics ("# Skill usage", "# Verification Process", <analysis>/<summary>/<system-reminder>), so leaving it always-on made it mutate the response payload of EVERY openai→claude stream. A legitimate reply opening with "# Skill usage: how to write one\n\nHere is the guide." lost that whole section. It is now gated on OMNIROUTE_STRIP_SYSTEM_PREAMBLE=1, mirroring the directive stripper's opt-in. Second cause, same feature: neither stripper was ever flushed. Both buffer while a construct is still undecided — a directive prefix that never completes, an <analysis> block that never closes — and nothing released that buffer at the end of the stream. A reply consisting of an unterminated echo block therefore reached the client as an EMPTY message: the answer was held in the buffer and discarded with the stripper. Both strippers now expose flush(), the finish handler calls it for both, and the released text is emitted as a text block. A construct that WAS finally classified as an echo is not resurrected (the drop is final). Tests: tests/unit/system-preamble-gate-and-flush.test.ts pins the default-off contract, the opted-in behaviour, the flush for both strippers (unit + wiring), and the no-resurrection guard. system-preamble-wiring.test.ts now opts in explicitly, since it exercises the stripping path. * fix(sse): thread the client's thinking intent into the non-streaming path The streaming and non-streaming translators disagreed on the default meaning of `requestedThinking`, so the SAME request produced different shapes depending on `stream`. Cause: chatCore computes the client's intent (hasActiveClaudeThinking) and threads it into the SSE translator, which relays reasoning as a thinking block only when it is explicitly `true` — but NO caller ever passed it to translateNonStreamingResponse(). The non-streaming OpenAI→Claude conversion therefore only ever saw `undefined`, its legacy "always relay a thinking block" default, and leaked reasoning to a client that had opted out with `thinking: {"type":"disabled"}`. The streaming plumbing also coerced an omitted value into an explicit `false`, hiding the divergence behind two different spellings of "no intent". Fix (least destructive of the options): do NOT flip either gate — both encode a deliberate, regression-tested contract — but give the non-streaming path the same input the streaming path already has. runNonStreamingProviderLeg owns the client body (`sourceBody`), so it computes the intent with the very same helper and passes it down through translateNonStreamingClientResponse. `undefined` keeps its documented back-compat relay for callers that cannot express intent (issue-7856 / issue-6623), and stream.ts no longer defaults the parameter to `false`, so "absent" now means the same thing in both signatures. No content is lost by the suppression: a reasoning-ONLY response is still relayed as an ordinary text block (no empty response, no 502) — exactly what the streaming finish handler does. Tests: tests/unit/nonstream-requested-thinking-parity.test.ts drives the real provider leg with thinking disabled / enabled / adaptive. --------- Co-authored-by: Jihyun Son <jihyun.son@sk.com> Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
AndresDiagoM
added a commit
to AndresDiagoM/OmniRoute
that referenced
this pull request
Oct 19, 2026
…helper clientTools now sits before streamBufferBytes, so the trailing buffer-size slot GLM fills (cheaper-inference#12925) stays last and GLM's call matches the helper arity. GLM passes null for clientTools; the translate call in streamingTail drops its placeholder undefined.
diegosouzapw
added a commit
that referenced
this pull request
Oct 22, 2026
…ng from every provider (#17118) (#17119) * fix(sse): hand Anthropic-format clients their declared tool-name casing from every provider Claude-format responses assembled by openai-to-claude, gemini-to-claude and the non-streaming responseTranslator all ended in restoreClaudeToolName(), whose canonical upgrade (read -> Read, #7926/#9008/#10392/#11085) assumes the client is Claude Code. OpenCode's @ai-sdk/anthropic provider declares lowercase tools, so a combo falling back from native claude to Antigravity, Codex or Gemini (or any of those used directly over /v1/messages) answered with tool_use.name "Read" for a tool declared as "read", and every tool call failed client-side ("No tool named Read"). Lift the #12721 passthrough rule into a shared module and apply it on the translate paths too: alias ledger first, then the CLIENT request's declared spelling (exact, then case-insensitive), then the legacy canonical upgrade only for names the request never declared. Claude Code declares "Read", so it keeps getting "Read" back when an OpenAI-style upstream downcases it; OpenCode gets "read" back from the same upstream. The client's tools[] is threaded into the translate-mode stream state and into translateNonStreamingResponse. * docs(changelog): add fragment for #17119 * fix(sse): keep streamBufferBytes the last parameter of the transform helper clientTools now sits before streamBufferBytes, so the trailing buffer-size slot GLM fills (#12925) stays last and GLM's call matches the helper arity. GLM passes null for clientTools; the translate call in streamingTail drops its placeholder undefined. * fix(sse): carry declared tools through Claude passthrough (#17118) * refactor(sse): split declaredToolCasing helpers under the complexity gate findDeclaredToolName (cyclomatic 17, cognitive 18) and restoreDeclaredToolName (cognitive 17) were over the new-code limit of 15. Extract declaredNameOf() for the per-entry tools[] spelling and aliasLedgerName() for the _toolNameMap precedence; behaviour is unchanged and the 17118/17119 suites still pass. --------- Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
DarknessKiller
added a commit
to DarknessKiller/OmniRoute
that referenced
this pull request
Oct 25, 2026
…1f05`
- New UI Changes are not applied
Squashed commit of the following:
commit fb2808905d16c0ed51ec54ee206f798465001f05
Author: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
Date: Sat Oct 24 23:02:31 2026 -0300
fix(cli): resolve the systray entry and unwrap its constructor (#17328)
Resolve the systray runtime entry and unwrap its constructor in the CLI tray.
Evidence: focused tests pass (tests/unit/cli/tray-failure-diagnostics-17315.test.ts, tests/unit/cli/tray-runtime-entry-17315.test.ts, tests/unit/cli/tray-runtime-windows-esm-import.test.ts), validated in one combined board of 9 PRs on origin/release/v3.8.53 with typecheck:core, check:open-sse-typecheck and ESLint clean; file-size OK; changelog integrity OK against origin/release/v3.8.53.
⚠️ base-red inherited: #17219
commit 033f012fc9b25e302debe59e9669b749d3fcd992
Author: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
Date: Sat Oct 24 23:02:17 2026 -0300
fix(ci): restore strict core types without runtime changes (#17857)
Restore strict core types for the stream/cache helpers without runtime changes.
Evidence: focused tests pass (tests/unit/compute-finish-reason-coverage.test.ts, tests/unit/proxy-dispatcher-cloud-reap.test.ts, tests/unit/semantic-cache-secret-storage-14484.test.ts), validated in one combined board of 9 PRs on origin/release/v3.8.53 with typecheck:core, check:open-sse-typecheck and ESLint clean; file-size OK; changelog integrity OK against origin/release/v3.8.53.
⚠️ base-red inherited: #17219
commit 3fc7d04a36d4e361daf8dc95540fe26dff104f0f
Author: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
Date: Sat Oct 24 23:02:06 2026 -0300
fix(ci): reject dependencies that drift from candidate lockfile (#17854)
Reject CI installs whose dependencies drift from the candidate lockfile.
Evidence: focused tests pass (tests/unit/build/verify-ci-install.test.mjs), validated in one combined board of 9 PRs on origin/release/v3.8.53 with typecheck:core, check:open-sse-typecheck and ESLint clean; file-size OK; changelog integrity OK against origin/release/v3.8.53.
⚠️ base-red inherited: #17219
commit 7d3a4787130c23e7eb5fa5483d9f468bbd061f5e
Author: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
Date: Sat Oct 24 23:01:54 2026 -0300
fix(ci): provision verified workflow scanners for release observers (#17846)
Provision verified, pinned scanners for the Release-Green observer jobs.
Evidence: focused tests pass (tests/unit/release-green-scanner-setup.test.mjs), validated in one combined board of 9 PRs on origin/release/v3.8.53 with typecheck:core, check:open-sse-typecheck and ESLint clean; file-size OK; changelog integrity OK against origin/release/v3.8.53.
⚠️ base-red inherited: #17219
commit 0d96ef1748dd765a289186b0fb31e3555117358d
Author: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
Date: Sat Oct 24 23:01:41 2026 -0300
fix(sse): surface midstream keepalive read failures (#17292) (#17341)
Signal upstream read failures after partial output in the early-stream keepalive path.
Evidence: focused tests pass (tests/unit/early-stream-midstream-failure-17292.test.ts, tests/unit/earlyStreamKeepalive.test.ts), validated in one combined board of 9 PRs on origin/release/v3.8.53 with typecheck:core, check:open-sse-typecheck and ESLint clean; file-size OK; changelog integrity OK against origin/release/v3.8.53.
⚠️ base-red inherited: #17219
Fixes #17292
commit 4fa23c64d7263f8eb346fad521e20e930e8a3439
Author: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
Date: Sat Oct 24 23:01:30 2026 -0300
fix(sse): preserve provider-native model IDs (#16823) (#17336)
Preserve known provider-native model IDs through model resolution.
Evidence: focused tests pass (tests/unit/16823-native-model-aliases.test.ts, tests/unit/16823-ollama-tags-persist-dispatch.test.ts), validated in one combined board of 9 PRs on origin/release/v3.8.53 with typecheck:core, check:open-sse-typecheck and ESLint clean; file-size OK; changelog integrity OK against origin/release/v3.8.53.
⚠️ base-red inherited: #17219
commit b69588a1e0585e658602a730f4f2dab7955cd219
Author: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
Date: Sat Oct 24 23:01:18 2026 -0300
fix(api): explain the Windows EBUSY/EPERM failure of the in-app npm update (#17335)
Explain the Windows EBUSY/EPERM failure of the in-app npm update with an actionable message.
Evidence: focused tests pass (tests/unit/system-update-install-error-windows-ebusy.test.ts), validated in one combined board of 9 PRs on origin/release/v3.8.53 with typecheck:core, check:open-sse-typecheck and ESLint clean; file-size OK; changelog integrity OK against origin/release/v3.8.53.
⚠️ base-red inherited: #17219
commit 3c90c0636832ec3b1c7f7d7871fa17933c721211
Author: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
Date: Sat Oct 24 23:01:05 2026 -0300
fix(sse): preserve explicit adaptive thinking effort (#17333)
Preserve an explicitly requested adaptive thinking effort instead of overriding it.
Evidence: focused tests pass (tests/unit/16662-explicit-adaptive-effort.test.ts, tests/unit/thinking-budget.test.ts), validated in one combined board of 9 PRs on origin/release/v3.8.53 with typecheck:core, check:open-sse-typecheck and ESLint clean; file-size OK; changelog integrity OK against origin/release/v3.8.53.
⚠️ base-red inherited: #17219
commit 5e146a4a75f4bf8bf7c62575615fcc12979f980d
Author: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
Date: Sat Oct 24 23:00:55 2026 -0300
fix(usage): preserve cache reads after compatibility zeros (#17297) (#17327)
Preserve cache-read token counts when a compatibility layer reports zeros.
Evidence: focused tests pass (tests/unit/issue-17297-cache-read-zero-compat.test.ts), validated in one combined board of 9 PRs on origin/release/v3.8.53 with typecheck:core, check:open-sse-typecheck and ESLint clean; file-size OK; changelog integrity OK against origin/release/v3.8.53.
⚠️ base-red inherited: #17219
Fixes #17297.
commit 8f2120868bff087673e402c517e1caa7320dca12
Author: Felipe Marques <contato@felipemarques.com.br>
Date: Fri Oct 23 01:09:15 2026 -0300
feat(audio): add ElevenLabs sound effects and music generation (#17287)
commit 6c928202d71d2ce7e0b94802ac6dfe0aa1278b48
Author: Fouad Salkini <fouad@wecansync.com>
Date: Thu Oct 22 23:21:03 2026 +0300
feat(api): add OpenRouter-format prices to /v1/models entries (#17259)
commit 3f83d37acefc3a5414d21530586e46d7dd31c814
Merge: 76f4325ab9 daca9902e8
Author: DarknessKiller <mrdarknesskiller@protonmail.com>
Date: Mon Oct 26 02:02:33 2026 +0800
Merge commit 'daca9902e859bc1aa95ba276e3ef200ba7f5d142' of https://github.com/diegosouzapw/OmniRoute into release/v3.8.53-mrdarknessk
commit daca9902e859bc1aa95ba276e3ef200ba7f5d142
Author: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
Date: Thu Oct 22 14:37:22 2026 -0300
docs(i18n): re-translate GUARDRAILS mirrors (66 locales) (#17950)
commit 34e3d1f99834f1ca4ca4724eb872ca5e9722c383
Author: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
Date: Thu Oct 22 14:34:24 2026 -0300
refactor(security): quantifier-free edge strip in combo step slugs (CodeQL #1165) (#17906)
slugify() in src/lib/combos/steps.ts strips the edge separator with /^-|-$/g instead of /^-+|-+$/g. The preceding replace already collapses every separator run into one dash, so the output is identical; tests/unit/combo-step-id-slug.test.ts pins the id shape.
commit da030357292857aed4e2e38d727f92c471e7aba9
Author: leoplife <leonidasl.1010@gmail.com>
Date: Thu Oct 22 14:30:50 2026 -0300
feat(config): refresh OpenCode Zen free models (#17345)
commit d63ab780f8aa7d1efd704a365fd8835728924788
Author: Fabio Junior Gruchovski <122614728+fabioKoruja00@users.noreply.github.com>
Date: Thu Oct 22 14:30:32 2026 -0300
fix: honor explicit combo selection in MCP and A2A (#17188) (#17235)
commit dc648dfce195861964d2d0d0f5b4731a37cd00b6
Author: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
Date: Thu Oct 22 13:53:45 2026 -0300
fix(ci): accept Dependabot's support@github.com sign-off in check:ai-attribution (#17876)
Dependabot ends every bump commit with Signed-off-by: dependabot[bot] <support@github.com>; the exemption only matched the noreply co-author address, so Lint and Fast Quality Gates failed on every Dependabot PR. The exemption now accepts that exact name with either exact address; look-alike names with the same address still fail.
commit 0482755c5e4faeeb23736b9e56ec293d84809efa
Author: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
Date: Thu Oct 22 08:47:26 2026 -0300
docs(i18n): ENVIRONMENT — carry the CodeBuddy ∅ (∞) default in source + 66 mirrors (base-red fix for cli-env-quality-docs-mirrors) (#17929)
commit b7a61c8d107ddc9771696e8c12be86736e778629
Author: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
Date: Thu Oct 22 08:42:36 2026 -0300
docs(i18n): re-translate CLAUDE.md mirrors (66 locales) — protected surface, owner approval required (#17910)
commit 00f340bc211603cb6083ceca22fe093fe13bbaac
Author: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
Date: Thu Oct 22 08:22:59 2026 -0300
docs(i18n): re-translate the ENVIRONMENT mirrors after #17074 (#17919)
commit cce4f5bc2579f4a4cb66471901a0fd835d6dd1a3
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 12:53:17 2026 +0200
fix(batch): preserve CSV source when remapping input (#17222)
commit 4bb1c22b055046a266a2b89ac699e1ca58673d6e
Author: MeTony <70nyIT@users.noreply.github.com>
Date: Thu Oct 22 12:52:52 2026 +0200
fix(tools): keep client-declared filePath in the Read shim (#17294) (#17295)
commit b68c33211e99aa24ce3ec04a1a68280b0bd8395d
Author: Fabio Junior Gruchovski <122614728+fabioKoruja00@users.noreply.github.com>
Date: Thu Oct 22 07:34:49 2026 -0300
Fix/17043 claude observed quota reset release (#17107)
commit 24f32794f925e25afdfe7800b4206c6dbaceb8fd
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 12:32:30 2026 +0200
fix(batch): discard file reads after input format changes (#17221)
commit c9d9a2ef06fc15d95498fb4ef7f222597bf2edbb
Author: Rafa Martins <146174365+rafacpti23@users.noreply.github.com>
Date: Thu Oct 22 07:32:13 2026 -0300
fix(sse): stop quota-share block from crashing the proxy and cooling the shared connection (#17132) (#17214)
commit 0a4a06eebb4b38d3698ad4578274016d45b412af
Author: Aldo <github@aldo.pw>
Date: Thu Oct 22 04:32:01 2026 -0600
fix(translator): contain malformed upstream payloads (#17198)
commit 4f8e62017d58cdfa985f4b956a9684090dfa0c16
Author: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
Date: Thu Oct 22 07:21:42 2026 -0300
docs(i18n): RESILIENCE_GUIDE — fix the lock-scope code span, carry the #16319 contract block in source + 66 mirrors (base-red fix) (#17921)
commit f5452822a84a6c76ed5059087b475946373e351c
Author: Mayank Jaiswal <mayankjaiswal1707@gmail.com>
Date: Thu Oct 22 15:27:35 2026 +0530
test(api): lock env master key bypass in model catalog auth (#17340)
commit f2070a84fde166e90d58ba0a95f619bda0e66099
Author: r2jaff <r2jaff000@gmail.com>
Date: Thu Oct 22 12:57:25 2026 +0300
test(sse): pin spec reporter in the Perplexity stream boundary test (#17321)
The test spawns its fixture with node --test and asserts on spec
reporter output ("ℹ tests 8"), but did not pass --test-reporter.
Node 22 defaults to the tap reporter when stdout is not a TTY, so the
assertion failed on Node 22 (supported by engines: >=22.22.2) while
passing on Node 24, where spec is the default. Pin the reporter the way
tests/unit/helpers/runIsolatedBoundaryFixture.ts already does.
Co-authored-by: Claude <noreply@anthropic.com>
commit 141844081819e333a4b251e0a9b62acc014f2b7c
Author: Calvin Chen <mrdarknesskiller@protonmail.com>
Date: Thu Oct 22 17:57:15 2026 +0800
fix(compression): keep Responses tool output and injected messages intact (#17310)
* fix(compression): treat trailing Responses tool outputs as the current turn in lite
An OpenAI Responses API tool turn carries no assistant message: the call and its
output arrive as top-level input items, which the adapter turns into a
synthesized role:"tool" message. lite derived the current turn from the last
assistant message and defaulted to protecting nothing when there was none, so
the newest function_call_output was truncated and the agent kept re-reading the
same file. Trailing Responses tool outputs now count as the current turn.
Adds isResponsesToolOutputMessage() to the body adapter for the check.
* fix(compression): restore engine-injected messages into Responses input
The Responses adapter maps input[] items to chat messages and maps the result
back by source index. A message an engine injects has no source item — CCR
prepends its protocol instruction — so the restore loop skipped it and the
instruction never reached the provider. The model then saw [CCR retrieve]
markers with no protocol telling it how to expand them. Injected messages are
now restored as new input items ahead of the mapped ones.
* refactor(compression): share the Responses input restore tail to clear the cognitive-complexity ratchet
Extract finalizeResponsesInput() for the two identical string-input + injected-items branches in restore(), add a test for the string-input path and a changelog fragment.
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
---------
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
commit 90d22e0c826db242a9485b37f1867caea61cc2b3
Author: Mayank Jaiswal <mayankjaiswal1707@gmail.com>
Date: Thu Oct 22 15:27:04 2026 +0530
fix(sse): honor Retry-After hint and jitter intra-URL retry backoff (#17306)
* fix(sse): honor Retry-After hint and jitter intra-URL retry backoff
* chore(changelog): add fragment for retry-after hint and jitter intra-URL retry
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
---------
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
commit 6a9b1e2efd1f58eb5bad4f3b3435f2ea87c9b331
Author: Junior-HJ <sjaradj@ucvvirtual.edu.pe>
Date: Thu Oct 22 04:56:54 2026 -0500
fix(cursor): bridge Grep when the declared pattern carries a length bound (#17298)
* fix(sse): bridge Cursor Grep when the declared pattern declares a length bound
* chore(sse): prefix the changelog fragment with its PR number
commit 5ad89354d140b5f34bdfb91109d6c24fb949ae69
Author: Fouad Salkini <fouad@wecansync.com>
Date: Thu Oct 22 12:56:44 2026 +0300
fix(models): stop the context-window reconcile from blocking the event loop (#17296)
* fix(models): stop the context-window reconcile from blocking the event loop
Each auto:discovery override write bumped the model catalog cache version,
so the next getCatalogWindow call in the same pass rebuilt the synced vision
verdict map from every synced catalog. On ~6,300 synced models with ~1,400
divergent windows a pass blocked the event loop for ~10.7 s, and since #11016
a pass runs after every synced catalog write.
The pass now writes without invalidating and bumps the catalog version once
at the end, and it skips rewriting an override that already holds the
discovered window.
* chore(changelog): name the reconcile-stall fragment after #17296
* chore(changelog): link the reconcile-stall fragment to #17296
* refactor(models): split reconcileContextWindows into small helpers to clear the cognitive-complexity ratchet
Behavior is unchanged: the per-entry decision moves into reconcileOne with isAlreadyPinned and dropStaleAutoPin, so the new-code cognitive-complexity gate reports 0 violations for contextWindowResolver.ts. Changelog fragment notes the refreshedAt semantics.
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
---------
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
commit 7e8f8f8bfa68e74064044357e70195c21d1851b0
Author: Nick Carter <mr.nicholas.b.carter@gmail.com>
Date: Thu Oct 22 05:56:34 2026 -0400
fix(sse): preserve restored thinking in active tool cycles (#17288)
* fix(sse): preserve restored thinking in active tool cycles
* docs(changelog): add fragment for preserving restored thinking in active tool cycles
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
---------
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
commit f4cf8441786800478603fdde52b9f0bd74bb3136
Author: Dizzle <112548150+maxmad64bis@users.noreply.github.com>
Date: Thu Oct 22 11:56:24 2026 +0200
fix(calls): measure content presence on streamed replies (#17277)
a streamed reply was always logged as empty because the reader read the envelope as a body; the summary is now measured like any other body
commit 9bbc2e37558328ef1dc7bec16c93651ca6b8a3fd
Author: Stanislav <lazygatto@gmail.com>
Date: Thu Oct 22 12:56:13 2026 +0300
fix(usage): release the captured provider request body when its dispatch settles (#17269)
* fix(usage): release the captured provider request body when its dispatch settles
The Capture object returned by createPreparedRequestLogger lives in an
AsyncLocalStorage store, so sockets and streams spawned during the dispatch
keep the store — and its latest.bodyString — alive after the request is done.
For agent traffic with base64 screenshots that string is 3-10 MB, which
remained reachable forever: heap climbed ~4-8 MB/h (day averages
847 -> 1314 MB over three days) until the pressure guard.
runWithCapture now calls an optional Capture.release() in its finally, so the
retained body is dropped as soon as the dispatch settles; body(fallback) already
falls back to the transformed body once latest is gone.
Follow-up to #16752. Measured on a self-hosted instance over 25.8 h after the
patch: heap plateaued at 241-388 MB (0.5 MB/h), RSS 790-1048 MB, zero guard
trips.
* chore: rename changelog fragment with the PR number (#17269)
* fix(usage): reject late captures from settled dispatches
* fix(usage): keep the captured wire body readable after dispatch, release it from the ALS store instead
Capture.release() cleared latest() when the dispatch settled, but chatCore reads providerRequestCapture.latest()/body() after that point (signature-failure diagnostics, call-log request body). AsyncLocalStorage now holds a small holder whose capture field is nulled in the finally of runWithCapture: sockets and streams that outlive the dispatch no longer pin the Capture and its multi-megabyte body, while chatCore keeps the Capture through its own closure. The settled-dispatch guard stays. Tests now assert the post-dispatch read still returns the wire body and the holder is empty.
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
---------
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
commit 6b2926286f69cd1872333510e1569dfc3ff84c1b
Author: aminHZDEV <107117131+aminHZDEV@users.noreply.github.com>
Date: Thu Oct 22 13:26:03 2026 +0330
fix(api): list only callable models in a restricted key's /v1/models (#17261)
* fix(api): list only callable models in a restricted key's /v1/models
A key restricted to cc/* listed other providers' claude-* rows
(dva/claude-opus-5-high, ddgw/claude-haiku-4-5) that every chat request
refused with 403. The catalog filter also checks a row's bare root (#781),
and with preferClaudeCodeForUnprefixedClaudeModels on, the permission check
expands a bare claude-* name to cc/<name>, which cc/* matches. Dispatch
checks only the requested id.
- The root fallback now also needs a bare allowlist entry matching the
root, which is the case #781 was added for (allowedModels: ["gpt-4o"]).
- isModelAllowedForKey judges no-think/<provider>/<model> as the real
model, as the chat handler strips the prefix before its key check. The
key's catalog now keeps the no-think/cc/ variants it can call.
* docs(changelog): add fragment for #17261
* docs(changelog): credit @aminHZDEV in the #17261 fragment
commit 3414466b4ba187e9bd93c21153c6449b6934dcf9
Author: aminHZDEV <107117131+aminHZDEV@users.noreply.github.com>
Date: Thu Oct 22 13:25:53 2026 +0330
fix(pricing): price claude-sonnet-5-5 on the cc provider (#17260)
* fix(pricing): price claude-sonnet-5-5 on the cc provider
The cc table priced claude-opus-5-5 but had no claude-sonnet-5-5 entry, so
getPricingForModel("cc", "claude-sonnet-5-5") returned null. Use the shared
Sonnet 5 tier ($2 / $10, cache read $0.20), which Anthropic lists for
Sonnet 5.5.
* docs(changelog): add fragment for #17260
* docs(changelog): credit @aminHZDEV in the #17260 fragment
commit 6e12c409f7278004475eee697450f5c57b76bba9
Author: Calvin Chen <mrdarknesskiller@protonmail.com>
Date: Thu Oct 22 17:55:43 2026 +0800
fix(compression): compact Anthropic tool_result content in headroom e… (#17258)
* fix(compression): compact Anthropic tool_result content in headroom engine
* docs(changelog): add fragment for headroom tool_result compaction
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
---------
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
commit 62ecd3deaf46b894574ced9b3df4cd38216d5081
Author: Patryk Kopyciński <patryk.kopycinski@elastic.co>
Date: Thu Oct 22 11:55:32 2026 +0200
fix(translator): hoist nested tool_result.content cache_control on the openai-compat and openai→claude paths (#17257)
* fix(translator): hoist tool_result.content cache_control to block level for openai-compat downstream re-translation
An OpenAI `role:"tool"` message carrying `cache_control` on its content blocks
reached Anthropic as `tool_result.content[i].cache_control`, which is hard
rejected:
[400] messages.N.content.0.tool_result.content.0.cache_control:
cache_control may not be specified within `tool_result.content`.
Instead, place it directly on `tool_result`
filterToOpenAIFormat() early-returned tool messages untouched, so nested markers
survived into openai-to-claude's tool_result block. The existing
prepareClaudeRequest hoist (6d45da2050) could not catch this: it only runs for
targetFormat === "claude", while this path is sourceFormat=openai →
targetFormat=openai into an openai-compatible gateway that itself re-translates
to Anthropic.
Two surgical changes:
- filterToOpenAIFormat strips nested markers off tool content blocks and, in
preserve mode, hoists the first one onto the tool MESSAGE.
- openai-to-claude emits that message-level marker on the `tool_result` block.
Covered by tests/unit/openai-tool-message-cache-control-400.test.ts (5 cases
across strip and preserve modes). Mutation-checked: reverting either change
turns 4/5 red.
* chore: drop replay scratch file
* fix(translator): hoist nested tool_result.content cache_control in openai-to-claude itself
Replaying the captured 157-message live body showed the previous commit only
covered the openai→openai (openai-compatible passthrough) leg. The DIRECT
openai→claude leg still emitted 2 nested markers, because the Claude-side
hoist from 6d45da2050 lives on another branch line and is not an ancestor of
this branch — and that path never calls filterToOpenAIFormat.
Add hoistToolResultCacheControl() in openai-to-claude and apply it at BOTH
tool_result construction sites (the role:"tool" branch and the user-turn
tool_result part). An explicitly provided block-level marker wins over a
nested one; a tool_result with no marker gains no cache_control key.
Replay of the live body is now clean on all four combinations:
openai->openai preserve=false/true 0 nested markers
openai->claude preserve=false/true 0 nested markers
Mutation-checked: neutering the helper returns the direct leg to 2 markers.
Suite grows 5 -> 9 cases. Targeted regression run (414 cache/translator/
openai/claude/tool files): 3334 pass, 1 fail — kiro-tool-call-validation,
pre-existing and reproduced with these changes stashed out.
* refactor(translator): rename to hoistNestedToolResultCacheControl to avoid shadowing claudeHelper's body-level guard
openai-to-claude.ts and claudeHelper.ts both exported hoistToolResultCacheControl
with different signatures (content-level vs body-level). No cross-import so it
compiled, but the name collision is a readability trap. The openai-to-claude one
operates on a single tool_result's content array, so name it accordingly.
* docs(changelog): add fragment for #17257
commit 0212597367e2a169cb341f4b3dc6cc03e668c856
Author: Edo Sulai <edosulai@icloud.com>
Date: Thu Oct 22 16:55:21 2026 +0700
fix(antigravity): keep Claude tool results before merged user text (#17256)
* fix(antigravity): keep Claude tool responses before merged user text
* style(antigravity): prettier-format the Claude tool-result order change and add its changelog fragment
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
---------
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
commit 4801197b0f063fce8c7bcf5eaf9c67265b32e09e
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 11:55:10 2026 +0200
fix(dashboard): ignore obsolete initial provider loads (#17253)
* fix(dashboard): ignore obsolete initial provider loads
* docs(changelog): record #17253
commit 90c00f61a6a4045e52e04e5f60aae9d0c6fcc269
Author: Daniil Karpenko <dankarrr@gmail.com>
Date: Thu Oct 22 13:55:00 2026 +0400
fix(capabilities): resolve compat vision overrides for prefix-addressed custom nodes (#17252)
* fix(capabilities): resolve compat vision overrides for prefix-addressed custom nodes
#15086 made the canonical capability resolver read
`modelCompatOverrides.supportsVision`, but the lookup is keyed by the provider id
`PUT /api/provider-models` received — normally a custom node's internal id
(`openai-compatible-responses-<uuid>`). The catalog addresses the same node by its
user-defined prefix (`catalog.ts`'s `alias = prefix || providerIdToAlias[providerId]
|| providerId`), and so do prefix-addressed combo steps, so the operator's vision
flag stayed invisible on that path: an image request to a prefix-addressed target
was rejected as vision-incapable even though the model does accept images.
`getProviderNodeIdByPrefixSync()` adds the missing reverse index (prefix -> node id,
built from the same per-DB memo as the existing id -> prefix lookup), and the compat
vision lookup consults the mapped node id LAST so a direct key match always wins and
nothing that resolved before can change. Verified with a regression test that fails
on the base tip (4 of 5 cases) and passes with the fix; the node-id form, the prefix
form and the catalog-shaped string form now agree, an explicit `false` still flows
through, and unrelated providers keep their own verdict.
* chore(changelog): add fragment for #17252
commit e7f22bae0b952854bdfb9225dd38186ccba42237
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 11:54:50 2026 +0200
test(cursor): cover keyed mutex successor cleanup (#17251)
* test(cursor): cover keyed mutex successor cleanup
* docs(changelog): record #17251
commit 07b78c97345385bc2c189dc1c401fdf4286b9444
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 11:34:50 2026 +0200
test(batch): cover JSONL sampling boundaries (#17249)
* test(batch): cover JSONL sampling boundaries
* docs(changelog): record #17249
commit e3aa3151fb028618fe4c885a887b48216f79820d
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 11:34:39 2026 +0200
test(batch): exercise forbidden CSV mapping paths (#17248)
* test(batch): exercise forbidden CSV mapping paths
* docs(changelog): record #17248
commit 10b0f292ad3f9c833f520e3ebc7592f436fe156b
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 11:34:29 2026 +0200
fix(sse): preserve refusal deltas in buffered OpenAI SSE (#17246)
* fix(sse): preserve refusal deltas in buffered OpenAI SSE
* docs(changelog): record #17246
commit 9f32603b28613500e36d26c86d6d80af83fdf32d
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 11:34:19 2026 +0200
fix(sse): ignore non-object events in buffered OpenAI SSE (#17245)
* fix(sse): ignore non-object events in buffered OpenAI SSE
* docs(changelog): record #17245
commit 8586d1d4786a9c413f262883da8fc1a4a03df270
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 11:34:07 2026 +0200
fix(batch): require content in CSV mappings (#17244)
* fix(batch): require content in CSV mappings
* docs(changelog): record #17244
commit 639cf25fa0de37120a8a20f0f169ccca6fc6deef
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 11:33:57 2026 +0200
fix(proxy): preserve malformed percent escapes in subscription labels (#17242)
* fix(proxy): preserve malformed percent escapes in subscription labels
* docs(changelog): record #17242
commit f233d031e01ea3211a532c8202ac63ea0d43b080
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 11:33:45 2026 +0200
fix(proxy): preserve default ports in subscription URIs (#17241)
* fix(proxy): preserve default ports in subscription URIs
* docs(changelog): record #17241
commit d77ebe1010e15a9ef58a6e509820e9069b3e148e
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 11:33:34 2026 +0200
fix(batch): preserve quoted multiline CSV headers (#17240)
* fix(batch): preserve quoted multiline CSV headers
* docs(changelog): record #17240
commit 847931fba1002a8fbd63619a5053a83083b94f49
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 11:33:23 2026 +0200
fix(sse): parse native Gemini events in buffered responses (#17239)
* fix(sse): parse native Gemini events in buffered responses
* docs(changelog): record #17239
commit 9085a2a4079abff697be677573d092dc1c43da62
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 11:33:13 2026 +0200
fix(dashboard): preserve URL continuation in copied cURL commands (#17238)
* fix(dashboard): preserve URL continuation in copied cURL commands
* docs(changelog): record #17238
commit dab9ce1d28f1ddf9c535692f7fb10808932f3d94
Author: Edo Sulai <edosulai@icloud.com>
Date: Thu Oct 22 16:33:03 2026 +0700
fix(api): honor native model aliases in audio transcriptions (#17232)
* fix(api): honor native model aliases in audio transcriptions
* refactor(api): keep audio alias dispatch within complexity budget
* test(audio): prove native alias through HTTP multipart
* fix(ci): dispose compression timer and scope mirror provenance checks
* chore(changelog): name the audio alias fragment after PR #17232 and credit the author
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
---------
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
commit 90843005a09e738d2c5ac3a402b86bf8c009217f
Author: Fabio Junior Gruchovski <122614728+fabioKoruja00@users.noreply.github.com>
Date: Thu Oct 22 06:32:52 2026 -0300
docs(mcp): correct tool-cardinality activation note (#17185) (#17231)
* docs(mcp): correct tool-cardinality activation note (#17185)
* test(mcp): cover default manifest and combined tool-filter precedence (#17185)
* docs(mcp): remove stale activation claim from cardinality tests (#17185)
* docs(changelog): register PR #17231 release fragment
commit 040561f4b128530ce03f0ec0f20c8a8f180a1ec0
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 11:32:39 2026 +0200
test(sse): drain call logs before thinking test cleanup (#17224)
commit 2e18ee71d0e001610122467282fa4d6751bccfd3
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 11:32:29 2026 +0200
test(cache): wait for loaded provider data before asserting stats (#17220)
* test(cache): wait for provider data before asserting stats
* docs(changelog): reference cache wait PR 17220
* docs(changelog): file the cache page wait fragment under maintenance
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
---------
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
commit 7695ba8f3c487bf952e010ffd9970b6f097e7c10
Author: Praveen K Palaniswamy <praveen.palaniswamy@gmail.com>
Date: Thu Oct 22 05:32:18 2026 -0400
fix(cli): make restart return by starting the new server detached (#17168) (#17218)
* fix(cli): make restart return by starting the new server detached (#17168)
omniroute restart stopped the daemon and then called runServe() without
daemon: true, so it took the foreground supervisor path and never returned
to the shell, which made it unusable from scripts and scheduled tasks.
Pass daemon: true so the restarted server detaches like serve --daemon.
runRestartCommand() now accepts injectable stop/sleep/serve deps (same
pattern as runStopCommand) so the regression test never touches a real
server. Update the stale update.mjs comment that described restart as
foreground.
* chore(changelog): add #17218 fragment
commit 3fef1092a9684e09b123cc01152871a0e0bf985f
Author: Rafa Martins <146174365+rafacpti23@users.noreply.github.com>
Date: Thu Oct 22 06:32:07 2026 -0300
fix(executors): normalize Bedrock tool_use ids to ^[a-zA-Z0-9_-]+$ with pairing preserved (#17143) (#17217)
* fix(executors): normalize Bedrock tool_use ids to ^[a-zA-Z0-9_-]+$ with pairing preserved (#17143)
Bedrock validates tool-use ids against ^[a-zA-Z0-9_-]+$ and 400s the whole
request when replaying history carrying anything else. The Bedrock executor
only trimmed ids, forwarding VS Code / IDE-bridge ids with dots, colons and
slashes verbatim, so any conversation with such tool history failed with
'messages.N.content.0.tool_use.id: String should match pattern'.
normalizeToolUseId now replaces out-of-pattern characters deterministically
with a digest of the original: tool_use and tool_result go through the same
helper so the pair normalizes to the same string, distinct originals stay
distinct, and already-valid ids pass through exactly unchanged.
* fix(executors): preserve Bedrock tool IDs across normalization collisions
---------
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
commit 80dae14fec596bdaa8c5aa01bb288e921c10f715
Author: Rafa Martins <146174365+rafacpti23@users.noreply.github.com>
Date: Thu Oct 22 06:31:57 2026 -0300
chore(db): remove unreachable default-settings seeding from runMigrations (#17186) (#17216)
The post-migration guard checked appliedRecords.some(name startsWith
'051_'), but record names are the filename regex's SECOND capture group
(text after the numeric prefix), so the branch could never execute and
orphaned insertDefaultDatabaseSettings() plus its DEFAULT_DATABASE_SETTINGS
import. The defaults it would have seeded are already supplied by
merge-on-read (optimizationSettings.ts), so removal keeps behavior
exactly; a tombstone comment records why the guard was dead.
Pinned by an invariant test over the real migrations directory.
commit 6abb163824a3bb35d79d2e744a010aa75840e48e
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 11:31:46 2026 +0200
fix(batch): upload complete input files instead of preview samples (#17213)
* fix(batch): preserve complete input files during upload
* test(batch): allow time for large CSV upload regression
* docs(changelog): reference batch upload PR 17213
commit 2a2d98d25f12df2f6e07212663d52a2ad6eb70d1
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 11:31:36 2026 +0200
fix(batch): reject array-valued Anthropic params in JSONL validation (#17211)
* fix(batch): reject array-valued Anthropic params in JSONL validation
* docs(changelog): reference batch params fix PR
commit e8ba277f9d251fb2281658ead86662862c016d2c
Author: seathatflowsinourveins <234074349+seathatflowsinourveins@users.noreply.github.com>
Date: Thu Oct 22 05:31:26 2026 -0400
fix(executors): preserve explicit Codex reasoning context (#17210)
* fix(executors): preserve explicit Codex reasoning context
Preserve explicit caller reasoning context at the Codex HTTP/WebSocket wire allowlist.
Keep unsupported reasoning siblings filtered and document the model/mode boundary.
* chore(changelog): number the fixes fragment for #17210
commit df53b3d1156c375776b6859df06e924115c0b2ce
Author: Rafa Martins <146174365+rafacpti23@users.noreply.github.com>
Date: Thu Oct 22 06:31:16 2026 -0300
fix(sse): stop injecting outputDimensionality into Gemini embeddings (#17158) (#17208)
* fix(sse): stop injecting outputDimensionality into Gemini embeddings (#17158)
Google's OpenAI-compatible embeddings endpoint honors the `dimensions`
field and rejects the camelCase Gemini-native `outputDimensionality`
with 400 "Unknown name", so every sized Gemini embedding request failed
and only the default 3072-dim output stayed reachable. The native
embedContent transport already maps `dimensions` to snake_case
`output_dimensionality` itself, so the translation is unnecessary on
both paths. Forward `dimensions` untouched and refresh the stale combo
schema comment.
* docs(changelog): add fragment for the Gemini embeddings outputDimensionality fix
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
---------
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
commit bdcd6c0088f7a68bb0d18b258fcdc1d6cd44c9ce
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 09:51:26 2026 +0200
test(providers): cover the Microsoft Designer web retirement helpers (#17207)
Pin the retired provider id matching, the 410 error raised for a retired provider and the guard that recognises exactly that error.
Co-authored-by: pacocartones <pacocartones@users.noreply.github.com>
commit 9106ec32df86651cf76acb6e5a3a95ca43046aa6
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 09:51:16 2026 +0200
test(dashboard): cover the hidden sidebar group normalisation (#17206)
Pin the normalisation of the hidden sidebar groups setting: non-arrays give none, only known ids are kept, duplicates collapse and the canonical order wins.
Co-authored-by: pacocartones <pacocartones@users.noreply.github.com>
commit 3dbced5dc1d68016bb906c956a0f7ea26248b880
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 09:51:06 2026 +0200
test(cli): cover buildHealthcheckPath (#17205)
Pin that the Node bin directory is appended to the healthcheck PATH unless it is already an exact entry, using path.delimiter so the cases hold on Windows.
Co-authored-by: pacocartones <pacocartones@users.noreply.github.com>
commit 57f487b4780694c634c3f94d7fc1b34585a242e9
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 09:50:56 2026 +0200
test(providers): cover the custom model metadata precedence (#17204)
Pin that a custom model overlays only the fields it stores (null counts, undefined does not), and how discovered and custom model lists merge by id.
Co-authored-by: pacocartones <pacocartones@users.noreply.github.com>
commit 6f626bde79b91b2e4b7ffc9ec305d227df7c5dd3
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 09:50:46 2026 +0200
test(analytics): cover sortProviderDailyUsageRows (#17203)
Pin the request-count table sort: string columns by localeCompare, numeric columns as numbers, ascending and descending, and the input array left in order.
Co-authored-by: pacocartones <pacocartones@users.noreply.github.com>
commit 0f76b4e3a1376d66eaa411df1a0607940ded9de8
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 09:50:36 2026 +0200
test(proxy): cover normalizeProxyHostForLog (#17202)
Pin the proxy log host normalisation: trim, one pair of IPv6 brackets removed, lowercase, and null for anything that is not a non-empty string.
Co-authored-by: pacocartones <pacocartones@users.noreply.github.com>
commit d4b9ca8547b5c20a3a0347fd9bcdda48ce4623f6
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 09:50:25 2026 +0200
test(rate-limit): cover the connection override mapping (#17201)
Pin how a per-connection override maps onto Bottleneck options (concurrency, minimum time, a per-minute reservoir), that zero or invalid values fall through, and how the override map is loaded.
Co-authored-by: pacocartones <pacocartones@users.noreply.github.com>
commit 823c9c33dfa78dcebe1e8f97ba96f5bf1204c509
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 09:50:15 2026 +0200
test(trae): cover parseTraeApiHost and resolveTraeApiHost (#17200)
Pin that only a plain https origin under trae.ai is accepted for the token refresh host, that look-alike hosts, credentials, ports and other protocols are rejected, and that the default region is the fallback.
Co-authored-by: pacocartones <pacocartones@users.noreply.github.com>
commit 80482f49763d08694814422da4d8cdc93aa7bfff
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 09:50:05 2026 +0200
test(qwen): cover the thinking tool_choice sanitiser (#17199)
Pin when Qwen thinking is active, which tool_choice values are incompatible with it, and that only that combination is rewritten to auto with a warning that names the provider.
Co-authored-by: pacocartones <pacocartones@users.noreply.github.com>
commit 0f1505f7fdad297c6e2905311baabee31a3da5bb
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 09:49:53 2026 +0200
test(fallback): cover isRequestScoped400 (#17194)
Pin which 400 responses are request-scoped and so do not rotate accounts: parameter, context overflow and malformed request texts, while credential and throttling texts and other statuses are not.
Co-authored-by: pacocartones <pacocartones@users.noreply.github.com>
commit 68e1572858053bff2c4ff8cca3d6329e042e6abb
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 09:49:43 2026 +0200
test(sse): cover normalizeFinalOpenAIStreamChunk (#17193)
Pin the final stream chunk normalisation: numeric chunk and tool-call ids become strings, aliased tool names are restored, and the result reports changes and the finish reason of the first choice.
Co-authored-by: pacocartones <pacocartones@users.noreply.github.com>
commit 0568c16789c323b0fb39f468afb77c48d8378314
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 09:49:33 2026 +0200
test(proxy): cover sanitizeTransportError (#17192)
Pin the allowlist of the rethrown transport error: the caller's message, an allowlisted code or the fallback, the cause code, a short errorCode and a finite statusCode, and nothing else.
Co-authored-by: pacocartones <pacocartones@users.noreply.github.com>
commit f5c4fa29c13b125342bc2198d449e5a8c37f4de9
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 09:49:23 2026 +0200
test(fallback): cover the shared-wallet 402 helpers (#17191)
Pin which providers and bodies count as a shared-wallet credit exhaustion, the usage balance signal, and the generic credit check that also accepts it. The behaviour is otherwise covered only through the auth integration test.
Co-authored-by: pacocartones <pacocartones@users.noreply.github.com>
commit 4531993a1362b8a5b1d2da62c91c9d7205f9b070
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 09:49:13 2026 +0200
test(claude-code): cover the thinking display summary rule (#17190)
Pin when a compatible request gets display summarized: from the connection setting or the Copilot marker, never for disabled thinking, and how an explicit display interacts with each.
Co-authored-by: pacocartones <pacocartones@users.noreply.github.com>
commit b42e271cdddc28cac91ffad7c7db436835650e86
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 09:49:03 2026 +0200
test(gemini): cover the pasted cookie normalisation (#17189)
Pin how a bare value, a cookie header and a flat or wrapped JSON export are normalised, and when the validation variant strips the Cookie prefix or returns null for a missing PSID.
Co-authored-by: pacocartones <pacocartones@users.noreply.github.com>
commit b93849a12d1b7cc8c63daf911044436d613e7c89
Author: 小妍儿 ✨ <258399167+xiaoyaner0201@users.noreply.github.com>
Date: Thu Oct 22 15:48:53 2026 +0800
fix(cursor): preserve structured model entitlement errors (#17182)
* fix(cursor): project typed Connect errors and scope weekly model denials
* fix(cursor): preserve buffered stream errors and JSON whitespace
* fix(cursor): classify pre-output stream failures at readiness boundary
* refactor(cursor): extract JSON whitespace predicate
* fix(cursor): preserve known-type legacy debug error details
* docs(changelog): record Cursor entitlement error fix for #17182
* fix(cursor): keep generic ActionRequired quota cues alongside typed error details
Typed or debug ErrorDetails replaced the envelope message, dropping generic
ActionRequiredError quota cues and changing otherwise equivalent refusals
from 429 to 502.
Keep public details first and unchanged. Append the complete sanitized
message only within the remaining title+detail budget; omit placeholders,
duplicates and over-budget messages rather than truncating either text.
Weekly model entitlement still takes precedence as 404. Public text keeps
the existing allowlist, credential redaction and original length limits.
Verified all three focused test files in default and private TMPDIR runs
(126/126 each), including full-budget, one-character-over and exact-fit
regressions for typed/debug details. All ten external probe files passed,
including the independent legacy safety probe (8/8). The full Cursor run
passed 769 tests with 13 skips after an unchanged retry of one subprocess
SIGKILL timing assertion. Complexity/dead-code ratchets, core/open-sse/API
typechecks, lint, mutation coverage and changed-file formatting passed.
commit 0eaf0b3d320161e38c140a0c1f885fb7e896c727
Author: Samar Nathani <samarnathani0@gmail.com>
Date: Thu Oct 22 13:18:42 2026 +0530
fix(cli): gate cmd.exe arg escaping on the resolved spawn shell (#17178)
On Windows the launch call sites (launch, launch-codex, fcc-claude and run)
cmd.exe-escaped pass-through arguments unconditionally. That escaping is only
correct on the `shell: true` path (npm .cmd shims, #8837); the native-installer
path spawns a real claude.exe/codex.exe with `shell: undefined` (#9454), where
the escaped text reached the binary literally (e.g. `^^^"-p^^^"`) and every
launch was silently mangled with exit code 0.
Add one shared quoteShellArgsForSpawn(args, platform, useShell) helper and gate
every spawn/plan site on the resolved spec's `shell`, so the `run` dry-run plan
keeps matching what actually spawns.
Fixes #17177
commit e6d2cbf76e81d4d6a4ca3408bbdcd4834dfc99b9
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 09:48:33 2026 +0200
test(db): cover the API key usage-limit field helpers (#17176)
Pin the usage-limit flag (true, 1 and the string 1 only), the positive finite USD limits, the snake_case then camelCase read of a row, and the SQL assignments an update appends.
Co-authored-by: pacocartones <pacocartones@users.noreply.github.com>
commit 5bb022b5e46146a79b2036277cae2c29de70d0e6
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 09:48:23 2026 +0200
test(translator): cover conversationSignatureFields (#17175)
Pin which fields enter a tool conversation signature: the tool-call fields that are present, the item type unless it is message, and never role or content.
Co-authored-by: pacocartones <pacocartones@users.noreply.github.com>
commit a3614d34aca43e03bc61ca2c9cb0a7ccd61a606e
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 09:48:13 2026 +0200
test(cli): cover the container config write refusal message (#17174)
Pin the refusal prefix that callers use to recognise it, the tool label and target path, the host command with its placeholder, and the override hint of the refusing surface.
Co-authored-by: pacocartones <pacocartones@users.noreply.github.com>
commit c3df8a0719f75d8f855f7ca2db0e5f4785d47ff7
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 09:48:03 2026 +0200
test(oauth): cover resolveDashboardPort and buildSshLocalForward (#17173)
Pin the dashboard port resolution (explicit port, https 443, http or missing 80) and the ssh local-forward command: one -L flag per port, duplicates collapsed, host filled in and the user placeholder left.
Co-authored-by: pacocartones <pacocartones@users.noreply.github.com>
commit ef008b34ee95230d8db848511c5306e7468fb63c
Author: Paco Cartones <253313177+pacocartones@users.noreply.github.com>
Date: Thu Oct 22 09:47:53 2026 +0200
test(combo): cover isRetryAfterEligibleStatus (#17172)
Pin the statuses allowed to carry a retry-after suffix on an all-targets-failed combo response: 429 and 503 only, never a config-class status such as 422, and nothing that is not a real number.
Co-authored-by: pacocartones <pacocartones@users.noreply.github.com>
commit 686769758c62154d17d2f2d7402d3795fc886930
Author: Mike Ng <iam@mikeng.io>
Date: Thu Oct 22 15:21:47 2026 +0800
fix(cache): version and canonicalize response control identities (#17161)
* fix(cache): version and canonicalize response control identities
* docs(cache): add response identity changelog fragment
* fix(cache): reuse the semanticCache import for canonical JSON and pin the schema:2 plain-text keys
Re-export canonicalJson from src/lib/semanticCache so the open-sse cache manager adds no new open-sse to src boundary edge (ratchet stays at 774), and align the #15816 plain-text key test to the intentional schema:2 identity while asserting the legacy payload is no longer reused.
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
---------
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
commit fa885d4699deb386484e91eff203935cdbeab078
Author: opensource-elearning <159253500+opensource-elearning@users.noreply.github.com>
Date: Thu Oct 22 12:51:37 2026 +0530
perf(resilience): memoize resolveResilienceSettings by settings object identity (#17153)
* perf(resilience): memoize resolveResilienceSettings by settings object identity
resolveResilienceSettings() is called on every request from chatCore.ts:417
and performs 13 normalizations + a full legacy fallback rebuild per call.
The settings object comes from getCachedSettings() which uses a TTLCache
with a 5s TTL that returns the SAME object reference on cache hits.
This change adds a WeakMap cache keyed by that exact object reference,
so repeated requests within the 5s window reuse the fully resolved
ResilienceSettings object.
Cold: 13 normalizations + fallback + object construction
Warm (within 5s): single WeakMap get + return (zero normalizations)
No behavior change: settings are immutable per request, and the cache
auto-invalidates when settings are updated (TTLCache evicts old object,
new object created, WeakMap key differs).
Tests: resilience-stream-recovery-feature-flags, providerCooldownTracker,
stream-throughput-watchdog, auto-routing-settings-resolve, cli-resilience-commands
all pass.
* test(resilience): cover settings memoization identity and invalidation
* docs(resilience): note the memoized settings are shared and env defaults frozen per object; add changelog fragment
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
---------
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
commit cd8706b36f5f22240a58806585433282d30b0b1c
Author: Dizzle <112548150+maxmad64bis@users.noreply.github.com>
Date: Thu Oct 22 09:21:27 2026 +0200
fix(syntx): cap SYNTX media download and data-URL decode at 50 MiB (#17152)
SYNTX media fetched by URL and the three data-URL decodes loaded unbounded content into memory; the download now enforces a 50 MiB limit (413) and a client abort (499), and the data-URL decodes reject oversized payloads before allocating (400)
commit dbd6492ba9cec6b33bc9788f449cceab21e2dee7
Author: opensource-elearning <159253500+opensource-elearning@users.noreply.github.com>
Date: Thu Oct 22 12:51:17 2026 +0530
perf(logging): build the HH:MM:SS clock prefix without a locale formatter (#17149)
* perf(logging): build the HH:MM:SS clock prefix without a locale formatter
getTimeString() in streamHandler.ts and usageTracking.ts called
toLocaleTimeString('en-US', ...) for every stream completion and every
usage line. Intl formatting dominates that helper; the value it returns
is a fixed zero-padded HH:MM:SS, so it can be built directly.
Measured on Node 24.21.0, 100k iterations x 11 alternating rounds,
production shape (a fresh new Date() inside each call):
toLocaleTimeString median 63.19 us/call
padStart median 0.30 us/call
saved 62.89 us/call
Two calls per request (one usage line, one stream completion log) is
~0.13 ms/request; ~126 s per million requests.
Output is unchanged: compared the two implementations across 518,400
second-resolution instants spanning 6 dates (incl. a leap day and both
DST boundaries) with zero value mismatches, and every value still
matches the strict CLOCK_TOKEN_RE /^\d{2}:\d{2}:\d{2}$/ the console
interceptor uses.
Also drops an unused catch binding in usageTracking.ts that the lint
gate reported, and prunes its now-orphaned suppression entry.
New test pins the log prefix shape and fails on a 12-hour-clock
regression.
* test(logging): cover clock boundaries and interceptor parsing
* chore(changelog): add the clock-prefix fragment with credit
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
---------
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
commit 679c736c59960ad4a90ce9cd3fe19566cabdd34b
Author: opensource-elearning <159253500+opensource-elearning@users.noreply.github.com>
Date: Thu Oct 22 12:51:05 2026 +0530
perf(build): enable incremental TypeScript for the open-sse workspace typecheck (#17147)
* perf(build): enable incremental TypeScript for the open-sse workspace typecheck
open-sse/tsconfig.json was the one typecheck config left without
incremental state after #16342 covered the four root configs. The
open-sse gate therefore re-checked the whole workspace (~26k files,
checkJs on JS too) on every invocation.
Adds incremental + tsBuildInfoFile, reusing the existing
.gitignore:306 '.tsbuildinfo-*' rule, so no build artefacts are
tracked.
Measured with node scripts/check/check-open-sse-typecheck.mjs on
Node 24.21.0 / tsc 6.0.3, 5 runs each:
cold (no build-info) 25.6s
warm (build-info) 6.3s
Correctness: a warm run still emits every diagnostic. Verified by
injecting a deliberate TS2322 into the workspace, confirming it is
reported on both the first and second run, then fixing it and
confirming a clean exit. The gate reports
openSseTypecheckErrors=0 against the frozen baseline in both states.
* chore(changelog): name the open-sse incremental typecheck fragment after its PR with credit
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
---------
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
commit 2b99af7bd9e98b0f37513c90fb479f865b02310f
Author: Devulapalli Naga Sri Vaishnavi <vaishnaviharish2006@gmail.com>
Date: Thu Oct 22 12:50:53 2026 +0530
Preserve tool calls in textual reasoning chunks (#17144)
* fix(responses): preserve tool calls in textual reasoning chunks
* chore(changelog): name the fragment with the PR number and add the contributor credit (#17144)
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
---------
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
commit 36613be7064a505c55a3a7ee356776c706488b5d
Author: Saeb Amini <SaebAmini@users.noreply.github.com>
Date: Thu Oct 22 17:20:40 2026 +1000
Add Max Output Tokens override to Custom Models section (#17140)
* Add max-output-tokens override editor to custom models list
* Add maxOutputTokenOverride field to CompatModelRow type
* Add maxOutputTokenOverrideInvalid translation key
* feat(dashboard): translate the max-output-tokens override error in all locales, add UI test and changelog fragment (#17140)
Adds providers.maxOutputTokenOverrideInvalid to the 66 locale catalogs, a vitest UI test covering load / number / blank-clears / invalid-no-PUT for the Custom Models editor, and the features fragment.
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
---------
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
commit 5b77da523f0c6f34958cb38a71375b6400d1f137
Author: Dizzle <112548150+maxmad64bis@users.noreply.github.com>
Date: Thu Oct 22 09:20:29 2026 +0200
fix(sse): reject shut-down models regardless of id letter case (#17135)
The lifecycle lookup key ignores letter case on the model side like the snapshot did, so non-lowercase spellings of a shut-down model id get the record verdict (410, which then cites the canonical record id) instead of being routed.
commit 6e4b353549145d6bfd8d677398df8d5e70af9aa6
Author: Dizzle <112548150+maxmad64bis@users.noreply.github.com>
Date: Thu Oct 22 09:20:16 2026 +0200
fix(sse): add the compat-rejected last-resort fallback to the universal combo dispatch (#17120)
the round-robin-only last-resort tier was missing from the shared dispatch loop, so a priority combo whose kept targets were all skipped answered 503 without reconsidering a compat-rejected-but-healthy target; the rejected set is now computed at resolution, threaded into the loop, and probed only when no kept target was ever attempted — each new case fails without the change.
commit 20683172beed44ccf29e86863c3217e5c6eb0808
Author: Andres Felipe Diago Matta <82129635+AndresDiagoM@users.noreply.github.com>
Date: Thu Oct 22 02:20:04 2026 -0500
fix(sse): hand Anthropic-format clients their declared tool-name casing from every provider (#17118) (#17119)
* fix(sse): hand Anthropic-format clients their declared tool-name casing from every provider
Claude-format responses assembled by openai-to-claude, gemini-to-claude and the
non-streaming responseTranslator all ended in restoreClaudeToolName(), whose
canonical upgrade (read -> Read, #7926/#9008/#10392/#11085) assumes the client
is Claude Code. OpenCode's @ai-sdk/anthropic provider declares lowercase tools,
so a combo falling back from native claude to Antigravity, Codex or Gemini (or
any of those used directly over /v1/messages) answered with tool_use.name
"Read" for a tool declared as "read", and every tool call failed client-side
("No tool named Read").
Lift the #12721 passthrough rule into a shared module and apply it on the
translate paths too: alias ledger first, then the CLIENT request's declared
spelling (exact, then case-insensitive), then the legacy canonical upgrade only
for names the request never declared. Claude Code declares "Read", so it keeps
getting "Read" back when an OpenAI-style upstream downcases it; OpenCode gets
"read" back from the same upstream. The client's tools[] is threaded into the
translate-mode stream state and into translateNonStreamingResponse.
* docs(changelog): add fragment for #17119
* fix(sse): keep streamBufferBytes the last parameter of the transform helper
clientTools now sits before streamBufferBytes, so the trailing buffer-size slot GLM fills (#12925) stays last and GLM's call matches the helper arity. GLM passes null for clientTools; the translate call in streamingTail drops its placeholder undefined.
* fix(sse): carry declared tools through Claude passthrough (#17118)
* refactor(sse): split declaredToolCasing helpers under the complexity gate
findDeclaredToolName (cyclomatic 17, cognitive 18) and restoreDeclaredToolName
(cognitive 17) were over the new-code limit of 15. Extract declaredNameOf()
for the per-entry tools[] spelling and aliasLedgerName() for the _toolNameMap
precedence; behaviour is unchanged and the 17118/17119 suites still pass.
---------
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
commit 4aa9958bc2966f9d38d325e92f9d709d05a1e51b
Author: Dizzle <112548150+maxmad64bis@users.noreply.github.com>
Date: Thu Oct 22 09:19:53 2026 +0200
fix(sse): a second 429 with a shorter cooldown no longer shortens the active cooldown (#17116)
markRateLimited overwrote the expiry unconditionally, so a second 429 with a shorter cooldown reopened the combo target early; the assignment now keeps the later expiry
commit 2d43b5c83b41970490bdb405615726c9eb41e045
Author: Davy Massoneto <davy.massoneto@yahoo.com>
Date: Thu Oct 22 04:19:41 2026 -0300
fix: preserve capped Claude output when fitting thinking budget (#17110)
* fix: preserve capped Claude output when fitting thinking budget
* docs: add changelog for Claude thinking budget fix
commit ce826c8c21edd72872c40a80e2d625b1d9a9b884
Author: Junior-HJ <sjaradj@ucvvirtual.edu.pe>
Date: Thu Oct 22 02:19:12 2026 -0500
fix(codebuddy): harden gateway compliance and tool schema contracts (#17080)
* fix(codebuddy): harden gateway compliance and tool schema contracts
* style(test): format codebuddy gateway hardening test with prettier
commit 5d315a9562064a6eec61cb2fd7832f65db01e991
Author: opensource-elearning <159253500+opensource-elearning@users.noreply.github.com>
Date: Thu Oct 22 12:49:02 2026 +0530
feat(sse): let the quota-refusal egress scope cover every provider (#17074)
* feat(sse): let the quota-refusal egress scope cover every provider
A 429 received through a proxy pool member set that member aside only for the
IP-bucketed family (opencode-go, opencode-cli, plus opencode-zen when its flag
is on). Every other provider kept egressing through the member that had just
answered 429, so a rate limit could not rotate the address — worst for the free
and keyless providers, whose quota is per IP because there is no key to bucket
by.
rotatesEgressOnQuotaRefusal() widens that write to every provider when the
operator sets OMNIROUTE_EGRESS_QUOTA_ROTATION_PROVIDERS=all, and keeps the
IP-bucketed family as the only default. The clear-on-success arm, the
sibling-connection lockout and every existing default are unch…
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.
This currently fails CI on every open PR in the repo, including ones that touch nothing near it.
#12179gave GLM a 64 KB stream buffer by adding a 16th argument tocreateSSETransformStreamWithLogger:The signature takes 15. Two things followed.
The visible one.
open-sse/executors/glm.ts(244,5): error TS2554: Expected 2-15 arguments, but got 16.The API Route Typecheck gate is "reject new errors not covered by the frozen baseline", so it reports1 new/regressed TypeScript errorand fails — on any PR, since nobody's branch removes it. I found it while auditing my own open PRs: #12896 fails the identical 8 checks after a clean rebase ontorelease/v3.8.51, with a test that passes locally, and #12919 (not mine) fails the same 8.The quiet one. The extra argument was simply dropped, and
createSSEStreamhard-coded the queue budget:So the 64 KB that call site asks for never reached the stream. The perf change that hunk describes has not been in effect since it landed — the comment above it has been describing something that does not happen.
The change
StreamOptionsgainsstreamBufferBytes, defaulting to the16384every provider used before it was configurable; the convenience wrapper takes it as a 16th parameter and forwards it; both queues use it.glm.tsis unchanged — its existing call now compiles and takes effect, which is the smallest edit that makes the original intent true rather than deleting it.The default is a parameter default rather than
|| DEFAULT, so a deliberate0— a queue that applies backpressure immediately — is honoured instead of silently replaced. There is a test for exactly that, because||here is the easy way to write it and the wrong one.Verification
tsc -p tsconfig.typecheck-api.json: 299 → 298 errors. The one removed isglm.tsTS2554, the one the gate names. Nothing new appears; the remainingstream.tsTS2353 aboutcancelis in the frozen baseline (it sat at line 2986 before this change and 2998 after — same error, shifted by the added lines).tests/unit/sse-stream-buffer-bytes.test.ts: 5 passed. ATransformStream's writable queue starts withdesiredSize === highWaterMark, so the assertions measure the queue that was actually built rather than standing in for it.Each claim checked by breaking it:
16384|| DEFAULTstreamBufferBytes: 0testI have not touched the buffer size for any other provider: without the option, every stream still gets 16384.