@copilotkit/react-core 1.56.5-canary.1777972218 → 1.57.0

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.
Files changed (45) hide show
  1. package/dist/{copilotkit-BVK_b6St.mjs → copilotkit-CPe2-340.mjs} +177 -330
  2. package/dist/copilotkit-CPe2-340.mjs.map +1 -0
  3. package/dist/{copilotkit-DV9LwRgi.d.mts → copilotkit-DFaI4j2r.d.mts} +6 -52
  4. package/dist/copilotkit-DFaI4j2r.d.mts.map +1 -0
  5. package/dist/{copilotkit-BGIsblrk.cjs → copilotkit-DGbvw8n2.cjs} +176 -335
  6. package/dist/copilotkit-DGbvw8n2.cjs.map +1 -0
  7. package/dist/{copilotkit-Bc7kZ72T.d.cts → copilotkit-Dg4r4Gi_.d.cts} +6 -52
  8. package/dist/copilotkit-Dg4r4Gi_.d.cts.map +1 -0
  9. package/dist/index.cjs +5 -2
  10. package/dist/index.cjs.map +1 -1
  11. package/dist/index.d.cts +1 -1
  12. package/dist/index.d.mts +1 -1
  13. package/dist/index.mjs +5 -2
  14. package/dist/index.mjs.map +1 -1
  15. package/dist/index.umd.js +172 -117
  16. package/dist/index.umd.js.map +1 -1
  17. package/dist/v2/index.cjs +1 -2
  18. package/dist/v2/index.css +1 -1
  19. package/dist/v2/index.d.cts +2 -2
  20. package/dist/v2/index.d.mts +2 -2
  21. package/dist/v2/index.mjs +2 -2
  22. package/dist/v2/index.umd.js +182 -340
  23. package/dist/v2/index.umd.js.map +1 -1
  24. package/package.json +6 -6
  25. package/src/hooks/__tests__/use-copilot-chat-internal-connect.test.tsx +6 -5
  26. package/src/hooks/use-copilot-chat_internal.ts +1 -0
  27. package/src/v2/components/chat/CopilotChat.tsx +1 -2
  28. package/src/v2/components/chat/CopilotChatMessageView.tsx +13 -124
  29. package/src/v2/components/chat/CopilotChatView.tsx +2 -2
  30. package/src/v2/components/chat/__tests__/CopilotChat.welcomeGate.test.tsx +3 -1
  31. package/src/v2/components/chat/__tests__/CopilotChatActivityRendering.e2e.test.tsx +25 -29
  32. package/src/v2/components/chat/__tests__/MCPAppsUiMessage.e2e.test.tsx +60 -5
  33. package/src/v2/components/index.ts +0 -1
  34. package/src/v2/hooks/__tests__/use-agent-thread-isolation.test.tsx +333 -0
  35. package/src/v2/hooks/use-agent.tsx +116 -7
  36. package/src/v2/hooks/use-render-activity-message.tsx +11 -3
  37. package/src/v2/hooks/use-render-custom-messages.tsx +6 -1
  38. package/src/v2/styles/globals.css +0 -112
  39. package/dist/copilotkit-BGIsblrk.cjs.map +0 -1
  40. package/dist/copilotkit-BVK_b6St.mjs.map +0 -1
  41. package/dist/copilotkit-Bc7kZ72T.d.cts.map +0 -1
  42. package/dist/copilotkit-DV9LwRgi.d.mts.map +0 -1
  43. package/src/v2/components/intelligence-indicator/IntelligenceIndicator.tsx +0 -265
  44. package/src/v2/components/intelligence-indicator/__tests__/IntelligenceIndicator.e2e.test.tsx +0 -362
  45. package/src/v2/components/intelligence-indicator/index.ts +0 -2
package/dist/index.umd.js CHANGED
@@ -2396,6 +2396,171 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
2396
2396
  ]);
2397
2397
  }
2398
2398
 
