agents 0.0.0-295f4dd → 0.0.0-29938d4
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/README.md +121 -0
- package/dist/ai-chat-agent.d.ts +142 -17
- package/dist/ai-chat-agent.js +346 -40
- package/dist/ai-chat-agent.js.map +1 -1
- package/dist/ai-chat-v5-migration.js +154 -2
- package/dist/ai-chat-v5-migration.js.map +1 -0
- package/dist/ai-react.d.ts +136 -17
- package/dist/ai-react.js +216 -53
- package/dist/ai-react.js.map +1 -1
- package/dist/{ai-types-D_hTbf25.d.ts → ai-types-0OnT3FHg.d.ts} +26 -2
- package/dist/{ai-types-CwgHzwUb.js → ai-types-DEtF_8Km.js} +5 -1
- package/dist/ai-types-DEtF_8Km.js.map +1 -0
- package/dist/ai-types.d.ts +1 -1
- package/dist/ai-types.js +1 -1
- package/dist/{client-ClORm6f0.d.ts → client-CdM5I962.d.ts} +2 -2
- package/dist/{client-C_M5uPrn.d.ts → client-DFotUKH_.d.ts} +9 -9
- package/dist/{client-CcyhkGfN.js → client-DjTPRM8-.js} +2 -2
- package/dist/{client-CcyhkGfN.js.map → client-DjTPRM8-.js.map} +1 -1
- package/dist/client.d.ts +1 -2
- package/dist/client.js +1 -2
- package/dist/codemode/ai.js +3 -4
- package/dist/codemode/ai.js.map +1 -1
- package/dist/{context-_sPQqJWv.d.ts → context-DcbQ8o7k.d.ts} +1 -1
- package/dist/context.d.ts +1 -1
- package/dist/{do-oauth-client-provider-B-ryFIPr.d.ts → do-oauth-client-provider--To1Tsjj.d.ts} +1 -1
- package/dist/{index-DUnsVDnf.d.ts → index-CT2tCrLr.d.ts} +14 -14
- package/dist/{index-CyDpAVHZ.d.ts → index-DLuxm_9W.d.ts} +2 -2
- package/dist/index.d.ts +4 -7
- package/dist/index.js +2 -3
- package/dist/mcp/client.d.ts +1 -3
- package/dist/mcp/do-oauth-client-provider.d.ts +1 -1
- package/dist/mcp/index.d.ts +18 -12
- package/dist/mcp/index.js +21 -49
- package/dist/mcp/index.js.map +1 -1
- package/dist/{mcp-CzbSsLfc.d.ts → mcp-CPSfGUgd.d.ts} +1 -1
- package/dist/observability/index.d.ts +1 -2
- package/dist/observability/index.js +2 -3
- package/dist/react.d.ts +133 -14
- package/dist/react.js +50 -57
- package/dist/react.js.map +1 -1
- package/dist/schedule.d.ts +18 -72
- package/dist/{serializable-C4GLimgv.d.ts → serializable-Crsj26mx.d.ts} +1 -1
- package/dist/serializable.d.ts +1 -1
- package/dist/{src-BmbDclOA.js → src-BZDh910Z.js} +3 -3
- package/dist/src-BZDh910Z.js.map +1 -0
- package/package.json +28 -13
- package/dist/ai-chat-v5-migration-DguhuLKF.js +0 -155
- package/dist/ai-chat-v5-migration-DguhuLKF.js.map +0 -1
- package/dist/ai-types-CwgHzwUb.js.map +0 -1
- package/dist/react-DIGWa87z.d.ts +0 -137
- package/dist/src-BmbDclOA.js.map +0 -1
package/dist/ai-react.d.ts
CHANGED
|
@@ -1,22 +1,64 @@
|
|
|
1
|
-
import "./context-
|
|
2
|
-
import "./client-
|
|
3
|
-
import "./
|
|
4
|
-
import "./
|
|
5
|
-
import "./
|
|
6
|
-
import "./
|
|
7
|
-
import "
|
|
8
|
-
import "./serializable-C4GLimgv.js";
|
|
9
|
-
import "./client-ClORm6f0.js";
|
|
10
|
-
import { r as useAgent } from "./react-DIGWa87z.js";
|
|
1
|
+
import "./context-DcbQ8o7k.js";
|
|
2
|
+
import "./client-DFotUKH_.js";
|
|
3
|
+
import "./ai-types-0OnT3FHg.js";
|
|
4
|
+
import "./index-CT2tCrLr.js";
|
|
5
|
+
import "./client-CdM5I962.js";
|
|
6
|
+
import { useAgent } from "./react.js";
|
|
7
|
+
import { ChatInit, JSONSchema7, Tool, UIMessage } from "ai";
|
|
11
8
|
import { UseChatOptions, useChat } from "@ai-sdk/react";
|
|
12
|
-
import { ChatInit, UIMessage } from "ai";
|
|
13
9
|
|
|
14
10
|
//#region src/ai-react.d.ts
|
|
11
|
+
/**
|
|
12
|
+
* JSON Schema type for tool parameters.
|
|
13
|
+
* Re-exported from the AI SDK for convenience.
|
|
14
|
+
* @deprecated Import JSONSchema7 directly from "ai" instead.
|
|
15
|
+
*/
|
|
16
|
+
type JSONSchemaType = JSONSchema7;
|
|
17
|
+
/**
|
|
18
|
+
* Definition for a tool that can be executed on the client.
|
|
19
|
+
* Tools with an `execute` function are automatically registered with the server.
|
|
20
|
+
*
|
|
21
|
+
* Note: Uses `parameters` (JSONSchema7) rather than AI SDK's `inputSchema` (FlexibleSchema)
|
|
22
|
+
* because client tools must be serializable for the wire format. Zod schemas cannot be
|
|
23
|
+
* serialized, so we require raw JSON Schema here.
|
|
24
|
+
*/
|
|
15
25
|
type AITool<Input = unknown, Output = unknown> = {
|
|
16
|
-
description
|
|
17
|
-
|
|
26
|
+
/** Human-readable description of what the tool does */
|
|
27
|
+
description?: Tool["description"];
|
|
28
|
+
/** JSON Schema defining the tool's input parameters */
|
|
29
|
+
parameters?: JSONSchema7;
|
|
30
|
+
/**
|
|
31
|
+
* @deprecated Use `parameters` instead. Will be removed in a future version.
|
|
32
|
+
*/
|
|
33
|
+
inputSchema?: JSONSchema7;
|
|
34
|
+
/**
|
|
35
|
+
* Function to execute the tool on the client.
|
|
36
|
+
* If provided, the tool schema is automatically sent to the server.
|
|
37
|
+
*/
|
|
18
38
|
execute?: (input: Input) => Output | Promise<Output>;
|
|
19
39
|
};
|
|
40
|
+
/**
|
|
41
|
+
* Schema for a client tool sent to the server.
|
|
42
|
+
* This is the wire format - what gets sent in the request body.
|
|
43
|
+
* Must match the server-side ClientToolSchema type in ai-chat-agent.ts.
|
|
44
|
+
*/
|
|
45
|
+
type ClientToolSchema = {
|
|
46
|
+
/** Unique name for the tool */
|
|
47
|
+
name: string;
|
|
48
|
+
/** Human-readable description of what the tool does */
|
|
49
|
+
description?: Tool["description"];
|
|
50
|
+
/** JSON Schema defining the tool's input parameters */
|
|
51
|
+
parameters?: JSONSchema7;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Extracts tool schemas from tools that have client-side execute functions.
|
|
55
|
+
* These schemas are automatically sent to the server with each request.
|
|
56
|
+
* @param tools - Record of tool name to tool definition
|
|
57
|
+
* @returns Array of tool schemas to send to server, or undefined if none
|
|
58
|
+
*/
|
|
59
|
+
declare function extractClientToolSchemas(
|
|
60
|
+
tools?: Record<string, AITool<unknown, unknown>>
|
|
61
|
+
): ClientToolSchema[] | undefined;
|
|
20
62
|
type GetInitialMessagesOptions = {
|
|
21
63
|
agent: string;
|
|
22
64
|
name: string;
|
|
@@ -24,6 +66,47 @@ type GetInitialMessagesOptions = {
|
|
|
24
66
|
};
|
|
25
67
|
type UseChatParams<M extends UIMessage = UIMessage> = ChatInit<M> &
|
|
26
68
|
UseChatOptions<M>;
|
|
69
|
+
/**
|
|
70
|
+
* Options for preparing the send messages request.
|
|
71
|
+
* Used by prepareSendMessagesRequest callback.
|
|
72
|
+
*/
|
|
73
|
+
type PrepareSendMessagesRequestOptions<
|
|
74
|
+
ChatMessage extends UIMessage = UIMessage
|
|
75
|
+
> = {
|
|
76
|
+
/** The chat ID */
|
|
77
|
+
id: string;
|
|
78
|
+
/** Messages to send */
|
|
79
|
+
messages: ChatMessage[];
|
|
80
|
+
/** What triggered this request */
|
|
81
|
+
trigger: "submit-message" | "regenerate-message";
|
|
82
|
+
/** ID of the message being sent (if applicable) */
|
|
83
|
+
messageId?: string;
|
|
84
|
+
/** Request metadata */
|
|
85
|
+
requestMetadata?: unknown;
|
|
86
|
+
/** Current body (if any) */
|
|
87
|
+
body?: Record<string, unknown>;
|
|
88
|
+
/** Current credentials (if any) */
|
|
89
|
+
credentials?: RequestCredentials;
|
|
90
|
+
/** Current headers (if any) */
|
|
91
|
+
headers?: HeadersInit;
|
|
92
|
+
/** API endpoint */
|
|
93
|
+
api?: string;
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Return type for prepareSendMessagesRequest callback.
|
|
97
|
+
* Allows customizing headers, body, and credentials for each request.
|
|
98
|
+
* All fields are optional; only specify what you need to customize.
|
|
99
|
+
*/
|
|
100
|
+
type PrepareSendMessagesRequestResult = {
|
|
101
|
+
/** Custom headers to send with the request */
|
|
102
|
+
headers?: HeadersInit;
|
|
103
|
+
/** Custom body data to merge with the request */
|
|
104
|
+
body?: Record<string, unknown>;
|
|
105
|
+
/** Custom credentials option */
|
|
106
|
+
credentials?: RequestCredentials;
|
|
107
|
+
/** Custom API endpoint */
|
|
108
|
+
api?: string;
|
|
109
|
+
};
|
|
27
110
|
/**
|
|
28
111
|
* Options for the useAgentChat hook
|
|
29
112
|
*/
|
|
@@ -47,18 +130,33 @@ type UseAgentChatOptions<
|
|
|
47
130
|
*/
|
|
48
131
|
experimental_automaticToolResolution?: boolean;
|
|
49
132
|
/**
|
|
50
|
-
*
|
|
51
|
-
* Tools without execute function will require confirmation.
|
|
133
|
+
* Tools that can be executed on the client.
|
|
52
134
|
*/
|
|
53
135
|
tools?: Record<string, AITool<unknown, unknown>>;
|
|
54
136
|
/**
|
|
55
137
|
* @description Manual override for tools requiring confirmation.
|
|
56
|
-
* If not provided, will auto-detect from tools object.
|
|
138
|
+
* If not provided, will auto-detect from tools object (tools without execute require confirmation).
|
|
57
139
|
*/
|
|
58
140
|
toolsRequiringConfirmation?: string[];
|
|
141
|
+
/**
|
|
142
|
+
* When true, the server automatically continues the conversation after
|
|
143
|
+
* receiving client-side tool results, similar to how server-executed tools
|
|
144
|
+
* work with maxSteps in streamText. The continuation is merged into the
|
|
145
|
+
* same assistant message.
|
|
146
|
+
*
|
|
147
|
+
* When false (default), the client calls sendMessage() after tool results
|
|
148
|
+
* to continue the conversation, which creates a new assistant message.
|
|
149
|
+
*
|
|
150
|
+
* @default false
|
|
151
|
+
*/
|
|
152
|
+
autoContinueAfterToolResult?: boolean;
|
|
59
153
|
/**
|
|
60
154
|
* When true (default), automatically sends the next message only after
|
|
61
155
|
* all pending confirmation-required tool calls have been resolved.
|
|
156
|
+
* When false, sends immediately after each tool result.
|
|
157
|
+
*
|
|
158
|
+
* Only applies when `autoContinueAfterToolResult` is false.
|
|
159
|
+
*
|
|
62
160
|
* @default true
|
|
63
161
|
*/
|
|
64
162
|
autoSendAfterAllConfirmationsResolved?: boolean;
|
|
@@ -67,6 +165,18 @@ type UseAgentChatOptions<
|
|
|
67
165
|
* @default true
|
|
68
166
|
*/
|
|
69
167
|
resume?: boolean;
|
|
168
|
+
/**
|
|
169
|
+
* Callback to customize the request before sending messages.
|
|
170
|
+
* Use this for advanced scenarios like adding custom headers or dynamic context.
|
|
171
|
+
*
|
|
172
|
+
* Note: Client tool schemas are automatically sent when tools have `execute` functions.
|
|
173
|
+
* This callback can add additional data alongside the auto-extracted schemas.
|
|
174
|
+
*/
|
|
175
|
+
prepareSendMessagesRequest?: (
|
|
176
|
+
options: PrepareSendMessagesRequestOptions<ChatMessage>
|
|
177
|
+
) =>
|
|
178
|
+
| PrepareSendMessagesRequestResult
|
|
179
|
+
| Promise<PrepareSendMessagesRequestResult>;
|
|
70
180
|
};
|
|
71
181
|
/**
|
|
72
182
|
* React hook for building AI chat interfaces using an Agent
|
|
@@ -91,5 +201,14 @@ declare function useAgentChat<
|
|
|
91
201
|
clearHistory: () => void;
|
|
92
202
|
};
|
|
93
203
|
//#endregion
|
|
94
|
-
export {
|
|
204
|
+
export {
|
|
205
|
+
AITool,
|
|
206
|
+
ClientToolSchema,
|
|
207
|
+
JSONSchemaType,
|
|
208
|
+
PrepareSendMessagesRequestOptions,
|
|
209
|
+
PrepareSendMessagesRequestResult,
|
|
210
|
+
detectToolsRequiringConfirmation,
|
|
211
|
+
extractClientToolSchemas,
|
|
212
|
+
useAgentChat
|
|
213
|
+
};
|
|
95
214
|
//# sourceMappingURL=ai-react.d.ts.map
|
package/dist/ai-react.js
CHANGED
|
@@ -1,10 +1,28 @@
|
|
|
1
|
-
import { t as MessageType } from "./ai-types-
|
|
1
|
+
import { t as MessageType } from "./ai-types-DEtF_8Km.js";
|
|
2
|
+
import { DefaultChatTransport, getToolName, isToolUIPart } from "ai";
|
|
2
3
|
import { nanoid } from "nanoid";
|
|
3
4
|
import { useChat } from "@ai-sdk/react";
|
|
4
|
-
import {
|
|
5
|
-
import { use, useCallback, useEffect, useMemo, useRef } from "react";
|
|
5
|
+
import { use, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
6
6
|
|
|
7
7
|
//#region src/ai-react.tsx
|
|
8
|
+
/**
|
|
9
|
+
* Extracts tool schemas from tools that have client-side execute functions.
|
|
10
|
+
* These schemas are automatically sent to the server with each request.
|
|
11
|
+
* @param tools - Record of tool name to tool definition
|
|
12
|
+
* @returns Array of tool schemas to send to server, or undefined if none
|
|
13
|
+
*/
|
|
14
|
+
function extractClientToolSchemas(tools) {
|
|
15
|
+
if (!tools) return void 0;
|
|
16
|
+
const schemas = Object.entries(tools).filter(([_, tool$1]) => tool$1.execute).map(([name, tool$1]) => {
|
|
17
|
+
if (tool$1.inputSchema && !tool$1.parameters) console.warn(`[useAgentChat] Tool "${name}" uses deprecated 'inputSchema'. Please migrate to 'parameters'.`);
|
|
18
|
+
return {
|
|
19
|
+
name,
|
|
20
|
+
description: tool$1.description,
|
|
21
|
+
parameters: tool$1.parameters ?? tool$1.inputSchema
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
return schemas.length > 0 ? schemas : void 0;
|
|
25
|
+
}
|
|
8
26
|
const requestCache = /* @__PURE__ */ new Map();
|
|
9
27
|
/**
|
|
10
28
|
* React hook for building AI chat interfaces using an Agent
|
|
@@ -22,7 +40,7 @@ function detectToolsRequiringConfirmation(tools) {
|
|
|
22
40
|
return Object.entries(tools).filter(([_name, tool$1]) => !tool$1.execute).map(([name]) => name);
|
|
23
41
|
}
|
|
24
42
|
function useAgentChat(options) {
|
|
25
|
-
const { agent, getInitialMessages, messages: optionsInitialMessages, experimental_automaticToolResolution, tools, toolsRequiringConfirmation: manualToolsRequiringConfirmation, autoSendAfterAllConfirmationsResolved = true, resume = true, ...rest } = options;
|
|
43
|
+
const { agent, getInitialMessages, messages: optionsInitialMessages, experimental_automaticToolResolution, tools, toolsRequiringConfirmation: manualToolsRequiringConfirmation, autoContinueAfterToolResult = false, autoSendAfterAllConfirmationsResolved = true, resume = true, prepareSendMessagesRequest, ...rest } = options;
|
|
26
44
|
const toolsRequiringConfirmation = manualToolsRequiringConfirmation ?? detectToolsRequiringConfirmation(tools);
|
|
27
45
|
const agentUrl = new URL(`${(agent._url || agent._pkurl)?.replace("ws://", "http://").replace("wss://", "https://")}`);
|
|
28
46
|
agentUrl.searchParams.delete("_pk");
|
|
@@ -142,12 +160,45 @@ function useAgentChat(options) {
|
|
|
142
160
|
}));
|
|
143
161
|
return new Response(stream);
|
|
144
162
|
}, []);
|
|
163
|
+
const toolsRef = useRef(tools);
|
|
164
|
+
toolsRef.current = tools;
|
|
165
|
+
const prepareSendMessagesRequestRef = useRef(prepareSendMessagesRequest);
|
|
166
|
+
prepareSendMessagesRequestRef.current = prepareSendMessagesRequest;
|
|
145
167
|
const customTransport = useMemo(() => ({
|
|
146
|
-
sendMessages: async (
|
|
168
|
+
sendMessages: async (sendMessageOptions) => {
|
|
169
|
+
const clientToolSchemas = extractClientToolSchemas(toolsRef.current);
|
|
147
170
|
return new DefaultChatTransport({
|
|
148
171
|
api: agentUrlString,
|
|
149
|
-
fetch: aiFetch
|
|
150
|
-
|
|
172
|
+
fetch: aiFetch,
|
|
173
|
+
prepareSendMessagesRequest: clientToolSchemas || prepareSendMessagesRequestRef.current ? async (prepareOptions) => {
|
|
174
|
+
let body = {};
|
|
175
|
+
let headers;
|
|
176
|
+
let credentials;
|
|
177
|
+
let api;
|
|
178
|
+
if (clientToolSchemas) body = {
|
|
179
|
+
id: prepareOptions.id,
|
|
180
|
+
messages: prepareOptions.messages,
|
|
181
|
+
trigger: prepareOptions.trigger,
|
|
182
|
+
clientTools: clientToolSchemas
|
|
183
|
+
};
|
|
184
|
+
if (prepareSendMessagesRequestRef.current) {
|
|
185
|
+
const userResult = await prepareSendMessagesRequestRef.current(prepareOptions);
|
|
186
|
+
headers = userResult.headers;
|
|
187
|
+
credentials = userResult.credentials;
|
|
188
|
+
api = userResult.api;
|
|
189
|
+
body = {
|
|
190
|
+
...body,
|
|
191
|
+
...userResult.body ?? {}
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
return {
|
|
195
|
+
body,
|
|
196
|
+
headers,
|
|
197
|
+
credentials,
|
|
198
|
+
api
|
|
199
|
+
};
|
|
200
|
+
} : void 0
|
|
201
|
+
}).sendMessages(sendMessageOptions);
|
|
151
202
|
},
|
|
152
203
|
reconnectToStream: async () => null
|
|
153
204
|
}), [agentUrlString, aiFetch]);
|
|
@@ -158,6 +209,10 @@ function useAgentChat(options) {
|
|
|
158
209
|
id: agent._pk
|
|
159
210
|
});
|
|
160
211
|
const processedToolCalls = useRef(/* @__PURE__ */ new Set());
|
|
212
|
+
const isResolvingToolsRef = useRef(false);
|
|
213
|
+
const [clientToolResults, setClientToolResults] = useState(/* @__PURE__ */ new Map());
|
|
214
|
+
const messagesRef = useRef(useChatHelpers.messages);
|
|
215
|
+
messagesRef.current = useChatHelpers.messages;
|
|
161
216
|
const lastMessage = useChatHelpers.messages[useChatHelpers.messages.length - 1];
|
|
162
217
|
const pendingConfirmations = (() => {
|
|
163
218
|
if (!lastMessage || lastMessage.role !== "assistant") return {
|
|
@@ -175,37 +230,65 @@ function useAgentChat(options) {
|
|
|
175
230
|
pendingConfirmationsRef.current = pendingConfirmations;
|
|
176
231
|
useEffect(() => {
|
|
177
232
|
if (!experimental_automaticToolResolution) return;
|
|
233
|
+
if (isResolvingToolsRef.current) return;
|
|
178
234
|
const lastMessage$1 = useChatHelpers.messages[useChatHelpers.messages.length - 1];
|
|
179
235
|
if (!lastMessage$1 || lastMessage$1.role !== "assistant") return;
|
|
180
236
|
const toolCalls = lastMessage$1.parts.filter((part) => isToolUIPart(part) && part.state === "input-available" && !processedToolCalls.current.has(part.toolCallId));
|
|
181
|
-
if (toolCalls.length > 0)
|
|
182
|
-
const
|
|
237
|
+
if (toolCalls.length > 0) {
|
|
238
|
+
const currentTools = toolsRef.current;
|
|
239
|
+
const toolCallsToResolve = toolCalls.filter((part) => isToolUIPart(part) && !toolsRequiringConfirmation.includes(getToolName(part)) && currentTools?.[getToolName(part)]?.execute);
|
|
183
240
|
if (toolCallsToResolve.length > 0) {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
241
|
+
isResolvingToolsRef.current = true;
|
|
242
|
+
(async () => {
|
|
243
|
+
try {
|
|
244
|
+
const toolResults = [];
|
|
245
|
+
for (const part of toolCallsToResolve) if (isToolUIPart(part)) {
|
|
246
|
+
let toolOutput = null;
|
|
247
|
+
const toolName = getToolName(part);
|
|
248
|
+
const tool$1 = currentTools?.[toolName];
|
|
249
|
+
if (tool$1?.execute && part.input !== void 0) try {
|
|
250
|
+
toolOutput = await tool$1.execute(part.input);
|
|
251
|
+
} catch (error) {
|
|
252
|
+
toolOutput = `Error executing tool: ${error instanceof Error ? error.message : String(error)}`;
|
|
253
|
+
}
|
|
254
|
+
processedToolCalls.current.add(part.toolCallId);
|
|
255
|
+
toolResults.push({
|
|
256
|
+
toolCallId: part.toolCallId,
|
|
257
|
+
toolName,
|
|
258
|
+
output: toolOutput
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
if (toolResults.length > 0) {
|
|
262
|
+
for (const result of toolResults) agentRef.current.send(JSON.stringify({
|
|
263
|
+
type: MessageType.CF_AGENT_TOOL_RESULT,
|
|
264
|
+
toolCallId: result.toolCallId,
|
|
265
|
+
toolName: result.toolName,
|
|
266
|
+
output: result.output,
|
|
267
|
+
autoContinue: autoContinueAfterToolResult
|
|
268
|
+
}));
|
|
269
|
+
await Promise.all(toolResults.map((result) => useChatHelpers.addToolResult({
|
|
270
|
+
tool: result.toolName,
|
|
271
|
+
toolCallId: result.toolCallId,
|
|
272
|
+
output: result.output
|
|
273
|
+
})));
|
|
274
|
+
setClientToolResults((prev) => {
|
|
275
|
+
const newMap = new Map(prev);
|
|
276
|
+
for (const result of toolResults) newMap.set(result.toolCallId, result.output);
|
|
277
|
+
return newMap;
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
} finally {
|
|
281
|
+
isResolvingToolsRef.current = false;
|
|
193
282
|
}
|
|
194
|
-
|
|
195
|
-
toolCallId: part.toolCallId,
|
|
196
|
-
tool: toolName,
|
|
197
|
-
output: toolOutput
|
|
198
|
-
});
|
|
199
|
-
}
|
|
200
|
-
if (pendingConfirmationsRef.current.toolCallIds.size === 0) useChatHelpers.sendMessage();
|
|
283
|
+
})();
|
|
201
284
|
}
|
|
202
|
-
}
|
|
285
|
+
}
|
|
203
286
|
}, [
|
|
204
287
|
useChatHelpers.messages,
|
|
205
288
|
experimental_automaticToolResolution,
|
|
206
289
|
useChatHelpers.addToolResult,
|
|
207
|
-
|
|
208
|
-
|
|
290
|
+
toolsRequiringConfirmation,
|
|
291
|
+
autoContinueAfterToolResult
|
|
209
292
|
]);
|
|
210
293
|
/**
|
|
211
294
|
* Contains the request ID, accumulated message parts, and a unique message ID.
|
|
@@ -237,6 +320,25 @@ function useAgentChat(options) {
|
|
|
237
320
|
case MessageType.CF_AGENT_CHAT_MESSAGES:
|
|
238
321
|
useChatHelpers.setMessages(data.messages);
|
|
239
322
|
break;
|
|
323
|
+
case MessageType.CF_AGENT_MESSAGE_UPDATED:
|
|
324
|
+
useChatHelpers.setMessages((prevMessages) => {
|
|
325
|
+
const updatedMessage = data.message;
|
|
326
|
+
let idx = prevMessages.findIndex((m) => m.id === updatedMessage.id);
|
|
327
|
+
if (idx < 0) {
|
|
328
|
+
const updatedToolCallIds = new Set(updatedMessage.parts.filter((p) => "toolCallId" in p && p.toolCallId).map((p) => p.toolCallId));
|
|
329
|
+
if (updatedToolCallIds.size > 0) idx = prevMessages.findIndex((m) => m.parts.some((p) => "toolCallId" in p && updatedToolCallIds.has(p.toolCallId)));
|
|
330
|
+
}
|
|
331
|
+
if (idx >= 0) {
|
|
332
|
+
const updated = [...prevMessages];
|
|
333
|
+
updated[idx] = {
|
|
334
|
+
...updatedMessage,
|
|
335
|
+
id: prevMessages[idx].id
|
|
336
|
+
};
|
|
337
|
+
return updated;
|
|
338
|
+
}
|
|
339
|
+
return [...prevMessages, updatedMessage];
|
|
340
|
+
});
|
|
341
|
+
break;
|
|
240
342
|
case MessageType.CF_AGENT_STREAM_RESUMING:
|
|
241
343
|
if (!resume) return;
|
|
242
344
|
activeStreamRef.current = null;
|
|
@@ -252,11 +354,24 @@ function useAgentChat(options) {
|
|
|
252
354
|
break;
|
|
253
355
|
case MessageType.CF_AGENT_USE_CHAT_RESPONSE: {
|
|
254
356
|
if (localRequestIdsRef.current.has(data.id)) return;
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
messageId
|
|
258
|
-
|
|
259
|
-
|
|
357
|
+
const isContinuation = data.continuation === true;
|
|
358
|
+
if (!activeStreamRef.current || activeStreamRef.current.id !== data.id) {
|
|
359
|
+
let messageId = nanoid();
|
|
360
|
+
let existingParts = [];
|
|
361
|
+
if (isContinuation) {
|
|
362
|
+
const currentMessages = messagesRef.current;
|
|
363
|
+
for (let i = currentMessages.length - 1; i >= 0; i--) if (currentMessages[i].role === "assistant") {
|
|
364
|
+
messageId = currentMessages[i].id;
|
|
365
|
+
existingParts = [...currentMessages[i].parts];
|
|
366
|
+
break;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
activeStreamRef.current = {
|
|
370
|
+
id: data.id,
|
|
371
|
+
messageId,
|
|
372
|
+
parts: existingParts
|
|
373
|
+
};
|
|
374
|
+
}
|
|
260
375
|
const activeMsg = activeStreamRef.current;
|
|
261
376
|
if (data.body?.trim()) try {
|
|
262
377
|
const chunkData = JSON.parse(data.body);
|
|
@@ -332,14 +447,16 @@ function useAgentChat(options) {
|
|
|
332
447
|
input: chunkData.input
|
|
333
448
|
});
|
|
334
449
|
break;
|
|
335
|
-
case "tool-output-available":
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
450
|
+
case "tool-output-available":
|
|
451
|
+
activeMsg.parts = activeMsg.parts.map((p) => {
|
|
452
|
+
if ("toolCallId" in p && p.toolCallId === chunkData.toolCallId && "state" in p) return {
|
|
453
|
+
...p,
|
|
454
|
+
state: "output-available",
|
|
455
|
+
output: chunkData.output
|
|
456
|
+
};
|
|
457
|
+
return p;
|
|
458
|
+
});
|
|
341
459
|
break;
|
|
342
|
-
}
|
|
343
460
|
case "step-start":
|
|
344
461
|
activeMsg.parts.push({ type: "step-start" });
|
|
345
462
|
break;
|
|
@@ -379,25 +496,71 @@ function useAgentChat(options) {
|
|
|
379
496
|
]);
|
|
380
497
|
const addToolResultAndSendMessage = async (args) => {
|
|
381
498
|
const { toolCallId } = args;
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
499
|
+
const toolName = "tool" in args ? args.tool : "";
|
|
500
|
+
const output = "output" in args ? args.output : void 0;
|
|
501
|
+
agentRef.current.send(JSON.stringify({
|
|
502
|
+
type: MessageType.CF_AGENT_TOOL_RESULT,
|
|
503
|
+
toolCallId,
|
|
504
|
+
toolName,
|
|
505
|
+
output,
|
|
506
|
+
autoContinue: autoContinueAfterToolResult
|
|
507
|
+
}));
|
|
508
|
+
setClientToolResults((prev) => new Map(prev).set(toolCallId, output));
|
|
509
|
+
useChatHelpers.addToolResult(args);
|
|
510
|
+
if (!autoContinueAfterToolResult) {
|
|
511
|
+
if (!autoSendAfterAllConfirmationsResolved) {
|
|
512
|
+
useChatHelpers.sendMessage();
|
|
513
|
+
return;
|
|
514
|
+
}
|
|
515
|
+
const pending = pendingConfirmationsRef.current?.toolCallIds;
|
|
516
|
+
if (!pending) {
|
|
517
|
+
useChatHelpers.sendMessage();
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
const wasLast = pending.size === 1 && pending.has(toolCallId);
|
|
521
|
+
if (pending.has(toolCallId)) pending.delete(toolCallId);
|
|
522
|
+
if (wasLast || pending.size === 0) useChatHelpers.sendMessage();
|
|
391
523
|
}
|
|
392
|
-
const wasLast = pending.size === 1 && pending.has(toolCallId);
|
|
393
|
-
if (pending.has(toolCallId)) pending.delete(toolCallId);
|
|
394
|
-
if (wasLast || pending.size === 0) useChatHelpers.sendMessage();
|
|
395
524
|
};
|
|
525
|
+
const messagesWithToolResults = useMemo(() => {
|
|
526
|
+
if (clientToolResults.size === 0) return useChatHelpers.messages;
|
|
527
|
+
return useChatHelpers.messages.map((msg) => ({
|
|
528
|
+
...msg,
|
|
529
|
+
parts: msg.parts.map((p) => {
|
|
530
|
+
if (!("toolCallId" in p) || !("state" in p) || p.state !== "input-available" || !clientToolResults.has(p.toolCallId)) return p;
|
|
531
|
+
return {
|
|
532
|
+
...p,
|
|
533
|
+
state: "output-available",
|
|
534
|
+
output: clientToolResults.get(p.toolCallId)
|
|
535
|
+
};
|
|
536
|
+
})
|
|
537
|
+
}));
|
|
538
|
+
}, [useChatHelpers.messages, clientToolResults]);
|
|
539
|
+
useEffect(() => {
|
|
540
|
+
const currentToolCallIds = /* @__PURE__ */ new Set();
|
|
541
|
+
for (const msg of useChatHelpers.messages) for (const part of msg.parts) if ("toolCallId" in part && part.toolCallId) currentToolCallIds.add(part.toolCallId);
|
|
542
|
+
setClientToolResults((prev) => {
|
|
543
|
+
if (prev.size === 0) return prev;
|
|
544
|
+
let hasStaleEntries = false;
|
|
545
|
+
for (const toolCallId of prev.keys()) if (!currentToolCallIds.has(toolCallId)) {
|
|
546
|
+
hasStaleEntries = true;
|
|
547
|
+
break;
|
|
548
|
+
}
|
|
549
|
+
if (!hasStaleEntries) return prev;
|
|
550
|
+
const newMap = /* @__PURE__ */ new Map();
|
|
551
|
+
for (const [id, output] of prev) if (currentToolCallIds.has(id)) newMap.set(id, output);
|
|
552
|
+
return newMap;
|
|
553
|
+
});
|
|
554
|
+
for (const toolCallId of processedToolCalls.current) if (!currentToolCallIds.has(toolCallId)) processedToolCalls.current.delete(toolCallId);
|
|
555
|
+
}, [useChatHelpers.messages]);
|
|
396
556
|
return {
|
|
397
557
|
...useChatHelpers,
|
|
558
|
+
messages: messagesWithToolResults,
|
|
398
559
|
addToolResult: addToolResultAndSendMessage,
|
|
399
560
|
clearHistory: () => {
|
|
400
561
|
useChatHelpers.setMessages([]);
|
|
562
|
+
setClientToolResults(/* @__PURE__ */ new Map());
|
|
563
|
+
processedToolCalls.current.clear();
|
|
401
564
|
agent.send(JSON.stringify({ type: MessageType.CF_AGENT_CHAT_CLEAR }));
|
|
402
565
|
},
|
|
403
566
|
setMessages: (messages) => {
|
|
@@ -411,5 +574,5 @@ function useAgentChat(options) {
|
|
|
411
574
|
}
|
|
412
575
|
|
|
413
576
|
//#endregion
|
|
414
|
-
export { detectToolsRequiringConfirmation, useAgentChat };
|
|
577
|
+
export { detectToolsRequiringConfirmation, extractClientToolSchemas, useAgentChat };
|
|
415
578
|
//# sourceMappingURL=ai-react.js.map
|