@copilotkit/react-core 1.51.3-next.6 → 1.51.3-next.7

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 (97) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/chunk-77IVITG3.mjs +158 -0
  3. package/dist/chunk-77IVITG3.mjs.map +1 -0
  4. package/dist/chunk-BKMJ4LC7.mjs +119 -0
  5. package/dist/chunk-BKMJ4LC7.mjs.map +1 -0
  6. package/dist/chunk-C3YJYDK4.mjs +189 -0
  7. package/dist/chunk-C3YJYDK4.mjs.map +1 -0
  8. package/dist/{chunk-GIU66J37.mjs → chunk-DQXCQWSG.mjs} +47 -5
  9. package/dist/chunk-DQXCQWSG.mjs.map +1 -0
  10. package/dist/{chunk-HBMPXNW2.mjs → chunk-LO4RRITI.mjs} +71 -18
  11. package/dist/chunk-LO4RRITI.mjs.map +1 -0
  12. package/dist/{chunk-3G4VFRVV.mjs → chunk-NXHQDCZF.mjs} +2 -2
  13. package/dist/{chunk-FDOMAPJY.mjs → chunk-QD7EID4N.mjs} +1 -1
  14. package/dist/chunk-QD7EID4N.mjs.map +1 -0
  15. package/dist/{chunk-YTQHRJUA.mjs → chunk-VKNLTZJE.mjs} +2 -2
  16. package/dist/{chunk-4RRUJHCI.mjs → chunk-VP43SLSZ.mjs} +2 -2
  17. package/dist/{chunk-MF2ZSLBV.mjs → chunk-XZFIJ7XF.mjs} +2 -2
  18. package/dist/components/copilot-provider/copilotkit.js +437 -150
  19. package/dist/components/copilot-provider/copilotkit.js.map +1 -1
  20. package/dist/components/copilot-provider/copilotkit.mjs +5 -3
  21. package/dist/components/copilot-provider/index.js +437 -150
  22. package/dist/components/copilot-provider/index.js.map +1 -1
  23. package/dist/components/copilot-provider/index.mjs +5 -3
  24. package/dist/components/index.js +437 -150
  25. package/dist/components/index.js.map +1 -1
  26. package/dist/components/index.mjs +5 -3
  27. package/dist/context/coagent-state-renders-context.d.ts +1 -0
  28. package/dist/context/coagent-state-renders-context.js.map +1 -1
  29. package/dist/context/coagent-state-renders-context.mjs +1 -1
  30. package/dist/context/index.js.map +1 -1
  31. package/dist/context/index.mjs +1 -1
  32. package/dist/hooks/index.js +512 -212
  33. package/dist/hooks/index.js.map +1 -1
  34. package/dist/hooks/index.mjs +19 -17
  35. package/dist/hooks/use-coagent-state-render-bridge.helpers.d.ts +92 -0
  36. package/dist/hooks/use-coagent-state-render-bridge.helpers.js +231 -0
  37. package/dist/hooks/use-coagent-state-render-bridge.helpers.js.map +1 -0
  38. package/dist/hooks/use-coagent-state-render-bridge.helpers.mjs +24 -0
  39. package/dist/hooks/use-coagent-state-render-bridge.helpers.mjs.map +1 -0
  40. package/dist/hooks/use-coagent-state-render-bridge.js +334 -72
  41. package/dist/hooks/use-coagent-state-render-bridge.js.map +1 -1
  42. package/dist/hooks/use-coagent-state-render-bridge.mjs +4 -2
  43. package/dist/hooks/use-coagent-state-render-registry.d.ts +25 -0
  44. package/dist/hooks/use-coagent-state-render-registry.js +358 -0
  45. package/dist/hooks/use-coagent-state-render-registry.js.map +1 -0
  46. package/dist/hooks/use-coagent-state-render-registry.mjs +9 -0
  47. package/dist/hooks/use-coagent-state-render-registry.mjs.map +1 -0
  48. package/dist/hooks/use-coagent-state-render.js.map +1 -1
  49. package/dist/hooks/use-coagent-state-render.mjs +2 -2
  50. package/dist/hooks/use-copilot-chat-headless_c.js +414 -114
  51. package/dist/hooks/use-copilot-chat-headless_c.js.map +1 -1
  52. package/dist/hooks/use-copilot-chat-headless_c.mjs +7 -5
  53. package/dist/hooks/use-copilot-chat.js +406 -106
  54. package/dist/hooks/use-copilot-chat.js.map +1 -1
  55. package/dist/hooks/use-copilot-chat.mjs +7 -5
  56. package/dist/hooks/use-copilot-chat_internal.js +406 -106
  57. package/dist/hooks/use-copilot-chat_internal.js.map +1 -1
  58. package/dist/hooks/use-copilot-chat_internal.mjs +6 -4
  59. package/dist/hooks/use-langgraph-interrupt-render.mjs +1 -1
  60. package/dist/index.js +651 -311
  61. package/dist/index.js.map +1 -1
  62. package/dist/index.mjs +22 -20
  63. package/dist/lib/copilot-task.js.map +1 -1
  64. package/dist/lib/copilot-task.mjs +6 -4
  65. package/dist/lib/index.js.map +1 -1
  66. package/dist/lib/index.mjs +6 -4
  67. package/dist/setupTests.js +1 -0
  68. package/dist/setupTests.js.map +1 -1
  69. package/dist/setupTests.mjs +1 -0
  70. package/dist/setupTests.mjs.map +1 -1
  71. package/dist/test-helpers/copilot-context.d.ts +14 -0
  72. package/dist/test-helpers/copilot-context.js +128 -0
  73. package/dist/test-helpers/copilot-context.js.map +1 -0
  74. package/dist/test-helpers/copilot-context.mjs +74 -0
  75. package/dist/test-helpers/copilot-context.mjs.map +1 -0
  76. package/dist/types/index.mjs +1 -1
  77. package/package.json +5 -5
  78. package/src/components/copilot-provider/copilotkit.tsx +56 -0
  79. package/src/context/coagent-state-renders-context.tsx +1 -0
  80. package/src/hooks/__tests__/use-coagent-state-render-bridge.helpers.test.ts +100 -0
  81. package/src/hooks/__tests__/use-coagent-state-render.e2e.test.tsx +892 -37
  82. package/src/hooks/__tests__/use-coagent-state-render.test.tsx +334 -0
  83. package/src/hooks/use-coagent-state-render-bridge.helpers.ts +311 -0
  84. package/src/hooks/use-coagent-state-render-bridge.tsx +25 -120
  85. package/src/hooks/use-coagent-state-render-registry.ts +215 -0
  86. package/src/hooks/use-copilot-chat_internal.ts +93 -34
  87. package/src/setupTests.ts +1 -0
  88. package/src/test-helpers/copilot-context.ts +91 -0
  89. package/dist/chunk-3X3I7OJV.mjs +0 -172
  90. package/dist/chunk-3X3I7OJV.mjs.map +0 -1
  91. package/dist/chunk-FDOMAPJY.mjs.map +0 -1
  92. package/dist/chunk-GIU66J37.mjs.map +0 -1
  93. package/dist/chunk-HBMPXNW2.mjs.map +0 -1
  94. /package/dist/{chunk-3G4VFRVV.mjs.map → chunk-NXHQDCZF.mjs.map} +0 -0
  95. /package/dist/{chunk-YTQHRJUA.mjs.map → chunk-VKNLTZJE.mjs.map} +0 -0
  96. /package/dist/{chunk-4RRUJHCI.mjs.map → chunk-VP43SLSZ.mjs.map} +0 -0
  97. /package/dist/{chunk-MF2ZSLBV.mjs.map → chunk-XZFIJ7XF.mjs.map} +0 -0
