Repository navigation
refactor(narratives): type the SSE frames the agent loop emits - #543
Merged
Merged
Conversation
Contributor
There was a problem hiding this comment.
Code Review
This pull request introduces a set of strongly-typed Server-Sent Event (SSE) frames to replace the previous untyped dictionary payloads in the chat pipeline. It defines a new module sse_frames.py containing dataclasses for each frame type (such as StatusFrame, ThoughtFrame, TextFrame, and various terminal frames) and updates the chat pipeline, routes, and tests to utilize these new types. I have no feedback to provide as there are no review comments to evaluate.
nick-nlb
marked this pull request as ready for review
October 22, 2026 00:31
juliawu
approved these changes
Oct 22, 2026
juliawu
left a comment
Contributor
There was a problem hiding this comment.
Very clean! Love the new typing. Passing along some gemini comments, but otherwise lgtm.
8 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
In
workflows/chat_pipeline.py, each turn reported progress by passing an event name and adict[str, Any]toemit(event, data), andserver/routes/chat.pyserialized that dictionary directly to SSE. The contents of a frame were never declared in code, so a misspelled key or a missing field reached the browser without any type-check error, which goes againstCODING_GUIDELINES.md§3.2.This change replaces the untyped
(event, dict)callback with a union of frozen dataclass frames (SseFrame) inworkflows/sse_frames.py, serialized in one place inserver/routes/chat.py. The wire output is unchanged. Typing the frames now means upcoming SSE changes in the agent loop rewrite become reviewed type changes rather than edits to inline dictionaries.Related Issues
Changes Made
Changes:
workflows/sse_frames.py,narratives/AGENTS.md): Defines a frozen dataclass for each SSE frame variant (StatusFrame,ThoughtFrame,TextFrame,ToolCallFrame,DataStatusFrame,SourcesFrame,ChartConfigFrame,FollowUpsFrame, and the terminal framesTerminalCompleteFrame,TerminalRefusedFrame, andTerminalErrorFrame) and theSseFrameunion.workflows/chat_pipeline.py,server/routes/chat.py): ChangesEmittoCallable[[SseFrame], None], replaces the inline dictionary emissions andterminal_framehelper with frame constructors, and serializesframe.payload()inchat.py.workflows/sse_frames_test.py,workflows/chat_pipeline_test.py,server/routes/chat_test.py): Adds per-variant serialization tests, a full-turn wire-equivalence test against the baseline output, and updates the route test stubs to emit typed frames.Testing Done
pnpm test:agent(uv run pytest): 879 passed.pnpm test:ui(vitest run): 26 files, 286 passed.pnpm lint:ui(tsc --noEmitandbiome check): passed.pnpm lint:agent(ruff format --check,ruff check, andmypy --strict): passed across all 67 source files.pnpm build:ui: passed.pnpm lint:deploy:terraform fmt -check,pnpm run lint:shell, andpnpm run lint:dockerpassed (terraform validatefails with a pre-existing GCS backend configuration error onmain; nodeploy/files were modified).Checklist:
Manual
Verified against public Data Commons with
pnpm dev:agent, comparing the rawPOST /agent/chat/streamoutput onmainand on this branch:status,thought,tool_call,data_status,sources, streamedtext,chart_config, the signedcompleteterminal frame, andfollow_upswere emitted with identical event names, payload keys, and key presence.refusedterminal frame with noerrorkey, and that an ambiguous place query ("What is the population of Georgia?") streamed the clarification and emitted a signedcompleteterminal frame with empty state slots.Risk & Rollback
The wire format is unchanged. Byte-for-byte compatibility is covered by the per-frame serialization tests in
workflows/sse_frames_test.pyandtest_a_complete_turn_serializes_to_the_recorded_framesinworkflows/chat_pipeline_test.py. Rollback is reverting the PR.Follow-ups
Checklist
AGENTS.mdand followedCODING_GUIDELINES.md, plusFRONTEND.mdfor UI changes.Note: Only Maintainers can approve and merge PRs. Expected initial review time: 3 business days.