@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
@@ -0,0 +1,358 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
8
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
+ var __spreadValues = (a, b) => {
10
+ for (var prop in b || (b = {}))
11
+ if (__hasOwnProp.call(b, prop))
12
+ __defNormalProp(a, prop, b[prop]);
13
+ if (__getOwnPropSymbols)
14
+ for (var prop of __getOwnPropSymbols(b)) {
15
+ if (__propIsEnum.call(b, prop))
16
+ __defNormalProp(a, prop, b[prop]);
17
+ }
18
+ return a;
19
+ };
20
+ var __objRest = (source, exclude) => {
21
+ var target = {};
22
+ for (var prop in source)
23
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
24
+ target[prop] = source[prop];
25
+ if (source != null && __getOwnPropSymbols)
26
+ for (var prop of __getOwnPropSymbols(source)) {
27
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
28
+ target[prop] = source[prop];
29
+ }
30
+ return target;
31
+ };
32
+ var __export = (target, all) => {
33
+ for (var name in all)
34
+ __defProp(target, name, { get: all[name], enumerable: true });
35
+ };
36
+ var __copyProps = (to, from, except, desc) => {
37
+ if (from && typeof from === "object" || typeof from === "function") {
38
+ for (let key of __getOwnPropNames(from))
39
+ if (!__hasOwnProp.call(to, key) && key !== except)
40
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
41
+ }
42
+ return to;
43
+ };
44
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
45
+
46
+ // src/hooks/use-coagent-state-render-registry.ts
47
+ var use_coagent_state_render_registry_exports = {};
48
+ __export(use_coagent_state_render_registry_exports, {
49
+ useStateRenderRegistry: () => useStateRenderRegistry
50
+ });
51
+ module.exports = __toCommonJS(use_coagent_state_render_registry_exports);
52
+ var import_react = require("react");
53
+
54
+ // src/hooks/use-coagent-state-render-bridge.helpers.ts
55
+ var import_shared = require("@copilotkit/shared");
56
+ function getStateWithoutConstantKeys(state) {
57
+ if (!state)
58
+ return {};
59
+ const _a = state, { messages, tools, copilotkit } = _a, stateWithoutConstantKeys = __objRest(_a, ["messages", "tools", "copilotkit"]);
60
+ return stateWithoutConstantKeys;
61
+ }
62
+ function areStatesEquals(a, b) {
63
+ if (a && !b || !a && b)
64
+ return false;
65
+ const _a = a, { messages, tools, copilotkit } = _a, aWithoutConstantKeys = __objRest(_a, ["messages", "tools", "copilotkit"]);
66
+ const _b = b, {
67
+ messages: bMessages,
68
+ tools: bTools,
69
+ copilotkit: bCopilotkit
70
+ } = _b, bWithoutConstantKeys = __objRest(_b, [
71
+ "messages",
72
+ "tools",
73
+ "copilotkit"
74
+ ]);
75
+ return JSON.stringify(aWithoutConstantKeys) === JSON.stringify(bWithoutConstantKeys);
76
+ }
77
+ function isPlaceholderMessageId(messageId) {
78
+ return !!messageId && messageId.startsWith("coagent-state-render-");
79
+ }
80
+ function isPlaceholderMessageName(messageName) {
81
+ return messageName === "coagent-state-render";
82
+ }
83
+ function readCachedMessageEntry(entry) {
84
+ if (!entry || typeof entry !== "object") {
85
+ return { snapshot: entry, runId: void 0 };
86
+ }
87
+ const snapshot = "snapshot" in entry ? entry.snapshot : entry;
88
+ const runId = "runId" in entry ? entry.runId : void 0;
89
+ return { snapshot, runId };
90
+ }
91
+ function getEffectiveRunId({
92
+ existingClaimRunId,
93
+ cachedMessageRunId,
94
+ runId
95
+ }) {
96
+ return existingClaimRunId || cachedMessageRunId || runId || "pending";
97
+ }
98
+ function resolveClaim({
99
+ claims,
100
+ context,
101
+ stateSnapshot
102
+ }) {
103
+ const { messageId, stateRenderId, runId, messageIndex } = context;
104
+ const existing = claims[messageId];
105
+ if (existing) {
106
+ const canRender = existing.stateRenderId === stateRenderId;
107
+ const shouldUpdateRunId = canRender && runId && (!existing.runId || existing.runId === "pending");
108
+ return {
109
+ canRender,
110
+ action: canRender ? "existing" /* Existing */ : "block" /* Block */,
111
+ updateRunId: shouldUpdateRunId ? runId : void 0
112
+ };
113
+ }
114
+ const normalizedRunId = runId != null ? runId : "pending";
115
+ const renderClaimedByOtherMessageEntry = Object.entries(claims).find(
116
+ ([, claim]) => {
117
+ var _a;
118
+ return claim.stateRenderId === stateRenderId && ((_a = claim.runId) != null ? _a : "pending") === normalizedRunId && (0, import_shared.dataToUUID)(getStateWithoutConstantKeys(claim.stateSnapshot)) === (0, import_shared.dataToUUID)(getStateWithoutConstantKeys(stateSnapshot));
119
+ }
120
+ );
121
+ const renderClaimedByOtherMessage = renderClaimedByOtherMessageEntry == null ? void 0 : renderClaimedByOtherMessageEntry[1];
122
+ const claimedMessageId = renderClaimedByOtherMessageEntry == null ? void 0 : renderClaimedByOtherMessageEntry[0];
123
+ if (renderClaimedByOtherMessage) {
124
+ if (messageIndex !== void 0 && renderClaimedByOtherMessage.messageIndex !== void 0 && messageIndex > renderClaimedByOtherMessage.messageIndex) {
125
+ return {
126
+ canRender: true,
127
+ action: "override" /* Override */,
128
+ nextClaim: { stateRenderId, runId, messageIndex },
129
+ lockOthers: runId === renderClaimedByOtherMessage.runId || isPlaceholderMessageId(claimedMessageId)
130
+ };
131
+ }
132
+ if (runId && renderClaimedByOtherMessage.runId && runId !== renderClaimedByOtherMessage.runId) {
133
+ return {
134
+ canRender: true,
135
+ action: "override" /* Override */,
136
+ nextClaim: { stateRenderId, runId, messageIndex },
137
+ lockOthers: isPlaceholderMessageId(claimedMessageId)
138
+ };
139
+ }
140
+ if (isPlaceholderMessageId(claimedMessageId)) {
141
+ return {
142
+ canRender: true,
143
+ action: "override" /* Override */,
144
+ nextClaim: { stateRenderId, runId, messageIndex },
145
+ lockOthers: true
146
+ };
147
+ }
148
+ if (stateSnapshot && renderClaimedByOtherMessage.stateSnapshot && !areStatesEquals(renderClaimedByOtherMessage.stateSnapshot, stateSnapshot)) {
149
+ return {
150
+ canRender: true,
151
+ action: "override" /* Override */,
152
+ nextClaim: { stateRenderId, runId }
153
+ };
154
+ }
155
+ return { canRender: false, action: "block" /* Block */ };
156
+ }
157
+ if (!runId) {
158
+ return { canRender: false, action: "block" /* Block */ };
159
+ }
160
+ return {
161
+ canRender: true,
162
+ action: "create" /* Create */,
163
+ nextClaim: { stateRenderId, runId, messageIndex }
164
+ };
165
+ }
166
+ function selectSnapshot({
167
+ messageId,
168
+ messageName,
169
+ allowLiveState,
170
+ skipLatestCache,
171
+ stateRenderId,
172
+ effectiveRunId,
173
+ stateSnapshotProp,
174
+ agentState,
175
+ agentMessages,
176
+ existingClaim,
177
+ caches
178
+ }) {
179
+ var _a, _b, _c, _d, _e, _f;
180
+ const lastAssistantId = agentMessages ? (_a = [...agentMessages].reverse().find((msg) => msg.role === "assistant")) == null ? void 0 : _a.id : void 0;
181
+ const latestSnapshot = stateRenderId !== void 0 ? caches.byStateRenderAndRun[`${stateRenderId}::latest`] : void 0;
182
+ const messageIndex = agentMessages ? agentMessages.findIndex((msg) => msg.id === messageId) : -1;
183
+ const messageRole = messageIndex >= 0 && agentMessages ? (_b = agentMessages[messageIndex]) == null ? void 0 : _b.role : void 0;
184
+ let previousUserMessageId;
185
+ if (messageIndex > 0 && agentMessages) {
186
+ for (let i = messageIndex - 1; i >= 0; i -= 1) {
187
+ if (((_c = agentMessages[i]) == null ? void 0 : _c.role) === "user") {
188
+ previousUserMessageId = (_d = agentMessages[i]) == null ? void 0 : _d.id;
189
+ break;
190
+ }
191
+ }
192
+ }
193
+ const liveStateIsStale = stateSnapshotProp === void 0 && latestSnapshot !== void 0 && agentState !== void 0 && areStatesEquals(latestSnapshot, agentState);
194
+ const shouldUseLiveState = (Boolean(allowLiveState) || !lastAssistantId || messageId === lastAssistantId) && !liveStateIsStale;
195
+ const snapshot = stateSnapshotProp ? (0, import_shared.parseJson)(stateSnapshotProp, stateSnapshotProp) : shouldUseLiveState ? agentState : void 0;
196
+ const hasSnapshotKeys = !!(snapshot && Object.keys(snapshot).length > 0);
197
+ const allowEmptySnapshot = snapshot !== void 0 && !hasSnapshotKeys && (stateSnapshotProp !== void 0 || shouldUseLiveState);
198
+ const messageCacheEntry = caches.byMessageId[messageId];
199
+ const cachedMessageSnapshot = readCachedMessageEntry(messageCacheEntry).snapshot;
200
+ const cacheKey = stateRenderId !== void 0 ? `${stateRenderId}::${effectiveRunId}` : void 0;
201
+ let cachedSnapshot = cachedMessageSnapshot != null ? cachedMessageSnapshot : caches.byMessageId[messageId];
202
+ if (cachedSnapshot === void 0 && cacheKey && caches.byStateRenderAndRun[cacheKey] !== void 0) {
203
+ cachedSnapshot = caches.byStateRenderAndRun[cacheKey];
204
+ }
205
+ if (cachedSnapshot === void 0 && stateRenderId && previousUserMessageId && caches.byStateRenderAndRun[`${stateRenderId}::pending:${previousUserMessageId}`] !== void 0) {
206
+ cachedSnapshot = caches.byStateRenderAndRun[`${stateRenderId}::pending:${previousUserMessageId}`];
207
+ }
208
+ if (cachedSnapshot === void 0 && !skipLatestCache && stateRenderId && messageRole !== "assistant" && (stateSnapshotProp !== void 0 || agentState && Object.keys(agentState).length > 0)) {
209
+ cachedSnapshot = caches.byStateRenderAndRun[`${stateRenderId}::latest`];
210
+ }
211
+ 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;
212
+ return { snapshot, hasSnapshotKeys, cachedSnapshot, allowEmptySnapshot, snapshotForClaim };
213
+ }
214
+
215
+ // src/hooks/use-coagent-state-render-registry.ts
216
+ var LAST_SNAPSHOTS_BY_RENDER_AND_RUN = "__lastSnapshotsByStateRenderIdAndRun";
217
+ var LAST_SNAPSHOTS_BY_MESSAGE = "__lastSnapshotsByMessageId";
218
+ function getClaimsStore(claimsRef) {
219
+ return claimsRef.current;
220
+ }
221
+ function getSnapshotCaches(claimsRef) {
222
+ var _a, _b;
223
+ const store = getClaimsStore(claimsRef);
224
+ return {
225
+ byStateRenderAndRun: (_a = store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN]) != null ? _a : {},
226
+ byMessageId: (_b = store[LAST_SNAPSHOTS_BY_MESSAGE]) != null ? _b : {}
227
+ };
228
+ }
229
+ function useStateRenderRegistry({
230
+ agentId,
231
+ stateRenderId,
232
+ message,
233
+ messageIndex,
234
+ stateSnapshot,
235
+ agentState,
236
+ agentMessages,
237
+ claimsRef
238
+ }) {
239
+ var _a, _b, _c, _d, _e, _f;
240
+ const store = getClaimsStore(claimsRef);
241
+ const runId = message.runId;
242
+ const cachedMessageEntry = (_a = store[LAST_SNAPSHOTS_BY_MESSAGE]) == null ? void 0 : _a[message.id];
243
+ const { runId: cachedMessageRunId } = readCachedMessageEntry(cachedMessageEntry);
244
+ const existingClaimRunId = (_b = claimsRef.current[message.id]) == null ? void 0 : _b.runId;
245
+ const effectiveRunId = getEffectiveRunId({
246
+ existingClaimRunId,
247
+ cachedMessageRunId,
248
+ runId
249
+ });
250
+ (0, import_react.useEffect)(() => {
251
+ return () => {
252
+ var _a2, _b2, _c2, _d2;
253
+ const existingClaim2 = claimsRef.current[message.id];
254
+ if ((existingClaim2 == null ? void 0 : existingClaim2.stateSnapshot) && Object.keys(existingClaim2.stateSnapshot).length > 0) {
255
+ const snapshotCache = __spreadValues({}, (_a2 = store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN]) != null ? _a2 : {});
256
+ const cacheKey = `${existingClaim2.stateRenderId}::${(_b2 = existingClaim2.runId) != null ? _b2 : "pending"}`;
257
+ snapshotCache[cacheKey] = existingClaim2.stateSnapshot;
258
+ snapshotCache[`${existingClaim2.stateRenderId}::latest`] = existingClaim2.stateSnapshot;
259
+ store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN] = snapshotCache;
260
+ const messageCache = __spreadValues({}, (_c2 = store[LAST_SNAPSHOTS_BY_MESSAGE]) != null ? _c2 : {});
261
+ messageCache[message.id] = {
262
+ snapshot: existingClaim2.stateSnapshot,
263
+ runId: (_d2 = existingClaim2.runId) != null ? _d2 : effectiveRunId
264
+ };
265
+ store[LAST_SNAPSHOTS_BY_MESSAGE] = messageCache;
266
+ }
267
+ delete claimsRef.current[message.id];
268
+ };
269
+ }, [claimsRef, effectiveRunId, message.id]);
270
+ if (!stateRenderId) {
271
+ return { canRender: false };
272
+ }
273
+ const caches = getSnapshotCaches(claimsRef);
274
+ const existingClaim = claimsRef.current[message.id];
275
+ const { snapshot, hasSnapshotKeys, allowEmptySnapshot, snapshotForClaim } = selectSnapshot({
276
+ messageId: message.id,
277
+ messageName: message.name,
278
+ allowLiveState: isPlaceholderMessageName(message.name) || isPlaceholderMessageId(message.id),
279
+ skipLatestCache: isPlaceholderMessageName(message.name) || isPlaceholderMessageId(message.id),
280
+ stateRenderId,
281
+ effectiveRunId,
282
+ stateSnapshotProp: stateSnapshot,
283
+ agentState,
284
+ agentMessages,
285
+ existingClaim,
286
+ caches
287
+ });
288
+ const resolution = resolveClaim({
289
+ claims: claimsRef.current,
290
+ context: {
291
+ agentId,
292
+ messageId: message.id,
293
+ stateRenderId,
294
+ runId: effectiveRunId,
295
+ messageIndex
296
+ },
297
+ stateSnapshot: snapshotForClaim
298
+ });
299
+ if (resolution.action === "block" /* Block */) {
300
+ return { canRender: false };
301
+ }
302
+ if (resolution.updateRunId && claimsRef.current[message.id]) {
303
+ claimsRef.current[message.id].runId = resolution.updateRunId;
304
+ }
305
+ if (resolution.nextClaim) {
306
+ claimsRef.current[message.id] = resolution.nextClaim;
307
+ }
308
+ if (resolution.lockOthers) {
309
+ Object.entries(claimsRef.current).forEach(([id, claim]) => {
310
+ if (id !== message.id && claim.stateRenderId === stateRenderId) {
311
+ claim.locked = true;
312
+ }
313
+ });
314
+ }
315
+ if (existingClaim && !existingClaim.locked && (agentMessages == null ? void 0 : agentMessages.length)) {
316
+ const indexInAgentMessages = agentMessages.findIndex((msg) => msg.id === message.id);
317
+ if (indexInAgentMessages >= 0 && indexInAgentMessages < agentMessages.length - 1) {
318
+ existingClaim.locked = true;
319
+ }
320
+ }
321
+ const existingSnapshot = claimsRef.current[message.id].stateSnapshot;
322
+ const snapshotChanged = stateSnapshot && existingSnapshot !== void 0 && !areStatesEquals(existingSnapshot, snapshot);
323
+ if (snapshot && (stateSnapshot || hasSnapshotKeys || allowEmptySnapshot) && (!claimsRef.current[message.id].locked || snapshotChanged)) {
324
+ if (!claimsRef.current[message.id].locked || snapshotChanged) {
325
+ claimsRef.current[message.id].stateSnapshot = snapshot;
326
+ const snapshotCache = __spreadValues({}, (_c = store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN]) != null ? _c : {});
327
+ const cacheKey = `${stateRenderId}::${effectiveRunId}`;
328
+ snapshotCache[cacheKey] = snapshot;
329
+ snapshotCache[`${stateRenderId}::latest`] = snapshot;
330
+ store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN] = snapshotCache;
331
+ const messageCache = __spreadValues({}, (_d = store[LAST_SNAPSHOTS_BY_MESSAGE]) != null ? _d : {});
332
+ messageCache[message.id] = { snapshot, runId: effectiveRunId };
333
+ store[LAST_SNAPSHOTS_BY_MESSAGE] = messageCache;
334
+ if (stateSnapshot) {
335
+ claimsRef.current[message.id].locked = true;
336
+ }
337
+ }
338
+ } else if (snapshotForClaim) {
339
+ const existingSnapshot2 = claimsRef.current[message.id].stateSnapshot;
340
+ if (!existingSnapshot2) {
341
+ claimsRef.current[message.id].stateSnapshot = snapshotForClaim;
342
+ const snapshotCache = __spreadValues({}, (_e = store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN]) != null ? _e : {});
343
+ const cacheKey = `${stateRenderId}::${effectiveRunId}`;
344
+ snapshotCache[cacheKey] = snapshotForClaim;
345
+ snapshotCache[`${stateRenderId}::latest`] = snapshotForClaim;
346
+ store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN] = snapshotCache;
347
+ const messageCache = __spreadValues({}, (_f = store[LAST_SNAPSHOTS_BY_MESSAGE]) != null ? _f : {});
348
+ messageCache[message.id] = { snapshot: snapshotForClaim, runId: effectiveRunId };
349
+ store[LAST_SNAPSHOTS_BY_MESSAGE] = messageCache;
350
+ }
351
+ }
352
+ return { canRender: true };
353
+ }
354
+ // Annotate the CommonJS export names for ESM import in node:
355
+ 0 && (module.exports = {
356
+ useStateRenderRegistry
357
+ });
358
+ //# sourceMappingURL=use-coagent-state-render-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/hooks/use-coagent-state-render-registry.ts","../../src/hooks/use-coagent-state-render-bridge.helpers.ts"],"sourcesContent":["import { useEffect } from \"react\";\nimport {\n areStatesEquals,\n ClaimAction,\n getEffectiveRunId,\n isPlaceholderMessageId,\n isPlaceholderMessageName,\n readCachedMessageEntry,\n resolveClaim,\n selectSnapshot,\n type Claim,\n type ClaimsByMessageId,\n type SnapshotCaches,\n type StateRenderContext,\n} from \"./use-coagent-state-render-bridge.helpers\";\n\nexport interface StateRenderRegistryInput {\n agentId: string;\n stateRenderId?: string;\n message: { id: string; runId?: string; name?: string };\n messageIndex?: number;\n stateSnapshot?: any;\n agentState?: any;\n agentMessages?: Array<{ id: string; role?: string }>;\n claimsRef: React.MutableRefObject<Record<string, Claim>>;\n}\n\nexport interface StateRenderRegistryResult {\n canRender: boolean;\n}\n\nconst LAST_SNAPSHOTS_BY_RENDER_AND_RUN = \"__lastSnapshotsByStateRenderIdAndRun\";\nconst LAST_SNAPSHOTS_BY_MESSAGE = \"__lastSnapshotsByMessageId\";\n\ntype SnapshotByMessageEntry = { snapshot: any; runId?: string } | any;\ntype ClaimsStore = Record<string, Claim> & {\n [LAST_SNAPSHOTS_BY_RENDER_AND_RUN]?: Record<string, any>;\n [LAST_SNAPSHOTS_BY_MESSAGE]?: Record<string, SnapshotByMessageEntry>;\n};\n\nfunction getClaimsStore(\n claimsRef: React.MutableRefObject<Record<string, Claim>>,\n): ClaimsStore {\n return claimsRef.current as ClaimsStore;\n}\n\nfunction getSnapshotCaches(claimsRef: React.MutableRefObject<Record<string, Claim>>): SnapshotCaches {\n const store = getClaimsStore(claimsRef);\n return {\n byStateRenderAndRun: store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN] ?? {},\n byMessageId: store[LAST_SNAPSHOTS_BY_MESSAGE] ?? {},\n };\n}\n\nexport function useStateRenderRegistry({\n agentId,\n stateRenderId,\n message,\n messageIndex,\n stateSnapshot,\n agentState,\n agentMessages,\n claimsRef,\n}: StateRenderRegistryInput): StateRenderRegistryResult {\n const store = getClaimsStore(claimsRef);\n const runId = message.runId;\n const cachedMessageEntry = store[LAST_SNAPSHOTS_BY_MESSAGE]?.[message.id];\n const { runId: cachedMessageRunId } = readCachedMessageEntry(cachedMessageEntry);\n const existingClaimRunId = claimsRef.current[message.id]?.runId;\n const effectiveRunId = getEffectiveRunId({\n existingClaimRunId,\n cachedMessageRunId,\n runId,\n });\n\n useEffect(() => {\n return () => {\n const existingClaim = claimsRef.current[message.id];\n if (\n existingClaim?.stateSnapshot &&\n Object.keys(existingClaim.stateSnapshot).length > 0\n ) {\n const snapshotCache = {\n ...(store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN] ?? {}),\n };\n const cacheKey = `${existingClaim.stateRenderId}::${existingClaim.runId ?? \"pending\"}`;\n snapshotCache[cacheKey] = existingClaim.stateSnapshot;\n snapshotCache[`${existingClaim.stateRenderId}::latest`] = existingClaim.stateSnapshot;\n store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN] = snapshotCache;\n\n const messageCache = {\n ...(store[LAST_SNAPSHOTS_BY_MESSAGE] ?? {}),\n };\n messageCache[message.id] = {\n snapshot: existingClaim.stateSnapshot,\n runId: existingClaim.runId ?? effectiveRunId,\n };\n store[LAST_SNAPSHOTS_BY_MESSAGE] = messageCache;\n }\n delete claimsRef.current[message.id];\n };\n }, [claimsRef, effectiveRunId, message.id]);\n\n if (!stateRenderId) {\n return { canRender: false };\n }\n\n const caches = getSnapshotCaches(claimsRef);\n const existingClaim = claimsRef.current[message.id] as Claim | undefined;\n\n const { snapshot, hasSnapshotKeys, allowEmptySnapshot, snapshotForClaim } = selectSnapshot({\n messageId: message.id,\n messageName: message.name,\n allowLiveState:\n isPlaceholderMessageName(message.name) || isPlaceholderMessageId(message.id),\n skipLatestCache:\n isPlaceholderMessageName(message.name) || isPlaceholderMessageId(message.id),\n stateRenderId,\n effectiveRunId,\n stateSnapshotProp: stateSnapshot,\n agentState,\n agentMessages,\n existingClaim,\n caches,\n });\n\n const resolution = resolveClaim({\n claims: claimsRef.current as ClaimsByMessageId,\n context: {\n agentId,\n messageId: message.id,\n stateRenderId,\n runId: effectiveRunId,\n messageIndex,\n } satisfies StateRenderContext,\n stateSnapshot: snapshotForClaim,\n });\n\n if (resolution.action === ClaimAction.Block) {\n return { canRender: false };\n }\n\n if (resolution.updateRunId && claimsRef.current[message.id]) {\n claimsRef.current[message.id].runId = resolution.updateRunId;\n }\n\n if (resolution.nextClaim) {\n claimsRef.current[message.id] = resolution.nextClaim;\n }\n\n if (resolution.lockOthers) {\n Object.entries(claimsRef.current).forEach(([id, claim]) => {\n if (id !== message.id && claim.stateRenderId === stateRenderId) {\n claim.locked = true;\n }\n });\n }\n\n if (existingClaim && !existingClaim.locked && agentMessages?.length) {\n const indexInAgentMessages = agentMessages.findIndex((msg: any) => msg.id === message.id);\n if (indexInAgentMessages >= 0 && indexInAgentMessages < agentMessages.length - 1) {\n existingClaim.locked = true;\n }\n }\n\n const existingSnapshot = claimsRef.current[message.id].stateSnapshot;\n const snapshotChanged =\n stateSnapshot &&\n existingSnapshot !== undefined &&\n !areStatesEquals(existingSnapshot, snapshot);\n\n if (\n snapshot &&\n (stateSnapshot || hasSnapshotKeys || allowEmptySnapshot) &&\n (!claimsRef.current[message.id].locked || snapshotChanged)\n ) {\n if (!claimsRef.current[message.id].locked || snapshotChanged) {\n claimsRef.current[message.id].stateSnapshot = snapshot;\n const snapshotCache = {\n ...(store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN] ?? {}),\n };\n const cacheKey = `${stateRenderId}::${effectiveRunId}`;\n snapshotCache[cacheKey] = snapshot;\n snapshotCache[`${stateRenderId}::latest`] = snapshot;\n store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN] = snapshotCache;\n const messageCache = {\n ...(store[LAST_SNAPSHOTS_BY_MESSAGE] ?? {}),\n };\n messageCache[message.id] = { snapshot, runId: effectiveRunId };\n store[LAST_SNAPSHOTS_BY_MESSAGE] = messageCache;\n if (stateSnapshot) {\n claimsRef.current[message.id].locked = true;\n }\n }\n } else if (snapshotForClaim) {\n const existingSnapshot = claimsRef.current[message.id].stateSnapshot;\n if (!existingSnapshot) {\n claimsRef.current[message.id].stateSnapshot = snapshotForClaim;\n const snapshotCache = {\n ...(store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN] ?? {}),\n };\n const cacheKey = `${stateRenderId}::${effectiveRunId}`;\n snapshotCache[cacheKey] = snapshotForClaim;\n snapshotCache[`${stateRenderId}::latest`] = snapshotForClaim;\n store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN] = snapshotCache;\n const messageCache = {\n ...(store[LAST_SNAPSHOTS_BY_MESSAGE] ?? {}),\n };\n messageCache[message.id] = { snapshot: snapshotForClaim, runId: effectiveRunId };\n store[LAST_SNAPSHOTS_BY_MESSAGE] = messageCache;\n }\n }\n\n return { canRender: true };\n}\n","import { dataToUUID, parseJson } from \"@copilotkit/shared\";\n\nexport enum RenderStatus {\n InProgress = \"inProgress\",\n Complete = \"complete\",\n}\n\nexport enum ClaimAction {\n Create = \"create\",\n Override = \"override\",\n Existing = \"existing\",\n Block = \"block\",\n}\n\nexport interface StateRenderContext {\n agentId: string;\n stateRenderId: string;\n messageId: string;\n runId: string;\n messageIndex?: number;\n}\n\nexport interface Claim {\n stateRenderId: string;\n runId?: string;\n stateSnapshot?: any;\n locked?: boolean;\n messageIndex?: number;\n}\n\nexport type ClaimsByMessageId = Record<string, Claim>;\n\nexport interface ClaimResolution {\n canRender: boolean;\n action: ClaimAction;\n nextClaim?: Claim;\n lockOthers?: boolean;\n updateRunId?: string;\n}\n\nexport interface SnapshotCaches {\n byStateRenderAndRun: Record<string, any>;\n byMessageId: Record<string, any>;\n}\n\nexport interface SnapshotSelectionInput {\n messageId: string;\n messageName?: string;\n allowLiveState?: boolean;\n skipLatestCache?: boolean;\n stateRenderId?: string;\n effectiveRunId: string;\n stateSnapshotProp?: any;\n agentState?: any;\n agentMessages?: Array<{ id: string; role?: string }>;\n existingClaim?: Claim;\n caches: SnapshotCaches;\n}\n\nexport interface SnapshotSelectionResult {\n snapshot?: any;\n hasSnapshotKeys: boolean;\n cachedSnapshot?: any;\n allowEmptySnapshot?: boolean;\n snapshotForClaim?: any;\n}\n\nfunction getStateWithoutConstantKeys(state: any) {\n if (!state) return {};\n const { messages, tools, copilotkit, ...stateWithoutConstantKeys } = state;\n return stateWithoutConstantKeys;\n}\n\n// Function that compares states, without the constant keys\nexport function areStatesEquals(a: any, b: any) {\n if ((a && !b) || (!a && b)) return false;\n const { messages, tools, copilotkit, ...aWithoutConstantKeys } = a;\n const {\n messages: bMessages,\n tools: bTools,\n copilotkit: bCopilotkit,\n ...bWithoutConstantKeys\n } = b;\n\n return JSON.stringify(aWithoutConstantKeys) === JSON.stringify(bWithoutConstantKeys);\n}\n\nexport function isPlaceholderMessageId(messageId: string | undefined) {\n return !!messageId && messageId.startsWith(\"coagent-state-render-\");\n}\n\nexport function isPlaceholderMessageName(messageName: string | undefined) {\n return messageName === \"coagent-state-render\";\n}\n\nexport function readCachedMessageEntry(entry: any): { snapshot?: any; runId?: string } {\n if (!entry || typeof entry !== \"object\") {\n return { snapshot: entry, runId: undefined };\n }\n const snapshot = \"snapshot\" in entry ? entry.snapshot : entry;\n const runId = \"runId\" in entry ? entry.runId : undefined;\n return { snapshot, runId };\n}\n\nexport function getEffectiveRunId({\n existingClaimRunId,\n cachedMessageRunId,\n runId,\n}: {\n existingClaimRunId?: string;\n cachedMessageRunId?: string;\n runId?: string;\n}) {\n return existingClaimRunId || cachedMessageRunId || runId || \"pending\";\n}\n\n/**\n * Resolve whether a message can claim a render slot.\n * This is a pure decision function; the caller applies claim mutations.\n */\nexport function resolveClaim({\n claims,\n context,\n stateSnapshot,\n}: {\n claims: ClaimsByMessageId;\n context: StateRenderContext;\n stateSnapshot?: any;\n}): ClaimResolution {\n const { messageId, stateRenderId, runId, messageIndex } = context;\n const existing = claims[messageId];\n\n if (existing) {\n const canRender = existing.stateRenderId === stateRenderId;\n const shouldUpdateRunId =\n canRender && runId && (!existing.runId || existing.runId === \"pending\");\n return {\n canRender,\n action: canRender ? ClaimAction.Existing : ClaimAction.Block,\n updateRunId: shouldUpdateRunId ? runId : undefined,\n };\n }\n\n const normalizedRunId = runId ?? \"pending\";\n const renderClaimedByOtherMessageEntry = Object.entries(claims).find(\n ([, claim]) =>\n claim.stateRenderId === stateRenderId &&\n (claim.runId ?? \"pending\") === normalizedRunId &&\n dataToUUID(getStateWithoutConstantKeys(claim.stateSnapshot)) ===\n dataToUUID(getStateWithoutConstantKeys(stateSnapshot)),\n );\n\n const renderClaimedByOtherMessage = renderClaimedByOtherMessageEntry?.[1];\n const claimedMessageId = renderClaimedByOtherMessageEntry?.[0];\n\n if (renderClaimedByOtherMessage) {\n if (\n messageIndex !== undefined &&\n renderClaimedByOtherMessage.messageIndex !== undefined &&\n messageIndex > renderClaimedByOtherMessage.messageIndex\n ) {\n return {\n canRender: true,\n action: ClaimAction.Override,\n nextClaim: { stateRenderId, runId, messageIndex },\n lockOthers:\n runId === renderClaimedByOtherMessage.runId || isPlaceholderMessageId(claimedMessageId),\n };\n }\n\n if (runId && renderClaimedByOtherMessage.runId && runId !== renderClaimedByOtherMessage.runId) {\n return {\n canRender: true,\n action: ClaimAction.Override,\n nextClaim: { stateRenderId, runId, messageIndex },\n lockOthers: isPlaceholderMessageId(claimedMessageId),\n };\n }\n\n if (isPlaceholderMessageId(claimedMessageId)) {\n return {\n canRender: true,\n action: ClaimAction.Override,\n nextClaim: { stateRenderId, runId, messageIndex },\n lockOthers: true,\n };\n }\n\n if (\n stateSnapshot &&\n renderClaimedByOtherMessage.stateSnapshot &&\n !areStatesEquals(renderClaimedByOtherMessage.stateSnapshot, stateSnapshot)\n ) {\n return {\n canRender: true,\n action: ClaimAction.Override,\n nextClaim: { stateRenderId, runId },\n };\n }\n\n return { canRender: false, action: ClaimAction.Block };\n }\n\n if (!runId) {\n return { canRender: false, action: ClaimAction.Block };\n }\n\n return {\n canRender: true,\n action: ClaimAction.Create,\n nextClaim: { stateRenderId, runId, messageIndex },\n };\n}\n\n/**\n * Select the best snapshot to render for this message.\n * Priority order is:\n * 1) explicit message snapshot\n * 2) live agent state (latest assistant only)\n * 3) cached snapshot for message\n * 4) cached snapshot for stateRenderId+runId\n * 5) last cached snapshot for stateRenderId\n */\nexport function selectSnapshot({\n messageId,\n messageName,\n allowLiveState,\n skipLatestCache,\n stateRenderId,\n effectiveRunId,\n stateSnapshotProp,\n agentState,\n agentMessages,\n existingClaim,\n caches,\n}: SnapshotSelectionInput): SnapshotSelectionResult {\n const lastAssistantId = agentMessages\n ? [...agentMessages].reverse().find((msg) => msg.role === \"assistant\")?.id\n : undefined;\n const latestSnapshot =\n stateRenderId !== undefined ? caches.byStateRenderAndRun[`${stateRenderId}::latest`] : undefined;\n const messageIndex = agentMessages\n ? agentMessages.findIndex((msg) => msg.id === messageId)\n : -1;\n const messageRole =\n messageIndex >= 0 && agentMessages ? agentMessages[messageIndex]?.role : undefined;\n let previousUserMessageId: string | undefined;\n if (messageIndex > 0 && agentMessages) {\n for (let i = messageIndex - 1; i >= 0; i -= 1) {\n if (agentMessages[i]?.role === \"user\") {\n previousUserMessageId = agentMessages[i]?.id;\n break;\n }\n }\n }\n const liveStateIsStale =\n stateSnapshotProp === undefined &&\n latestSnapshot !== undefined &&\n agentState !== undefined &&\n areStatesEquals(latestSnapshot, agentState);\n const shouldUseLiveState =\n (Boolean(allowLiveState) || !lastAssistantId || messageId === lastAssistantId) &&\n !liveStateIsStale;\n const snapshot = stateSnapshotProp\n ? parseJson(stateSnapshotProp, stateSnapshotProp)\n : shouldUseLiveState\n ? agentState\n : undefined;\n const hasSnapshotKeys = !!(snapshot && Object.keys(snapshot).length > 0);\n const allowEmptySnapshot =\n snapshot !== undefined &&\n !hasSnapshotKeys &&\n (stateSnapshotProp !== undefined || shouldUseLiveState);\n\n const messageCacheEntry = caches.byMessageId[messageId];\n const cachedMessageSnapshot = readCachedMessageEntry(messageCacheEntry).snapshot;\n const cacheKey =\n stateRenderId !== undefined ? `${stateRenderId}::${effectiveRunId}` : undefined;\n let cachedSnapshot = cachedMessageSnapshot ?? caches.byMessageId[messageId];\n if (cachedSnapshot === undefined && cacheKey && caches.byStateRenderAndRun[cacheKey] !== undefined) {\n cachedSnapshot = caches.byStateRenderAndRun[cacheKey];\n }\n if (\n cachedSnapshot === undefined &&\n stateRenderId &&\n previousUserMessageId &&\n caches.byStateRenderAndRun[`${stateRenderId}::pending:${previousUserMessageId}`] !==\n undefined\n ) {\n cachedSnapshot =\n caches.byStateRenderAndRun[`${stateRenderId}::pending:${previousUserMessageId}`];\n }\n if (\n cachedSnapshot === undefined &&\n !skipLatestCache &&\n stateRenderId &&\n messageRole !== \"assistant\" &&\n (stateSnapshotProp !== undefined ||\n (agentState && Object.keys(agentState).length > 0))\n ) {\n cachedSnapshot = caches.byStateRenderAndRun[`${stateRenderId}::latest`];\n }\n\n const snapshotForClaim = existingClaim?.locked\n ? existingClaim.stateSnapshot ?? cachedSnapshot\n : hasSnapshotKeys\n ? snapshot\n : existingClaim?.stateSnapshot ?? cachedSnapshot;\n\n return { snapshot, hasSnapshotKeys, cachedSnapshot, allowEmptySnapshot, snapshotForClaim };\n}\n"],"mappings":"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","names":["_a","_b","_c","_d","existingClaim","existingSnapshot"]}
@@ -0,0 +1,9 @@
1
+ import {
2
+ useStateRenderRegistry
3
+ } from "../chunk-77IVITG3.mjs";
4
+ import "../chunk-C3YJYDK4.mjs";
5
+ import "../chunk-SKC7AJIV.mjs";
6
+ export {
7
+ useStateRenderRegistry
8
+ };
9
+ //# sourceMappingURL=use-coagent-state-render-registry.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/hooks/use-coagent-state-render.ts","../../src/context/copilot-context.tsx","../../src/components/toast/toast-provider.tsx","../../src/context/coagent-state-renders-context.tsx"],"sourcesContent":["/**\n * The useCoAgentStateRender hook allows you to render UI or text based components on a Agentic Copilot's state in the chat.\n * This is particularly useful for showing intermediate state or progress during Agentic Copilot operations.\n *\n * ## Usage\n *\n * ### Simple Usage\n *\n * ```tsx\n * import { useCoAgentStateRender } from \"@copilotkit/react-core\";\n *\n * type YourAgentState = {\n * agent_state_property: string;\n * }\n *\n * useCoAgentStateRender<YourAgentState>({\n * name: \"basic_agent\",\n * nodeName: \"optionally_specify_a_specific_node\",\n * render: ({ status, state, nodeName }) => {\n * return (\n * <YourComponent\n * agentStateProperty={state.agent_state_property}\n * status={status}\n * nodeName={nodeName}\n * />\n * );\n * },\n * });\n * ```\n *\n * This allows for you to render UI components or text based on what is happening within the agent.\n *\n * ### Example\n * A great example of this is in our Perplexity Clone where we render the progress of an agent's internet search as it is happening.\n * You can play around with it below or learn how to build it with its [demo](/coagents/videos/perplexity-clone).\n *\n * <Callout type=\"info\">\n * This example is hosted on Vercel and may take a few seconds to load.\n * </Callout>\n *\n * <iframe src=\"https://examples-coagents-ai-researcher-ui.vercel.app/\" className=\"w-full rounded-lg border h-[700px] my-4\" />\n */\n\nimport { useRef, useContext, useEffect } from \"react\";\nimport { CopilotContext } from \"../context/copilot-context\";\nimport { randomId, CopilotKitAgentDiscoveryError } from \"@copilotkit/shared\";\nimport { CoAgentStateRender } from \"../types/coagent-action\";\nimport { useToast } from \"../components/toast/toast-provider\";\nimport { useCoAgentStateRenders } from \"../context/coagent-state-renders-context\";\n\n/**\n * This hook is used to render agent state with custom UI components or text. This is particularly\n * useful for showing intermediate state or progress during Agentic Copilot operations.\n * To get started using rendering intermediate state through this hook, checkout the documentation.\n *\n * https://docs.copilotkit.ai/coagents/shared-state/predictive-state-updates\n */\n\n// We implement useCoAgentStateRender dependency handling so that\n// the developer has the option to not provide any dependencies.\n// see useCopilotAction for more details about this approach.\nexport function useCoAgentStateRender<T = any>(\n action: CoAgentStateRender<T>,\n dependencies?: any[],\n): void {\n const { chatComponentsCache, availableAgents } = useContext(CopilotContext);\n const { setCoAgentStateRender, removeCoAgentStateRender, coAgentStateRenders } =\n useCoAgentStateRenders();\n const idRef = useRef<string>(randomId());\n const { setBannerError, addToast } = useToast();\n\n useEffect(() => {\n if (availableAgents?.length && !availableAgents.some((a) => a.name === action.name)) {\n const message = `(useCoAgentStateRender): Agent \"${action.name}\" not found. Make sure the agent exists and is properly configured.`;\n\n // Route to banner instead of toast for consistency\n const agentError = new CopilotKitAgentDiscoveryError({\n agentName: action.name,\n availableAgents: availableAgents.map((a) => ({ name: a.name, id: a.id })),\n });\n setBannerError(agentError);\n }\n }, [availableAgents]);\n\n const key = `${action.name}-${action.nodeName || \"global\"}`;\n\n if (dependencies === undefined) {\n if (coAgentStateRenders[idRef.current]) {\n coAgentStateRenders[idRef.current].handler = action.handler as any;\n if (typeof action.render === \"function\") {\n if (chatComponentsCache.current !== null) {\n chatComponentsCache.current.coAgentStateRenders[key] = action.render;\n }\n }\n }\n }\n\n useEffect(() => {\n // Check for duplicates by comparing against all other actions\n const currentId = idRef.current;\n const hasDuplicate = Object.entries(coAgentStateRenders).some(([id, otherAction]) => {\n // Skip comparing with self\n if (id === currentId) return false;\n\n // Different agent names are never duplicates\n if (otherAction.name !== action.name) return false;\n\n // Same agent names:\n const hasNodeName = !!action.nodeName;\n const hasOtherNodeName = !!otherAction.nodeName;\n\n // If neither has nodeName, they're duplicates\n if (!hasNodeName && !hasOtherNodeName) return true;\n\n // If one has nodeName and other doesn't, they're not duplicates\n if (hasNodeName !== hasOtherNodeName) return false;\n\n // If both have nodeName, they're duplicates only if the names match\n return action.nodeName === otherAction.nodeName;\n });\n\n if (hasDuplicate) {\n const message = action.nodeName\n ? `Found multiple state renders for agent ${action.name} and node ${action.nodeName}. State renders might get overridden`\n : `Found multiple state renders for agent ${action.name}. State renders might get overridden`;\n\n addToast({\n type: \"warning\",\n message,\n id: `dup-action-${action.name}`,\n });\n }\n }, [coAgentStateRenders]);\n\n useEffect(() => {\n setCoAgentStateRender(idRef.current, action as any);\n if (chatComponentsCache.current !== null && action.render !== undefined) {\n chatComponentsCache.current.coAgentStateRenders[key] = action.render;\n }\n return () => {\n removeCoAgentStateRender(idRef.current);\n };\n }, [\n setCoAgentStateRender,\n removeCoAgentStateRender,\n action.name,\n // include render only if it's a string\n typeof action.render === \"string\" ? action.render : undefined,\n // dependencies set by the developer\n ...(dependencies || []),\n ]);\n}\n","import {\n CopilotCloudConfig,\n FunctionCallHandler,\n CopilotErrorHandler,\n CopilotKitError,\n} from \"@copilotkit/shared\";\nimport {\n ActionRenderProps,\n CatchAllActionRenderProps,\n FrontendAction,\n} from \"../types/frontend-action\";\nimport React from \"react\";\nimport { TreeNodeId, Tree } from \"../hooks/use-tree\";\nimport { DocumentPointer } from \"../types\";\nimport { CopilotChatSuggestionConfiguration } from \"../types/chat-suggestion-configuration\";\nimport { CoAgentStateRender, CoAgentStateRenderProps } from \"../types/coagent-action\";\nimport { CoagentState } from \"../types/coagent-state\";\nimport {\n CopilotRuntimeClient,\n ExtensionsInput,\n ForwardedParametersInput,\n} from \"@copilotkit/runtime-client-gql\";\nimport { Agent } from \"@copilotkit/runtime-client-gql\";\nimport {\n LangGraphInterruptRender,\n LangGraphInterruptActionSetter,\n QueuedInterruptEvent,\n} from \"../types/interrupt-action\";\n\n/**\n * Interface for the configuration of the Copilot API.\n */\nexport interface CopilotApiConfig {\n /**\n * The public API key for Copilot Cloud.\n */\n publicApiKey?: string;\n\n /**\n * The configuration for Copilot Cloud.\n */\n cloud?: CopilotCloudConfig;\n\n /**\n * The endpoint for the chat API.\n */\n chatApiEndpoint: string;\n\n /**\n * The endpoint for the Copilot transcribe audio service.\n */\n transcribeAudioUrl?: string;\n\n /**\n * The endpoint for the Copilot text to speech service.\n */\n textToSpeechUrl?: string;\n\n /**\n * additional headers to be sent with the request\n * @default {}\n * @example\n * ```\n * {\n * 'Authorization': 'Bearer your_token_here'\n * }\n * ```\n */\n headers: Record<string, string>;\n\n /**\n * Custom properties to be sent with the request\n * @default {}\n * @example\n * ```\n * {\n * 'user_id': 'user_id'\n * }\n * ```\n */\n properties?: Record<string, any>;\n\n /**\n * Indicates whether the user agent should send or receive cookies from the other domain\n * in the case of cross-origin requests.\n */\n credentials?: RequestCredentials;\n\n /**\n * Optional configuration for connecting to Model Context Protocol (MCP) servers.\n * This is typically derived from the CopilotKitProps and used internally.\n * @experimental\n */\n mcpServers?: Array<{ endpoint: string; apiKey?: string }>;\n}\n\nexport type InChatRenderFunction<TProps = ActionRenderProps<any> | CatchAllActionRenderProps<any>> =\n (props: TProps) => string | React.JSX.Element;\nexport type CoagentInChatRenderFunction = (\n props: CoAgentStateRenderProps<any>,\n) => string | React.JSX.Element | undefined | null;\n\nexport interface ChatComponentsCache {\n actions: Record<string, InChatRenderFunction | string>;\n coAgentStateRenders: Record<string, CoagentInChatRenderFunction | string>;\n}\n\nexport interface AgentSession {\n agentName: string;\n threadId?: string;\n nodeName?: string;\n}\n\nexport interface AuthState {\n status: \"authenticated\" | \"unauthenticated\";\n authHeaders: Record<string, string>;\n userId?: string;\n metadata?: Record<string, any>;\n}\n\nexport type ActionName = string;\nexport type ContextTree = Tree;\n\nexport interface CopilotContextParams {\n // function-calling\n actions: Record<string, FrontendAction<any>>;\n setAction: (id: string, action: FrontendAction<any>) => void;\n removeAction: (id: string) => void;\n\n // registered actions for component-based rendering\n setRegisteredActions: (actionConfig: any) => string;\n removeRegisteredAction: (actionKey: string) => void;\n\n chatComponentsCache: React.RefObject<ChatComponentsCache>;\n\n getFunctionCallHandler: (\n customEntryPoints?: Record<string, FrontendAction<any>>,\n ) => FunctionCallHandler;\n\n // text context\n addContext: (context: string, parentId?: string, categories?: string[]) => TreeNodeId;\n removeContext: (id: TreeNodeId) => void;\n getAllContext: () => Tree;\n getContextString: (documents: DocumentPointer[], categories: string[]) => string;\n\n // document context\n addDocumentContext: (documentPointer: DocumentPointer, categories?: string[]) => TreeNodeId;\n removeDocumentContext: (documentId: string) => void;\n getDocumentsContext: (categories: string[]) => DocumentPointer[];\n\n isLoading: boolean;\n setIsLoading: React.Dispatch<React.SetStateAction<boolean>>;\n\n chatSuggestionConfiguration: { [key: string]: CopilotChatSuggestionConfiguration };\n addChatSuggestionConfiguration: (\n id: string,\n suggestion: CopilotChatSuggestionConfiguration,\n ) => void;\n removeChatSuggestionConfiguration: (id: string) => void;\n\n chatInstructions: string;\n setChatInstructions: React.Dispatch<React.SetStateAction<string>>;\n\n additionalInstructions?: string[];\n setAdditionalInstructions: React.Dispatch<React.SetStateAction<string[]>>;\n\n // api endpoints\n copilotApiConfig: CopilotApiConfig;\n\n showDevConsole: boolean;\n\n // agents\n coagentStates: Record<string, CoagentState>;\n setCoagentStates: React.Dispatch<React.SetStateAction<Record<string, CoagentState>>>;\n coagentStatesRef: React.RefObject<Record<string, CoagentState>>;\n setCoagentStatesWithRef: (\n value:\n | Record<string, CoagentState>\n | ((prev: Record<string, CoagentState>) => Record<string, CoagentState>),\n ) => void;\n\n agentSession: AgentSession | null;\n setAgentSession: React.Dispatch<React.SetStateAction<AgentSession | null>>;\n\n agentLock: string | null;\n\n threadId: string;\n setThreadId: React.Dispatch<React.SetStateAction<string>>;\n\n runId: string | null;\n setRunId: React.Dispatch<React.SetStateAction<string | null>>;\n\n // The chat abort controller can be used to stop generation globally,\n // i.e. when using `stop()` from `useChat`\n chatAbortControllerRef: React.MutableRefObject<AbortController | null>;\n\n /**\n * The forwarded parameters to use for the task.\n */\n forwardedParameters?: Partial<Pick<ForwardedParametersInput, \"temperature\">>;\n availableAgents: Agent[];\n\n /**\n * The auth states for the CopilotKit.\n */\n authStates_c?: Record<ActionName, AuthState>;\n setAuthStates_c?: React.Dispatch<React.SetStateAction<Record<ActionName, AuthState>>>;\n\n /**\n * The auth config for the CopilotKit.\n */\n authConfig_c?: {\n SignInComponent: React.ComponentType<{\n onSignInComplete: (authState: AuthState) => void;\n }>;\n };\n\n extensions: ExtensionsInput;\n setExtensions: React.Dispatch<React.SetStateAction<ExtensionsInput>>;\n interruptActions: Record<string, LangGraphInterruptRender>;\n setInterruptAction: LangGraphInterruptActionSetter;\n removeInterruptAction: (actionId: string) => void;\n interruptEventQueue: Record<string, QueuedInterruptEvent[]>;\n addInterruptEvent: (queuedEvent: QueuedInterruptEvent) => void;\n resolveInterruptEvent: (threadId: string, eventId: string, response: string) => void;\n\n /**\n * Optional trace handler for comprehensive debugging and observability.\n */\n onError: CopilotErrorHandler;\n\n // banner error state\n bannerError: CopilotKitError | null;\n setBannerError: React.Dispatch<React.SetStateAction<CopilotKitError | null>>;\n // Internal error handlers\n // These are used to handle errors that occur during the execution of the chat.\n // They are not intended for use by the developer. A component can register itself an error listener to be activated somewhere else as needed\n internalErrorHandlers: Record<string, CopilotErrorHandler>;\n setInternalErrorHandler: (handler: Record<string, CopilotErrorHandler>) => void;\n removeInternalErrorHandler: (id: string) => void;\n}\n\nconst emptyCopilotContext: CopilotContextParams = {\n actions: {},\n setAction: () => {},\n removeAction: () => {},\n\n setRegisteredActions: () => \"\",\n removeRegisteredAction: () => {},\n\n chatComponentsCache: { current: { actions: {}, coAgentStateRenders: {} } },\n getContextString: (documents: DocumentPointer[], categories: string[]) =>\n returnAndThrowInDebug(\"\"),\n addContext: () => \"\",\n removeContext: () => {},\n getAllContext: () => [],\n\n getFunctionCallHandler: () => returnAndThrowInDebug(async () => {}),\n\n isLoading: false,\n setIsLoading: () => returnAndThrowInDebug(false),\n\n chatInstructions: \"\",\n setChatInstructions: () => returnAndThrowInDebug(\"\"),\n\n additionalInstructions: [],\n setAdditionalInstructions: () => returnAndThrowInDebug([]),\n\n getDocumentsContext: (categories: string[]) => returnAndThrowInDebug([]),\n addDocumentContext: () => returnAndThrowInDebug(\"\"),\n removeDocumentContext: () => {},\n\n copilotApiConfig: new (class implements CopilotApiConfig {\n get chatApiEndpoint(): string {\n throw new Error(\"Remember to wrap your app in a `<CopilotKit> {...} </CopilotKit>` !!!\");\n }\n\n get headers(): Record<string, string> {\n return {};\n }\n get body(): Record<string, any> {\n return {};\n }\n })(),\n\n chatSuggestionConfiguration: {},\n addChatSuggestionConfiguration: () => {},\n removeChatSuggestionConfiguration: () => {},\n showDevConsole: false,\n coagentStates: {},\n setCoagentStates: () => {},\n coagentStatesRef: { current: {} },\n setCoagentStatesWithRef: () => {},\n agentSession: null,\n setAgentSession: () => {},\n forwardedParameters: {},\n agentLock: null,\n threadId: \"\",\n setThreadId: () => {},\n runId: null,\n setRunId: () => {},\n chatAbortControllerRef: { current: null },\n availableAgents: [],\n extensions: {},\n setExtensions: () => {},\n interruptActions: {},\n setInterruptAction: () => {},\n removeInterruptAction: () => {},\n interruptEventQueue: {},\n addInterruptEvent: () => {},\n resolveInterruptEvent: () => {},\n onError: () => {},\n bannerError: null,\n setBannerError: () => {},\n internalErrorHandlers: {},\n setInternalErrorHandler: () => {},\n removeInternalErrorHandler: () => {},\n};\n\nexport const CopilotContext = React.createContext<CopilotContextParams>(emptyCopilotContext);\n\nexport function useCopilotContext(): CopilotContextParams {\n const context = React.useContext(CopilotContext);\n if (context === emptyCopilotContext) {\n throw new Error(\"Remember to wrap your app in a `<CopilotKit> {...} </CopilotKit>` !!!\");\n }\n return context;\n}\n\nfunction returnAndThrowInDebug<T>(_value: T): T {\n throw new Error(\"Remember to wrap your app in a `<CopilotKit> {...} </CopilotKit>` !!!\");\n}\n","import { GraphQLError } from \"@copilotkit/runtime-client-gql\";\nimport React, { createContext, useContext, useState, useCallback } from \"react\";\nimport { PartialBy, CopilotKitError, Severity } from \"@copilotkit/shared\";\n\ninterface Toast {\n id: string;\n message: string | React.ReactNode;\n type: \"info\" | \"success\" | \"warning\" | \"error\";\n duration?: number;\n}\n\ninterface ToastContextValue {\n toasts: Toast[];\n addToast: (toast: PartialBy<Toast, \"id\">) => void;\n addGraphQLErrorsToast: (errors: GraphQLError[]) => void;\n removeToast: (id: string) => void;\n enabled: boolean;\n // Banner management\n bannerError: CopilotKitError | null;\n setBannerError: (error: CopilotKitError | null) => void;\n}\n\nconst ToastContext = createContext<ToastContextValue | undefined>(undefined);\n\n// Helper functions for error banner styling\ntype ErrorSeverity = \"critical\" | \"warning\" | \"info\";\n\ninterface ErrorColors {\n background: string;\n border: string;\n text: string;\n icon: string;\n}\n\nfunction getErrorSeverity(error: CopilotKitError): ErrorSeverity {\n // Use structured error severity if available\n if (error.severity) {\n switch (error.severity) {\n case Severity.CRITICAL:\n return \"critical\";\n case Severity.WARNING:\n return \"warning\";\n case Severity.INFO:\n return \"info\";\n default:\n return \"info\";\n }\n }\n\n // Fallback: Check for API key errors which should always be critical\n const message = error.message.toLowerCase();\n if (\n message.includes(\"api key\") ||\n message.includes(\"401\") ||\n message.includes(\"unauthorized\") ||\n message.includes(\"authentication\") ||\n message.includes(\"incorrect api key\")\n ) {\n return \"critical\";\n }\n\n // Default to info level\n return \"info\";\n}\n\nfunction getErrorColors(severity: ErrorSeverity): ErrorColors {\n switch (severity) {\n case \"critical\":\n return {\n background: \"#fee2e2\",\n border: \"#dc2626\",\n text: \"#7f1d1d\",\n icon: \"#dc2626\",\n };\n case \"warning\":\n return {\n background: \"#fef3c7\",\n border: \"#d97706\",\n text: \"#78350f\",\n icon: \"#d97706\",\n };\n case \"info\":\n return {\n background: \"#dbeafe\",\n border: \"#2563eb\",\n text: \"#1e3a8a\",\n icon: \"#2563eb\",\n };\n }\n}\n\nexport function useToast() {\n const context = useContext(ToastContext);\n if (!context) {\n throw new Error(\"useToast must be used within a ToastProvider\");\n }\n return context;\n}\n\nexport function ToastProvider({\n enabled,\n children,\n}: {\n enabled: boolean;\n children: React.ReactNode;\n}) {\n const [toasts, setToasts] = useState<Toast[]>([]);\n const [bannerError, setBannerErrorState] = useState<CopilotKitError | null>(null);\n\n const removeToast = useCallback((id: string) => {\n setToasts((prev) => prev.filter((toast) => toast.id !== id));\n }, []);\n\n const addToast = useCallback(\n (toast: PartialBy<Toast, \"id\">) => {\n // Respect the enabled flag for ALL toasts\n if (!enabled) {\n return;\n }\n\n const id = toast.id ?? Math.random().toString(36).substring(2, 9);\n\n setToasts((currentToasts) => {\n if (currentToasts.find((toast) => toast.id === id)) return currentToasts;\n return [...currentToasts, { ...toast, id }];\n });\n\n if (toast.duration) {\n setTimeout(() => {\n removeToast(id);\n }, toast.duration);\n }\n },\n [enabled, removeToast],\n );\n\n const setBannerError = useCallback(\n (error: CopilotKitError | null) => {\n // Respect the enabled flag for ALL errors\n if (!enabled && error !== null) {\n return;\n }\n setBannerErrorState(error);\n },\n [enabled],\n );\n\n const addGraphQLErrorsToast = useCallback((errors: GraphQLError[]) => {\n // DEPRECATED: All errors now route to banners for consistency\n console.warn(\"addGraphQLErrorsToast is deprecated. All errors now show as banners.\");\n // Function kept for backward compatibility - does nothing\n }, []);\n\n const value = {\n toasts,\n addToast,\n addGraphQLErrorsToast,\n removeToast,\n enabled,\n bannerError,\n setBannerError,\n };\n\n return (\n <ToastContext.Provider value={value}>\n {/* Banner Error Display */}\n {bannerError &&\n (() => {\n const severity = getErrorSeverity(bannerError);\n const colors = getErrorColors(severity);\n\n return (\n <div\n style={{\n position: \"fixed\",\n bottom: \"20px\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n zIndex: 9999,\n backgroundColor: colors.background,\n border: `1px solid ${colors.border}`,\n borderLeft: `4px solid ${colors.border}`,\n borderRadius: \"8px\",\n padding: \"12px 16px\",\n fontSize: \"13px\",\n boxShadow: \"0 4px 12px rgba(0, 0, 0, 0.15)\",\n backdropFilter: \"blur(8px)\",\n maxWidth: \"min(90vw, 700px)\",\n width: \"100%\",\n boxSizing: \"border-box\",\n overflow: \"hidden\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n gap: \"10px\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"8px\",\n flex: 1,\n minWidth: 0,\n }}\n >\n <div\n style={{\n width: \"12px\",\n height: \"12px\",\n borderRadius: \"50%\",\n backgroundColor: colors.border,\n flexShrink: 0,\n }}\n />\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"10px\",\n flex: 1,\n minWidth: 0,\n }}\n >\n <div\n style={{\n color: colors.text,\n lineHeight: \"1.4\",\n fontWeight: \"400\",\n fontSize: \"13px\",\n flex: 1,\n wordBreak: \"break-all\",\n overflowWrap: \"break-word\",\n maxWidth: \"550px\",\n overflow: \"hidden\",\n display: \"-webkit-box\",\n WebkitLineClamp: 10,\n WebkitBoxOrient: \"vertical\",\n }}\n >\n {(() => {\n let message = bannerError.message;\n\n // Try to extract the useful message from JSON first\n const jsonMatch = message.match(/'message':\\s*'([^']+)'/);\n if (jsonMatch) {\n return jsonMatch[1]; // Return the actual error message\n }\n\n // Strip technical garbage but keep the meaningful message\n message = message.split(\" - \")[0]; // Remove everything after \" - {\"\n message = message.split(\": Error code\")[0]; // Remove \": Error code: 401\"\n message = message.replace(/:\\s*\\d{3}$/, \"\"); // Remove trailing \": 401\"\n message = message.replace(/See more:.*$/g, \"\"); // Remove \"See more\" links\n message = message.trim();\n\n // If it's still garbage (contains { or '), use fallback\n // if (message.includes(\"{\") || message.includes(\"'\")) {\n // return \"Configuration error.... Please check your setup.\";\n // }\n\n return message || \"Configuration error occurred.\";\n })()}\n </div>\n\n {(() => {\n const message = bannerError.message;\n const markdownLinkRegex = /\\[([^\\]]+)\\]\\(([^)]+)\\)/g;\n const plainUrlRegex = /(https?:\\/\\/[^\\s)]+)/g;\n\n // Extract the first URL found\n let url = null;\n let buttonText = \"See More\";\n\n // Check for markdown links first\n const markdownMatch = markdownLinkRegex.exec(message);\n if (markdownMatch) {\n url = markdownMatch[2];\n buttonText = \"See More\";\n } else {\n // Check for plain URLs\n const urlMatch = plainUrlRegex.exec(message);\n if (urlMatch) {\n url = urlMatch[0].replace(/[.,;:'\"]*$/, \"\"); // Remove trailing punctuation\n buttonText = \"See More\";\n }\n }\n\n if (!url) return null;\n\n return (\n <button\n onClick={() => window.open(url, \"_blank\", \"noopener,noreferrer\")}\n style={{\n background: colors.border,\n color: \"white\",\n border: \"none\",\n borderRadius: \"5px\",\n padding: \"4px 10px\",\n fontSize: \"11px\",\n fontWeight: \"500\",\n cursor: \"pointer\",\n transition: \"all 0.2s ease\",\n flexShrink: 0,\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.opacity = \"0.9\";\n e.currentTarget.style.transform = \"translateY(-1px)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.opacity = \"1\";\n e.currentTarget.style.transform = \"translateY(0)\";\n }}\n >\n {buttonText}\n </button>\n );\n })()}\n </div>\n </div>\n <button\n onClick={() => setBannerError(null)}\n style={{\n background: \"transparent\",\n border: \"none\",\n color: colors.text,\n cursor: \"pointer\",\n padding: \"2px\",\n borderRadius: \"3px\",\n fontSize: \"14px\",\n lineHeight: \"1\",\n opacity: 0.6,\n transition: \"all 0.2s ease\",\n flexShrink: 0,\n }}\n title=\"Dismiss\"\n onMouseEnter={(e) => {\n e.currentTarget.style.opacity = \"1\";\n e.currentTarget.style.background = \"rgba(0, 0, 0, 0.05)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.opacity = \"0.6\";\n e.currentTarget.style.background = \"transparent\";\n }}\n >\n ×\n </button>\n </div>\n </div>\n );\n })()}\n\n {/* Toast Display - Deprecated: All errors now show as banners */}\n {children}\n </ToastContext.Provider>\n );\n}\n\n// Toast component removed - all errors now show as banners for consistency\n","import React, {\n createContext,\n useContext,\n useCallback,\n useState,\n useRef,\n ReactNode,\n RefObject,\n} from \"react\";\nimport { CoAgentStateRender } from \"../types/coagent-action\";\n\ninterface StateRenderClaim {\n stateRenderId: string;\n stateSnapshot?: any;\n runId?: string;\n locked?: boolean;\n}\n\ntype ClaimsRef = Record<string, StateRenderClaim>;\n\nexport interface CoAgentStateRendersContextValue {\n coAgentStateRenders: Record<string, CoAgentStateRender<any>>;\n setCoAgentStateRender: (id: string, stateRender: CoAgentStateRender<any>) => void;\n removeCoAgentStateRender: (id: string) => void;\n claimsRef: RefObject<ClaimsRef>;\n}\n\nconst CoAgentStateRendersContext = createContext<CoAgentStateRendersContextValue | undefined>(\n undefined,\n);\n\nexport function CoAgentStateRendersProvider({ children }: { children: ReactNode }) {\n const [coAgentStateRenders, setCoAgentStateRenders] = useState<\n Record<string, CoAgentStateRender<any>>\n >({});\n\n const setCoAgentStateRender = useCallback((id: string, stateRender: CoAgentStateRender<any>) => {\n setCoAgentStateRenders((prevPoints) => ({\n ...prevPoints,\n [id]: stateRender,\n }));\n }, []);\n\n const removeCoAgentStateRender = useCallback((id: string) => {\n setCoAgentStateRenders((prevPoints) => {\n const newPoints = { ...prevPoints };\n delete newPoints[id];\n return newPoints;\n });\n }, []);\n\n const claimsRef = useRef<ClaimsRef>({});\n\n return (\n <CoAgentStateRendersContext.Provider\n value={{\n coAgentStateRenders,\n setCoAgentStateRender,\n removeCoAgentStateRender,\n claimsRef,\n }}\n >\n {children}\n </CoAgentStateRendersContext.Provider>\n );\n}\n\nexport function useCoAgentStateRenders() {\n const context = useContext(CoAgentStateRendersContext);\n if (!context) {\n throw new Error(\"useCoAgentStateRenders must be used within CoAgentStateRendersProvider\");\n }\n return context;\n}\n\nexport { CoAgentStateRendersContext };\n"],"mappings":"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","names":["import_react","React","import_shared","import_react","import_react","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../../src/hooks/use-coagent-state-render.ts","../../src/context/copilot-context.tsx","../../src/components/toast/toast-provider.tsx","../../src/context/coagent-state-renders-context.tsx"],"sourcesContent":["/**\n * The useCoAgentStateRender hook allows you to render UI or text based components on a Agentic Copilot's state in the chat.\n * This is particularly useful for showing intermediate state or progress during Agentic Copilot operations.\n *\n * ## Usage\n *\n * ### Simple Usage\n *\n * ```tsx\n * import { useCoAgentStateRender } from \"@copilotkit/react-core\";\n *\n * type YourAgentState = {\n * agent_state_property: string;\n * }\n *\n * useCoAgentStateRender<YourAgentState>({\n * name: \"basic_agent\",\n * nodeName: \"optionally_specify_a_specific_node\",\n * render: ({ status, state, nodeName }) => {\n * return (\n * <YourComponent\n * agentStateProperty={state.agent_state_property}\n * status={status}\n * nodeName={nodeName}\n * />\n * );\n * },\n * });\n * ```\n *\n * This allows for you to render UI components or text based on what is happening within the agent.\n *\n * ### Example\n * A great example of this is in our Perplexity Clone where we render the progress of an agent's internet search as it is happening.\n * You can play around with it below or learn how to build it with its [demo](/coagents/videos/perplexity-clone).\n *\n * <Callout type=\"info\">\n * This example is hosted on Vercel and may take a few seconds to load.\n * </Callout>\n *\n * <iframe src=\"https://examples-coagents-ai-researcher-ui.vercel.app/\" className=\"w-full rounded-lg border h-[700px] my-4\" />\n */\n\nimport { useRef, useContext, useEffect } from \"react\";\nimport { CopilotContext } from \"../context/copilot-context\";\nimport { randomId, CopilotKitAgentDiscoveryError } from \"@copilotkit/shared\";\nimport { CoAgentStateRender } from \"../types/coagent-action\";\nimport { useToast } from \"../components/toast/toast-provider\";\nimport { useCoAgentStateRenders } from \"../context/coagent-state-renders-context\";\n\n/**\n * This hook is used to render agent state with custom UI components or text. This is particularly\n * useful for showing intermediate state or progress during Agentic Copilot operations.\n * To get started using rendering intermediate state through this hook, checkout the documentation.\n *\n * https://docs.copilotkit.ai/coagents/shared-state/predictive-state-updates\n */\n\n// We implement useCoAgentStateRender dependency handling so that\n// the developer has the option to not provide any dependencies.\n// see useCopilotAction for more details about this approach.\nexport function useCoAgentStateRender<T = any>(\n action: CoAgentStateRender<T>,\n dependencies?: any[],\n): void {\n const { chatComponentsCache, availableAgents } = useContext(CopilotContext);\n const { setCoAgentStateRender, removeCoAgentStateRender, coAgentStateRenders } =\n useCoAgentStateRenders();\n const idRef = useRef<string>(randomId());\n const { setBannerError, addToast } = useToast();\n\n useEffect(() => {\n if (availableAgents?.length && !availableAgents.some((a) => a.name === action.name)) {\n const message = `(useCoAgentStateRender): Agent \"${action.name}\" not found. Make sure the agent exists and is properly configured.`;\n\n // Route to banner instead of toast for consistency\n const agentError = new CopilotKitAgentDiscoveryError({\n agentName: action.name,\n availableAgents: availableAgents.map((a) => ({ name: a.name, id: a.id })),\n });\n setBannerError(agentError);\n }\n }, [availableAgents]);\n\n const key = `${action.name}-${action.nodeName || \"global\"}`;\n\n if (dependencies === undefined) {\n if (coAgentStateRenders[idRef.current]) {\n coAgentStateRenders[idRef.current].handler = action.handler as any;\n if (typeof action.render === \"function\") {\n if (chatComponentsCache.current !== null) {\n chatComponentsCache.current.coAgentStateRenders[key] = action.render;\n }\n }\n }\n }\n\n useEffect(() => {\n // Check for duplicates by comparing against all other actions\n const currentId = idRef.current;\n const hasDuplicate = Object.entries(coAgentStateRenders).some(([id, otherAction]) => {\n // Skip comparing with self\n if (id === currentId) return false;\n\n // Different agent names are never duplicates\n if (otherAction.name !== action.name) return false;\n\n // Same agent names:\n const hasNodeName = !!action.nodeName;\n const hasOtherNodeName = !!otherAction.nodeName;\n\n // If neither has nodeName, they're duplicates\n if (!hasNodeName && !hasOtherNodeName) return true;\n\n // If one has nodeName and other doesn't, they're not duplicates\n if (hasNodeName !== hasOtherNodeName) return false;\n\n // If both have nodeName, they're duplicates only if the names match\n return action.nodeName === otherAction.nodeName;\n });\n\n if (hasDuplicate) {\n const message = action.nodeName\n ? `Found multiple state renders for agent ${action.name} and node ${action.nodeName}. State renders might get overridden`\n : `Found multiple state renders for agent ${action.name}. State renders might get overridden`;\n\n addToast({\n type: \"warning\",\n message,\n id: `dup-action-${action.name}`,\n });\n }\n }, [coAgentStateRenders]);\n\n useEffect(() => {\n setCoAgentStateRender(idRef.current, action as any);\n if (chatComponentsCache.current !== null && action.render !== undefined) {\n chatComponentsCache.current.coAgentStateRenders[key] = action.render;\n }\n return () => {\n removeCoAgentStateRender(idRef.current);\n };\n }, [\n setCoAgentStateRender,\n removeCoAgentStateRender,\n action.name,\n // include render only if it's a string\n typeof action.render === \"string\" ? action.render : undefined,\n // dependencies set by the developer\n ...(dependencies || []),\n ]);\n}\n","import {\n CopilotCloudConfig,\n FunctionCallHandler,\n CopilotErrorHandler,\n CopilotKitError,\n} from \"@copilotkit/shared\";\nimport {\n ActionRenderProps,\n CatchAllActionRenderProps,\n FrontendAction,\n} from \"../types/frontend-action\";\nimport React from \"react\";\nimport { TreeNodeId, Tree } from \"../hooks/use-tree\";\nimport { DocumentPointer } from \"../types\";\nimport { CopilotChatSuggestionConfiguration } from \"../types/chat-suggestion-configuration\";\nimport { CoAgentStateRender, CoAgentStateRenderProps } from \"../types/coagent-action\";\nimport { CoagentState } from \"../types/coagent-state\";\nimport {\n CopilotRuntimeClient,\n ExtensionsInput,\n ForwardedParametersInput,\n} from \"@copilotkit/runtime-client-gql\";\nimport { Agent } from \"@copilotkit/runtime-client-gql\";\nimport {\n LangGraphInterruptRender,\n LangGraphInterruptActionSetter,\n QueuedInterruptEvent,\n} from \"../types/interrupt-action\";\n\n/**\n * Interface for the configuration of the Copilot API.\n */\nexport interface CopilotApiConfig {\n /**\n * The public API key for Copilot Cloud.\n */\n publicApiKey?: string;\n\n /**\n * The configuration for Copilot Cloud.\n */\n cloud?: CopilotCloudConfig;\n\n /**\n * The endpoint for the chat API.\n */\n chatApiEndpoint: string;\n\n /**\n * The endpoint for the Copilot transcribe audio service.\n */\n transcribeAudioUrl?: string;\n\n /**\n * The endpoint for the Copilot text to speech service.\n */\n textToSpeechUrl?: string;\n\n /**\n * additional headers to be sent with the request\n * @default {}\n * @example\n * ```\n * {\n * 'Authorization': 'Bearer your_token_here'\n * }\n * ```\n */\n headers: Record<string, string>;\n\n /**\n * Custom properties to be sent with the request\n * @default {}\n * @example\n * ```\n * {\n * 'user_id': 'user_id'\n * }\n * ```\n */\n properties?: Record<string, any>;\n\n /**\n * Indicates whether the user agent should send or receive cookies from the other domain\n * in the case of cross-origin requests.\n */\n credentials?: RequestCredentials;\n\n /**\n * Optional configuration for connecting to Model Context Protocol (MCP) servers.\n * This is typically derived from the CopilotKitProps and used internally.\n * @experimental\n */\n mcpServers?: Array<{ endpoint: string; apiKey?: string }>;\n}\n\nexport type InChatRenderFunction<TProps = ActionRenderProps<any> | CatchAllActionRenderProps<any>> =\n (props: TProps) => string | React.JSX.Element;\nexport type CoagentInChatRenderFunction = (\n props: CoAgentStateRenderProps<any>,\n) => string | React.JSX.Element | undefined | null;\n\nexport interface ChatComponentsCache {\n actions: Record<string, InChatRenderFunction | string>;\n coAgentStateRenders: Record<string, CoagentInChatRenderFunction | string>;\n}\n\nexport interface AgentSession {\n agentName: string;\n threadId?: string;\n nodeName?: string;\n}\n\nexport interface AuthState {\n status: \"authenticated\" | \"unauthenticated\";\n authHeaders: Record<string, string>;\n userId?: string;\n metadata?: Record<string, any>;\n}\n\nexport type ActionName = string;\nexport type ContextTree = Tree;\n\nexport interface CopilotContextParams {\n // function-calling\n actions: Record<string, FrontendAction<any>>;\n setAction: (id: string, action: FrontendAction<any>) => void;\n removeAction: (id: string) => void;\n\n // registered actions for component-based rendering\n setRegisteredActions: (actionConfig: any) => string;\n removeRegisteredAction: (actionKey: string) => void;\n\n chatComponentsCache: React.RefObject<ChatComponentsCache>;\n\n getFunctionCallHandler: (\n customEntryPoints?: Record<string, FrontendAction<any>>,\n ) => FunctionCallHandler;\n\n // text context\n addContext: (context: string, parentId?: string, categories?: string[]) => TreeNodeId;\n removeContext: (id: TreeNodeId) => void;\n getAllContext: () => Tree;\n getContextString: (documents: DocumentPointer[], categories: string[]) => string;\n\n // document context\n addDocumentContext: (documentPointer: DocumentPointer, categories?: string[]) => TreeNodeId;\n removeDocumentContext: (documentId: string) => void;\n getDocumentsContext: (categories: string[]) => DocumentPointer[];\n\n isLoading: boolean;\n setIsLoading: React.Dispatch<React.SetStateAction<boolean>>;\n\n chatSuggestionConfiguration: { [key: string]: CopilotChatSuggestionConfiguration };\n addChatSuggestionConfiguration: (\n id: string,\n suggestion: CopilotChatSuggestionConfiguration,\n ) => void;\n removeChatSuggestionConfiguration: (id: string) => void;\n\n chatInstructions: string;\n setChatInstructions: React.Dispatch<React.SetStateAction<string>>;\n\n additionalInstructions?: string[];\n setAdditionalInstructions: React.Dispatch<React.SetStateAction<string[]>>;\n\n // api endpoints\n copilotApiConfig: CopilotApiConfig;\n\n showDevConsole: boolean;\n\n // agents\n coagentStates: Record<string, CoagentState>;\n setCoagentStates: React.Dispatch<React.SetStateAction<Record<string, CoagentState>>>;\n coagentStatesRef: React.RefObject<Record<string, CoagentState>>;\n setCoagentStatesWithRef: (\n value:\n | Record<string, CoagentState>\n | ((prev: Record<string, CoagentState>) => Record<string, CoagentState>),\n ) => void;\n\n agentSession: AgentSession | null;\n setAgentSession: React.Dispatch<React.SetStateAction<AgentSession | null>>;\n\n agentLock: string | null;\n\n threadId: string;\n setThreadId: React.Dispatch<React.SetStateAction<string>>;\n\n runId: string | null;\n setRunId: React.Dispatch<React.SetStateAction<string | null>>;\n\n // The chat abort controller can be used to stop generation globally,\n // i.e. when using `stop()` from `useChat`\n chatAbortControllerRef: React.MutableRefObject<AbortController | null>;\n\n /**\n * The forwarded parameters to use for the task.\n */\n forwardedParameters?: Partial<Pick<ForwardedParametersInput, \"temperature\">>;\n availableAgents: Agent[];\n\n /**\n * The auth states for the CopilotKit.\n */\n authStates_c?: Record<ActionName, AuthState>;\n setAuthStates_c?: React.Dispatch<React.SetStateAction<Record<ActionName, AuthState>>>;\n\n /**\n * The auth config for the CopilotKit.\n */\n authConfig_c?: {\n SignInComponent: React.ComponentType<{\n onSignInComplete: (authState: AuthState) => void;\n }>;\n };\n\n extensions: ExtensionsInput;\n setExtensions: React.Dispatch<React.SetStateAction<ExtensionsInput>>;\n interruptActions: Record<string, LangGraphInterruptRender>;\n setInterruptAction: LangGraphInterruptActionSetter;\n removeInterruptAction: (actionId: string) => void;\n interruptEventQueue: Record<string, QueuedInterruptEvent[]>;\n addInterruptEvent: (queuedEvent: QueuedInterruptEvent) => void;\n resolveInterruptEvent: (threadId: string, eventId: string, response: string) => void;\n\n /**\n * Optional trace handler for comprehensive debugging and observability.\n */\n onError: CopilotErrorHandler;\n\n // banner error state\n bannerError: CopilotKitError | null;\n setBannerError: React.Dispatch<React.SetStateAction<CopilotKitError | null>>;\n // Internal error handlers\n // These are used to handle errors that occur during the execution of the chat.\n // They are not intended for use by the developer. A component can register itself an error listener to be activated somewhere else as needed\n internalErrorHandlers: Record<string, CopilotErrorHandler>;\n setInternalErrorHandler: (handler: Record<string, CopilotErrorHandler>) => void;\n removeInternalErrorHandler: (id: string) => void;\n}\n\nconst emptyCopilotContext: CopilotContextParams = {\n actions: {},\n setAction: () => {},\n removeAction: () => {},\n\n setRegisteredActions: () => \"\",\n removeRegisteredAction: () => {},\n\n chatComponentsCache: { current: { actions: {}, coAgentStateRenders: {} } },\n getContextString: (documents: DocumentPointer[], categories: string[]) =>\n returnAndThrowInDebug(\"\"),\n addContext: () => \"\",\n removeContext: () => {},\n getAllContext: () => [],\n\n getFunctionCallHandler: () => returnAndThrowInDebug(async () => {}),\n\n isLoading: false,\n setIsLoading: () => returnAndThrowInDebug(false),\n\n chatInstructions: \"\",\n setChatInstructions: () => returnAndThrowInDebug(\"\"),\n\n additionalInstructions: [],\n setAdditionalInstructions: () => returnAndThrowInDebug([]),\n\n getDocumentsContext: (categories: string[]) => returnAndThrowInDebug([]),\n addDocumentContext: () => returnAndThrowInDebug(\"\"),\n removeDocumentContext: () => {},\n\n copilotApiConfig: new (class implements CopilotApiConfig {\n get chatApiEndpoint(): string {\n throw new Error(\"Remember to wrap your app in a `<CopilotKit> {...} </CopilotKit>` !!!\");\n }\n\n get headers(): Record<string, string> {\n return {};\n }\n get body(): Record<string, any> {\n return {};\n }\n })(),\n\n chatSuggestionConfiguration: {},\n addChatSuggestionConfiguration: () => {},\n removeChatSuggestionConfiguration: () => {},\n showDevConsole: false,\n coagentStates: {},\n setCoagentStates: () => {},\n coagentStatesRef: { current: {} },\n setCoagentStatesWithRef: () => {},\n agentSession: null,\n setAgentSession: () => {},\n forwardedParameters: {},\n agentLock: null,\n threadId: \"\",\n setThreadId: () => {},\n runId: null,\n setRunId: () => {},\n chatAbortControllerRef: { current: null },\n availableAgents: [],\n extensions: {},\n setExtensions: () => {},\n interruptActions: {},\n setInterruptAction: () => {},\n removeInterruptAction: () => {},\n interruptEventQueue: {},\n addInterruptEvent: () => {},\n resolveInterruptEvent: () => {},\n onError: () => {},\n bannerError: null,\n setBannerError: () => {},\n internalErrorHandlers: {},\n setInternalErrorHandler: () => {},\n removeInternalErrorHandler: () => {},\n};\n\nexport const CopilotContext = React.createContext<CopilotContextParams>(emptyCopilotContext);\n\nexport function useCopilotContext(): CopilotContextParams {\n const context = React.useContext(CopilotContext);\n if (context === emptyCopilotContext) {\n throw new Error(\"Remember to wrap your app in a `<CopilotKit> {...} </CopilotKit>` !!!\");\n }\n return context;\n}\n\nfunction returnAndThrowInDebug<T>(_value: T): T {\n throw new Error(\"Remember to wrap your app in a `<CopilotKit> {...} </CopilotKit>` !!!\");\n}\n","import { GraphQLError } from \"@copilotkit/runtime-client-gql\";\nimport React, { createContext, useContext, useState, useCallback } from \"react\";\nimport { PartialBy, CopilotKitError, Severity } from \"@copilotkit/shared\";\n\ninterface Toast {\n id: string;\n message: string | React.ReactNode;\n type: \"info\" | \"success\" | \"warning\" | \"error\";\n duration?: number;\n}\n\ninterface ToastContextValue {\n toasts: Toast[];\n addToast: (toast: PartialBy<Toast, \"id\">) => void;\n addGraphQLErrorsToast: (errors: GraphQLError[]) => void;\n removeToast: (id: string) => void;\n enabled: boolean;\n // Banner management\n bannerError: CopilotKitError | null;\n setBannerError: (error: CopilotKitError | null) => void;\n}\n\nconst ToastContext = createContext<ToastContextValue | undefined>(undefined);\n\n// Helper functions for error banner styling\ntype ErrorSeverity = \"critical\" | \"warning\" | \"info\";\n\ninterface ErrorColors {\n background: string;\n border: string;\n text: string;\n icon: string;\n}\n\nfunction getErrorSeverity(error: CopilotKitError): ErrorSeverity {\n // Use structured error severity if available\n if (error.severity) {\n switch (error.severity) {\n case Severity.CRITICAL:\n return \"critical\";\n case Severity.WARNING:\n return \"warning\";\n case Severity.INFO:\n return \"info\";\n default:\n return \"info\";\n }\n }\n\n // Fallback: Check for API key errors which should always be critical\n const message = error.message.toLowerCase();\n if (\n message.includes(\"api key\") ||\n message.includes(\"401\") ||\n message.includes(\"unauthorized\") ||\n message.includes(\"authentication\") ||\n message.includes(\"incorrect api key\")\n ) {\n return \"critical\";\n }\n\n // Default to info level\n return \"info\";\n}\n\nfunction getErrorColors(severity: ErrorSeverity): ErrorColors {\n switch (severity) {\n case \"critical\":\n return {\n background: \"#fee2e2\",\n border: \"#dc2626\",\n text: \"#7f1d1d\",\n icon: \"#dc2626\",\n };\n case \"warning\":\n return {\n background: \"#fef3c7\",\n border: \"#d97706\",\n text: \"#78350f\",\n icon: \"#d97706\",\n };\n case \"info\":\n return {\n background: \"#dbeafe\",\n border: \"#2563eb\",\n text: \"#1e3a8a\",\n icon: \"#2563eb\",\n };\n }\n}\n\nexport function useToast() {\n const context = useContext(ToastContext);\n if (!context) {\n throw new Error(\"useToast must be used within a ToastProvider\");\n }\n return context;\n}\n\nexport function ToastProvider({\n enabled,\n children,\n}: {\n enabled: boolean;\n children: React.ReactNode;\n}) {\n const [toasts, setToasts] = useState<Toast[]>([]);\n const [bannerError, setBannerErrorState] = useState<CopilotKitError | null>(null);\n\n const removeToast = useCallback((id: string) => {\n setToasts((prev) => prev.filter((toast) => toast.id !== id));\n }, []);\n\n const addToast = useCallback(\n (toast: PartialBy<Toast, \"id\">) => {\n // Respect the enabled flag for ALL toasts\n if (!enabled) {\n return;\n }\n\n const id = toast.id ?? Math.random().toString(36).substring(2, 9);\n\n setToasts((currentToasts) => {\n if (currentToasts.find((toast) => toast.id === id)) return currentToasts;\n return [...currentToasts, { ...toast, id }];\n });\n\n if (toast.duration) {\n setTimeout(() => {\n removeToast(id);\n }, toast.duration);\n }\n },\n [enabled, removeToast],\n );\n\n const setBannerError = useCallback(\n (error: CopilotKitError | null) => {\n // Respect the enabled flag for ALL errors\n if (!enabled && error !== null) {\n return;\n }\n setBannerErrorState(error);\n },\n [enabled],\n );\n\n const addGraphQLErrorsToast = useCallback((errors: GraphQLError[]) => {\n // DEPRECATED: All errors now route to banners for consistency\n console.warn(\"addGraphQLErrorsToast is deprecated. All errors now show as banners.\");\n // Function kept for backward compatibility - does nothing\n }, []);\n\n const value = {\n toasts,\n addToast,\n addGraphQLErrorsToast,\n removeToast,\n enabled,\n bannerError,\n setBannerError,\n };\n\n return (\n <ToastContext.Provider value={value}>\n {/* Banner Error Display */}\n {bannerError &&\n (() => {\n const severity = getErrorSeverity(bannerError);\n const colors = getErrorColors(severity);\n\n return (\n <div\n style={{\n position: \"fixed\",\n bottom: \"20px\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n zIndex: 9999,\n backgroundColor: colors.background,\n border: `1px solid ${colors.border}`,\n borderLeft: `4px solid ${colors.border}`,\n borderRadius: \"8px\",\n padding: \"12px 16px\",\n fontSize: \"13px\",\n boxShadow: \"0 4px 12px rgba(0, 0, 0, 0.15)\",\n backdropFilter: \"blur(8px)\",\n maxWidth: \"min(90vw, 700px)\",\n width: \"100%\",\n boxSizing: \"border-box\",\n overflow: \"hidden\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n gap: \"10px\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"8px\",\n flex: 1,\n minWidth: 0,\n }}\n >\n <div\n style={{\n width: \"12px\",\n height: \"12px\",\n borderRadius: \"50%\",\n backgroundColor: colors.border,\n flexShrink: 0,\n }}\n />\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"10px\",\n flex: 1,\n minWidth: 0,\n }}\n >\n <div\n style={{\n color: colors.text,\n lineHeight: \"1.4\",\n fontWeight: \"400\",\n fontSize: \"13px\",\n flex: 1,\n wordBreak: \"break-all\",\n overflowWrap: \"break-word\",\n maxWidth: \"550px\",\n overflow: \"hidden\",\n display: \"-webkit-box\",\n WebkitLineClamp: 10,\n WebkitBoxOrient: \"vertical\",\n }}\n >\n {(() => {\n let message = bannerError.message;\n\n // Try to extract the useful message from JSON first\n const jsonMatch = message.match(/'message':\\s*'([^']+)'/);\n if (jsonMatch) {\n return jsonMatch[1]; // Return the actual error message\n }\n\n // Strip technical garbage but keep the meaningful message\n message = message.split(\" - \")[0]; // Remove everything after \" - {\"\n message = message.split(\": Error code\")[0]; // Remove \": Error code: 401\"\n message = message.replace(/:\\s*\\d{3}$/, \"\"); // Remove trailing \": 401\"\n message = message.replace(/See more:.*$/g, \"\"); // Remove \"See more\" links\n message = message.trim();\n\n // If it's still garbage (contains { or '), use fallback\n // if (message.includes(\"{\") || message.includes(\"'\")) {\n // return \"Configuration error.... Please check your setup.\";\n // }\n\n return message || \"Configuration error occurred.\";\n })()}\n </div>\n\n {(() => {\n const message = bannerError.message;\n const markdownLinkRegex = /\\[([^\\]]+)\\]\\(([^)]+)\\)/g;\n const plainUrlRegex = /(https?:\\/\\/[^\\s)]+)/g;\n\n // Extract the first URL found\n let url = null;\n let buttonText = \"See More\";\n\n // Check for markdown links first\n const markdownMatch = markdownLinkRegex.exec(message);\n if (markdownMatch) {\n url = markdownMatch[2];\n buttonText = \"See More\";\n } else {\n // Check for plain URLs\n const urlMatch = plainUrlRegex.exec(message);\n if (urlMatch) {\n url = urlMatch[0].replace(/[.,;:'\"]*$/, \"\"); // Remove trailing punctuation\n buttonText = \"See More\";\n }\n }\n\n if (!url) return null;\n\n return (\n <button\n onClick={() => window.open(url, \"_blank\", \"noopener,noreferrer\")}\n style={{\n background: colors.border,\n color: \"white\",\n border: \"none\",\n borderRadius: \"5px\",\n padding: \"4px 10px\",\n fontSize: \"11px\",\n fontWeight: \"500\",\n cursor: \"pointer\",\n transition: \"all 0.2s ease\",\n flexShrink: 0,\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.opacity = \"0.9\";\n e.currentTarget.style.transform = \"translateY(-1px)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.opacity = \"1\";\n e.currentTarget.style.transform = \"translateY(0)\";\n }}\n >\n {buttonText}\n </button>\n );\n })()}\n </div>\n </div>\n <button\n onClick={() => setBannerError(null)}\n style={{\n background: \"transparent\",\n border: \"none\",\n color: colors.text,\n cursor: \"pointer\",\n padding: \"2px\",\n borderRadius: \"3px\",\n fontSize: \"14px\",\n lineHeight: \"1\",\n opacity: 0.6,\n transition: \"all 0.2s ease\",\n flexShrink: 0,\n }}\n title=\"Dismiss\"\n onMouseEnter={(e) => {\n e.currentTarget.style.opacity = \"1\";\n e.currentTarget.style.background = \"rgba(0, 0, 0, 0.05)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.opacity = \"0.6\";\n e.currentTarget.style.background = \"transparent\";\n }}\n >\n ×\n </button>\n </div>\n </div>\n );\n })()}\n\n {/* Toast Display - Deprecated: All errors now show as banners */}\n {children}\n </ToastContext.Provider>\n );\n}\n\n// Toast component removed - all errors now show as banners for consistency\n","import React, {\n createContext,\n useContext,\n useCallback,\n useState,\n useRef,\n ReactNode,\n RefObject,\n} from \"react\";\nimport { CoAgentStateRender } from \"../types/coagent-action\";\n\ninterface StateRenderClaim {\n stateRenderId: string;\n stateSnapshot?: any;\n runId?: string;\n messageIndex?: number;\n locked?: boolean;\n}\n\ntype ClaimsRef = Record<string, StateRenderClaim>;\n\nexport interface CoAgentStateRendersContextValue {\n coAgentStateRenders: Record<string, CoAgentStateRender<any>>;\n setCoAgentStateRender: (id: string, stateRender: CoAgentStateRender<any>) => void;\n removeCoAgentStateRender: (id: string) => void;\n claimsRef: RefObject<ClaimsRef>;\n}\n\nconst CoAgentStateRendersContext = createContext<CoAgentStateRendersContextValue | undefined>(\n undefined,\n);\n\nexport function CoAgentStateRendersProvider({ children }: { children: ReactNode }) {\n const [coAgentStateRenders, setCoAgentStateRenders] = useState<\n Record<string, CoAgentStateRender<any>>\n >({});\n\n const setCoAgentStateRender = useCallback((id: string, stateRender: CoAgentStateRender<any>) => {\n setCoAgentStateRenders((prevPoints) => ({\n ...prevPoints,\n [id]: stateRender,\n }));\n }, []);\n\n const removeCoAgentStateRender = useCallback((id: string) => {\n setCoAgentStateRenders((prevPoints) => {\n const newPoints = { ...prevPoints };\n delete newPoints[id];\n return newPoints;\n });\n }, []);\n\n const claimsRef = useRef<ClaimsRef>({});\n\n return (\n <CoAgentStateRendersContext.Provider\n value={{\n coAgentStateRenders,\n setCoAgentStateRender,\n removeCoAgentStateRender,\n claimsRef,\n }}\n >\n {children}\n </CoAgentStateRendersContext.Provider>\n );\n}\n\nexport function useCoAgentStateRenders() {\n const context = useContext(CoAgentStateRendersContext);\n if (!context) {\n throw new Error(\"useCoAgentStateRenders must be used within CoAgentStateRendersProvider\");\n }\n return context;\n}\n\nexport { CoAgentStateRendersContext };\n"],"mappings":"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","names":["import_react","React","import_shared","import_react","import_react","import_jsx_runtime"]}
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  useCoAgentStateRender
3
- } from "../chunk-YTQHRJUA.mjs";
3
+ } from "../chunk-VKNLTZJE.mjs";
4
4
  import "../chunk-EFL5OBKN.mjs";
5
- import "../chunk-FDOMAPJY.mjs";
5
+ import "../chunk-QD7EID4N.mjs";
6
6
  import "../chunk-AFNWX62Q.mjs";
7
7
  import "../chunk-SKC7AJIV.mjs";
8
8
  export {