/** * Multi-step agent streaming with tool execution * * IMPORTANT: Tool Execution Timing and Error Recovery * * Tools execute immediately after the model produces tool-call parts, BEFORE * the full response is validated. This provides real-time tool execution for * responsive multi-step agentic flows, but creates a potential atomicity issue: * * 1. Model streams response with tool-call parts * 2. Tools execute (side effects committed to database, APIs, etc.) * 3. Tool results added to conversation history * 4. Stream continues or completes * 5. Response validation happens (in @effect/ai or downstream) * 6. If validation fails → Error bubbles up BUT tools already executed * * This means: User sees error, but tool side effects persisted. * * Mitigation Strategies: * * 1. **Idempotent Tools**: Design tools to be safely retriable * - Check if operation already completed before executing * - Use unique request IDs to prevent duplicate operations * * 2. **Read-Only Tools**: Prefer read-only tools where possible * - Query operations have no side effects * - Safe to execute multiple times * * 3. **Transaction Support** (future): * - Implement two-phase commit for database tools * - Tools return prepare() → commit() handles * - Only commit after validation succeeds * * 4. **Error Recovery**: The streamOutput utility detects this situation * and logs a warning when stream processing fails after tool execution * * See: FRED_IMPROVEMENTS.md in client projects for detailed analysis */ import { Stream } from 'effect'; import { Prompt } from '@effect/ai'; import { type AgentToolChoice } from './agent'; import type { StreamEvent } from '../stream/events'; export interface MultiStepConfig { /** The AiModel to use for streaming */ model: any; toolkit?: any; toolHandlers?: Map) => Promise | any>; maxSteps: number; toolChoice?: AgentToolChoice; temperature?: number; } export interface MultiStepState { stepIndex: number; messages: Prompt.MessageEncoded[]; accumulatedText: string; pendingToolCalls?: Array<{ id: string; name: string; params: Record; }>; } /** * Stream multi-step agent responses with real-time event emission. * * Hybrid approach: * - Manual multi-step recursion for proper event emission * - @effect/ai handles tool execution (via toolkit + toolLayer) * - We capture tool results and build conversation history */ export declare const streamMultiStep: (initialMessages: Array, config: MultiStepConfig, options: { runId: string; threadId?: string; messageId: string; agentId?: string; }) => Stream.Stream; //# sourceMappingURL=streaming.d.ts.map