import { Stream } from 'effect'; import type { StreamEvent } from './events'; /** * Stream status indicating current state */ export type StreamStatus = 'streaming' | 'complete' | 'error'; /** * Token usage information */ export interface TokenUsage { promptTokens: number; completionTokens: number; totalTokens: number; } /** * Tool call information extracted from stream */ export interface ToolCallInfo { toolId: string; args: Record; result?: unknown; } /** * Options for creating a StreamResult */ export interface StreamResultOptions { /** Effect Stream of events */ stream: Stream.Stream; /** Optional callbacks - set before iteration starts */ onChunk?: (chunk: StreamEvent) => void; onFinish?: (result: { text: string; usage: TokenUsage; steps: number; }) => void; onError?: (error: Error) => void; } /** * StreamResult - Rich streaming result object following Vercel AI SDK pattern. * * Provides multiple ways to consume streaming responses: * * 1. AsyncIterable streams: * - `textStream` - yields only text content * - `fullStream` - yields all StreamEvent objects * * 2. Callbacks: * - `onChunk(event)` - called for each event * - `onFinish({ text, usage, steps })` - called when stream completes * - `onError(error)` - called on stream error * * 3. Promise accessors (lazy evaluation): * - `text` - resolves to full aggregated text * - `usage` - resolves to token usage stats * - `steps` - resolves to array of step responses * * @example Basic text streaming * ```typescript * const result = fred.streamMessage('Hello'); * * for await (const text of result.textStream) { * process.stdout.write(text); * } * ``` * * @example Full event streaming with callbacks * ```typescript * const result = fred.streamMessage('Hello'); * * result.onChunk = (event) => console.log('Event:', event.type); * result.onFinish = ({ text, usage }) => console.log('Done:', text.length, 'tokens:', usage.totalTokens); * * for await (const event of result.fullStream) { * // Process events * } * ``` * * @example Await final result * ```typescript * const result = fred.streamMessage('Hello'); * const finalText = await result.text; * const usage = await result.usage; * ``` */ export interface StreamResult { /** * AsyncIterable of text chunks only. * Filters stream to just text events and yields their content. */ readonly textStream: AsyncIterable; /** * AsyncIterable of all stream events. * Yields every StreamEvent including text, tool calls, step boundaries. */ readonly fullStream: AsyncIterable; /** * Callback invoked for each stream event. * Set before starting iteration to receive all events. */ onChunk?: (chunk: StreamEvent) => void; /** * Callback invoked when stream completes successfully. */ onFinish?: (result: { text: string; usage: TokenUsage; steps: number; }) => void; /** * Callback invoked on stream error. */ onError?: (error: Error) => void; /** * Promise resolving to the full aggregated text response. * Consumes the stream internally - only one of text/usage/steps should be awaited * unless you're also consuming the stream. */ readonly text: Promise; /** * Promise resolving to token usage statistics. */ readonly usage: Promise; /** * Promise resolving to the number of steps executed. */ readonly steps: Promise; /** * Current stream status (synchronous). * Returns 'streaming' while active, 'complete' when finished, 'error' on failure. */ readonly status: StreamStatus; /** * Stored error if status is 'error', null otherwise (synchronous). */ readonly error: Error | null; /** * Promise resolving to array of tool calls with their results. * Consumes the stream internally. */ readonly toolCalls: Promise; /** * Collect all events into an array. * Consumes the stream internally. */ toArray(): Promise; /** * Alias for text getter. */ toText(): Promise; /** * Execute callback for each event. * If stream already consumed, replays cached events. * If not yet consumed, iterates live stream. */ onEvent(callback: (event: StreamEvent) => void | Promise): Promise; /** * AsyncIterator for backward compatibility. * Enables: for await (const event of result) { ... } */ [Symbol.asyncIterator](): AsyncIterator; } /** * Implementation of StreamResult */ export declare class StreamResultImpl implements StreamResult { private effectStream; private consumed; private collectedEvents; private textPromise; private usagePromise; private stepsPromise; private toolCallsPromise; private _status; private _error; private _toolCalls; onChunk?: (chunk: StreamEvent) => void; onFinish?: (result: { text: string; usage: TokenUsage; steps: number; }) => void; onError?: (error: Error) => void; constructor(options: StreamResultOptions); /** * Current stream status (synchronous) */ get status(): StreamStatus; /** * Stored error if status is 'error' (synchronous) */ get error(): Error | null; get textStream(): AsyncIterable; get fullStream(): AsyncIterable; get text(): Promise; get usage(): Promise; get steps(): Promise; get toolCalls(): Promise; private collectToolCalls; toArray(): Promise; toText(): Promise; onEvent(callback: (event: StreamEvent) => void | Promise): Promise; /** * AsyncIterator for backward compatibility. * Enables: for await (const event of result) { ... } */ [Symbol.asyncIterator](): AsyncIterator; private collectText; private collectUsage; private collectSteps; private consumeIfNeeded; } /** * Create a StreamResult from an Effect Stream */ export declare const createStreamResult: (stream: Stream.Stream, options?: Partial) => StreamResult; /** * Create a StreamResult from an AsyncIterable */ export declare const createStreamResultFromIterable: (iterable: AsyncIterable, options?: Partial) => StreamResult; //# sourceMappingURL=result.d.ts.map