2399
+ //#endregion
2400
+ //#region src/v2/hooks/use-agent.tsx
2401
+ let UseAgentUpdate = /* @__PURE__ */ function(UseAgentUpdate) {
2402
+ UseAgentUpdate["OnMessagesChanged"] = "OnMessagesChanged";
2403
+ UseAgentUpdate["OnStateChanged"] = "OnStateChanged";
2404
+ UseAgentUpdate["OnRunStatusChanged"] = "OnRunStatusChanged";
2405
+ return UseAgentUpdate;
2406
+ }({});
2407
+ const ALL_UPDATES = [
2408
+ UseAgentUpdate.OnMessagesChanged,
2409
+ UseAgentUpdate.OnStateChanged,
2410
+ UseAgentUpdate.OnRunStatusChanged
2411
+ ];
2412
+ /**
2413
+ * Clone a registry agent for per-thread isolation.
2414
+ * Copies agent configuration (transport, headers, etc.) but resets conversation
2415
+ * state (messages, threadId, state) so each thread starts fresh.
2416
+ */
2417
+ function cloneForThread(source, threadId, headers) {
2418
+ const clone = source.clone();
2419
+ if (clone === source) throw new Error(`useAgent: ${source.constructor.name}.clone() returned the same instance. clone() must return a new, independent object.`);
2420
+ clone.threadId = threadId;
2421
+ clone.setMessages([]);
2422
+ clone.setState({});
2423
+ if (clone instanceof _ag_ui_client.HttpAgent) clone.headers = { ...headers };
2424
+ return clone;
2425
+ }
2426
+ /**
2427
+ * Module-level WeakMap: registryAgent → (threadId → clone).
2428
+ * Shared across all useAgent() calls so that every component using the same
2429
+ * (agentId, threadId) pair receives the same agent instance. Using WeakMap
2430
+ * ensures the clone map is garbage-collected when the registry agent is
2431
+ * replaced (e.g. after reconnect or hot-reload).
2432
+ */
2433
+ const globalThreadCloneMap = /* @__PURE__ */ new WeakMap();
2434
+ /**
2435
+ * Look up an existing per-thread clone without creating one.
2436
+ * Returns undefined when no clone has been created yet for this pair.
2437
+ */
2438
+ function getThreadClone(registryAgent, threadId) {
2439
+ var _globalThreadCloneMap;
2440
+ if (!registryAgent || !threadId) return void 0;
2441
+ return (_globalThreadCloneMap = globalThreadCloneMap.get(registryAgent)) === null || _globalThreadCloneMap === void 0 ? void 0 : _globalThreadCloneMap.get(threadId);
2442
+ }
2443
+ function getOrCreateThreadClone(existing, threadId, headers) {
2444
+ let byThread = globalThreadCloneMap.get(existing);
2445
+ if (!byThread) {
2446
+ byThread = /* @__PURE__ */ new Map();
2447
+ globalThreadCloneMap.set(existing, byThread);
2448
+ }
2449
+ const cached = byThread.get(threadId);
2450
+ if (cached) return cached;
2451
+ const clone = cloneForThread(existing, threadId, headers);
2452
+ byThread.set(threadId, clone);
2453
+ return clone;
2454
+ }
2455
+ function useAgent({ agentId, threadId, updates, throttleMs } = {}) {
2456
+ var _agentId, _threadId;
2457
+ (_agentId = agentId) !== null && _agentId !== void 0 || (agentId = _copilotkit_shared.DEFAULT_AGENT_ID);
2458
+ const { copilotkit } = useCopilotKit();
2459
+ const providerThrottleMs = copilotkit.defaultThrottleMs;
2460
+ const chatConfig = useCopilotChatConfiguration();
2461
+ (_threadId = threadId) !== null && _threadId !== void 0 || (threadId = chatConfig === null || chatConfig === void 0 ? void 0 : chatConfig.threadId);
2462
+ const [, forceUpdate] = (0, react.useReducer)((x) => x + 1, 0);
2463
+ const updateFlags = (0, react.useMemo)(() => updates !== null && updates !== void 0 ? updates : ALL_UPDATES, [JSON.stringify(updates)]);
2464
+ const provisionalAgentCache = (0, react.useRef)(/* @__PURE__ */ new Map());
2465
+ const agent = (0, react.useMemo)(() => {
2466
+ var _copilotkit$agents;
2467
+ const cacheKey = threadId ? `${agentId}:${threadId}` : agentId;
2468
+ const existing = copilotkit.getAgent(agentId);
2469
+ if (existing) {
2470
+ provisionalAgentCache.current.delete(cacheKey);
2471
+ provisionalAgentCache.current.delete(agentId);
2472
+ if (!threadId) return existing;
2473
+ return getOrCreateThreadClone(existing, threadId, copilotkit.headers);
2474
+ }
2475
+ const isRuntimeConfigured = copilotkit.runtimeUrl !== void 0;
2476
+ const status = copilotkit.runtimeConnectionStatus;
2477
+ if (isRuntimeConfigured && (status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Disconnected || status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Connecting)) {
2478
+ const cached = provisionalAgentCache.current.get(cacheKey);
2479
+ if (cached) {
2480
+ cached.headers = { ...copilotkit.headers };
2481
+ return cached;
2482
+ }
2483
+ const provisional = new _copilotkit_core.ProxiedCopilotRuntimeAgent({
2484
+ runtimeUrl: copilotkit.runtimeUrl,
2485
+ agentId,
2486
+ transport: copilotkit.runtimeTransport,
2487
+ runtimeMode: "pending"
2488
+ });
2489
+ provisional.headers = { ...copilotkit.headers };
2490
+ if (threadId) provisional.threadId = threadId;
2491
+ provisionalAgentCache.current.set(cacheKey, provisional);
2492
+ return provisional;
2493
+ }
2494
+ if (isRuntimeConfigured && status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Error) {
2495
+ const cached = provisionalAgentCache.current.get(cacheKey);
2496
+ if (cached) {
2497
+ cached.headers = { ...copilotkit.headers };
2498
+ return cached;
2499
+ }
2500
+ const provisional = new _copilotkit_core.ProxiedCopilotRuntimeAgent({
2501
+ runtimeUrl: copilotkit.runtimeUrl,
2502
+ agentId,
2503
+ transport: copilotkit.runtimeTransport,
2504
+ runtimeMode: "pending"
2505
+ });
2506
+ provisional.headers = { ...copilotkit.headers };
2507
+ if (threadId) provisional.threadId = threadId;
2508
+ provisionalAgentCache.current.set(cacheKey, provisional);
2509
+ return provisional;
2510
+ }
2511
+ const knownAgents = Object.keys((_copilotkit$agents = copilotkit.agents) !== null && _copilotkit$agents !== void 0 ? _copilotkit$agents : {});
2512
+ const runtimePart = isRuntimeConfigured ? `runtimeUrl=${copilotkit.runtimeUrl}` : "no runtimeUrl";
2513
+ 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.");
2514
+ }, [
2515
+ agentId,
2516
+ threadId,
2517
+ copilotkit.agents,
2518
+ copilotkit.runtimeConnectionStatus,
2519
+ copilotkit.runtimeUrl,
2520
+ copilotkit.runtimeTransport,
2521
+ JSON.stringify(copilotkit.headers)
2522
+ ]);
2523
+ (0, react.useEffect)(() => {
2524
+ if (updateFlags.length === 0) return;
2525
+ let active = true;
2526
+ const handlers = {};
2527
+ let batchScheduled = false;
2528
+ const batchedForceUpdate = () => {
2529
+ if (!active) return;
2530
+ if (!batchScheduled) {
2531
+ batchScheduled = true;
2532
+ queueMicrotask(() => {
2533
+ batchScheduled = false;
2534
+ if (active) forceUpdate();
2535
+ });
2536
+ }
2537
+ };
2538
+ if (updateFlags.includes(UseAgentUpdate.OnMessagesChanged)) handlers.onMessagesChanged = forceUpdate;
2539
+ if (updateFlags.includes(UseAgentUpdate.OnStateChanged)) handlers.onStateChanged = batchedForceUpdate;
2540
+ if (updateFlags.includes(UseAgentUpdate.OnRunStatusChanged)) {
2541
+ handlers.onRunInitialized = batchedForceUpdate;
2542
+ handlers.onRunFinalized = batchedForceUpdate;
2543
+ handlers.onRunFailed = batchedForceUpdate;
2544
+ handlers.onRunErrorEvent = batchedForceUpdate;
2545
+ }
2546
+ const subscription = copilotkit.subscribeToAgentWithOptions(agent, handlers, { throttleMs });
2547
+ return () => {
2548
+ active = false;
2549
+ subscription.unsubscribe();
2550
+ };
2551
+ }, [
2552
+ agent,
2553
+ forceUpdate,
2554
+ throttleMs,
2555
+ providerThrottleMs,
2556
+ updateFlags
2557
+ ]);
2558
+ (0, react.useEffect)(() => {
2559
+ if (agent instanceof _ag_ui_client.HttpAgent) agent.headers = { ...copilotkit.headers };
2560
+ }, [agent, JSON.stringify(copilotkit.headers)]);
2561
+ return { agent };
2562
+ }
2563
+
2399
2564
  //#endregion
