fix(ai): keep the first text delta when the text starts before the tool call - #1271
Conversation
…ol call The first delta after a tool call cannot enter the isNewSegment branch, since previousSegment is empty at that point. The flag survived into the second delta, which then matched all three conditions: the accumulation reset and updateTextPart wrote the remainder over the text part the first delta had created. TEXT_MESSAGE_START. This covers the other order, where the text starts first.
The harness added with TanStack#1248 streams the tool call before the message's TEXT_MESSAGE_START. This one streams them the other way round, which is what providers that open the assistant message first emit.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (7)
Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review. 📝 WalkthroughWalkthroughThe stream processor now preserves the first text delta after a tool call. Unit and end-to-end tests cover the event sequence with multiple text chunks. ChangesText-first tool stream handling
Estimated code review effort: 3 (Moderate) | ~20 minutes Merge Risk: ⚪ Minimal · up to This change preserves the first streamed text delta when text begins before a tool call, preventing incomplete messages while retaining existing multi-segment behavior. No actionable merge-blocking risk remains beyond normal checks and review. Sequence Diagram(s)sequenceDiagram
participant Browser
participant TextFirstToolPage
participant ApiTextFirstToolWire
participant StreamProcessor
Browser->>TextFirstToolPage: Open /text-first-tool
TextFirstToolPage->>ApiTextFirstToolWire: POST chat request
ApiTextFirstToolWire-->>TextFirstToolPage: Return SSE event stream
TextFirstToolPage->>StreamProcessor: Process text and tool chunks
StreamProcessor-->>TextFirstToolPage: Accumulate assistant text
TextFirstToolPage-->>Browser: Render Hello, world.
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 6 files. (1 skipped: 1 unsupported.) ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
View your CI Pipeline Execution ↗ for commit 0ae844d ☁️ Nx Cloud last updated this comment at |
|
View your CI Pipeline Execution ↗ for commit 0ae844d
☁️ Nx Cloud last updated this comment at |
@tanstack/ai
@tanstack/ai-acp
@tanstack/ai-angular
@tanstack/ai-anthropic
@tanstack/ai-bedrock
@tanstack/ai-byteplus
@tanstack/ai-claude-code
@tanstack/ai-client
@tanstack/ai-code-mode
@tanstack/ai-code-mode-snippets
@tanstack/ai-codex
@tanstack/ai-cohere
@tanstack/ai-compaction
@tanstack/ai-devtools-core
@tanstack/ai-durable-stream
@tanstack/ai-elevenlabs
@tanstack/ai-event-client
@tanstack/ai-fal
@tanstack/ai-gemini
@tanstack/ai-grok
@tanstack/ai-grok-build
@tanstack/ai-groq
@tanstack/ai-isolate-cloudflare
@tanstack/ai-isolate-daytona
@tanstack/ai-isolate-node
@tanstack/ai-isolate-quickjs
@tanstack/ai-isolate-quickjs-bun
@tanstack/ai-llmgateway
@tanstack/ai-lovable
@tanstack/ai-mcp
@tanstack/ai-memory
@tanstack/ai-mistral
@tanstack/ai-octane
@tanstack/ai-ollama
@tanstack/ai-openai
@tanstack/ai-opencode
@tanstack/ai-openrouter
@tanstack/ai-perplexity
@tanstack/ai-persistence
@tanstack/ai-preact
@tanstack/ai-react
@tanstack/ai-react-ui
@tanstack/ai-sandbox
@tanstack/ai-sandbox-cloudflare
@tanstack/ai-sandbox-daytona
@tanstack/ai-sandbox-docker
@tanstack/ai-sandbox-local-process
@tanstack/ai-sandbox-sprites
@tanstack/ai-sandbox-upstash-box
@tanstack/ai-sandbox-vercel
@tanstack/ai-skills
@tanstack/ai-solid
@tanstack/ai-solid-ui
@tanstack/ai-svelte
@tanstack/ai-utils
@tanstack/ai-vercel-gateway
@tanstack/ai-vertex
@tanstack/ai-vue
@tanstack/ai-vue-ui
@tanstack/openai-base
@tanstack/preact-ai-devtools
@tanstack/react-ai-devtools
@tanstack/solid-ai-devtools
@tanstack/svelte-ai-devtools
commit: |
|
Thanks for the PR, @iRanadheer! 🙌 @tombeckenham will take a look. Automated pre-review checks
Automated triage — a human review follows. |
|
/ai-review |
|
This comment is automated by a Grok agent. It is not a maintainer review. Verdict: ready Findings
Push Maintainers still GitHub-approve. |
🎯 Changes
Follow-up to #1247. #1248 fixed the order where the tool call precedes the message's
TEXT_MESSAGE_START. The first delta is still dropped in the other order, where the text starts first, becausehasToolCallsSinceTextStartis cleared on the start paths and never once a segment has begun.The first delta after a tool call cannot enter the
isNewSegmentbranch, sincepreviousSegmentis empty at that point. The flag survives into the second delta, which then matches all three conditions: the accumulation resets andupdateTextPartwrites the remainder over the text part the first delta had created. Multi-segment behaviour is unaffected, since a later tool call sets the flag again inhandleToolCallStartEvent.Reproduces on 0.52.0 and on main.
What is in it:
packages/ai/src/activities/chat/stream/processor.ts: clear the flag once a segment has started.packages/ai/tests/stream-processor.test.ts: a sibling to the test added with fix(ai): reset segment state when a tool-first message's TEXT_MESSAGE_START arrives #1248, same fixture, opposite event order.testing/e2e/: a harness mirroring the one added with fix(ai): reset segment state when a tool-first message's TEXT_MESSAGE_START arrives #1248, for the text-first order.Verified locally:
'sunny.'instead of'It is sunny.') and passes with the change.'world.'instead of'Hello, world.') and passes with it.pnpm run test:prpasses across all 82 projects.playwright test.✅ Checklist
pnpm run test:pr, or these tests do not apply to this pull request.docs/for this change, or this change is not user-facing.pnpm changeset), or this PR does not change a published package.🚀 Release Impact
Summary by CodeRabbit
Bug Fixes
Tests