yyqdbngt opened a new pull request, #5326:
URL: https://github.com/apache/rocketmq-dashboard/pull/5326
### Which Issue(s) This PR Fixes
- Fixes #5186
### Brief Description
`consumeEventStream` (`web/src/api/ai.ts`) treated the end of the response
body as a normal
termination: the `for (;;)` loop breaks on `done` from `reader.read()` and
the function returned, so
a body that closed before the server's terminal `event: done` was
indistinguishable from a finished
run — for `openRunStream` and `attachRunStream` alike. A proxy timeout, a
dropped connection or a
restarted server therefore made the run stream resolve silently:
`useAgentRun` left its error path
untouched, the console stopped streaming, and the rest of the answer was
lost with no explanation.
The idle watchdog cannot catch this, because `reader.read()` resolves
immediately with
`done: true` instead of going quiet.
The fix is 9 lines in the same function (`web/src/api/ai.ts:305`): `onFrame`
already returns `true`
for the terminal `done` frame and every such return exits the function, so
reaching the end of the
body without one now throws a structured `AiStreamError`
(`llm.stream.premature_eof`, "AI stream ended before the terminal done
frame") with a hint telling
the operator the run continues server-side. Frames that were delivered
before the truncation stay
delivered. A `done` frame that arrives without a trailing blank line is
still accepted through the
final-flush path, and normal `done` frames, `error` frames, explicit aborts
(`AbortController`),
the idle watchdog and reader cancellation keep their behaviour.
The tests are in `web/src/api/ai.test.ts`: two regression cases (open and
attach) that fail on the
unmodified tree, plus one case pinning the trailing-blank-line flush path so
the new check cannot
turn a complete run into a failure.
### How Did You Test This Change?
Red — the two new cases, written and run first, with `web/src/api/ai.ts`
still unmodified:
```
$ cd web && npx vitest run src/api/ai.test.ts
FAIL src/api/ai.test.ts > AI API > openRunStream / attachRunStream (SSE) >
rejectsWhenTheBodyEndsBeforeTheTerminalDoneFrameTest
AssertionError: promise resolved "undefined" instead of rejecting
- Expected:
Error {
"message": "rejected promise",
}
+ Received:
undefined
❯ src/api/ai.test.ts:219:7
FAIL src/api/ai.test.ts > AI API > openRunStream / attachRunStream (SSE) >
rejectsWhenAnAttachedStreamEndsBeforeTheTerminalDoneFrameTest
AssertionError: promise resolved "undefined" instead of rejecting
❯ src/api/ai.test.ts:239:64
Test Files 1 failed (1)
Tests 2 failed | 28 passed (30)
```
Green — the same file after the fix:
```
$ cd web && npx vitest run src/api/ai.test.ts
Test Files 1 passed (1)
Tests 30 passed (30)
```
Also run for the two touched files: `npx tsc -b` (exit 0) and
`npx eslint src/api/ai.ts src/api/ai.test.ts` (exit 0).
### Checklist
- [x] One coherent change; unrelated modifications are not bundled in
- [x] Commit subject follows Conventional Commits
- [x] Tests added or updated for non-trivial changes
- [x] New UI text has both Chinese and English entries under `web/src/i18n/`
— not applicable: no
user-facing string is added. The error code and message travel through
the existing
`AiStreamError` → `ErrorBlock` path, which renders
`code`/`message`/`hint` as-is.
- [x] Architecture constraints stay green (`mvn test` runs the ArchUnit
checks) — not applicable:
the change is web-only and touches no Java module.
- [x] New source files carry the ASF license header — no new file; `ai.ts`
and `ai.test.ts` keep
their existing header.
- [x] Documentation touched where behaviour changed (README / `docs/` /
in-app help) — not
applicable: the wire contract is unchanged, the client now enforces
the terminal frame the
server already documents and always writes.
--
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]