@copilotkit/react-core 1.63.0 → 1.63.2-canary.1784918757

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,13 +1,12 @@
1
- import { CopilotKitCoreReact, useCopilotKit } from "@copilotkit/react-core/v2/context";
1
+ import { CopilotKitCoreReact, useCopilotKit, useCopilotKit as useCopilotKit$1 } from "@copilotkit/react-core/v2/context";
2
2
  import React, { createContext, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useReducer, useRef, useState, useSyncExternalStore } from "react";
3
- import { DEFAULT_AGENT_ID, randomUUID } from "@copilotkit/shared";
4
- import { twMerge } from "tailwind-merge";
3
+ import { DEFAULT_AGENT_ID, partialJSONParse, randomUUID } from "@copilotkit/shared";
5
4
  import { jsx } from "react/jsx-runtime";
6
- import { HttpAgent, buildResumeArray, isInterruptExpired, randomUUID as randomUUID$1 } from "@ag-ui/client";
7
- import { CopilotKitCoreRuntimeConnectionStatus, ProxiedCopilotRuntimeAgent, ToolCallStatus, ɵcreateThreadStore, ɵselectFetchMoreError, ɵselectHasNextPage, ɵselectIsFetchingNextPage, ɵselectIsMutating, ɵselectThreads, ɵselectThreadsError, ɵselectThreadsIsLoading } from "@copilotkit/core";
5
+ import { HttpAgent, randomUUID as randomUUID$1 } from "@ag-ui/client";
6
+ import { CopilotKitCoreRuntimeConnectionStatus, ProxiedCopilotRuntimeAgent, ToolCallStatus, ɵInterruptState, ɵcreateThreadStore, ɵselectFetchMoreError, ɵselectHasNextPage, ɵselectIsFetchingNextPage, ɵselectIsMutating, ɵselectThreads, ɵselectThreadsError, ɵselectThreadsIsLoading } from "@copilotkit/core";
8
7
  import { z } from "zod";
9
8
 
10
- //#region src/v2/lib/slots.tsx
9
+ //#region src/v2/lib/shallow-stable-ref.ts
11
10
  /**
12
11
  * Shallow equality comparison for objects.
13
12
  */
@@ -47,49 +46,6 @@ function useShallowStableRef(value) {
47
46
  ref.current = value;
48
47
  return ref.current;
49
48
  }
50
- /**
51
- * Check if a value is a React component type (function, class, forwardRef, memo, etc.)
52
- */
53
- function isReactComponentType(value) {
54
- if (typeof value === "function") return true;
55
- if (value && typeof value === "object" && "$$typeof" in value && !React.isValidElement(value)) return true;
56
- return false;
57
- }
58
- /**
59
- * Internal function to render a slot value as a React element (non-memoized).
60
- */
61
- function renderSlotElement(slot, DefaultComponent, props) {
62
- if (typeof slot === "string") {
63
- const existingClassName = props.className;
64
- return React.createElement(DefaultComponent, {
65
- ...props,
66
- className: twMerge(existingClassName, slot)
67
- });
68
- }
69
- if (isReactComponentType(slot)) return React.createElement(slot, props);
70
- if (slot && typeof slot === "object" && !React.isValidElement(slot)) return React.createElement(DefaultComponent, {
71
- ...props,
72
- ...slot
73
- });
74
- return React.createElement(DefaultComponent, props);
75
- }
76
- /**
77
- * Internal memoized wrapper component for renderSlot.
78
- * Uses forwardRef to support ref forwarding.
79
- */
80
- const MemoizedSlotWrapper = React.memo(React.forwardRef(function MemoizedSlotWrapper(props, ref) {
81
- const { $slot, $component, ...rest } = props;
82
- return renderSlotElement($slot, $component, ref !== null ? {
83
- ...rest,
84
- ref
85
- } : rest);
86
- }), (prev, next) => {
87
- if (prev.$slot !== next.$slot) return false;
88
- if (prev.$component !== next.$component) return false;
89
- const { $slot: _ps, $component: _pc, ...prevRest } = prev;
90
- const { $slot: _ns, $component: _nc, ...nextRest } = next;
91
- return shallowEqual(prevRest, nextRest);
92
- });
93
49
 
