@yourgpt/copilot-sdk 1.2.1 → 1.2.3

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.
@@ -84,6 +84,12 @@ var SimpleChatState = class {
84
84
  const lastIndex = this._messages.length - 1;
85
85
  this.replaceMessage(lastIndex, updater(this._messages[lastIndex]));
86
86
  }
87
+ updateMessageById(id, updater) {
88
+ const index = this._messages.findIndex((m) => m.id === id);
89
+ if (index === -1) return false;
90
+ this.replaceMessage(index, updater(this._messages[index]));
91
+ return true;
92
+ }
87
93
  setMessages(messages) {
88
94
  this._messages = messages;
89
95
  this.notify();
@@ -479,6 +485,7 @@ var AbstractChat = class {
479
485
  async sendMessage(content, attachments) {
480
486
  this.debug("sendMessage", { content, attachments });
481
487
  try {
488
+ this.resolveUnresolvedToolCalls();
482
489
  const userMessage = createUserMessage(content, attachments);
483
490
  this.state.pushMessage(userMessage);
484
491
  this.state.status = "submitted";
@@ -491,6 +498,49 @@ var AbstractChat = class {
491
498
  this.handleError(error);
492
499
  }
493
500
  }
501
+ /**
502
+ * Resolve any tool_calls that don't have corresponding tool_results.
503
+ * This prevents Anthropic API errors when tool_use has no tool_result.
504
+ * Can happen when max iterations is reached or tool execution is interrupted.
505
+ */
506
+ resolveUnresolvedToolCalls() {
507
+ const messages = this.state.messages;
508
+ const allToolCallIds = /* @__PURE__ */ new Set();
509
+ const resolvedIds = /* @__PURE__ */ new Set();
510
+ for (const msg of messages) {
511
+ if (msg.role === "assistant" && msg.toolCalls?.length) {
512
+ for (const tc of msg.toolCalls) {
513
+ allToolCallIds.add(tc.id);
514
+ }
515
+ }
516
+ if (msg.role === "tool" && msg.toolCallId) {
517
+ resolvedIds.add(msg.toolCallId);
518
+ }
519
+ }
520
+ const unresolvedIds = [...allToolCallIds].filter(
521
+ (id) => !resolvedIds.has(id)
522
+ );
523
+ if (unresolvedIds.length > 0) {
524
+ this.debug(
525
+ "resolveUnresolvedToolCalls",
526
+ `Adding ${unresolvedIds.length} missing tool results`
527
+ );
528
+ for (const toolCallId of unresolvedIds) {
529
+ const toolMessage = {
530
+ id: generateMessageId(),
531
+ role: "tool",
532
+ content: JSON.stringify({
533
+ success: false,
534
+ error: "Tool execution was interrupted. Please try again."
535
+ }),
536
+ toolCallId,
537
+ createdAt: /* @__PURE__ */ new Date()
538
+ };
539
+ this.state.pushMessage(toolMessage);
540
+ }
541
+ this.callbacks.onMessagesChange?.(this.state.messages);
542
+ }
543
+ }
494
544
  /**
495
545
  * Continue with tool results
496
546
  *
@@ -746,7 +796,7 @@ ${this.dynamicContext}`.trim() : this.config.systemPrompt,
746
796
  }
747
797
  this.streamState = processStreamChunk(chunk, this.streamState);
748
798
  const updatedMessage = streamStateToMessage(this.streamState);
749
- this.state.updateLastMessage(() => updatedMessage);
799
+ this.state.updateMessageById(this.streamState.messageId, () => updatedMessage);
750
800
  if (chunk.type === "message:delta") {
751
801
  this.callbacks.onMessageDelta?.(assistantMessage.id, chunk.content);
752
802
  }
@@ -762,7 +812,7 @@ ${this.dynamicContext}`.trim() : this.config.systemPrompt,
762
812
  }
763
813
  this.debug("handleStreamResponse", `Processed ${chunkCount} chunks`);
764
814
  const finalMessage = streamStateToMessage(this.streamState);
765
- this.state.updateLastMessage(() => finalMessage);
815
+ this.state.updateMessageById(this.streamState.messageId, () => finalMessage);
766
816
  this.state.status = "ready";
767
817
  if (!finalMessage.content && (!finalMessage.toolCalls || finalMessage.toolCalls.length === 0)) {
768
818
  this.debug("warning", "Empty response - no content and no tool calls");
@@ -1115,6 +1165,14 @@ var AbstractAgentLoop = class {
1115
1165
  this.clearToolExecutions();
1116
1166
  this.pendingApprovals.clear();
1117
1167
  }
1168
+ /**
1169
+ * Reset iteration counter only (allows continuing after max iterations)
1170
+ * Called when user sends a new message
1171
+ */
1172
+ resetIterations() {
1173
+ this.setIteration(0);
1174
+ this._maxIterationsReached = false;
1175
+ }
1118
1176
  /**
1119
1177
  * Update configuration
1120
1178
  */
@@ -1223,11 +1281,12 @@ var ChatWithTools = class {
1223
1281
  await this.chat.continueWithToolResults(toolResults);
1224
1282
  } else if (this.agentLoop.maxIterationsReached && toolCallInfos.length > 0) {
1225
1283
  this.debug("Max iterations reached, adding blocked tool results");
1284
+ const errorMessage = this.config.maxIterationsMessage || "Tool execution paused: iteration limit reached. User can say 'continue' to resume.";
1226
1285
  const blockedResults = toolCallInfos.map((tc) => ({
1227
1286
  toolCallId: tc.id,
1228
1287
  result: {
1229
1288
  success: false,
1230
- error: "Tool execution blocked: maximum iterations reached"
1289
+ error: errorMessage
1231
1290
  }
1232
1291
  }));
1233
1292
  await this.chat.continueWithToolResults(blockedResults);
@@ -1278,6 +1337,7 @@ var ChatWithTools = class {
1278
1337
  * Send a message
1279
1338
  */
1280
1339
  async sendMessage(content, attachments) {
1340
+ this.agentLoop.resetIterations();
1281
1341
  await this.chat.sendMessage(content, attachments);
1282
1342
  }
1283
1343
  /**
@@ -1469,6 +1529,15 @@ var ReactChatState = class {
1469
1529
  ];
1470
1530
  this.notify();
1471
1531
  }
1532
+ updateMessageById(id, updater) {
1533
+ const index = this._messages.findIndex((m) => m.id === id);
1534
+ if (index === -1) return false;
1535
+ this._messages = this._messages.map(
1536
+ (m, i) => i === index ? updater(m) : m
1537
+ );
1538
+ this.notify();
1539
+ return true;
1540
+ }
1472
1541
  setMessages(messages) {
1473
1542
  this._messages = messages;
1474
1543
  this.notify();
@@ -1606,7 +1675,8 @@ function CopilotProvider({
1606
1675
  onError,
1607
1676
  streaming,
1608
1677
  debug = false,
1609
- maxIterations
1678
+ maxIterations,
1679
+ maxIterationsMessage
1610
1680
  }) {
1611
1681
  const debugLog = react.useCallback(
1612
1682
  (...args) => {
@@ -1643,7 +1713,8 @@ function CopilotProvider({
1643
1713
  initialMessages: uiInitialMessages,
1644
1714
  streaming,
1645
1715
  debug,
1646
- maxIterations
1716
+ maxIterations,
1717
+ maxIterationsMessage
1647
1718
  },
1648
1719
  {
1649
1720
  onToolExecutionsChange: (executions) => {
@@ -3591,5 +3662,5 @@ exports.useToolExecutor = useToolExecutor;
3591
3662
  exports.useToolWithSchema = useToolWithSchema;
3592
3663
  exports.useTools = useTools;
3593
3664
  exports.useToolsWithSchema = useToolsWithSchema;
3594
- //# sourceMappingURL=chunk-C7YQX7ZT.cjs.map
3595
- //# sourceMappingURL=chunk-C7YQX7ZT.cjs.map
3665
+ //# sourceMappingURL=chunk-2IPWAEIC.cjs.map
3666
+ //# sourceMappingURL=chunk-2IPWAEIC.cjs.map