@copilotkit/react-core 1.77.0 → 1.77.2

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.
@@ -1655,7 +1655,7 @@ function useRenderToolCall() {
1655
1655
 
1656
1656
  //#endregion
1657
1657
  //#region package.json
1658
- var version = "1.77.0";
1658
+ var version = "1.77.2";
1659
1659
 
1660
1660
  //#endregion
1661
1661
  //#region src/v2/components/CopilotKitInspector.tsx
@@ -3412,7 +3412,12 @@ const DEFAULT_DESIGN_SKILL = `When generating UI with generateSandboxedUi, follo
3412
3412
  - Use CSS Grid or Flexbox for layout. Ensure the UI looks good at any width.
3413
3413
  - Minimal transitions (150ms) for hover/focus states only. No decorative animations.
3414
3414
  - Keep the UI focused and dense — avoid excessive padding. Use compact spacing (8–12px gaps, 10–14px padding in controls).`;
3415
- const GENERATE_SANDBOXED_UI_DESCRIPTION = "Generate sandboxed UI. IMPORTANT: The generated code runs in a sandboxed iframe WITHOUT same-origin access. Do NOT use localStorage, sessionStorage, document.cookie, IndexedDB, or fetch/XMLHttpRequest to same-origin URLs. To communicate with the host application, use Websandbox.connection.remote.<functionName>(args) which returns a Promise.\n\nYou CAN use external libraries from CDNs by including <script> or <link> tags in the HTML <head> (e.g., Chart.js, D3, Three.js, x-data-spreadsheet, etc.). CDN resources load normally inside the sandbox.\n\nPARAMETER ORDER IS CRITICAL — generate parameters in exactly this order:\n1. initialHeight + placeholderMessages (shown to user while generating)\n2. css (all styles FIRST — the user sees a placeholder until CSS is complete)\n3. html (streams in live — the user watches the UI build as HTML is generated)\n4. jsFunctions (reusable helper functions)\n5. jsExpressions (applied one-by-one — the user sees each expression take effect)";
3415
+ const DEFAULT_LEARNING = Object.freeze({});
3416
+ function toLearningConfig(learning) {
3417
+ if (learning === true) return DEFAULT_LEARNING;
3418
+ if (learning === false) return void 0;
3419
+ return learning;
3420
+ }
3416
3421
  function useStableArrayProp(prop, warningMessage, isMeaningfulChange) {
3417
3422
  const empty = (0, react.useMemo)(() => [], []);
3418
3423
  const value = prop ?? empty;
@@ -3423,6 +3428,7 @@ function useStableArrayProp(prop, warningMessage, isMeaningfulChange) {
3423
3428
  return value;
3424
3429
  }
3425
3430
  const CopilotKitProvider = ({ children, runtimeUrl, headers: headersProp = EMPTY_HEADERS, credentials, messageFilter, publicApiKey, publicLicenseKey, licenseToken, properties = EMPTY_PROPERTIES, agents__unsafe_dev_only: agents = EMPTY_AGENTS, selfManagedAgents = EMPTY_AGENTS, renderToolCalls, renderActivityMessages, renderCustomMessages, frontendTools, humanInTheLoop, openGenerativeUI, enableInspector, agentId, showIntelligenceIndicator = true, useSingleEndpoint, onError, a2ui, defaultThrottleMs, debug, learning }) => {
3431
+ const learningConfig = toLearningConfig(learning);
3426
3432
  const [shouldRenderInspector, setShouldRenderInspector] = (0, react.useState)(false);
3427
3433
  const [inspectorVisible, setInspectorVisible] = (0, react.useState)(false);
3428
3434
  (0, react.useEffect)(() => {
@@ -3605,7 +3611,7 @@ const CopilotKitProvider = ({ children, runtimeUrl, headers: headersProp = EMPTY
3605
3611
  if (!openGenUIActive) return [];
3606
3612
  return [{
3607
3613
  name: "generateSandboxedUi",
3608
- description: GENERATE_SANDBOXED_UI_DESCRIPTION,
3614
+ description: _copilotkit_shared.GENERATE_SANDBOXED_UI_DESCRIPTION,
3609
3615
  parameters: GenerateSandboxedUiArgsSchema,
3610
3616
  handler: async () => "UI generated",
3611
3617
  followUp: true,
@@ -3658,7 +3664,7 @@ const CopilotKitProvider = ({ children, runtimeUrl, headers: headersProp = EMPTY
3658
3664
  renderActivityMessages: allActivityRenderers,
3659
3665
  renderCustomMessages: renderCustomMessagesList,
3660
3666
  debug,
3661
- learning
3667
+ learning: learningConfig
3662
3668
  });
3663
3669
  if (defaultThrottleMs !== void 0) copilotkitRef.current.setDefaultThrottleMs(defaultThrottleMs);
3664
3670
  }
@@ -3763,17 +3769,21 @@ const CopilotKitProvider = ({ children, runtimeUrl, headers: headersProp = EMPTY
3763
3769
  useSingleEndpoint,
3764
3770
  debug
3765
3771
  ]);
3766
- const learningEnabled = learning !== void 0;
3767
- const trajectoryId = learning?.trajectoryId;
3768
- const learningContainerIdsRef = (0, react.useRef)(learning?.learningContainerIds);
3769
- (0, react.useEffect)(() => {
3770
- copilotkit.setLearningConfig(learning);
3771
- learningContainerIdsRef.current = learning?.learningContainerIds;
3772
- if (learning?.sink === void 0 && learning?.trajectoryId === void 0 && learning?.learningContainerIds !== void 0) console.warn("[CopilotKit] learningContainerIds is supported only with a custom sink. Authenticated Trajectory capture does not assign Learning Containers; remove learningContainerIds from the capture options.");
3773
- }, [copilotkit, learning]);
3774
- (0, react.useEffect)(() => {
3772
+ const learningEnabled = learningConfig !== void 0;
3773
+ const generatesTrajectoryId = learning === true;
3774
+ const suppliedTrajectoryId = learningConfig?.trajectoryId;
3775
+ const learningContainerIdsRef = (0, react.useRef)(learningConfig?.learningContainerIds);
3776
+ const generatedTrajectoryIdRef = (0, react.useRef)(void 0);
3777
+ (0, react.useEffect)(() => {
3778
+ copilotkit.setLearningConfig(learningConfig);
3779
+ learningContainerIdsRef.current = learningConfig?.learningContainerIds;
3780
+ if (learningConfig?.sink === void 0 && learningConfig?.trajectoryId === void 0 && learningConfig?.learningContainerIds !== void 0) console.warn("[CopilotKit] learningContainerIds is supported only with a custom sink. Authenticated Trajectory capture does not assign Learning Containers; remove learningContainerIds from the capture options.");
3781
+ }, [copilotkit, learningConfig]);
3782
+ (0, react.useEffect)(() => {
3783
+ if (!generatesTrajectoryId) generatedTrajectoryIdRef.current = void 0;
3775
3784
  if (!learningEnabled) return;
3776
3785
  let disposed = false;
3786
+ const trajectoryId = generatesTrajectoryId ? generatedTrajectoryIdRef.current ??= (0, _copilotkit_shared.randomUUID)() : suppliedTrajectoryId;
3777
3787
  if (trajectoryId !== void 0) copilotkit.startTrajectory({
3778
3788
  trajectoryId,
3779
3789
  learningContainerIds: learningContainerIdsRef.current
@@ -3787,7 +3797,8 @@ const CopilotKitProvider = ({ children, runtimeUrl, headers: headersProp = EMPTY
3787
3797
  }, [
3788
3798
  copilotkit,
3789
3799
  learningEnabled,
3790
- trajectoryId
3800
+ generatesTrajectoryId,
3801
+ suppliedTrajectoryId
3791
3802
  ]);
3792
3803
  const didMountRef = (0, react.useRef)(false);
3793
3804
  (0, react.useEffect)(() => {
@@ -7684,8 +7695,23 @@ function deduplicateMessages(messages) {
7684
7695
  }
7685
7696
  return [...acc.values()];
7686
7697
  }
7698
+ /** A row holding a single message, rendered as it would be ungrouped. */
7699
+ function messageRow(message) {
7700
+ return {
7701
+ type: "message",
7702
+ message
7703
+ };
7704
+ }
7705
+ /** A row holding a group of messages, rendered inside `wrapper`. */
7706
+ function messageGroup(group) {
7707
+ return {
7708
+ type: "group",
7709
+ ...group
7710
+ };
7711
+ }
7712
+ const GROUP_ROW_KEY_PREFIX = "copilotkit-group:";
7687
7713
  const VIRTUALIZE_THRESHOLD = 50;
7688
- function CopilotChatMessageView({ messages = [], assistantMessage, userMessage, reasoningMessage, cursor, intelligenceIndicator, isRunning = false, transformMessages, children, className, ...props }) {
7714
+ function CopilotChatMessageView({ messages = [], assistantMessage, userMessage, reasoningMessage, cursor, intelligenceIndicator, isRunning = false, transformMessages, groupMessages, children, className, ...props }) {
7689
7715
  const isPinnedToBottom = (0, react.useContext)(ScrollPinnedContext);
7690
7716
  const renderCustomMessage = useRenderCustomMessages();
7691
7717
  const { renderActivityMessage } = useRenderActivityMessage();
@@ -7718,20 +7744,43 @@ function CopilotChatMessageView({ messages = [], assistantMessage, userMessage,
7718
7744
  return copilotkit.getStateByRun(config.agentId, config.threadId, resolvedRunId);
7719
7745
  };
7720
7746
  const deduplicatedMessages = (0, react.useMemo)(() => deduplicateMessages(messages), [messages]);
7721
- const renderedMessages = (0, react.useMemo)(() => transformMessages ? transformMessages(deduplicatedMessages) : deduplicatedMessages, [deduplicatedMessages, transformMessages]);
7747
+ const transformedMessages = (0, react.useMemo)(() => transformMessages ? transformMessages(deduplicatedMessages) : deduplicatedMessages, [deduplicatedMessages, transformMessages]);
7748
+ const rows = (0, react.useMemo)(() => groupMessages ? groupMessages(transformedMessages) : transformedMessages.map(messageRow), [transformedMessages, groupMessages]);
7749
+ const renderedMessages = (0, react.useMemo)(() => groupMessages ? rows.flatMap((row) => row.type === "group" ? row.messages : [row.message]) : transformedMessages, [
7750
+ rows,
7751
+ groupMessages,
7752
+ transformedMessages
7753
+ ]);
7722
7754
  const latestRenderedId = renderedMessages[renderedMessages.length - 1]?.id;
7723
7755
  const transformDuplicateId = (0, react.useMemo)(() => {
7724
- if (process.env.NODE_ENV === "production" || !transformMessages) return;
7756
+ if (process.env.NODE_ENV === "production" || !transformMessages && !groupMessages) return;
7725
7757
  const seen = /* @__PURE__ */ new Set();
7726
7758
  for (const message of renderedMessages) {
7727
7759
  if (seen.has(message.id)) return message.id;
7728
7760
  seen.add(message.id);
7729
7761
  }
7730
- }, [renderedMessages, transformMessages]);
7762
+ }, [
7763
+ renderedMessages,
7764
+ transformMessages,
7765
+ groupMessages
7766
+ ]);
7731
7767
  (0, react.useEffect)(() => {
7732
7768
  if (transformDuplicateId === void 0) return;
7733
- console.warn(`[CopilotKit] CopilotChatMessageView: \`transformMessages\` returned more than one message with id "${transformDuplicateId}". Return each id at most once; a message you create needs its own id, stable across renders.`);
7734
- }, [transformDuplicateId]);
7769
+ console.warn(groupMessages ? `[CopilotKit] CopilotChatMessageView: the message with id "${transformDuplicateId}" renders more than once. \`groupMessages\` should place each message in at most one row, and \`transformMessages\` return each id at most once.` : `[CopilotKit] CopilotChatMessageView: \`transformMessages\` returned more than one message with id "${transformDuplicateId}". Return each id at most once; a message you create needs its own id, stable across renders.`);
7770
+ }, [transformDuplicateId, groupMessages]);
7771
+ const duplicateGroupKey = (0, react.useMemo)(() => {
7772
+ if (process.env.NODE_ENV === "production" || !groupMessages) return;
7773
+ const seen = /* @__PURE__ */ new Set();
7774
+ for (const row of rows) {
7775
+ if (row.type !== "group") continue;
7776
+ if (seen.has(row.key)) return row.key;
7777
+ seen.add(row.key);
7778
+ }
7779
+ }, [rows, groupMessages]);
7780
+ (0, react.useEffect)(() => {
7781
+ if (duplicateGroupKey === void 0) return;
7782
+ console.warn(`[CopilotKit] CopilotChatMessageView: \`groupMessages\` returned more than one group with key "${duplicateGroupKey}". Give each group its own key, stable across renders.`);
7783
+ }, [duplicateGroupKey]);
7735
7784
  const rowKeyStoreRef = (0, react.useRef)(null);
7736
7785
  rowKeyStoreRef.current ??= (0, _copilotkit_shared.createRowKeyStore)();
7737
7786
  const rowKeyStore = rowKeyStoreRef.current;
@@ -7739,6 +7788,31 @@ function CopilotChatMessageView({ messages = [], assistantMessage, userMessage,
7739
7788
  (0, react.useLayoutEffect)(() => {
7740
7789
  (0, _copilotkit_shared.commitRowKeyStore)(rowKeyStore, renderedMessages);
7741
7790
  }, [rowKeyStore, renderedMessages]);
7791
+ const stableGroupKey = (key) => rowRenderKeys.get(key) ?? key;
7792
+ const groupStateRef = (0, react.useRef)(/* @__PURE__ */ new Map());
7793
+ const groupSettersRef = (0, react.useRef)(/* @__PURE__ */ new Map());
7794
+ const groupStateThreadRef = (0, react.useRef)(config?.threadId);
7795
+ if (groupStateThreadRef.current !== config?.threadId) {
7796
+ groupStateThreadRef.current = config?.threadId;
7797
+ groupStateRef.current = /* @__PURE__ */ new Map();
7798
+ groupSettersRef.current = /* @__PURE__ */ new Map();
7799
+ }
7800
+ const groupSetter = (key) => {
7801
+ let setter = groupSettersRef.current.get(key);
7802
+ if (!setter) {
7803
+ setter = (next) => {
7804
+ groupStateRef.current.set(key, next);
7805
+ forceUpdate();
7806
+ };
7807
+ groupSettersRef.current.set(key, setter);
7808
+ }
7809
+ return setter;
7810
+ };
7811
+ (0, react.useLayoutEffect)(() => {
7812
+ const live = /* @__PURE__ */ new Set();
7813
+ for (const row of rows) if (row.type === "group") live.add(stableGroupKey(row.key));
7814
+ for (const store of [groupStateRef.current, groupSettersRef.current]) for (const key of store.keys()) if (!live.has(key)) store.delete(key);
7815
+ }, [rows, rowRenderKeys]);
7742
7816
  if (process.env.NODE_ENV === "development" && deduplicatedMessages.length < messages.length) console.warn(`CopilotChatMessageView: Merged ${messages.length - deduplicatedMessages.length} message(s) with duplicate IDs.`);
7743
7817
  const { Component: AssistantComponent, slotProps: assistantSlotProps } = (0, react.useMemo)(() => resolveSlotComponent(assistantMessage, CopilotChatAssistantMessage_default), [assistantMessage]);
7744
7818
  const agentId = config?.agentId;
@@ -7778,7 +7852,7 @@ function CopilotChatMessageView({ messages = [], assistantMessage, userMessage,
7778
7852
  (0, react.useEffect)(() => {
7779
7853
  if (process.env.NODE_ENV === "production" || !childrenDisabledVirtualization || warnedChildrenRef.current) return;
7780
7854
  warnedChildrenRef.current = true;
7781
- console.warn(`[CopilotKit] CopilotChatMessageView: the \`children\` render prop disables virtualization, so all ${renderedMessages.length} messages are mounted. ` + (transformMessages ? "`transformMessages` keeps virtualization on by itself; drop `children` to use it." : "To reshape the list and keep virtualization, use `transformMessages` instead."));
7855
+ console.warn(`[CopilotKit] CopilotChatMessageView: the \`children\` render prop disables virtualization, so all ${renderedMessages.length} messages are mounted. ` + (transformMessages || groupMessages ? "`transformMessages` and `groupMessages` keep virtualization on by themselves; drop `children` to use them." : "To reshape the list and keep virtualization, use `transformMessages` instead, or `groupMessages` to render several messages as one row."));
7782
7856
  }, [
7783
7857
  childrenDisabledVirtualization,
7784
7858
  renderedMessages.length,
@@ -7818,7 +7892,7 @@ function CopilotChatMessageView({ messages = [], assistantMessage, userMessage,
7818
7892
  return item.start < (instance.scrollOffset ?? 0) + scrollAdjustments;
7819
7893
  }, []);
7820
7894
  const virtualizer = (0, _tanstack_react_virtual.useVirtualizer)({
7821
- count: shouldVirtualize ? renderedMessages.length : 0,
7895
+ count: shouldVirtualize ? rows.length : 0,
7822
7896
  getScrollElement: () => scrollElement,
7823
7897
  estimateSize: estimateRowSize,
7824
7898
  overscan: 5,
@@ -7831,8 +7905,8 @@ function CopilotChatMessageView({ messages = [], assistantMessage, userMessage,
7831
7905
  isPinnedToBottomRef.current = isPinnedToBottom;
7832
7906
  virtualizer.shouldAdjustScrollPositionOnItemSizeChange = shouldAdjustScrollOnResize;
7833
7907
  (0, react.useLayoutEffect)(() => {
7834
- if (!shouldVirtualize || !renderedMessages.length) return;
7835
- virtualizer.scrollToIndex(renderedMessages.length - 1, { align: "end" });
7908
+ if (!shouldVirtualize || !rows.length) return;
7909
+ virtualizer.scrollToIndex(rows.length - 1, { align: "end" });
7836
7910
  }, [shouldVirtualize, firstMessageId]);
7837
7911
  const intelligenceTurnAnchors = (0, react.useMemo)(() => getIntelligenceTurnAnchors(deduplicatedMessages, renderedMessages), [deduplicatedMessages, renderedMessages]);
7838
7912
  const renderMessageBlock = (message) => {
@@ -7884,7 +7958,20 @@ function CopilotChatMessageView({ messages = [], assistantMessage, userMessage,
7884
7958
  }, `intelligence-${intelligenceTurnId}`));
7885
7959
  return elements.filter(Boolean);
7886
7960
  };
7887
- const messageElements = shouldVirtualize ? [] : renderedMessages.flatMap(renderMessageBlock);
7961
+ const rowKey = (row) => row.type === "group" ? `${GROUP_ROW_KEY_PREFIX}${stableGroupKey(row.key)}` : rowRenderKeys.get(row.message.id) ?? row.message.id;
7962
+ const renderRow = (row) => {
7963
+ if (row.type === "message") return renderMessageBlock(row.message);
7964
+ const Wrapper = row.wrapper;
7965
+ const stateKey = stableGroupKey(row.key);
7966
+ return [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Wrapper, {
7967
+ groupKey: row.key,
7968
+ messages: row.messages,
7969
+ state: groupStateRef.current.get(stateKey),
7970
+ setState: groupSetter(stateKey),
7971
+ children: row.messages.flatMap(renderMessageBlock)
7972
+ }, rowKey(row))];
7973
+ };
7974
+ const messageElements = shouldVirtualize ? [] : rows.flatMap(renderRow);
7888
7975
  if (children) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7889
7976
  "data-copilotkit": true,
7890
7977
  style: { display: "contents" },
@@ -7909,7 +7996,7 @@ function CopilotChatMessageView({ messages = [], assistantMessage, userMessage,
7909
7996
  position: "relative"
7910
7997
  },
7911
7998
  children: virtualizer.getVirtualItems().map((virtualItem) => {
7912
- const message = renderedMessages[virtualItem.index];
7999
+ const row = rows[virtualItem.index];
7913
8000
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7914
8001
  "data-index": virtualItem.index,
7915
8002
  ref: virtualizer.measureElement,
@@ -7920,8 +8007,8 @@ function CopilotChatMessageView({ messages = [], assistantMessage, userMessage,
7920
8007
  width: "100%",
7921
8008
  transform: `translateY(${virtualItem.start}px)`
7922
8009
  },
7923
- children: renderMessageBlock(message)
7924
- }, rowRenderKeys.get(message.id) ?? message.id);
8010
+ children: renderRow(row)
8011
+ }, rowKey(row));
7925
8012
  })
7926
8013
  }) : messageElements,
7927
8014
  interruptElement,
@@ -8989,6 +9076,29 @@ function CopilotChat({ agentId, threadId, labels, inspectorTools, chatView, isMo
8989
9076
  const [lastConnectedThreadId, setLastConnectedThreadId] = (0, react.useState)(null);
8990
9077
  const isConnecting = hasExplicitThreadId && lastConnectedThreadId !== resolvedThreadId;
8991
9078
  const activeConnectCountRef = (0, react.useRef)(0);
9079
+ const pendingConnectionsRef = (0, react.useRef)(/* @__PURE__ */ new Map());
9080
+ const failedConnectionsRef = (0, react.useRef)(/* @__PURE__ */ new WeakSet());
9081
+ const submissionQueueRef = (0, react.useRef)(Promise.resolve());
9082
+ const trackConnection = (0, react.useCallback)((connectingAgent, connect) => {
9083
+ const selection = previousThreadRef.current;
9084
+ const connectingThreadId = connectingAgent.threadId;
9085
+ let failed = false;
9086
+ const subscription = copilotkit.subscribe({ onError: (event) => {
9087
+ if (selection?.active && previousThreadRef.current === selection && event.context?.agentId === connectingAgent.agentId && (!event.context.threadId || event.context.threadId === connectingThreadId) && (event.code === _copilotkit_core.CopilotKitCoreErrorCode.AGENT_CONNECT_FAILED || event.code === _copilotkit_core.CopilotKitCoreErrorCode.AGENT_RUN_FAILED_EVENT)) failed = true;
9088
+ } });
9089
+ const pending = connect().catch((error) => {
9090
+ failed = true;
9091
+ console.error("CopilotChat: connection failed", error);
9092
+ }).finally(() => {
9093
+ subscription.unsubscribe();
9094
+ if (pendingConnectionsRef.current.get(connectingAgent) === pending) {
9095
+ pendingConnectionsRef.current.delete(connectingAgent);
9096
+ if (selection?.active && previousThreadRef.current === selection) if (failed) failedConnectionsRef.current.add(connectingAgent);
9097
+ else failedConnectionsRef.current.delete(connectingAgent);
9098
+ }
9099
+ });
9100
+ pendingConnectionsRef.current.set(connectingAgent, pending);
9101
+ }, [copilotkit]);
8992
9102
  const pendingRunActivityReconnectRef = (0, react.useRef)(false);
8993
9103
  const runActivityReconnectGenerationRef = (0, react.useRef)(0);
8994
9104
  const activeLocalRunIdsRef = (0, react.useRef)(/* @__PURE__ */ new Set());
@@ -9048,9 +9158,12 @@ function CopilotChat({ agentId, threadId, labels, inspectorTools, chatView, isMo
9048
9158
  const selection = {
9049
9159
  threadId: resolvedThreadId,
9050
9160
  inspectorRequestId,
9051
- agent
9161
+ agent,
9162
+ active: true
9052
9163
  };
9053
9164
  previousThreadRef.current = selection;
9165
+ submissionQueueRef.current = Promise.resolve();
9166
+ failedConnectionsRef.current.delete(agent);
9054
9167
  const discardedThreadId = previousThread?.agent === agent ? previousThread.threadId : agent.threadId;
9055
9168
  if (inspectorTransition) if (typeof copilotkit.stopAgent === "function") copilotkit.stopAgent({ agent });
9056
9169
  else agent.abortRun?.();
@@ -9088,6 +9201,7 @@ function CopilotChat({ agentId, threadId, labels, inspectorTools, chatView, isMo
9088
9201
  }
9089
9202
  return () => {
9090
9203
  active = false;
9204
+ selection.active = false;
9091
9205
  };
9092
9206
  }
9093
9207
  let detached = false;
@@ -9101,8 +9215,8 @@ function CopilotChat({ agentId, threadId, labels, inspectorTools, chatView, isMo
9101
9215
  await copilotkit.connectAgent({ agent: agentToConnect });
9102
9216
  } catch (error) {
9103
9217
  if (detached) return;
9104
- console.error("CopilotChat: connectAgent failed", error);
9105
9218
  if (inspectorRequestId) failInspectorOverride(inspectorRequestId);
9219
+ throw error;
9106
9220
  } finally {
9107
9221
  if (!detached) (typeof requestAnimationFrame === "function" ? requestAnimationFrame : (cb) => setTimeout(cb, 16))(() => {
9108
9222
  if (!detached) setLastConnectedThreadId(resolvedThreadId);
@@ -9118,8 +9232,9 @@ function CopilotChat({ agentId, threadId, labels, inspectorTools, chatView, isMo
9118
9232
  }
9119
9233
  }
9120
9234
  };
9121
- connect(agent);
9235
+ trackConnection(agent, () => connect(agent));
9122
9236
  return () => {
9237
+ selection.active = false;
9123
9238
  detached = true;
9124
9239
  connectAbortController.abort();
9125
9240
  const detach = agent.detachActiveRun().catch(() => {});
@@ -9182,7 +9297,7 @@ function CopilotChat({ agentId, threadId, labels, inspectorTools, chatView, isMo
9182
9297
  await copilotkit.connectAgent({ agent });
9183
9298
  didConnect = true;
9184
9299
  } catch (error) {
9185
- if (!detached) console.error("CopilotChat: run activity reconnect failed", error);
9300
+ if (!detached) throw error;
9186
9301
  } finally {
9187
9302
  if (wakeRunId) {
9188
9303
  activeWakeRunIdsRef.current.delete(wakeRunId);
@@ -9192,7 +9307,7 @@ function CopilotChat({ agentId, threadId, labels, inspectorTools, chatView, isMo
9192
9307
  wakeReconnectActive = false;
9193
9308
  if (!detached && runActivityReconnectGenerationRef.current === generation && activeConnectCountRef.current === 0 && pendingRunActivityReconnectRef.current) {
9194
9309
  pendingRunActivityReconnectRef.current = false;
9195
- connect();
9310
+ trackConnection(agent, connect);
9196
9311
  }
9197
9312
  }
9198
9313
  };
@@ -9208,7 +9323,7 @@ function CopilotChat({ agentId, threadId, labels, inspectorTools, chatView, isMo
9208
9323
  return;
9209
9324
  }
9210
9325
  pendingRunActivityReconnectRef.current = false;
9211
- connect();
9326
+ trackConnection(agent, connect);
9212
9327
  };
9213
9328
  const subscription = threadStore.subscribeToRunActivity((notification) => {
9214
9329
  if (notification.threadId !== resolvedThreadId) return;
@@ -9251,6 +9366,18 @@ function CopilotChat({ agentId, threadId, labels, inspectorTools, chatView, isMo
9251
9366
  rememberRecentlyWakeRunId
9252
9367
  ]);
9253
9368
  const waitForActiveRunToSettle = (0, react.useCallback)(async () => {
9369
+ const selection = previousThreadRef.current;
9370
+ const isCurrentSelection = () => selection?.active && previousThreadRef.current === selection;
9371
+ let connection = pendingConnectionsRef.current.get(agent);
9372
+ while (connection && isCurrentSelection()) {
9373
+ await connection;
9374
+ connection = pendingConnectionsRef.current.get(agent);
9375
+ }
9376
+ if (!isCurrentSelection()) return false;
9377
+ if (failedConnectionsRef.current.has(agent)) {
9378
+ setTranscriptionError("Could not load saved conversation. Reopen the thread and try again.");
9379
+ return "failed";
9380
+ }
9254
9381
  const maybeAware = agent;
9255
9382
  const activeRunCompletionPromise = (0, _copilotkit_core.isRunCompletionAware)(maybeAware) ? maybeAware.activeRunCompletionPromise : void 0;
9256
9383
  if (agent.isRunning && activeRunCompletionPromise) try {
@@ -9258,7 +9385,18 @@ function CopilotChat({ agentId, threadId, labels, inspectorTools, chatView, isMo
9258
9385
  } catch (error) {
9259
9386
  console.error("CopilotChat: in-flight run rejected while queuing send", error);
9260
9387
  }
9388
+ return isCurrentSelection();
9261
9389
  }, [agent]);
9390
+ const enqueueSubmission = (0, react.useCallback)((submit) => {
9391
+ const selection = previousThreadRef.current;
9392
+ const pending = submissionQueueRef.current.then(async () => {
9393
+ if (selection?.active && previousThreadRef.current === selection) await submit();
9394
+ }).catch((error) => {
9395
+ console.error("CopilotChat: queued submission failed", error);
9396
+ });
9397
+ submissionQueueRef.current = pending;
9398
+ return pending;
9399
+ }, []);
9262
9400
  const onSubmitInput = (0, react.useCallback)(async (value) => {
9263
9401
  if (selectedAttachmentsRef.current.some((a) => a.status === "uploading")) {
9264
9402
  console.error("[CopilotKit] Cannot send while attachments are uploading (pre-await guard)");
@@ -9266,92 +9404,102 @@ function CopilotChat({ agentId, threadId, labels, inspectorTools, chatView, isMo
9266
9404
  return;
9267
9405
  }
9268
9406
  setInputValue("");
9269
- await waitForActiveRunToSettle();
9270
- if (selectedAttachmentsRef.current.some((a) => a.status === "uploading")) {
9271
- console.error("[CopilotKit] Cannot send while attachments are uploading (post-await re-check)");
9272
- setTranscriptionError("Cannot send while attachments are uploading.");
9273
- setInputValue(value);
9274
- return;
9275
- }
9276
- const readyAttachments = consumeAttachments();
9277
- if (readyAttachments.length > 0) {
9278
- const contentParts = [];
9279
- if (value.trim()) contentParts.push({
9280
- type: "text",
9281
- text: value
9282
- });
9283
- for (const att of readyAttachments) contentParts.push((0, _copilotkit_shared.createAttachmentContent)(att));
9284
- agent.addMessage({
9407
+ await enqueueSubmission(async () => {
9408
+ const ready = await waitForActiveRunToSettle();
9409
+ if (ready !== true) {
9410
+ if (ready === "failed") setInputValue(value);
9411
+ return;
9412
+ }
9413
+ if (selectedAttachmentsRef.current.some((a) => a.status === "uploading")) {
9414
+ console.error("[CopilotKit] Cannot send while attachments are uploading (post-await re-check)");
9415
+ setTranscriptionError("Cannot send while attachments are uploading.");
9416
+ setInputValue(value);
9417
+ return;
9418
+ }
9419
+ const readyAttachments = consumeAttachments();
9420
+ if (readyAttachments.length > 0) {
9421
+ const contentParts = [];
9422
+ if (value.trim()) contentParts.push({
9423
+ type: "text",
9424
+ text: value
9425
+ });
9426
+ for (const att of readyAttachments) contentParts.push((0, _copilotkit_shared.createAttachmentContent)(att));
9427
+ agent.addMessage({
9428
+ id: (0, _copilotkit_shared.randomUUID)(),
9429
+ role: "user",
9430
+ content: contentParts
9431
+ });
9432
+ } else agent.addMessage({
9285
9433
  id: (0, _copilotkit_shared.randomUUID)(),
9286
9434
  role: "user",
9287
- content: contentParts
9288
- });
9289
- } else agent.addMessage({
9290
- id: (0, _copilotkit_shared.randomUUID)(),
9291
- role: "user",
9292
- content: value
9293
- });
9294
- const localRunId = hasNativeIntelligenceRunActivity ? (0, _copilotkit_shared.randomUUID)() : void 0;
9295
- if (localRunId) activeLocalRunIdsRef.current.add(localRunId);
9296
- try {
9297
- await copilotkit.runAgent({
9298
- agent,
9299
- ...localRunId !== void 0 ? { runId: localRunId } : {}
9435
+ content: value
9300
9436
  });
9301
- } catch (error) {
9302
- console.error("CopilotChat: runAgent failed", error);
9303
- } finally {
9304
- if (localRunId) {
9305
- activeLocalRunIdsRef.current.delete(localRunId);
9306
- rememberRecentlyLocalRunId(localRunId);
9307
- }
9308
- if (pendingRunActivityReconnectRef.current && activeLocalRunIdsRef.current.size === 0 && activeConnectCountRef.current === 0) {
9309
- const startReconnect = startRunActivityReconnectRef.current;
9310
- if (startReconnect) {
9311
- pendingRunActivityReconnectRef.current = false;
9312
- startReconnect(runActivityReconnectGenerationRef.current);
9437
+ const localRunId = hasNativeIntelligenceRunActivity ? (0, _copilotkit_shared.randomUUID)() : void 0;
9438
+ if (localRunId) activeLocalRunIdsRef.current.add(localRunId);
9439
+ try {
9440
+ await copilotkit.runAgent({
9441
+ agent,
9442
+ ...localRunId !== void 0 ? { runId: localRunId } : {}
9443
+ });
9444
+ } catch (error) {
9445
+ console.error("CopilotChat: runAgent failed", error);
9446
+ } finally {
9447
+ if (localRunId) {
9448
+ activeLocalRunIdsRef.current.delete(localRunId);
9449
+ rememberRecentlyLocalRunId(localRunId);
9450
+ }
9451
+ if (pendingRunActivityReconnectRef.current && activeLocalRunIdsRef.current.size === 0 && activeConnectCountRef.current === 0) {
9452
+ const startReconnect = startRunActivityReconnectRef.current;
9453
+ if (startReconnect) {
9454
+ pendingRunActivityReconnectRef.current = false;
9455
+ startReconnect(runActivityReconnectGenerationRef.current);
9456
+ }
9313
9457
  }
9314
9458
  }
9315
- }
9459
+ });
9316
9460
  }, [
9317
9461
  agent,
9318
9462
  consumeAttachments,
9319
9463
  waitForActiveRunToSettle,
9464
+ enqueueSubmission,
9320
9465
  hasNativeIntelligenceRunActivity,
9321
9466
  rememberRecentlyLocalRunId
9322
9467
  ]);
9323
9468
  const handleSelectSuggestion = (0, react.useCallback)(async (suggestion) => {
9324
- await waitForActiveRunToSettle();
9325
- agent.addMessage({
9326
- id: (0, _copilotkit_shared.randomUUID)(),
9327
- role: "user",
9328
- content: suggestion.message
9329
- });
9330
- const localRunId = hasNativeIntelligenceRunActivity ? (0, _copilotkit_shared.randomUUID)() : void 0;
9331
- if (localRunId) activeLocalRunIdsRef.current.add(localRunId);
9332
- try {
9333
- await copilotkit.runAgent({
9334
- agent,
9335
- ...localRunId !== void 0 ? { runId: localRunId } : {}
9469
+ await enqueueSubmission(async () => {
9470
+ if (await waitForActiveRunToSettle() !== true) return;
9471
+ agent.addMessage({
9472
+ id: (0, _copilotkit_shared.randomUUID)(),
9473
+ role: "user",
9474
+ content: suggestion.message
9336
9475
  });
9337
- } catch (error) {
9338
- console.error("CopilotChat: runAgent failed after selecting suggestion", error);
9339
- } finally {
9340
- if (localRunId) {
9341
- activeLocalRunIdsRef.current.delete(localRunId);
9342
- rememberRecentlyLocalRunId(localRunId);
9343
- }
9344
- if (pendingRunActivityReconnectRef.current && activeLocalRunIdsRef.current.size === 0 && activeConnectCountRef.current === 0) {
9345
- const startReconnect = startRunActivityReconnectRef.current;
9346
- if (startReconnect) {
9347
- pendingRunActivityReconnectRef.current = false;
9348
- startReconnect(runActivityReconnectGenerationRef.current);
9476
+ const localRunId = hasNativeIntelligenceRunActivity ? (0, _copilotkit_shared.randomUUID)() : void 0;
9477
+ if (localRunId) activeLocalRunIdsRef.current.add(localRunId);
9478
+ try {
9479
+ await copilotkit.runAgent({
9480
+ agent,
9481
+ ...localRunId !== void 0 ? { runId: localRunId } : {}
9482
+ });
9483
+ } catch (error) {
9484
+ console.error("CopilotChat: runAgent failed after selecting suggestion", error);
9485
+ } finally {
9486
+ if (localRunId) {
9487
+ activeLocalRunIdsRef.current.delete(localRunId);
9488
+ rememberRecentlyLocalRunId(localRunId);
9489
+ }
9490
+ if (pendingRunActivityReconnectRef.current && activeLocalRunIdsRef.current.size === 0 && activeConnectCountRef.current === 0) {
9491
+ const startReconnect = startRunActivityReconnectRef.current;
9492
+ if (startReconnect) {
9493
+ pendingRunActivityReconnectRef.current = false;
9494
+ startReconnect(runActivityReconnectGenerationRef.current);
9495
+ }
9349
9496
  }
9350
9497
  }
9351
- }
9498
+ });
9352
9499
  }, [
9353
9500
  agent,
9354
9501
  waitForActiveRunToSettle,
9502
+ enqueueSubmission,
9355
9503
  hasNativeIntelligenceRunActivity,
9356
9504
  rememberRecentlyLocalRunId
9357
9505
  ]);
@@ -13020,6 +13168,18 @@ Object.defineProperty(exports, 'getIntelligenceTurnAnchors', {
13020
13168
  return getIntelligenceTurnAnchors;
13021
13169
  }
13022
13170
  });
13171
+ Object.defineProperty(exports, 'messageGroup', {
13172
+ enumerable: true,
13173
+ get: function () {
13174
+ return messageGroup;
13175
+ }
13176
+ });
13177
+ Object.defineProperty(exports, 'messageRow', {
13178
+ enumerable: true,
13179
+ get: function () {
13180
+ return messageRow;
13181
+ }
13182
+ });
13023
13183
  Object.defineProperty(exports, 'shouldShowDevConsole', {
13024
13184
  enumerable: true,
13025
13185
  get: function () {
@@ -13206,4 +13366,4 @@ Object.defineProperty(exports, 'useToast', {
13206
13366
  return useToast;
13207
13367
  }
13208
13368
  });
13209
- //# sourceMappingURL=copilotkit-CFPkj9B9.cjs.map
13369
+ //# sourceMappingURL=copilotkit-D7_J5Hs_.cjs.map