Skip to content

fix(chat): drop empty assistant_message from projection - #738

Merged
delete-cloud merged 2 commits into
mainfrom
fix/empty-assistant-message-projection
Sep 4, 2026
Merged

delete-cloud merged 2 commits into
mainfrom
fix/empty-assistant-message-projection

Conversation

@delete-cloud

@delete-cloud delete-cloud commented Sep 3, 2026 •

Copy link
Copy Markdown
Owner

Summary

Two dogfood bugs on the new runtime chat path.

  1. Tool-call-only model rounds persist assistant_message with {"content": ""}. Projection mapped that to text="" and validation 500'd GET /sessions, GET /sessions/{id}, and GET /sessions/{id}/chat-events. Fix: project_chat_event returns None for empty assistant text. EventRecords are not deleted (ADR-0077).

  2. _transition_unit copied pending facts without run_id. After restore, snapshot LEFT JOIN agent_runs on payload.run_id could not attach the superseded run, so the chat view kept the post-checkpoint turn. Fix: stamp state_version.run_id when the payload omits it; keep an explicit child run_id.

Test plan

  • uv run pytest tests/coding_agent/test_connected_chat_projection.py tests/coding_agent/test_durable_commit_ports.py -q
  • Poisoned dogfood session 0c9c82a8 GET endpoints 200 after (1)
  • CI

Tool-call-only model rounds persist assistant_message facts with empty
content. Connected-chat projection mapped those to text="" and then
failed payload validation, so GET /sessions, GET /sessions/{id}, and
GET /sessions/{id}/chat-events returned 500.

Drop the empty fact at projection time. Existing EventRecords stay in
the audit log (ADR-0077).

Verified: tests/coding_agent/test_connected_chat_projection.py (17 passed);
poisoned dogfood session 0c9c82a8 GET endpoints now 200.
@delete-cloud
delete-cloud deleted the fix/empty-assistant-message-projection branch September 3, 2026 18:07
New-runtime transitions copied engine pending facts into EventRecords
without run_id. After restore, snapshot LEFT JOIN could not attach the
superseded run, so the chat view kept the post-checkpoint turn.

Stamp state_version.run_id when the payload omits it; keep an explicit
child run_id. Empty assistant_message drop stays in the projection.
@delete-cloud delete-cloud reopened this Sep 4, 2026
@delete-cloud
delete-cloud merged commit 903c4db into main Sep 4, 2026
1 check passed
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