Streaming lets you pipe generated tokens to the client — or to any output sink — as soon as they arrive, without waiting for the model to finish the entire response. In aisdk/core every streaming request returns aDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/phpaisdk/core/llms.txt
Use this file to discover all available pages before exploring further.
Stream object that exposes two iteration modes, four lifecycle hooks, and a ->run() helper for when you only need the final TextResult.
Streaming requires the model to advertise
Capability::Streaming. Calling ->stream() automatically adds this capability requirement; the SDK raises a CapabilityNotSupportedException before making any HTTP call if the model does not support it.Basic streaming
Call->stream() instead of ->run(). Iterate ->chunks() to receive raw text deltas as strings:
->chunks() is a Generator<int, string> that only yields TextDeltaPart text values. Non-text stream events (tool call fragments, finish metadata, etc.) are still recorded internally but not surfaced here.
Collecting the final result
After iterating chunks
After theforeach loop completes, call ->result() to retrieve the assembled TextResult:
Draining with ->run()
If you don’t need to print tokens incrementally — for example, you are recording the full response — call ->run() to drain the stream and return the TextResult directly:
Typed stream parts
For fine-grained control — interleaving reasoning tokens, responding to tool call fragments mid-stream, or detecting errors without exceptions — iterate->parts() instead of ->chunks(). Each yielded value is a StreamPart subclass:
StreamPart reference
| Class | Key properties | Description |
|---|---|---|
TextDeltaPart | $text: string | One fragment of generated text. |
ReasoningDeltaPart | $text: string | Fragment of an inner reasoning trace (reasoning models only). |
ToolCallStartPart | $index: int, $id: string, $name: string | Signals the start of a new tool call. Argument JSON follows as ToolCallDeltaParts. |
ToolCallDeltaPart | $index: int, $argsJson: string, $id: ?string, $name: ?string | Partial argument JSON for the tool call at $index. |
FinishPart | $reason: FinishReason, $usage: Usage | Emitted once when the model stops generating. |
ProviderMetadataPart | $provider: string, $metadata: array | Provider-specific metadata emitted during the stream. Accumulated by StreamState and available via $result->providerMetadata after the stream ends. |
ErrorPart | $error: Throwable | Signals a stream error. Never yielded to the caller — when an ->onError() hook is registered, the callback receives the Throwable and iteration continues; otherwise the Throwable is thrown immediately. |
Lifecycle hooks
Hooks let you react to stream events without managing loop boilerplate. They are registered before iteration begins and fire during the same->parts() / ->chunks() / ->run() pass:
Hook summary
| Method | Callback signature | Fires |
|---|---|---|
->onChunk(callable) | fn(string $text): void | Once per TextDeltaPart, with the raw text fragment. |
->onToolCall(callable) | fn(ToolCall $call): void | Once per assembled tool call, after all argument fragments have been received. |
->onFinish(callable) | fn(TextResult $result): void | Once, when the stream ends and the final TextResult is ready. |
->onError(callable) | fn(Throwable $e): void | On stream error. Registering this hook prevents the exception from propagating. |
Streaming in an HTTP response
aisdk/core is transport-agnostic. The following skeleton shows how to wrap a stream in a PSR-7 / Laravel-style streaming HTTP response:- Plain PHP
- Laravel