2400
2565
  //#region src/v2/hooks/use-render-custom-messages.tsx
2401
2566
  function useRenderCustomMessages() {
@@ -2409,12 +2574,13 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
2409
2574
  return aHasAgent ? -1 : 1;
2410
2575
  });
2411
2576
  return function(params) {
2412
- var _copilotkit$getRunIdF;
2577
+ var _copilotkit$getRunIdF, _getThreadClone;
2413
2578
  if (!customMessageRenderers.length) return null;
2414
2579
  const { message, position } = params;
2415
2580
  const resolvedRunId = (_copilotkit$getRunIdF = copilotkit.getRunIdForMessage(agentId, threadId, message.id)) !== null && _copilotkit$getRunIdF !== void 0 ? _copilotkit$getRunIdF : copilotkit.getRunIdsForThread(agentId, threadId).slice(-1)[0];
2416
2581
  const runId = resolvedRunId !== null && resolvedRunId !== void 0 ? resolvedRunId : `missing-run-id:${message.id}`;
2417
- const agent = copilotkit.getAgent(agentId);
2582
+ const registryAgent = copilotkit.getAgent(agentId);
2583
+ const agent = (_getThreadClone = getThreadClone(registryAgent, threadId)) !== null && _getThreadClone !== void 0 ? _getThreadClone : registryAgent;
2418
2584
  if (!agent) return null;
2419
2585
  const messagesIdsInRun = resolvedRunId ? agent.messages.filter((msg) => copilotkit.getRunIdForMessage(agentId, threadId, msg.id) === resolvedRunId).map((msg) => msg.id) : [message.id];
2420
2586
  const rawMessageIndex = agent.messages.findIndex((msg) => msg.id === message.id);
@@ -2542,120 +2708,6 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
2542
2708
  ]);
