Pin es2020 browser target for IIFE/ESM bundles (fix streamed chat turn) → 0.5.2#12
Merged
Merged
Conversation
…egression e2e The deployed `<script src=chat-widget.global.js>` embed could break on the streamed chat turn (`send_message` → "Connection issue") while the ESM build of the same version worked. Root cause is a build-output footgun: tsdown derived a *Node* transpile target (`node22.0.0`) from the package `engines` for what is actually a browser bundle. A Node target is the class of setting that silently downlevels the smooth-operator client's async generators / `for await` over the streaming `MessageTurn` (`Symbol.asyncIterator`) into regenerator/helper shims, mangling the stream in stricter engines — while the externalized ESM build (the host supplies the client) is unaffected. Fix: pin an explicit `es2020` browser target on all three outputs (ESM + both IIFE globals) so native async iteration is preserved and the IIFE global bundle stays byte-faithful to the ESM build on the streaming path. Verification: built bundle streams a full grounded turn against the live prod operator (`wss://ai.smoo.ai/ws`, agent 2590dfd6-…) in headless Chromium. Added two regression specs: `e2e/repro-stream-mock.spec.ts` (CI-safe, drives the real shadow-DOM UI through a deterministic mock WS replaying the operator frame sequence) and `e2e/repro-prod.spec.ts` (gated on SMOOTH_AGENT_PROD_E2E=1, hits live prod). typecheck/test/build all green. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
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.
Problem
The deployed
<script src=\"chat-widget.global.js\">embed could fail on the streamed chat turn: it connects + creates a session (greeting shows, status "ready" — single-await calls work) but throws "Connection issue" onsend_message, while the ESM build of the same version works. The raw operator protocol,src/conversation.ts, and the protocol client are all correct — it's a build-output issue isolated to the streaming path (MessageTurnasync-iterator /for await).Root cause (build setting)
tsdownderived a Node transpile target (target: node22.0.0) from the packageenginesfor all outputs — including the browser<script>IIFE globals. A Node target is wrong for a browser embed and is exactly the class of setting that can silently downlevel the smooth-operator client's async generators /for awaitover the streamingMessageTurn(Symbol.asyncIterator) into regenerator/helper shims, mangling the stream in stricter engines. The ESM build keeps the client external (the host supplies it), so it's unaffected — which is why ESM worked and the IIFE didn't.Fix
Pin an explicit
es2020browser target on all three outputs (ESM + both IIFE globals), so native async iteration is preserved and the IIFE global bundle stays byte-faithful to the ESM build on the streaming path. The bundle keeps nativeSymbol.asyncIterator/for await(verified in the emitted output — no regenerator/helper shims).Verification
wss://ai.smoo.ai/ws, agent2590dfd6-…, Origin spoofed tohttps://smoo.ai) in headless Chromium — multiple runs, full multi-sentence grounded reply renders.pnpm check(typecheck + 30 unit tests + build) green.e2e/repro-stream-mock.spec.ts— CI-safe; drives the real shadow-DOM UI through a deterministic mock WS replaying the operator frame sequence (immediate_response{202} →stream_token×N →eventual_response).e2e/repro-prod.spec.ts— gated onSMOOTH_AGENT_PROD_E2E=1; hits live prod.Publish version
0.5.2 (patch; changeset included).
🤖 Generated with Claude Code