@@ -112,17 +112,29 @@ export const stream = <T extends Tools>(options: StreamOptions<T>): Stream.Strea
112112
113113 const dispatched = yield * Effect . forEach (
114114 state . toolCalls ,
115- ( call ) => dispatch ( tools , call ) . pipe ( Effect . map ( ( result ) => [ call , result ] as const ) ) ,
115+ ( call ) =>
116+ dispatch ( tools , call ) . pipe ( Effect . map ( ( result ) => [ call , result . result , result . error ] as const ) ) ,
116117 { concurrency } ,
117118 )
118- const resultStream = Stream . fromIterable ( dispatched . flatMap ( ( [ call , result ] ) => emitEvents ( call , result ) ) )
119+ const resultStream = Stream . fromIterable (
120+ dispatched . flatMap ( ( [ call , result , error ] ) => emitEvents ( call , result , error ) ) ,
121+ )
119122
120123 if ( ! options . stopWhen ) return resultStream . pipe ( Stream . concat ( finishStream ) )
121124 if ( options . stopWhen ( { step, request } ) ) return resultStream . pipe ( Stream . concat ( finishStream ) )
122125
123126 return resultStream . pipe (
124127 Stream . concat (
125- loop ( followUpRequest ( request , state , dispatched ) , step + 1 , totalUsage , totalProviderMetadata ) ,
128+ loop (
129+ followUpRequest (
130+ request ,
131+ state ,
132+ dispatched . map ( ( [ call , result ] ) => [ call , result ] as const ) ,
133+ ) ,
134+ step + 1 ,
135+ totalUsage ,
136+ totalProviderMetadata ,
137+ ) ,
126138 ) ,
127139 )
128140 } ) ,
@@ -215,7 +227,7 @@ const addUsage = (left: Usage | undefined, right: Usage | undefined) => {
215227 | "reasoningTokens"
216228 | "totalTokens"
217229 const sum = ( key : UsageKey ) =>
218- left [ key ] === undefined && right [ key ] === undefined ? undefined : Number ( left [ key ] ?? 0 ) + Number ( right [ key ] ?? 0 )
230+ left [ key ] === undefined && right [ key ] === undefined ? undefined : ( left [ key ] ?? 0 ) + ( right [ key ] ?? 0 )
219231
220232 return new Usage ( {
221233 inputTokens : sum ( "inputTokens" ) ,
@@ -264,16 +276,20 @@ const appendStreamingText = (
264276 state . assistantContent . push ( { type, text, providerMetadata } )
265277}
266278
267- const dispatch = ( tools : Tools , call : ToolCallPart ) : Effect . Effect < ToolResultValue > => {
279+ const dispatch = ( tools : Tools , call : ToolCallPart ) : Effect . Effect < { result : ToolResultValue ; error ?: unknown } > => {
268280 const tool = tools [ call . name ]
269- if ( ! tool ) return Effect . succeed ( { type : "error" as const , value : `Unknown tool: ${ call . name } ` } )
281+ if ( ! tool ) return Effect . succeed ( { result : { type : "error" as const , value : `Unknown tool: ${ call . name } ` } } )
270282 if ( ! tool . execute )
271- return Effect . succeed ( { type : "error" as const , value : `Tool has no execute handler: ${ call . name } ` } )
283+ return Effect . succeed ( { result : { type : "error" as const , value : `Tool has no execute handler: ${ call . name } ` } } )
272284
273285 return decodeAndExecute ( tool , call ) . pipe (
274286 Effect . catchTag ( "LLM.ToolFailure" , ( failure ) =>
275- Effect . succeed ( { type : "error" as const , value : failure . message } satisfies ToolResultValue ) ,
287+ Effect . succeed ( {
288+ result : { type : "error" as const , value : failure . message } satisfies ToolResultValue ,
289+ error : failure . error ,
290+ } ) ,
276291 ) ,
292+ Effect . map ( ( result ) => ( "result" in result ? result : { result } ) ) ,
277293 )
278294}
279295
@@ -294,10 +310,10 @@ const decodeAndExecute = (tool: AnyTool, call: ToolCallPart): Effect.Effect<Tool
294310 Effect . map ( ( encoded ) : ToolResultValue => ( { type : "json" , value : encoded } ) ) ,
295311 )
296312
297- const emitEvents = ( call : ToolCallPart , result : ToolResultValue ) : ReadonlyArray < LLMEvent > =>
313+ const emitEvents = ( call : ToolCallPart , result : ToolResultValue , error : unknown ) : ReadonlyArray < LLMEvent > =>
298314 result . type === "error"
299315 ? [
300- LLMEvent . toolError ( { id : call . id , name : call . name , message : String ( result . value ) } ) ,
316+ LLMEvent . toolError ( { id : call . id , name : call . name , message : String ( result . value ) , error } ) ,
301317 LLMEvent . toolResult ( { id : call . id , name : call . name , result } ) ,
302318 ]
303319 : [ LLMEvent . toolResult ( { id : call . id , name : call . name , result } ) ]
0 commit comments