Fix staging Stop requests and queued edits - #8257
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
|
| ): Promise<PersistedMessage | null> { | ||
| const events = await readEvents(streamId, '0') | ||
| /** StreamWriter starts at 1; Redis may trim oldest events or skip corrupt entries. */ | ||
| if (events.length === 0 || !events.every((event, index) => event.seq === index + 1)) return null |
There was a problem hiding this comment.
Partial replay becomes final When Stop reads Redis while newer events are still being flushed, this check accepts the contiguous prefix as a complete response. Stop can save that truncated response first, after which the run owner's finalization sees an existing assistant message and cannot save the missing text or tool output.
| status: 'cancelled', | ||
| }) | ||
| if (!replay) return null | ||
| return withStoppedContentBlock({ |
There was a problem hiding this comment.
Stopped tools remain executing If a tool call has no result event when Stop replays the stream, the replay leaves it marked
executing. Adding the cancelled completion block does not update the tool, so the saved response can show it still running after a refetch. The removed client snapshot path marked unfinished tools cancelled.
| ...(requestId ? { requestId } : {}), | ||
| }) | ||
| ) | ||
| : await readStoppedAssistantMessage(streamId) |
There was a problem hiding this comment.
Replay precedes stream matching Access is checked for
chatId, but this call loads the full event history for the supplied streamId before checking whether it belongs to that chat. Repeated Stop requests with a mismatched stream ID can therefore cause large, unnecessary Redis reads. Match the stream to the chat before loading its replay.
Summary
Stopping a long staging response uploaded all assistant text and tool content, exceeding the 10 MiB request limit. The worker also rejected Stop because its headers declared legacy billing without attribution, leaving queued corrections waiting for shutdown.
Stop now sends only chat/run identifiers and uses valid unbilled service headers. Server replay preserves the response; when replay is incomplete, the run owner retains responsibility for persistence. Immediate queued sends also respect the active edit marker, including empty-composer double Enter.
Type of Change
Testing
settled: true.Checklist