unbridled-41 opened a new issue, #5003:
URL: https://github.com/apache/rocketmq-dashboard/issues/5003

   ### Studio Version
   
   branch: rocketmq-studio
   git commit id: 1ef5d860799ac3fabfcdea942cc4dcc77ded7be6
   
   ### Runtime Environment
   
   Service-level reproduction in the repository's test suite (AiRunServiceTest, 
MockMvc-free); no browser, cluster or MySQL needed.
   
   ### Connected RocketMQ Cluster
   
   Not applicable — the defect is in the AI run stream replay path, independent 
of any RocketMQ cluster topology.
   
   ### Describe the Bug
   
   Reconnecting to a finished agent run (`GET /api/ai/runs/:runId/stream`, the 
replay path in `AiRunService.attach`) delivers a terminal `run_finished` frame 
**without** the `durationMs` field. The live path (`AiRunExecutor.finalizeRun` 
→ `RunFinished(runId, status, durationMs)`) always carries it, so a replayed 
block is observably different from what the run originally streamed.
   
   `AgentEventProjector.replay` 
(`server/src/main/java/org/apache/rocketmq/studio/ops/ai/conversation/event/AgentEventProjector.java:272-273`
 at 1ef5d860) maps a persisted terminal to `new LiveEvent.RunFinished(runId, 
terminal.status(), null)`, and the class is annotated 
`@JsonInclude(JsonInclude.Include.NON_NULL)` (`LiveEvent.java:49`), so the null 
duration is omitted from the serialized frame entirely. The projector's own doc 
comment at `:240-243` promises the opposite ("Same wire vocabulary on both 
sides, so the client cannot tell a replayed block from a streamed one").
   
   ### Steps to Reproduce
   
   1. Run an agent run to completion.
   2. Reconnect to it via `GET /api/ai/runs/{runId}/stream?after=0`.
   3. Observe the replayed `run_finished` frame: it has `type`, `runId`, 
`status` but no `durationMs` key.
   
   The repository's own contract artifacts state the field must exist:
   - `web/src/api/aiEvents.contract.test.ts:139` — `run_finished: { type: true, 
runId: true, status: true, durationMs: true }`, and the live absent-field 
matrix at `:424-433` expects `['run_finished', []]` (no field may be absent).
   - `web/src/api/aiEvents.ts:169` — `LiveRunFinishedEvent.durationMs: number` 
(non-optional).
   - `docs/api-spec.md:2424` — `run_finished` fields listed as `runId, status, 
durationMs` (no `?` marker, unlike `tool_done`'s `durationMs?`).
   
   ### What Did You Expect to See?
   
   A replayed `run_finished` carries `durationMs` with the run row's persisted 
duration, indistinguishable from the live frame.
   
   ### What Did You See Instead?
   
   The `durationMs` key is absent from the replayed frame (NON_NULL 
serialization drops the hard-coded null).
   
   ### Additional Context
   
   Note on current impact: the web render layer today maps `run_finished` to a 
terminal status and does not read `durationMs` (`foldTimeline.ts:178`, 
`reduceLive.ts:48-50`), so the defect surfaces as a contract/type drift rather 
than a visible crash. `equivalence.test.ts` builds its scenarios with the field 
set, so the equivalence property the projector cites assumes it.
   
   Corresponding pull request: #4999.


-- 
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]

Reply via email to