Repository navigation
feat(sse): opt-in Claude delta coalescing, frame batching and interval stall watchdog - #16722
Merged
diegosouzapw merged 74 commits intoOct 15, 2026
Merged
Conversation
…l stall watchdog
All three are OFF by default; with no env set the stream is byte-identical
and makes the same enqueue/timer calls as before.
- SSE_COALESCE_MS / SSE_COALESCE_{THINKING,TEXT,INPUT_JSON}_MS: merge
consecutive Claude content_block_delta frames (same index and delta type)
sent to Claude clients, losslessly. Runs on the formatted frames forward()
emits, so the translate lane and the claude->claude passthrough lane are
both covered. signature_delta, boundary events and anything unparseable
flush the pending group first, keeping order.
- SSE_FRAME_COALESCE_MS: batch frames forwarded inside the window into one
enqueue. The first frame and terminal frames ([DONE], message_stop, error,
response.completed/failed/incomplete) are never held back.
- SSE_STALL_WATCHDOG=interval: the pipeWithDisconnect byte-stall watchdog
stamps the last chunk time and checks it from one unref'd interval per
stream instead of re-arming a timer per chunk. Default stays `timer`.
forward() moves into open-sse/utils/sseOutputSink.ts; the transformer is
wrapped so flush() drains pending output and cancel() disposes the timers.
Co-authored-by: Nikan Wystaf <nikan.wystaf@gmail.com>
Inspired-by: decolua/9router#4658
Co-authored-by: wallerjenifernk530-hash <wallerjenifernk530-hash@users.noreply.github.com>
Inspired-by: decolua/9router#4721
…sync diff/resolve (#16721) The `omniroute sync` subcommands were written against an API the server never had: - `sync push` sent `{parts, dryRun, target}` to `POST /api/sync/cloud`, whose schema only accepts `{action: "enable"|"sync"|"disable"}`, so it always failed with 400. It now sends `{action: "sync"}` (the dashboard's call), never retries it (the "Cloud sync is disabled" refusal is a 502 and a sync is not idempotent), and explains a disabled cloud sync or a missing manage-scoped credential. --target/--bundle/--dry-run are dropped. - `sync bundle` sent the API key plus an ignored `?parts=` to `GET /api/sync/bundle`, which accepts only a sync token. It now takes `--token` (or OMNIROUTE_SYNC_TOKEN), fails before any request without one, and writes the `{version, bundle}` JSON to an owner-only file it never overwrites. --include is dropped (the route always returns the whole bundle). - `sync diff` / `sync resolve` called `GET /api/sync/cloud?op=diff|conflicts`; the route ignores `op` and answers with the cloud status, so they printed a status (or did nothing) silently. No server route computes a diff or lists conflicts, so both are removed. - `sync initialize --from-cloud` sent a flag the route never reads; the flag is dropped. All of them now go through apiFetch with the global connection options (so a loopback server gets the local CLI credential) and report `HTTP <status>: <server message>` plus a hint with the usual CLI exit codes. `sync pull` reuses the same helpers unchanged in behavior. The unused CLI locale keys go away from all 67 catalogs (key parity kept), the generated cli-backup-sync skill is regenerated, FEATURES.md no longer claims the config bundle holds only non-sensitive settings (it carries provider credentials and API keys), and the new env var is documented in .env.example / ENVIRONMENT.md. The two stub tests in cli-sync-commands.test.ts that asserted the buggy contracts are replaced by tests/unit/cli-sync-subcommands-routes.test.ts, which drives the real registerSync() wiring; their removal drops 6 `any` from the frozen suppression count.
…s, settings and providers routes (#16671) This PR: POST /api/logs/detail, PATCH and PUT /api/settings, DELETE /api/providers answer 400 for a non-object JSON body. Covered by tests/unit/mgmt-null-json-body-400.test.ts. Validated on the combined pacocartones board 5a429eab (30 PRs, clean merges, each refs/prs/N ancestor of HEAD) against release/v3.8.52. Focused node tests on that tree: 82 passed, 0 failed. typecheck:core is red only on lines that already exist on origin/release/v3.8.52 (open-sse/translator/request/openai-to-claude.ts and open-sse/utils/dsmlToolCalls.ts are byte-identical; the never-typed pushes in response/openai-to-claude.ts sit outside this batch's hunks). open-sse typecheck reports 3 errors in files byte-identical to origin/release/v3.8.52 (copilotAutoModel.ts TS2339 x2, request/openai-responses.ts TS2345 x1). The baseline was not widened. Changelog integrity passed. File-size growth is confined to src/sse/handlers/chat.ts and is handled on #16668/#16615, not in this PR.⚠️ base-red inherited: #15306 Thanks @pacocartones.
…ashboard and management list routes (#16661) This PR: non-integer limit, offset and page answer 400 on the management list routes via src/lib/api/queryIntegerParam.ts. Covered by tests/unit/mgmt-list-params-validation.test.ts. Validated on the combined pacocartones board 5a429eab (30 PRs, clean merges, each refs/prs/N ancestor of HEAD) against release/v3.8.52. Focused node tests on that tree: 82 passed, 0 failed. typecheck:core is red only on lines that already exist on origin/release/v3.8.52 (open-sse/translator/request/openai-to-claude.ts and open-sse/utils/dsmlToolCalls.ts are byte-identical; the never-typed pushes in response/openai-to-claude.ts sit outside this batch's hunks). open-sse typecheck reports 3 errors in files byte-identical to origin/release/v3.8.52 (copilotAutoModel.ts TS2339 x2, request/openai-responses.ts TS2345 x1). The baseline was not widened. Changelog integrity passed. File-size growth is confined to src/sse/handlers/chat.ts and is handled on #16668/#16615, not in this PR.⚠️ base-red inherited: #15306 Thanks @pacocartones.
…assthrough (#16614) This PR: a numeric delta.content stays string text. Covered by tests/unit/openai-numeric-delta-content.test.ts. Validated on the combined pacocartones board 5a429eab (30 PRs, clean merges, each refs/prs/N ancestor of HEAD) against release/v3.8.52. Focused node tests on that tree: 82 passed, 0 failed. typecheck:core is red only on lines that already exist on origin/release/v3.8.52 (open-sse/translator/request/openai-to-claude.ts and open-sse/utils/dsmlToolCalls.ts are byte-identical; the never-typed pushes in response/openai-to-claude.ts sit outside this batch's hunks). open-sse typecheck reports 3 errors in files byte-identical to origin/release/v3.8.52 (copilotAutoModel.ts TS2339 x2, request/openai-responses.ts TS2345 x1). The baseline was not widened. Changelog integrity passed. File-size growth is confined to src/sse/handlers/chat.ts and is handled on #16668/#16615, not in this PR.⚠️ base-red inherited: #15306 Thanks @pacocartones.
…d DeepInfra builders (#16609) This PR: a null rerank document becomes an empty passage for NVIDIA and DeepInfra. Covered by tests/unit/rerank-null-document.test.ts. Validated on the combined pacocartones board 5a429eab (30 PRs, clean merges, each refs/prs/N ancestor of HEAD) against release/v3.8.52. Focused node tests on that tree: 82 passed, 0 failed. typecheck:core is red only on lines that already exist on origin/release/v3.8.52 (open-sse/translator/request/openai-to-claude.ts and open-sse/utils/dsmlToolCalls.ts are byte-identical; the never-typed pushes in response/openai-to-claude.ts sit outside this batch's hunks). open-sse typecheck reports 3 errors in files byte-identical to origin/release/v3.8.52 (copilotAutoModel.ts TS2339 x2, request/openai-responses.ts TS2345 x1). The baseline was not widened. Changelog integrity passed. File-size growth is confined to src/sse/handlers/chat.ts and is handled on #16668/#16615, not in this PR.⚠️ base-red inherited: #15306 Thanks @pacocartones.
…sconnects (#16607) This PR: devin-cli does not write to a stream after the client disconnects. Covered by tests/unit/devin-cli-client-disconnect.test.ts. Validated on the combined pacocartones board 5a429eab (30 PRs, clean merges, each refs/prs/N ancestor of HEAD) against release/v3.8.52. Focused node tests on that tree: 82 passed, 0 failed. typecheck:core is red only on lines that already exist on origin/release/v3.8.52 (open-sse/translator/request/openai-to-claude.ts and open-sse/utils/dsmlToolCalls.ts are byte-identical; the never-typed pushes in response/openai-to-claude.ts sit outside this batch's hunks). open-sse typecheck reports 3 errors in files byte-identical to origin/release/v3.8.52 (copilotAutoModel.ts TS2339 x2, request/openai-responses.ts TS2345 x1). The baseline was not widened. Changelog integrity passed. File-size growth is confined to src/sse/handlers/chat.ts and is handled on #16668/#16615, not in this PR.⚠️ base-red inherited: #15306 Thanks @pacocartones.
… stream end (#16606) This PR: an unclosed invoke or tool_call tail is released as text when the stream ends. Covered by tests/unit/openai-to-claude-unclosed-invoke-tail.test.ts. Validated on the combined pacocartones board 5a429eab (30 PRs, clean merges, each refs/prs/N ancestor of HEAD) against release/v3.8.52. Focused node tests on that tree: 82 passed, 0 failed. typecheck:core is red only on lines that already exist on origin/release/v3.8.52 (open-sse/translator/request/openai-to-claude.ts and open-sse/utils/dsmlToolCalls.ts are byte-identical; the never-typed pushes in response/openai-to-claude.ts sit outside this batch's hunks). open-sse typecheck reports 3 errors in files byte-identical to origin/release/v3.8.52 (copilotAutoModel.ts TS2339 x2, request/openai-responses.ts TS2345 x1). The baseline was not widened. Changelog integrity passed. File-size growth is confined to src/sse/handlers/chat.ts and is handled on #16668/#16615, not in this PR.⚠️ base-red inherited: #15306 Thanks @pacocartones.
…etadata (#16556) This PR: combo metadata honours a member max_output_tokens override. Covered by tests/unit/16515-combo-max-output-override.test.ts. catalog.ts stays under its frozen ceiling. Validated on the combined pacocartones board 5a429eab (30 PRs, clean merges, each refs/prs/N ancestor of HEAD) against release/v3.8.52. Focused node tests on that tree: 82 passed, 0 failed. typecheck:core is red only on lines that already exist on origin/release/v3.8.52 (open-sse/translator/request/openai-to-claude.ts and open-sse/utils/dsmlToolCalls.ts are byte-identical; the never-typed pushes in response/openai-to-claude.ts sit outside this batch's hunks). open-sse typecheck reports 3 errors in files byte-identical to origin/release/v3.8.52 (copilotAutoModel.ts TS2339 x2, request/openai-responses.ts TS2345 x1). The baseline was not widened. Changelog integrity passed. File-size growth is confined to src/sse/handlers/chat.ts and is handled on #16668/#16615, not in this PR.⚠️ base-red inherited: #15306 Thanks @pacocartones.
…reaming path does (#16544) This PR: non-streaming Claude stop reasons are normalized the same way as the streaming path. Covered by tests/unit/claude-nonstream-stop-reasons.test.ts. Validated on the combined pacocartones board 5a429eab (30 PRs, clean merges, each refs/prs/N ancestor of HEAD) against release/v3.8.52. Focused node tests on that tree: 82 passed, 0 failed. typecheck:core is red only on lines that already exist on origin/release/v3.8.52 (open-sse/translator/request/openai-to-claude.ts and open-sse/utils/dsmlToolCalls.ts are byte-identical; the never-typed pushes in response/openai-to-claude.ts sit outside this batch's hunks). open-sse typecheck reports 3 errors in files byte-identical to origin/release/v3.8.52 (copilotAutoModel.ts TS2339 x2, request/openai-responses.ts TS2345 x1). The baseline was not widened. Changelog integrity passed. File-size growth is confined to src/sse/handlers/chat.ts and is handled on #16668/#16615, not in this PR.⚠️ base-red inherited: #15306 Thanks @pacocartones.
…es client as incomplete (#16517) This PR: a truncated non-streaming Chat turn reaches a Responses client as incomplete. Covered by tests/unit/responses-client-incomplete-nonstreaming.test.ts. Validated on the combined pacocartones board 5a429eab (30 PRs, clean merges, each refs/prs/N ancestor of HEAD) against release/v3.8.52. Focused node tests on that tree: 82 passed, 0 failed. typecheck:core is red only on lines that already exist on origin/release/v3.8.52 (open-sse/translator/request/openai-to-claude.ts and open-sse/utils/dsmlToolCalls.ts are byte-identical; the never-typed pushes in response/openai-to-claude.ts sit outside this batch's hunks). open-sse typecheck reports 3 errors in files byte-identical to origin/release/v3.8.52 (copilotAutoModel.ts TS2339 x2, request/openai-responses.ts TS2345 x1). The baseline was not widened. Changelog integrity passed. File-size growth is confined to src/sse/handlers/chat.ts and is handled on #16668/#16615, not in this PR.⚠️ base-red inherited: #15306 Thanks @pacocartones.
…th length for Chat clients (#16507) This PR: a truncated non-streaming Responses turn finishes with length for Chat clients. Covered by tests/unit/responses-incomplete-nonstreaming-chat.test.ts. Validated on the combined pacocartones board 5a429eab (30 PRs, clean merges, each refs/prs/N ancestor of HEAD) against release/v3.8.52. Focused node tests on that tree: 82 passed, 0 failed. typecheck:core is red only on lines that already exist on origin/release/v3.8.52 (open-sse/translator/request/openai-to-claude.ts and open-sse/utils/dsmlToolCalls.ts are byte-identical; the never-typed pushes in response/openai-to-claude.ts sit outside this batch's hunks). open-sse typecheck reports 3 errors in files byte-identical to origin/release/v3.8.52 (copilotAutoModel.ts TS2339 x2, request/openai-responses.ts TS2345 x1). The baseline was not widened. Changelog integrity passed. File-size growth is confined to src/sse/handlers/chat.ts and is handled on #16668/#16615, not in this PR.⚠️ base-red inherited: #15306 Thanks @pacocartones.
…f raw or clean stop reasons (#16501) This PR: Claude clients receive refusal and max_tokens instead of a raw or clean stop. Covered by tests/unit/claude-client-stop-reasons.test.ts. Validated on the combined pacocartones board 5a429eab (30 PRs, clean merges, each refs/prs/N ancestor of HEAD) against release/v3.8.52. Focused node tests on that tree: 82 passed, 0 failed. typecheck:core is red only on lines that already exist on origin/release/v3.8.52 (open-sse/translator/request/openai-to-claude.ts and open-sse/utils/dsmlToolCalls.ts are byte-identical; the never-typed pushes in response/openai-to-claude.ts sit outside this batch's hunks). open-sse typecheck reports 3 errors in files byte-identical to origin/release/v3.8.52 (copilotAutoModel.ts TS2339 x2, request/openai-responses.ts TS2345 x1). The baseline was not widened. Changelog integrity passed. File-size growth is confined to src/sse/handlers/chat.ts and is handled on #16668/#16615, not in this PR.⚠️ base-red inherited: #15306 Thanks @pacocartones.
This PR: the SambaNova free catalog matches that provider's free-tier table (MiniMax and Llama-4 leave the free catalog, DeepSeek-V3.1 and gemma-4-31B-it join it, curated date 2026-10-10). Covered by tests/unit/sambanova-free-models-2026-10.test.ts. The SVG label change is a screenshot, not an agent-instruction surface. Validated on the combined pacocartones board 5a429eab (30 PRs, clean merges, each refs/prs/N ancestor of HEAD) against release/v3.8.52. Focused node tests on that tree: 82 passed, 0 failed. typecheck:core is red only on lines that already exist on origin/release/v3.8.52 (open-sse/translator/request/openai-to-claude.ts and open-sse/utils/dsmlToolCalls.ts are byte-identical; the never-typed pushes in response/openai-to-claude.ts sit outside this batch's hunks). open-sse typecheck reports 3 errors in files byte-identical to origin/release/v3.8.52 (copilotAutoModel.ts TS2339 x2, request/openai-responses.ts TS2345 x1). The baseline was not widened. Changelog integrity passed. File-size growth is confined to src/sse/handlers/chat.ts and is handled on #16668/#16615, not in this PR.⚠️ base-red inherited: #15306 Thanks @pacocartones.
…#16620) This PR: real Spanish translations of UI strings that were still in English. Replacements in that locale file only, no new keys. The inherited my/phi ratio gap on the release tip was left untouched. Validated on the combined pacocartones board 5a429eab (30 PRs, clean merges, each refs/prs/N ancestor of HEAD) against release/v3.8.52. Focused node tests on that tree: 82 passed, 0 failed. typecheck:core is red only on lines that already exist on origin/release/v3.8.52 (open-sse/translator/request/openai-to-claude.ts and open-sse/utils/dsmlToolCalls.ts are byte-identical; the never-typed pushes in response/openai-to-claude.ts sit outside this batch's hunks). open-sse typecheck reports 3 errors in files byte-identical to origin/release/v3.8.52 (copilotAutoModel.ts TS2339 x2, request/openai-responses.ts TS2345 x1). The baseline was not widened. Changelog integrity passed. File-size growth is confined to src/sse/handlers/chat.ts and is handled on #16668/#16615, not in this PR.⚠️ base-red inherited: #15306 Thanks @pacocartones.
…ish (#16641) This PR: real Vietnamese translations of UI strings that were still in English. Replacements in that locale file only, no new keys. The inherited my/phi ratio gap on the release tip was left untouched. Validated on the combined pacocartones board 5a429eab (30 PRs, clean merges, each refs/prs/N ancestor of HEAD) against release/v3.8.52. Focused node tests on that tree: 82 passed, 0 failed. typecheck:core is red only on lines that already exist on origin/release/v3.8.52 (open-sse/translator/request/openai-to-claude.ts and open-sse/utils/dsmlToolCalls.ts are byte-identical; the never-typed pushes in response/openai-to-claude.ts sit outside this batch's hunks). open-sse typecheck reports 3 errors in files byte-identical to origin/release/v3.8.52 (copilotAutoModel.ts TS2339 x2, request/openai-responses.ts TS2345 x1). The baseline was not widened. Changelog integrity passed. File-size growth is confined to src/sse/handlers/chat.ts and is handled on #16668/#16615, not in this PR.⚠️ base-red inherited: #15306 Thanks @pacocartones.
…#16630) This PR: real Russian translations of UI strings that were still in English. Replacements in that locale file only, no new keys. The inherited my/phi ratio gap on the release tip was left untouched. Validated on the combined pacocartones board 5a429eab (30 PRs, clean merges, each refs/prs/N ancestor of HEAD) against release/v3.8.52. Focused node tests on that tree: 82 passed, 0 failed. typecheck:core is red only on lines that already exist on origin/release/v3.8.52 (open-sse/translator/request/openai-to-claude.ts and open-sse/utils/dsmlToolCalls.ts are byte-identical; the never-typed pushes in response/openai-to-claude.ts sit outside this batch's hunks). open-sse typecheck reports 3 errors in files byte-identical to origin/release/v3.8.52 (copilotAutoModel.ts TS2339 x2, request/openai-responses.ts TS2345 x1). The baseline was not widened. Changelog integrity passed. File-size growth is confined to src/sse/handlers/chat.ts and is handled on #16668/#16615, not in this PR.⚠️ base-red inherited: #15306 Thanks @pacocartones.
#16633) This PR: real Japanese translations of UI strings that were still in English. Replacements in that locale file only, no new keys. The inherited my/phi ratio gap on the release tip was left untouched. Validated on the combined pacocartones board 5a429eab (30 PRs, clean merges, each refs/prs/N ancestor of HEAD) against release/v3.8.52. Focused node tests on that tree: 82 passed, 0 failed. typecheck:core is red only on lines that already exist on origin/release/v3.8.52 (open-sse/translator/request/openai-to-claude.ts and open-sse/utils/dsmlToolCalls.ts are byte-identical; the never-typed pushes in response/openai-to-claude.ts sit outside this batch's hunks). open-sse typecheck reports 3 errors in files byte-identical to origin/release/v3.8.52 (copilotAutoModel.ts TS2339 x2, request/openai-responses.ts TS2345 x1). The baseline was not widened. Changelog integrity passed. File-size growth is confined to src/sse/handlers/chat.ts and is handled on #16668/#16615, not in this PR.⚠️ base-red inherited: #15306 Thanks @pacocartones.
…16636) This PR: real Korean translations of UI strings that were still in English. Replacements in that locale file only, no new keys. The inherited my/phi ratio gap on the release tip was left untouched. Validated on the combined pacocartones board 5a429eab (30 PRs, clean merges, each refs/prs/N ancestor of HEAD) against release/v3.8.52. Focused node tests on that tree: 82 passed, 0 failed. typecheck:core is red only on lines that already exist on origin/release/v3.8.52 (open-sse/translator/request/openai-to-claude.ts and open-sse/utils/dsmlToolCalls.ts are byte-identical; the never-typed pushes in response/openai-to-claude.ts sit outside this batch's hunks). open-sse typecheck reports 3 errors in files byte-identical to origin/release/v3.8.52 (copilotAutoModel.ts TS2339 x2, request/openai-responses.ts TS2345 x1). The baseline was not widened. Changelog integrity passed. File-size growth is confined to src/sse/handlers/chat.ts and is handled on #16668/#16615, not in this PR.⚠️ base-red inherited: #15306 Thanks @pacocartones.
…t in English (#16639) This PR: real Traditional Chinese translations of UI strings that were still in English. Replacements in that locale file only, no new keys. The inherited my/phi ratio gap on the release tip was left untouched. Validated on the combined pacocartones board 5a429eab (30 PRs, clean merges, each refs/prs/N ancestor of HEAD) against release/v3.8.52. Focused node tests on that tree: 82 passed, 0 failed. typecheck:core is red only on lines that already exist on origin/release/v3.8.52 (open-sse/translator/request/openai-to-claude.ts and open-sse/utils/dsmlToolCalls.ts are byte-identical; the never-typed pushes in response/openai-to-claude.ts sit outside this batch's hunks). open-sse typecheck reports 3 errors in files byte-identical to origin/release/v3.8.52 (copilotAutoModel.ts TS2339 x2, request/openai-responses.ts TS2345 x1). The baseline was not widened. Changelog integrity passed. File-size growth is confined to src/sse/handlers/chat.ts and is handled on #16668/#16615, not in this PR.⚠️ base-red inherited: #15306 Thanks @pacocartones.
…#16647) This PR: real Turkish translations of UI strings that were still in English. Replacements in that locale file only, no new keys. The inherited my/phi ratio gap on the release tip was left untouched. Validated on the combined pacocartones board 5a429eab (30 PRs, clean merges, each refs/prs/N ancestor of HEAD) against release/v3.8.52. Focused node tests on that tree: 82 passed, 0 failed. typecheck:core is red only on lines that already exist on origin/release/v3.8.52 (open-sse/translator/request/openai-to-claude.ts and open-sse/utils/dsmlToolCalls.ts are byte-identical; the never-typed pushes in response/openai-to-claude.ts sit outside this batch's hunks). open-sse typecheck reports 3 errors in files byte-identical to origin/release/v3.8.52 (copilotAutoModel.ts TS2339 x2, request/openai-responses.ts TS2345 x1). The baseline was not widened. Changelog integrity passed. File-size growth is confined to src/sse/handlers/chat.ts and is handled on #16668/#16615, not in this PR.⚠️ base-red inherited: #15306 Thanks @pacocartones.
…16649) This PR: real Polish translations of UI strings that were still in English. Replacements in that locale file only, no new keys. The inherited my/phi ratio gap on the release tip was left untouched. Validated on the combined pacocartones board 5a429eab (30 PRs, clean merges, each refs/prs/N ancestor of HEAD) against release/v3.8.52. Focused node tests on that tree: 82 passed, 0 failed. typecheck:core is red only on lines that already exist on origin/release/v3.8.52 (open-sse/translator/request/openai-to-claude.ts and open-sse/utils/dsmlToolCalls.ts are byte-identical; the never-typed pushes in response/openai-to-claude.ts sit outside this batch's hunks). open-sse typecheck reports 3 errors in files byte-identical to origin/release/v3.8.52 (copilotAutoModel.ts TS2339 x2, request/openai-responses.ts TS2345 x1). The baseline was not widened. Changelog integrity passed. File-size growth is confined to src/sse/handlers/chat.ts and is handled on #16668/#16615, not in this PR.⚠️ base-red inherited: #15306 Thanks @pacocartones.
…16650) This PR: real Dutch translations of UI strings that were still in English. Replacements in that locale file only, no new keys. The inherited my/phi ratio gap on the release tip was left untouched. Validated on the combined pacocartones board 5a429eab (30 PRs, clean merges, each refs/prs/N ancestor of HEAD) against release/v3.8.52. Focused node tests on that tree: 82 passed, 0 failed. typecheck:core is red only on lines that already exist on origin/release/v3.8.52 (open-sse/translator/request/openai-to-claude.ts and open-sse/utils/dsmlToolCalls.ts are byte-identical; the never-typed pushes in response/openai-to-claude.ts sit outside this batch's hunks). open-sse typecheck reports 3 errors in files byte-identical to origin/release/v3.8.52 (copilotAutoModel.ts TS2339 x2, request/openai-responses.ts TS2345 x1). The baseline was not widened. Changelog integrity passed. File-size growth is confined to src/sse/handlers/chat.ts and is handled on #16668/#16615, not in this PR.⚠️ base-red inherited: #15306 Thanks @pacocartones.
…ish (#16651) This PR: real Indonesian translations of UI strings that were still in English. Replacements in that locale file only, no new keys. The inherited my/phi ratio gap on the release tip was left untouched. Validated on the combined pacocartones board 5a429eab (30 PRs, clean merges, each refs/prs/N ancestor of HEAD) against release/v3.8.52. Focused node tests on that tree: 82 passed, 0 failed. typecheck:core is red only on lines that already exist on origin/release/v3.8.52 (open-sse/translator/request/openai-to-claude.ts and open-sse/utils/dsmlToolCalls.ts are byte-identical; the never-typed pushes in response/openai-to-claude.ts sit outside this batch's hunks). open-sse typecheck reports 3 errors in files byte-identical to origin/release/v3.8.52 (copilotAutoModel.ts TS2339 x2, request/openai-responses.ts TS2345 x1). The baseline was not widened. Changelog integrity passed. File-size growth is confined to src/sse/handlers/chat.ts and is handled on #16668/#16615, not in this PR.⚠️ base-red inherited: #15306 Thanks @pacocartones.
This PR: a JSON body that parses but is not an object (null, a string, a number, or true) is answered with 400 "Request body must be a JSON object" on /v1/chat/completions, /v1/messages, and /v1/completions. Covered by tests/unit/chat-non-object-body.test.ts. The check lives in admissionRejectionLog.rejectPayload. chat.ts keeps one call, so the frozen file stays at its 2697-line ceiling. The changelog fragment now points at this PR. Validated on the contributor branch after that extraction. The combined pacocartones board 5a429eab had already passed 82 focused tests; complexity 3038 (baseline 3218) and cognitive 1401 (baseline 1437). typecheck:core is red only on lines that already exist on origin/release/v3.8.52 (open-sse/translator/request/openai-to-claude.ts and open-sse/utils/dsmlToolCalls.ts are byte-identical; the never-typed pushes in response/openai-to-claude.ts sit outside this batch's hunks). open-sse typecheck reports 3 errors in files byte-identical to origin/release/v3.8.52 (copilotAutoModel.ts TS2339 x2, request/openai-responses.ts TS2345 x1). The baseline was not widened.⚠️ base-red inherited: #15306 Thanks @pacocartones.
…sh (#16656) This PR: real Ukrainian translations of UI strings that were still in English. Replacements in that locale file only, no new keys. The inherited my/phi ratio gap on the release tip was left untouched. Validated on the combined pacocartones board 5a429eab (30 PRs, clean merges, each refs/prs/N ancestor of HEAD) against release/v3.8.52. Focused node tests on that tree: 82 passed, 0 failed. typecheck:core is red only on lines that already exist on origin/release/v3.8.52 (open-sse/translator/request/openai-to-claude.ts and open-sse/utils/dsmlToolCalls.ts are byte-identical; the never-typed pushes in response/openai-to-claude.ts sit outside this batch's hunks). open-sse typecheck reports 3 errors in files byte-identical to origin/release/v3.8.52 (copilotAutoModel.ts TS2339 x2, request/openai-responses.ts TS2345 x1). The baseline was not widened. Changelog integrity passed. File-size growth is confined to src/sse/handlers/chat.ts and is handled on #16668/#16615, not in this PR.⚠️ base-red inherited: #15306 Thanks @pacocartones.
…16657) This PR: real Thai translations of UI strings that were still in English. Replacements in that locale file only, no new keys. The inherited my/phi ratio gap on the release tip was left untouched. Validated on the combined pacocartones board 5a429eab (30 PRs, clean merges, each refs/prs/N ancestor of HEAD) against release/v3.8.52. Focused node tests on that tree: 82 passed, 0 failed. typecheck:core is red only on lines that already exist on origin/release/v3.8.52 (open-sse/translator/request/openai-to-claude.ts and open-sse/utils/dsmlToolCalls.ts are byte-identical; the never-typed pushes in response/openai-to-claude.ts sit outside this batch's hunks). open-sse typecheck reports 3 errors in files byte-identical to origin/release/v3.8.52 (copilotAutoModel.ts TS2339 x2, request/openai-responses.ts TS2345 x1). The baseline was not widened. Changelog integrity passed. File-size growth is confined to src/sse/handlers/chat.ts and is handled on #16668/#16615, not in this PR.⚠️ base-red inherited: #15306 Thanks @pacocartones.
…16658) This PR: real Hindi translations of UI strings that were still in English. Replacements in that locale file only, no new keys. The inherited my/phi ratio gap on the release tip was left untouched. Validated on the combined pacocartones board 5a429eab (30 PRs, clean merges, each refs/prs/N ancestor of HEAD) against release/v3.8.52. Focused node tests on that tree: 82 passed, 0 failed. typecheck:core is red only on lines that already exist on origin/release/v3.8.52 (open-sse/translator/request/openai-to-claude.ts and open-sse/utils/dsmlToolCalls.ts are byte-identical; the never-typed pushes in response/openai-to-claude.ts sit outside this batch's hunks). open-sse typecheck reports 3 errors in files byte-identical to origin/release/v3.8.52 (copilotAutoModel.ts TS2339 x2, request/openai-responses.ts TS2345 x1). The baseline was not widened. Changelog integrity passed. File-size growth is confined to src/sse/handlers/chat.ts and is handled on #16668/#16615, not in this PR.⚠️ base-red inherited: #15306 Thanks @pacocartones.
…16659) This PR: real Arabic translations of UI strings that were still in English. Replacements in that locale file only, no new keys. The inherited my/phi ratio gap on the release tip was left untouched. Validated on the combined pacocartones board 5a429eab (30 PRs, clean merges, each refs/prs/N ancestor of HEAD) against release/v3.8.52. Focused node tests on that tree: 82 passed, 0 failed. typecheck:core is red only on lines that already exist on origin/release/v3.8.52 (open-sse/translator/request/openai-to-claude.ts and open-sse/utils/dsmlToolCalls.ts are byte-identical; the never-typed pushes in response/openai-to-claude.ts sit outside this batch's hunks). open-sse typecheck reports 3 errors in files byte-identical to origin/release/v3.8.52 (copilotAutoModel.ts TS2339 x2, request/openai-responses.ts TS2345 x1). The baseline was not widened. Changelog integrity passed. File-size growth is confined to src/sse/handlers/chat.ts and is handled on #16668/#16615, not in this PR.⚠️ base-red inherited: #15306 Thanks @pacocartones.
Validated on local board 917689fb (batch-owner-1015) with the owner wave: static gates plus focused tests. This squash is that same head (14be1dc).⚠️ base-red inherited: #15306 Thanks @diegosouzapw.
Validated on local board 917689fb (batch-owner-1015) with the owner wave: static gates plus focused tests. This squash is that same head (73a9098).⚠️ base-red inherited: #15306 Thanks @diegosouzapw.
… path (#16621) Validated on local board 917689fb (batch-owner-1015) with the owner wave: static gates plus focused tests. This squash is that same head (42c54b0).⚠️ base-red inherited: #15306 Thanks @diegosouzapw.
…pivot (#16710) Validated on local board 917689fb (batch-owner-1015) with the owner wave: static gates plus focused tests. This squash is that same head (d5ac5e6).⚠️ base-red inherited: #15306 Thanks @diegosouzapw.
Validated on local board 917689fb (batch-owner-1015) with the owner wave: static gates plus focused tests. This squash is that same head (d5615da).⚠️ base-red inherited: #15306 Thanks @diegosouzapw.
…6638) Validated on local board 917689fb (batch-owner-1015) with the owner wave: static gates plus focused tests. This squash is that same head (ee767e5).⚠️ base-red inherited: #15306 Thanks @diegosouzapw.
… keyless free models (#15540) (#16042) Validated on local board 917689fb (batch-owner-1015) with the owner wave: static gates plus focused tests. This squash is that same head (da88f98).⚠️ base-red inherited: #15306 Thanks @diegosouzapw.
…16723) Validated on local board 917689fb (batch-owner-1015) with the owner wave: static gates plus focused tests. This squash is that same head (f83c6d9).⚠️ base-red inherited: #15306 Thanks @diegosouzapw.
…wer (#16521) Validated on local board 917689fb (batch-owner-1015) with the owner wave: static gates plus focused tests. This squash is that same head (be96a63).⚠️ base-red inherited: #15306 Thanks @diegosouzapw.
…ter, coalescing) (#16480) Validated on local board 917689fb (batch-owner-1015) with the owner wave: static gates plus focused tests. This squash is that same head (6ec49cf).⚠️ base-red inherited: #15306 Thanks @diegosouzapw.
…es route (#16704) Validated on local board 917689fb (batch-owner-1015) with the owner wave: static gates plus focused tests. This squash is that same head (eeb30f5).⚠️ base-red inherited: #15306 Thanks @diegosouzapw.
Validated on local board 917689fb (batch-owner-1015) with the owner wave: static gates plus focused tests. This squash is that same head (bd32a68).⚠️ base-red inherited: #15306 Thanks @diegosouzapw.
…reset (#16705) Validated on local board 917689fb (batch-owner-1015) with the owner wave: static gates plus focused tests. This squash is that same head (2135f8d).⚠️ base-red inherited: #15306 Thanks @diegosouzapw.
… output (#16495) Validated on local board 917689fb (batch-owner-1015) with the owner wave: static gates plus focused tests. This squash is that same head (85fc894).⚠️ base-red inherited: #15306 Thanks @diegosouzapw.
Validated on local board 917689fb (batch-owner-1015) with the owner wave: static gates plus focused tests. This squash is that same head (2b592b2).⚠️ base-red inherited: #15306 Thanks @diegosouzapw.
Validated on local board 917689fb (batch-owner-1015) with the owner wave: static gates plus focused tests. This squash is that same head (0a7ab95).⚠️ base-red inherited: #15306 Closes #16225 Thanks @diegosouzapw.
Validated on local board 917689fb (batch-owner-1015) with the owner wave: static gates plus focused tests. This squash is that same head (7ccf491).⚠️ base-red inherited: #15306 Thanks @diegosouzapw.
Validated on local board 917689fb (batch-owner-1015) with the owner wave: static gates plus focused tests. This squash is that same head (1db721c).⚠️ base-red inherited: #15306 Thanks @diegosouzapw.
) Validated on local board 917689fb (batch-owner-1015) with the owner wave: static gates plus focused tests. This squash is that same head (0b88490).⚠️ base-red inherited: #15306 Thanks @diegosouzapw.
…) to non-Anthropic providers (#16720) Validated on local board 917689fb. The squash includes the type guard that narrows the Claude passthrough body before hoistDeferredToolsForTarget (head 99d62e8). The Claude passthrough case already passed on the board; the guard keeps open-sse typecheck inside the empty baseline.⚠️ base-red inherited: #15306 Thanks @diegosouzapw.
Validated on local board 917689fb (batch-owner-1015) with the owner wave: static gates plus focused tests. This squash is that same head (0176042).⚠️ base-red inherited: #15306 Fixes #16220. Thanks @diegosouzapw.
Validated on local board 917689fb (batch-owner-1015) with the owner wave: static gates plus focused tests. This squash is that same head (7b942e1).⚠️ base-red inherited: #15306 Thanks @diegosouzapw.
) Validated on local board 917689fb (batch-owner-1015) with the owner wave: static gates plus focused tests. This squash is that same head (48db7b5).⚠️ base-red inherited: #15306 Thanks @diegosouzapw.
…tions (#16684) Validated on local board 917689fb. The squash includes the priority-helper narrowing so optional connection ids typecheck (head 83f0ffb). tests/unit/provider-connection-priority-updates.test.ts passed 7/7 after the change. Dashboard typecheck on the board rerun stayed inside the frozen baseline (195).⚠️ base-red inherited: #15306 Thanks @diegosouzapw.
…ive_finish_reason errors (#16524) Validated on local board 917689fb. merge-tree against the post-wave tip is clean. Head 766ed38.⚠️ base-red inherited: #15306 Thanks @diegosouzapw.
Keep the landed idle-timer cancel and close outputSink.wrap so opt-in coalescing still wraps the stream.
Contributor
CI Coverage Report
Coverage artifact was not available for this run. |
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.
Summary
content_block_deltaevents (SSE_COALESCE_MS, plus per-typeSSE_COALESCE_THINKING_MS/SSE_COALESCE_TEXT_MS/SSE_COALESCE_INPUT_JSON_MS). Fast Anthropic-compatible upstreams send one delta per token, and clients that render one UI update per SSE event (the Claude Code VS Code extension) fall behind. Consecutive deltas with the same block index and delta type are merged losslessly. This covers both the translate lane and the claude→claude passthrough lane.SSE_FRAME_COALESCE_MS): frames forwarded inside the window go to the client as one enqueue. The first frame and terminal frames are never held back.SSE_STALL_WATCHDOG=interval):pipeWithDisconnectstamps the last chunk time and checks it from one unref'd interval per stream, so it no longer re-arms a timer on every upstream chunk.Everything is OFF by default. With no env set, the stream is byte-identical and makes the same
enqueueand timer calls as before.sseOutputSink.wrap()returns the transformer untouched,forward()takes the legacy fast path, and the watchdog stays intimermode.Attribution
Thanks to @WYSTAF for the original delta-coalescing implementation, and to @wallerjenifernk530-hash for the original frame-coalescing and stall-watchdog analysis.
Changes
open-sse/utils/sseDeltaCoalesce.ts(new): a frame-level coalescer.[event: content_block_delta\n]data: {...}\n\nframes whose delta type istext_delta,thinking_deltaorinput_json_delta.signature_delta, boundary events, comments and multi-frame chunks.open-sse/utils/sseOutputSink.ts(new):forward()moves here. The sink composes the delta stage (Claude clients only) with the frame batcher. Batching is capped at 64 KiB and terminal frames are detected ([DONE],message_stop,error,response.completed|failed|incomplete).wrap()makes the transformer'sflush()drain pending output and itscancel()dispose the timers. An enqueue that throws on a closed or errored stream makes the sink inert instead of throwing from a timer.open-sse/utils/stream.ts:forwardnow comes from the sink, and the transformer is wrapped withoutputSink.wrap({...}). The file is net −2 lines and stays under its frozen file-size ceiling.open-sse/utils/streamStallWatchdog.ts(new) +open-sse/utils/streamHandler.ts:armStall/clearStallnow come fromcreateStallWatchdog.timermode (the default) keeps the legacy per-chunkclearTimeout+setTimeout. Inintervalmode the period isclamp(stall/4, 1s, 5s).armActive, the content-stall watcher and the upstream tap are untouched..env.example+docs/reference/ENVIRONMENT.md: the six new variables are documented.Deviations from the original upstream changes:
SSE_FRAME_COALESCE_MSand defaults to off. Upstream usedSSE_COALESCE_MSwith a 2 ms default, which collides with the delta-coalescing variable of the same name.clientPayloadCollectorand the request logger still record the per-token events. The merged text is identical, but the event counts differ when coalescing is on.Test plan
stream.tsswapped in, 5 integration tests fail (claude passthrough: SSE_COALESCE_MS merges deltas…,translate lane … is coalesced too,SSE_FRAME_COALESCE_MS batches a burst…,… never delays the first frame or a terminal frame,delta coalescing and frame batching compose losslessly). On the base, the module-level tests cannot even import their module.node --import tsx/esm --test tests/unit/sse-delta-coalesce.test.ts→ℹ pass 13 ℹ fail 0node --import tsx/esm --test tests/unit/sse-output-coalescing.test.ts→ℹ pass 7 ℹ fail 0test:unit:cipreamble: every test file that importsstream.ts,streamHandler.tsorpipeWithDisconnect, plus the 3 new ones andtests/integration/sse-correctness.test.ts. Result:ℹ tests 636 ℹ pass 635 ℹ fail 1. The single failure iskiro-content-stall-15260 › fragmented prelude…. It is a 100 ms content-stall timing test and also fails on the basestream.ts/streamHandler.tson this loaded host (2 failures there), so it is not caused by this change.npm run typecheck:core→ exit 0npx eslint --suppressions-location config/quality/eslint-suppressions.json <changed files>→ exit 0;npx prettier --checkon the changed files → cleannode scripts/check/check-env-doc-sync.mjs→✓ Env / docs contract is in sync.;npm run check:docs-all→ exit 0GITHUB_BASE_REF=release/v3.8.52 node scripts/check/check-pr-test-policy.mjs→Result: PASS;npm run check:test-masking→OK — 0 modificado(s) … sem enfraquecimentonode scripts/check/check-file-size.mjs:stream.ts3326→3324 (ceiling 3326) andstreamHandler.tsat 1193 (cap 1200). The 4 remaining violations are in files this PR does not touch (responseSanitizer.ts,error.ts, and two test files).