Bug: abortRun sends a thread-wide stop, so a delayed stop can cancel the next run
♻️ Reproduction Steps
- Start a run on a thread with the v2 runtime and the stock
@copilotkit/react-coreclient. - Press Stop.
ProxiedCopilotRuntimeAgent.abortRunfiresPOST .../agent/:agentId/stop/:threadIdwith no body and does not await the response (packages/core/src/agent.ts,void fetch(...)). - Immediately send the next message on the same thread, so a new run starts.
- Let the stop request from step 2 arrive after the new run has started, for example on a slow network.
✅ Expected Behavior
Only the run the user pressed Stop on is cancelled. The next run keeps streaming.
❌ Actual Behavior
The stop request carries no runId, so the runtime calls runner.stop({ threadId }) and cancels whichever run is active on the thread, including the new one. Both InMemoryAgentRunner.stop and IntelligenceAgentRunner.stop already return false for a non-matching runId, and since 05d6cacd (#7078) the Intelligence stop handler reads an optional { "runId": "..." } body. #6982 extends that to every runtime kind. No client in this repository sends the body yet, so the per-run scope on the server is unreachable through the SDK.
#7078 asked for exactly this scoping on the server side: "Do not release a lock using only threadId, because a delayed or duplicate Stop could otherwise release the lock belonging to a newer run." The same argument applies to the client that issues the stop.
Proposed change
abortRun sends { "runId": "<current run>" } for both the multi-route and the single-route transport. The client already knows the run it is aborting: run-handler.ts tracks logicalRunId for the active run. A runtime that ignores the body keeps its thread-wide behaviour, and a runtime that reads it stops only that run, so old and new clients and servers stay compatible in every combination. This is independent of #6982 and does not need to be stacked on it.
I can open a PR for this if the direction is fine.
CopilotKit Version
@copilotkit/[email protected]
@copilotkit/[email protected]
@copilotkit/[email protected]Source: CopilotKit/CopilotKit