fix(assistant): records renders keep empty lists; streamed progress keeps the turn context #59

Merged
KofTwentyTwo merged 1 commits from fix/records-render-and-stream-context into develop 2026-10-16 00:55:50 +00:00
KofTwentyTwo commented 2026-10-16 00:37:29 +00:00 (Migrated from github.com)

Two bugs the owner hit on kof22 (assistant_message 84, 2026-10-16 00:24 UTC):

  1. Page crash on an empty query result. A query_records result that matched nothing was stored and streamed as a records render without rows or columns, because QQQ's default JSON drops empty lists. Next read render.rows.length and the whole page failed (qqq-frontend-next#170 guards the UI side).
    • New RenderShapes: parts and TurnEvents are serialized keeping empty lists (NON_NULL).
    • Parts and events stored before this fix are completed when read (records columns/rows, record fields, history entries/details).
    • UI API extension 1.4.0 (minor): adds AssistantRecordsRenderV1 documenting that the lists are always present. The contract test passes and assistant.yaml is regenerated.
  2. "Could not flush job progress" NPE. Anthropic, and the scripted test provider, stream deltas on a virtual thread with no QContext. The writing phase progress then ran JobLogWriter.flush with no instance. The delta handler now runs in the turn's captured context.

Tests:

  • RenderShapesTest: empty lists survive serialization; the exact stored payload is completed on read; old events too.
  • DurableTurnsTest.streamedProgressRunsInTheTurnContext: progress during streaming sees the instance.
  • Module verify: 329 tests pass.

🤖 Generated with Claude Code

Two bugs the owner hit on kof22 (assistant_message 84, 2026-10-16 00:24 UTC): 1. **Page crash on an empty query result.** A `query_records` result that matched nothing was stored and streamed as a `records` render without `rows` or `columns`, because QQQ's default JSON drops empty lists. Next read `render.rows.length` and the whole page failed (qqq-frontend-next#170 guards the UI side). - New `RenderShapes`: parts and `TurnEvent`s are serialized keeping empty lists (NON_NULL). - Parts and events stored before this fix are completed when read (records columns/rows, record fields, history entries/details). - UI API extension **1.4.0** (minor): adds `AssistantRecordsRenderV1` documenting that the lists are always present. The contract test passes and `assistant.yaml` is regenerated. 2. **"Could not flush job progress" NPE.** Anthropic, and the scripted test provider, stream deltas on a virtual thread with no `QContext`. The `writing` phase progress then ran `JobLogWriter.flush` with no instance. The delta handler now runs in the turn's captured context. **Tests:** - `RenderShapesTest`: empty lists survive serialization; the exact stored payload is completed on read; old events too. - `DurableTurnsTest.streamedProgressRunsInTheTurnContext`: progress during streaming sees the instance. - Module verify: 329 tests pass. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.