@copilotkit/react-core 1.62.1 → 1.62.2-canary.1784333495

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.
@@ -1,6 +1,6 @@
1
1
  import * as React$1 from "react";
2
2
  import React, { createContext, forwardRef, memo, useCallback, useContext, useEffect, useId, useImperativeHandle, useLayoutEffect, useMemo, useReducer, useRef, useState, useSyncExternalStore } from "react";
3
- import { CopilotKitCore, CopilotKitCoreRuntimeConnectionStatus, ProxiedCopilotRuntimeAgent, ToolCallStatus, isRunCompletionAware, ɵcreateThreadStore, ɵselectHasNextPage, ɵselectIsFetchingNextPage, ɵselectIsMutating, ɵselectThreads, ɵselectThreadsError, ɵselectThreadsIsLoading } from "@copilotkit/core";
3
+ import { CopilotKitCore, CopilotKitCoreRuntimeConnectionStatus, ProxiedCopilotRuntimeAgent, ToolCallStatus, isRunCompletionAware, ɵcreateThreadStore, ɵselectFetchMoreError, ɵselectHasNextPage, ɵselectIsFetchingNextPage, ɵselectIsMutating, ɵselectMemories, ɵselectMemoriesAvailable, ɵselectMemoriesError, ɵselectMemoriesIsLoading, ɵselectMemoriesRealtimeStatus, ɵselectThreads, ɵselectThreadsError, ɵselectThreadsIsLoading } from "@copilotkit/core";
4
4
  import { HttpAgent, buildResumeArray, isInterruptExpired, randomUUID } from "@ag-ui/client";
5
5
  import { extendTailwindMerge, twMerge } from "tailwind-merge";
6
6
  import { ArrowUp, Check, ChevronDown, ChevronLeft, ChevronRight, ChevronRightIcon, Copy, Edit, Loader2, MessageCircle, Mic, PanelLeftOpen, Play, Plus, RefreshCw, Square, ThumbsDown, ThumbsUp, Upload, Volume2, X } from "lucide-react";
