@mariozechner/pi-ai 0.25.3 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"agent-loop.d.ts","sourceRoot":"","sources":["../../src/agent/agent-loop.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAyD,WAAW,EAAE,MAAM,aAAa,CAAC;AACtG,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,eAAe,EAA6C,MAAM,YAAY,CAAC;AAEvH;;;GAGG;AACH,wBAAgB,SAAS,CACxB,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,OAAO,YAAY,GAC5B,WAAW,CAAC,UAAU,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC,CAmBnD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAChC,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,OAAO,YAAY,GAC5B,WAAW,CAAC,UAAU,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC,CAwBnD","sourcesContent":["import { streamSimple } from \"../stream.js\";\nimport type { AssistantMessage, Context, Message, ToolResultMessage, UserMessage } from \"../types.js\";\nimport { EventStream } from \"../utils/event-stream.js\";\nimport { validateToolArguments } from \"../utils/validation.js\";\nimport type { AgentContext, AgentEvent, AgentLoopConfig, AgentTool, AgentToolResult, QueuedMessage } from \"./types.js\";\n\n/**\n * Start an agent loop with a new user message.\n * The prompt is added to the context and events are emitted for it.\n */\nexport function agentLoop(\n\tprompt: UserMessage,\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal?: AbortSignal,\n\tstreamFn?: typeof streamSimple,\n): EventStream<AgentEvent, AgentContext[\"messages\"]> {\n\tconst stream = createAgentStream();\n\n\t(async () => {\n\t\tconst newMessages: AgentContext[\"messages\"] = [prompt];\n\t\tconst currentContext: AgentContext = {\n\t\t\t...context,\n\t\t\tmessages: [...context.messages, prompt],\n\t\t};\n\n\t\tstream.push({ type: \"agent_start\" });\n\t\tstream.push({ type: \"turn_start\" });\n\t\tstream.push({ type: \"message_start\", message: prompt });\n\t\tstream.push({ type: \"message_end\", message: prompt });\n\n\t\tawait runLoop(currentContext, newMessages, config, signal, stream, streamFn);\n\t})();\n\n\treturn stream;\n}\n\n/**\n * Continue an agent loop from the current context without adding a new message.\n * Used for retry after overflow - context already has user message or tool results.\n * Throws if the last message is not a user message or tool result.\n */\nexport function agentLoopContinue(\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal?: AbortSignal,\n\tstreamFn?: typeof streamSimple,\n): EventStream<AgentEvent, AgentContext[\"messages\"]> {\n\t// Validate that we can continue from this context\n\tconst lastMessage = context.messages[context.messages.length - 1];\n\tif (!lastMessage) {\n\t\tthrow new Error(\"Cannot continue: no messages in context\");\n\t}\n\tif (lastMessage.role !== \"user\" && lastMessage.role !== \"toolResult\") {\n\t\tthrow new Error(`Cannot continue from message role: ${lastMessage.role}. Expected 'user' or 'toolResult'.`);\n\t}\n\n\tconst stream = createAgentStream();\n\n\t(async () => {\n\t\tconst newMessages: AgentContext[\"messages\"] = [];\n\t\tconst currentContext: AgentContext = { ...context };\n\n\t\tstream.push({ type: \"agent_start\" });\n\t\tstream.push({ type: \"turn_start\" });\n\t\t// No user message events - we're continuing from existing context\n\n\t\tawait runLoop(currentContext, newMessages, config, signal, stream, streamFn);\n\t})();\n\n\treturn stream;\n}\n\nfunction createAgentStream(): EventStream<AgentEvent, AgentContext[\"messages\"]> {\n\treturn new EventStream<AgentEvent, AgentContext[\"messages\"]>(\n\t\t(event: AgentEvent) => event.type === \"agent_end\",\n\t\t(event: AgentEvent) => (event.type === \"agent_end\" ? event.messages : []),\n\t);\n}\n\n/**\n * Shared loop logic for both agentLoop and agentLoopContinue.\n */\nasync function runLoop(\n\tcurrentContext: AgentContext,\n\tnewMessages: AgentContext[\"messages\"],\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\tstream: EventStream<AgentEvent, AgentContext[\"messages\"]>,\n\tstreamFn?: typeof streamSimple,\n): Promise<void> {\n\tlet hasMoreToolCalls = true;\n\tlet firstTurn = true;\n\tlet queuedMessages: QueuedMessage<any>[] = (await config.getQueuedMessages?.()) || [];\n\tlet queuedAfterTools: QueuedMessage<any>[] | null = null;\n\n\twhile (hasMoreToolCalls || queuedMessages.length > 0) {\n\t\tif (!firstTurn) {\n\t\t\tstream.push({ type: \"turn_start\" });\n\t\t} else {\n\t\t\tfirstTurn = false;\n\t\t}\n\n\t\t// Process queued messages first (inject before next assistant response)\n\t\tif (queuedMessages.length > 0) {\n\t\t\tfor (const { original, llm } of queuedMessages) {\n\t\t\t\tstream.push({ type: \"message_start\", message: original });\n\t\t\t\tstream.push({ type: \"message_end\", message: original });\n\t\t\t\tif (llm) {\n\t\t\t\t\tcurrentContext.messages.push(llm);\n\t\t\t\t\tnewMessages.push(llm);\n\t\t\t\t}\n\t\t\t}\n\t\t\tqueuedMessages = [];\n\t\t}\n\n\t\t// Stream assistant response\n\t\tconst message = await streamAssistantResponse(currentContext, config, signal, stream, streamFn);\n\t\tnewMessages.push(message);\n\n\t\tif (message.stopReason === \"error\" || message.stopReason === \"aborted\") {\n\t\t\t// Stop the loop on error or abort\n\t\t\tstream.push({ type: \"turn_end\", message, toolResults: [] });\n\t\t\tstream.push({ type: \"agent_end\", messages: newMessages });\n\t\t\tstream.end(newMessages);\n\t\t\treturn;\n\t\t}\n\n\t\t// Check for tool calls\n\t\tconst toolCalls = message.content.filter((c) => c.type === \"toolCall\");\n\t\thasMoreToolCalls = toolCalls.length > 0;\n\n\t\tconst toolResults: ToolResultMessage[] = [];\n\t\tif (hasMoreToolCalls) {\n\t\t\t// Execute tool calls\n\t\t\tconst toolExecution = await executeToolCalls(\n\t\t\t\tcurrentContext.tools,\n\t\t\t\tmessage,\n\t\t\t\tsignal,\n\t\t\t\tstream,\n\t\t\t\tconfig.getQueuedMessages,\n\t\t\t);\n\t\t\ttoolResults.push(...toolExecution.toolResults);\n\t\t\tqueuedAfterTools = toolExecution.queuedMessages ?? null;\n\t\t\tcurrentContext.messages.push(...toolResults);\n\t\t\tnewMessages.push(...toolResults);\n\t\t}\n\t\tstream.push({ type: \"turn_end\", message, toolResults: toolResults });\n\n\t\t// Get queued messages after turn completes\n\t\tif (queuedAfterTools && queuedAfterTools.length > 0) {\n\t\t\tqueuedMessages = queuedAfterTools;\n\t\t\tqueuedAfterTools = null;\n\t\t} else {\n\t\t\tqueuedMessages = (await config.getQueuedMessages?.()) || [];\n\t\t}\n\t}\n\n\tstream.push({ type: \"agent_end\", messages: newMessages });\n\tstream.end(newMessages);\n}\n\n// Helper functions\nasync function streamAssistantResponse(\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\tstream: EventStream<AgentEvent, AgentContext[\"messages\"]>,\n\tstreamFn?: typeof streamSimple,\n): Promise<AssistantMessage> {\n\t// Convert AgentContext to Context for streamSimple\n\t// Use a copy of messages to avoid mutating the original context\n\tconst processedMessages = config.preprocessor\n\t\t? await config.preprocessor(context.messages, signal)\n\t\t: [...context.messages];\n\tconst processedContext: Context = {\n\t\tsystemPrompt: context.systemPrompt,\n\t\tmessages: [...processedMessages].map((m) => {\n\t\t\tif (m.role === \"toolResult\") {\n\t\t\t\tconst { details, ...rest } = m;\n\t\t\t\treturn rest;\n\t\t\t} else {\n\t\t\t\treturn m;\n\t\t\t}\n\t\t}),\n\t\ttools: context.tools, // AgentTool extends Tool, so this works\n\t};\n\n\t// Use custom stream function if provided, otherwise use default streamSimple\n\tconst streamFunction = streamFn || streamSimple;\n\n\t// Resolve API key for every assistant response (important for expiring tokens)\n\tconst resolvedApiKey =\n\t\t(config.getApiKey ? await config.getApiKey(config.model.provider) : undefined) || config.apiKey;\n\n\tconst response = await streamFunction(config.model, processedContext, { ...config, apiKey: resolvedApiKey, signal });\n\n\tlet partialMessage: AssistantMessage | null = null;\n\tlet addedPartial = false;\n\n\tfor await (const event of response) {\n\t\tswitch (event.type) {\n\t\t\tcase \"start\":\n\t\t\t\tpartialMessage = event.partial;\n\t\t\t\tcontext.messages.push(partialMessage);\n\t\t\t\taddedPartial = true;\n\t\t\t\tstream.push({ type: \"message_start\", message: { ...partialMessage } });\n\t\t\t\tbreak;\n\n\t\t\tcase \"text_start\":\n\t\t\tcase \"text_delta\":\n\t\t\tcase \"text_end\":\n\t\t\tcase \"thinking_start\":\n\t\t\tcase \"thinking_delta\":\n\t\t\tcase \"thinking_end\":\n\t\t\tcase \"toolcall_start\":\n\t\t\tcase \"toolcall_delta\":\n\t\t\tcase \"toolcall_end\":\n\t\t\t\tif (partialMessage) {\n\t\t\t\t\tpartialMessage = event.partial;\n\t\t\t\t\tcontext.messages[context.messages.length - 1] = partialMessage;\n\t\t\t\t\tstream.push({ type: \"message_update\", assistantMessageEvent: event, message: { ...partialMessage } });\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase \"done\":\n\t\t\tcase \"error\": {\n\t\t\t\tconst finalMessage = await response.result();\n\t\t\t\tif (addedPartial) {\n\t\t\t\t\tcontext.messages[context.messages.length - 1] = finalMessage;\n\t\t\t\t} else {\n\t\t\t\t\tcontext.messages.push(finalMessage);\n\t\t\t\t}\n\t\t\t\tif (!addedPartial) {\n\t\t\t\t\tstream.push({ type: \"message_start\", message: { ...finalMessage } });\n\t\t\t\t}\n\t\t\t\tstream.push({ type: \"message_end\", message: finalMessage });\n\t\t\t\treturn finalMessage;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn await response.result();\n}\n\nasync function executeToolCalls<T>(\n\ttools: AgentTool<any, T>[] | undefined,\n\tassistantMessage: AssistantMessage,\n\tsignal: AbortSignal | undefined,\n\tstream: EventStream<AgentEvent, Message[]>,\n\tgetQueuedMessages?: AgentLoopConfig[\"getQueuedMessages\"],\n): Promise<{ toolResults: ToolResultMessage<T>[]; queuedMessages?: QueuedMessage<any>[] }> {\n\tconst toolCalls = assistantMessage.content.filter((c) => c.type === \"toolCall\");\n\tconst results: ToolResultMessage<any>[] = [];\n\tlet queuedMessages: QueuedMessage<any>[] | undefined;\n\n\tfor (let index = 0; index < toolCalls.length; index++) {\n\t\tconst toolCall = toolCalls[index];\n\t\tconst tool = tools?.find((t) => t.name === toolCall.name);\n\n\t\tstream.push({\n\t\t\ttype: \"tool_execution_start\",\n\t\t\ttoolCallId: toolCall.id,\n\t\t\ttoolName: toolCall.name,\n\t\t\targs: toolCall.arguments,\n\t\t});\n\n\t\tlet result: AgentToolResult<T>;\n\t\tlet isError = false;\n\n\t\ttry {\n\t\t\tif (!tool) throw new Error(`Tool ${toolCall.name} not found`);\n\n\t\t\t// Validate arguments using shared validation function\n\t\t\tconst validatedArgs = validateToolArguments(tool, toolCall);\n\n\t\t\t// Execute with validated, typed arguments, passing update callback\n\t\t\tresult = await tool.execute(toolCall.id, validatedArgs, signal, (partialResult) => {\n\t\t\t\tstream.push({\n\t\t\t\t\ttype: \"tool_execution_update\",\n\t\t\t\t\ttoolCallId: toolCall.id,\n\t\t\t\t\ttoolName: toolCall.name,\n\t\t\t\t\targs: toolCall.arguments,\n\t\t\t\t\tpartialResult,\n\t\t\t\t});\n\t\t\t});\n\t\t} catch (e) {\n\t\t\tresult = {\n\t\t\t\tcontent: [{ type: \"text\", text: e instanceof Error ? e.message : String(e) }],\n\t\t\t\tdetails: {} as T,\n\t\t\t};\n\t\t\tisError = true;\n\t\t}\n\n\t\tstream.push({\n\t\t\ttype: \"tool_execution_end\",\n\t\t\ttoolCallId: toolCall.id,\n\t\t\ttoolName: toolCall.name,\n\t\t\tresult,\n\t\t\tisError,\n\t\t});\n\n\t\tconst toolResultMessage: ToolResultMessage<T> = {\n\t\t\trole: \"toolResult\",\n\t\t\ttoolCallId: toolCall.id,\n\t\t\ttoolName: toolCall.name,\n\t\t\tcontent: result.content,\n\t\t\tdetails: result.details,\n\t\t\tisError,\n\t\t\ttimestamp: Date.now(),\n\t\t};\n\n\t\tresults.push(toolResultMessage);\n\t\tstream.push({ type: \"message_start\", message: toolResultMessage });\n\t\tstream.push({ type: \"message_end\", message: toolResultMessage });\n\n\t\tif (getQueuedMessages) {\n\t\t\tconst queued = await getQueuedMessages();\n\t\t\tif (queued.length > 0) {\n\t\t\t\tqueuedMessages = queued;\n\t\t\t\tconst remainingCalls = toolCalls.slice(index + 1);\n\t\t\t\tfor (const skipped of remainingCalls) {\n\t\t\t\t\tresults.push(skipToolCall(skipped, stream));\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { toolResults: results, queuedMessages };\n}\n\nfunction skipToolCall<T>(\n\ttoolCall: Extract<AssistantMessage[\"content\"][number], { type: \"toolCall\" }>,\n\tstream: EventStream<AgentEvent, Message[]>,\n): ToolResultMessage<T> {\n\tconst result: AgentToolResult<T> = {\n\t\tcontent: [{ type: \"text\", text: \"Skipped due to queued user message.\" }],\n\t\tdetails: {} as T,\n\t};\n\n\tstream.push({\n\t\ttype: \"tool_execution_start\",\n\t\ttoolCallId: toolCall.id,\n\t\ttoolName: toolCall.name,\n\t\targs: toolCall.arguments,\n\t});\n\tstream.push({\n\t\ttype: \"tool_execution_end\",\n\t\ttoolCallId: toolCall.id,\n\t\ttoolName: toolCall.name,\n\t\tresult,\n\t\tisError: true,\n\t});\n\n\tconst toolResultMessage: ToolResultMessage<T> = {\n\t\trole: \"toolResult\",\n\t\ttoolCallId: toolCall.id,\n\t\ttoolName: toolCall.name,\n\t\tcontent: result.content,\n\t\tdetails: result.details,\n\t\tisError: true,\n\t\ttimestamp: Date.now(),\n\t};\n\n\tstream.push({ type: \"message_start\", message: toolResultMessage });\n\tstream.push({ type: \"message_end\", message: toolResultMessage });\n\n\treturn toolResultMessage;\n}\n"]}
1
+ {"version":3,"file":"agent-loop.d.ts","sourceRoot":"","sources":["../../src/agent/agent-loop.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAyD,WAAW,EAAE,MAAM,aAAa,CAAC;AACtG,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,eAAe,EAA6C,MAAM,YAAY,CAAC;AAEvH;;;GAGG;AACH,wBAAgB,SAAS,CACxB,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,OAAO,YAAY,GAC5B,WAAW,CAAC,UAAU,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC,CAmBnD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAChC,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,OAAO,YAAY,GAC5B,WAAW,CAAC,UAAU,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC,CAwBnD","sourcesContent":["import { streamSimple } from \"../stream.js\";\nimport type { AssistantMessage, Context, Message, ToolResultMessage, UserMessage } from \"../types.js\";\nimport { EventStream } from \"../utils/event-stream.js\";\nimport { validateToolArguments } from \"../utils/validation.js\";\nimport type { AgentContext, AgentEvent, AgentLoopConfig, AgentTool, AgentToolResult, QueuedMessage } from \"./types.js\";\n\n/**\n * Start an agent loop with a new user message.\n * The prompt is added to the context and events are emitted for it.\n */\nexport function agentLoop(\n\tprompt: UserMessage,\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal?: AbortSignal,\n\tstreamFn?: typeof streamSimple,\n): EventStream<AgentEvent, AgentContext[\"messages\"]> {\n\tconst stream = createAgentStream();\n\n\t(async () => {\n\t\tconst newMessages: AgentContext[\"messages\"] = [prompt];\n\t\tconst currentContext: AgentContext = {\n\t\t\t...context,\n\t\t\tmessages: [...context.messages, prompt],\n\t\t};\n\n\t\tstream.push({ type: \"agent_start\" });\n\t\tstream.push({ type: \"turn_start\" });\n\t\tstream.push({ type: \"message_start\", message: prompt });\n\t\tstream.push({ type: \"message_end\", message: prompt });\n\n\t\tawait runLoop(currentContext, newMessages, config, signal, stream, streamFn);\n\t})();\n\n\treturn stream;\n}\n\n/**\n * Continue an agent loop from the current context without adding a new message.\n * Used for retry after overflow - context already has user message or tool results.\n * Throws if the last message is not a user message or tool result.\n */\nexport function agentLoopContinue(\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal?: AbortSignal,\n\tstreamFn?: typeof streamSimple,\n): EventStream<AgentEvent, AgentContext[\"messages\"]> {\n\t// Validate that we can continue from this context\n\tconst lastMessage = context.messages[context.messages.length - 1];\n\tif (!lastMessage) {\n\t\tthrow new Error(\"Cannot continue: no messages in context\");\n\t}\n\tif (lastMessage.role !== \"user\" && lastMessage.role !== \"toolResult\") {\n\t\tthrow new Error(`Cannot continue from message role: ${lastMessage.role}. Expected 'user' or 'toolResult'.`);\n\t}\n\n\tconst stream = createAgentStream();\n\n\t(async () => {\n\t\tconst newMessages: AgentContext[\"messages\"] = [];\n\t\tconst currentContext: AgentContext = { ...context };\n\n\t\tstream.push({ type: \"agent_start\" });\n\t\tstream.push({ type: \"turn_start\" });\n\t\t// No user message events - we're continuing from existing context\n\n\t\tawait runLoop(currentContext, newMessages, config, signal, stream, streamFn);\n\t})();\n\n\treturn stream;\n}\n\nfunction createAgentStream(): EventStream<AgentEvent, AgentContext[\"messages\"]> {\n\treturn new EventStream<AgentEvent, AgentContext[\"messages\"]>(\n\t\t(event: AgentEvent) => event.type === \"agent_end\",\n\t\t(event: AgentEvent) => (event.type === \"agent_end\" ? event.messages : []),\n\t);\n}\n\n/**\n * Shared loop logic for both agentLoop and agentLoopContinue.\n */\nasync function runLoop(\n\tcurrentContext: AgentContext,\n\tnewMessages: AgentContext[\"messages\"],\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\tstream: EventStream<AgentEvent, AgentContext[\"messages\"]>,\n\tstreamFn?: typeof streamSimple,\n): Promise<void> {\n\tlet hasMoreToolCalls = true;\n\tlet firstTurn = true;\n\tlet queuedMessages: QueuedMessage<any>[] = (await config.getQueuedMessages?.()) || [];\n\tlet queuedAfterTools: QueuedMessage<any>[] | null = null;\n\n\twhile (hasMoreToolCalls || queuedMessages.length > 0) {\n\t\tif (!firstTurn) {\n\t\t\tstream.push({ type: \"turn_start\" });\n\t\t} else {\n\t\t\tfirstTurn = false;\n\t\t}\n\n\t\t// Process queued messages first (inject before next assistant response)\n\t\tif (queuedMessages.length > 0) {\n\t\t\tfor (const { original, llm } of queuedMessages) {\n\t\t\t\tstream.push({ type: \"message_start\", message: original });\n\t\t\t\tstream.push({ type: \"message_end\", message: original });\n\t\t\t\tif (llm) {\n\t\t\t\t\tcurrentContext.messages.push(llm);\n\t\t\t\t\tnewMessages.push(llm);\n\t\t\t\t}\n\t\t\t}\n\t\t\tqueuedMessages = [];\n\t\t}\n\n\t\t// Stream assistant response\n\t\tconst message = await streamAssistantResponse(currentContext, config, signal, stream, streamFn);\n\t\tnewMessages.push(message);\n\n\t\tif (message.stopReason === \"error\" || message.stopReason === \"aborted\") {\n\t\t\t// Stop the loop on error or abort\n\t\t\tstream.push({ type: \"turn_end\", message, toolResults: [] });\n\t\t\tstream.push({ type: \"agent_end\", messages: newMessages });\n\t\t\tstream.end(newMessages);\n\t\t\treturn;\n\t\t}\n\n\t\t// Check for tool calls\n\t\tconst toolCalls = message.content.filter((c) => c.type === \"toolCall\");\n\t\thasMoreToolCalls = toolCalls.length > 0;\n\n\t\tconst toolResults: ToolResultMessage[] = [];\n\t\tif (hasMoreToolCalls) {\n\t\t\t// Execute tool calls\n\t\t\tconst toolExecution = await executeToolCalls(\n\t\t\t\tcurrentContext.tools,\n\t\t\t\tmessage,\n\t\t\t\tsignal,\n\t\t\t\tstream,\n\t\t\t\tconfig.getQueuedMessages,\n\t\t\t);\n\t\t\ttoolResults.push(...toolExecution.toolResults);\n\t\t\tqueuedAfterTools = toolExecution.queuedMessages ?? null;\n\t\t\tcurrentContext.messages.push(...toolResults);\n\t\t\tnewMessages.push(...toolResults);\n\t\t}\n\t\tstream.push({ type: \"turn_end\", message, toolResults: toolResults });\n\n\t\t// Get queued messages after turn completes\n\t\tif (queuedAfterTools && queuedAfterTools.length > 0) {\n\t\t\tqueuedMessages = queuedAfterTools;\n\t\t\tqueuedAfterTools = null;\n\t\t} else {\n\t\t\tqueuedMessages = (await config.getQueuedMessages?.()) || [];\n\t\t}\n\t}\n\n\tstream.push({ type: \"agent_end\", messages: newMessages });\n\tstream.end(newMessages);\n}\n\n// Helper functions\nasync function streamAssistantResponse(\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\tstream: EventStream<AgentEvent, AgentContext[\"messages\"]>,\n\tstreamFn?: typeof streamSimple,\n): Promise<AssistantMessage> {\n\t// Convert AgentContext to Context for streamSimple\n\t// Use a copy of messages to avoid mutating the original context\n\tconst processedMessages = config.preprocessor\n\t\t? await config.preprocessor(context.messages, signal)\n\t\t: [...context.messages];\n\tconst processedContext: Context = {\n\t\tsystemPrompt: context.systemPrompt,\n\t\tmessages: [...processedMessages].map((m) => {\n\t\t\tif (m.role === \"toolResult\") {\n\t\t\t\t// biome-ignore lint/correctness/noUnusedVariables: fine here\n\t\t\t\tconst { details, ...rest } = m;\n\t\t\t\treturn rest;\n\t\t\t} else {\n\t\t\t\treturn m;\n\t\t\t}\n\t\t}),\n\t\ttools: context.tools, // AgentTool extends Tool, so this works\n\t};\n\n\t// Use custom stream function if provided, otherwise use default streamSimple\n\tconst streamFunction = streamFn || streamSimple;\n\n\t// Resolve API key for every assistant response (important for expiring tokens)\n\tconst resolvedApiKey =\n\t\t(config.getApiKey ? await config.getApiKey(config.model.provider) : undefined) || config.apiKey;\n\n\tconst response = await streamFunction(config.model, processedContext, { ...config, apiKey: resolvedApiKey, signal });\n\n\tlet partialMessage: AssistantMessage | null = null;\n\tlet addedPartial = false;\n\n\tfor await (const event of response) {\n\t\tswitch (event.type) {\n\t\t\tcase \"start\":\n\t\t\t\tpartialMessage = event.partial;\n\t\t\t\tcontext.messages.push(partialMessage);\n\t\t\t\taddedPartial = true;\n\t\t\t\tstream.push({ type: \"message_start\", message: { ...partialMessage } });\n\t\t\t\tbreak;\n\n\t\t\tcase \"text_start\":\n\t\t\tcase \"text_delta\":\n\t\t\tcase \"text_end\":\n\t\t\tcase \"thinking_start\":\n\t\t\tcase \"thinking_delta\":\n\t\t\tcase \"thinking_end\":\n\t\t\tcase \"toolcall_start\":\n\t\t\tcase \"toolcall_delta\":\n\t\t\tcase \"toolcall_end\":\n\t\t\t\tif (partialMessage) {\n\t\t\t\t\tpartialMessage = event.partial;\n\t\t\t\t\tcontext.messages[context.messages.length - 1] = partialMessage;\n\t\t\t\t\tstream.push({ type: \"message_update\", assistantMessageEvent: event, message: { ...partialMessage } });\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase \"done\":\n\t\t\tcase \"error\": {\n\t\t\t\tconst finalMessage = await response.result();\n\t\t\t\tif (addedPartial) {\n\t\t\t\t\tcontext.messages[context.messages.length - 1] = finalMessage;\n\t\t\t\t} else {\n\t\t\t\t\tcontext.messages.push(finalMessage);\n\t\t\t\t}\n\t\t\t\tif (!addedPartial) {\n\t\t\t\t\tstream.push({ type: \"message_start\", message: { ...finalMessage } });\n\t\t\t\t}\n\t\t\t\tstream.push({ type: \"message_end\", message: finalMessage });\n\t\t\t\treturn finalMessage;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn await response.result();\n}\n\nasync function executeToolCalls<T>(\n\ttools: AgentTool<any, T>[] | undefined,\n\tassistantMessage: AssistantMessage,\n\tsignal: AbortSignal | undefined,\n\tstream: EventStream<AgentEvent, Message[]>,\n\tgetQueuedMessages?: AgentLoopConfig[\"getQueuedMessages\"],\n): Promise<{ toolResults: ToolResultMessage<T>[]; queuedMessages?: QueuedMessage<any>[] }> {\n\tconst toolCalls = assistantMessage.content.filter((c) => c.type === \"toolCall\");\n\tconst results: ToolResultMessage<any>[] = [];\n\tlet queuedMessages: QueuedMessage<any>[] | undefined;\n\n\tfor (let index = 0; index < toolCalls.length; index++) {\n\t\tconst toolCall = toolCalls[index];\n\t\tconst tool = tools?.find((t) => t.name === toolCall.name);\n\n\t\tstream.push({\n\t\t\ttype: \"tool_execution_start\",\n\t\t\ttoolCallId: toolCall.id,\n\t\t\ttoolName: toolCall.name,\n\t\t\targs: toolCall.arguments,\n\t\t});\n\n\t\tlet result: AgentToolResult<T>;\n\t\tlet isError = false;\n\n\t\ttry {\n\t\t\tif (!tool) throw new Error(`Tool ${toolCall.name} not found`);\n\n\t\t\t// Validate arguments using shared validation function\n\t\t\tconst validatedArgs = validateToolArguments(tool, toolCall);\n\n\t\t\t// Execute with validated, typed arguments, passing update callback\n\t\t\tresult = await tool.execute(toolCall.id, validatedArgs, signal, (partialResult) => {\n\t\t\t\tstream.push({\n\t\t\t\t\ttype: \"tool_execution_update\",\n\t\t\t\t\ttoolCallId: toolCall.id,\n\t\t\t\t\ttoolName: toolCall.name,\n\t\t\t\t\targs: toolCall.arguments,\n\t\t\t\t\tpartialResult,\n\t\t\t\t});\n\t\t\t});\n\t\t} catch (e) {\n\t\t\tresult = {\n\t\t\t\tcontent: [{ type: \"text\", text: e instanceof Error ? e.message : String(e) }],\n\t\t\t\tdetails: {} as T,\n\t\t\t};\n\t\t\tisError = true;\n\t\t}\n\n\t\tstream.push({\n\t\t\ttype: \"tool_execution_end\",\n\t\t\ttoolCallId: toolCall.id,\n\t\t\ttoolName: toolCall.name,\n\t\t\tresult,\n\t\t\tisError,\n\t\t});\n\n\t\tconst toolResultMessage: ToolResultMessage<T> = {\n\t\t\trole: \"toolResult\",\n\t\t\ttoolCallId: toolCall.id,\n\t\t\ttoolName: toolCall.name,\n\t\t\tcontent: result.content,\n\t\t\tdetails: result.details,\n\t\t\tisError,\n\t\t\ttimestamp: Date.now(),\n\t\t};\n\n\t\tresults.push(toolResultMessage);\n\t\tstream.push({ type: \"message_start\", message: toolResultMessage });\n\t\tstream.push({ type: \"message_end\", message: toolResultMessage });\n\n\t\tif (getQueuedMessages) {\n\t\t\tconst queued = await getQueuedMessages();\n\t\t\tif (queued.length > 0) {\n\t\t\t\tqueuedMessages = queued;\n\t\t\t\tconst remainingCalls = toolCalls.slice(index + 1);\n\t\t\t\tfor (const skipped of remainingCalls) {\n\t\t\t\t\tresults.push(skipToolCall(skipped, stream));\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { toolResults: results, queuedMessages };\n}\n\nfunction skipToolCall<T>(\n\ttoolCall: Extract<AssistantMessage[\"content\"][number], { type: \"toolCall\" }>,\n\tstream: EventStream<AgentEvent, Message[]>,\n): ToolResultMessage<T> {\n\tconst result: AgentToolResult<T> = {\n\t\tcontent: [{ type: \"text\", text: \"Skipped due to queued user message.\" }],\n\t\tdetails: {} as T,\n\t};\n\n\tstream.push({\n\t\ttype: \"tool_execution_start\",\n\t\ttoolCallId: toolCall.id,\n\t\ttoolName: toolCall.name,\n\t\targs: toolCall.arguments,\n\t});\n\tstream.push({\n\t\ttype: \"tool_execution_end\",\n\t\ttoolCallId: toolCall.id,\n\t\ttoolName: toolCall.name,\n\t\tresult,\n\t\tisError: true,\n\t});\n\n\tconst toolResultMessage: ToolResultMessage<T> = {\n\t\trole: \"toolResult\",\n\t\ttoolCallId: toolCall.id,\n\t\ttoolName: toolCall.name,\n\t\tcontent: result.content,\n\t\tdetails: result.details,\n\t\tisError: true,\n\t\ttimestamp: Date.now(),\n\t};\n\n\tstream.push({ type: \"message_start\", message: toolResultMessage });\n\tstream.push({ type: \"message_end\", message: toolResultMessage });\n\n\treturn toolResultMessage;\n}\n"]}
@@ -122,6 +122,7 @@ async function streamAssistantResponse(context, config, signal, stream, streamFn
122
122
  systemPrompt: context.systemPrompt,
123
123
  messages: [...processedMessages].map((m) => {
124
124
  if (m.role === "toolResult") {
125
+ // biome-ignore lint/correctness/noUnusedVariables: fine here
125
126
  const { details, ...rest } = m;
126
127
  return rest;
127
128
  }
@@ -1 +1 @@
1
- {"version":3,"file":"agent-loop.js","sourceRoot":"","sources":["../../src/agent/agent-loop.ts"],"names":[],"mappings":"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","sourcesContent":["import { streamSimple } from \"../stream.js\";\nimport type { AssistantMessage, Context, Message, ToolResultMessage, UserMessage } from \"../types.js\";\nimport { EventStream } from \"../utils/event-stream.js\";\nimport { validateToolArguments } from \"../utils/validation.js\";\nimport type { AgentContext, AgentEvent, AgentLoopConfig, AgentTool, AgentToolResult, QueuedMessage } from \"./types.js\";\n\n/**\n * Start an agent loop with a new user message.\n * The prompt is added to the context and events are emitted for it.\n */\nexport function agentLoop(\n\tprompt: UserMessage,\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal?: AbortSignal,\n\tstreamFn?: typeof streamSimple,\n): EventStream<AgentEvent, AgentContext[\"messages\"]> {\n\tconst stream = createAgentStream();\n\n\t(async () => {\n\t\tconst newMessages: AgentContext[\"messages\"] = [prompt];\n\t\tconst currentContext: AgentContext = {\n\t\t\t...context,\n\t\t\tmessages: [...context.messages, prompt],\n\t\t};\n\n\t\tstream.push({ type: \"agent_start\" });\n\t\tstream.push({ type: \"turn_start\" });\n\t\tstream.push({ type: \"message_start\", message: prompt });\n\t\tstream.push({ type: \"message_end\", message: prompt });\n\n\t\tawait runLoop(currentContext, newMessages, config, signal, stream, streamFn);\n\t})();\n\n\treturn stream;\n}\n\n/**\n * Continue an agent loop from the current context without adding a new message.\n * Used for retry after overflow - context already has user message or tool results.\n * Throws if the last message is not a user message or tool result.\n */\nexport function agentLoopContinue(\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal?: AbortSignal,\n\tstreamFn?: typeof streamSimple,\n): EventStream<AgentEvent, AgentContext[\"messages\"]> {\n\t// Validate that we can continue from this context\n\tconst lastMessage = context.messages[context.messages.length - 1];\n\tif (!lastMessage) {\n\t\tthrow new Error(\"Cannot continue: no messages in context\");\n\t}\n\tif (lastMessage.role !== \"user\" && lastMessage.role !== \"toolResult\") {\n\t\tthrow new Error(`Cannot continue from message role: ${lastMessage.role}. Expected 'user' or 'toolResult'.`);\n\t}\n\n\tconst stream = createAgentStream();\n\n\t(async () => {\n\t\tconst newMessages: AgentContext[\"messages\"] = [];\n\t\tconst currentContext: AgentContext = { ...context };\n\n\t\tstream.push({ type: \"agent_start\" });\n\t\tstream.push({ type: \"turn_start\" });\n\t\t// No user message events - we're continuing from existing context\n\n\t\tawait runLoop(currentContext, newMessages, config, signal, stream, streamFn);\n\t})();\n\n\treturn stream;\n}\n\nfunction createAgentStream(): EventStream<AgentEvent, AgentContext[\"messages\"]> {\n\treturn new EventStream<AgentEvent, AgentContext[\"messages\"]>(\n\t\t(event: AgentEvent) => event.type === \"agent_end\",\n\t\t(event: AgentEvent) => (event.type === \"agent_end\" ? event.messages : []),\n\t);\n}\n\n/**\n * Shared loop logic for both agentLoop and agentLoopContinue.\n */\nasync function runLoop(\n\tcurrentContext: AgentContext,\n\tnewMessages: AgentContext[\"messages\"],\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\tstream: EventStream<AgentEvent, AgentContext[\"messages\"]>,\n\tstreamFn?: typeof streamSimple,\n): Promise<void> {\n\tlet hasMoreToolCalls = true;\n\tlet firstTurn = true;\n\tlet queuedMessages: QueuedMessage<any>[] = (await config.getQueuedMessages?.()) || [];\n\tlet queuedAfterTools: QueuedMessage<any>[] | null = null;\n\n\twhile (hasMoreToolCalls || queuedMessages.length > 0) {\n\t\tif (!firstTurn) {\n\t\t\tstream.push({ type: \"turn_start\" });\n\t\t} else {\n\t\t\tfirstTurn = false;\n\t\t}\n\n\t\t// Process queued messages first (inject before next assistant response)\n\t\tif (queuedMessages.length > 0) {\n\t\t\tfor (const { original, llm } of queuedMessages) {\n\t\t\t\tstream.push({ type: \"message_start\", message: original });\n\t\t\t\tstream.push({ type: \"message_end\", message: original });\n\t\t\t\tif (llm) {\n\t\t\t\t\tcurrentContext.messages.push(llm);\n\t\t\t\t\tnewMessages.push(llm);\n\t\t\t\t}\n\t\t\t}\n\t\t\tqueuedMessages = [];\n\t\t}\n\n\t\t// Stream assistant response\n\t\tconst message = await streamAssistantResponse(currentContext, config, signal, stream, streamFn);\n\t\tnewMessages.push(message);\n\n\t\tif (message.stopReason === \"error\" || message.stopReason === \"aborted\") {\n\t\t\t// Stop the loop on error or abort\n\t\t\tstream.push({ type: \"turn_end\", message, toolResults: [] });\n\t\t\tstream.push({ type: \"agent_end\", messages: newMessages });\n\t\t\tstream.end(newMessages);\n\t\t\treturn;\n\t\t}\n\n\t\t// Check for tool calls\n\t\tconst toolCalls = message.content.filter((c) => c.type === \"toolCall\");\n\t\thasMoreToolCalls = toolCalls.length > 0;\n\n\t\tconst toolResults: ToolResultMessage[] = [];\n\t\tif (hasMoreToolCalls) {\n\t\t\t// Execute tool calls\n\t\t\tconst toolExecution = await executeToolCalls(\n\t\t\t\tcurrentContext.tools,\n\t\t\t\tmessage,\n\t\t\t\tsignal,\n\t\t\t\tstream,\n\t\t\t\tconfig.getQueuedMessages,\n\t\t\t);\n\t\t\ttoolResults.push(...toolExecution.toolResults);\n\t\t\tqueuedAfterTools = toolExecution.queuedMessages ?? null;\n\t\t\tcurrentContext.messages.push(...toolResults);\n\t\t\tnewMessages.push(...toolResults);\n\t\t}\n\t\tstream.push({ type: \"turn_end\", message, toolResults: toolResults });\n\n\t\t// Get queued messages after turn completes\n\t\tif (queuedAfterTools && queuedAfterTools.length > 0) {\n\t\t\tqueuedMessages = queuedAfterTools;\n\t\t\tqueuedAfterTools = null;\n\t\t} else {\n\t\t\tqueuedMessages = (await config.getQueuedMessages?.()) || [];\n\t\t}\n\t}\n\n\tstream.push({ type: \"agent_end\", messages: newMessages });\n\tstream.end(newMessages);\n}\n\n// Helper functions\nasync function streamAssistantResponse(\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\tstream: EventStream<AgentEvent, AgentContext[\"messages\"]>,\n\tstreamFn?: typeof streamSimple,\n): Promise<AssistantMessage> {\n\t// Convert AgentContext to Context for streamSimple\n\t// Use a copy of messages to avoid mutating the original context\n\tconst processedMessages = config.preprocessor\n\t\t? await config.preprocessor(context.messages, signal)\n\t\t: [...context.messages];\n\tconst processedContext: Context = {\n\t\tsystemPrompt: context.systemPrompt,\n\t\tmessages: [...processedMessages].map((m) => {\n\t\t\tif (m.role === \"toolResult\") {\n\t\t\t\tconst { details, ...rest } = m;\n\t\t\t\treturn rest;\n\t\t\t} else {\n\t\t\t\treturn m;\n\t\t\t}\n\t\t}),\n\t\ttools: context.tools, // AgentTool extends Tool, so this works\n\t};\n\n\t// Use custom stream function if provided, otherwise use default streamSimple\n\tconst streamFunction = streamFn || streamSimple;\n\n\t// Resolve API key for every assistant response (important for expiring tokens)\n\tconst resolvedApiKey =\n\t\t(config.getApiKey ? await config.getApiKey(config.model.provider) : undefined) || config.apiKey;\n\n\tconst response = await streamFunction(config.model, processedContext, { ...config, apiKey: resolvedApiKey, signal });\n\n\tlet partialMessage: AssistantMessage | null = null;\n\tlet addedPartial = false;\n\n\tfor await (const event of response) {\n\t\tswitch (event.type) {\n\t\t\tcase \"start\":\n\t\t\t\tpartialMessage = event.partial;\n\t\t\t\tcontext.messages.push(partialMessage);\n\t\t\t\taddedPartial = true;\n\t\t\t\tstream.push({ type: \"message_start\", message: { ...partialMessage } });\n\t\t\t\tbreak;\n\n\t\t\tcase \"text_start\":\n\t\t\tcase \"text_delta\":\n\t\t\tcase \"text_end\":\n\t\t\tcase \"thinking_start\":\n\t\t\tcase \"thinking_delta\":\n\t\t\tcase \"thinking_end\":\n\t\t\tcase \"toolcall_start\":\n\t\t\tcase \"toolcall_delta\":\n\t\t\tcase \"toolcall_end\":\n\t\t\t\tif (partialMessage) {\n\t\t\t\t\tpartialMessage = event.partial;\n\t\t\t\t\tcontext.messages[context.messages.length - 1] = partialMessage;\n\t\t\t\t\tstream.push({ type: \"message_update\", assistantMessageEvent: event, message: { ...partialMessage } });\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase \"done\":\n\t\t\tcase \"error\": {\n\t\t\t\tconst finalMessage = await response.result();\n\t\t\t\tif (addedPartial) {\n\t\t\t\t\tcontext.messages[context.messages.length - 1] = finalMessage;\n\t\t\t\t} else {\n\t\t\t\t\tcontext.messages.push(finalMessage);\n\t\t\t\t}\n\t\t\t\tif (!addedPartial) {\n\t\t\t\t\tstream.push({ type: \"message_start\", message: { ...finalMessage } });\n\t\t\t\t}\n\t\t\t\tstream.push({ type: \"message_end\", message: finalMessage });\n\t\t\t\treturn finalMessage;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn await response.result();\n}\n\nasync function executeToolCalls<T>(\n\ttools: AgentTool<any, T>[] | undefined,\n\tassistantMessage: AssistantMessage,\n\tsignal: AbortSignal | undefined,\n\tstream: EventStream<AgentEvent, Message[]>,\n\tgetQueuedMessages?: AgentLoopConfig[\"getQueuedMessages\"],\n): Promise<{ toolResults: ToolResultMessage<T>[]; queuedMessages?: QueuedMessage<any>[] }> {\n\tconst toolCalls = assistantMessage.content.filter((c) => c.type === \"toolCall\");\n\tconst results: ToolResultMessage<any>[] = [];\n\tlet queuedMessages: QueuedMessage<any>[] | undefined;\n\n\tfor (let index = 0; index < toolCalls.length; index++) {\n\t\tconst toolCall = toolCalls[index];\n\t\tconst tool = tools?.find((t) => t.name === toolCall.name);\n\n\t\tstream.push({\n\t\t\ttype: \"tool_execution_start\",\n\t\t\ttoolCallId: toolCall.id,\n\t\t\ttoolName: toolCall.name,\n\t\t\targs: toolCall.arguments,\n\t\t});\n\n\t\tlet result: AgentToolResult<T>;\n\t\tlet isError = false;\n\n\t\ttry {\n\t\t\tif (!tool) throw new Error(`Tool ${toolCall.name} not found`);\n\n\t\t\t// Validate arguments using shared validation function\n\t\t\tconst validatedArgs = validateToolArguments(tool, toolCall);\n\n\t\t\t// Execute with validated, typed arguments, passing update callback\n\t\t\tresult = await tool.execute(toolCall.id, validatedArgs, signal, (partialResult) => {\n\t\t\t\tstream.push({\n\t\t\t\t\ttype: \"tool_execution_update\",\n\t\t\t\t\ttoolCallId: toolCall.id,\n\t\t\t\t\ttoolName: toolCall.name,\n\t\t\t\t\targs: toolCall.arguments,\n\t\t\t\t\tpartialResult,\n\t\t\t\t});\n\t\t\t});\n\t\t} catch (e) {\n\t\t\tresult = {\n\t\t\t\tcontent: [{ type: \"text\", text: e instanceof Error ? e.message : String(e) }],\n\t\t\t\tdetails: {} as T,\n\t\t\t};\n\t\t\tisError = true;\n\t\t}\n\n\t\tstream.push({\n\t\t\ttype: \"tool_execution_end\",\n\t\t\ttoolCallId: toolCall.id,\n\t\t\ttoolName: toolCall.name,\n\t\t\tresult,\n\t\t\tisError,\n\t\t});\n\n\t\tconst toolResultMessage: ToolResultMessage<T> = {\n\t\t\trole: \"toolResult\",\n\t\t\ttoolCallId: toolCall.id,\n\t\t\ttoolName: toolCall.name,\n\t\t\tcontent: result.content,\n\t\t\tdetails: result.details,\n\t\t\tisError,\n\t\t\ttimestamp: Date.now(),\n\t\t};\n\n\t\tresults.push(toolResultMessage);\n\t\tstream.push({ type: \"message_start\", message: toolResultMessage });\n\t\tstream.push({ type: \"message_end\", message: toolResultMessage });\n\n\t\tif (getQueuedMessages) {\n\t\t\tconst queued = await getQueuedMessages();\n\t\t\tif (queued.length > 0) {\n\t\t\t\tqueuedMessages = queued;\n\t\t\t\tconst remainingCalls = toolCalls.slice(index + 1);\n\t\t\t\tfor (const skipped of remainingCalls) {\n\t\t\t\t\tresults.push(skipToolCall(skipped, stream));\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { toolResults: results, queuedMessages };\n}\n\nfunction skipToolCall<T>(\n\ttoolCall: Extract<AssistantMessage[\"content\"][number], { type: \"toolCall\" }>,\n\tstream: EventStream<AgentEvent, Message[]>,\n): ToolResultMessage<T> {\n\tconst result: AgentToolResult<T> = {\n\t\tcontent: [{ type: \"text\", text: \"Skipped due to queued user message.\" }],\n\t\tdetails: {} as T,\n\t};\n\n\tstream.push({\n\t\ttype: \"tool_execution_start\",\n\t\ttoolCallId: toolCall.id,\n\t\ttoolName: toolCall.name,\n\t\targs: toolCall.arguments,\n\t});\n\tstream.push({\n\t\ttype: \"tool_execution_end\",\n\t\ttoolCallId: toolCall.id,\n\t\ttoolName: toolCall.name,\n\t\tresult,\n\t\tisError: true,\n\t});\n\n\tconst toolResultMessage: ToolResultMessage<T> = {\n\t\trole: \"toolResult\",\n\t\ttoolCallId: toolCall.id,\n\t\ttoolName: toolCall.name,\n\t\tcontent: result.content,\n\t\tdetails: result.details,\n\t\tisError: true,\n\t\ttimestamp: Date.now(),\n\t};\n\n\tstream.push({ type: \"message_start\", message: toolResultMessage });\n\tstream.push({ type: \"message_end\", message: toolResultMessage });\n\n\treturn toolResultMessage;\n}\n"]}
1
+ {"version":3,"file":"agent-loop.js","sourceRoot":"","sources":["../../src/agent/agent-loop.ts"],"names":[],"mappings":"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","sourcesContent":["import { streamSimple } from \"../stream.js\";\nimport type { AssistantMessage, Context, Message, ToolResultMessage, UserMessage } from \"../types.js\";\nimport { EventStream } from \"../utils/event-stream.js\";\nimport { validateToolArguments } from \"../utils/validation.js\";\nimport type { AgentContext, AgentEvent, AgentLoopConfig, AgentTool, AgentToolResult, QueuedMessage } from \"./types.js\";\n\n/**\n * Start an agent loop with a new user message.\n * The prompt is added to the context and events are emitted for it.\n */\nexport function agentLoop(\n\tprompt: UserMessage,\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal?: AbortSignal,\n\tstreamFn?: typeof streamSimple,\n): EventStream<AgentEvent, AgentContext[\"messages\"]> {\n\tconst stream = createAgentStream();\n\n\t(async () => {\n\t\tconst newMessages: AgentContext[\"messages\"] = [prompt];\n\t\tconst currentContext: AgentContext = {\n\t\t\t...context,\n\t\t\tmessages: [...context.messages, prompt],\n\t\t};\n\n\t\tstream.push({ type: \"agent_start\" });\n\t\tstream.push({ type: \"turn_start\" });\n\t\tstream.push({ type: \"message_start\", message: prompt });\n\t\tstream.push({ type: \"message_end\", message: prompt });\n\n\t\tawait runLoop(currentContext, newMessages, config, signal, stream, streamFn);\n\t})();\n\n\treturn stream;\n}\n\n/**\n * Continue an agent loop from the current context without adding a new message.\n * Used for retry after overflow - context already has user message or tool results.\n * Throws if the last message is not a user message or tool result.\n */\nexport function agentLoopContinue(\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal?: AbortSignal,\n\tstreamFn?: typeof streamSimple,\n): EventStream<AgentEvent, AgentContext[\"messages\"]> {\n\t// Validate that we can continue from this context\n\tconst lastMessage = context.messages[context.messages.length - 1];\n\tif (!lastMessage) {\n\t\tthrow new Error(\"Cannot continue: no messages in context\");\n\t}\n\tif (lastMessage.role !== \"user\" && lastMessage.role !== \"toolResult\") {\n\t\tthrow new Error(`Cannot continue from message role: ${lastMessage.role}. Expected 'user' or 'toolResult'.`);\n\t}\n\n\tconst stream = createAgentStream();\n\n\t(async () => {\n\t\tconst newMessages: AgentContext[\"messages\"] = [];\n\t\tconst currentContext: AgentContext = { ...context };\n\n\t\tstream.push({ type: \"agent_start\" });\n\t\tstream.push({ type: \"turn_start\" });\n\t\t// No user message events - we're continuing from existing context\n\n\t\tawait runLoop(currentContext, newMessages, config, signal, stream, streamFn);\n\t})();\n\n\treturn stream;\n}\n\nfunction createAgentStream(): EventStream<AgentEvent, AgentContext[\"messages\"]> {\n\treturn new EventStream<AgentEvent, AgentContext[\"messages\"]>(\n\t\t(event: AgentEvent) => event.type === \"agent_end\",\n\t\t(event: AgentEvent) => (event.type === \"agent_end\" ? event.messages : []),\n\t);\n}\n\n/**\n * Shared loop logic for both agentLoop and agentLoopContinue.\n */\nasync function runLoop(\n\tcurrentContext: AgentContext,\n\tnewMessages: AgentContext[\"messages\"],\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\tstream: EventStream<AgentEvent, AgentContext[\"messages\"]>,\n\tstreamFn?: typeof streamSimple,\n): Promise<void> {\n\tlet hasMoreToolCalls = true;\n\tlet firstTurn = true;\n\tlet queuedMessages: QueuedMessage<any>[] = (await config.getQueuedMessages?.()) || [];\n\tlet queuedAfterTools: QueuedMessage<any>[] | null = null;\n\n\twhile (hasMoreToolCalls || queuedMessages.length > 0) {\n\t\tif (!firstTurn) {\n\t\t\tstream.push({ type: \"turn_start\" });\n\t\t} else {\n\t\t\tfirstTurn = false;\n\t\t}\n\n\t\t// Process queued messages first (inject before next assistant response)\n\t\tif (queuedMessages.length > 0) {\n\t\t\tfor (const { original, llm } of queuedMessages) {\n\t\t\t\tstream.push({ type: \"message_start\", message: original });\n\t\t\t\tstream.push({ type: \"message_end\", message: original });\n\t\t\t\tif (llm) {\n\t\t\t\t\tcurrentContext.messages.push(llm);\n\t\t\t\t\tnewMessages.push(llm);\n\t\t\t\t}\n\t\t\t}\n\t\t\tqueuedMessages = [];\n\t\t}\n\n\t\t// Stream assistant response\n\t\tconst message = await streamAssistantResponse(currentContext, config, signal, stream, streamFn);\n\t\tnewMessages.push(message);\n\n\t\tif (message.stopReason === \"error\" || message.stopReason === \"aborted\") {\n\t\t\t// Stop the loop on error or abort\n\t\t\tstream.push({ type: \"turn_end\", message, toolResults: [] });\n\t\t\tstream.push({ type: \"agent_end\", messages: newMessages });\n\t\t\tstream.end(newMessages);\n\t\t\treturn;\n\t\t}\n\n\t\t// Check for tool calls\n\t\tconst toolCalls = message.content.filter((c) => c.type === \"toolCall\");\n\t\thasMoreToolCalls = toolCalls.length > 0;\n\n\t\tconst toolResults: ToolResultMessage[] = [];\n\t\tif (hasMoreToolCalls) {\n\t\t\t// Execute tool calls\n\t\t\tconst toolExecution = await executeToolCalls(\n\t\t\t\tcurrentContext.tools,\n\t\t\t\tmessage,\n\t\t\t\tsignal,\n\t\t\t\tstream,\n\t\t\t\tconfig.getQueuedMessages,\n\t\t\t);\n\t\t\ttoolResults.push(...toolExecution.toolResults);\n\t\t\tqueuedAfterTools = toolExecution.queuedMessages ?? null;\n\t\t\tcurrentContext.messages.push(...toolResults);\n\t\t\tnewMessages.push(...toolResults);\n\t\t}\n\t\tstream.push({ type: \"turn_end\", message, toolResults: toolResults });\n\n\t\t// Get queued messages after turn completes\n\t\tif (queuedAfterTools && queuedAfterTools.length > 0) {\n\t\t\tqueuedMessages = queuedAfterTools;\n\t\t\tqueuedAfterTools = null;\n\t\t} else {\n\t\t\tqueuedMessages = (await config.getQueuedMessages?.()) || [];\n\t\t}\n\t}\n\n\tstream.push({ type: \"agent_end\", messages: newMessages });\n\tstream.end(newMessages);\n}\n\n// Helper functions\nasync function streamAssistantResponse(\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\tstream: EventStream<AgentEvent, AgentContext[\"messages\"]>,\n\tstreamFn?: typeof streamSimple,\n): Promise<AssistantMessage> {\n\t// Convert AgentContext to Context for streamSimple\n\t// Use a copy of messages to avoid mutating the original context\n\tconst processedMessages = config.preprocessor\n\t\t? await config.preprocessor(context.messages, signal)\n\t\t: [...context.messages];\n\tconst processedContext: Context = {\n\t\tsystemPrompt: context.systemPrompt,\n\t\tmessages: [...processedMessages].map((m) => {\n\t\t\tif (m.role === \"toolResult\") {\n\t\t\t\t// biome-ignore lint/correctness/noUnusedVariables: fine here\n\t\t\t\tconst { details, ...rest } = m;\n\t\t\t\treturn rest;\n\t\t\t} else {\n\t\t\t\treturn m;\n\t\t\t}\n\t\t}),\n\t\ttools: context.tools, // AgentTool extends Tool, so this works\n\t};\n\n\t// Use custom stream function if provided, otherwise use default streamSimple\n\tconst streamFunction = streamFn || streamSimple;\n\n\t// Resolve API key for every assistant response (important for expiring tokens)\n\tconst resolvedApiKey =\n\t\t(config.getApiKey ? await config.getApiKey(config.model.provider) : undefined) || config.apiKey;\n\n\tconst response = await streamFunction(config.model, processedContext, { ...config, apiKey: resolvedApiKey, signal });\n\n\tlet partialMessage: AssistantMessage | null = null;\n\tlet addedPartial = false;\n\n\tfor await (const event of response) {\n\t\tswitch (event.type) {\n\t\t\tcase \"start\":\n\t\t\t\tpartialMessage = event.partial;\n\t\t\t\tcontext.messages.push(partialMessage);\n\t\t\t\taddedPartial = true;\n\t\t\t\tstream.push({ type: \"message_start\", message: { ...partialMessage } });\n\t\t\t\tbreak;\n\n\t\t\tcase \"text_start\":\n\t\t\tcase \"text_delta\":\n\t\t\tcase \"text_end\":\n\t\t\tcase \"thinking_start\":\n\t\t\tcase \"thinking_delta\":\n\t\t\tcase \"thinking_end\":\n\t\t\tcase \"toolcall_start\":\n\t\t\tcase \"toolcall_delta\":\n\t\t\tcase \"toolcall_end\":\n\t\t\t\tif (partialMessage) {\n\t\t\t\t\tpartialMessage = event.partial;\n\t\t\t\t\tcontext.messages[context.messages.length - 1] = partialMessage;\n\t\t\t\t\tstream.push({ type: \"message_update\", assistantMessageEvent: event, message: { ...partialMessage } });\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase \"done\":\n\t\t\tcase \"error\": {\n\t\t\t\tconst finalMessage = await response.result();\n\t\t\t\tif (addedPartial) {\n\t\t\t\t\tcontext.messages[context.messages.length - 1] = finalMessage;\n\t\t\t\t} else {\n\t\t\t\t\tcontext.messages.push(finalMessage);\n\t\t\t\t}\n\t\t\t\tif (!addedPartial) {\n\t\t\t\t\tstream.push({ type: \"message_start\", message: { ...finalMessage } });\n\t\t\t\t}\n\t\t\t\tstream.push({ type: \"message_end\", message: finalMessage });\n\t\t\t\treturn finalMessage;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn await response.result();\n}\n\nasync function executeToolCalls<T>(\n\ttools: AgentTool<any, T>[] | undefined,\n\tassistantMessage: AssistantMessage,\n\tsignal: AbortSignal | undefined,\n\tstream: EventStream<AgentEvent, Message[]>,\n\tgetQueuedMessages?: AgentLoopConfig[\"getQueuedMessages\"],\n): Promise<{ toolResults: ToolResultMessage<T>[]; queuedMessages?: QueuedMessage<any>[] }> {\n\tconst toolCalls = assistantMessage.content.filter((c) => c.type === \"toolCall\");\n\tconst results: ToolResultMessage<any>[] = [];\n\tlet queuedMessages: QueuedMessage<any>[] | undefined;\n\n\tfor (let index = 0; index < toolCalls.length; index++) {\n\t\tconst toolCall = toolCalls[index];\n\t\tconst tool = tools?.find((t) => t.name === toolCall.name);\n\n\t\tstream.push({\n\t\t\ttype: \"tool_execution_start\",\n\t\t\ttoolCallId: toolCall.id,\n\t\t\ttoolName: toolCall.name,\n\t\t\targs: toolCall.arguments,\n\t\t});\n\n\t\tlet result: AgentToolResult<T>;\n\t\tlet isError = false;\n\n\t\ttry {\n\t\t\tif (!tool) throw new Error(`Tool ${toolCall.name} not found`);\n\n\t\t\t// Validate arguments using shared validation function\n\t\t\tconst validatedArgs = validateToolArguments(tool, toolCall);\n\n\t\t\t// Execute with validated, typed arguments, passing update callback\n\t\t\tresult = await tool.execute(toolCall.id, validatedArgs, signal, (partialResult) => {\n\t\t\t\tstream.push({\n\t\t\t\t\ttype: \"tool_execution_update\",\n\t\t\t\t\ttoolCallId: toolCall.id,\n\t\t\t\t\ttoolName: toolCall.name,\n\t\t\t\t\targs: toolCall.arguments,\n\t\t\t\t\tpartialResult,\n\t\t\t\t});\n\t\t\t});\n\t\t} catch (e) {\n\t\t\tresult = {\n\t\t\t\tcontent: [{ type: \"text\", text: e instanceof Error ? e.message : String(e) }],\n\t\t\t\tdetails: {} as T,\n\t\t\t};\n\t\t\tisError = true;\n\t\t}\n\n\t\tstream.push({\n\t\t\ttype: \"tool_execution_end\",\n\t\t\ttoolCallId: toolCall.id,\n\t\t\ttoolName: toolCall.name,\n\t\t\tresult,\n\t\t\tisError,\n\t\t});\n\n\t\tconst toolResultMessage: ToolResultMessage<T> = {\n\t\t\trole: \"toolResult\",\n\t\t\ttoolCallId: toolCall.id,\n\t\t\ttoolName: toolCall.name,\n\t\t\tcontent: result.content,\n\t\t\tdetails: result.details,\n\t\t\tisError,\n\t\t\ttimestamp: Date.now(),\n\t\t};\n\n\t\tresults.push(toolResultMessage);\n\t\tstream.push({ type: \"message_start\", message: toolResultMessage });\n\t\tstream.push({ type: \"message_end\", message: toolResultMessage });\n\n\t\tif (getQueuedMessages) {\n\t\t\tconst queued = await getQueuedMessages();\n\t\t\tif (queued.length > 0) {\n\t\t\t\tqueuedMessages = queued;\n\t\t\t\tconst remainingCalls = toolCalls.slice(index + 1);\n\t\t\t\tfor (const skipped of remainingCalls) {\n\t\t\t\t\tresults.push(skipToolCall(skipped, stream));\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { toolResults: results, queuedMessages };\n}\n\nfunction skipToolCall<T>(\n\ttoolCall: Extract<AssistantMessage[\"content\"][number], { type: \"toolCall\" }>,\n\tstream: EventStream<AgentEvent, Message[]>,\n): ToolResultMessage<T> {\n\tconst result: AgentToolResult<T> = {\n\t\tcontent: [{ type: \"text\", text: \"Skipped due to queued user message.\" }],\n\t\tdetails: {} as T,\n\t};\n\n\tstream.push({\n\t\ttype: \"tool_execution_start\",\n\t\ttoolCallId: toolCall.id,\n\t\ttoolName: toolCall.name,\n\t\targs: toolCall.arguments,\n\t});\n\tstream.push({\n\t\ttype: \"tool_execution_end\",\n\t\ttoolCallId: toolCall.id,\n\t\ttoolName: toolCall.name,\n\t\tresult,\n\t\tisError: true,\n\t});\n\n\tconst toolResultMessage: ToolResultMessage<T> = {\n\t\trole: \"toolResult\",\n\t\ttoolCallId: toolCall.id,\n\t\ttoolName: toolCall.name,\n\t\tcontent: result.content,\n\t\tdetails: result.details,\n\t\tisError: true,\n\t\ttimestamp: Date.now(),\n\t};\n\n\tstream.push({ type: \"message_start\", message: toolResultMessage });\n\tstream.push({ type: \"message_end\", message: toolResultMessage });\n\n\treturn toolResultMessage;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"calculate.d.ts","sourceRoot":"","sources":["../../../src/agent/tools/calculate.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvE,MAAM,WAAW,eAAgB,SAAQ,eAAe,CAAC,SAAS,CAAC;IAClE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,OAAO,EAAE,SAAS,CAAC;CACnB;AAED,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,eAAe,CAO7D;AAED,QAAA,MAAM,eAAe;;EAEnB,CAAC;AAIH,eAAO,MAAM,aAAa,EAAE,SAAS,CAAC,OAAO,eAAe,EAAE,SAAS,CAQtE,CAAC","sourcesContent":["import { type Static, Type } from \"@sinclair/typebox\";\nimport type { AgentTool, AgentToolResult } from \"../../agent/types.js\";\n\nexport interface CalculateResult extends AgentToolResult<undefined> {\n\tcontent: Array<{ type: \"text\"; text: string }>;\n\tdetails: undefined;\n}\n\nexport function calculate(expression: string): CalculateResult {\n\ttry {\n\t\tconst result = new Function(\"return \" + expression)();\n\t\treturn { content: [{ type: \"text\", text: `${expression} = ${result}` }], details: undefined };\n\t} catch (e: any) {\n\t\tthrow new Error(e.message || String(e));\n\t}\n}\n\nconst calculateSchema = Type.Object({\n\texpression: Type.String({ description: \"The mathematical expression to evaluate\" }),\n});\n\ntype CalculateParams = Static<typeof calculateSchema>;\n\nexport const calculateTool: AgentTool<typeof calculateSchema, undefined> = {\n\tlabel: \"Calculator\",\n\tname: \"calculate\",\n\tdescription: \"Evaluate mathematical expressions\",\n\tparameters: calculateSchema,\n\texecute: async (_toolCallId: string, args: CalculateParams) => {\n\t\treturn calculate(args.expression);\n\t},\n};\n"]}
1
+ {"version":3,"file":"calculate.d.ts","sourceRoot":"","sources":["../../../src/agent/tools/calculate.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvE,MAAM,WAAW,eAAgB,SAAQ,eAAe,CAAC,SAAS,CAAC;IAClE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,OAAO,EAAE,SAAS,CAAC;CACnB;AAED,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,eAAe,CAO7D;AAED,QAAA,MAAM,eAAe;;EAEnB,CAAC;AAIH,eAAO,MAAM,aAAa,EAAE,SAAS,CAAC,OAAO,eAAe,EAAE,SAAS,CAQtE,CAAC","sourcesContent":["import { type Static, Type } from \"@sinclair/typebox\";\nimport type { AgentTool, AgentToolResult } from \"../../agent/types.js\";\n\nexport interface CalculateResult extends AgentToolResult<undefined> {\n\tcontent: Array<{ type: \"text\"; text: string }>;\n\tdetails: undefined;\n}\n\nexport function calculate(expression: string): CalculateResult {\n\ttry {\n\t\tconst result = new Function(`return ${expression}`)();\n\t\treturn { content: [{ type: \"text\", text: `${expression} = ${result}` }], details: undefined };\n\t} catch (e: any) {\n\t\tthrow new Error(e.message || String(e));\n\t}\n}\n\nconst calculateSchema = Type.Object({\n\texpression: Type.String({ description: \"The mathematical expression to evaluate\" }),\n});\n\ntype CalculateParams = Static<typeof calculateSchema>;\n\nexport const calculateTool: AgentTool<typeof calculateSchema, undefined> = {\n\tlabel: \"Calculator\",\n\tname: \"calculate\",\n\tdescription: \"Evaluate mathematical expressions\",\n\tparameters: calculateSchema,\n\texecute: async (_toolCallId: string, args: CalculateParams) => {\n\t\treturn calculate(args.expression);\n\t},\n};\n"]}
@@ -1,7 +1,7 @@
1
1
  import { Type } from "@sinclair/typebox";
2
2
  export function calculate(expression) {
3
3
  try {
4
- const result = new Function("return " + expression)();
4
+ const result = new Function(`return ${expression}`)();
5
5
  return { content: [{ type: "text", text: `${expression} = ${result}` }], details: undefined };
6
6
  }
7
7
  catch (e) {
@@ -1 +1 @@
1
- {"version":3,"file":"calculate.js","sourceRoot":"","sources":["../../../src/agent/tools/calculate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAQtD,MAAM,UAAU,SAAS,CAAC,UAAkB,EAAmB;IAC9D,IAAI,CAAC;QACJ,MAAM,MAAM,GAAG,IAAI,QAAQ,CAAC,SAAS,GAAG,UAAU,CAAC,EAAE,CAAC;QACtD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,UAAU,MAAM,MAAM,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;IAC/F,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,OAAO,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACzC,CAAC;AAAA,CACD;AAED,MAAM,eAAe,GAAG,IAAI,CAAC,MAAM,CAAC;IACnC,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,yCAAyC,EAAE,CAAC;CACnF,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,aAAa,GAAiD;IAC1E,KAAK,EAAE,YAAY;IACnB,IAAI,EAAE,WAAW;IACjB,WAAW,EAAE,mCAAmC;IAChD,UAAU,EAAE,eAAe;IAC3B,OAAO,EAAE,KAAK,EAAE,WAAmB,EAAE,IAAqB,EAAE,EAAE,CAAC;QAC9D,OAAO,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAAA,CAClC;CACD,CAAC","sourcesContent":["import { type Static, Type } from \"@sinclair/typebox\";\nimport type { AgentTool, AgentToolResult } from \"../../agent/types.js\";\n\nexport interface CalculateResult extends AgentToolResult<undefined> {\n\tcontent: Array<{ type: \"text\"; text: string }>;\n\tdetails: undefined;\n}\n\nexport function calculate(expression: string): CalculateResult {\n\ttry {\n\t\tconst result = new Function(\"return \" + expression)();\n\t\treturn { content: [{ type: \"text\", text: `${expression} = ${result}` }], details: undefined };\n\t} catch (e: any) {\n\t\tthrow new Error(e.message || String(e));\n\t}\n}\n\nconst calculateSchema = Type.Object({\n\texpression: Type.String({ description: \"The mathematical expression to evaluate\" }),\n});\n\ntype CalculateParams = Static<typeof calculateSchema>;\n\nexport const calculateTool: AgentTool<typeof calculateSchema, undefined> = {\n\tlabel: \"Calculator\",\n\tname: \"calculate\",\n\tdescription: \"Evaluate mathematical expressions\",\n\tparameters: calculateSchema,\n\texecute: async (_toolCallId: string, args: CalculateParams) => {\n\t\treturn calculate(args.expression);\n\t},\n};\n"]}
1
+ {"version":3,"file":"calculate.js","sourceRoot":"","sources":["../../../src/agent/tools/calculate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAQtD,MAAM,UAAU,SAAS,CAAC,UAAkB,EAAmB;IAC9D,IAAI,CAAC;QACJ,MAAM,MAAM,GAAG,IAAI,QAAQ,CAAC,UAAU,UAAU,EAAE,CAAC,EAAE,CAAC;QACtD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,UAAU,MAAM,MAAM,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;IAC/F,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,OAAO,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACzC,CAAC;AAAA,CACD;AAED,MAAM,eAAe,GAAG,IAAI,CAAC,MAAM,CAAC;IACnC,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,yCAAyC,EAAE,CAAC;CACnF,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,aAAa,GAAiD;IAC1E,KAAK,EAAE,YAAY;IACnB,IAAI,EAAE,WAAW;IACjB,WAAW,EAAE,mCAAmC;IAChD,UAAU,EAAE,eAAe;IAC3B,OAAO,EAAE,KAAK,EAAE,WAAmB,EAAE,IAAqB,EAAE,EAAE,CAAC;QAC9D,OAAO,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAAA,CAClC;CACD,CAAC","sourcesContent":["import { type Static, Type } from \"@sinclair/typebox\";\nimport type { AgentTool, AgentToolResult } from \"../../agent/types.js\";\n\nexport interface CalculateResult extends AgentToolResult<undefined> {\n\tcontent: Array<{ type: \"text\"; text: string }>;\n\tdetails: undefined;\n}\n\nexport function calculate(expression: string): CalculateResult {\n\ttry {\n\t\tconst result = new Function(`return ${expression}`)();\n\t\treturn { content: [{ type: \"text\", text: `${expression} = ${result}` }], details: undefined };\n\t} catch (e: any) {\n\t\tthrow new Error(e.message || String(e));\n\t}\n}\n\nconst calculateSchema = Type.Object({\n\texpression: Type.String({ description: \"The mathematical expression to evaluate\" }),\n});\n\ntype CalculateParams = Static<typeof calculateSchema>;\n\nexport const calculateTool: AgentTool<typeof calculateSchema, undefined> = {\n\tlabel: \"Calculator\",\n\tname: \"calculate\",\n\tdescription: \"Evaluate mathematical expressions\",\n\tparameters: calculateSchema,\n\texecute: async (_toolCallId: string, args: CalculateParams) => {\n\t\treturn calculate(args.expression);\n\t},\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"get-current-time.d.ts","sourceRoot":"","sources":["../../../src/agent/tools/get-current-time.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,MAAM,WAAW,oBAAqB,SAAQ,eAAe,CAAC;IAAE,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC;CAAG;AAE1F,wBAAsB,cAAc,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAsBrF;AAED,QAAA,MAAM,oBAAoB;;EAIxB,CAAC;AAIH,eAAO,MAAM,kBAAkB,EAAE,SAAS,CAAC,OAAO,oBAAoB,EAAE;IAAE,YAAY,EAAE,MAAM,CAAA;CAAE,CAQ/F,CAAC","sourcesContent":["import { type Static, Type } from \"@sinclair/typebox\";\nimport type { AgentTool } from \"../../agent/index.js\";\nimport type { AgentToolResult } from \"../types.js\";\n\nexport interface GetCurrentTimeResult extends AgentToolResult<{ utcTimestamp: number }> {}\n\nexport async function getCurrentTime(timezone?: string): Promise<GetCurrentTimeResult> {\n\tconst date = new Date();\n\tif (timezone) {\n\t\ttry {\n\t\t\tconst timeStr = date.toLocaleString(\"en-US\", {\n\t\t\t\ttimeZone: timezone,\n\t\t\t\tdateStyle: \"full\",\n\t\t\t\ttimeStyle: \"long\",\n\t\t\t});\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: timeStr }],\n\t\t\t\tdetails: { utcTimestamp: date.getTime() },\n\t\t\t};\n\t\t} catch (e) {\n\t\t\tthrow new Error(`Invalid timezone: ${timezone}. Current UTC time: ${date.toISOString()}`);\n\t\t}\n\t}\n\tconst timeStr = date.toLocaleString(\"en-US\", { dateStyle: \"full\", timeStyle: \"long\" });\n\treturn {\n\t\tcontent: [{ type: \"text\", text: timeStr }],\n\t\tdetails: { utcTimestamp: date.getTime() },\n\t};\n}\n\nconst getCurrentTimeSchema = Type.Object({\n\ttimezone: Type.Optional(\n\t\tType.String({ description: \"Optional timezone (e.g., 'America/New_York', 'Europe/London')\" }),\n\t),\n});\n\ntype GetCurrentTimeParams = Static<typeof getCurrentTimeSchema>;\n\nexport const getCurrentTimeTool: AgentTool<typeof getCurrentTimeSchema, { utcTimestamp: number }> = {\n\tlabel: \"Current Time\",\n\tname: \"get_current_time\",\n\tdescription: \"Get the current date and time\",\n\tparameters: getCurrentTimeSchema,\n\texecute: async (_toolCallId: string, args: GetCurrentTimeParams) => {\n\t\treturn getCurrentTime(args.timezone);\n\t},\n};\n"]}
1
+ {"version":3,"file":"get-current-time.d.ts","sourceRoot":"","sources":["../../../src/agent/tools/get-current-time.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,MAAM,WAAW,oBAAqB,SAAQ,eAAe,CAAC;IAAE,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC;CAAG;AAE1F,wBAAsB,cAAc,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAsBrF;AAED,QAAA,MAAM,oBAAoB;;EAIxB,CAAC;AAIH,eAAO,MAAM,kBAAkB,EAAE,SAAS,CAAC,OAAO,oBAAoB,EAAE;IAAE,YAAY,EAAE,MAAM,CAAA;CAAE,CAQ/F,CAAC","sourcesContent":["import { type Static, Type } from \"@sinclair/typebox\";\nimport type { AgentTool } from \"../../agent/index.js\";\nimport type { AgentToolResult } from \"../types.js\";\n\nexport interface GetCurrentTimeResult extends AgentToolResult<{ utcTimestamp: number }> {}\n\nexport async function getCurrentTime(timezone?: string): Promise<GetCurrentTimeResult> {\n\tconst date = new Date();\n\tif (timezone) {\n\t\ttry {\n\t\t\tconst timeStr = date.toLocaleString(\"en-US\", {\n\t\t\t\ttimeZone: timezone,\n\t\t\t\tdateStyle: \"full\",\n\t\t\t\ttimeStyle: \"long\",\n\t\t\t});\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: timeStr }],\n\t\t\t\tdetails: { utcTimestamp: date.getTime() },\n\t\t\t};\n\t\t} catch (_e) {\n\t\t\tthrow new Error(`Invalid timezone: ${timezone}. Current UTC time: ${date.toISOString()}`);\n\t\t}\n\t}\n\tconst timeStr = date.toLocaleString(\"en-US\", { dateStyle: \"full\", timeStyle: \"long\" });\n\treturn {\n\t\tcontent: [{ type: \"text\", text: timeStr }],\n\t\tdetails: { utcTimestamp: date.getTime() },\n\t};\n}\n\nconst getCurrentTimeSchema = Type.Object({\n\ttimezone: Type.Optional(\n\t\tType.String({ description: \"Optional timezone (e.g., 'America/New_York', 'Europe/London')\" }),\n\t),\n});\n\ntype GetCurrentTimeParams = Static<typeof getCurrentTimeSchema>;\n\nexport const getCurrentTimeTool: AgentTool<typeof getCurrentTimeSchema, { utcTimestamp: number }> = {\n\tlabel: \"Current Time\",\n\tname: \"get_current_time\",\n\tdescription: \"Get the current date and time\",\n\tparameters: getCurrentTimeSchema,\n\texecute: async (_toolCallId: string, args: GetCurrentTimeParams) => {\n\t\treturn getCurrentTime(args.timezone);\n\t},\n};\n"]}
@@ -13,7 +13,7 @@ export async function getCurrentTime(timezone) {
13
13
  details: { utcTimestamp: date.getTime() },
14
14
  };
15
15
  }
16
- catch (e) {
16
+ catch (_e) {
17
17
  throw new Error(`Invalid timezone: ${timezone}. Current UTC time: ${date.toISOString()}`);
18
18
  }
19
19
  }
@@ -1 +1 @@
1
- {"version":3,"file":"get-current-time.js","sourceRoot":"","sources":["../../../src/agent/tools/get-current-time.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAMtD,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,QAAiB,EAAiC;IACtF,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;IACxB,IAAI,QAAQ,EAAE,CAAC;QACd,IAAI,CAAC;YACJ,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE;gBAC5C,QAAQ,EAAE,QAAQ;gBAClB,SAAS,EAAE,MAAM;gBACjB,SAAS,EAAE,MAAM;aACjB,CAAC,CAAC;YACH,OAAO;gBACN,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;gBAC1C,OAAO,EAAE,EAAE,YAAY,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE;aACzC,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,qBAAqB,QAAQ,uBAAuB,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QAC3F,CAAC;IACF,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;IACvF,OAAO;QACN,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;QAC1C,OAAO,EAAE,EAAE,YAAY,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE;KACzC,CAAC;AAAA,CACF;AAED,MAAM,oBAAoB,GAAG,IAAI,CAAC,MAAM,CAAC;IACxC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CACtB,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,+DAA+D,EAAE,CAAC,CAC7F;CACD,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,kBAAkB,GAAqE;IACnG,KAAK,EAAE,cAAc;IACrB,IAAI,EAAE,kBAAkB;IACxB,WAAW,EAAE,+BAA+B;IAC5C,UAAU,EAAE,oBAAoB;IAChC,OAAO,EAAE,KAAK,EAAE,WAAmB,EAAE,IAA0B,EAAE,EAAE,CAAC;QACnE,OAAO,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAAA,CACrC;CACD,CAAC","sourcesContent":["import { type Static, Type } from \"@sinclair/typebox\";\nimport type { AgentTool } from \"../../agent/index.js\";\nimport type { AgentToolResult } from \"../types.js\";\n\nexport interface GetCurrentTimeResult extends AgentToolResult<{ utcTimestamp: number }> {}\n\nexport async function getCurrentTime(timezone?: string): Promise<GetCurrentTimeResult> {\n\tconst date = new Date();\n\tif (timezone) {\n\t\ttry {\n\t\t\tconst timeStr = date.toLocaleString(\"en-US\", {\n\t\t\t\ttimeZone: timezone,\n\t\t\t\tdateStyle: \"full\",\n\t\t\t\ttimeStyle: \"long\",\n\t\t\t});\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: timeStr }],\n\t\t\t\tdetails: { utcTimestamp: date.getTime() },\n\t\t\t};\n\t\t} catch (e) {\n\t\t\tthrow new Error(`Invalid timezone: ${timezone}. Current UTC time: ${date.toISOString()}`);\n\t\t}\n\t}\n\tconst timeStr = date.toLocaleString(\"en-US\", { dateStyle: \"full\", timeStyle: \"long\" });\n\treturn {\n\t\tcontent: [{ type: \"text\", text: timeStr }],\n\t\tdetails: { utcTimestamp: date.getTime() },\n\t};\n}\n\nconst getCurrentTimeSchema = Type.Object({\n\ttimezone: Type.Optional(\n\t\tType.String({ description: \"Optional timezone (e.g., 'America/New_York', 'Europe/London')\" }),\n\t),\n});\n\ntype GetCurrentTimeParams = Static<typeof getCurrentTimeSchema>;\n\nexport const getCurrentTimeTool: AgentTool<typeof getCurrentTimeSchema, { utcTimestamp: number }> = {\n\tlabel: \"Current Time\",\n\tname: \"get_current_time\",\n\tdescription: \"Get the current date and time\",\n\tparameters: getCurrentTimeSchema,\n\texecute: async (_toolCallId: string, args: GetCurrentTimeParams) => {\n\t\treturn getCurrentTime(args.timezone);\n\t},\n};\n"]}
1
+ {"version":3,"file":"get-current-time.js","sourceRoot":"","sources":["../../../src/agent/tools/get-current-time.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAMtD,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,QAAiB,EAAiC;IACtF,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;IACxB,IAAI,QAAQ,EAAE,CAAC;QACd,IAAI,CAAC;YACJ,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE;gBAC5C,QAAQ,EAAE,QAAQ;gBAClB,SAAS,EAAE,MAAM;gBACjB,SAAS,EAAE,MAAM;aACjB,CAAC,CAAC;YACH,OAAO;gBACN,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;gBAC1C,OAAO,EAAE,EAAE,YAAY,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE;aACzC,CAAC;QACH,CAAC;QAAC,OAAO,EAAE,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,qBAAqB,QAAQ,uBAAuB,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QAC3F,CAAC;IACF,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;IACvF,OAAO;QACN,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;QAC1C,OAAO,EAAE,EAAE,YAAY,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE;KACzC,CAAC;AAAA,CACF;AAED,MAAM,oBAAoB,GAAG,IAAI,CAAC,MAAM,CAAC;IACxC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CACtB,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,+DAA+D,EAAE,CAAC,CAC7F;CACD,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,kBAAkB,GAAqE;IACnG,KAAK,EAAE,cAAc;IACrB,IAAI,EAAE,kBAAkB;IACxB,WAAW,EAAE,+BAA+B;IAC5C,UAAU,EAAE,oBAAoB;IAChC,OAAO,EAAE,KAAK,EAAE,WAAmB,EAAE,IAA0B,EAAE,EAAE,CAAC;QACnE,OAAO,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAAA,CACrC;CACD,CAAC","sourcesContent":["import { type Static, Type } from \"@sinclair/typebox\";\nimport type { AgentTool } from \"../../agent/index.js\";\nimport type { AgentToolResult } from \"../types.js\";\n\nexport interface GetCurrentTimeResult extends AgentToolResult<{ utcTimestamp: number }> {}\n\nexport async function getCurrentTime(timezone?: string): Promise<GetCurrentTimeResult> {\n\tconst date = new Date();\n\tif (timezone) {\n\t\ttry {\n\t\t\tconst timeStr = date.toLocaleString(\"en-US\", {\n\t\t\t\ttimeZone: timezone,\n\t\t\t\tdateStyle: \"full\",\n\t\t\t\ttimeStyle: \"long\",\n\t\t\t});\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: timeStr }],\n\t\t\t\tdetails: { utcTimestamp: date.getTime() },\n\t\t\t};\n\t\t} catch (_e) {\n\t\t\tthrow new Error(`Invalid timezone: ${timezone}. Current UTC time: ${date.toISOString()}`);\n\t\t}\n\t}\n\tconst timeStr = date.toLocaleString(\"en-US\", { dateStyle: \"full\", timeStyle: \"long\" });\n\treturn {\n\t\tcontent: [{ type: \"text\", text: timeStr }],\n\t\tdetails: { utcTimestamp: date.getTime() },\n\t};\n}\n\nconst getCurrentTimeSchema = Type.Object({\n\ttimezone: Type.Optional(\n\t\tType.String({ description: \"Optional timezone (e.g., 'America/New_York', 'Europe/London')\" }),\n\t),\n});\n\ntype GetCurrentTimeParams = Static<typeof getCurrentTimeSchema>;\n\nexport const getCurrentTimeTool: AgentTool<typeof getCurrentTimeSchema, { utcTimestamp: number }> = {\n\tlabel: \"Current Time\",\n\tname: \"get_current_time\",\n\tdescription: \"Get the current date and time\",\n\tparameters: getCurrentTimeSchema,\n\texecute: async (_toolCallId: string, args: GetCurrentTimeParams) => {\n\t\treturn getCurrentTime(args.timezone);\n\t},\n};\n"]}
@@ -6149,7 +6149,7 @@ export declare const MODELS: {
6149
6149
  contextWindow: number;
6150
6150
  maxTokens: number;
6151
6151
  };
6152
- readonly "anthropic/claude-3.5-haiku-20241022": {
6152
+ readonly "anthropic/claude-3.5-haiku": {
6153
6153
  id: string;
6154
6154
  name: string;
6155
6155
  api: "openai-completions";
@@ -6166,7 +6166,7 @@ export declare const MODELS: {
6166
6166
  contextWindow: number;
6167
6167
  maxTokens: number;
6168
6168
  };
6169
- readonly "anthropic/claude-3.5-haiku": {
6169
+ readonly "anthropic/claude-3.5-haiku-20241022": {
6170
6170
  id: string;
6171
6171
  name: string;
6172
6172
  api: "openai-completions";
@@ -6404,7 +6404,7 @@ export declare const MODELS: {
6404
6404
  contextWindow: number;
6405
6405
  maxTokens: number;
6406
6406
  };
6407
- readonly "meta-llama/llama-3.1-8b-instruct": {
6407
+ readonly "meta-llama/llama-3.1-405b-instruct": {
6408
6408
  id: string;
6409
6409
  name: string;
6410
6410
  api: "openai-completions";
@@ -6421,7 +6421,7 @@ export declare const MODELS: {
6421
6421
  contextWindow: number;
6422
6422
  maxTokens: number;
6423
6423
  };
6424
- readonly "meta-llama/llama-3.1-405b-instruct": {
6424
+ readonly "meta-llama/llama-3.1-8b-instruct": {
6425
6425
  id: string;
6426
6426
  name: string;
6427
6427
  api: "openai-completions";