[STG-1607] Yield finished SSE event instead of silently dropping it#1846
[STG-1607] Yield finished SSE event instead of silently dropping it#1846
Conversation
🦋 Changeset detectedLatest commit: 066c4c5 The changes in this PR will be included in the next version bump. This PR includes changesets to release 5 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
✱ Stainless preview buildsThis PR will update the ✅ stagehand-ruby studio · code
✅ stagehand-php studio · code
✅ stagehand-go studio · code
✅ stagehand-kotlin studio · code
✅ stagehand-python studio · code
✅ stagehand-java studio · code
|
Greptile SummaryThis PR fixes a bug where the terminal SSE event ( Root cause: Fix: Changing to Key changes:
Confidence Score: 5/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant C as SDK Client
participant S as Server (stream.ts)
Note over C,S: BEFORE (handle: done)
S->>C: SSE: {"data":{"status":"starting",...}}
S->>C: SSE: {"data":{"status":"connected",...}}
S->>C: SSE: {"data":{"status":"running",...}} (0..n)
S->>C: SSE: {"data":{"status":"finished", result, actionId}}
Note over C: break — event silently dropped ❌
S-->>C: EOF (reply.raw.end())
Note over C: Caller never receives result
Note over C,S: AFTER (handle: yield)
S->>C: SSE: {"data":{"status":"starting",...}}
S->>C: SSE: {"data":{"status":"connected",...}}
S->>C: SSE: {"data":{"status":"running",...}} (0..n)
S->>C: SSE: {"data":{"status":"finished", result, actionId}}
Note over C: yield — event delivered to caller ✅
S-->>C: EOF (reply.raw.end())
Note over C: Loop exits naturally on EOF
Last reviewed commit: "fix: yield finished ..." |
There was a problem hiding this comment.
cubic analysis
No issues found across 1 file
Confidence score: 5/5
- Automated review surfaced no issues in the provided summaries.
- No files require special attention.
Linked issue analysis
Linked issue: STG-1607: Fix bug in Python SDK to yield finished SSE events
| Status | Acceptance criteria | Notes |
|---|---|---|
| ✅ | Change streaming handling so the finished SSE event is yielded instead of dropped | Updated stainless.yml to use handle: yield for finished event |
| ❌ | Apply the fix to both sync Stream.__stream__() and async AsyncStream.__stream__() in the Python SDK | No modifications to src/stagehand/_streaming.py shown in PR |
| Ensure yielding the finished event does not hang the stream (stream terminates naturally on EOF) | PR rationale explains safety but no tests or server changes included | |
| ❌ | Regenerate SDKs and confirm the Python fix (test plan: regenerated SDKs and confirm python fix) | No regenerated SDK files or test confirmations present in diffs |
|
great catch, thank you for debugging + fixing this @aq17! |
This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated. # Releases ## @browserbasehq/browse-cli@0.2.0 ### Minor Changes - [#1816](#1816) [`687d54a`](687d54a) Thanks [@shrey150](https://github.com/shrey150)! - Add `--context-id` and `--persist` flags to `browse open` for loading and persisting Browserbase Contexts across sessions - [#1793](#1793) [`e38c13b`](e38c13b) Thanks [@shrey150](https://github.com/shrey150)! - Initial release of browse CLI - browser automation for AI agents ### Patch Changes - [#1806](#1806) [`f8c7738`](f8c7738) Thanks [@shrey150](https://github.com/shrey150)! - Fix `browse env` showing stale mode after `browse env remote` - Updated dependencies \[[`505e8c6`](505e8c6), [`2f43ffa`](2f43ffa), [`63ee247`](63ee247), [`7dc35f5`](7dc35f5), [`335cf47`](335cf47), [`6ba0a1d`](6ba0a1d), [`4ff3bb8`](4ff3bb8), [`c27054b`](c27054b), [`2abf5b9`](2abf5b9), [`7817fcc`](7817fcc), [`7390508`](7390508), [`611f43a`](611f43a), [`521a10e`](521a10e), [`2402a3c`](2402a3c)]: - @browserbasehq/stagehand@3.2.0 ## @browserbasehq/stagehand@3.2.0 ### Minor Changes - [#1779](#1779) [`2f43ffa`](2f43ffa) Thanks [@shrey150](https://github.com/shrey150)! - feat: add `cdpHeaders` option to `localBrowserLaunchOptions` for passing custom HTTP headers when connecting to an existing browser via CDP URL - [#1834](#1834) [`63ee247`](63ee247) Thanks [@tkattkat](https://github.com/tkattkat)! - Update stagehand agents search tool - [#1774](#1774) [`521a10e`](521a10e) Thanks [@seanmcguire12](https://github.com/seanmcguire12)! - add new page.setExtraHTTPHeaders() method ### Patch Changes - [#1759](#1759) [`505e8c6`](505e8c6) Thanks [@shrey150](https://github.com/shrey150)! - Add bedrock to the provider enum in model configuration schemas and regenerate OpenAPI spec. - [#1814](#1814) [`7dc35f5`](7dc35f5) Thanks [@tkattkat](https://github.com/tkattkat)! - Change usage of openai provider in agent to default to store:false - [#1846](#1846) [`335cf47`](335cf47) Thanks [@aq17](https://github.com/aq17)! - Fix streaming finished event being silently dropped. The final SSE event containing the result payload (success status, message, actions, usage, and messages) was previously discarded instead of being yielded to the caller. - [#1764](#1764) [`6ba0a1d`](6ba0a1d) Thanks [@shrey150](https://github.com/shrey150)! - Expose `headers` in `GoogleVertexProviderSettings` so model configs can pass custom provider headers (for example `X-Goog-Priority`) without TypeScript errors. - [#1847](#1847) [`4ff3bb8`](4ff3bb8) Thanks [@miguelg719](https://github.com/miguelg719)! - Enable FlowLogger on BROWSERBASE_FLOW_LOGS=1 - [#1752](#1752) [`c27054b`](c27054b) Thanks [@derekmeegan](https://github.com/derekmeegan)! - fix: pause Browserbase agents while captcha solving is active and improve CUA recovery after the solve completes - [#1800](#1800) [`2abf5b9`](2abf5b9) Thanks [@shrey150](https://github.com/shrey150)! - Make projectId optional for Browserbase sessions — only BROWSERBASE_API_KEY is required - [#1766](#1766) [`7817fcc`](7817fcc) Thanks [@tkattkat](https://github.com/tkattkat)! - Add configurable timeout to tools in agent - [#1749](#1749) [`7390508`](7390508) Thanks [@pirate](https://github.com/pirate)! - When connecting to a browser session that has zero open tabs, Stagehand now automatically creates an initial `about:blank` tab so the connection can continue. - [#1761](#1761) [`611f43a`](611f43a) Thanks [@seanmcguire12](https://github.com/seanmcguire12)! - fix issue where handlePossibleNavigation was producing unnecessary error logs on clicks that trigger page close - [#1817](#1817) [`2402a3c`](2402a3c) Thanks [@tkattkat](https://github.com/tkattkat)! - Add support for passing custom headers in clientOptions ## @browserbasehq/stagehand-evals@1.1.9 ### Patch Changes - Updated dependencies \[[`505e8c6`](505e8c6), [`2f43ffa`](2f43ffa), [`63ee247`](63ee247), [`7dc35f5`](7dc35f5), [`335cf47`](335cf47), [`6ba0a1d`](6ba0a1d), [`4ff3bb8`](4ff3bb8), [`c27054b`](c27054b), [`2abf5b9`](2abf5b9), [`7817fcc`](7817fcc), [`7390508`](7390508), [`611f43a`](611f43a), [`521a10e`](521a10e), [`2402a3c`](2402a3c)]: - @browserbasehq/stagehand@3.2.0 ## @browserbasehq/stagehand-server-v3@3.6.1 ### Patch Changes - [#1759](#1759) [`505e8c6`](505e8c6) Thanks [@shrey150](https://github.com/shrey150)! - Add bedrock to the provider enum in model configuration schemas and regenerate OpenAPI spec. - Updated dependencies \[[`505e8c6`](505e8c6), [`2f43ffa`](2f43ffa), [`63ee247`](63ee247), [`7dc35f5`](7dc35f5), [`335cf47`](335cf47), [`6ba0a1d`](6ba0a1d), [`4ff3bb8`](4ff3bb8), [`c27054b`](c27054b), [`2abf5b9`](2abf5b9), [`7817fcc`](7817fcc), [`7390508`](7390508), [`611f43a`](611f43a), [`521a10e`](521a10e), [`2402a3c`](2402a3c)]: - @browserbasehq/stagehand@3.2.0 ## @browserbasehq/stagehand-server-v4@3.6.1 ### Patch Changes - Updated dependencies \[[`505e8c6`](505e8c6), [`2f43ffa`](2f43ffa), [`63ee247`](63ee247), [`7dc35f5`](7dc35f5), [`335cf47`](335cf47), [`6ba0a1d`](6ba0a1d), [`4ff3bb8`](4ff3bb8), [`c27054b`](c27054b), [`2abf5b9`](2abf5b9), [`7817fcc`](7817fcc), [`7390508`](7390508), [`611f43a`](611f43a), [`521a10e`](521a10e), [`2402a3c`](2402a3c)]: - @browserbasehq/stagehand@3.2.0 Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
why
Customer reported a bug in the Python SDK (stagehand-python v3.6.0).
In src/stagehand/_streaming.py, both the sync Stream.stream() (line 62-63) and async AsyncStream.stream() (line 147-148) have:
When the server sends the finished SSE event (which contains success, message, actions, usage, and messages), the SDK immediately breaks out of the loop without yielding the event to the caller. This means the final result payload is silently dropped.
what changed
The streaming on_event config had
handle: donefor the{"data":{"status":"finished"...}}event. Stainless generates this as a bare break, which exits the SSE loop without yielding the event – silently dropping the final result payload (success status, message, actions, usage, and messages) from every streaming response.Fix – Changed to
handle: yieldso the finished event is delivered to callers before the stream terminates. This is safe because the server explicitly callsreply.raw.end()immediately after sending the finished event (packages/server-v3/src/lib/stream.ts), so the SSE connection closes right after the yield and the loop exits naturally on EOF – no hang risk.test plan
Regenerate SDKs and confirm fix