@tanstack/ai 0.35.0 → 0.36.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.
- package/package.json +2 -2
- package/skills/ai-core/tool-calling/SKILL.md +26 -1
- package/src/activities/chat/index.ts +8 -0
- package/src/activities/chat/tools/lazy-tool-manager.ts +12 -4
- package/src/activities/chat/tools/lazy-tools.ts +33 -0
- package/src/index.ts +5 -0
- package/src/types.ts +23 -1
- package/dist/esm/activities/chat/adapter.d.ts +0 -163
- package/dist/esm/activities/chat/adapter.js +0 -17
- package/dist/esm/activities/chat/adapter.js.map +0 -1
- package/dist/esm/activities/chat/agent-loop-strategies.d.ts +0 -59
- package/dist/esm/activities/chat/agent-loop-strategies.js +0 -23
- package/dist/esm/activities/chat/agent-loop-strategies.js.map +0 -1
- package/dist/esm/activities/chat/index.d.ts +0 -264
- package/dist/esm/activities/chat/index.js +0 -1723
- package/dist/esm/activities/chat/index.js.map +0 -1
- package/dist/esm/activities/chat/mcp/manager.d.ts +0 -25
- package/dist/esm/activities/chat/mcp/manager.js +0 -71
- package/dist/esm/activities/chat/mcp/manager.js.map +0 -1
- package/dist/esm/activities/chat/mcp/types.d.ts +0 -56
- package/dist/esm/activities/chat/messages.d.ts +0 -78
- package/dist/esm/activities/chat/messages.js +0 -374
- package/dist/esm/activities/chat/messages.js.map +0 -1
- package/dist/esm/activities/chat/middleware/builder.d.ts +0 -46
- package/dist/esm/activities/chat/middleware/builder.js +0 -17
- package/dist/esm/activities/chat/middleware/builder.js.map +0 -1
- package/dist/esm/activities/chat/middleware/capabilities.d.ts +0 -93
- package/dist/esm/activities/chat/middleware/capabilities.js +0 -45
- package/dist/esm/activities/chat/middleware/capabilities.js.map +0 -1
- package/dist/esm/activities/chat/middleware/compose.d.ts +0 -87
- package/dist/esm/activities/chat/middleware/compose.js +0 -510
- package/dist/esm/activities/chat/middleware/compose.js.map +0 -1
- package/dist/esm/activities/chat/middleware/define.d.ts +0 -20
- package/dist/esm/activities/chat/middleware/define.js +0 -7
- package/dist/esm/activities/chat/middleware/define.js.map +0 -1
- package/dist/esm/activities/chat/middleware/index.d.ts +0 -10
- package/dist/esm/activities/chat/middleware/tool-cache-middleware.d.ts +0 -89
- package/dist/esm/activities/chat/middleware/tool-cache-middleware.js +0 -76
- package/dist/esm/activities/chat/middleware/tool-cache-middleware.js.map +0 -1
- package/dist/esm/activities/chat/middleware/types.d.ts +0 -405
- package/dist/esm/activities/chat/middleware/validate.d.ts +0 -19
- package/dist/esm/activities/chat/middleware/validate.js +0 -30
- package/dist/esm/activities/chat/middleware/validate.js.map +0 -1
- package/dist/esm/activities/chat/runtime-context-types.d.ts +0 -43
- package/dist/esm/activities/chat/stream/index.d.ts +0 -11
- package/dist/esm/activities/chat/stream/json-parser.d.ts +0 -38
- package/dist/esm/activities/chat/stream/json-parser.js +0 -28
- package/dist/esm/activities/chat/stream/json-parser.js.map +0 -1
- package/dist/esm/activities/chat/stream/message-updaters.d.ts +0 -81
- package/dist/esm/activities/chat/stream/message-updaters.js +0 -253
- package/dist/esm/activities/chat/stream/message-updaters.js.map +0 -1
- package/dist/esm/activities/chat/stream/processor.d.ts +0 -439
- package/dist/esm/activities/chat/stream/processor.js +0 -1426
- package/dist/esm/activities/chat/stream/processor.js.map +0 -1
- package/dist/esm/activities/chat/stream/strategies.d.ts +0 -43
- package/dist/esm/activities/chat/stream/strategies.js +0 -54
- package/dist/esm/activities/chat/stream/strategies.js.map +0 -1
- package/dist/esm/activities/chat/stream/types.d.ts +0 -90
- package/dist/esm/activities/chat/tools/lazy-tool-manager.d.ts +0 -81
- package/dist/esm/activities/chat/tools/lazy-tool-manager.js +0 -188
- package/dist/esm/activities/chat/tools/lazy-tool-manager.js.map +0 -1
- package/dist/esm/activities/chat/tools/schema-converter.d.ts +0 -140
- package/dist/esm/activities/chat/tools/schema-converter.js +0 -167
- package/dist/esm/activities/chat/tools/schema-converter.js.map +0 -1
- package/dist/esm/activities/chat/tools/tool-calls.d.ts +0 -140
- package/dist/esm/activities/chat/tools/tool-calls.js +0 -512
- package/dist/esm/activities/chat/tools/tool-calls.js.map +0 -1
- package/dist/esm/activities/chat/tools/tool-definition.d.ts +0 -135
- package/dist/esm/activities/chat/tools/tool-definition.js +0 -25
- package/dist/esm/activities/chat/tools/tool-definition.js.map +0 -1
- package/dist/esm/activities/error-payload.d.ts +0 -30
- package/dist/esm/activities/error-payload.js +0 -54
- package/dist/esm/activities/error-payload.js.map +0 -1
- package/dist/esm/activities/generateAudio/adapter.d.ts +0 -62
- package/dist/esm/activities/generateAudio/adapter.js +0 -16
- package/dist/esm/activities/generateAudio/adapter.js.map +0 -1
- package/dist/esm/activities/generateAudio/index.d.ts +0 -85
- package/dist/esm/activities/generateAudio/index.js +0 -114
- package/dist/esm/activities/generateAudio/index.js.map +0 -1
- package/dist/esm/activities/generateImage/adapter.d.ts +0 -78
- package/dist/esm/activities/generateImage/adapter.js +0 -16
- package/dist/esm/activities/generateImage/adapter.js.map +0 -1
- package/dist/esm/activities/generateImage/index.d.ts +0 -134
- package/dist/esm/activities/generateImage/index.js +0 -121
- package/dist/esm/activities/generateImage/index.js.map +0 -1
- package/dist/esm/activities/generateSpeech/adapter.d.ts +0 -62
- package/dist/esm/activities/generateSpeech/adapter.js +0 -16
- package/dist/esm/activities/generateSpeech/adapter.js.map +0 -1
- package/dist/esm/activities/generateSpeech/index.d.ts +0 -96
- package/dist/esm/activities/generateSpeech/index.js +0 -119
- package/dist/esm/activities/generateSpeech/index.js.map +0 -1
- package/dist/esm/activities/generateTranscription/adapter.d.ts +0 -62
- package/dist/esm/activities/generateTranscription/adapter.js +0 -16
- package/dist/esm/activities/generateTranscription/adapter.js.map +0 -1
- package/dist/esm/activities/generateTranscription/index.d.ts +0 -109
- package/dist/esm/activities/generateTranscription/index.js +0 -109
- package/dist/esm/activities/generateTranscription/index.js.map +0 -1
- package/dist/esm/activities/generateVideo/adapter.d.ts +0 -145
- package/dist/esm/activities/generateVideo/adapter.js +0 -30
- package/dist/esm/activities/generateVideo/adapter.js.map +0 -1
- package/dist/esm/activities/generateVideo/index.d.ts +0 -223
- package/dist/esm/activities/generateVideo/index.js +0 -295
- package/dist/esm/activities/generateVideo/index.js.map +0 -1
- package/dist/esm/activities/generateVideo/snap.d.ts +0 -14
- package/dist/esm/activities/generateVideo/snap.js +0 -54
- package/dist/esm/activities/generateVideo/snap.js.map +0 -1
- package/dist/esm/activities/index.d.ts +0 -27
- package/dist/esm/activities/index.js +0 -43
- package/dist/esm/activities/index.js.map +0 -1
- package/dist/esm/activities/middleware/index.d.ts +0 -2
- package/dist/esm/activities/middleware/run.d.ts +0 -20
- package/dist/esm/activities/middleware/run.js +0 -42
- package/dist/esm/activities/middleware/run.js.map +0 -1
- package/dist/esm/activities/middleware/types.d.ts +0 -118
- package/dist/esm/activities/stream-generation-result.d.ts +0 -15
- package/dist/esm/activities/stream-generation-result.js +0 -49
- package/dist/esm/activities/stream-generation-result.js.map +0 -1
- package/dist/esm/activities/summarize/adapter.d.ts +0 -74
- package/dist/esm/activities/summarize/adapter.js +0 -16
- package/dist/esm/activities/summarize/adapter.js.map +0 -1
- package/dist/esm/activities/summarize/chat-stream-summarize.d.ts +0 -45
- package/dist/esm/activities/summarize/chat-stream-summarize.js +0 -212
- package/dist/esm/activities/summarize/chat-stream-summarize.js.map +0 -1
- package/dist/esm/activities/summarize/index.d.ts +0 -108
- package/dist/esm/activities/summarize/index.js +0 -113
- package/dist/esm/activities/summarize/index.js.map +0 -1
- package/dist/esm/adapter-internals.d.ts +0 -5
- package/dist/esm/adapter-internals.js +0 -10
- package/dist/esm/adapter-internals.js.map +0 -1
- package/dist/esm/client.d.ts +0 -44
- package/dist/esm/client.js +0 -67
- package/dist/esm/client.js.map +0 -1
- package/dist/esm/extend-adapter.d.ts +0 -152
- package/dist/esm/extend-adapter.js +0 -21
- package/dist/esm/extend-adapter.js.map +0 -1
- package/dist/esm/index.d.ts +0 -44
- package/dist/esm/index.js +0 -106
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/logger/console-logger.d.ts +0 -29
- package/dist/esm/logger/console-logger.js +0 -83
- package/dist/esm/logger/console-logger.js.map +0 -1
- package/dist/esm/logger/internal-logger.d.ts +0 -41
- package/dist/esm/logger/internal-logger.js +0 -86
- package/dist/esm/logger/internal-logger.js.map +0 -1
- package/dist/esm/logger/resolve.d.ts +0 -14
- package/dist/esm/logger/resolve.js +0 -54
- package/dist/esm/logger/resolve.js.map +0 -1
- package/dist/esm/logger/types.d.ts +0 -75
- package/dist/esm/middlewares/content-guard.d.ts +0 -77
- package/dist/esm/middlewares/content-guard.js +0 -156
- package/dist/esm/middlewares/content-guard.js.map +0 -1
- package/dist/esm/middlewares/index.d.ts +0 -2
- package/dist/esm/middlewares/index.js +0 -7
- package/dist/esm/middlewares/index.js.map +0 -1
- package/dist/esm/middlewares/otel.d.ts +0 -81
- package/dist/esm/middlewares/otel.js +0 -745
- package/dist/esm/middlewares/otel.js.map +0 -1
- package/dist/esm/middlewares/tool-cache.d.ts +0 -1
- package/dist/esm/middlewares/usage-attributes.d.ts +0 -24
- package/dist/esm/middlewares/usage-attributes.js +0 -43
- package/dist/esm/middlewares/usage-attributes.js.map +0 -1
- package/dist/esm/realtime/index.d.ts +0 -28
- package/dist/esm/realtime/index.js +0 -8
- package/dist/esm/realtime/index.js.map +0 -1
- package/dist/esm/realtime/types.d.ts +0 -282
- package/dist/esm/stream-to-response.d.ts +0 -102
- package/dist/esm/stream-to-response.js +0 -121
- package/dist/esm/stream-to-response.js.map +0 -1
- package/dist/esm/strip-to-spec-middleware.d.ts +0 -18
- package/dist/esm/strip-to-spec-middleware.js +0 -20
- package/dist/esm/strip-to-spec-middleware.js.map +0 -1
- package/dist/esm/system-prompts.d.ts +0 -66
- package/dist/esm/system-prompts.js +0 -23
- package/dist/esm/system-prompts.js.map +0 -1
- package/dist/esm/tool-registry.d.ts +0 -81
- package/dist/esm/tool-registry.js +0 -49
- package/dist/esm/tool-registry.js.map +0 -1
- package/dist/esm/tools/provider-tool.d.ts +0 -30
- package/dist/esm/tools/provider-tool.js +0 -7
- package/dist/esm/tools/provider-tool.js.map +0 -1
- package/dist/esm/types.d.ts +0 -1573
- package/dist/esm/utilities/ag-ui-wire.d.ts +0 -44
- package/dist/esm/utilities/ag-ui-wire.js +0 -107
- package/dist/esm/utilities/ag-ui-wire.js.map +0 -1
- package/dist/esm/utilities/chat-params.d.ts +0 -85
- package/dist/esm/utilities/chat-params.js +0 -100
- package/dist/esm/utilities/chat-params.js.map +0 -1
- package/dist/esm/utilities/errors.d.ts +0 -13
- package/dist/esm/utilities/errors.js +0 -22
- package/dist/esm/utilities/errors.js.map +0 -1
- package/dist/esm/utilities/media-prompt.d.ts +0 -35
- package/dist/esm/utilities/media-prompt.js +0 -43
- package/dist/esm/utilities/media-prompt.js.map +0 -1
- package/dist/esm/utilities/numbers.d.ts +0 -8
- package/dist/esm/utilities/numbers.js +0 -12
- package/dist/esm/utilities/numbers.js.map +0 -1
- package/dist/esm/utilities/sampling-keys.d.ts +0 -20
- package/dist/esm/utilities/sampling-keys.js +0 -20
- package/dist/esm/utilities/sampling-keys.js.map +0 -1
- package/dist/esm/utilities/tool-result.d.ts +0 -21
- package/dist/esm/utilities/tool-result.js +0 -37
- package/dist/esm/utilities/tool-result.js.map +0 -1
- package/dist/esm/utilities/usage.d.ts +0 -31
- package/dist/esm/utilities/usage.js +0 -11
- package/dist/esm/utilities/usage.js.map +0 -1
- package/dist/esm/utils.d.ts +0 -17
- package/dist/esm/utils.js +0 -20
- package/dist/esm/utils.js.map +0 -1
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import { AnyTool, CustomEvent, ModelMessage, RunFinishedEvent, Tool, ToolCall, ToolCallArgsEvent, ToolCallEndEvent, ToolCallStartEvent } from '../../../types.js';
|
|
2
|
-
import { AfterToolCallInfo, BeforeToolCallDecision } from '../middleware/types.js';
|
|
3
|
-
import { ContextFromTool, DefinedContext, MergeContext, UnionToIntersection } from '../runtime-context-types.js';
|
|
4
|
-
/**
|
|
5
|
-
* Optional middleware hooks for tool execution.
|
|
6
|
-
* When provided, these callbacks are invoked before/after each tool execution.
|
|
7
|
-
*/
|
|
8
|
-
export interface ToolExecutionMiddlewareHooks {
|
|
9
|
-
onBeforeToolCall?: (toolCall: ToolCall, tool: Tool | undefined, args: unknown) => Promise<BeforeToolCallDecision>;
|
|
10
|
-
onAfterToolCall?: (info: AfterToolCallInfo) => Promise<void>;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Error thrown when middleware decides to abort the chat run during tool execution.
|
|
14
|
-
*/
|
|
15
|
-
export declare class MiddlewareAbortError extends Error {
|
|
16
|
-
constructor(reason: string);
|
|
17
|
-
}
|
|
18
|
-
type RequiredContextFromToolUnion<T> = T extends unknown ? undefined extends ContextFromTool<T> ? never : ContextFromTool<T> : never;
|
|
19
|
-
type ContextFromToolUnion<T> = [
|
|
20
|
-
UnionToIntersection<DefinedContext<ContextFromTool<T>>>
|
|
21
|
-
] extends [never] ? unknown : [RequiredContextFromToolUnion<T>] extends [never] ? UnionToIntersection<DefinedContext<ContextFromTool<T>>> | undefined : UnionToIntersection<DefinedContext<ContextFromTool<T>>>;
|
|
22
|
-
type ContextFromTools<TTools> = TTools extends readonly [
|
|
23
|
-
infer THead,
|
|
24
|
-
...infer TTail
|
|
25
|
-
] ? MergeContext<ContextFromTool<THead>, ContextFromTools<TTail>> : TTools extends ReadonlyArray<infer TTool> ? ContextFromToolUnion<TTool> : unknown;
|
|
26
|
-
type ExecuteToolsContextArgs<TContext> = undefined extends TContext ? [userContext?: TContext] : [userContext: TContext];
|
|
27
|
-
/**
|
|
28
|
-
* Manages tool call accumulation and execution for the chat() method's automatic tool execution loop.
|
|
29
|
-
*
|
|
30
|
-
* Responsibilities:
|
|
31
|
-
* - Accumulates streaming tool call events (ID, name, arguments)
|
|
32
|
-
* - Validates tool calls (filters out incomplete ones)
|
|
33
|
-
* - Executes tool `execute` functions with parsed arguments
|
|
34
|
-
* - Emits `TOOL_CALL_END` events for client visibility
|
|
35
|
-
* - Returns tool result messages for conversation history
|
|
36
|
-
*
|
|
37
|
-
* This class is used internally by the AI.chat() method to handle the automatic
|
|
38
|
-
* tool execution loop. It can also be used independently for custom tool execution logic.
|
|
39
|
-
*
|
|
40
|
-
* @example
|
|
41
|
-
* ```typescript
|
|
42
|
-
* const manager = new ToolCallManager(tools);
|
|
43
|
-
*
|
|
44
|
-
* // During streaming, accumulate tool calls
|
|
45
|
-
* for await (const chunk of stream) {
|
|
46
|
-
* if (chunk.type === 'TOOL_CALL_START') {
|
|
47
|
-
* manager.addToolCallStartEvent(chunk);
|
|
48
|
-
* } else if (chunk.type === 'TOOL_CALL_ARGS') {
|
|
49
|
-
* manager.addToolCallArgsEvent(chunk);
|
|
50
|
-
* }
|
|
51
|
-
* }
|
|
52
|
-
*
|
|
53
|
-
* // After stream completes, execute tools
|
|
54
|
-
* if (manager.hasToolCalls()) {
|
|
55
|
-
* const toolResults = yield* manager.executeTools(finishEvent);
|
|
56
|
-
* messages = [...messages, ...toolResults];
|
|
57
|
-
* manager.clear();
|
|
58
|
-
* }
|
|
59
|
-
* ```
|
|
60
|
-
*/
|
|
61
|
-
export declare class ToolCallManager<TToolsOrContext = ReadonlyArray<AnyTool>, TContext = TToolsOrContext extends ReadonlyArray<AnyTool> ? ContextFromTools<TToolsOrContext> : TToolsOrContext> {
|
|
62
|
-
private readonly toolCallsMap;
|
|
63
|
-
private readonly tools;
|
|
64
|
-
constructor(tools: TToolsOrContext extends ReadonlyArray<AnyTool> ? TToolsOrContext : ReadonlyArray<AnyTool>);
|
|
65
|
-
/**
|
|
66
|
-
* Add a TOOL_CALL_START event to begin tracking a tool call (AG-UI)
|
|
67
|
-
*/
|
|
68
|
-
addToolCallStartEvent(event: ToolCallStartEvent): void;
|
|
69
|
-
/**
|
|
70
|
-
* Add a TOOL_CALL_ARGS event to accumulate arguments (AG-UI)
|
|
71
|
-
*/
|
|
72
|
-
addToolCallArgsEvent(event: ToolCallArgsEvent): void;
|
|
73
|
-
/**
|
|
74
|
-
* Complete a tool call with its final input
|
|
75
|
-
* Called when TOOL_CALL_END is received
|
|
76
|
-
*/
|
|
77
|
-
completeToolCall(event: ToolCallEndEvent): void;
|
|
78
|
-
/**
|
|
79
|
-
* Check if there are any complete tool calls to execute
|
|
80
|
-
*/
|
|
81
|
-
hasToolCalls(): boolean;
|
|
82
|
-
/**
|
|
83
|
-
* Get all complete tool calls (filtered for valid ID and name)
|
|
84
|
-
*/
|
|
85
|
-
getToolCalls(): Array<ToolCall>;
|
|
86
|
-
/**
|
|
87
|
-
* Execute all tool calls and return tool result messages
|
|
88
|
-
* Yields TOOL_CALL_END events for streaming
|
|
89
|
-
* @param finishEvent - RUN_FINISHED event from the stream
|
|
90
|
-
*/
|
|
91
|
-
executeTools(finishEvent: RunFinishedEvent, ...contextArgs: ExecuteToolsContextArgs<TContext>): AsyncGenerator<ToolCallEndEvent, Array<ModelMessage>, void>;
|
|
92
|
-
/**
|
|
93
|
-
* Clear the tool calls map for the next iteration
|
|
94
|
-
*/
|
|
95
|
-
clear(): void;
|
|
96
|
-
}
|
|
97
|
-
export interface ToolResult {
|
|
98
|
-
toolCallId: string;
|
|
99
|
-
toolName: string;
|
|
100
|
-
result: any;
|
|
101
|
-
state?: 'output-available' | 'output-error';
|
|
102
|
-
/** Duration of tool execution in milliseconds (only for server-executed tools) */
|
|
103
|
-
duration?: number;
|
|
104
|
-
}
|
|
105
|
-
export interface ApprovalRequest {
|
|
106
|
-
toolCallId: string;
|
|
107
|
-
toolName: string;
|
|
108
|
-
input: any;
|
|
109
|
-
approvalId: string;
|
|
110
|
-
}
|
|
111
|
-
export interface ClientToolRequest {
|
|
112
|
-
toolCallId: string;
|
|
113
|
-
toolName: string;
|
|
114
|
-
input: any;
|
|
115
|
-
}
|
|
116
|
-
interface ExecuteToolCallsResult {
|
|
117
|
-
/** Tool results ready to send to LLM */
|
|
118
|
-
results: Array<ToolResult>;
|
|
119
|
-
/** Tools that need user approval before execution */
|
|
120
|
-
needsApproval: Array<ApprovalRequest>;
|
|
121
|
-
/** Tools that need client-side execution */
|
|
122
|
-
needsClientExecution: Array<ClientToolRequest>;
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
* Execute tool calls based on their configuration.
|
|
126
|
-
* Yields CustomEvent chunks during tool execution for real-time progress updates.
|
|
127
|
-
*
|
|
128
|
-
* Handles three cases:
|
|
129
|
-
* 1. Client tools (no execute) - request client to execute
|
|
130
|
-
* 2. Server tools with approval - check approval before executing
|
|
131
|
-
* 3. Normal server tools - execute immediately
|
|
132
|
-
*
|
|
133
|
-
* @param toolCalls - Tool calls from the LLM
|
|
134
|
-
* @param tools - Available tools with their configurations
|
|
135
|
-
* @param approvals - Map of approval decisions (approval.id -> approved boolean)
|
|
136
|
-
* @param clientResults - Map of client-side execution results (toolCallId -> result)
|
|
137
|
-
* @param createCustomEventChunk - Factory to create CustomEvent chunks (optional)
|
|
138
|
-
*/
|
|
139
|
-
export declare function executeToolCalls<TContext = unknown>(toolCalls: Array<ToolCall>, tools: ReadonlyArray<AnyTool>, approvals?: Map<string, boolean>, clientResults?: Map<string, any>, createCustomEventChunk?: (eventName: string, value: Record<string, any>) => CustomEvent, middlewareHooks?: ToolExecutionMiddlewareHooks, userContext?: TContext, abortSignal?: AbortSignal): AsyncGenerator<CustomEvent, ExecuteToolCallsResult, void>;
|
|
140
|
-
export {};
|
|
@@ -1,512 +0,0 @@
|
|
|
1
|
-
import { normalizeToolResult } from "../../../utilities/tool-result.js";
|
|
2
|
-
import { isStandardSchema, parseWithStandardSchema } from "./schema-converter.js";
|
|
3
|
-
function safeJsonParse(value) {
|
|
4
|
-
try {
|
|
5
|
-
return JSON.parse(value);
|
|
6
|
-
} catch {
|
|
7
|
-
return value;
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
class MiddlewareAbortError extends Error {
|
|
11
|
-
constructor(reason) {
|
|
12
|
-
super(reason);
|
|
13
|
-
this.name = "MiddlewareAbortError";
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
class ToolCallManager {
|
|
17
|
-
toolCallsMap = /* @__PURE__ */ new Map();
|
|
18
|
-
tools;
|
|
19
|
-
constructor(tools) {
|
|
20
|
-
this.tools = tools;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Add a TOOL_CALL_START event to begin tracking a tool call (AG-UI)
|
|
24
|
-
*/
|
|
25
|
-
addToolCallStartEvent(event) {
|
|
26
|
-
const index = event.index ?? this.toolCallsMap.size;
|
|
27
|
-
const runtimeEvent = event;
|
|
28
|
-
const name = runtimeEvent.toolCallName ?? runtimeEvent.toolName;
|
|
29
|
-
this.toolCallsMap.set(index, {
|
|
30
|
-
id: event.toolCallId,
|
|
31
|
-
type: "function",
|
|
32
|
-
function: {
|
|
33
|
-
name,
|
|
34
|
-
arguments: ""
|
|
35
|
-
},
|
|
36
|
-
...event.metadata !== void 0 && { metadata: event.metadata }
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Add a TOOL_CALL_ARGS event to accumulate arguments (AG-UI)
|
|
41
|
-
*/
|
|
42
|
-
addToolCallArgsEvent(event) {
|
|
43
|
-
for (const [, toolCall] of this.toolCallsMap.entries()) {
|
|
44
|
-
if (toolCall.id === event.toolCallId) {
|
|
45
|
-
toolCall.function.arguments += event.delta;
|
|
46
|
-
break;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Complete a tool call with its final input
|
|
52
|
-
* Called when TOOL_CALL_END is received
|
|
53
|
-
*/
|
|
54
|
-
completeToolCall(event) {
|
|
55
|
-
for (const [, toolCall] of this.toolCallsMap.entries()) {
|
|
56
|
-
if (toolCall.id === event.toolCallId) {
|
|
57
|
-
if (event.input !== void 0) {
|
|
58
|
-
const normalized = event.input && typeof event.input === "object" ? event.input : {};
|
|
59
|
-
toolCall.function.arguments = JSON.stringify(normalized);
|
|
60
|
-
}
|
|
61
|
-
break;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Check if there are any complete tool calls to execute
|
|
67
|
-
*/
|
|
68
|
-
hasToolCalls() {
|
|
69
|
-
return this.getToolCalls().length > 0;
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Get all complete tool calls (filtered for valid ID and name)
|
|
73
|
-
*/
|
|
74
|
-
getToolCalls() {
|
|
75
|
-
return Array.from(this.toolCallsMap.values()).filter(
|
|
76
|
-
(tc) => tc.id && tc.function.name && tc.function.name.trim().length > 0
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Execute all tool calls and return tool result messages
|
|
81
|
-
* Yields TOOL_CALL_END events for streaming
|
|
82
|
-
* @param finishEvent - RUN_FINISHED event from the stream
|
|
83
|
-
*/
|
|
84
|
-
async *executeTools(finishEvent, ...contextArgs) {
|
|
85
|
-
const toolCallsArray = this.getToolCalls();
|
|
86
|
-
const toolResults = [];
|
|
87
|
-
const hasRuntimeContext = contextArgs.length > 0;
|
|
88
|
-
const userContext = contextArgs[0];
|
|
89
|
-
for (const toolCall of toolCallsArray) {
|
|
90
|
-
const tool = this.tools.find((t) => t.name === toolCall.function.name);
|
|
91
|
-
let toolResultContent;
|
|
92
|
-
let toolResultState;
|
|
93
|
-
if (tool?.execute) {
|
|
94
|
-
try {
|
|
95
|
-
let args;
|
|
96
|
-
try {
|
|
97
|
-
const argsString = toolCall.function.arguments.trim() || "{}";
|
|
98
|
-
const parsed = JSON.parse(argsString);
|
|
99
|
-
args = parsed && typeof parsed === "object" ? parsed : {};
|
|
100
|
-
} catch (parseError) {
|
|
101
|
-
throw new Error(
|
|
102
|
-
`Failed to parse tool arguments as JSON: ${toolCall.function.arguments}`
|
|
103
|
-
);
|
|
104
|
-
}
|
|
105
|
-
if (tool.inputSchema && isStandardSchema(tool.inputSchema)) {
|
|
106
|
-
try {
|
|
107
|
-
args = parseWithStandardSchema(tool.inputSchema, args);
|
|
108
|
-
} catch (validationError) {
|
|
109
|
-
const message = validationError instanceof Error ? validationError.message : "Validation failed";
|
|
110
|
-
throw new Error(
|
|
111
|
-
`Input validation failed for tool ${tool.name}: ${message}`
|
|
112
|
-
);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
const executionContext = {
|
|
116
|
-
toolCallId: toolCall.id,
|
|
117
|
-
context: userContext,
|
|
118
|
-
emitCustomEvent: () => {
|
|
119
|
-
}
|
|
120
|
-
};
|
|
121
|
-
let result = hasRuntimeContext ? await tool.execute(args, executionContext) : await tool.execute(args);
|
|
122
|
-
if (tool.outputSchema && isStandardSchema(tool.outputSchema)) {
|
|
123
|
-
try {
|
|
124
|
-
result = parseWithStandardSchema(tool.outputSchema, result);
|
|
125
|
-
} catch (validationError) {
|
|
126
|
-
const message = validationError instanceof Error ? validationError.message : "Validation failed";
|
|
127
|
-
throw new Error(
|
|
128
|
-
`Output validation failed for tool ${tool.name}: ${message}`
|
|
129
|
-
);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
toolResultContent = normalizeToolResult(result);
|
|
133
|
-
} catch (error) {
|
|
134
|
-
const message = error instanceof Error ? error.message : "Unknown error";
|
|
135
|
-
toolResultContent = `Error executing tool: ${message}`;
|
|
136
|
-
toolResultState = "output-error";
|
|
137
|
-
}
|
|
138
|
-
} else {
|
|
139
|
-
toolResultContent = `Tool ${toolCall.function.name} does not have an execute function`;
|
|
140
|
-
}
|
|
141
|
-
yield {
|
|
142
|
-
type: "TOOL_CALL_END",
|
|
143
|
-
toolCallId: toolCall.id,
|
|
144
|
-
toolCallName: toolCall.function.name,
|
|
145
|
-
toolName: toolCall.function.name,
|
|
146
|
-
model: finishEvent.model,
|
|
147
|
-
timestamp: Date.now(),
|
|
148
|
-
result: toolResultContent,
|
|
149
|
-
...toolResultState !== void 0 && { state: toolResultState }
|
|
150
|
-
};
|
|
151
|
-
toolResults.push({
|
|
152
|
-
role: "tool",
|
|
153
|
-
content: toolResultContent,
|
|
154
|
-
toolCallId: toolCall.id
|
|
155
|
-
});
|
|
156
|
-
}
|
|
157
|
-
return toolResults;
|
|
158
|
-
}
|
|
159
|
-
/**
|
|
160
|
-
* Clear the tool calls map for the next iteration
|
|
161
|
-
*/
|
|
162
|
-
clear() {
|
|
163
|
-
this.toolCallsMap.clear();
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
async function* executeWithEventPolling(executionPromise, pendingEvents) {
|
|
167
|
-
const state = { done: false, result: void 0 };
|
|
168
|
-
const executionWithFlag = executionPromise.then((r) => {
|
|
169
|
-
state.done = true;
|
|
170
|
-
state.result = r;
|
|
171
|
-
return r;
|
|
172
|
-
});
|
|
173
|
-
while (!state.done) {
|
|
174
|
-
await Promise.race([
|
|
175
|
-
executionWithFlag,
|
|
176
|
-
new Promise((resolve) => setTimeout(resolve, 10))
|
|
177
|
-
]);
|
|
178
|
-
let event2;
|
|
179
|
-
while ((event2 = pendingEvents.shift()) !== void 0) {
|
|
180
|
-
yield event2;
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
let event;
|
|
184
|
-
while ((event = pendingEvents.shift()) !== void 0) {
|
|
185
|
-
yield event;
|
|
186
|
-
}
|
|
187
|
-
return state.result;
|
|
188
|
-
}
|
|
189
|
-
async function applyBeforeToolCallDecision(toolCall, tool, input, toolName, middlewareHooks, results) {
|
|
190
|
-
if (!middlewareHooks.onBeforeToolCall) {
|
|
191
|
-
return { proceed: true, input };
|
|
192
|
-
}
|
|
193
|
-
const decision = await middlewareHooks.onBeforeToolCall(toolCall, tool, input);
|
|
194
|
-
if (!decision) {
|
|
195
|
-
return { proceed: true, input };
|
|
196
|
-
}
|
|
197
|
-
if (decision.type === "abort") {
|
|
198
|
-
throw new MiddlewareAbortError(decision.reason || "Aborted by middleware");
|
|
199
|
-
}
|
|
200
|
-
if (decision.type === "skip") {
|
|
201
|
-
const skipResult = decision.result;
|
|
202
|
-
results.push({
|
|
203
|
-
toolCallId: toolCall.id,
|
|
204
|
-
toolName,
|
|
205
|
-
result: typeof skipResult === "string" ? safeJsonParse(skipResult) : skipResult ?? null,
|
|
206
|
-
duration: 0
|
|
207
|
-
});
|
|
208
|
-
if (middlewareHooks.onAfterToolCall) {
|
|
209
|
-
await middlewareHooks.onAfterToolCall({
|
|
210
|
-
toolCall,
|
|
211
|
-
tool,
|
|
212
|
-
toolName,
|
|
213
|
-
toolCallId: toolCall.id,
|
|
214
|
-
ok: true,
|
|
215
|
-
duration: 0,
|
|
216
|
-
result: skipResult
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
return { proceed: false };
|
|
220
|
-
}
|
|
221
|
-
return { proceed: true, input: decision.args };
|
|
222
|
-
}
|
|
223
|
-
async function* executeServerTool(toolCall, tool, toolName, input, context, pendingEvents, results, middlewareHooks) {
|
|
224
|
-
const startTime = Date.now();
|
|
225
|
-
try {
|
|
226
|
-
if (!tool.execute) {
|
|
227
|
-
throw new Error(`Tool ${toolName} has no execute() implementation`);
|
|
228
|
-
}
|
|
229
|
-
const executionPromise = Promise.resolve(tool.execute(input, context));
|
|
230
|
-
let result = yield* executeWithEventPolling(executionPromise, pendingEvents);
|
|
231
|
-
const duration = Date.now() - startTime;
|
|
232
|
-
let pendingEvent;
|
|
233
|
-
while ((pendingEvent = pendingEvents.shift()) !== void 0) {
|
|
234
|
-
yield pendingEvent;
|
|
235
|
-
}
|
|
236
|
-
if (tool.outputSchema && isStandardSchema(tool.outputSchema)) {
|
|
237
|
-
result = parseWithStandardSchema(tool.outputSchema, result);
|
|
238
|
-
}
|
|
239
|
-
const finalResult = typeof result === "string" ? safeJsonParse(result) : result ?? null;
|
|
240
|
-
results.push({
|
|
241
|
-
toolCallId: toolCall.id,
|
|
242
|
-
toolName,
|
|
243
|
-
result: finalResult,
|
|
244
|
-
duration
|
|
245
|
-
});
|
|
246
|
-
if (middlewareHooks?.onAfterToolCall) {
|
|
247
|
-
await middlewareHooks.onAfterToolCall({
|
|
248
|
-
toolCall,
|
|
249
|
-
tool,
|
|
250
|
-
toolName,
|
|
251
|
-
toolCallId: toolCall.id,
|
|
252
|
-
ok: true,
|
|
253
|
-
duration,
|
|
254
|
-
result: finalResult
|
|
255
|
-
});
|
|
256
|
-
}
|
|
257
|
-
} catch (error) {
|
|
258
|
-
const duration = Date.now() - startTime;
|
|
259
|
-
let pendingEvent;
|
|
260
|
-
while ((pendingEvent = pendingEvents.shift()) !== void 0) {
|
|
261
|
-
yield pendingEvent;
|
|
262
|
-
}
|
|
263
|
-
if (error instanceof MiddlewareAbortError) {
|
|
264
|
-
throw error;
|
|
265
|
-
}
|
|
266
|
-
const message = error instanceof Error ? error.message : "Unknown error";
|
|
267
|
-
results.push({
|
|
268
|
-
toolCallId: toolCall.id,
|
|
269
|
-
toolName,
|
|
270
|
-
result: { error: message },
|
|
271
|
-
state: "output-error",
|
|
272
|
-
duration
|
|
273
|
-
});
|
|
274
|
-
if (middlewareHooks?.onAfterToolCall) {
|
|
275
|
-
await middlewareHooks.onAfterToolCall({
|
|
276
|
-
toolCall,
|
|
277
|
-
tool,
|
|
278
|
-
toolName,
|
|
279
|
-
toolCallId: toolCall.id,
|
|
280
|
-
ok: false,
|
|
281
|
-
duration,
|
|
282
|
-
error
|
|
283
|
-
});
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
function buildClientToolResult(toolCallId, toolName, tool, rawResult) {
|
|
288
|
-
try {
|
|
289
|
-
let result = rawResult;
|
|
290
|
-
if (tool.outputSchema && isStandardSchema(tool.outputSchema)) {
|
|
291
|
-
result = parseWithStandardSchema(tool.outputSchema, result);
|
|
292
|
-
}
|
|
293
|
-
return {
|
|
294
|
-
toolCallId,
|
|
295
|
-
toolName,
|
|
296
|
-
result: typeof result === "string" ? safeJsonParse(result) : result ?? null
|
|
297
|
-
};
|
|
298
|
-
} catch (error) {
|
|
299
|
-
const message = error instanceof Error ? error.message : "Validation failed";
|
|
300
|
-
return {
|
|
301
|
-
toolCallId,
|
|
302
|
-
toolName,
|
|
303
|
-
result: { error: message },
|
|
304
|
-
state: "output-error"
|
|
305
|
-
};
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
async function* executeToolCalls(toolCalls, tools, approvals = /* @__PURE__ */ new Map(), clientResults = /* @__PURE__ */ new Map(), createCustomEventChunk, middlewareHooks, userContext, abortSignal) {
|
|
309
|
-
const results = [];
|
|
310
|
-
const needsApproval = [];
|
|
311
|
-
const needsClientExecution = [];
|
|
312
|
-
const toolMap = /* @__PURE__ */ new Map();
|
|
313
|
-
for (const tool of tools) {
|
|
314
|
-
toolMap.set(tool.name, tool);
|
|
315
|
-
}
|
|
316
|
-
const hasPendingApprovals = toolCalls.some((tc) => {
|
|
317
|
-
const t = toolMap.get(tc.function.name);
|
|
318
|
-
return t?.needsApproval && !approvals.has(`approval_${tc.id}`);
|
|
319
|
-
});
|
|
320
|
-
for (const toolCall of toolCalls) {
|
|
321
|
-
const tool = toolMap.get(toolCall.function.name);
|
|
322
|
-
const toolName = toolCall.function.name;
|
|
323
|
-
if (!tool) {
|
|
324
|
-
results.push({
|
|
325
|
-
toolCallId: toolCall.id,
|
|
326
|
-
toolName,
|
|
327
|
-
result: { error: `Unknown tool: ${toolName}` },
|
|
328
|
-
state: "output-error"
|
|
329
|
-
});
|
|
330
|
-
continue;
|
|
331
|
-
}
|
|
332
|
-
if (hasPendingApprovals) {
|
|
333
|
-
if (!tool.needsApproval || approvals.has(`approval_${toolCall.id}`)) {
|
|
334
|
-
continue;
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
let input = {};
|
|
338
|
-
const argsStr = toolCall.function.arguments.trim() || "{}";
|
|
339
|
-
{
|
|
340
|
-
try {
|
|
341
|
-
const parsed = JSON.parse(argsStr);
|
|
342
|
-
input = parsed && typeof parsed === "object" ? parsed : {};
|
|
343
|
-
} catch (parseError) {
|
|
344
|
-
throw new Error(`Failed to parse tool arguments as JSON: ${argsStr}`);
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
if (tool.inputSchema && isStandardSchema(tool.inputSchema)) {
|
|
348
|
-
try {
|
|
349
|
-
input = parseWithStandardSchema(tool.inputSchema, input);
|
|
350
|
-
} catch (validationError) {
|
|
351
|
-
const message = validationError instanceof Error ? validationError.message : "Validation failed";
|
|
352
|
-
results.push({
|
|
353
|
-
toolCallId: toolCall.id,
|
|
354
|
-
toolName,
|
|
355
|
-
result: {
|
|
356
|
-
error: `Input validation failed for tool ${tool.name}: ${message}`
|
|
357
|
-
},
|
|
358
|
-
state: "output-error"
|
|
359
|
-
});
|
|
360
|
-
continue;
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
const pendingEvents = [];
|
|
364
|
-
const context = {
|
|
365
|
-
toolCallId: toolCall.id,
|
|
366
|
-
context: userContext,
|
|
367
|
-
abortSignal,
|
|
368
|
-
emitCustomEvent: (eventName, value) => {
|
|
369
|
-
if (createCustomEventChunk) {
|
|
370
|
-
pendingEvents.push(
|
|
371
|
-
createCustomEventChunk(eventName, {
|
|
372
|
-
...value,
|
|
373
|
-
toolCallId: toolCall.id
|
|
374
|
-
})
|
|
375
|
-
);
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
};
|
|
379
|
-
if (!tool.execute) {
|
|
380
|
-
if (tool.needsApproval) {
|
|
381
|
-
const approvalId = `approval_${toolCall.id}`;
|
|
382
|
-
if (approvals.has(approvalId)) {
|
|
383
|
-
const approved = approvals.get(approvalId);
|
|
384
|
-
if (approved) {
|
|
385
|
-
if (clientResults.has(toolCall.id)) {
|
|
386
|
-
results.push(
|
|
387
|
-
buildClientToolResult(
|
|
388
|
-
toolCall.id,
|
|
389
|
-
toolName,
|
|
390
|
-
tool,
|
|
391
|
-
clientResults.get(toolCall.id)
|
|
392
|
-
)
|
|
393
|
-
);
|
|
394
|
-
} else {
|
|
395
|
-
needsClientExecution.push({
|
|
396
|
-
toolCallId: toolCall.id,
|
|
397
|
-
toolName,
|
|
398
|
-
input
|
|
399
|
-
});
|
|
400
|
-
}
|
|
401
|
-
} else {
|
|
402
|
-
results.push({
|
|
403
|
-
toolCallId: toolCall.id,
|
|
404
|
-
toolName,
|
|
405
|
-
result: { error: "User declined tool execution" },
|
|
406
|
-
state: "output-error"
|
|
407
|
-
});
|
|
408
|
-
}
|
|
409
|
-
} else {
|
|
410
|
-
needsApproval.push({
|
|
411
|
-
toolCallId: toolCall.id,
|
|
412
|
-
toolName: toolCall.function.name,
|
|
413
|
-
input,
|
|
414
|
-
approvalId
|
|
415
|
-
});
|
|
416
|
-
}
|
|
417
|
-
} else {
|
|
418
|
-
if (clientResults.has(toolCall.id)) {
|
|
419
|
-
results.push(
|
|
420
|
-
buildClientToolResult(
|
|
421
|
-
toolCall.id,
|
|
422
|
-
toolName,
|
|
423
|
-
tool,
|
|
424
|
-
clientResults.get(toolCall.id)
|
|
425
|
-
)
|
|
426
|
-
);
|
|
427
|
-
} else {
|
|
428
|
-
needsClientExecution.push({
|
|
429
|
-
toolCallId: toolCall.id,
|
|
430
|
-
toolName,
|
|
431
|
-
input
|
|
432
|
-
});
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
continue;
|
|
436
|
-
}
|
|
437
|
-
if (tool.needsApproval) {
|
|
438
|
-
const approvalId = `approval_${toolCall.id}`;
|
|
439
|
-
if (approvals.has(approvalId)) {
|
|
440
|
-
const approved = approvals.get(approvalId);
|
|
441
|
-
if (approved) {
|
|
442
|
-
if (middlewareHooks) {
|
|
443
|
-
const decision = await applyBeforeToolCallDecision(
|
|
444
|
-
toolCall,
|
|
445
|
-
tool,
|
|
446
|
-
input,
|
|
447
|
-
toolName,
|
|
448
|
-
middlewareHooks,
|
|
449
|
-
results
|
|
450
|
-
);
|
|
451
|
-
if (!decision.proceed) continue;
|
|
452
|
-
input = decision.input;
|
|
453
|
-
}
|
|
454
|
-
yield* executeServerTool(
|
|
455
|
-
toolCall,
|
|
456
|
-
tool,
|
|
457
|
-
toolName,
|
|
458
|
-
input,
|
|
459
|
-
context,
|
|
460
|
-
pendingEvents,
|
|
461
|
-
results,
|
|
462
|
-
middlewareHooks
|
|
463
|
-
);
|
|
464
|
-
} else {
|
|
465
|
-
results.push({
|
|
466
|
-
toolCallId: toolCall.id,
|
|
467
|
-
toolName,
|
|
468
|
-
result: { error: "User declined tool execution" },
|
|
469
|
-
state: "output-error"
|
|
470
|
-
});
|
|
471
|
-
}
|
|
472
|
-
} else {
|
|
473
|
-
needsApproval.push({
|
|
474
|
-
toolCallId: toolCall.id,
|
|
475
|
-
toolName,
|
|
476
|
-
input,
|
|
477
|
-
approvalId
|
|
478
|
-
});
|
|
479
|
-
}
|
|
480
|
-
continue;
|
|
481
|
-
}
|
|
482
|
-
if (middlewareHooks) {
|
|
483
|
-
const decision = await applyBeforeToolCallDecision(
|
|
484
|
-
toolCall,
|
|
485
|
-
tool,
|
|
486
|
-
input,
|
|
487
|
-
toolName,
|
|
488
|
-
middlewareHooks,
|
|
489
|
-
results
|
|
490
|
-
);
|
|
491
|
-
if (!decision.proceed) continue;
|
|
492
|
-
input = decision.input;
|
|
493
|
-
}
|
|
494
|
-
yield* executeServerTool(
|
|
495
|
-
toolCall,
|
|
496
|
-
tool,
|
|
497
|
-
toolName,
|
|
498
|
-
input,
|
|
499
|
-
context,
|
|
500
|
-
pendingEvents,
|
|
501
|
-
results,
|
|
502
|
-
middlewareHooks
|
|
503
|
-
);
|
|
504
|
-
}
|
|
505
|
-
return { results, needsApproval, needsClientExecution };
|
|
506
|
-
}
|
|
507
|
-
export {
|
|
508
|
-
MiddlewareAbortError,
|
|
509
|
-
ToolCallManager,
|
|
510
|
-
executeToolCalls
|
|
511
|
-
};
|
|
512
|
-
//# sourceMappingURL=tool-calls.js.map
|