unbridled-41 opened a new pull request, #5002:
URL: https://github.com/apache/rocketmq-dashboard/pull/5002
## Problem
A prompt typed immediately after clicking 停止生成 was **silently lost**. The
stop window works like this (base `1ef5d860`):
1. The stop POST resolves; the terminal frames have not arrived.
`useAgentRun` keeps `isStreaming=true` but sets `stopRequested=true`
(`useAgentRun.ts:393`, deliberately not aborting the fetch so
`run_status{STOPPED}` can still arrive).
2. `Composer` derives `generating = isStreaming && !stopRequested`
(`Composer.tsx:248`), so `generating` is now **false** and `canSend` (`:250`)
becomes **true**: the composer accepts the send.
3. `Composer.handleSend` (`:256-261`) calls `onSend(text)` and immediately
clears the draft (`onChange('')`).
4. `useAiSend.startRun`'s existing-conversation branch
(`useAiSend.ts:109-111`, base) did `void optionsRef.current.send(...)` and
returned the non-null id, so `AiPage.handleSend`'s only restore path — `target
=== null` (`index.tsx:122-124`, base) — never fired.
5. `useAgentRun.startStream`'s in-flight guard (`useAgentRun.ts:307`, base:
`if (chatInFlightRef.current) return;`) silently no-oped — `chatInFlightRef` is
released only in `finishStream` (`:257`) after the stream closes.
## Root cause
`startStream`'s two refusal branches `return` instead of rejecting, and the
only failure signal `AiPage.handleSend` checks (`startRun === null`) covers
just the create-conversation path. The button state (`stopping`,
`SendStopButton.tsx:62`) and the Enter-enabled state (`!generating`) disagree
inside this window, so the in-flight guard is the last line of defence — and it
was silent.
## Fix
- `startStream` throws (with a reason) instead of silently returning on both
guard branches.
- `useAiSend` awaits the send in the existing-conversation branch so the
refusal propagates to the caller instead of dying in a `void`.
- `AiPage.handleSend` restores the cleared draft on a rejected send
(mirroring the existing create-failure restore), so the operator sees their
prompt again.
The double-submit guarantee is unchanged: still one stream, first prompt
wins (`opensOnlyOneStreamForADoubleSubmitTest` keeps its assertion).
## Scoring (AGENTS.md)
PRIORITY **56** = impact 24 (a user's typed prompt irrecoverably dropped,
zero feedback, on a common interaction: stop a long run, retype) + reach 10 (AI
composer) + reproducibility 12 (deterministic inside the stop window, which is
the normal way to abandon a long answer and continue) + maintainability value
10 (removes a silent no-op guard). FIX_CONFIDENCE **88**: guard->reject is
mechanical; the draft-restore path already existed for create failures and is
now extended; tests pin both the refusal and the restore.
## Tests
- New:
`useAgentRunTest.reportsASendInTheStoppingWindowInsteadOfSilentlyDroppingItTest`
— pre-fix: **`AssertionError: promise resolved "undefined" instead of
rejecting`**; it also verifies the in-flight stream is not clobbered by the
refused send.
- Updated: `AiPage.doesNotAdmitASecondSendWhileOneIsInFlightTest` now also
pins the draft being restored after the refused second send;
`useAgentRunTest.opensOnlyOneStreamForADoubleSubmitTest` swallows the
now-throwing second send the way production does.
- Post-fix: `npx vitest run src/pages/ai/` -> **16 files, 192/192 passed**,
no unhandled rejections; `npx tsc --noEmit` clean; `npx eslint` on the changed
files clean; `src/pages/studio/` + `src/pages/home/` (the other `useAiSend`
consumers) -> **101/101**.
## Risk
Low. The refusal previously vanished; now it either restores the draft (page
path) or surfaces as a handled rejection. Any caller that fire-and-forgets
`run.send()` directly would now see an unhandled rejection instead of a silent
no-op — the production callers are `AiPage.handleSend` and the draft-handoff,
both covered.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]