Repository navigation
refactor(sse): split handleChatCore into four response-path leaves - #14725
diegosouzapw merged 12 commits into
Conversation
6e9344a to
2ac0d92
Compare
|
Replayed onto the current release/v3.8.51 tip How the replay kept the extraction honest: the 40 upstream hunks that landed in chatCore.ts since the original cut were classified mechanically — 27 fell entirely in code that stays in the barrel (taken as-is), 20 fell entirely inside the four lifted regions, 0 straddled the boundary. The in-region hunks were folded into the leaves, so each leaf still diffs empty against the tip implementation except for imports/exports and the deps/carry wiring, which is the acceptance criterion from the #13065 review. Folded-in upstream changes worth naming: Verified locally: typecheck:core clean, the four leaf test files plus the surrounding chatCore suites 70/70, test-discovery and file-size gates pass (the four file-size entries GitHub will see are pre-existing tip debt in files this branch does not touch). |
|
Thanks for redoing this on top of the current tip, @HouMinXi — the split into four leaves is the shape we asked for, and it merges cleanly against the release branch. Before we can land a 4.4k-line change on the hot path we'd like a few things: (1) the full run of the ~209 chatcore-referencing test files plus |
2ac0d92 to
b1b2386
Compare
Re-extraction of diegosouzapw#13065 onto the current release/v3.8.51 tip (a41ded2). Each leaf is lifted out of handleChatCore unchanged apart from imports/exports and the deps/carry wiring, so every leaf diffs empty against the tip implementation except the wiring: - executeProviderRequest.ts — one provider send (admission, body preparation, executor call, retry ladder) - nonStreamingResponse.ts — the !stream leg - streamingResponse.ts — the stream leg up to readiness - streamingTail.ts — readiness, translation pipeline, tail finalization While replaying, the 18 upstream hunks that landed inside the lifted regions were folded into the leaves so behaviour stays identical to the tip: getExecutorClientHeaders() call sites, metered-budget cost wrapping, the stream-readiness fallback hook, formatted FLUSH_EMPTY_RETRY verdict logging, captureStreamReasoningForReplay, videoTranscriptSensitive flags, and the connection-id provenance fields on the streaming response headers. The hard-lease inventory guard moves its FLUSH_EMPTY_RETRY expectation to the leaf's new home. Signed-off-by: Minxi Hou <houminxi@gmail.com>
b1b2386 to
d3e0be8
Compare
|
Here is the follow-up addressing the four points from the review: 1. Test, typecheck, and file-size gate evidence
2. Assertion restored in
|
diff-chatcore-leaves.mjs declared region start/end patterns but never applied them — the loop only checked that each leaf file existed and unconditionally printed "1:1 behavioral extraction verified", giving false confidence that the four-leaf extraction was proven mechanical when no verification actually ran. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Re-lift the tip's chatCore.ts changes since the merge-base into the corresponding response-path leaves: system transforms + tool-metadata capture in the barrel prelude, wire-model tracking in executeProviderRequest.ts, and the empty-turn-retry loop extraction + TTFT timing refactor + executor cascade timeout in streamingTail.ts. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
|
Re-homed to |
…direct refresh retry runs runStreamingResponse reads getExecutorClientHeaders from its deps bag, but handleChatCoreInner never passed it. The bag is typed Record<string, any>, so the compiler could not see it, and the 401/403 direct-refresh retry threw 'getExecutorClientHeaders is not a function' — swallowed by the retry catch — surfacing the original 401 instead of the retried response. Add a structural contract test asserting every deps key each of the three response leaves reads is passed by chatCore.ts. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
…g tail leaf recordCost moved out of chatCore.ts with the streaming tail when handleChatCore was split into leaves; keep the calculateCost check on chatCore.ts and assert recordCost where it now lives. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
…ion diff - upstream-status-restatement: assert the classification helper precedes the streaming dispatch that hands it to the leaf holding the providerFailure block, and that the dispatch passes it in (cross-file form of classifyIndex < blockIndex). - error-public-boundaries-hardening fixture: read the providerFailure block from chatCore/streamingResponse.ts where it now lives. - scripts/dev/diff-chatcore-leaves.mjs: token-level region diff of each leaf against the pre-split chatCore.ts; only documented lift seams are accepted, anything else exits 1. Unit-tested in tests/unit/chatcore/diff-chatcore-leaves.test.ts. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
# Conflicts: # config/quality/file-size-baseline.json # open-sse/handlers/chatCore.ts
The split moved the userAgent destructure into streamingResponse, but every use of it stayed in the handleChatCore barrel. The binding in the leaf was never read, so lint flagged it. The barrel still passes userAgent to the header builder, the format resolver and the bypass handler. Signed-off-by: Minxi Hou <houminxi@gmail.com>
The split put chatcore tests under tests/unit/chatcore and package.json test:unit runs them, but merge-train.sh kept the old subdir list. The allowlist mirror test failed because the two sets no longer matched. Signed-off-by: Minxi Hou <houminxi@gmail.com>
# Conflicts: # config/quality/file-size-baseline.json
da4ddc2
into
diegosouzapw:release/v3.8.52
|
Thanks @HouMinXi — merged into |
handleChatCore was split into leaves (diegosouzapw#14725), so the streaming policy now reaches assembleStreamingResponseHeaders through streamingTail.ts. The non-streaming strip is dropped: on the tip the client's non-streaming headers are rebuilt from scratch and never carry upstream headers, and stripping the upstream Response there only hid anthropic-ratelimit-* from the internal consumers. An end-to-end handleChatCore test covers both paths and asserts the rate-limit learner still sees the headers for a strip key. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
…er migrations to 208/209 - release/v3.8.52 split handleChatCore into leaf modules (diegosouzapw#14725): thread agentContext into runNonStreamingResponse and runStreamingTail so streamed and non-streamed usage rows are attributed again (a conflict-only resolution left only the failure path wired). New tests/unit/agent-context-chatcore-usage.test.ts drives handleChatCore end to end on all three paths. - Renumber 198_agent_sessions / 199_usage_history_agent_session_id to 208/209: the tip owns 198/199, so boot aborted with a migration version collision. - Drop idx_uh_api_key_timestamp from 209: 051 already creates the identical (api_key_id, timestamp) index on usage_history; a regression test guards it. - Session pricing and the agent_sessions upsert are best-effort: a failure there now logs and saves the usage_history row unattributed instead of dropping it. - Remove the stale chatCore.ts file-size rebaseline note (the split file is far below its cap). Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Summary
Re-extraction of #13065 onto the current release/v3.8.51 tip, as asked in the #13065 review: each leaf is lifted out of handleChatCore unchanged apart from imports/exports and the deps/carry wiring, so every leaf diffs empty against its region of the tip barrel.
chatCore/executeProviderRequest.ts— executor dispatch, account fallback, semaphore acquire/release, 401/403 refresh replaychatCore/nonStreamingResponse.ts— theif (!stream)leg plus therunNonStreamingProviderLeg/finalizeToolLoopErrorwrapperschatCore/streamingResponse.ts— theif (stream)provider pipelinechatCore/streamingTail.ts— the post-dispatch streaming tail: SSE finalization, usage capture, analytics flush, error mapping, disconnect handlingRelated to #13065. #13065 stays open.
What the suite caught after the lifts
Two seams in the wiring (not in the lifted bodies) needed fixes, both covered by tests:
translatedBodyat construction; the pre-decomposition inline closure captured it live, so server-tool follow-up legs re-sent the stale first-turn body (dropping the materializedreasoning_effortand the tool transcript). The barrel now passessyncExecuteTranslatedBodyand both response legs call it at every rebinding site. Thesuffix-effort-propagationserver-tool follow-up test goes red with the sync lines removed and green with them restored.tests/unit/chatcorejoins the node:test runner globs (package.json scripts and the collector list inscripts/check/check-test-discovery.mjs) so the leaf suites run under discovery instead of direct invocation only.Verification