[pull] main from CopilotKit:main - #416
Merged
Merged
Conversation
…#5812) Pressing Stop mid-stream against a CopilotRuntime + HttpAgent proxy aborts the upstream agent, which emits a live RUN_ERROR while a text message is still open. finalizeRunEvents then appended a trailing TEXT_MESSAGE_END *after* that RUN_ERROR. Because the runners stream finalization events after everything the agent already emitted, the closer landed past the terminal and the AG-UI verifier rejected it with "the run has already errored with 'RUN_ERROR'. No further events can be sent." — crashing the chat. finalizeRunEvents (in @copilotkit/shared, consumed by the in-memory, intelligence, and sqlite runners) now returns early and appends nothing when the stream already contains a terminal event (RUN_FINISHED or RUN_ERROR): any message or tool call still open is closed by the terminal on the client. The abrupt-end path (no terminal -> close open streams + synthesize a terminal) is unchanged. Tests: - finalize-events.test.ts: terminal-present appends nothing (both RUN_FINISHED and RUN_ERROR) + a named #5812 case. - in-memory-runner.test.ts: end-to-end mid-stream-stop regression that asserts no events follow RUN_ERROR and the stream passes AG-UI verifyEvents (the verifier the browser runs). - intelligence-runner.test.ts: corrected an assertion that had encoded the buggy post-terminal TEXT_MESSAGE_END. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [actions/setup-node](https://redirect.github.com/actions/setup-node) | action | major | `v6.4.0` → `v7.0.0` | | [ruby/setup-ruby](https://redirect.github.com/ruby/setup-ruby) | action | minor | `v1.316.0` → `v1.317.0` | --- > [!WARNING] > Some dependencies could not be looked up. Check the [Dependency Dashboard](../issues/592) for more information. --- ### Release Notes <details> <summary>actions/setup-node (actions/setup-node)</summary> ### [`v7.0.0`](https://redirect.github.com/actions/setup-node/compare/v6.5.0...v7.0.0) [Compare Source](https://redirect.github.com/actions/setup-node/compare/v7.0.0...v7.0.0) ### [`v7`](https://redirect.github.com/actions/setup-node/compare/v6.5.0...v7.0.0) [Compare Source](https://redirect.github.com/actions/setup-node/compare/v6.5.0...v7.0.0) ### [`v6.5.0`](https://redirect.github.com/actions/setup-node/compare/v6.4.0...v6.5.0) [Compare Source](https://redirect.github.com/actions/setup-node/compare/v6.4.0...v6.5.0) </details> <details> <summary>ruby/setup-ruby (ruby/setup-ruby)</summary> ### [`v1.317.0`](https://redirect.github.com/ruby/setup-ruby/releases/tag/v1.317.0) [Compare Source](https://redirect.github.com/ruby/setup-ruby/compare/v1.316.0...v1.317.0) ##### What's Changed - Add ruby-4.0.6 by [@​ruby-builder-bot](https://redirect.github.com/ruby-builder-bot) in [#​928](https://redirect.github.com/ruby/setup-ruby/pull/928) **Full Changelog**: <ruby/setup-ruby@v1.316.0...v1.317.0> </details> --- ### Configuration 📅 **Schedule**: (in timezone America/Los_Angeles) - Branch creation - "before 9am every weekday" - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://redirect.github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/CopilotKit/CopilotKit). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yNTkuMiIsInVwZGF0ZWRJblZlciI6IjQzLjI1OS4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->
…#5812) (#5885) ## Summary Pressing **Stop** while an assistant message is streaming (CopilotRuntime + `HttpAgent` proxy) crashed the chat with: ``` Cannot send event type 'TEXT_MESSAGE_END': The run has already errored with 'RUN_ERROR'. No further events can be sent. ``` Root cause: `finalizeRunEvents` appended a trailing `TEXT_MESSAGE_END` **after** the `RUN_ERROR` that the aborted agent had already emitted. Fixes #5812. ## Root cause When the upstream agent (e.g. pydantic-ai's `AGUIAdapter`) is aborted mid-stream it emits a live `RUN_ERROR` while a text message is still open — it does **not** close the message first. All runners (`in-memory`, `intelligence`, `sqlite`) stream `finalizeRunEvents`' output *after* everything the agent already emitted, so the appended closer landed past the terminal: | | outgoing event order | |---|---| | **Before** | `… TEXT_MESSAGE_CONTENT → RUN_ERROR → TEXT_MESSAGE_END` ❌ verifier throws | | **After** | `… TEXT_MESSAGE_CONTENT → RUN_ERROR` ✅ terminal closes the message client-side | Per the AG-UI invariant: at most one terminal event per run, and no sub-events after it. I confirmed against the real `@ag-ui/client` `verifyEvents` (the verifier the browser runs) that a terminal arriving with a message still open is valid — the terminal implicitly closes it. ## Fix `finalizeRunEvents` (in `@copilotkit/shared`) now returns early and appends **nothing** when the stream already contains a terminal event (`RUN_FINISHED` or `RUN_ERROR`). The abrupt-end path (no terminal → close open streams + synthesize a terminal, in the correct order) is unchanged. No API/signature change; the in-memory, intelligence, and sqlite runners all inherit the fix. ## Testing RED→GREEN verified — each new/updated assertion was confirmed to fail against the pre-fix code: - **`finalize-events.test.ts`** — terminal-present appends nothing (parametrized over `RUN_FINISHED` and `RUN_ERROR`) + a named #5812 case. - **`in-memory-runner.test.ts`** — end-to-end mid-stream-stop regression: a fake `HttpAgent`-style agent is stopped between `TEXT_MESSAGE_START` and `TEXT_MESSAGE_END`; asserts no events follow `RUN_ERROR` **and** that the collected stream passes `verifyEvents` (before the fix this threw the exact browser error). - **`intelligence-runner.test.ts`** — corrected a pre-existing assertion that had encoded the buggy post-terminal `TEXT_MESSAGE_END`. Green: full `@copilotkit/runtime` suite, `@copilotkit/sqlite-runner`, `@copilotkit/shared`, `check-types`, `oxlint` (0 errors), and build. ## Reviewer notes - The behavior change is a single early-return in `finalize-events.ts`; the `terminalEventMissing` guards simplify away because they're only reachable when no terminal exists. - Diff is +204/−55 across 4 files, the bulk of it tests.
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? 💖 Please sponsor : )