94
50
  //#endregion
95
51
  //#region src/v2/providers/CopilotChatConfigurationProvider.tsx
@@ -311,16 +267,19 @@ const ALL_UPDATES = [
311
267
  function useAgent({ agentId, updates, throttleMs } = {}) {
312
268
  const chatConfig = useCopilotChatConfiguration();
313
269
  const resolvedAgentId = agentId ?? chatConfig?.agentId ?? DEFAULT_AGENT_ID;
314
- const { copilotkit } = useCopilotKit();
270
+ const { copilotkit } = useCopilotKit$1();
315
271
  const providerThrottleMs = copilotkit.defaultThrottleMs;
316
272
  const [, forceUpdate] = useReducer((x) => x + 1, 0);
317
273
  const updateFlags = useMemo(() => updates ?? ALL_UPDATES, [JSON.stringify(updates)]);
318
274
  const provisionalAgentCache = useRef(/* @__PURE__ */ new Map());
319
- const agent = useMemo(() => {
275
+ const { agent, isReady } = useMemo(() => {
320
276
  const existing = copilotkit.getAgent(resolvedAgentId);
321
277
  if (existing) {
322
278
  provisionalAgentCache.current.delete(resolvedAgentId);
323
- return existing;
279
+ return {
280
+ agent: existing,
281
+ isReady: true
282
+ };
324
283
  }
325
284
  const isRuntimeConfigured = copilotkit.runtimeUrl !== void 0;
326
285
  const status = copilotkit.runtimeConnectionStatus;
@@ -328,7 +287,10 @@ function useAgent({ agentId, updates, throttleMs } = {}) {
328
287
  const cached = provisionalAgentCache.current.get(resolvedAgentId);
329
288
  if (cached) {
330
289
  copilotkit.applyHeadersToAgent(cached);
331
- return cached;
290
+ return {
291
+ agent: cached,
292
+ isReady: false
293
+ };
332
294
  }
333
295
  const provisional = new ProxiedCopilotRuntimeAgent({
334
296
  runtimeUrl: copilotkit.runtimeUrl,
@@ -338,13 +300,19 @@ function useAgent({ agentId, updates, throttleMs } = {}) {
338
300
  });
339
301
  copilotkit.applyHeadersToAgent(provisional);
340
302
  provisionalAgentCache.current.set(resolvedAgentId, provisional);
341
- return provisional;
303
+ return {
304
+ agent: provisional,
305
+ isReady: false
306
+ };
342
307
  }
343
308
  if (isRuntimeConfigured && status === CopilotKitCoreRuntimeConnectionStatus.Error) {
344
309
  const cached = provisionalAgentCache.current.get(resolvedAgentId);
345
310
  if (cached) {
346
311
  copilotkit.applyHeadersToAgent(cached);
347
- return cached;
312
+ return {
313
+ agent: cached,
314
+ isReady: false
315
+ };
348
316
  }
349
317
  const provisional = new ProxiedCopilotRuntimeAgent({
350
318
  runtimeUrl: copilotkit.runtimeUrl,
@@ -354,7 +322,10 @@ function useAgent({ agentId, updates, throttleMs } = {}) {
354
322
  });
355
323
  copilotkit.applyHeadersToAgent(provisional);
356
324
  provisionalAgentCache.current.set(resolvedAgentId, provisional);
357
- return provisional;
325
+ return {
326
+ agent: provisional,
327
+ isReady: false
328
+ };
358
329
  }
359
330
  const knownAgents = Object.keys(copilotkit.agents ?? {});
360
331
  const runtimePart = isRuntimeConfigured ? `runtimeUrl=${copilotkit.runtimeUrl}` : "no runtimeUrl";
@@ -415,14 +386,17 @@ function useAgent({ agentId, updates, throttleMs } = {}) {
415
386
  configThreadId,
416
387
  configHasExplicitThreadId
417
388
  ]);
418
- return { agent };
389
+ return {
390
+ agent,
391
+ isReady
392
+ };
419
393
  }
420
394
 
421
395
  //#endregion
422
396
  //#region src/v2/hooks/use-frontend-tool.tsx
423
397
  const EMPTY_DEPS$1 = [];
424
398
  function useFrontendTool(tool, deps) {
425
- const { copilotkit } = useCopilotKit();
399
+ const { copilotkit } = useCopilotKit$1();
426
400
  const extraDeps = deps ?? EMPTY_DEPS$1;
427
401
  useEffect(() => {
428
402
  const name = tool.name;
@@ -522,7 +496,7 @@ function useComponent(config, deps) {
522
496
  //#endregion
523
497
  //#region src/v2/hooks/use-human-in-the-loop.tsx
524
498
  function useHumanInTheLoop(tool, deps) {
525
- const { copilotkit } = useCopilotKit();
499
+ const { copilotkit } = useCopilotKit$1();
526
500
  const resolvePromiseRef = useRef(null);
527
501
  const cleanupAbortRef = useRef(null);
528
502
  const respond = useCallback(async (result) => {
@@ -650,14 +624,15 @@ function toLegacyEvent(pending) {
650
624
  * ```
651
625
  */
652
626
  function useInterrupt(config) {
653
- const { copilotkit } = useCopilotKit();
627
+ const { copilotkit } = useCopilotKit$1();
654
628
  const { agent } = useAgent({ agentId: config.agentId });
655
629
  const [pending, setPending] = useState(null);
656
630
  const pendingRef = useRef(pending);
657
631
  pendingRef.current = pending;
658
632
  const [handlerResult, setHandlerResult] = useState(null);
659
- const responsesRef = useRef({});
633
+ const interruptStateRef = useRef(new ɵInterruptState());
660
634
  useEffect(() => {
635
+ const interruptState = interruptStateRef.current;
661
636
  let localLegacy = null;
662
637
  let localStandard = null;
663
638
  const subscription = agent.subscribe({
@@ -673,106 +648,111 @@ function useInterrupt(config) {
673
648
  onRunStartedEvent: () => {
674
649
  localLegacy = null;
675
650
  localStandard = null;
676
- responsesRef.current = {};
651
+ interruptState.clear();
677
652
  setPending(null);
678
653
  },
679
654
  onRunFinalized: () => {
680
- if (localStandard && localStandard.length > 0) setPending({
681
- kind: "standard",
682
- interrupts: localStandard
683
- });
684
- else if (localLegacy) setPending({
685
- kind: "legacy",
686
- event: localLegacy
687
- });
655
+ if (localStandard && localStandard.length > 0) {
656
+ interruptState.setStandard(localStandard);
657
+ setPending(interruptState.pending);
658
+ } else if (localLegacy) {
659
+ interruptState.setLegacy(localLegacy);
660
+ setPending(interruptState.pending);
661
+ }
688
662
  localLegacy = null;
689
663
  localStandard = null;
690
664
  },
691
665
  onRunFailed: () => {
692
666
  localLegacy = null;
693
667
  localStandard = null;
694
- responsesRef.current = {};
668
+ interruptState.clear();
695
669
  setPending(null);
696
670
  }
697
671
  });
698
- return () => subscription.unsubscribe();
672
+ return () => {
673
+ subscription.unsubscribe();
674
+ interruptState.clear();
675
+ };
699
676
  }, [agent]);
700
- const submitStandardIfComplete = useCallback(async (interrupts) => {
701
- if (!interrupts.every((i) => responsesRef.current[i.id])) return;
702
- const expired = interrupts.find((i) => isInterruptExpired(i));
703
- if (expired) {
704
- console.error(`[CopilotKit] useInterrupt: interrupt ${expired.id} expired at ${expired.expiresAt}; not resuming.`);
705
- responsesRef.current = {};
706
- setPending(null);
707
- return;
708
- }
709
- const resume = buildResumeArray(interrupts, responsesRef.current);
710
- for (const i of interrupts) {
711
- if (!i.toolCallId) continue;
712
- const response = responsesRef.current[i.id];
713
- const content = response.status === "cancelled" ? { status: "cancelled" } : response.payload ?? { status: "resolved" };
714
- agent.addMessage({
715
- id: randomUUID$1(),
716
- role: "tool",
717
- toolCallId: i.toolCallId,
718
- content: JSON.stringify(content)
719
- });
720
- }
721
- responsesRef.current = {};
722
- try {
677
+ const resolve = useCallback(async (payload, interruptId) => {
678
+ const current = pendingRef.current;
679
+ if (!current) return;
680
+ if (current.kind === "standard" && current.interrupts.length > 1 && interruptId === void 0) console.warn(`[CopilotKit] useInterrupt: resolve()/cancel() called without an interruptId while ${current.interrupts.length} interrupts are open; defaulting to the first. Pass an interruptId to address a specific interrupt.`);
681
+ const decision = interruptStateRef.current.resolve(payload, interruptId);
682
+ if (decision.kind === "legacy-resume") try {
723
683
  return await copilotkit.runAgent({
724
684
  agent,
725
- resume
685
+ forwardedProps: { command: {
686
+ resume: decision.payload,
687
+ interruptEvent: decision.interruptValue
688
+ } }
726
689
  });
727
690
  } catch (err) {
728
691
  console.error("[CopilotKit] useInterrupt resolve: runAgent rejected; clearing pending + rethrowing", err);
729
692
  setPending(null);
730
693
  throw err;
731
694
  }
732
- }, [agent, copilotkit]);
733
- const resolve = useCallback(async (payload, interruptId) => {
734
- const current = pendingRef.current;
735
- if (!current) return;
736
- if (current.kind === "legacy") try {
695
+ if (decision.kind === "expired") {
696
+ console.error(`[CopilotKit] useInterrupt: interrupt ${decision.interrupt.id} expired at ${decision.interrupt.expiresAt}; not resuming.`);
697
+ interruptStateRef.current.clear();
698
+ setPending(null);
699
+ return;
700
+ }
701
+ if (decision.kind !== "resume") return;
702
+ for (const toolResult of decision.toolResults) agent.addMessage({
703
+ id: randomUUID$1(),
704
+ role: "tool",
705
+ toolCallId: toolResult.toolCallId,
706
+ content: toolResult.content
707
+ });
708
+ try {
737
709
  return await copilotkit.runAgent({
738
710
  agent,
739
- forwardedProps: { command: {
740
- resume: payload,
741
- interruptEvent: current.event.value
742
- } }
711
+ resume: decision.resume
743
712
  });
744
713
  } catch (err) {
745
714
  console.error("[CopilotKit] useInterrupt resolve: runAgent rejected; clearing pending + rethrowing", err);
715
+ interruptStateRef.current.clear();
746
716
  setPending(null);
747
717
  throw err;
748
718
  }
749
- if (current.interrupts.length > 1 && interruptId === void 0) console.warn(`[CopilotKit] useInterrupt: resolve()/cancel() called without an interruptId while ${current.interrupts.length} interrupts are open; defaulting to the first. Pass an interruptId to address a specific interrupt.`);
750
- const id = interruptId ?? current.interrupts[0]?.id;
751
- if (!id) return;
752
- responsesRef.current[id] = {
753
- status: "resolved",
754
- payload
755
- };
756
- return submitStandardIfComplete(current.interrupts);
757
- }, [
758
- agent,
759
- copilotkit,
760
- submitStandardIfComplete
761
- ]);
719
+ }, [agent, copilotkit]);
762
720
  const cancel = useCallback(async (interruptId) => {
763
721
  const current = pendingRef.current;
764
722
  if (!current) return;
765
- if (current.kind === "legacy") {
723
+ if (current.kind === "standard" && current.interrupts.length > 1 && interruptId === void 0) console.warn(`[CopilotKit] useInterrupt: resolve()/cancel() called without an interruptId while ${current.interrupts.length} interrupts are open; defaulting to the first. Pass an interruptId to address a specific interrupt.`);
724
+ const decision = interruptStateRef.current.cancel(interruptId);
725
+ if (decision.kind === "dismiss") {
766
726
  console.warn("[CopilotKit] useInterrupt: cancel() is not supported for legacy on_interrupt interrupts; dismissing.");
727
+ interruptStateRef.current.clear();
728
+ setPending(null);
729
+ return;
730
+ }
731
+ if (decision.kind === "expired") {
732
+ console.error(`[CopilotKit] useInterrupt: interrupt ${decision.interrupt.id} expired at ${decision.interrupt.expiresAt}; not resuming.`);
733
+ interruptStateRef.current.clear();
767
734
  setPending(null);
768
735
  return;
769
736
  }
770
- if (current.interrupts.length > 1 && interruptId === void 0) console.warn(`[CopilotKit] useInterrupt: resolve()/cancel() called without an interruptId while ${current.interrupts.length} interrupts are open; defaulting to the first. Pass an interruptId to address a specific interrupt.`);
771
- const id = interruptId ?? current.interrupts[0]?.id;
772
- if (!id) return;
773
- responsesRef.current[id] = { status: "cancelled" };
774
- return submitStandardIfComplete(current.interrupts);
775
- }, [submitStandardIfComplete]);
737
+ if (decision.kind !== "resume") return;
738
+ for (const toolResult of decision.toolResults) agent.addMessage({
739
+ id: randomUUID$1(),
740
+ role: "tool",
741
+ toolCallId: toolResult.toolCallId,
742
+ content: toolResult.content
743
+ });
744
+ try {
745
+ return await copilotkit.runAgent({
746
+ agent,
747
+ resume: decision.resume
748
+ });
749
+ } catch (err) {
750
+ console.error("[CopilotKit] useInterrupt resolve: runAgent rejected; clearing pending + rethrowing", err);
751
+ interruptStateRef.current.clear();
752
+ setPending(null);
753
+ throw err;
754
+ }
755
+ }, [agent, copilotkit]);
776
756
  const renderRef = useRef(config.render);
777
757
  renderRef.current = config.render;
778
758
  const enabledRef = useRef(config.enabled);
@@ -814,7 +794,7 @@ function useInterrupt(config) {
814
794
  maybePromise = handler({
815
795
  event: legacyEvent,
816
796
  interrupt: pending.kind === "standard" ? pending.interrupts[0] : null,
817
- interrupts: pending.kind === "standard" ? pending.interrupts : [],
797
+ interrupts: pending.kind === "standard" ? [...pending.interrupts] : [],
818
798
  resolve: resolveRef.current,
819
799
  cancel: cancelRef.current
820
800
  });
@@ -843,7 +823,7 @@ function useInterrupt(config) {
843
823
  return renderRef.current({
844
824
  event: legacyEvent,
845
825
  interrupt: pending.kind === "standard" ? pending.interrupts[0] : null,
846
- interrupts: pending.kind === "standard" ? pending.interrupts : [],
826
+ interrupts: pending.kind === "standard" ? [...pending.interrupts] : [],
847
827
  result: handlerResult,
848
828
  resolve,
849
829
  cancel
@@ -874,7 +854,7 @@ function useInterrupt(config) {
874
854
  //#endregion
875
855
  //#region src/v2/hooks/use-suggestions.tsx
876
856
  function useSuggestions({ agentId } = {}) {
877
- const { copilotkit } = useCopilotKit();
857
+ const { copilotkit } = useCopilotKit$1();
878
858
  const config = useCopilotChatConfiguration();
879
859
  const resolvedAgentId = useMemo(() => agentId ?? config?.agentId ?? DEFAULT_AGENT_ID, [agentId, config?.agentId]);
880
860
  const [suggestions, setSuggestions] = useState(() => {
@@ -927,7 +907,7 @@ function useSuggestions({ agentId } = {}) {
927
907
  //#endregion
928
908
  //#region src/v2/hooks/use-configure-suggestions.tsx
929
909
  function useConfigureSuggestions(config, deps) {
930
- const { copilotkit } = useCopilotKit();
910
+ const { copilotkit } = useCopilotKit$1();
931
911
  const chatConfig = useCopilotChatConfiguration();
932
912
  const extraDeps = deps ?? [];
933
913
  const resolvedConsumerAgentId = useMemo(() => chatConfig?.agentId ?? DEFAULT_AGENT_ID, [chatConfig?.agentId]);
@@ -1087,7 +1067,7 @@ function normalizeStaticSuggestions(suggestions) {
1087
1067
  //#region src/v2/hooks/use-agent-context.tsx
1088
1068
  function useAgentContext(context) {
1089
1069
  const { description, value } = context;
1090
- const { copilotkit } = useCopilotKit();
1070
+ const { copilotkit } = useCopilotKit$1();
1091
1071
  const stringValue = useMemo(() => {
1092
1072
  if (typeof value === "string") return value;
1093
1073
  return JSON.stringify(value);
@@ -1158,7 +1138,7 @@ function useThreadStoreSelector(store, selector) {
1158
1138
  * ```
1159
1139
  */
1160
1140
  function useThreads({ agentId, includeArchived, limit, enabled = true }) {
1161
- const { copilotkit } = useCopilotKit();
1141
+ const { copilotkit } = useCopilotKit$1();
1162
1142
  const [store] = useState(() => ɵcreateThreadStore({ fetch: globalThis.fetch }));
1163
1143
  const coreThreads = useThreadStoreSelector(store, ɵselectThreads);
1164
1144
  const threads = useMemo(() => coreThreads.map(({ id, agentId, name, archived, createdAt, updatedAt, lastRunAt }) => ({
@@ -1352,7 +1332,7 @@ const EMPTY_DEPS = [];
1352
1332
  * ```
1353
1333
  */
1354
1334
  function useRenderTool(config, deps) {
1355
- const { copilotkit } = useCopilotKit();
1335
+ const { copilotkit } = useCopilotKit$1();
1356
1336
  const extraDeps = deps ?? EMPTY_DEPS;
1357
1337
  useEffect(() => {
1358
1338
  const renderer = config.name === "*" && !config.parameters ? defineToolCallRenderer({
@@ -1389,6 +1369,76 @@ function useRenderTool(config, deps) {
1389
1369
  ]);
1390
1370
  }
1391
1371
 
1372
+ //#endregion
1373
+ //#region src/v2/hooks/use-render-tool-call.tsx
1374
+ /**
1375
+ * Memoized component that renders a single tool call.
1376
+ * This prevents unnecessary re-renders when parent components update
1377
+ * but the tool call data hasn't changed.
1378
+ */
1379
+ const ToolCallRenderer = React.memo(function ToolCallRenderer({ toolCall, toolMessage, RenderComponent, isExecuting }) {
1380
+ const args = useMemo(() => partialJSONParse(toolCall.function.arguments), [toolCall.function.arguments]);
1381
+ const toolName = toolCall.function.name;
1382
+ if (toolMessage) return /* @__PURE__ */ jsx(RenderComponent, {
1383
+ name: toolName,
1384
+ toolCallId: toolCall.id,
1385
+ args,
1386
+ status: ToolCallStatus.Complete,
1387
+ result: toolMessage.content
1388
+ });
1389
+ else if (isExecuting) return /* @__PURE__ */ jsx(RenderComponent, {
1390
+ name: toolName,
1391
+ toolCallId: toolCall.id,
1392
+ args,
1393
+ status: ToolCallStatus.Executing,
1394
+ result: void 0
1395
+ });
1396
+ else return /* @__PURE__ */ jsx(RenderComponent, {
1397
+ name: toolName,
1398
+ toolCallId: toolCall.id,
1399
+ args,
1400
+ status: ToolCallStatus.InProgress,
1401
+ result: void 0
1402
+ });
1403
+ }, (prevProps, nextProps) => {
1404
+ if (prevProps.toolCall.id !== nextProps.toolCall.id) return false;
1405
+ if (prevProps.toolCall.function.name !== nextProps.toolCall.function.name) return false;
1406
+ if (prevProps.toolCall.function.arguments !== nextProps.toolCall.function.arguments) return false;
1407
+ if (prevProps.toolMessage?.content !== nextProps.toolMessage?.content) return false;
1408
+ if (prevProps.isExecuting !== nextProps.isExecuting) return false;
1409
+ if (prevProps.RenderComponent !== nextProps.RenderComponent) return false;
1410
+ return true;
1411
+ });
1412
+ /**
1413
+ * Hook that returns a function to render tool calls based on the render functions
1414
+ * defined in CopilotKitProvider.
1415
+ *
1416
+ * @returns A function that takes a tool call and optional tool message and returns the rendered component
1417
+ */
1418
+ function useRenderToolCall() {
1419
+ const { copilotkit, executingToolCallIds } = useCopilotKit$1();
1420
+ const agentId = useCopilotChatConfiguration()?.agentId ?? DEFAULT_AGENT_ID;
1421
+ const renderToolCalls = useSyncExternalStore((callback) => {
1422
+ return copilotkit.subscribe({ onRenderToolCallsChanged: callback }).unsubscribe;
1423
+ }, () => copilotkit.renderToolCalls, () => copilotkit.renderToolCalls);
1424
+ return useCallback(({ toolCall, toolMessage }) => {
1425
+ const exactMatches = renderToolCalls.filter((rc) => rc.name === toolCall.function.name);
1426
+ const renderConfig = exactMatches.find((rc) => rc.agentId === agentId) || exactMatches.find((rc) => !rc.agentId) || exactMatches[0] || renderToolCalls.find((rc) => rc.name === "*");
1427
+ if (!renderConfig) return null;
1428
+ const RenderComponent = renderConfig.render;
1429
+ return /* @__PURE__ */ jsx(ToolCallRenderer, {
1430
+ toolCall,
1431
+ toolMessage,
1432
+ RenderComponent,
1433
+ isExecuting: executingToolCallIds.has(toolCall.id)
1434
+ }, toolCall.id);
1435
+ }, [
1436
+ renderToolCalls,
1437
+ executingToolCallIds,
1438
+ agentId
1439
+ ]);
1440
+ }
1441
+
1392
1442
  //#endregion
1393
1443
  //#region src/v2/hooks/use-capabilities.tsx
1394
1444
  /**
@@ -1410,5 +1460,5 @@ function useCapabilities(agentId) {
1410
1460
  }
1411
1461
 
1412
1462
  //#endregion
1413
- export { CopilotChatConfigurationProvider, CopilotChatDefaultLabels, CopilotKitCoreReact, defineToolCallRenderer, useAgent, useAgentContext, useCapabilities, useComponent, useConfigureSuggestions, useCopilotChatConfiguration, useFrontendTool, useHumanInTheLoop, useInterrupt, useRenderTool, useSuggestions, useThreads };
1463
+ export { CopilotChatConfigurationProvider, CopilotChatDefaultLabels, CopilotKitCoreReact, UseAgentUpdate, defineToolCallRenderer, useAgent, useAgentContext, useCapabilities, useComponent, useConfigureSuggestions, useCopilotChatConfiguration, useCopilotKit, useFrontendTool, useHumanInTheLoop, useInterrupt, useRenderTool, useRenderToolCall, useSuggestions, useThreads };
1414
1464
  //# sourceMappingURL=headless.mjs.map