@copilotkit/react-core 1.60.2 → 1.61.1

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.
@@ -431,49 +431,72 @@ function useComponent(config, deps) {
431
431
  function useHumanInTheLoop(tool, deps) {
432
432
  const { copilotkit } = (0, _copilotkit_react_core_v2_context.useCopilotKit)();
433
433
  const resolvePromiseRef = (0, react.useRef)(null);
434
+ const cleanupAbortRef = (0, react.useRef)(null);
434
435
  const respond = (0, react.useCallback)(async (result) => {
435
436
  if (resolvePromiseRef.current) {
437
+ cleanupAbortRef.current?.();
438
+ cleanupAbortRef.current = null;
436
439
  resolvePromiseRef.current(result);
437
440
  resolvePromiseRef.current = null;
438
441
  }
439
442
  }, []);
440
- const handler = (0, react.useCallback)(async () => {
441
- return new Promise((resolve) => {
443
+ const handler = (0, react.useCallback)(async (_args, context) => {
444
+ const signal = context?.signal;
445
+ return new Promise((resolve, reject) => {
446
+ if (signal?.aborted) {
447
+ reject(/* @__PURE__ */ new Error("Human-in-the-loop interaction aborted"));
448
+ return;
449
+ }
442
450
  resolvePromiseRef.current = resolve;
451
+ if (signal) {
452
+ const onAbort = () => {
453
+ cleanupAbortRef.current = null;
454
+ resolvePromiseRef.current = null;
455
+ reject(/* @__PURE__ */ new Error("Human-in-the-loop interaction aborted"));
456
+ };
457
+ signal.addEventListener("abort", onAbort, { once: true });
458
+ cleanupAbortRef.current = () => {
459
+ signal.removeEventListener("abort", onAbort);
460
+ };
461
+ }
443
462
  });
444
463
  }, []);
445
464
  const RenderComponent = (0, react.useCallback)((props) => {
446
465
  const ToolComponent = tool.render;
447
- if (props.status === "inProgress") {
466
+ if (props.status === _copilotkit_core.ToolCallStatus.InProgress) {
448
467
  const enhancedProps = {
449
468
  ...props,
450
469
  name: tool.name,
451
470
  description: tool.description || "",
471
+ agentId: tool.agentId,
452
472
  respond: void 0
453
473
  };
454
474
  return react.default.createElement(ToolComponent, enhancedProps);
455
- } else if (props.status === "executing") {
475
+ } else if (props.status === _copilotkit_core.ToolCallStatus.Executing) {
456
476
  const enhancedProps = {
457
477
  ...props,
458
478
  name: tool.name,
459
479
  description: tool.description || "",
480
+ agentId: tool.agentId,
460
481
  respond
461
482
  };
462
483
  return react.default.createElement(ToolComponent, enhancedProps);
463
- } else if (props.status === "complete") {
484
+ } else if (props.status === _copilotkit_core.ToolCallStatus.Complete) {
464
485
  const enhancedProps = {
465
486
  ...props,
466
487
  name: tool.name,
467
488
  description: tool.description || "",
489
+ agentId: tool.agentId,
468
490
  respond: void 0
469
491
  };
470
492
  return react.default.createElement(ToolComponent, enhancedProps);
471
493
  }
472
- return react.default.createElement(ToolComponent, props);
494
+ return props;
473
495
  }, [
474
496
  tool.render,
475
497
  tool.name,
476
498
  tool.description,
499
+ tool.agentId,
477
500
  respond
478
501
  ]);
479
502
  useFrontendTool({
@@ -999,21 +1022,32 @@ function useThreads({ agentId, includeArchived, limit }) {
999
1022
  const headersKey = (0, react.useMemo)(() => {
1000
1023
  return JSON.stringify(Object.entries(copilotkit.headers ?? {}).sort(([left], [right]) => left.localeCompare(right)));
1001
1024
  }, [copilotkit.headers]);
1025
+ const runtimeStatus = copilotkit.runtimeConnectionStatus;
1026
+ const threadListEndpointSupported = copilotkit.threadEndpoints?.list !== false;
1027
+ const threadMutationsSupported = copilotkit.threadEndpoints?.mutations !== false;
1028
+ const threadEndpointsUnavailable = !!copilotkit.runtimeUrl && runtimeStatus === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Connected && !threadListEndpointSupported;
1002
1029
  const runtimeError = (0, react.useMemo)(() => {
1003
1030
  if (copilotkit.runtimeUrl) return null;
1004
1031
  return /* @__PURE__ */ new Error("Runtime URL is not configured");
1005
1032
  }, [copilotkit.runtimeUrl]);
1033
+ const threadEndpointsError = (0, react.useMemo)(() => {
1034
+ if (!threadEndpointsUnavailable) return null;
1035
+ return /* @__PURE__ */ new Error("Thread endpoints are not available on this CopilotKit runtime");
1036
+ }, [threadEndpointsUnavailable]);
1037
+ const threadMutationsError = (0, react.useMemo)(() => {
1038
+ if (threadMutationsSupported) return null;
1039
+ return /* @__PURE__ */ new Error("Thread mutations are not available on this CopilotKit runtime");
1040
+ }, [threadMutationsSupported]);
1006
1041
  const [hasDispatchedContext, setHasDispatchedContext] = (0, react.useState)(false);
1007
- const preConnectLoading = !!copilotkit.runtimeUrl && !hasDispatchedContext;
1008
- const isLoading = runtimeError ? false : preConnectLoading || storeIsLoading;
1009
- const error = runtimeError ?? storeError;
1042
+ const preConnectLoading = !!copilotkit.runtimeUrl && !threadEndpointsUnavailable && !hasDispatchedContext;
1043
+ const isLoading = runtimeError || threadEndpointsError ? false : preConnectLoading || storeIsLoading;
1044
+ const error = runtimeError ?? threadEndpointsError ?? storeError;
1010
1045
  (0, react.useEffect)(() => {
1011
1046
  store.start();
1012
1047
  return () => {
1013
1048
  store.stop();
1014
1049
  };
1015
1050
  }, [store]);
1016
- const runtimeStatus = copilotkit.runtimeConnectionStatus;
1017
1051
  (0, react.useEffect)(() => {
1018
1052
  copilotkit.registerThreadStore(agentId, store);
1019
1053
  return () => {
@@ -1027,9 +1061,15 @@ function useThreads({ agentId, includeArchived, limit }) {
1027
1061
  (0, react.useEffect)(() => {
1028
1062
  if (!copilotkit.runtimeUrl) {
1029
1063
  store.setContext(null);
1064
+ setHasDispatchedContext(false);
1030
1065
  return;
1031
1066
  }
1032
1067
  if (runtimeStatus !== _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Connected) return;
1068
+ if (!threadListEndpointSupported) {
1069
+ store.setContext(null);
1070
+ setHasDispatchedContext(false);
1071
+ return;
1072
+ }
1033
1073
  const context = {
1034
1074
  runtimeUrl: copilotkit.runtimeUrl,
1035
1075
  headers: { ...copilotkit.headers },
@@ -1046,13 +1086,20 @@ function useThreads({ agentId, includeArchived, limit }) {
1046
1086
  runtimeStatus,
1047
1087
  headersKey,
1048
1088
  copilotkit.intelligence?.wsUrl,
1089
+ threadListEndpointSupported,
1049
1090
  agentId,
1050
1091
  includeArchived,
1051
1092
  limit
1052
1093
  ]);
1053
- const renameThread = (0, react.useCallback)((threadId, name) => store.renameThread(threadId, name), [store]);
1054
- const archiveThread = (0, react.useCallback)((threadId) => store.archiveThread(threadId), [store]);
1055
- const deleteThread = (0, react.useCallback)((threadId) => store.deleteThread(threadId), [store]);
1094
+ const guardMutation = (0, react.useCallback)((mutation) => {
1095
+ return (...args) => {
1096
+ if (threadMutationsError) return Promise.reject(threadMutationsError);
1097
+ return mutation(...args);
1098
+ };
1099
+ }, [threadMutationsError]);
1100
+ const renameThread = (0, react.useMemo)(() => guardMutation((threadId, name) => store.renameThread(threadId, name)), [store, guardMutation]);
1101
+ const archiveThread = (0, react.useMemo)(() => guardMutation((threadId) => store.archiveThread(threadId)), [store, guardMutation]);
1102
+ const deleteThread = (0, react.useMemo)(() => guardMutation((threadId) => store.deleteThread(threadId)), [store, guardMutation]);
1056
1103
  return {
1057
1104
  threads,
1058
1105
  isLoading,