@cloudflare/ai-chat 0.0.5 → 0.0.7

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/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # @cloudflare/ai-chat
2
2
 
3
+ ## 0.0.7
4
+
5
+ ### Patch Changes
6
+
7
+ - [#859](https://github.com/cloudflare/agents/pull/859) [`3de98a3`](https://github.com/cloudflare/agents/commit/3de98a398d55aeca51c7b845ed4c5d6051887d6d) Thanks [@threepointone](https://github.com/threepointone)! - broaden peer deps
8
+
9
+ - [#865](https://github.com/cloudflare/agents/pull/865) [`c3211d0`](https://github.com/cloudflare/agents/commit/c3211d0b0cc36aa294c15569ae650d3afeab9926) Thanks [@threepointone](https://github.com/threepointone)! - update dependencies
10
+
11
+ ## 0.0.6
12
+
13
+ ### Patch Changes
14
+
15
+ - [#829](https://github.com/cloudflare/agents/pull/829) [`83f137f`](https://github.com/cloudflare/agents/commit/83f137f7046aeafc3b480b5aa4518f6290b14406) Thanks [@Muhammad-Bin-Ali](https://github.com/Muhammad-Bin-Ali)! - Fix duplicate assistant messages when using needsApproval tools
16
+
17
+ When calling `addToolApprovalResponse`, the original assistant message is now updated in place instead of creating a duplicate with a new ID.
18
+
19
+ - Updated dependencies [[`68916bf`](https://github.com/cloudflare/agents/commit/68916bfa08358d4bb5d61aff37acd8dc4ffc950e), [`3f490d0`](https://github.com/cloudflare/agents/commit/3f490d045844e4884db741afbb66ca1fe65d4093)]:
20
+ - agents@0.3.10
21
+
3
22
  ## 0.0.5
4
23
 
5
24
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -20,8 +20,8 @@ import { Agent, AgentContext } from "agents";
20
20
  * and handle them via the `onToolCall` callback in `useAgentChat`.
21
21
  */
22
22
  type ClientToolSchema = {
23
- /** Unique name for the tool */ name: string; /** Human-readable description of what the tool does */
24
- description?: Tool["description"]; /** JSON Schema defining the tool's input parameters */
23
+ /** Unique name for the tool */ name: string /** Human-readable description of what the tool does */;
24
+ description?: Tool["description"] /** JSON Schema defining the tool's input parameters */;
25
25
  parameters?: JSONSchema7;
26
26
  };
27
27
  /**
@@ -296,6 +296,16 @@ declare class AIChatAgent<
296
296
  private updateDynamicToolPart;
297
297
  private updateToolPart;
298
298
  private updateMessageMetadata;
299
+ /**
300
+ * Applies a tool approval response from the client, updating the persisted message.
301
+ * This is called when the client sends CF_AGENT_TOOL_APPROVAL for tools with needsApproval.
302
+ * Updates the tool part state from input-available/approval-requested to approval-responded.
303
+ *
304
+ * @param toolCallId - The tool call ID this approval is for
305
+ * @param approved - Whether the tool execution was approved
306
+ * @returns true if the approval was applied, false if the message was not found
307
+ */
308
+ private _applyToolApproval;
299
309
  private _reply;
300
310
  /**
301
311
  * Mark a stream as errored and clean up state.
package/dist/index.js CHANGED
@@ -238,6 +238,11 @@ var AIChatAgent = class extends Agent {
238
238
  });
239
239
  return;
240
240
  }
241
+ if (data.type === MessageType.CF_AGENT_TOOL_APPROVAL) {
242
+ const { toolCallId, approved } = data;
243
+ this._applyToolApproval(toolCallId, approved);
244
+ return;
245
+ }
241
246
  }
242
247
  return _onMessage(connection, message);
243
248
  };
@@ -542,7 +547,7 @@ var AIChatAgent = class extends Agent {
542
547
  */
543
548
  _resolveMessageForToolMerge(message) {
544
549
  if (message.role !== "assistant") return message;
545
- for (const part of message.parts) if ("toolCallId" in part && "state" in part && part.state === "output-available") {
550
+ for (const part of message.parts) if ("toolCallId" in part && "state" in part && (part.state === "output-available" || part.state === "approval-responded" || part.state === "approval-requested")) {
546
551
  const toolCallId = part.toolCallId;
547
552
  const existingMessage = this._findMessageByToolCallId(toolCallId);
548
553
  if (existingMessage && existingMessage.id !== message.id) return {
@@ -1068,6 +1073,79 @@ var AIChatAgent = class extends Agent {
1068
1073
  ...metadata
1069
1074
  } : metadata;
1070
1075
  }
1076
+ /**
1077
+ * Applies a tool approval response from the client, updating the persisted message.
1078
+ * This is called when the client sends CF_AGENT_TOOL_APPROVAL for tools with needsApproval.
1079
+ * Updates the tool part state from input-available/approval-requested to approval-responded.
1080
+ *
1081
+ * @param toolCallId - The tool call ID this approval is for
1082
+ * @param approved - Whether the tool execution was approved
1083
+ * @returns true if the approval was applied, false if the message was not found
1084
+ */
1085
+ async _applyToolApproval(toolCallId, approved) {
1086
+ let message;
1087
+ if (this._streamingMessage) {
1088
+ for (const part of this._streamingMessage.parts) if ("toolCallId" in part && part.toolCallId === toolCallId) {
1089
+ message = this._streamingMessage;
1090
+ break;
1091
+ }
1092
+ }
1093
+ if (!message) for (let attempt = 0; attempt < 10; attempt++) {
1094
+ message = this._findMessageByToolCallId(toolCallId);
1095
+ if (message) break;
1096
+ await new Promise((resolve) => setTimeout(resolve, 100));
1097
+ }
1098
+ if (!message) {
1099
+ console.warn(`[AIChatAgent] _applyToolApproval: Could not find message with toolCallId ${toolCallId} after retries`);
1100
+ return false;
1101
+ }
1102
+ const isStreamingMessage = message === this._streamingMessage;
1103
+ let updated = false;
1104
+ if (isStreamingMessage) {
1105
+ for (const part of message.parts) if ("toolCallId" in part && part.toolCallId === toolCallId && "state" in part && (part.state === "input-available" || part.state === "approval-requested")) {
1106
+ part.state = "approval-responded";
1107
+ part.approval = { approved };
1108
+ updated = true;
1109
+ break;
1110
+ }
1111
+ } else {
1112
+ const updatedParts = message.parts.map((part) => {
1113
+ if ("toolCallId" in part && part.toolCallId === toolCallId && "state" in part && (part.state === "input-available" || part.state === "approval-requested")) {
1114
+ updated = true;
1115
+ return {
1116
+ ...part,
1117
+ state: "approval-responded",
1118
+ approval: { approved }
1119
+ };
1120
+ }
1121
+ return part;
1122
+ });
1123
+ if (updated) {
1124
+ const updatedMessage = this._sanitizeMessageForPersistence({
1125
+ ...message,
1126
+ parts: updatedParts
1127
+ });
1128
+ this.sql`
1129
+ update cf_ai_chat_agent_messages
1130
+ set message = ${JSON.stringify(updatedMessage)}
1131
+ where id = ${message.id}
1132
+ `;
1133
+ this.messages = autoTransformMessages(this._loadMessagesFromDb());
1134
+ }
1135
+ }
1136
+ if (!updated) {
1137
+ console.warn(`[AIChatAgent] _applyToolApproval: Tool part with toolCallId ${toolCallId} not in input-available or approval-requested state`);
1138
+ return false;
1139
+ }
1140
+ if (!isStreamingMessage) {
1141
+ const broadcastMessage = this._findMessageByToolCallId(toolCallId);
1142
+ if (broadcastMessage) this._broadcastChatMessage({
1143
+ type: MessageType.CF_AGENT_MESSAGE_UPDATED,
1144
+ message: broadcastMessage
1145
+ });
1146
+ }
1147
+ return true;
1148
+ }
1071
1149
  async _reply(id, response, excludeBroadcastIds = [], options = {}) {
1072
1150
  const { continuation = false } = options;
1073
1151
  return this._tryCatchChat(async () => {