feat: add animated spinner and streaming token output - #1
Merged
Conversation
Replace the static single-frame "Thinking..." spinner with a background- threaded AnimatedSpinner that cycles braille frames at ~80ms, providing visual feedback while the model processes. Stream TextDelta tokens directly to stdout as they arrive instead of buffering through MarkdownStreamState, so the response appears incrementally. Add 8ms TTY pacing between tokens to prevent buffered HTTP chunks from rendering as a wall of text. The spinner is automatically stopped via a global AtomicBool flag when the first text or thinking token arrives. Also make find_stream_safe_boundary flush after every complete line (instead of only on blank lines) and add a 240-char fallback for long lines without newlines. Made-with: Cursor
Apply rustfmt across the workspace to fix CI formatting check. Re-enable MarkdownStreamState for TextDelta streaming so output renders with proper ANSI formatting (bold, bullets, code blocks) while still flushing per-line for incremental display. Made-with: Cursor
The text content block was hardcoded to index 1 (reserving 0 for reasoning), which collided with tool-call index 0+1 and broke assertions when no reasoning content was present. Now text_index() returns 0 when there is no reasoning block and 1 when there is, and tool-call indices are offset from text_index()+1 accordingly. Fixes openai_streaming_requests_opt_into_usage_chunks and stream_message_normalizes_text_and_multiple_tool_calls tests. Made-with: Cursor
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.
Summary
AnimatedSpinnerthat cycles braille frames (~80ms interval), giving continuous visual feedback while the model processesTextDeltatokens directly to stdout as they arrive instead of buffering throughMarkdownStreamState, making the response appear incrementally (like Claude's web UI)find_stream_safe_boundaryflush after every complete line and add a 240-char fallback for long unwrapped linesTest plan
physmindinteractively and verify the spinner animates while waiting for the modelphysmind -p "hello" | cat) to confirm pacing is skipped for non-TTYcargo testpassesMade with Cursor