@@ -83,7 +83,7 @@ __export(use_copilot_chat_internal_exports, {
83
83
  useCopilotChatInternal: () => useCopilotChatInternal
84
84
  });
85
85
  module.exports = __toCommonJS(use_copilot_chat_internal_exports);
86
- var import_react13 = require("react");
86
+ var import_react14 = require("react");
87
87
 
88
88
  // src/context/copilot-context.tsx
89
89
  var import_react = __toESM(require("react"));
@@ -472,7 +472,7 @@ function useLangGraphInterruptRender(agent) {
472
472
  }
473
473
 
474
474
  // src/hooks/use-copilot-chat_internal.ts
475
- var import_react14 = require("@copilotkitnext/react");
475
+ var import_react15 = require("@copilotkitnext/react");
476
476
 
477
477
  // src/hooks/use-lazy-tool-renderer.tsx
478
478
  var import_react9 = require("@copilotkitnext/react");
@@ -503,8 +503,11 @@ function useLazyToolRenderer() {
503
503
  var import_client = require("@ag-ui/client");
504
504
 
505
505
  // src/hooks/use-coagent-state-render-bridge.tsx
506
- var import_react11 = require("@copilotkitnext/react");
507
- var import_react12 = require("react");
506
+ var import_react12 = require("@copilotkitnext/react");
507
+ var import_react13 = require("react");
508
+ var import_shared4 = require("@copilotkit/shared");
509
+
510
+ // src/hooks/use-coagent-state-render-bridge.helpers.ts
508
511
  var import_shared3 = require("@copilotkit/shared");
509
512
  function getStateWithoutConstantKeys(state) {
510
513
  if (!state)
@@ -527,16 +530,294 @@ function areStatesEquals(a, b) {
527
530
  ]);
528
531
  return JSON.stringify(aWithoutConstantKeys) === JSON.stringify(bWithoutConstantKeys);
529
532
  }
