docs: chat app recipe with streaming patterns#6788
Conversation
Merging this PR will not alter performance
Comparing Footnotes
|
Greptile SummaryThis PR adds a new "Chat App" recipe under
Confidence Score: 5/5Safe to merge — this is a documentation-only change adding a new recipe page and its sidebar entry. All previously flagged issues have been addressed. The streaming code examples are logically correct: mutations happen inside async with self, the yield is placed after the block exits, is_streaming resets unconditionally in finally, and overlapping submits are serialized via is_generating with index-based bubble updates. No runtime code is touched. No files require special attention. Important Files Changed
Reviews (4): Last reviewed commit: "Keep streamed tokens tied to their own a..." | Re-trigger Greptile |
…nai, try/finally is_streaming)
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 722007582a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| self.is_streaming = False # hide dots on first token | ||
| first_token = False | ||
| else: | ||
| self.messages[-1]["content"] += delta |
There was a problem hiding this comment.
Keep streamed tokens tied to their own assistant message
Because this handler is registered with background=True, a second submit can run while the first stream is still appending tokens. In that case each async with self refreshes state, and self.messages[-1] points to whichever message is currently last (for example the next user's prompt or another assistant reply), so the first response can corrupt a later message. Capture the assistant message index when it is appended, or serialize/disable concurrent sends before recommending this as the correct streaming pattern.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed. Confirmed the concern against Reflex's event processor: background events call _create_event_task immediately and bypass per-token ordering (unlike sequential events, which go through _enqueue_for_token), so two send_message submits on the same token run as concurrent asyncio tasks. Each async with self then re-resolves self.messages[-1] against current state, so one stream could append to another turn's message.
The Correct example now (1) captures the assistant message's index when the bubble is created on the first token and appends subsequent tokens to self.messages[assistant_index] instead of self.messages[-1], and (2) adds a separate is_generating guard (distinct from is_streaming, which flips off on the first token) that's set at the start and reset in finally, so overlapping submits are ignored while a reply is still streaming. The stream-append-on-first-token teaching point is unchanged. Added an explanatory sentence above the snippet plus a bullet in the 'differences that matter' list.
|
Addressed in the latest commit ("Keep streamed tokens tied to their own assistant message"), taking the second remedy you suggested (per-turn index rather than The streaming handler now captures the assistant bubble's index when it's first appended ( On the loading flag: I traced the state mutations rather than driving a live token stream (the example uses a placeholder LLM client). |
Adds a chat-app recipe under
docs/recipes/others/: a basic message-bubble chat UI plus the streaming-append patterns (append the assistant message on the first token, not before) that keep the loading experience clean.Draft — from the AI-builder memory corpus. Draft pending a news fragment /
skip-changeloglabel and a sidebar/recipe-index entry if needed.🤖 Generated with Claude Code