Skip to content

Fix staging Stop requests and queued edits - #8257

Merged
Sg312 merged 1 commit into
stagingfrom
fix/staging-queued-edit
Sep 24, 2026
Merged

Sg312 merged 1 commit into
stagingfrom
fix/staging-queued-edit

Conversation

@Sg312

@Sg312 Sg312 commented Sep 24, 2026

Copy link
Copy Markdown
Collaborator

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

  • Bug fix
  • New feature
  • Breaking change
  • Documentation
  • Other

Testing

  • 113 focused regression tests pass, including an 11 MiB tool input, sub-1 KB Stop request, queued correction delivery, edited-message protection, and lossless server replay.
  • App type checking, Biome, and API validation audit pass.
  • Live staging request against the already-cancelled affected run: previous billing headers return HTTP 400; corrected control headers return HTTP 200 with settled: true.
  • Browser automation runtime exits before initialization, so an interactive staging check remains unavailable.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel

vercel Bot commented Sep 24, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
docs Skipped Skipped Sep 24, 2026 7:24pm UTC

Request Review

@Sg312
Sg312 merged commit d9db35e into staging Sep 24, 2026
25 checks passed
@greptile-apps

greptile-apps Bot commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 4/5

The PR should not merge until Stop cannot commit an incomplete replay ahead of the run owner's full response.

Findings

  1. P1 Partial replay becomes final ▶
  2. P2 Stopped tools remain executing ▶
  3. P2 Replay precedes stream matching ▶

Summary

The PR makes Stop requests identifiers-only, rebuilds stopped responses from server events, changes explicit-abort billing headers, and prevents immediate dispatch of a queued message while it is being edited.

  • A non-terminal but contiguous replay can win persistence and permanently truncate the response.
  • Stopped replay can retain an executing tool state, and replay is loaded before stream-to-chat matching.

Reviews (1) · Last reviewed commit: "Fix staging Stop admission and oversized..."

): 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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 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({

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 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)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 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.

This branch was previously deployed

1 inactive deployment
Preview — c7ee6325 Deployed Sep 24, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant