agents 0.0.0-6ee3a60 → 0.0.0-70499f1

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.
Files changed (77) hide show
  1. package/README.md +257 -33
  2. package/dist/_esm-LV5FJ3HK.js +3922 -0
  3. package/dist/_esm-LV5FJ3HK.js.map +1 -0
  4. package/dist/ai-chat-agent.d.ts +58 -6
  5. package/dist/ai-chat-agent.js +600 -99
  6. package/dist/ai-chat-agent.js.map +1 -1
  7. package/dist/ai-chat-v5-migration.d.ts +152 -0
  8. package/dist/ai-chat-v5-migration.js +20 -0
  9. package/dist/ai-react.d.ts +78 -67
  10. package/dist/ai-react.js +282 -121
  11. package/dist/ai-react.js.map +1 -1
  12. package/dist/ai-types.d.ts +41 -18
  13. package/dist/ai-types.js +7 -0
  14. package/dist/ccip-CMBYN64O.js +15 -0
  15. package/dist/ccip-CMBYN64O.js.map +1 -0
  16. package/dist/chunk-5Y6BEZDY.js +276 -0
  17. package/dist/chunk-5Y6BEZDY.js.map +1 -0
  18. package/dist/chunk-BER7KXUJ.js +18 -0
  19. package/dist/chunk-BER7KXUJ.js.map +1 -0
  20. package/dist/chunk-C2OEBJZ2.js +113 -0
  21. package/dist/chunk-C2OEBJZ2.js.map +1 -0
  22. package/dist/chunk-JJBFIGUC.js +5202 -0
  23. package/dist/chunk-JJBFIGUC.js.map +1 -0
  24. package/dist/chunk-PR4QN5HX.js +43 -0
  25. package/dist/chunk-PR4QN5HX.js.map +1 -0
  26. package/dist/chunk-QEVM4BVL.js +116 -0
  27. package/dist/chunk-QEVM4BVL.js.map +1 -0
  28. package/dist/chunk-TYAY6AU6.js +159 -0
  29. package/dist/chunk-TYAY6AU6.js.map +1 -0
  30. package/dist/chunk-UJVEAURM.js +150 -0
  31. package/dist/chunk-UJVEAURM.js.map +1 -0
  32. package/dist/chunk-XGMKNUJA.js +1343 -0
  33. package/dist/chunk-XGMKNUJA.js.map +1 -0
  34. package/dist/chunk-ZMMHNOMZ.js +942 -0
  35. package/dist/chunk-ZMMHNOMZ.js.map +1 -0
  36. package/dist/client-C8tswVoM.d.ts +5248 -0
  37. package/dist/client.d.ts +16 -2
  38. package/dist/client.js +8 -133
  39. package/dist/client.js.map +1 -1
  40. package/dist/codemode/ai.d.ts +25 -0
  41. package/dist/codemode/ai.js +5200 -0
  42. package/dist/codemode/ai.js.map +1 -0
  43. package/dist/index.d.ts +277 -22
  44. package/dist/index.js +16 -4
  45. package/dist/mcp/client.d.ts +12 -0
  46. package/dist/mcp/client.js +10 -0
  47. package/dist/mcp/client.js.map +1 -0
  48. package/dist/mcp/do-oauth-client-provider.d.ts +42 -0
  49. package/dist/mcp/do-oauth-client-provider.js +8 -0
  50. package/dist/mcp/do-oauth-client-provider.js.map +1 -0
  51. package/dist/mcp/index.d.ts +79 -0
  52. package/dist/mcp/index.js +1099 -0
  53. package/dist/mcp/index.js.map +1 -0
  54. package/dist/mcp/x402.d.ts +39 -0
  55. package/dist/mcp/x402.js +3195 -0
  56. package/dist/mcp/x402.js.map +1 -0
  57. package/dist/mcp-BH1fJeiU.d.ts +58 -0
  58. package/dist/observability/index.d.ts +34 -0
  59. package/dist/observability/index.js +12 -0
  60. package/dist/observability/index.js.map +1 -0
  61. package/dist/react.d.ts +97 -9
  62. package/dist/react.js +153 -34
  63. package/dist/react.js.map +1 -1
  64. package/dist/schedule.d.ts +81 -7
  65. package/dist/schedule.js +20 -7
  66. package/dist/schedule.js.map +1 -1
  67. package/dist/secp256k1-M22GZP2U.js +2193 -0
  68. package/dist/secp256k1-M22GZP2U.js.map +1 -0
  69. package/dist/serializable.d.ts +32 -0
  70. package/dist/serializable.js +1 -0
  71. package/dist/serializable.js.map +1 -0
  72. package/package.json +112 -43
  73. package/src/index.ts +1327 -184
  74. package/dist/chunk-HMLY7DHA.js +0 -16
  75. package/dist/chunk-X6BBKLSC.js +0 -568
  76. package/dist/chunk-X6BBKLSC.js.map +0 -1
  77. /package/dist/{chunk-HMLY7DHA.js.map → ai-chat-v5-migration.js.map} +0 -0
