@yourgpt/copilot-sdk 1.4.3 → 1.4.32

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.
@@ -438,7 +438,7 @@ var AbstractChat = class {
438
438
  * Dynamic context from useAIContext hook
439
439
  */
440
440
  this.dynamicContext = "";
441
- this.isDisposed = false;
441
+ this._isDisposed = false;
442
442
  this.config = {
443
443
  runtimeUrl: init.runtimeUrl,
444
444
  llm: init.llm,
@@ -906,18 +906,35 @@ ${this.dynamicContext}`.trim() : this.config.systemPrompt,
906
906
  isAsyncIterable(value) {
907
907
  return value !== null && typeof value === "object" && Symbol.asyncIterator in value;
908
908
  }
909
+ /**
910
+ * Whether this instance has been disposed
911
+ */
912
+ get disposed() {
913
+ return this._isDisposed;
914
+ }
909
915
  /**
910
916
  * Dispose and cleanup
917
+ * Note: Event handlers are NOT cleared to support React StrictMode revive()
911
918
  */
912
919
  dispose() {
913
- if (this.isDisposed) {
920
+ if (this._isDisposed) {
914
921
  this.debug("dispose() called but already disposed - ignoring");
915
922
  return;
916
923
  }
917
- this.debug("dispose() - clearing event handlers");
918
- this.isDisposed = true;
924
+ this.debug("dispose() - stopping active requests");
925
+ this._isDisposed = true;
919
926
  this.stop();
920
- this.eventHandlers.clear();
927
+ }
928
+ /**
929
+ * Revive a disposed instance (for React StrictMode compatibility)
930
+ * This allows reusing an instance after dispose() was called
931
+ */
932
+ revive() {
933
+ if (!this._isDisposed) {
934
+ return;
935
+ }
936
+ this.debug("revive() - restoring disposed instance");
937
+ this._isDisposed = false;
921
938
  }
922
939
  };
923
940
 
@@ -932,10 +949,18 @@ var AbstractAgentLoop = class {
932
949
  this._isCancelled = false;
933
950
  // Cancellation support
934
951
  this.abortController = null;
935
- // Registered tools
952
+ // Registered tools with reference counting for React StrictMode compatibility
953
+ // Tools are never fully removed during a session - only marked as inactive
936
954
  this.registeredTools = /* @__PURE__ */ new Map();
937
955
  // Pending approvals - resolve with approval result including extraData
938
956
  this.pendingApprovals = /* @__PURE__ */ new Map();
957
+ // ============================================
958
+ // Cleanup
959
+ // ============================================
960
+ /**
961
+ * Dispose of resources
962
+ */
963
+ this._isDisposed = false;
939
964
  this.config = config;
940
965
  this.callbacks = callbacks;
941
966
  this._maxIterations = config.maxIterations ?? 20;
@@ -985,7 +1010,7 @@ var AbstractAgentLoop = class {
985
1010
  );
986
1011
  }
987
1012
  get tools() {
988
- return Array.from(this.registeredTools.values());
1013
+ return Array.from(this.registeredTools.values()).filter((entry) => entry.active).map((entry) => entry.tool);
989
1014
  }
990
1015
  // ============================================
991
1016
  // Private setters with callbacks
@@ -1019,22 +1044,42 @@ var AbstractAgentLoop = class {
1019
1044
  // Tool Registration
1020
1045
  // ============================================
1021
1046
  /**
1022
- * Register a tool
1047
+ * Register a tool (reference counted for React StrictMode compatibility)
1048
+ * Tools are never fully removed - ref counting ensures StrictMode works correctly
1023
1049
  */
1024
1050
  registerTool(tool) {
1025
- this.registeredTools.set(tool.name, tool);
1051
+ const existing = this.registeredTools.get(tool.name);
1052
+ if (existing) {
1053
+ existing.tool = tool;
1054
+ existing.refCount++;
1055
+ existing.active = true;
1056
+ } else {
1057
+ this.registeredTools.set(tool.name, {
1058
+ tool,
1059
+ refCount: 1,
1060
+ active: true
1061
+ });
1062
+ }
1026
1063
  }
1027
1064
  /**
1028
- * Unregister a tool
1065
+ * Unregister a tool (reference counted for React StrictMode compatibility)
1066
+ * Tool is only marked inactive when refCount reaches 0, never deleted
1029
1067
  */
1030
1068
  unregisterTool(name) {
1031
- this.registeredTools.delete(name);
1069
+ const entry = this.registeredTools.get(name);
1070
+ if (entry) {
1071
+ entry.refCount = Math.max(0, entry.refCount - 1);
1072
+ if (entry.refCount === 0) {
1073
+ entry.active = false;
1074
+ }
1075
+ }
1032
1076
  }
1033
1077
  /**
1034
- * Get a registered tool
1078
+ * Get a registered tool (returns active tools, or inactive if forExecution=true)
1035
1079
  */
1036
1080
  getTool(name) {
1037
- return this.registeredTools.get(name);
1081
+ const entry = this.registeredTools.get(name);
1082
+ return entry?.tool;
1038
1083
  }
1039
1084
  // ============================================
1040
1085
  // Tool Execution
@@ -1076,7 +1121,7 @@ var AbstractAgentLoop = class {
1076
1121
  * Execute a single tool
1077
1122
  */
1078
1123
  async executeSingleTool(toolCall) {
1079
- const tool = this.registeredTools.get(toolCall.name);
1124
+ const tool = this.getTool(toolCall.name);
1080
1125
  const execution = {
1081
1126
  id: toolCall.id,
1082
1127
  toolCallId: toolCall.id,
@@ -1287,20 +1332,39 @@ var AbstractAgentLoop = class {
1287
1332
  updateCallbacks(callbacks) {
1288
1333
  this.callbacks = { ...this.callbacks, ...callbacks };
1289
1334
  }
1290
- // ============================================
1291
- // Cleanup
1292
- // ============================================
1293
1335
  /**
1294
- * Dispose of resources
1336
+ * Whether this instance has been disposed
1337
+ */
1338
+ get disposed() {
1339
+ return this._isDisposed;
1340
+ }
1341
+ /**
1342
+ * Dispose and cleanup
1343
+ * Note: Tools are NOT cleared to support React StrictMode revive()
1295
1344
  */
1296
1345
  dispose() {
1346
+ if (this._isDisposed) {
1347
+ return;
1348
+ }
1349
+ this._isDisposed = true;
1297
1350
  for (const [_id, pending] of this.pendingApprovals) {
1298
1351
  pending.resolve({ approved: false });
1299
1352
  }
1300
1353
  this.pendingApprovals.clear();
1301
- this.registeredTools.clear();
1302
1354
  this._toolExecutions = [];
1303
1355
  }
1356
+ /**
1357
+ * Revive a disposed instance (for React StrictMode compatibility)
1358
+ * Tools are preserved across dispose/revive cycle
1359
+ */
1360
+ revive() {
1361
+ if (!this._isDisposed) {
1362
+ return;
1363
+ }
1364
+ this._isDisposed = false;
1365
+ this._isCancelled = false;
1366
+ this._maxIterationsReached = false;
1367
+ }
1304
1368
  };
1305
1369
 
1306
1370
  // src/chat/ChatWithTools.ts
@@ -1352,13 +1416,11 @@ var ChatWithTools = class {
1352
1416
  wireEvents() {
1353
1417
  this.debug("Wiring up toolCalls event handler");
1354
1418
  this.chat.on("toolCalls", async (event) => {
1355
- this.debug("\u{1F3AF} toolCalls event handler FIRED", event);
1356
1419
  const toolCalls = event.toolCalls;
1357
1420
  if (!toolCalls?.length) {
1358
- this.debug("No tool calls in event");
1359
1421
  return;
1360
1422
  }
1361
- this.debug("Tool calls received:", toolCalls);
1423
+ this.debug("Tool calls received:", toolCalls.length);
1362
1424
  const toolCallInfos = toolCalls.map((tc) => {
1363
1425
  const tcAny = tc;
1364
1426
  const name = tcAny.function?.name ?? tcAny.name ?? "";
@@ -1563,6 +1625,21 @@ var ChatWithTools = class {
1563
1625
  // ============================================
1564
1626
  // Cleanup
1565
1627
  // ============================================
1628
+ /**
1629
+ * Whether this instance has been disposed
1630
+ */
1631
+ get disposed() {
1632
+ return this.chat.disposed;
1633
+ }
1634
+ /**
1635
+ * Revive a disposed instance (for React StrictMode compatibility)
1636
+ * This allows reusing an instance after dispose() was called,
1637
+ * preserving registered tools and state
1638
+ */
1639
+ revive() {
1640
+ this.chat.revive();
1641
+ this.agentLoop.revive();
1642
+ }
1566
1643
  /**
1567
1644
  * Dispose and cleanup
1568
1645
  */
@@ -1694,6 +1771,12 @@ var ReactChatState = class {
1694
1771
  dispose() {
1695
1772
  this.subscribers.clear();
1696
1773
  }
1774
+ /**
1775
+ * Revive after dispose (for React StrictMode compatibility)
1776
+ * Subscribers will be re-added automatically via useSyncExternalStore
1777
+ */
1778
+ revive() {
1779
+ }
1697
1780
  };
1698
1781
  function createReactChatState(initialMessages) {
1699
1782
  return new ReactChatState(initialMessages);
@@ -1719,6 +1802,13 @@ var ReactChatWithTools = class extends ChatWithTools {
1719
1802
  super.dispose();
1720
1803
  this.reactState.dispose();
1721
1804
  }
1805
+ /**
1806
+ * Revive a disposed instance (for React StrictMode compatibility)
1807
+ */
1808
+ revive() {
1809
+ super.revive();
1810
+ this.reactState.revive();
1811
+ }
1722
1812
  };
1723
1813
 
1724
1814
  // src/react/utils/context-tree.ts
@@ -1830,6 +1920,10 @@ function CopilotProvider({
1830
1920
  }, [toolsConfig]);
1831
1921
  const [toolExecutions, setToolExecutions] = react.useState([]);
1832
1922
  const chatRef = react.useRef(null);
1923
+ if (chatRef.current !== null && chatRef.current.disposed) {
1924
+ chatRef.current.revive();
1925
+ debugLog("Revived disposed instance (React StrictMode)");
1926
+ }
1833
1927
  if (chatRef.current === null) {
1834
1928
  const uiInitialMessages = initialMessages?.map(
1835
1929
  (m) => ({
@@ -3689,6 +3783,13 @@ var ReactChat = class extends AbstractChat {
3689
3783
  super.dispose();
3690
3784
  this.reactState.dispose();
3691
3785
  }
3786
+ /**
3787
+ * Revive a disposed instance (for React StrictMode compatibility)
3788
+ */
3789
+ revive() {
3790
+ super.revive();
3791
+ this.reactState.revive();
3792
+ }
3692
3793
  };
3693
3794
  function createReactChat(config) {
3694
3795
  return new ReactChat(config);
@@ -3696,6 +3797,9 @@ function createReactChat(config) {
3696
3797
  function useChat(config) {
3697
3798
  const chatRef = react.useRef(null);
3698
3799
  const [input, setInput] = react.useState("");
3800
+ if (chatRef.current !== null && chatRef.current.disposed) {
3801
+ chatRef.current.revive();
3802
+ }
3699
3803
  if (chatRef.current === null) {
3700
3804
  chatRef.current = createReactChat({
3701
3805
  runtimeUrl: config.runtimeUrl,
@@ -3816,5 +3920,5 @@ exports.useToolExecutor = useToolExecutor;
3816
3920
  exports.useToolWithSchema = useToolWithSchema;
3817
3921
  exports.useTools = useTools;
3818
3922
  exports.useToolsWithSchema = useToolsWithSchema;
3819
- //# sourceMappingURL=chunk-N24PPVNQ.cjs.map
3820
- //# sourceMappingURL=chunk-N24PPVNQ.cjs.map
3923
+ //# sourceMappingURL=chunk-B7SF5SGS.cjs.map
3924
+ //# sourceMappingURL=chunk-B7SF5SGS.cjs.map