533
+ function isPlaceholderMessageId(messageId) {
534
+ return !!messageId && messageId.startsWith("coagent-state-render-");
535
+ }
536
+ function isPlaceholderMessageName(messageName) {
537
+ return messageName === "coagent-state-render";
538
+ }
539
+ function readCachedMessageEntry(entry) {
540
+ if (!entry || typeof entry !== "object") {
541
+ return { snapshot: entry, runId: void 0 };
542
+ }
543
+ const snapshot = "snapshot" in entry ? entry.snapshot : entry;
544
+ const runId = "runId" in entry ? entry.runId : void 0;
545
+ return { snapshot, runId };
546
+ }
547
+ function getEffectiveRunId({
548
+ existingClaimRunId,
549
+ cachedMessageRunId,
550
+ runId
551
+ }) {
552
+ return existingClaimRunId || cachedMessageRunId || runId || "pending";
553
+ }
554
+ function resolveClaim({
555
+ claims,
556
+ context,
557
+ stateSnapshot
558
+ }) {
559
+ const { messageId, stateRenderId, runId, messageIndex } = context;
560
+ const existing = claims[messageId];
561
+ if (existing) {
562
+ const canRender = existing.stateRenderId === stateRenderId;
563
+ const shouldUpdateRunId = canRender && runId && (!existing.runId || existing.runId === "pending");
564
+ return {
565
+ canRender,
566
+ action: canRender ? "existing" /* Existing */ : "block" /* Block */,
567
+ updateRunId: shouldUpdateRunId ? runId : void 0
568
+ };
569
+ }
570
+ const normalizedRunId = runId != null ? runId : "pending";
571
+ const renderClaimedByOtherMessageEntry = Object.entries(claims).find(
572
+ ([, claim]) => {
573
+ var _a;
574
+ return claim.stateRenderId === stateRenderId && ((_a = claim.runId) != null ? _a : "pending") === normalizedRunId && (0, import_shared3.dataToUUID)(getStateWithoutConstantKeys(claim.stateSnapshot)) === (0, import_shared3.dataToUUID)(getStateWithoutConstantKeys(stateSnapshot));
575
+ }
576
+ );
577
+ const renderClaimedByOtherMessage = renderClaimedByOtherMessageEntry == null ? void 0 : renderClaimedByOtherMessageEntry[1];
578
+ const claimedMessageId = renderClaimedByOtherMessageEntry == null ? void 0 : renderClaimedByOtherMessageEntry[0];
579
+ if (renderClaimedByOtherMessage) {
580
+ if (messageIndex !== void 0 && renderClaimedByOtherMessage.messageIndex !== void 0 && messageIndex > renderClaimedByOtherMessage.messageIndex) {
581
+ return {
582
+ canRender: true,
583
+ action: "override" /* Override */,
584
+ nextClaim: { stateRenderId, runId, messageIndex },
585
+ lockOthers: runId === renderClaimedByOtherMessage.runId || isPlaceholderMessageId(claimedMessageId)
586
+ };
587
+ }
588
+ if (runId && renderClaimedByOtherMessage.runId && runId !== renderClaimedByOtherMessage.runId) {
589
+ return {
590
+ canRender: true,
591
+ action: "override" /* Override */,
592
+ nextClaim: { stateRenderId, runId, messageIndex },
593
+ lockOthers: isPlaceholderMessageId(claimedMessageId)
594
+ };
595
+ }
596
+ if (isPlaceholderMessageId(claimedMessageId)) {
597
+ return {
598
+ canRender: true,
599
+ action: "override" /* Override */,
600
+ nextClaim: { stateRenderId, runId, messageIndex },
601
+ lockOthers: true
602
+ };
603
+ }
604
+ if (stateSnapshot && renderClaimedByOtherMessage.stateSnapshot && !areStatesEquals(renderClaimedByOtherMessage.stateSnapshot, stateSnapshot)) {
605
+ return {
606
+ canRender: true,
607
+ action: "override" /* Override */,
608
+ nextClaim: { stateRenderId, runId }
609
+ };
610
+ }
611
+ return { canRender: false, action: "block" /* Block */ };
612
+ }
613
+ if (!runId) {
614
+ return { canRender: false, action: "block" /* Block */ };
615
+ }
616
+ return {
617
+ canRender: true,
618
+ action: "create" /* Create */,
619
+ nextClaim: { stateRenderId, runId, messageIndex }
620
+ };
621
+ }
622
+ function selectSnapshot({
623
+ messageId,
624
+ messageName,
625
+ allowLiveState,
626
+ skipLatestCache,
627
+ stateRenderId,
628
+ effectiveRunId,
629
+ stateSnapshotProp,
630
+ agentState,
631
+ agentMessages,
632
+ existingClaim,
633
+ caches
634
+ }) {
635
+ var _a, _b, _c, _d, _e, _f;
636
+ const lastAssistantId = agentMessages ? (_a = [...agentMessages].reverse().find((msg) => msg.role === "assistant")) == null ? void 0 : _a.id : void 0;
637
+ const latestSnapshot = stateRenderId !== void 0 ? caches.byStateRenderAndRun[`${stateRenderId}::latest`] : void 0;
638
+ const messageIndex = agentMessages ? agentMessages.findIndex((msg) => msg.id === messageId) : -1;
639
+ const messageRole = messageIndex >= 0 && agentMessages ? (_b = agentMessages[messageIndex]) == null ? void 0 : _b.role : void 0;
640
+ let previousUserMessageId;
641
+ if (messageIndex > 0 && agentMessages) {
642
+ for (let i = messageIndex - 1; i >= 0; i -= 1) {
643
+ if (((_c = agentMessages[i]) == null ? void 0 : _c.role) === "user") {
644
+ previousUserMessageId = (_d = agentMessages[i]) == null ? void 0 : _d.id;
645
+ break;
646
+ }
647
+ }
648
+ }
649
+ const liveStateIsStale = stateSnapshotProp === void 0 && latestSnapshot !== void 0 && agentState !== void 0 && areStatesEquals(latestSnapshot, agentState);
650
+ const shouldUseLiveState = (Boolean(allowLiveState) || !lastAssistantId || messageId === lastAssistantId) && !liveStateIsStale;
651
+ const snapshot = stateSnapshotProp ? (0, import_shared3.parseJson)(stateSnapshotProp, stateSnapshotProp) : shouldUseLiveState ? agentState : void 0;
652
+ const hasSnapshotKeys = !!(snapshot && Object.keys(snapshot).length > 0);
653
+ const allowEmptySnapshot = snapshot !== void 0 && !hasSnapshotKeys && (stateSnapshotProp !== void 0 || shouldUseLiveState);
654
+ const messageCacheEntry = caches.byMessageId[messageId];
655
+ const cachedMessageSnapshot = readCachedMessageEntry(messageCacheEntry).snapshot;
656
+ const cacheKey = stateRenderId !== void 0 ? `${stateRenderId}::${effectiveRunId}` : void 0;
657
+ let cachedSnapshot = cachedMessageSnapshot != null ? cachedMessageSnapshot : caches.byMessageId[messageId];
658
+ if (cachedSnapshot === void 0 && cacheKey && caches.byStateRenderAndRun[cacheKey] !== void 0) {
659
+ cachedSnapshot = caches.byStateRenderAndRun[cacheKey];
660
+ }
661
+ if (cachedSnapshot === void 0 && stateRenderId && previousUserMessageId && caches.byStateRenderAndRun[`${stateRenderId}::pending:${previousUserMessageId}`] !== void 0) {
662
+ cachedSnapshot = caches.byStateRenderAndRun[`${stateRenderId}::pending:${previousUserMessageId}`];
663
+ }
664
+ if (cachedSnapshot === void 0 && !skipLatestCache && stateRenderId && messageRole !== "assistant" && (stateSnapshotProp !== void 0 || agentState && Object.keys(agentState).length > 0)) {
665
+ cachedSnapshot = caches.byStateRenderAndRun[`${stateRenderId}::latest`];
666
+ }
667
+ const snapshotForClaim = (existingClaim == null ? void 0 : existingClaim.locked) ? (_e = existingClaim.stateSnapshot) != null ? _e : cachedSnapshot : hasSnapshotKeys ? snapshot : (_f = existingClaim == null ? void 0 : existingClaim.stateSnapshot) != null ? _f : cachedSnapshot;
668
+ return { snapshot, hasSnapshotKeys, cachedSnapshot, allowEmptySnapshot, snapshotForClaim };
669
+ }
670
+
671
+ // src/hooks/use-coagent-state-render-registry.ts
672
+ var import_react11 = require("react");
673
+ var LAST_SNAPSHOTS_BY_RENDER_AND_RUN = "__lastSnapshotsByStateRenderIdAndRun";
674
+ var LAST_SNAPSHOTS_BY_MESSAGE = "__lastSnapshotsByMessageId";
675
+ function getClaimsStore(claimsRef) {
676
+ return claimsRef.current;
677
+ }
678
+ function getSnapshotCaches(claimsRef) {
679
+ var _a, _b;
680
+ const store = getClaimsStore(claimsRef);
681
+ return {
682
+ byStateRenderAndRun: (_a = store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN]) != null ? _a : {},
683
+ byMessageId: (_b = store[LAST_SNAPSHOTS_BY_MESSAGE]) != null ? _b : {}
684
+ };
685
+ }
686
+ function useStateRenderRegistry({
687
+ agentId,
688
+ stateRenderId,
689
+ message,
690
+ messageIndex,
691
+ stateSnapshot,
692
+ agentState,
693
+ agentMessages,
694
+ claimsRef
695
+ }) {
696
+ var _a, _b, _c, _d, _e, _f;
697
+ const store = getClaimsStore(claimsRef);
698
+ const runId = message.runId;
699
+ const cachedMessageEntry = (_a = store[LAST_SNAPSHOTS_BY_MESSAGE]) == null ? void 0 : _a[message.id];
700
+ const { runId: cachedMessageRunId } = readCachedMessageEntry(cachedMessageEntry);
701
+ const existingClaimRunId = (_b = claimsRef.current[message.id]) == null ? void 0 : _b.runId;
702
+ const effectiveRunId = getEffectiveRunId({
703
+ existingClaimRunId,
704
+ cachedMessageRunId,
705
+ runId
706
+ });
707
+ (0, import_react11.useEffect)(() => {
708
+ return () => {
709
+ var _a2, _b2, _c2, _d2;
710
+ const existingClaim2 = claimsRef.current[message.id];
711
+ if ((existingClaim2 == null ? void 0 : existingClaim2.stateSnapshot) && Object.keys(existingClaim2.stateSnapshot).length > 0) {
712
+ const snapshotCache = __spreadValues({}, (_a2 = store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN]) != null ? _a2 : {});
713
+ const cacheKey = `${existingClaim2.stateRenderId}::${(_b2 = existingClaim2.runId) != null ? _b2 : "pending"}`;
714
+ snapshotCache[cacheKey] = existingClaim2.stateSnapshot;
715
+ snapshotCache[`${existingClaim2.stateRenderId}::latest`] = existingClaim2.stateSnapshot;
716
+ store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN] = snapshotCache;
717
+ const messageCache = __spreadValues({}, (_c2 = store[LAST_SNAPSHOTS_BY_MESSAGE]) != null ? _c2 : {});
718
+ messageCache[message.id] = {
719
+ snapshot: existingClaim2.stateSnapshot,
720
+ runId: (_d2 = existingClaim2.runId) != null ? _d2 : effectiveRunId
721
+ };
722
+ store[LAST_SNAPSHOTS_BY_MESSAGE] = messageCache;
723
+ }
724
+ delete claimsRef.current[message.id];
725
+ };
726
+ }, [claimsRef, effectiveRunId, message.id]);
727
+ if (!stateRenderId) {
728
+ return { canRender: false };
729
+ }
730
+ const caches = getSnapshotCaches(claimsRef);
731
+ const existingClaim = claimsRef.current[message.id];
732
+ const { snapshot, hasSnapshotKeys, allowEmptySnapshot, snapshotForClaim } = selectSnapshot({
733
+ messageId: message.id,
734
+ messageName: message.name,
735
+ allowLiveState: isPlaceholderMessageName(message.name) || isPlaceholderMessageId(message.id),
736
+ skipLatestCache: isPlaceholderMessageName(message.name) || isPlaceholderMessageId(message.id),
737
+ stateRenderId,
738
+ effectiveRunId,
739
+ stateSnapshotProp: stateSnapshot,
740
+ agentState,
741
+ agentMessages,
742
+ existingClaim,
743
+ caches
744
+ });
745
+ const resolution = resolveClaim({
746
+ claims: claimsRef.current,
747
+ context: {
748
+ agentId,
749
+ messageId: message.id,
750
+ stateRenderId,
751
+ runId: effectiveRunId,
752
+ messageIndex
753
+ },
754
+ stateSnapshot: snapshotForClaim
755
+ });
756
+ if (resolution.action === "block" /* Block */) {
757
+ return { canRender: false };
758
+ }
759
+ if (resolution.updateRunId && claimsRef.current[message.id]) {
760
+ claimsRef.current[message.id].runId = resolution.updateRunId;
761
+ }
762
+ if (resolution.nextClaim) {
763
+ claimsRef.current[message.id] = resolution.nextClaim;
764
+ }
765
+ if (resolution.lockOthers) {
766
+ Object.entries(claimsRef.current).forEach(([id, claim]) => {
767
+ if (id !== message.id && claim.stateRenderId === stateRenderId) {
768
+ claim.locked = true;
769
+ }
770
+ });
771
+ }
772
+ if (existingClaim && !existingClaim.locked && (agentMessages == null ? void 0 : agentMessages.length)) {
773
+ const indexInAgentMessages = agentMessages.findIndex((msg) => msg.id === message.id);
774
+ if (indexInAgentMessages >= 0 && indexInAgentMessages < agentMessages.length - 1) {
775
+ existingClaim.locked = true;
776
+ }
777
+ }
778
+ const existingSnapshot = claimsRef.current[message.id].stateSnapshot;
779
+ const snapshotChanged = stateSnapshot && existingSnapshot !== void 0 && !areStatesEquals(existingSnapshot, snapshot);
780
+ if (snapshot && (stateSnapshot || hasSnapshotKeys || allowEmptySnapshot) && (!claimsRef.current[message.id].locked || snapshotChanged)) {
781
+ if (!claimsRef.current[message.id].locked || snapshotChanged) {
782
+ claimsRef.current[message.id].stateSnapshot = snapshot;
783
+ const snapshotCache = __spreadValues({}, (_c = store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN]) != null ? _c : {});
784
+ const cacheKey = `${stateRenderId}::${effectiveRunId}`;
785
+ snapshotCache[cacheKey] = snapshot;
786
+ snapshotCache[`${stateRenderId}::latest`] = snapshot;
787
+ store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN] = snapshotCache;
788
+ const messageCache = __spreadValues({}, (_d = store[LAST_SNAPSHOTS_BY_MESSAGE]) != null ? _d : {});
789
+ messageCache[message.id] = { snapshot, runId: effectiveRunId };
790
+ store[LAST_SNAPSHOTS_BY_MESSAGE] = messageCache;
791
+ if (stateSnapshot) {
792
+ claimsRef.current[message.id].locked = true;
793
+ }
794
+ }
795
+ } else if (snapshotForClaim) {
796
+ const existingSnapshot2 = claimsRef.current[message.id].stateSnapshot;
797
+ if (!existingSnapshot2) {
798
+ claimsRef.current[message.id].stateSnapshot = snapshotForClaim;
799
+ const snapshotCache = __spreadValues({}, (_e = store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN]) != null ? _e : {});
800
+ const cacheKey = `${stateRenderId}::${effectiveRunId}`;
801
+ snapshotCache[cacheKey] = snapshotForClaim;
802
+ snapshotCache[`${stateRenderId}::latest`] = snapshotForClaim;
803
+ store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN] = snapshotCache;
804
+ const messageCache = __spreadValues({}, (_f = store[LAST_SNAPSHOTS_BY_MESSAGE]) != null ? _f : {});
805
+ messageCache[message.id] = { snapshot: snapshotForClaim, runId: effectiveRunId };
806
+ store[LAST_SNAPSHOTS_BY_MESSAGE] = messageCache;
807
+ }
808
+ }
809
+ return { canRender: true };
810
+ }
811
+
812
+ // src/hooks/use-coagent-state-render-bridge.tsx
530
813
  function useCoagentStateRenderBridge(agentId, props) {
531
814
  var _a;
532
- const { stateSnapshot, messageIndexInRun, message } = props;
815
+ const { stateSnapshot, message } = props;
533
816
  const { coAgentStateRenders, claimsRef } = useCoAgentStateRenders();
534
- const { agent } = (0, import_react11.useAgent)({ agentId });
535
- const [nodeName, setNodeName] = (0, import_react12.useState)(void 0);
536
- const [, forceUpdate] = (0, import_react12.useState)(0);
537
- const runId = (_a = props.runId) != null ? _a : message.runId;
538
- const effectiveRunId = runId || "pending";
539
- (0, import_react12.useEffect)(() => {
817
+ const { agent } = (0, import_react12.useAgent)({ agentId });
818
+ const [nodeName, setNodeName] = (0, import_react13.useState)(void 0);
819
+ const [, forceUpdate] = (0, import_react13.useState)(0);
820
+ (0, import_react13.useEffect)(() => {
540
821
  if (!agent)
541
822
  return;
542
823
  const subscriber = {
@@ -559,103 +840,69 @@ function useCoagentStateRenderBridge(agentId, props) {
559
840
  unsubscribe();
560
841
  };
561
842
  }, [agentId, nodeName]);
562
- const getStateRender = (0, import_react12.useCallback)(
843
+ const getStateRender = (0, import_react13.useCallback)(
563
844
  (messageId) => {
564
- return Object.entries(coAgentStateRenders).find(([stateRenderId, stateRender]) => {
845
+ return Object.entries(coAgentStateRenders).find(([stateRenderId2, stateRender2]) => {
565
846
  if (claimsRef.current[messageId]) {
566
- return stateRenderId === claimsRef.current[messageId].stateRenderId;
847
+ return stateRenderId2 === claimsRef.current[messageId].stateRenderId;
567
848
  }
568
- const matchingAgentName = stateRender.name === agentId;
569
- const matchesNodeContext = stateRender.nodeName ? stateRender.nodeName === nodeName : true;
849
+ const matchingAgentName = stateRender2.name === agentId;
850
+ const matchesNodeContext = stateRender2.nodeName ? stateRender2.nodeName === nodeName : true;
570
851
  return matchingAgentName && matchesNodeContext;
571
852
  });
572
853
  },
573
854
  [coAgentStateRenders, nodeName, agentId]
574
855
  );
575
- const handleRenderRequest = ({
856
+ const stateRenderEntry = (0, import_react13.useMemo)(() => getStateRender(message.id), [getStateRender, message.id]);
857
+ const stateRenderId = stateRenderEntry == null ? void 0 : stateRenderEntry[0];
858
+ const stateRender = stateRenderEntry == null ? void 0 : stateRenderEntry[1];
859
+ const registryMessage = __spreadProps(__spreadValues({}, message), {
860
+ runId: (_a = props.runId) != null ? _a : message.runId
861
+ });
862
+ const { canRender } = useStateRenderRegistry({
863
+ agentId,
576
864
  stateRenderId,
577
- messageId,
578
- runId: runId2,
579
- stateSnapshot: renderSnapshot
580
- }) => {
581
- if (claimsRef.current[messageId]) {
582
- const canRender = claimsRef.current[messageId].stateRenderId === stateRenderId;
583
- if (canRender && runId2 && (!claimsRef.current[messageId].runId || claimsRef.current[messageId].runId === "pending")) {
584
- claimsRef.current[messageId].runId = runId2;
585
- }
586
- return canRender;
587
- }
588
- const renderClaimedByOtherMessage = Object.values(claimsRef.current).find(
589
- (c) => c.stateRenderId === stateRenderId && (0, import_shared3.dataToUUID)(getStateWithoutConstantKeys(c.stateSnapshot)) === (0, import_shared3.dataToUUID)(getStateWithoutConstantKeys(renderSnapshot))
590
- );
591
- if (renderClaimedByOtherMessage) {
592
- if (renderSnapshot && renderClaimedByOtherMessage.stateSnapshot && !areStatesEquals(renderClaimedByOtherMessage.stateSnapshot, renderSnapshot)) {
593
- claimsRef.current[messageId] = { stateRenderId, runId: runId2 };
594
- return true;
595
- }
596
- return false;
597
- }
598
- if (!runId2) {
599
- return false;
600
- }
601
- claimsRef.current[messageId] = { stateRenderId, runId: runId2 };
602
- return true;
603
- };
604
- return (0, import_react12.useMemo)(() => {
605
- var _a2, _b, _c;
606
- if (messageIndexInRun !== 0) {
607
- return null;
608
- }
609
- const [stateRenderId, stateRender] = (_a2 = getStateRender(message.id)) != null ? _a2 : [];
865
+ message: registryMessage,
866
+ messageIndex: props.messageIndex,
867
+ stateSnapshot,
868
+ agentState: agent == null ? void 0 : agent.state,
869
+ agentMessages: agent == null ? void 0 : agent.messages,
870
+ claimsRef
871
+ });
872
+ return (0, import_react13.useMemo)(() => {
873
+ var _a2, _b;
610
874
  if (!stateRender || !stateRenderId) {
611
875
  return null;
612
876
  }
613
- const snapshot = stateSnapshot ? (0, import_shared3.parseJson)(stateSnapshot, stateSnapshot) : agent == null ? void 0 : agent.state;
614
- const canRender = handleRenderRequest({
615
- stateRenderId,
616
- messageId: message.id,
617
- runId: effectiveRunId,
618
- stateSnapshot: snapshot
619
- });
620
877
  if (!canRender) {
621
878
  return null;
622
879
  }
623
- if (snapshot) {
624
- const existingSnapshot = claimsRef.current[message.id].stateSnapshot;
625
- const snapshotChanged = stateSnapshot && existingSnapshot !== void 0 && !areStatesEquals(existingSnapshot, snapshot);
626
- if (!claimsRef.current[message.id].locked || snapshotChanged) {
627
- claimsRef.current[message.id].stateSnapshot = snapshot;
628
- if (stateSnapshot) {
629
- claimsRef.current[message.id].locked = true;
630
- }
631
- }
632
- }
633
880
  if (stateRender.handler) {
634
881
  stateRender.handler({
635
- state: stateSnapshot ? (0, import_shared3.parseJson)(stateSnapshot, stateSnapshot) : (_b = agent == null ? void 0 : agent.state) != null ? _b : {},
882
+ state: stateSnapshot ? (0, import_shared4.parseJson)(stateSnapshot, stateSnapshot) : (_a2 = agent == null ? void 0 : agent.state) != null ? _a2 : {},
636
883
  nodeName: nodeName != null ? nodeName : ""
637
884
  });
638
885
  }
639
886
  if (stateRender.render) {
640
- const status = (agent == null ? void 0 : agent.isRunning) ? "inProgress" : "complete";
887
+ const status = (agent == null ? void 0 : agent.isRunning) ? "inProgress" /* InProgress */ : "complete" /* Complete */;
641
888
  if (typeof stateRender.render === "string")
642
889
  return stateRender.render;
643
890
  return stateRender.render({
644
891
  status,
645
892
  // Always use state from claim, to make sure the state does not seem "wiped" for a fraction of a second
646
- state: (_c = claimsRef.current[message.id].stateSnapshot) != null ? _c : {},
893
+ state: (_b = claimsRef.current[message.id].stateSnapshot) != null ? _b : {},
647
894
  nodeName: nodeName != null ? nodeName : ""
648
895
  });
649
896
  }
650
897
  }, [
651
- getStateRender,
652
- stateSnapshot,
898
+ stateRender,
899
+ stateRenderId,
653
900
  agent == null ? void 0 : agent.state,
654
901
  agent == null ? void 0 : agent.isRunning,
655
902
  nodeName,
656
- effectiveRunId,
657
903
  message.id,
658
- messageIndexInRun
904
+ stateSnapshot,
905
+ canRender
659
906
  ]);
660
907
  }
661
908
  function CoAgentStateRenderBridge(props) {
@@ -671,13 +918,13 @@ function useCopilotChatInternal({
671
918
  onReloadMessages
672
919
  } = {}) {
673
920
  var _a, _b, _c;
674
- const { copilotkit } = (0, import_react14.useCopilotKit)();
921
+ const { copilotkit } = (0, import_react15.useCopilotKit)();
675
922
  const { threadId, agentSession } = useCopilotContext();
676
- const existingConfig = (0, import_react14.useCopilotChatConfiguration)();
677
- const [agentAvailable, setAgentAvailable] = (0, import_react13.useState)(false);
923
+ const existingConfig = (0, import_react15.useCopilotChatConfiguration)();
924
+ const [agentAvailable, setAgentAvailable] = (0, import_react14.useState)(false);
678
925
  const resolvedAgentId = (_a = existingConfig == null ? void 0 : existingConfig.agentId) != null ? _a : "default";
679
- const { agent } = (0, import_react14.useAgent)({ agentId: resolvedAgentId });
680
- (0, import_react13.useEffect)(() => {
926
+ const { agent } = (0, import_react15.useAgent)({ agentId: resolvedAgentId });
927
+ (0, import_react14.useEffect)(() => {
681
928
  const connect = (agent2) => __async(this, null, function* () {
682
929
  setAgentAvailable(false);
683
930
  try {
@@ -686,7 +933,7 @@ function useCopilotChatInternal({
686
933
  } catch (error) {
687
934
  if (error instanceof import_client.AGUIConnectNotImplementedError) {
688
935
  } else {
689
- throw error;
936
+ console.error("CopilotChat: connectAgent failed", error);
690
937
  }
691
938
  }
692
939
  });
@@ -697,7 +944,7 @@ function useCopilotChatInternal({
697
944
  return () => {
698
945
  };
699
946
  }, [existingConfig == null ? void 0 : existingConfig.threadId, agent, copilotkit, resolvedAgentId]);
700
- (0, import_react13.useEffect)(() => {
947
+ (0, import_react14.useEffect)(() => {
701
948
  onInProgress == null ? void 0 : onInProgress(Boolean(agent == null ? void 0 : agent.isRunning));
702
949
  }, [agent == null ? void 0 : agent.isRunning, onInProgress]);
703
950
  const interrupt = useLangGraphInterruptRender(agent);
@@ -705,7 +952,7 @@ function useCopilotChatInternal({
705
952
  agent == null ? void 0 : agent.setMessages([]);
706
953
  agent == null ? void 0 : agent.setState(null);
707
954
  };
708
- const deleteMessage = (0, import_react13.useCallback)(
955
+ const deleteMessage = (0, import_react14.useCallback)(
709
956
  (messageId) => {
710
957
  var _a2;
711
958
  const filteredMessages = ((_a2 = agent == null ? void 0 : agent.messages) != null ? _a2 : []).filter(
@@ -716,13 +963,13 @@ function useCopilotChatInternal({
716
963
  [agent == null ? void 0 : agent.setMessages, agent == null ? void 0 : agent.messages]
717
964
  );
718
965
  const latestDelete = useUpdatedRef(deleteMessage);
719
- const latestDeleteFunc = (0, import_react13.useCallback)(
966
+ const latestDeleteFunc = (0, import_react14.useCallback)(
720
967
  (messageId) => {
721
968
  return latestDelete.current(messageId);
722
969
  },
723
970
  [latestDelete]
724
971
  );
725
- const currentSuggestions = (0, import_react14.useSuggestions)({ agentId: resolvedAgentId });
972
+ const currentSuggestions = (0, import_react15.useSuggestions)({ agentId: resolvedAgentId });
726
973
  const reload = useAsyncCallback(
727
974
  (reloadMessageId) => __async(this, null, function* () {
728
975
  var _a2;
@@ -757,7 +1004,11 @@ function useCopilotChatInternal({
757
1004
  }
758
1005
  agent == null ? void 0 : agent.setMessages(historyCutoff);
759
1006
  if (agent) {
760
- copilotkit.runAgent({ agent });
1007
+ try {
1008
+ yield copilotkit.runAgent({ agent });
1009
+ } catch (error) {
1010
+ console.error("CopilotChat: runAgent failed during reload", error);
1011
+ }
761
1012
  }
762
1013
  return;
763
1014
  }),
@@ -797,7 +1048,7 @@ function useCopilotChatInternal({
797
1048
  }),
798
1049
  [latestSendMessageFunc]
799
1050
  );
800
- const latestSetMessagesFunc = (0, import_react13.useCallback)(
1051
+ const latestSetMessagesFunc = (0, import_react14.useCallback)(
801
1052
  (messages) => {
802
1053
  var _a2, _b2;
803
1054
  if (messages.every((message) => message instanceof import_runtime_client_gql2.Message)) {
@@ -820,7 +1071,7 @@ function useCopilotChatInternal({
820
1071
  }),
821
1072
  [latestReload, agent, onReloadMessages]
822
1073
  );
823
- const latestStopFunc = (0, import_react13.useCallback)(() => {
1074
+ const latestStopFunc = (0, import_react14.useCallback)(() => {
824
1075
  var _a2, _b2;
825
1076
  onStopGeneration == null ? void 0 : onStopGeneration({
826
1077
  currentAgentName: agent == null ? void 0 : agent.agentId,
@@ -829,11 +1080,11 @@ function useCopilotChatInternal({
829
1080
  return (_b2 = agent == null ? void 0 : agent.abortRun) == null ? void 0 : _b2.call(agent);
830
1081
  }, [onStopGeneration, agent]);
831
1082
  const latestReset = useUpdatedRef(reset);
832
- const latestResetFunc = (0, import_react13.useCallback)(() => {
1083
+ const latestResetFunc = (0, import_react14.useCallback)(() => {
833
1084
  return latestReset.current();
834
1085
  }, [latestReset]);
835
1086
  const lazyToolRendered = useLazyToolRenderer();
836
- const renderCustomMessage = (0, import_react14.useRenderCustomMessages)();
1087
+ const renderCustomMessage = (0, import_react15.useRenderCustomMessages)();
837
1088
  const legacyCustomMessageRenderer = useLegacyCoagentRenderer({
838
1089
  copilotkit,
839
1090
  agent,
@@ -841,7 +1092,8 @@ function useCopilotChatInternal({
841
1092
  threadId: (_b = existingConfig == null ? void 0 : existingConfig.threadId) != null ? _b : threadId
842
1093
  });
843
1094
  const allMessages = (_c = agent == null ? void 0 : agent.messages) != null ? _c : [];
844
- const resolvedMessages = (0, import_react13.useMemo)(() => {
1095
+ const resolvedMessages = (0, import_react14.useMemo)(() => {
1096
+ var _a2, _b2;
845
1097
  let processedMessages = allMessages.map((message) => {
846
1098
  if (message.role !== "assistant") {
847
1099
  return message;
@@ -854,31 +1106,78 @@ function useCopilotChatInternal({
854
1106
  }
855
1107
  }
856
1108
  const bridgeRenderer = legacyCustomMessageRenderer || renderCustomMessage ? () => {
857
- const customRender = renderCustomMessage == null ? void 0 : renderCustomMessage({
858
- message,
859
- position: "before"
860
- });
861
- if (customRender) {
862
- return customRender;
1109
+ var _a3;
1110
+ if (legacyCustomMessageRenderer) {
1111
+ return legacyCustomMessageRenderer({ message, position: "before" });
1112
+ }
1113
+ try {
1114
+ return (_a3 = renderCustomMessage == null ? void 0 : renderCustomMessage({ message, position: "before" })) != null ? _a3 : null;
1115
+ } catch (error) {
1116
+ console.warn(
1117
+ "[CopilotKit] renderCustomMessages failed, falling back to legacy renderer",
1118
+ error
1119
+ );
1120
+ return null;
863
1121
  }
864
- return legacyCustomMessageRenderer == null ? void 0 : legacyCustomMessageRenderer({ message, position: "before" });
865
1122
  } : null;
866
1123
  if (bridgeRenderer) {
867
- return __spreadProps(__spreadValues({}, message), { generativeUI: bridgeRenderer });
1124
+ return __spreadProps(__spreadValues({}, message), {
1125
+ generativeUI: bridgeRenderer,
1126
+ generativeUIPosition: "before"
1127
+ });
868
1128
  }
869
1129
  return message;
870
1130
  });
871
1131
  const hasAssistantMessages = processedMessages.some((msg) => msg.role === "assistant");
1132
+ const canUseCustomRenderer = Boolean(
1133
+ renderCustomMessage && ((_a2 = copilotkit == null ? void 0 : copilotkit.getAgent) == null ? void 0 : _a2.call(copilotkit, resolvedAgentId))
1134
+ );
1135
+ const placeholderRenderer = legacyCustomMessageRenderer ? legacyCustomMessageRenderer : canUseCustomRenderer ? renderCustomMessage : null;
1136
+ const shouldRenderPlaceholder = Boolean(agent == null ? void 0 : agent.isRunning) || Boolean((agent == null ? void 0 : agent.state) && Object.keys(agent.state).length);
1137
+ const effectiveThreadId = (_b2 = threadId != null ? threadId : agent == null ? void 0 : agent.threadId) != null ? _b2 : "default";
1138
+ let latestUserIndex = -1;
1139
+ for (let i = processedMessages.length - 1; i >= 0; i -= 1) {
1140
+ if (processedMessages[i].role === "user") {
1141
+ latestUserIndex = i;
1142
+ break;
1143
+ }
1144
+ }
1145
+ const latestUserMessageId = latestUserIndex >= 0 ? processedMessages[latestUserIndex].id : void 0;
1146
+ const currentRunId = latestUserMessageId ? copilotkit.getRunIdForMessage(resolvedAgentId, effectiveThreadId, latestUserMessageId) || `pending:${latestUserMessageId}` : void 0;
1147
+ const hasAssistantForCurrentRun = latestUserIndex >= 0 ? processedMessages.slice(latestUserIndex + 1).some((msg) => msg.role === "assistant") : hasAssistantMessages;
1148
+ if (placeholderRenderer && shouldRenderPlaceholder && !hasAssistantForCurrentRun) {
1149
+ const placeholderId = currentRunId ? `coagent-state-render-${resolvedAgentId}-${currentRunId}` : `coagent-state-render-${resolvedAgentId}`;
1150
+ const placeholderMessage = {
1151
+ id: placeholderId,
1152
+ role: "assistant",
1153
+ content: "",
1154
+ name: "coagent-state-render",
1155
+ runId: currentRunId
1156
+ };
1157
+ processedMessages = [
1158
+ ...processedMessages,
1159
+ __spreadProps(__spreadValues({}, placeholderMessage), {
1160
+ generativeUIPosition: "before",
1161
+ generativeUI: () => placeholderRenderer({
1162
+ message: placeholderMessage,
1163
+ position: "before"
1164
+ })
1165
+ })
1166
+ ];
1167
+ }
872
1168
  return processedMessages;
873
1169
  }, [
874
1170
  agent == null ? void 0 : agent.messages,
875
1171
  lazyToolRendered,
876
1172
  allMessages,
877
1173
  renderCustomMessage,
878
- // legacyCustomMessageRenderer,
879
- resolvedAgentId
1174
+ legacyCustomMessageRenderer,
1175
+ resolvedAgentId,
1176
+ copilotkit,
1177
+ agent == null ? void 0 : agent.isRunning,
1178
+ agent == null ? void 0 : agent.state
880
1179
  ]);
881
- const renderedSuggestions = (0, import_react13.useMemo)(() => {
1180
+ const renderedSuggestions = (0, import_react14.useMemo)(() => {
882
1181
  if (Array.isArray(suggestions)) {
883
1182
  return {
884
1183
  suggestions: suggestions.map((s) => __spreadProps(__spreadValues({}, s), { isLoading: false })),
@@ -913,8 +1212,8 @@ function useCopilotChatInternal({
913
1212
  };
914
1213
  }
915
1214
  function useUpdatedRef(value) {
916
- const ref = (0, import_react13.useRef)(value);
917
- (0, import_react13.useEffect)(() => {
1215
+ const ref = (0, import_react14.useRef)(value);
1216
+ (0, import_react14.useEffect)(() => {
918
1217
  ref.current = value;
919
1218
  }, [value]);
920
1219
  return ref;
@@ -925,14 +1224,15 @@ function useLegacyCoagentRenderer({
925
1224
  agentId,
926
1225
  threadId
927
1226
  }) {
928
- return (0, import_react13.useMemo)(() => {
1227
+ return (0, import_react14.useMemo)(() => {
929
1228
  if (!copilotkit || !agent) {
930
1229
  return null;
931
1230
  }
932
1231
  return ({ message, position }) => {
933
1232
  var _a;
934
1233
  const effectiveThreadId = (_a = threadId != null ? threadId : agent.threadId) != null ? _a : "default";
935
- const existingRunId = copilotkit.getRunIdForMessage(agentId, effectiveThreadId, message.id);
1234
+ const providedRunId = message.runId;
1235
+ const existingRunId = providedRunId ? providedRunId : copilotkit.getRunIdForMessage(agentId, effectiveThreadId, message.id);
936
1236
  const runId = existingRunId || `pending:${message.id}`;
937
1237
  const messageIndex = Math.max(
938
1238
  agent.messages.findIndex((msg) => msg.id === message.id),
@@ -948,7 +1248,7 @@ function useLegacyCoagentRenderer({
948
1248
  agentId,
949
1249
  stateSnapshot: message.state
950
1250
  };
951
- return (0, import_react13.createElement)(CoAgentStateRenderBridge, bridgeProps);
1251
+ return (0, import_react14.createElement)(CoAgentStateRenderBridge, bridgeProps);
952
1252
  };
953
1253
  }, [agent, agentId, copilotkit, threadId]);
954
1254
  }