You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
streamText now honors TimeoutConfiguration.FirstChunkMs. It aborts a step with a TimeoutError ("First chunk timeout of Nms exceeded") when the provider returns its response stream but no content arrives in time. Chunks without output (response metadata, raw chunks, empty deltas) do not stop the timer. The first text, reasoning, tool input, or tool call chunk disarms it, and each step starts a fresh budget. The end of the model response, a provider stream error, and the end of the step also clear it. GenerateTextAsync has no stream, so it logs the upstream "only supported by streaming functions" warning, together with the chunkMs one when both are set.
streamText first chunk timeout::should clear firstChunkMs when the registered step stream is cancelled (stream-text-timeout.test.ts; the port has no experimental_transform / stopStream)
packages/ai/src/prompt/prepare-language-model-call-options.test.ts::timeout helpers (from request-options) > getStepTimeoutMs::should return stepMs from an object (the port has no getStepTimeoutMs; callers read TimeoutConfiguration.StepMs)
packages/ai/src/prompt/prepare-language-model-call-options.test.ts::timeout helpers (from request-options) > getFirstChunkTimeoutMs::should return undefined when timeout is undefined (no getFirstChunkTimeoutMs; callers read FirstChunkMs)
packages/ai/src/prompt/prepare-language-model-call-options.test.ts::timeout helpers (from request-options) > getFirstChunkTimeoutMs::should return undefined when timeout is a number (same reason; a TimeSpan converts to TotalMs only)
packages/ai/src/prompt/prepare-language-model-call-options.test.ts::timeout helpers (from request-options) > getFirstChunkTimeoutMs::should return firstChunkMs from an object (same reason)
The file and reasoning file cases of "should disarm firstChunkMs before forwarding the first ${name}" (the port has no file stream part).
Still open in #702: toolMs, per-tool timeouts, the stream retry tests, and AgentOptions.Timeout.
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 0 remain after this review.
📝 Walkthrough
Streaming generation now supports a per-step timeout that runs until the first content chunk arrives. Non-output chunks do not end the timeout. Non-streaming generation warns when either streaming-only timeout is configured.
Changes: First-chunk timeout
Layer / File(s)
Summary
Timeout configuration and setup src/Vercel.AI/Prompt/TimeoutConfiguration.cs, src/Vercel.AI/Util/CallTimeouts.cs, src/Vercel.AI/PublicTypes.cs
TimeoutConfiguration adds FirstChunkMs. CallTimeouts creates its controller for streaming calls and includes it in merged abort signals.
Streaming starts the timeout before consuming model output. It clears on first output, step completion, cleanup, or error, and re-arms for each step. Tests cover non-output chunks, output types, multiple steps, and provider errors.
Unsupported-timeout warnings and documentation src/Vercel.AI/Generation.cs, tests/Vercel.AI.Tests/Upstream/GenerateText/OptionsTimeoutTests.cs, docs/articles/quickstart.md
Non-streaming generation warns separately for FirstChunkMs and ChunkMs. Tests cover each warning and their combined order. The quickstart describes the timeout behavior.
Issue 702 requests firstChunkMs for streamText; this change implements that timeout and its warning behavior.
Issue 697 covers streamText timeout options and unported timeout tests; this change implements the firstChunkMs portion.
Merge Risk:⚪ Minimal · up to 2d6fb
The first-output deadline interrupts a stalled stream as intended. No identified issue blocks merging after normal checks.
Security architecture risk:🔵 Low · up to 2d6fb
The timeout is opt-in and confined to one generation call. Normal cleanup and cancellation paths are wired, but concurrent timer expiry and provider-specific cancellation behavior remain unverified.
Retained concerns
No architecture-level concerns identified.
Security review details
Security Blast Radius
inferred — The new abort authority is scoped to one generation call and inherited by its later steps through a shared signal. Expiry faults that call's result tasks and cancels its token; the inspected change does not introduce a cross-call controller or additional tool authority.
Trust Boundaries and Controls
observed — A provider cannot keep the first-output deadline alive indefinitely using only metadata or empty deltas. A qualifying output part intentionally ends this deadline, so FirstChunkMs alone is not a whole-response execution budget.
Resilience and Maintainability Implications
observed — Each provider read is raced against the call's abort signal, allowing timeout handling to proceed without waiting for a noncooperative read. Stopping the provider's underlying work still requires cancellation cooperation. An atomic completion guard prevents a later abort from replacing an already selected successful outcome.
Hardening Proposals
proposed — If strict step-local expiry arbitration is required, use one atomic ownership decision for timer expiry and retirement. The existing scheduler checks cancellation outside the lifecycle lock and does not join an executing callback; strengthening that behavior would make boundary-time cleanup guarantees explicit rather than scheduling-dependent.
Pre-merge checks: 5
Check name
Status
Explanation
Description Check
Check skipped - CodeRabbit’s high-level summary is enabled.
Title check
The title clearly and concisely identifies the main change: adding timeout.firstChunkMs support to streamText.
Linked Issues check
Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check
Check skipped because no linked issues were found for this pull request.
Upstream Parity
PASS. The PR names upstream tests and behavior, so the check applies. TimeoutConfiguration.FirstChunkMs maps to upstream firstChunkMs; the timeout lifecycle and generate warning match `vercel/ai@d…
Full details: Upstream Parity
Explanation
PASS. The PR names upstream tests and behavior, so the check applies. TimeoutConfiguration.FirstChunkMs maps to upstream firstChunkMs; the timeout lifecycle and generate warning match vercel/ai@dfcace2a3e7f3016ccb0e3c7e3a5b8103c8967b4 (packages/ai/src/prompt/request-options.ts, generate-text.ts, and stream-text.ts). The port includes the warning tests and the four supported first-chunk tests. It marks the upstream file and reasoning-file cases as Partial and lists both omissions with the reason that the .NET port has no file stream part. The changed user-visible API and behavior are documented in docs/articles/quickstart.md; COMPATIBILITY.md is unchanged, so the pin-move condition does not apply. No unapproved .NET-only behavior or unmapped source symbol is introduced.
✨ Finishing Touches
📝 Generate docstrings
Commit to this branch
Create a new PR
🧪 Generate unit tests (beta)
Commit to this branch
Create a new PR
Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Comment @coderabbitai help to get the list of available commands.
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
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.
streamTextnow honorsTimeoutConfiguration.FirstChunkMs. It aborts a step with aTimeoutError("First chunk timeout of Nms exceeded") when the provider returns its response stream but no content arrives in time. Chunks without output (response metadata, raw chunks, empty deltas) do not stop the timer. The first text, reasoning, tool input, or tool call chunk disarms it, and each step starts a fresh budget. The end of the model response, a provider stream error, and the end of the step also clear it.GenerateTextAsynchas no stream, so it logs the upstream "only supported by streaming functions" warning, together with thechunkMsone when both are set.Part of #702.
.NET-only symbols: none.
TimeoutConfiguration.FirstChunkMsmirrorsfirstChunkMs.Not ported
Tracked in #702.
streamText first chunk timeout::should clear firstChunkMs when the registered step stream is cancelled(stream-text-timeout.test.ts; the port has noexperimental_transform/stopStream)getStepTimeoutMs; callers readTimeoutConfiguration.StepMs)getFirstChunkTimeoutMs; callers readFirstChunkMs)TimeSpanconverts toTotalMsonly)Still open in #702:
toolMs, per-tool timeouts, the stream retry tests, andAgentOptions.Timeout.🤖 Generated with Claude Code
https://claude.ai/code/session_01TQmtUKfZTs497KkiGSfYk9
Summary by CodeRabbit
New Features
FirstChunkMsto configure a streaming timeout for receiving the first content chunk from each generation step.Bug Fixes
Documentation
FirstChunkMsand its streaming-only behavior.