@@ -3620,12 +3620,13 @@ const CopilotKitProvider = ({ children, runtimeUrl, headers: headersProp = EMPTY
3620
3620
  }
3621
3621
  const copilotkit = copilotkitRef.current;
3622
3622
  useEffect(() => {
3623
- setRuntimeA2UIEnabled(copilotkit.a2uiEnabled);
3624
- const subscription = copilotkit.subscribe({ onRuntimeConnectionStatusChanged: () => {
3623
+ const syncRuntimeInfo = () => {
3625
3624
  setRuntimeA2UIEnabled(copilotkit.a2uiEnabled);
3626
3625
  setRuntimeOpenGenUIEnabled(copilotkit.openGenerativeUIEnabled);
3627
3626
  setRuntimeLicenseStatus(copilotkit.licenseStatus);
3628
- } });
3627
+ };
3628
+ const subscription = copilotkit.subscribe({ onRuntimeConnectionStatusChanged: syncRuntimeInfo });
3629
+ syncRuntimeInfo();
3629
3630
  return () => {
3630
3631
  subscription.unsubscribe();
3631
3632
  };
@@ -4351,57 +4352,58 @@ const ALL_UPDATES = [
4351
4352
  UseAgentUpdate.OnRunStatusChanged
4352
4353
  ];
4353
4354
  function useAgent({ agentId, updates, throttleMs } = {}) {
4354
- agentId ??= DEFAULT_AGENT_ID;
4355
+ const chatConfig = useCopilotChatConfiguration();
4356
+ const resolvedAgentId = agentId ?? chatConfig?.agentId ?? DEFAULT_AGENT_ID;
4355
4357
  const { copilotkit } = useCopilotKit();
4356
4358
  const providerThrottleMs = copilotkit.defaultThrottleMs;
4357
4359
  const [, forceUpdate] = useReducer((x) => x + 1, 0);
4358
4360
  const updateFlags = useMemo(() => updates ?? ALL_UPDATES, [JSON.stringify(updates)]);
4359
4361
  const provisionalAgentCache = useRef(/* @__PURE__ */ new Map());
4360
4362
  const agent = useMemo(() => {
4361
- const existing = copilotkit.getAgent(agentId);
4363
+ const existing = copilotkit.getAgent(resolvedAgentId);
4362
4364
  if (existing) {
4363
- provisionalAgentCache.current.delete(agentId);
4365
+ provisionalAgentCache.current.delete(resolvedAgentId);
4364
4366
  return existing;
4365
4367
  }
4366
4368
  const isRuntimeConfigured = copilotkit.runtimeUrl !== void 0;
4367
4369
  const status = copilotkit.runtimeConnectionStatus;
4368
4370
  if (isRuntimeConfigured && (status === CopilotKitCoreRuntimeConnectionStatus.Disconnected || status === CopilotKitCoreRuntimeConnectionStatus.Connecting)) {
4369
- const cached = provisionalAgentCache.current.get(agentId);
4371
+ const cached = provisionalAgentCache.current.get(resolvedAgentId);
4370
4372
  if (cached) {
4371
4373
  copilotkit.applyHeadersToAgent(cached);
4372
4374
  return cached;
4373
4375
  }
4374
4376
  const provisional = new ProxiedCopilotRuntimeAgent({
4375
4377
  runtimeUrl: copilotkit.runtimeUrl,
4376
- agentId,
4378
+ agentId: resolvedAgentId,
4377
4379
  transport: copilotkit.runtimeTransport,
4378
4380
  runtimeMode: "pending"
4379
4381
  });
4380
4382
  copilotkit.applyHeadersToAgent(provisional);
4381
- provisionalAgentCache.current.set(agentId, provisional);
4383
+ provisionalAgentCache.current.set(resolvedAgentId, provisional);
4382
4384
  return provisional;
4383
4385
  }
4384
4386
  if (isRuntimeConfigured && status === CopilotKitCoreRuntimeConnectionStatus.Error) {
4385
- const cached = provisionalAgentCache.current.get(agentId);
4387
+ const cached = provisionalAgentCache.current.get(resolvedAgentId);
4386
4388
  if (cached) {
4387
4389
  copilotkit.applyHeadersToAgent(cached);
4388
4390
  return cached;
4389
4391
  }
4390
4392
  const provisional = new ProxiedCopilotRuntimeAgent({
4391
4393
  runtimeUrl: copilotkit.runtimeUrl,
4392
- agentId,
4394
+ agentId: resolvedAgentId,
4393
4395
  transport: copilotkit.runtimeTransport,
4394
4396
  runtimeMode: "pending"
4395
4397
  });
4396
4398
  copilotkit.applyHeadersToAgent(provisional);
4397
- provisionalAgentCache.current.set(agentId, provisional);
4399
+ provisionalAgentCache.current.set(resolvedAgentId, provisional);
4398
4400
  return provisional;
4399
4401
  }
4400
4402
  const knownAgents = Object.keys(copilotkit.agents ?? {});
4401
4403
  const runtimePart = isRuntimeConfigured ? `runtimeUrl=${copilotkit.runtimeUrl}` : "no runtimeUrl";
4402
- throw new Error(`useAgent: Agent '${agentId}' not found after runtime sync (${runtimePart}). ` + (knownAgents.length ? `Known agents: [${knownAgents.join(", ")}]` : "No agents registered.") + " Verify your runtime /info and/or agents__unsafe_dev_only.");
4404
+ throw new Error(`useAgent: Agent '${resolvedAgentId}' not found after runtime sync (${runtimePart}). ` + (knownAgents.length ? `Known agents: [${knownAgents.join(", ")}]` : "No agents registered.") + " Verify your runtime /info and/or agents__unsafe_dev_only.");
4403
4405
  }, [
4404
- agentId,
4406
+ resolvedAgentId,
4405
4407
  copilotkit.agents,
4406
4408
  copilotkit.runtimeConnectionStatus,
4407
4409
  copilotkit.runtimeUrl,
@@ -4446,7 +4448,6 @@ function useAgent({ agentId, updates, throttleMs } = {}) {
4446
4448
  useEffect(() => {
4447
4449
  if (agent instanceof HttpAgent) copilotkit.applyHeadersToAgent(agent);
4448
4450
  }, [agent, JSON.stringify(copilotkit.headers)]);
4449
- const chatConfig = useCopilotChatConfiguration();
4450
4451
  const configThreadId = chatConfig?.threadId;
4451
4452
  const configHasExplicitThreadId = chatConfig?.hasExplicitThreadId;
4452
4453
  useEffect(() => {
@@ -4460,16 +4461,87 @@ function useAgent({ agentId, updates, throttleMs } = {}) {
4460
4461
  return { agent };
4461
4462
  }
4462
4463
 
4464
+ //#endregion
4465
+ //#region src/v2/hooks/use-subagent.tsx
4466
+ const warnedAmbiguousNames = /* @__PURE__ */ new Set();
4467
+ function resolveSubagent(subagents, subagentId, subagentName) {
4468
+ if (subagentId) {
4469
+ const match = subagents[subagentId];
4470
+ return match ? { ...match } : void 0;
4471
+ }
4472
+ if (subagentName) {
4473
+ const matches = Object.values(subagents).filter((s) => s.name === subagentName);
4474
+ if (matches.length === 0) return;
4475
+ const chosen = matches[matches.length - 1];
4476
+ return matches.length > 1 ? {
4477
+ ...chosen,
4478
+ isAmbiguous: true,
4479
+ matchCount: matches.length
4480
+ } : { ...chosen };
4481
+ }
4482
+ }
4483
+ /**
4484
+ * Read a subagent's live lifecycle state (name, description, running status)
4485
+ * from the CopilotKit core subagent registry, by id or by declared name.
4486
+ *
4487
+ * @example
4488
+ * const sub = useSubagent({ subagentId: message.subagentId });
4489
+ * // sub?.name, sub?.description, sub?.status
4490
+ */
4491
+ function useSubagent(params) {
4492
+ const { subagentId, subagentName, agentId } = params;
4493
+ const { copilotkit } = useCopilotKit();
4494
+ const config = useCopilotChatConfiguration();
4495
+ const resolvedAgentId = useMemo(() => agentId ?? config?.agentId ?? DEFAULT_AGENT_ID, [agentId, config?.agentId]);
4496
+ const [subagent, setSubagent] = useState(() => resolveSubagent(copilotkit.getSubagents(resolvedAgentId), subagentId, subagentName));
4497
+ useEffect(() => {
4498
+ setSubagent(resolveSubagent(copilotkit.getSubagents(resolvedAgentId), subagentId, subagentName));
4499
+ }, [
4500
+ copilotkit,
4501
+ resolvedAgentId,
4502
+ subagentId,
4503
+ subagentName
4504
+ ]);
4505
+ useEffect(() => {
4506
+ const subscription = copilotkit.subscribe({ onSubagentsChanged: ({ agentId: changedAgentId, subagents }) => {
4507
+ if (changedAgentId !== resolvedAgentId) return;
4508
+ setSubagent(resolveSubagent(subagents, subagentId, subagentName));
4509
+ } });
4510
+ return () => {
4511
+ subscription.unsubscribe();
4512
+ };
4513
+ }, [
4514
+ copilotkit,
4515
+ resolvedAgentId,
4516
+ subagentId,
4517
+ subagentName
4518
+ ]);
4519
+ useEffect(() => {
4520
+ if (process.env.NODE_ENV === "production" || !subagentName || !subagent?.isAmbiguous) return;
4521
+ const key = `${subagentName}:${subagent.matchCount}`;
4522
+ if (warnedAmbiguousNames.has(key)) return;
4523
+ warnedAmbiguousNames.add(key);
4524
+ console.warn(`[CopilotKit] useSubagent({ subagentName: ${JSON.stringify(subagentName)} }) matched ${subagent.matchCount} subagents. Returning the most recently started one; pass a subagentId for a stable reference.`);
4525
+ }, [
4526
+ subagentName,
4527
+ subagent?.isAmbiguous,
4528
+ subagent?.matchCount
4529
+ ]);
4530
+ return subagent;
4531
+ }
4532
+
4463
4533
  //#endregion
4464
4534
  //#region src/v2/hooks/use-capabilities.tsx
4465
4535
  /**
4466
- * Returns the capabilities declared by the given agent (or the default agent).
4536
+ * Returns the capabilities declared by the given agent (or the agent resolved
4537
+ * from the surrounding chat configuration, falling back to the default agent).
4467
4538
  * Capabilities are populated from the runtime `/info` response at connection
4468
4539
  * time. The hook reads them synchronously from the agent instance — there is
4469
4540
  * no separate loading state, but the value will be `undefined` until the
4470
4541
  * runtime handshake completes.
4471
4542
  *
4472
- * @param agentId - Optional agent ID. If omitted, uses the default agent.
4543
+ * @param agentId - Optional agent ID. If omitted, inherits the surrounding
4544
+ * chat configuration's agent, falling back to the default agent.
4473
4545
  * @returns The agent's capabilities, or `undefined` if the agent doesn't
4474
4546
  * declare capabilities.
4475
4547
  */
@@ -5042,6 +5114,7 @@ function useThreads$1({ agentId, includeArchived, limit, enabled = true }) {
5042
5114
  })), [coreThreads]);
5043
5115
  const storeIsLoading = useThreadStoreSelector(store, ɵselectThreadsIsLoading);
5044
5116
  const storeError = useThreadStoreSelector(store, ɵselectThreadsError);
5117
+ const fetchMoreError = useThreadStoreSelector(store, ɵselectFetchMoreError);
5045
5118
  const hasMoreThreads = useThreadStoreSelector(store, ɵselectHasNextPage);
5046
5119
  const isFetchingMoreThreads = useThreadStoreSelector(store, ɵselectIsFetchingNextPage);
5047
5120
  const isMutating = useThreadStoreSelector(store, ɵselectIsMutating);
@@ -5147,6 +5220,7 @@ function useThreads$1({ agentId, includeArchived, limit, enabled = true }) {
5147
5220
  isLoading,
5148
5221
  error,
5149
5222
  listError,
5223
+ fetchMoreError,
5150
5224
  hasMoreThreads,
5151
5225
  isFetchingMoreThreads,
5152
5226
  isMutating,
@@ -5163,6 +5237,70 @@ function useThreads$1({ agentId, includeArchived, limit, enabled = true }) {
5163
5237
  };
5164
5238
  }
5165
5239
 
5240
+ //#endregion
5241
+ //#region src/v2/hooks/use-memories.tsx
5242
+ function useMemoryStoreSelector(store, selector) {
5243
+ return useSyncExternalStore(useCallback((onStoreChange) => {
5244
+ const subscription = store.select(selector).subscribe(onStoreChange);
5245
+ return () => subscription.unsubscribe();
5246
+ }, [store, selector]), () => selector(store.getState()), () => selector(store.getServerState()));
5247
+ }
5248
+ /**
5249
+ * React hook for listing and managing platform memories.
5250
+ *
5251
+ * Reads the memory store owned and wired by `CopilotKitCore`. On mount the
5252
+ * hook exposes the live list plus stable `addMemory` / `updateMemory` /
5253
+ * `removeMemory` / `refresh` callbacks. Mutations are server-authoritative:
5254
+ * each resolves once the platform confirms the operation and rejects with an
5255
+ * `Error` on failure.
5256
+ *
5257
+ * Realtime updates are automatic: the core's memory store opens its own
5258
+ * `user_meta:memories:<joinCode>` channel and applies `memory_metadata` deltas
5259
+ * to the list. You can still call `refresh()` to re-pull the REST snapshot on
5260
+ * demand.
5261
+ *
5262
+ * @returns Memory list state and stable mutation callbacks.
5263
+ *
5264
+ * @example
5265
+ * ```tsx
5266
+ * import { useMemories } from "@copilotkit/react-core";
5267
+ *
5268
+ * function MemoryList() {
5269
+ * const { memories, isLoading, isAvailable, addMemory, removeMemory } =
5270
+ * useMemories();
5271
+ *
5272
+ * if (!isAvailable) return null;
5273
+ * if (isLoading) return <p>Loading…</p>;
5274
+ *
5275
+ * return (
5276
+ * <ul>
5277
+ * {memories.map((m) => (
5278
+ * <li key={m.id}>
5279
+ * {m.content}
5280
+ * <button onClick={() => removeMemory(m.id)}>Delete</button>
5281
+ * </li>
5282
+ * ))}
5283
+ * </ul>
5284
+ * );
5285
+ * }
5286
+ * ```
5287
+ */
5288
+ function useMemories() {
5289
+ const { copilotkit } = useCopilotKit();
5290
+ const store = copilotkit.getMemoryStore();
5291
+ return {
5292
+ memories: useMemoryStoreSelector(store, ɵselectMemories),
5293
+ isLoading: useMemoryStoreSelector(store, ɵselectMemoriesIsLoading),
5294
+ error: useMemoryStoreSelector(store, ɵselectMemoriesError),
5295
+ isAvailable: useMemoryStoreSelector(store, ɵselectMemoriesAvailable),
5296
+ realtimeStatus: useMemoryStoreSelector(store, ɵselectMemoriesRealtimeStatus),
5297
+ refresh: useCallback(() => store.refresh(), [store]),
5298
+ addMemory: useCallback((input) => store.addMemory(input), [store]),
5299
+ updateMemory: useCallback((id, changes) => store.updateMemory(id, changes), [store]),
5300
+ removeMemory: useCallback((id) => store.removeMemory(id), [store])
5301
+ };
5302
+ }
5303
+
5166
5304
  //#endregion
5167
5305
  //#region src/v2/lib/record-annotation.ts
5168
5306
  /**
@@ -7925,9 +8063,57 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
7925
8063
  const { messageView: providedMessageView, suggestionView: providedSuggestionView, onStop: providedStopHandler, ...restProps } = props;
7926
8064
  const [lastConnectedThreadId, setLastConnectedThreadId] = useState(null);
7927
8065
  const isConnecting = hasExplicitThreadId && lastConnectedThreadId !== resolvedThreadId;
8066
+ const activeConnectCountRef = useRef(0);
8067
+ const pendingRunActivityReconnectRef = useRef(false);
8068
+ const runActivityReconnectGenerationRef = useRef(0);
8069
+ const activeLocalRunIdsRef = useRef(/* @__PURE__ */ new Set());
8070
+ const recentlyLocalRunIdsRef = useRef(/* @__PURE__ */ new Map());
8071
+ const activeWakeRunIdsRef = useRef(/* @__PURE__ */ new Set());
8072
+ const recentlyWakeRunIdsRef = useRef(/* @__PURE__ */ new Map());
8073
+ const pendingWakeRunIdRef = useRef(void 0);
8074
+ const startRunActivityReconnectRef = useRef(null);
8075
+ const runtimeStatus = copilotkit.runtimeConnectionStatus === CopilotKitCoreRuntimeConnectionStatus.Connected ? "Connected" : copilotkit.runtimeConnectionStatus;
8076
+ const hasNativeIntelligenceRunActivity = hasExplicitThreadId && runtimeStatus === "Connected" && !!copilotkit.intelligence?.wsUrl && copilotkit.threadEndpoints?.realtimeMetadata === true;
8077
+ const [standaloneRunActivityStore] = useState(() => ɵcreateThreadStore({ fetch: globalThis.fetch }));
7928
8078
  const previousThreadIdRef = useRef(null);
7929
8079
  const hasExplicitThreadIdRef = useRef(hasExplicitThreadId);
7930
8080
  hasExplicitThreadIdRef.current = hasExplicitThreadId;
8081
+ const rememberRecentlyLocalRunId = useCallback((runId) => {
8082
+ const existingTimeout = recentlyLocalRunIdsRef.current.get(runId);
8083
+ if (existingTimeout) clearTimeout(existingTimeout);
8084
+ const timeout = setTimeout(() => {
8085
+ recentlyLocalRunIdsRef.current.delete(runId);
8086
+ }, 3e4);
8087
+ recentlyLocalRunIdsRef.current.set(runId, timeout);
8088
+ }, []);
8089
+ const rememberRecentlyWakeRunId = useCallback((runId) => {
8090
+ const existingTimeout = recentlyWakeRunIdsRef.current.get(runId);
8091
+ if (existingTimeout) clearTimeout(existingTimeout);
8092
+ const timeout = setTimeout(() => {
8093
+ recentlyWakeRunIdsRef.current.delete(runId);
8094
+ }, 3e4);
8095
+ recentlyWakeRunIdsRef.current.set(runId, timeout);
8096
+ }, []);
8097
+ const isLocalActiveRunActivity = useCallback((notification) => {
8098
+ if (notification.agentId && notification.agentId !== resolvedAgentId) return false;
8099
+ if (!notification.runId || !activeLocalRunIdsRef.current.has(notification.runId) && !recentlyLocalRunIdsRef.current.has(notification.runId)) return false;
8100
+ const eventType = notification.eventType.toUpperCase();
8101
+ return eventType === "RUN_STARTED" || eventType === "RUN_FINISHED" || eventType === "RUN_ERROR";
8102
+ }, [resolvedAgentId]);
8103
+ useEffect(() => {
8104
+ const recentlyLocalRunIds = recentlyLocalRunIdsRef.current;
8105
+ const recentlyWakeRunIds = recentlyWakeRunIdsRef.current;
8106
+ return () => {
8107
+ recentlyLocalRunIds.forEach((timeout) => {
8108
+ clearTimeout(timeout);
8109
+ });
8110
+ recentlyLocalRunIds.clear();
8111
+ recentlyWakeRunIds.forEach((timeout) => {
8112
+ clearTimeout(timeout);
8113
+ });
8114
+ recentlyWakeRunIds.clear();
8115
+ };
8116
+ }, []);
7931
8117
  useEffect(() => {
7932
8118
  const threadChanged = previousThreadIdRef.current !== resolvedThreadId;
7933
8119
  previousThreadIdRef.current = resolvedThreadId;
@@ -7940,6 +8126,7 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
7940
8126
  const connectAbortController = new AbortController();
7941
8127
  if (agent instanceof HttpAgent) agent.abortController = connectAbortController;
7942
8128
  const connect = async (agentToConnect) => {
8129
+ activeConnectCountRef.current += 1;
7943
8130
  try {
7944
8131
  await copilotkit.connectAgent({ agent: agentToConnect });
7945
8132
  } catch (error) {
@@ -7950,6 +8137,14 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
7950
8137
  if (!detached) setLastConnectedThreadId(resolvedThreadId);
7951
8138
  });
7952
8139
  else if (!hasExplicitThreadIdRef.current) agentToConnect.setMessages([]);
8140
+ activeConnectCountRef.current = Math.max(0, activeConnectCountRef.current - 1);
8141
+ if (!detached && activeConnectCountRef.current === 0) {
8142
+ const startReconnect = startRunActivityReconnectRef.current;
8143
+ if (pendingRunActivityReconnectRef.current && startReconnect) {
8144
+ pendingRunActivityReconnectRef.current = false;
8145
+ startReconnect(runActivityReconnectGenerationRef.current);
8146
+ }
8147
+ }
7953
8148
  }
7954
8149
  };
7955
8150
  connect(agent);
@@ -7964,6 +8159,119 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
7964
8159
  resolvedAgentId,
7965
8160
  hasExplicitThreadId
7966
8161
  ]);
8162
+ useEffect(() => {
8163
+ if (!hasNativeIntelligenceRunActivity) return;
8164
+ const registeredThreadStore = copilotkit.getThreadStore(resolvedAgentId);
8165
+ const threadStore = registeredThreadStore ?? standaloneRunActivityStore;
8166
+ if (!threadStore?.subscribeToRunActivity) return;
8167
+ const ownsStandaloneStore = registeredThreadStore === void 0;
8168
+ if (ownsStandaloneStore) {
8169
+ threadStore.start();
8170
+ const context = copilotkit.runtimeUrl ? {
8171
+ runtimeUrl: copilotkit.runtimeUrl,
8172
+ headers: { ...copilotkit.headers },
8173
+ wsUrl: copilotkit.intelligence?.wsUrl,
8174
+ agentId: resolvedAgentId
8175
+ } : null;
8176
+ threadStore.setContext(context);
8177
+ }
8178
+ const generation = runActivityReconnectGenerationRef.current + 1;
8179
+ runActivityReconnectGenerationRef.current = generation;
8180
+ let detached = false;
8181
+ let wakeReconnectActive = false;
8182
+ let pendingAgentIdleDrain = null;
8183
+ const hasActiveAgentRun = () => activeLocalRunIdsRef.current.size > 0 || agent.isRunning;
8184
+ const scheduleAgentIdleDrain = () => {
8185
+ if (pendingAgentIdleDrain !== null) return;
8186
+ pendingAgentIdleDrain = setTimeout(() => {
8187
+ pendingAgentIdleDrain = null;
8188
+ if (detached || runActivityReconnectGenerationRef.current !== generation || !pendingRunActivityReconnectRef.current) return;
8189
+ if (hasActiveAgentRun()) {
8190
+ scheduleAgentIdleDrain();
8191
+ return;
8192
+ }
8193
+ startRunActivityReconnectRef.current?.(generation);
8194
+ }, 10);
8195
+ };
8196
+ const connect = async () => {
8197
+ activeConnectCountRef.current += 1;
8198
+ wakeReconnectActive = true;
8199
+ const wakeRunId = pendingWakeRunIdRef.current;
8200
+ pendingWakeRunIdRef.current = void 0;
8201
+ if (wakeRunId) activeWakeRunIdsRef.current.add(wakeRunId);
8202
+ let didConnect = false;
8203
+ try {
8204
+ await copilotkit.connectAgent({ agent });
8205
+ didConnect = true;
8206
+ } catch (error) {
8207
+ if (!detached) console.error("CopilotChat: run activity reconnect failed", error);
8208
+ } finally {
8209
+ if (wakeRunId) {
8210
+ activeWakeRunIdsRef.current.delete(wakeRunId);
8211
+ if (didConnect) rememberRecentlyWakeRunId(wakeRunId);
8212
+ }
8213
+ activeConnectCountRef.current = Math.max(0, activeConnectCountRef.current - 1);
8214
+ wakeReconnectActive = false;
8215
+ if (!detached && runActivityReconnectGenerationRef.current === generation && activeConnectCountRef.current === 0 && pendingRunActivityReconnectRef.current) {
8216
+ pendingRunActivityReconnectRef.current = false;
8217
+ connect();
8218
+ }
8219
+ }
8220
+ };
8221
+ startRunActivityReconnectRef.current = (requestedGeneration) => {
8222
+ if (detached || requestedGeneration !== generation || runActivityReconnectGenerationRef.current !== generation) return;
8223
+ if (hasActiveAgentRun()) {
8224
+ pendingRunActivityReconnectRef.current = true;
8225
+ scheduleAgentIdleDrain();
8226
+ return;
8227
+ }
8228
+ if (activeConnectCountRef.current > 0) {
8229
+ if (!wakeReconnectActive) pendingRunActivityReconnectRef.current = true;
8230
+ return;
8231
+ }
8232
+ pendingRunActivityReconnectRef.current = false;
8233
+ connect();
8234
+ };
8235
+ const subscription = threadStore.subscribeToRunActivity((notification) => {
8236
+ if (notification.threadId !== resolvedThreadId) return;
8237
+ if (notification.agentId && notification.agentId !== resolvedAgentId) return;
8238
+ if (isLocalActiveRunActivity(notification)) return;
8239
+ if (notification.runId && (activeWakeRunIdsRef.current.has(notification.runId) || recentlyWakeRunIdsRef.current.has(notification.runId))) return;
8240
+ pendingWakeRunIdRef.current = notification.runId;
8241
+ startRunActivityReconnectRef.current?.(generation);
8242
+ });
8243
+ return () => {
8244
+ detached = true;
8245
+ pendingRunActivityReconnectRef.current = false;
8246
+ pendingWakeRunIdRef.current = void 0;
8247
+ if (pendingAgentIdleDrain !== null) {
8248
+ clearTimeout(pendingAgentIdleDrain);
8249
+ pendingAgentIdleDrain = null;
8250
+ }
8251
+ if (startRunActivityReconnectRef.current) startRunActivityReconnectRef.current = null;
8252
+ if (wakeReconnectActive) agent.detachActiveRun().catch(() => {});
8253
+ activeWakeRunIdsRef.current.clear();
8254
+ subscription.unsubscribe();
8255
+ if (ownsStandaloneStore) {
8256
+ threadStore.setContext(null);
8257
+ threadStore.stop();
8258
+ }
8259
+ };
8260
+ }, [
8261
+ agent,
8262
+ resolvedAgentId,
8263
+ resolvedThreadId,
8264
+ hasExplicitThreadId,
8265
+ hasNativeIntelligenceRunActivity,
8266
+ copilotkit.runtimeConnectionStatus,
8267
+ copilotkit.runtimeUrl,
8268
+ copilotkit.headers,
8269
+ copilotkit.intelligence?.wsUrl,
8270
+ copilotkit.threadEndpoints?.realtimeMetadata,
8271
+ standaloneRunActivityStore,
8272
+ isLocalActiveRunActivity,
8273
+ rememberRecentlyWakeRunId
8274
+ ]);
7967
8275
  const waitForActiveRunToSettle = useCallback(async () => {
7968
8276
  const maybeAware = agent;
7969
8277
  const activeRunCompletionPromise = isRunCompletionAware(maybeAware) ? maybeAware.activeRunCompletionPromise : void 0;
@@ -8012,15 +8320,34 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
8012
8320
  role: "user",
8013
8321
  content: value
8014
8322
  });
8323
+ const localRunId = hasNativeIntelligenceRunActivity ? randomUUID$1() : void 0;
8324
+ if (localRunId) activeLocalRunIdsRef.current.add(localRunId);
8015
8325
  try {
8016
- await copilotkit.runAgent({ agent });
8326
+ await copilotkit.runAgent({
8327
+ agent,
8328
+ ...localRunId !== void 0 ? { runId: localRunId } : {}
8329
+ });
8017
8330
  } catch (error) {
8018
8331
  console.error("CopilotChat: runAgent failed", error);
8332
+ } finally {
8333
+ if (localRunId) {
8334
+ activeLocalRunIdsRef.current.delete(localRunId);
8335
+ rememberRecentlyLocalRunId(localRunId);
8336
+ }
8337
+ if (pendingRunActivityReconnectRef.current && activeLocalRunIdsRef.current.size === 0 && activeConnectCountRef.current === 0) {
8338
+ const startReconnect = startRunActivityReconnectRef.current;
8339
+ if (startReconnect) {
8340
+ pendingRunActivityReconnectRef.current = false;
8341
+ startReconnect(runActivityReconnectGenerationRef.current);
8342
+ }
8343
+ }
8019
8344
  }
8020
8345
  }, [
8021
8346
  agent,
8022
8347
  consumeAttachments,
8023
- waitForActiveRunToSettle
8348
+ waitForActiveRunToSettle,
8349
+ hasNativeIntelligenceRunActivity,
8350
+ rememberRecentlyLocalRunId
8024
8351
  ]);
8025
8352
  const handleSelectSuggestion = useCallback(async (suggestion) => {
8026
8353
  await waitForActiveRunToSettle();
@@ -8029,12 +8356,34 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
8029
8356
  role: "user",
8030
8357
  content: suggestion.message
8031
8358
  });
8359
+ const localRunId = hasNativeIntelligenceRunActivity ? randomUUID$1() : void 0;
8360
+ if (localRunId) activeLocalRunIdsRef.current.add(localRunId);
8032
8361
  try {
8033
- await copilotkit.runAgent({ agent });
8362
+ await copilotkit.runAgent({
8363
+ agent,
8364
+ ...localRunId !== void 0 ? { runId: localRunId } : {}
8365
+ });
8034
8366
  } catch (error) {
8035
8367
  console.error("CopilotChat: runAgent failed after selecting suggestion", error);
8368
+ } finally {
8369
+ if (localRunId) {
8370
+ activeLocalRunIdsRef.current.delete(localRunId);
8371
+ rememberRecentlyLocalRunId(localRunId);
8372
+ }
8373
+ if (pendingRunActivityReconnectRef.current && activeLocalRunIdsRef.current.size === 0 && activeConnectCountRef.current === 0) {
8374
+ const startReconnect = startRunActivityReconnectRef.current;
8375
+ if (startReconnect) {
8376
+ pendingRunActivityReconnectRef.current = false;
8377
+ startReconnect(runActivityReconnectGenerationRef.current);
8378
+ }
8379
+ }
8036
8380
  }
8037
- }, [agent, waitForActiveRunToSettle]);
8381
+ }, [
8382
+ agent,
8383
+ waitForActiveRunToSettle,
8384
+ hasNativeIntelligenceRunActivity,
8385
+ rememberRecentlyLocalRunId
8386
+ ]);
8038
8387
  const stopCurrentRun = useCallback(() => {
8039
8388
  try {
8040
8389
  copilotkit.stopAgent({ agent });
@@ -8813,7 +9162,7 @@ function findChatInput(origin) {
8813
9162
  * during prerender to avoid hydration mismatch).
8814
9163
  * - Feeds the element domain data: `threads`, `loading`, `error`,
8815
9164
  * `activeThreadId`, `licensed`, fetch-more state.
8816
- * - Routes the element's nine outbound events to core thread operations
9165
+ * - Routes the element's outbound events to core thread operations
8817
9166
  * ({@link useThreads}) and chat-configuration changes.
8818
9167
  * - Registers with the surrounding chat configuration so the header
8819
9168
  * thread-list launcher appears, and binds the element `open` state to the
@@ -8840,16 +9189,16 @@ function findChatInput(origin) {
8840
9189
  * </CopilotKitProvider>
8841
9190
  * ```
8842
9191
  */
8843
- function CopilotThreadsDrawer({ agentId, onThreadSelect, onNewThread, onLicensed, licenseUrl, renderRow, label, limit, "data-testid": dataTestId = "copilot-threads-drawer" }) {
9192
+ function CopilotThreadsDrawer({ agentId, onThreadSelect, onNewThread, onLicensed, licenseUrl, renderRow, label, recentLabel, collapsible, onCollapseChange, limit, "data-testid": dataTestId = "copilot-threads-drawer" }) {
8844
9193
  const configuration = useCopilotChatConfiguration();
8845
9194
  const { status, checkFeature } = useLicenseContext();
8846
9195
  const licensePresent = status === "valid" || status === "expiring";
8847
9196
  const featureLicensed = checkFeature("threads");
8848
9197
  const licensed = licensePresent && featureLicensed;
8849
9198
  const licensePending = status === null;
8850
- const resolvedAgentId = agentId ?? configuration?.agentId ?? "default";
9199
+ const resolvedAgentId = agentId ?? configuration?.agentId ?? DEFAULT_AGENT_ID;
8851
9200
  const activeThreadId = configuration?.threadId ?? null;
8852
- const { threads, isLoading, listError, hasMoreThreads, isFetchingMoreThreads, archiveThread, unarchiveThread, deleteThread, fetchMoreThreads, refetchThreads, startNewThread } = useThreads$1({
9201
+ const { threads, isLoading, listError, fetchMoreError, hasMoreThreads, isFetchingMoreThreads, archiveThread, unarchiveThread, deleteThread, fetchMoreThreads, refetchThreads, startNewThread } = useThreads$1({
8853
9202
  agentId: resolvedAgentId,
8854
9203
  includeArchived: true,
8855
9204
  enabled: licensed,
@@ -8930,6 +9279,9 @@ function CopilotThreadsDrawer({ agentId, onThreadSelect, onNewThread, onLicensed
8930
9279
  const handleLoadMore = useCallback(() => {
8931
9280
  fetchMoreThreads();
8932
9281
  }, [fetchMoreThreads]);
9282
+ const handleCollapseChange = useCallback((collapsed) => {
9283
+ onCollapseChange?.(collapsed);
9284
+ }, [onCollapseChange]);
8933
9285
  const handlersRef = useRef({
8934
9286
  handleThreadSelected,
8935
9287
  handleNewThread,
@@ -8940,7 +9292,8 @@ function CopilotThreadsDrawer({ agentId, onThreadSelect, onNewThread, onLicensed
8940
9292
  handleRetry,
8941
9293
  handleOpenChange,
8942
9294
  handleLicensed,
8943
- handleLoadMore
9295
+ handleLoadMore,
9296
+ handleCollapseChange
8944
9297
  });
8945
9298
  handlersRef.current = {
8946
9299
  handleThreadSelected,
@@ -8952,7 +9305,8 @@ function CopilotThreadsDrawer({ agentId, onThreadSelect, onNewThread, onLicensed
8952
9305
  handleRetry,
8953
9306
  handleOpenChange,
8954
9307
  handleLicensed,
8955
- handleLoadMore
9308
+ handleLoadMore,
9309
+ handleCollapseChange
8956
9310
  };
8957
9311
  useEffect(() => {
8958
9312
  const el = elementRef.current;
@@ -8987,6 +9341,10 @@ function CopilotThreadsDrawer({ agentId, onThreadSelect, onNewThread, onLicensed
8987
9341
  };
8988
9342
  const onLicensedEvent = () => handlersRef.current.handleLicensed();
8989
9343
  const onLoadMore = () => handlersRef.current.handleLoadMore();
9344
+ const onCollapseChangeEvent = (event) => {
9345
+ const detail = event.detail;
9346
+ handlersRef.current.handleCollapseChange(detail.collapsed);
9347
+ };
8990
9348
  el.addEventListener("thread-selected", onThreadSelected);
8991
9349
  el.addEventListener("new-thread", onNewThreadEvent);
8992
9350
  el.addEventListener("archive", onArchive);
@@ -8997,6 +9355,7 @@ function CopilotThreadsDrawer({ agentId, onThreadSelect, onNewThread, onLicensed
8997
9355
  el.addEventListener("retry", onRetry);
8998
9356
  el.addEventListener("licensed", onLicensedEvent);
8999
9357
  el.addEventListener("load-more", onLoadMore);
9358
+ el.addEventListener("collapse-change", onCollapseChangeEvent);
9000
9359
  return () => {
9001
9360
  el.removeEventListener("thread-selected", onThreadSelected);
9002
9361
  el.removeEventListener("new-thread", onNewThreadEvent);
@@ -9008,6 +9367,7 @@ function CopilotThreadsDrawer({ agentId, onThreadSelect, onNewThread, onLicensed
9008
9367
  el.removeEventListener("retry", onRetry);
9009
9368
  el.removeEventListener("licensed", onLicensedEvent);
9010
9369
  el.removeEventListener("load-more", onLoadMore);
9370
+ el.removeEventListener("collapse-change", onCollapseChangeEvent);
9011
9371
  };
9012
9372
  }, [mounted]);
9013
9373
  useEffect(() => {
@@ -9024,9 +9384,11 @@ function CopilotThreadsDrawer({ agentId, onThreadSelect, onNewThread, onLicensed
9024
9384
  el.licensed = licensed || licensePending;
9025
9385
  el.hasMore = hasMoreThreads;
9026
9386
  el.fetchingMore = isFetchingMoreThreads;
9387
+ el.fetchMoreError = fetchMoreError ? fetchMoreError.message : null;
9027
9388
  }, [
9028
9389
  isLoading,
9029
9390
  listError,
9391
+ fetchMoreError,
9030
9392
  activeThreadId,
9031
9393
  licensed,
9032
9394
  licensePending,
@@ -9049,6 +9411,11 @@ function CopilotThreadsDrawer({ agentId, onThreadSelect, onNewThread, onLicensed
9049
9411
  if (!el) return;
9050
9412
  if (licenseUrl !== void 0) el.licenseUrl = licenseUrl;
9051
9413
  }, [licenseUrl, mounted]);
9414
+ useEffect(() => {
9415
+ const el = elementRef.current;
9416
+ if (!el) return;
9417
+ if (collapsible !== void 0) el.collapsible = collapsible;
9418
+ }, [collapsible, mounted]);
9052
9419
  const rowChildren = useMemo(() => {
9053
9420
  if (!renderRow) return null;
9054
9421
  return drawerThreads.map((drawerThread) => {
@@ -9069,7 +9436,8 @@ function CopilotThreadsDrawer({ agentId, onThreadSelect, onNewThread, onLicensed
9069
9436
  if (!mounted) return null;
9070
9437
  return React.createElement(COPILOTKIT_THREADS_DRAWER_TAG, {
9071
9438
  ref: elementRef,
9072
- "data-testid": dataTestId
9439
+ "data-testid": dataTestId,
9440
+ ...recentLabel !== void 0 ? { "recent-label": recentLabel } : {}
9073
9441
  }, rowChildren);
9074
9442
  }
9075
9443
  CopilotThreadsDrawer.displayName = "CopilotThreadsDrawer";
@@ -10722,8 +11090,18 @@ const usePredictStateSubscription = (agent) => {
10722
11090
  }, [agent, getSubscriber]);
10723
11091
  };
10724
11092
  function CopilotListenersAgentSubscription() {
10725
- const resolvedAgentId = useCopilotChatConfiguration()?.agentId;
10726
- const { agent } = useAgent({ agentId: resolvedAgentId });
11093
+ const { copilotkit } = useCopilotKit();
11094
+ const configAgentId = useCopilotChatConfiguration()?.agentId;
11095
+ const { agent } = useAgent({ agentId: useMemo(() => {
11096
+ const requested = configAgentId ?? DEFAULT_AGENT_ID;
11097
+ const registered = copilotkit.agents ?? {};
11098
+ if (registered[requested]) return requested;
11099
+ if (requested === DEFAULT_AGENT_ID) {
11100
+ const firstRegistered = Object.keys(registered)[0];
11101
+ if (firstRegistered) return firstRegistered;
11102
+ }
11103
+ return requested;
11104
+ }, [configAgentId, copilotkit.agents]) });
10727
11105
  usePredictStateSubscription(agent);
10728
11106
  return null;
10729
11107
  }
@@ -11256,5 +11634,5 @@ function validateProps(props) {
11256
11634
  }
11257
11635
 
11258
11636
  //#endregion
11259
- export { UseAgentUpdate as $, CopilotChatMessageView as A, CopilotChatAssistantMessage_default as B, CopilotModalHeader as C, CopilotChatConfigurationProvider as Ct, CopilotChat as D, DefaultOpenIcon as E, CopilotChatSuggestionView as F, useLearnFromUserActionInCurrentThread as G, useLearningContainersInCurrentThread as H, CopilotChatSuggestionPill as I, useInterrupt as J, useLearnFromUserAction as K, CopilotChatReasoningMessage_default as L, IntelligenceIndicator as M, getIntelligenceTurnAnchors as N, CopilotChatView_default as O, IntelligenceIndicatorView as P, useCapabilities as Q, CopilotChatUserMessage_default as R, CopilotSidebarView as S, CopilotChatAudioRecorder as St, DefaultCloseIcon as T, useLearningContainers as U, CopilotChatToolCallsView as V, useAttachments as W, useSuggestions as X, useConfigureSuggestions as Y, useAgentContext as Z, WildcardToolCallRender as _, useRenderToolCall as _t, ThreadsProvider as a, useFrontendTool as at, CopilotSidebar as b, CopilotChatInput_default as bt, CoAgentStateRendersProvider as c, CopilotKitProvider as ct, shouldShowDevConsole as d, SandboxFunctionsContext as dt, useAgent as et, useToast as f, useSandboxFunctions as ft, useCopilotContext as g, CopilotKitInspector as gt, CopilotContext as h, MCPAppsActivityType as ht, ThreadsContext as i, useComponent as it, INTELLIGENCE_TURN_HEAD as j, CopilotChatAttachmentQueue as k, useCoAgentStateRenders as l, defineToolCallRenderer as lt, useCopilotMessagesContext as m, MCPAppsActivityRenderer as mt, defaultCopilotContextCategories as n, useDefaultRenderTool as nt, useThreads as o, useRenderActivityMessage as ot, CopilotMessagesContext as p, MCPAppsActivityContentSchema as pt, useThreads$1 as q, CoAgentStateRenderBridge as r, useRenderTool as rt, CoAgentStateRendersContext as s, useRenderCustomMessages as st, CopilotKit as t, useHumanInTheLoop as tt, useAsyncCallback as u, createA2UIMessageRenderer as ut, CopilotThreadsDrawer as v, useCopilotKit as vt, CopilotChatToggleButton as w, useCopilotChatConfiguration as wt, CopilotPopupView as x, AudioRecorderError as xt, CopilotPopup as y, CopilotKitCoreReact as yt, CopilotChatAttachmentRenderer as z };
11260
- //# sourceMappingURL=copilotkit-BtRkFsNR.mjs.map
11637
+ export { useCapabilities as $, CopilotChatMessageView as A, CopilotChatAssistantMessage_default as B, CopilotModalHeader as C, AudioRecorderError as Ct, CopilotChat as D, DefaultOpenIcon as E, useCopilotChatConfiguration as Et, CopilotChatSuggestionView as F, useLearnFromUserActionInCurrentThread as G, useLearningContainersInCurrentThread as H, CopilotChatSuggestionPill as I, useThreads$1 as J, useLearnFromUserAction as K, CopilotChatReasoningMessage_default as L, IntelligenceIndicator as M, getIntelligenceTurnAnchors as N, CopilotChatView_default as O, IntelligenceIndicatorView as P, useAgentContext as Q, CopilotChatUserMessage_default as R, CopilotSidebarView as S, CopilotChatInput_default as St, DefaultCloseIcon as T, CopilotChatConfigurationProvider as Tt, useLearningContainers as U, CopilotChatToolCallsView as V, useAttachments as W, useConfigureSuggestions as X, useInterrupt as Y, useSuggestions as Z, WildcardToolCallRender as _, MCPAppsActivityType as _t, ThreadsProvider as a, useRenderTool as at, CopilotSidebar as b, useCopilotKit as bt, CoAgentStateRendersProvider as c, useRenderActivityMessage as ct, shouldShowDevConsole as d, defineToolCallRenderer as dt, useSubagent as et, useToast as f, createA2UIMessageRenderer as ft, useCopilotContext as g, MCPAppsActivityRenderer as gt, CopilotContext as h, MCPAppsActivityContentSchema as ht, ThreadsContext as i, useDefaultRenderTool as it, INTELLIGENCE_TURN_HEAD as j, CopilotChatAttachmentQueue as k, useCoAgentStateRenders as l, useRenderCustomMessages as lt, useCopilotMessagesContext as m, useSandboxFunctions as mt, defaultCopilotContextCategories as n, useAgent as nt, useThreads as o, useComponent as ot, CopilotMessagesContext as p, SandboxFunctionsContext as pt, useMemories as q, CoAgentStateRenderBridge as r, useHumanInTheLoop as rt, CoAgentStateRendersContext as s, useFrontendTool as st, CopilotKit as t, UseAgentUpdate as tt, useAsyncCallback as u, CopilotKitProvider as ut, CopilotThreadsDrawer as v, CopilotKitInspector as vt, CopilotChatToggleButton as w, CopilotChatAudioRecorder as wt, CopilotPopupView as x, CopilotKitCoreReact as xt, CopilotPopup as y, useRenderToolCall as yt, CopilotChatAttachmentRenderer as z };
11638
+ //# sourceMappingURL=copilotkit-dtSVHJCs.mjs.map