@@ -1,165 +1,666 @@
1
1
  import {
2
- Agent
3
- } from "./chunk-X6BBKLSC.js";
2
+ autoTransformMessages
3
+ } from "./chunk-UJVEAURM.js";
4
4
  import {
5
- __privateAdd,
6
- __privateMethod
7
- } from "./chunk-HMLY7DHA.js";
5
+ Agent
6
+ } from "./chunk-XGMKNUJA.js";
7
+ import "./chunk-ZMMHNOMZ.js";
8
+ import "./chunk-C2OEBJZ2.js";
9
+ import "./chunk-QEVM4BVL.js";
10
+ import "./chunk-BER7KXUJ.js";
11
+ import "./chunk-PR4QN5HX.js";
8
12
 
9
13
  // src/ai-chat-agent.ts
10
- import { appendResponseMessages } from "ai";
14
+ import {
15
+ getToolName,
16
+ isToolUIPart,
17
+ parsePartialJson
18
+ } from "ai";
11
19
  var decoder = new TextDecoder();
12
- var _AIChatAgent_instances, broadcastChatMessage_fn, tryCatch_fn, persistMessages_fn, reply_fn;
13
20
  var AIChatAgent = class extends Agent {
14
21
  constructor(ctx, env) {
15
22
  super(ctx, env);
16
- __privateAdd(this, _AIChatAgent_instances);
17
23
  this.sql`create table if not exists cf_ai_chat_agent_messages (
18
24
  id text primary key,
19
25
  message text not null,
20
26
  created_at datetime default current_timestamp
21
27
  )`;
22
- this.messages = (this.sql`select * from cf_ai_chat_agent_messages` || []).map((row) => {
23
- return JSON.parse(row.message);
24
- });
28
+ const rawMessages = this._loadMessagesFromDb();
29
+ this.messages = autoTransformMessages(rawMessages);
30
+ this._chatMessageAbortControllers = /* @__PURE__ */ new Map();
31
+ }
32
+ _broadcastChatMessage(message, exclude) {
33
+ this.broadcast(JSON.stringify(message), exclude);
34
+ }
35
+ _loadMessagesFromDb() {
36
+ const rows = this.sql`select * from cf_ai_chat_agent_messages order by created_at` || [];
37
+ return rows.map((row) => {
38
+ try {
39
+ return JSON.parse(row.message);
40
+ } catch (error) {
41
+ console.error(`Failed to parse message ${row.id}:`, error);
42
+ return null;
43
+ }
44
+ }).filter((msg) => msg !== null);
25
45
  }
26
46
  async onMessage(connection, message) {
27
47
  if (typeof message === "string") {
28
48
  let data;
29
49
  try {
30
50
  data = JSON.parse(message);
31
- } catch (error) {
51
+ } catch (_error) {
32
52
  return;
33
53
  }
34
- if (data.type === "cf_agent_use_chat_request" && data.init.method === "POST") {
54
+ if (data.type === "cf_agent_use_chat_request" /* CF_AGENT_USE_CHAT_REQUEST */ && data.init.method === "POST") {
35
55
  const {
36
- method,
37
- keepalive,
38
- headers,
39
- body,
56
+ // method,
57
+ // keepalive,
58
+ // headers,
59
+ body
40
60
  // we're reading this
41
- redirect,
42
- integrity,
43
- credentials,
44
- mode,
45
- referrer,
46
- referrerPolicy,
47
- window
61
+ //
62
+ // // these might not exist?
48
63
  // dispatcher,
49
64
  // duplex
50
65
  } = data.init;
51
66
  const { messages } = JSON.parse(body);
52
- __privateMethod(this, _AIChatAgent_instances, broadcastChatMessage_fn).call(this, {
53
- type: "cf_agent_chat_messages",
54
- messages
55
- }, [connection.id]);
56
- await __privateMethod(this, _AIChatAgent_instances, persistMessages_fn).call(this, messages, [connection.id]);
57
- return __privateMethod(this, _AIChatAgent_instances, tryCatch_fn).call(this, async () => {
58
- const response = await this.onChatMessage(async ({ response: response2 }) => {
59
- const finalMessages = appendResponseMessages({
60
- messages,
61
- responseMessages: response2.messages
62
- });
63
- await __privateMethod(this, _AIChatAgent_instances, persistMessages_fn).call(this, finalMessages, [connection.id]);
64
- });
67
+ const transformedMessages = autoTransformMessages(messages);
68
+ this._broadcastChatMessage(
69
+ {
70
+ messages: transformedMessages,
71
+ type: "cf_agent_chat_messages" /* CF_AGENT_CHAT_MESSAGES */
72
+ },
73
+ [connection.id]
74
+ );
75
+ await this.persistMessages(transformedMessages, [connection.id]);
76
+ this.observability?.emit(
77
+ {
78
+ displayMessage: "Chat message request",
79
+ id: data.id,
80
+ payload: {},
81
+ timestamp: Date.now(),
82
+ type: "message:request"
83
+ },
84
+ this.ctx
85
+ );
86
+ const chatMessageId = data.id;
87
+ const abortSignal = this._getAbortSignal(chatMessageId);
88
+ return this._tryCatchChat(async () => {
89
+ const response = await this.onChatMessage(
90
+ async (_finishResult) => {
91
+ this._removeAbortController(chatMessageId);
92
+ this.observability?.emit(
93
+ {
94
+ displayMessage: "Chat message response",
95
+ id: data.id,
96
+ payload: {},
97
+ timestamp: Date.now(),
98
+ type: "message:response"
99
+ },
100
+ this.ctx
101
+ );
102
+ },
103
+ abortSignal ? { abortSignal } : void 0
104
+ );
65
105
  if (response) {
66
- await __privateMethod(this, _AIChatAgent_instances, reply_fn).call(this, data.id, response);
106
+ await this._reply(data.id, response);
107
+ } else {
108
+ console.warn(
109
+ `[AIChatAgent] onChatMessage returned no response for chatMessageId: ${chatMessageId}`
110
+ );
111
+ this._broadcastChatMessage(
112
+ {
113
+ body: "No response was generated by the agent.",
114
+ done: true,
115
+ id: data.id,
116
+ type: "cf_agent_use_chat_response" /* CF_AGENT_USE_CHAT_RESPONSE */
117
+ },
118
+ [connection.id]
119
+ );
67
120
  }
68
121
  });
69
122
  }
70
- if (data.type === "cf_agent_chat_clear") {
123
+ if (data.type === "cf_agent_chat_clear" /* CF_AGENT_CHAT_CLEAR */) {
124
+ this._destroyAbortControllers();
71
125
  this.sql`delete from cf_ai_chat_agent_messages`;
72
126
  this.messages = [];
73
- __privateMethod(this, _AIChatAgent_instances, broadcastChatMessage_fn).call(this, {
74
- type: "cf_agent_chat_clear"
75
- }, [connection.id]);
76
- } else if (data.type === "cf_agent_chat_messages") {
77
- await __privateMethod(this, _AIChatAgent_instances, persistMessages_fn).call(this, data.messages, [connection.id]);
127
+ this._broadcastChatMessage(
128
+ {
129
+ type: "cf_agent_chat_clear" /* CF_AGENT_CHAT_CLEAR */
130
+ },
131
+ [connection.id]
132
+ );
133
+ } else if (data.type === "cf_agent_chat_messages" /* CF_AGENT_CHAT_MESSAGES */) {
134
+ const transformedMessages = autoTransformMessages(data.messages);
135
+ await this.persistMessages(transformedMessages, [connection.id]);
136
+ } else if (data.type === "cf_agent_chat_request_cancel" /* CF_AGENT_CHAT_REQUEST_CANCEL */) {
137
+ this._cancelChatRequest(data.id);
78
138
  }
79
139
  }
80
140
  }
81
141
  async onRequest(request) {
82
- return __privateMethod(this, _AIChatAgent_instances, tryCatch_fn).call(this, () => {
83
- if (request.url.endsWith("/get-messages")) {
84
- const messages = (this.sql`select * from cf_ai_chat_agent_messages` || []).map((row) => {
85
- return JSON.parse(row.message);
86
- });
142
+ return this._tryCatchChat(() => {
143
+ const url = new URL(request.url);
144
+ if (url.pathname.endsWith("/get-messages")) {
145
+ const messages = this._loadMessagesFromDb();
87
146
  return Response.json(messages);
88
147
  }
89
148
  return super.onRequest(request);
90
149
  });
91
150
  }
151
+ async _tryCatchChat(fn) {
152
+ try {
153
+ return await fn();
154
+ } catch (e) {
155
+ throw this.onError(e);
156
+ }
157
+ }
92
158
  /**
93
159
  * Handle incoming chat messages and generate a response
94
160
  * @param onFinish Callback to be called when the response is finished
161
+ * @param options.signal A signal to pass to any child requests which can be used to cancel them
95
162
  * @returns Response to send to the client or undefined
96
163
  */
97
- async onChatMessage(onFinish) {
164
+ async onChatMessage(onFinish, options) {
98
165
  throw new Error(
99
166
  "recieved a chat message, override onChatMessage and return a Response to send to the client"
100
167
  );
101
168
  }
102
169
  /**
103
- * Save messages on the server side and trigger AI response
170
+ * Save messages on the server side
104
171
  * @param messages Chat messages to save
105
172
  */
106
173
  async saveMessages(messages) {
107
- await __privateMethod(this, _AIChatAgent_instances, persistMessages_fn).call(this, messages);
108
- const response = await this.onChatMessage(async ({ response: response2 }) => {
109
- const finalMessages = appendResponseMessages({
110
- messages,
111
- responseMessages: response2.messages
174
+ await this.persistMessages(messages);
175
+ await this._tryCatchChat(async () => {
176
+ const response = await this.onChatMessage(() => {
112
177
  });
113
- await __privateMethod(this, _AIChatAgent_instances, persistMessages_fn).call(this, finalMessages, []);
178
+ if (response) this._reply(crypto.randomUUID(), response);
114
179
  });
115
- if (response) {
116
- for await (const chunk of response.body) {
117
- decoder.decode(chunk);
180
+ }
181
+ async persistMessages(messages, excludeBroadcastIds = []) {
182
+ for (const message of messages) {
183
+ this.sql`
184
+ insert into cf_ai_chat_agent_messages (id, message)
185
+ values (${message.id}, ${JSON.stringify(message)})
186
+ on conflict(id) do update set message = excluded.message
187
+ `;
188
+ }
189
+ const persisted = this._loadMessagesFromDb();
190
+ this.messages = autoTransformMessages(persisted);
191
+ this._broadcastChatMessage(
192
+ {
193
+ messages,
194
+ type: "cf_agent_chat_messages" /* CF_AGENT_CHAT_MESSAGES */
195
+ },
196
+ excludeBroadcastIds
197
+ );
198
+ }
199
+ async _reply(id, response) {
200
+ return this._tryCatchChat(async () => {
201
+ if (!response.body) {
202
+ this._broadcastChatMessage({
203
+ body: "",
204
+ done: true,
205
+ id,
206
+ type: "cf_agent_use_chat_response" /* CF_AGENT_USE_CHAT_RESPONSE */
207
+ });
208
+ return;
209
+ }
210
+ const reader = response.body.getReader();
211
+ const message = {
212
+ id: `assistant_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`,
213
+ // default
214
+ role: "assistant",
215
+ parts: []
216
+ };
217
+ let activeTextParts = {};
218
+ let activeReasoningParts = {};
219
+ const partialToolCalls = {};
220
+ function updateDynamicToolPart(options) {
221
+ const part = message.parts.find(
222
+ (part2) => part2.type === "dynamic-tool" && part2.toolCallId === options.toolCallId
223
+ );
224
+ const anyOptions = options;
225
+ const anyPart = part;
226
+ if (part != null) {
227
+ part.state = options.state;
228
+ anyPart.toolName = options.toolName;
229
+ anyPart.input = anyOptions.input;
230
+ anyPart.output = anyOptions.output;
231
+ anyPart.errorText = anyOptions.errorText;
232
+ anyPart.rawInput = anyOptions.rawInput ?? anyPart.rawInput;
233
+ anyPart.preliminary = anyOptions.preliminary;
234
+ if (anyOptions.providerMetadata != null && part.state === "input-available") {
235
+ part.callProviderMetadata = anyOptions.providerMetadata;
236
+ }
237
+ } else {
238
+ message.parts.push({
239
+ type: "dynamic-tool",
240
+ toolName: options.toolName,
241
+ toolCallId: options.toolCallId,
242
+ state: options.state,
243
+ input: anyOptions.input,
244
+ output: anyOptions.output,
245
+ errorText: anyOptions.errorText,
246
+ preliminary: anyOptions.preliminary,
247
+ ...anyOptions.providerMetadata != null ? { callProviderMetadata: anyOptions.providerMetadata } : {}
248
+ });
249
+ }
250
+ }
251
+ function updateToolPart(options) {
252
+ const part = message.parts.find(
253
+ (part2) => isToolUIPart(part2) && part2.toolCallId === options.toolCallId
254
+ );
255
+ const anyOptions = options;
256
+ const anyPart = part;
257
+ if (part != null) {
258
+ part.state = options.state;
259
+ anyPart.input = anyOptions.input;
260
+ anyPart.output = anyOptions.output;
261
+ anyPart.errorText = anyOptions.errorText;
262
+ anyPart.rawInput = anyOptions.rawInput;
263
+ anyPart.preliminary = anyOptions.preliminary;
264
+ anyPart.providerExecuted = anyOptions.providerExecuted ?? part.providerExecuted;
265
+ if (anyOptions.providerMetadata != null && part.state === "input-available") {
266
+ part.callProviderMetadata = anyOptions.providerMetadata;
267
+ }
268
+ } else {
269
+ message.parts.push({
270
+ type: `tool-${options.toolName}`,
271
+ toolCallId: options.toolCallId,
272
+ state: options.state,
273
+ input: anyOptions.input,
274
+ output: anyOptions.output,
275
+ rawInput: anyOptions.rawInput,
276
+ errorText: anyOptions.errorText,
277
+ providerExecuted: anyOptions.providerExecuted,
278
+ preliminary: anyOptions.preliminary,
279
+ ...anyOptions.providerMetadata != null ? { callProviderMetadata: anyOptions.providerMetadata } : {}
280
+ });
281
+ }
118
282
  }
119
- response.body?.cancel();
283
+ async function updateMessageMetadata(metadata) {
284
+ if (metadata != null) {
285
+ const mergedMetadata = message.metadata != null ? { ...message.metadata, ...metadata } : metadata;
286
+ message.metadata = mergedMetadata;
287
+ }
288
+ }
289
+ try {
290
+ while (true) {
291
+ const { done, value } = await reader.read();
292
+ if (done) {
293
+ this._broadcastChatMessage({
294
+ body: "",
295
+ done: true,
296
+ id,
297
+ type: "cf_agent_use_chat_response" /* CF_AGENT_USE_CHAT_RESPONSE */
298
+ });
299
+ break;
300
+ }
301
+ const chunk = decoder.decode(value);
302
+ const contentType = response.headers.get("content-type") || "";
303
+ const isSSE = contentType.includes("text/event-stream");
304
+ if (isSSE) {
305
+ const lines = chunk.split("\n");
306
+ for (const line of lines) {
307
+ if (line.startsWith("data: ") && line !== "data: [DONE]") {
308
+ try {
309
+ const data = JSON.parse(line.slice(6));
310
+ switch (data.type) {
311
+ case "text-start": {
312
+ const textPart = {
313
+ type: "text",
314
+ text: "",
315
+ providerMetadata: data.providerMetadata,
316
+ state: "streaming"
317
+ };
318
+ activeTextParts[data.id] = textPart;
319
+ message.parts.push(textPart);
320
+ break;
321
+ }
322
+ case "text-delta": {
323
+ const textPart = activeTextParts[data.id];
324
+ textPart.text += data.delta;
325
+ textPart.providerMetadata = data.providerMetadata ?? textPart.providerMetadata;
326
+ break;
327
+ }
328
+ case "text-end": {
329
+ const textPart = activeTextParts[data.id];
330
+ textPart.state = "done";
331
+ textPart.providerMetadata = data.providerMetadata ?? textPart.providerMetadata;
332
+ delete activeTextParts[data.id];
333
+ break;
334
+ }
335
+ case "reasoning-start": {
336
+ const reasoningPart = {
337
+ type: "reasoning",
338
+ text: "",
339
+ providerMetadata: data.providerMetadata,
340
+ state: "streaming"
341
+ };
342
+ activeReasoningParts[data.id] = reasoningPart;
343
+ message.parts.push(reasoningPart);
344
+ break;
345
+ }
346
+ case "reasoning-delta": {
347
+ const reasoningPart = activeReasoningParts[data.id];
348
+ reasoningPart.text += data.delta;
349
+ reasoningPart.providerMetadata = data.providerMetadata ?? reasoningPart.providerMetadata;
350
+ break;
351
+ }
352
+ case "reasoning-end": {
353
+ const reasoningPart = activeReasoningParts[data.id];
354
+ reasoningPart.providerMetadata = data.providerMetadata ?? reasoningPart.providerMetadata;
355
+ reasoningPart.state = "done";
356
+ delete activeReasoningParts[data.id];
357
+ break;
358
+ }
359
+ case "file": {
360
+ message.parts.push({
361
+ type: "file",
362
+ mediaType: data.mediaType,
363
+ url: data.url
364
+ });
365
+ break;
366
+ }
367
+ case "source-url": {
368
+ message.parts.push({
369
+ type: "source-url",
370
+ sourceId: data.sourceId,
371
+ url: data.url,
372
+ title: data.title,
373
+ providerMetadata: data.providerMetadata
374
+ });
375
+ break;
376
+ }
377
+ case "source-document": {
378
+ message.parts.push({
379
+ type: "source-document",
380
+ sourceId: data.sourceId,
381
+ mediaType: data.mediaType,
382
+ title: data.title,
383
+ filename: data.filename,
384
+ providerMetadata: data.providerMetadata
385
+ });
386
+ break;
387
+ }
388
+ case "tool-input-start": {
389
+ const toolInvocations = message.parts.filter(isToolUIPart);
390
+ partialToolCalls[data.toolCallId] = {
391
+ text: "",
392
+ toolName: data.toolName,
393
+ index: toolInvocations.length,
394
+ dynamic: data.dynamic
395
+ };
396
+ if (data.dynamic) {
397
+ updateDynamicToolPart({
398
+ toolCallId: data.toolCallId,
399
+ toolName: data.toolName,
400
+ state: "input-streaming",
401
+ input: void 0
402
+ });
403
+ } else {
404
+ updateToolPart({
405
+ toolCallId: data.toolCallId,
406
+ toolName: data.toolName,
407
+ state: "input-streaming",
408
+ input: void 0
409
+ });
410
+ }
411
+ break;
412
+ }
413
+ case "tool-input-delta": {
414
+ const partialToolCall = partialToolCalls[data.toolCallId];
415
+ partialToolCall.text += data.inputTextDelta;
416
+ const { value: partialArgs } = await parsePartialJson(
417
+ partialToolCall.text
418
+ );
419
+ if (partialToolCall.dynamic) {
420
+ updateDynamicToolPart({
421
+ toolCallId: data.toolCallId,
422
+ toolName: partialToolCall.toolName,
423
+ state: "input-streaming",
424
+ input: partialArgs
425
+ });
426
+ } else {
427
+ updateToolPart({
428
+ toolCallId: data.toolCallId,
429
+ toolName: partialToolCall.toolName,
430
+ state: "input-streaming",
431
+ input: partialArgs
432
+ });
433
+ }
434
+ break;
435
+ }
436
+ case "tool-input-available": {
437
+ if (data.dynamic) {
438
+ updateDynamicToolPart({
439
+ toolCallId: data.toolCallId,
440
+ toolName: data.toolName,
441
+ state: "input-available",
442
+ input: data.input,
443
+ providerMetadata: data.providerMetadata
444
+ });
445
+ } else {
446
+ updateToolPart({
447
+ toolCallId: data.toolCallId,
448
+ toolName: data.toolName,
449
+ state: "input-available",
450
+ input: data.input,
451
+ providerExecuted: data.providerExecuted,
452
+ providerMetadata: data.providerMetadata
453
+ });
454
+ }
455
+ break;
456
+ }
457
+ case "tool-input-error": {
458
+ if (data.dynamic) {
459
+ updateDynamicToolPart({
460
+ toolCallId: data.toolCallId,
461
+ toolName: data.toolName,
462
+ state: "output-error",
463
+ input: data.input,
464
+ errorText: data.errorText,
465
+ providerMetadata: data.providerMetadata
466
+ });
467
+ } else {
468
+ updateToolPart({
469
+ toolCallId: data.toolCallId,
470
+ toolName: data.toolName,
471
+ state: "output-error",
472
+ input: void 0,
473
+ rawInput: data.input,
474
+ errorText: data.errorText,
475
+ providerExecuted: data.providerExecuted,
476
+ providerMetadata: data.providerMetadata
477
+ });
478
+ }
479
+ break;
480
+ }
481
+ case "tool-output-available": {
482
+ if (data.dynamic) {
483
+ const toolInvocations = message.parts.filter(
484
+ (part) => part.type === "dynamic-tool"
485
+ );
486
+ const toolInvocation = toolInvocations.find(
487
+ (invocation) => invocation.toolCallId === data.toolCallId
488
+ );
489
+ if (!toolInvocation)
490
+ throw new Error("Tool invocation not found");
491
+ updateDynamicToolPart({
492
+ toolCallId: data.toolCallId,
493
+ toolName: toolInvocation.toolName,
494
+ state: "output-available",
495
+ input: toolInvocation.input,
496
+ output: data.output,
497
+ preliminary: data.preliminary
498
+ });
499
+ } else {
500
+ const toolInvocations = message.parts.filter(isToolUIPart);
501
+ const toolInvocation = toolInvocations.find(
502
+ (invocation) => invocation.toolCallId === data.toolCallId
503
+ );
504
+ if (!toolInvocation)
505
+ throw new Error("Tool invocation not found");
506
+ updateToolPart({
507
+ toolCallId: data.toolCallId,
508
+ toolName: getToolName(toolInvocation),
509
+ state: "output-available",
510
+ input: toolInvocation.input,
511
+ output: data.output,
512
+ providerExecuted: data.providerExecuted,
513
+ preliminary: data.preliminary
514
+ });
515
+ }
516
+ break;
517
+ }
518
+ case "tool-output-error": {
519
+ if (data.dynamic) {
520
+ const toolInvocations = message.parts.filter(
521
+ (part) => part.type === "dynamic-tool"
522
+ );
523
+ const toolInvocation = toolInvocations.find(
524
+ (invocation) => invocation.toolCallId === data.toolCallId
525
+ );
526
+ if (!toolInvocation)
527
+ throw new Error("Tool invocation not found");
528
+ updateDynamicToolPart({
529
+ toolCallId: data.toolCallId,
530
+ toolName: toolInvocation.toolName,
531
+ state: "output-error",
532
+ input: toolInvocation.input,
533
+ errorText: data.errorText
534
+ });
535
+ } else {
536
+ const toolInvocations = message.parts.filter(isToolUIPart);
537
+ const toolInvocation = toolInvocations.find(
538
+ (invocation) => invocation.toolCallId === data.toolCallId
539
+ );
540
+ if (!toolInvocation)
541
+ throw new Error("Tool invocation not found");
542
+ updateToolPart({
543
+ toolCallId: data.toolCallId,
544
+ toolName: getToolName(toolInvocation),
545
+ state: "output-error",
546
+ input: toolInvocation.input,
547
+ rawInput: "rawInput" in toolInvocation ? toolInvocation.rawInput : void 0,
548
+ errorText: data.errorText
549
+ });
550
+ }
551
+ break;
552
+ }
553
+ case "start-step": {
554
+ message.parts.push({ type: "step-start" });
555
+ break;
556
+ }
557
+ case "finish-step": {
558
+ activeTextParts = {};
559
+ activeReasoningParts = {};
560
+ break;
561
+ }
562
+ case "start": {
563
+ if (data.messageId != null) {
564
+ message.id = data.messageId;
565
+ }
566
+ await updateMessageMetadata(data.messageMetadata);
567
+ break;
568
+ }
569
+ case "finish": {
570
+ await updateMessageMetadata(data.messageMetadata);
571
+ break;
572
+ }
573
+ case "message-metadata": {
574
+ await updateMessageMetadata(data.messageMetadata);
575
+ break;
576
+ }
577
+ case "error": {
578
+ this._broadcastChatMessage({
579
+ error: true,
580
+ body: data.errorText ?? JSON.stringify(data),
581
+ done: false,
582
+ id,
583
+ type: "cf_agent_use_chat_response" /* CF_AGENT_USE_CHAT_RESPONSE */
584
+ });
585
+ break;
586
+ }
587
+ }
588
+ this._broadcastChatMessage({
589
+ body: JSON.stringify(data),
590
+ done: false,
591
+ id,
592
+ type: "cf_agent_use_chat_response" /* CF_AGENT_USE_CHAT_RESPONSE */
593
+ });
594
+ } catch (_e) {
595
+ }
596
+ }
597
+ }
598
+ } else {
599
+ if (chunk.length > 0) {
600
+ message.parts.push({ type: "text", text: chunk });
601
+ this._broadcastChatMessage({
602
+ body: JSON.stringify({ type: "text-delta", delta: chunk }),
603
+ done: false,
604
+ id,
605
+ type: "cf_agent_use_chat_response" /* CF_AGENT_USE_CHAT_RESPONSE */
606
+ });
607
+ }
608
+ }
609
+ }
610
+ } finally {
611
+ reader.releaseLock();
612
+ }
613
+ if (message.parts.length > 0) {
614
+ await this.persistMessages([...this.messages, message]);
615
+ }
616
+ });
617
+ }
618
+ /**
619
+ * For the given message id, look up its associated AbortController
620
+ * If the AbortController does not exist, create and store one in memory
621
+ *
622
+ * returns the AbortSignal associated with the AbortController
623
+ */
624
+ _getAbortSignal(id) {
625
+ if (typeof id !== "string") {
626
+ return void 0;
627
+ }
628
+ if (!this._chatMessageAbortControllers.has(id)) {
629
+ this._chatMessageAbortControllers.set(id, new AbortController());
120
630
  }
631
+ return this._chatMessageAbortControllers.get(id)?.signal;
121
632
  }
122
- };
123
- _AIChatAgent_instances = new WeakSet();
124
- broadcastChatMessage_fn = function(message, exclude) {
125
- this.broadcast(JSON.stringify(message), exclude);
126
- };
127
- tryCatch_fn = async function(fn) {
128
- try {
129
- return await fn();
130
- } catch (e) {
131
- throw this.onError(e);
633
+ /**
634
+ * Remove an abort controller from the cache of pending message responses
635
+ */
636
+ _removeAbortController(id) {
637
+ this._chatMessageAbortControllers.delete(id);
132
638
  }
133
- };
134
- persistMessages_fn = async function(messages, excludeBroadcastIds = []) {
135
- this.sql`delete from cf_ai_chat_agent_messages`;
136
- for (const message of messages) {
137
- this.sql`insert into cf_ai_chat_agent_messages (id, message) values (${message.id},${JSON.stringify(message)})`;
639
+ /**
640
+ * Propagate an abort signal for any requests associated with the given message id
641
+ */
642
+ _cancelChatRequest(id) {
643
+ if (this._chatMessageAbortControllers.has(id)) {
644
+ const abortController = this._chatMessageAbortControllers.get(id);
645
+ abortController?.abort();
646
+ }
138
647
  }
139
- this.messages = messages;
140
- __privateMethod(this, _AIChatAgent_instances, broadcastChatMessage_fn).call(this, {
141
- type: "cf_agent_chat_messages",
142
- messages
143
- }, excludeBroadcastIds);
144
- };
145
- reply_fn = async function(id, response) {
146
- return __privateMethod(this, _AIChatAgent_instances, tryCatch_fn).call(this, async () => {
147
- for await (const chunk of response.body) {
148
- const body = decoder.decode(chunk);
149
- __privateMethod(this, _AIChatAgent_instances, broadcastChatMessage_fn).call(this, {
150
- id,
151
- type: "cf_agent_use_chat_response",
152
- body,
153
- done: false
154
- });
648
+ /**
649
+ * Abort all pending requests and clear the cache of AbortControllers
650
+ */
651
+ _destroyAbortControllers() {
652
+ for (const controller of this._chatMessageAbortControllers.values()) {
653
+ controller?.abort();
155
654
  }
156
- __privateMethod(this, _AIChatAgent_instances, broadcastChatMessage_fn).call(this, {
157
- id,
158
- type: "cf_agent_use_chat_response",
159
- body: "",
160
- done: true
161
- });
162
- });
655
+ this._chatMessageAbortControllers.clear();
656
+ }
657
+ /**
658
+ * When the DO is destroyed, cancel all pending requests
659
+ */
660
+ async destroy() {
661
+ this._destroyAbortControllers();
662
+ await super.destroy();
663
+ }
163
664
  };
164
665
  export {
165
666
  AIChatAgent