2543
2709
  }
2544
2710
 
2545
- //#endregion
2546
- //#region src/v2/hooks/use-agent.tsx
2547
- let UseAgentUpdate = /* @__PURE__ */ function(UseAgentUpdate) {
2548
- UseAgentUpdate["OnMessagesChanged"] = "OnMessagesChanged";
2549
- UseAgentUpdate["OnStateChanged"] = "OnStateChanged";
2550
- UseAgentUpdate["OnRunStatusChanged"] = "OnRunStatusChanged";
2551
- return UseAgentUpdate;
2552
- }({});
2553
- const ALL_UPDATES = [
2554
- UseAgentUpdate.OnMessagesChanged,
2555
- UseAgentUpdate.OnStateChanged,
2556
- UseAgentUpdate.OnRunStatusChanged
2557
- ];
2558
- function useAgent({ agentId, updates, throttleMs } = {}) {
2559
- var _agentId;
2560
- (_agentId = agentId) !== null && _agentId !== void 0 || (agentId = _copilotkit_shared.DEFAULT_AGENT_ID);
2561
- const { copilotkit } = useCopilotKit();
2562
- const providerThrottleMs = copilotkit.defaultThrottleMs;
2563
- const [, forceUpdate] = (0, react.useReducer)((x) => x + 1, 0);
2564
- const updateFlags = (0, react.useMemo)(() => updates !== null && updates !== void 0 ? updates : ALL_UPDATES, [JSON.stringify(updates)]);
2565
- const provisionalAgentCache = (0, react.useRef)(/* @__PURE__ */ new Map());
2566
- const agent = (0, react.useMemo)(() => {
2567
- var _copilotkit$agents;
2568
- const existing = copilotkit.getAgent(agentId);
2569
- if (existing) {
2570
- provisionalAgentCache.current.delete(agentId);
2571
- return existing;
2572
- }
2573
- const isRuntimeConfigured = copilotkit.runtimeUrl !== void 0;
2574
- const status = copilotkit.runtimeConnectionStatus;
2575
- if (isRuntimeConfigured && (status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Disconnected || status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Connecting)) {
2576
- const cached = provisionalAgentCache.current.get(agentId);
2577
- if (cached) {
2578
- cached.headers = { ...copilotkit.headers };
2579
- return cached;
2580
- }
2581
- const provisional = new _copilotkit_core.ProxiedCopilotRuntimeAgent({
2582
- runtimeUrl: copilotkit.runtimeUrl,
2583
- agentId,
2584
- transport: copilotkit.runtimeTransport,
2585
- runtimeMode: "pending"
2586
- });
2587
- provisional.headers = { ...copilotkit.headers };
2588
- provisionalAgentCache.current.set(agentId, provisional);
2589
- return provisional;
2590
- }
2591
- if (isRuntimeConfigured && status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Error) {
2592
- const cached = provisionalAgentCache.current.get(agentId);
2593
- if (cached) {
2594
- cached.headers = { ...copilotkit.headers };
2595
- return cached;
2596
- }
2597
- const provisional = new _copilotkit_core.ProxiedCopilotRuntimeAgent({
2598
- runtimeUrl: copilotkit.runtimeUrl,
2599
- agentId,
2600
- transport: copilotkit.runtimeTransport,
2601
- runtimeMode: "pending"
2602
- });
2603
- provisional.headers = { ...copilotkit.headers };
2604
- provisionalAgentCache.current.set(agentId, provisional);
2605
- return provisional;
2606
- }
2607
- const knownAgents = Object.keys((_copilotkit$agents = copilotkit.agents) !== null && _copilotkit$agents !== void 0 ? _copilotkit$agents : {});
2608
- const runtimePart = isRuntimeConfigured ? `runtimeUrl=${copilotkit.runtimeUrl}` : "no runtimeUrl";
2609
- 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.");
2610
- }, [
2611
- agentId,
2612
- copilotkit.agents,
2613
- copilotkit.runtimeConnectionStatus,
2614
- copilotkit.runtimeUrl,
2615
- copilotkit.runtimeTransport,
2616
- JSON.stringify(copilotkit.headers)
2617
- ]);
2618
- (0, react.useEffect)(() => {
2619
- if (updateFlags.length === 0) return;
2620
- let active = true;
2621
- const handlers = {};
2622
- let batchScheduled = false;
2623
- const batchedForceUpdate = () => {
2624
- if (!active) return;
2625
- if (!batchScheduled) {
2626
- batchScheduled = true;
2627
- queueMicrotask(() => {
2628
- batchScheduled = false;
2629
- if (active) forceUpdate();
2630
- });
2631
- }
2632
- };
2633
- if (updateFlags.includes(UseAgentUpdate.OnMessagesChanged)) handlers.onMessagesChanged = forceUpdate;
2634
- if (updateFlags.includes(UseAgentUpdate.OnStateChanged)) handlers.onStateChanged = batchedForceUpdate;
2635
- if (updateFlags.includes(UseAgentUpdate.OnRunStatusChanged)) {
2636
- handlers.onRunInitialized = batchedForceUpdate;
2637
- handlers.onRunFinalized = batchedForceUpdate;
2638
- handlers.onRunFailed = batchedForceUpdate;
2639
- handlers.onRunErrorEvent = batchedForceUpdate;
2640
- }
2641
- const subscription = copilotkit.subscribeToAgentWithOptions(agent, handlers, { throttleMs });
2642
- return () => {
2643
- active = false;
2644
- subscription.unsubscribe();
2645
- };
2646
- }, [
2647
- agent,
2648
- forceUpdate,
2649
- throttleMs,
2650
- providerThrottleMs,
2651
- updateFlags
2652
- ]);
2653
- (0, react.useEffect)(() => {
2654
- if (agent instanceof _ag_ui_client.HttpAgent) agent.headers = { ...copilotkit.headers };
2655
- }, [agent, JSON.stringify(copilotkit.headers)]);
2656
- return { agent };
2657
- }
2658
-
2659
2711
  //#endregion
2660
2712
  //#region src/v2/hooks/use-suggestions.tsx
2661
2713
  function useSuggestions({ agentId } = {}) {
@@ -5247,7 +5299,10 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
5247
5299
  const existingConfig = useCopilotChatConfiguration();
5248
5300
  const [agentAvailable, setAgentAvailable] = (0, react.useState)(false);
5249
5301
  const resolvedAgentId = (_existingConfig$agent = existingConfig === null || existingConfig === void 0 ? void 0 : existingConfig.agentId) !== null && _existingConfig$agent !== void 0 ? _existingConfig$agent : "default";
5250
- const { agent } = useAgent({ agentId: resolvedAgentId });
5302
+ const { agent } = useAgent({
5303
+ agentId: resolvedAgentId,
5304
+ threadId: existingConfig === null || existingConfig === void 0 ? void 0 : existingConfig.threadId
5305
+ });
5251
5306
  const lastConnectedAgentRef = (0, react.useRef)(null);
5252
5307
  (0, react.useEffect)(() => {
5253
5308
  let detached = false;