@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.
- package/CHANGELOG.md +10 -0
- package/dist/chunk-77IVITG3.mjs +158 -0
- package/dist/chunk-77IVITG3.mjs.map +1 -0
- package/dist/chunk-BKMJ4LC7.mjs +119 -0
- package/dist/chunk-BKMJ4LC7.mjs.map +1 -0
- package/dist/chunk-C3YJYDK4.mjs +189 -0
- package/dist/chunk-C3YJYDK4.mjs.map +1 -0
- package/dist/{chunk-GIU66J37.mjs → chunk-DQXCQWSG.mjs} +47 -5
- package/dist/chunk-DQXCQWSG.mjs.map +1 -0
- package/dist/{chunk-HBMPXNW2.mjs → chunk-LO4RRITI.mjs} +71 -18
- package/dist/chunk-LO4RRITI.mjs.map +1 -0
- package/dist/{chunk-3G4VFRVV.mjs → chunk-NXHQDCZF.mjs} +2 -2
- package/dist/{chunk-FDOMAPJY.mjs → chunk-QD7EID4N.mjs} +1 -1
- package/dist/chunk-QD7EID4N.mjs.map +1 -0
- package/dist/{chunk-YTQHRJUA.mjs → chunk-VKNLTZJE.mjs} +2 -2
- package/dist/{chunk-4RRUJHCI.mjs → chunk-VP43SLSZ.mjs} +2 -2
- package/dist/{chunk-MF2ZSLBV.mjs → chunk-XZFIJ7XF.mjs} +2 -2
- package/dist/components/copilot-provider/copilotkit.js +437 -150
- package/dist/components/copilot-provider/copilotkit.js.map +1 -1
- package/dist/components/copilot-provider/copilotkit.mjs +5 -3
- package/dist/components/copilot-provider/index.js +437 -150
- package/dist/components/copilot-provider/index.js.map +1 -1
- package/dist/components/copilot-provider/index.mjs +5 -3
- package/dist/components/index.js +437 -150
- package/dist/components/index.js.map +1 -1
- package/dist/components/index.mjs +5 -3
- package/dist/context/coagent-state-renders-context.d.ts +1 -0
- package/dist/context/coagent-state-renders-context.js.map +1 -1
- package/dist/context/coagent-state-renders-context.mjs +1 -1
- package/dist/context/index.js.map +1 -1
- package/dist/context/index.mjs +1 -1
- package/dist/hooks/index.js +512 -212
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +19 -17
- package/dist/hooks/use-coagent-state-render-bridge.helpers.d.ts +92 -0
- package/dist/hooks/use-coagent-state-render-bridge.helpers.js +231 -0
- package/dist/hooks/use-coagent-state-render-bridge.helpers.js.map +1 -0
- package/dist/hooks/use-coagent-state-render-bridge.helpers.mjs +24 -0
- package/dist/hooks/use-coagent-state-render-bridge.helpers.mjs.map +1 -0
- package/dist/hooks/use-coagent-state-render-bridge.js +334 -72
- package/dist/hooks/use-coagent-state-render-bridge.js.map +1 -1
- package/dist/hooks/use-coagent-state-render-bridge.mjs +4 -2
- package/dist/hooks/use-coagent-state-render-registry.d.ts +25 -0
- package/dist/hooks/use-coagent-state-render-registry.js +358 -0
- package/dist/hooks/use-coagent-state-render-registry.js.map +1 -0
- package/dist/hooks/use-coagent-state-render-registry.mjs +9 -0
- package/dist/hooks/use-coagent-state-render-registry.mjs.map +1 -0
- package/dist/hooks/use-coagent-state-render.js.map +1 -1
- package/dist/hooks/use-coagent-state-render.mjs +2 -2
- package/dist/hooks/use-copilot-chat-headless_c.js +414 -114
- package/dist/hooks/use-copilot-chat-headless_c.js.map +1 -1
- package/dist/hooks/use-copilot-chat-headless_c.mjs +7 -5
- package/dist/hooks/use-copilot-chat.js +406 -106
- package/dist/hooks/use-copilot-chat.js.map +1 -1
- package/dist/hooks/use-copilot-chat.mjs +7 -5
- package/dist/hooks/use-copilot-chat_internal.js +406 -106
- package/dist/hooks/use-copilot-chat_internal.js.map +1 -1
- package/dist/hooks/use-copilot-chat_internal.mjs +6 -4
- package/dist/hooks/use-langgraph-interrupt-render.mjs +1 -1
- package/dist/index.js +651 -311
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +22 -20
- package/dist/lib/copilot-task.js.map +1 -1
- package/dist/lib/copilot-task.mjs +6 -4
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/index.mjs +6 -4
- package/dist/setupTests.js +1 -0
- package/dist/setupTests.js.map +1 -1
- package/dist/setupTests.mjs +1 -0
- package/dist/setupTests.mjs.map +1 -1
- package/dist/test-helpers/copilot-context.d.ts +14 -0
- package/dist/test-helpers/copilot-context.js +128 -0
- package/dist/test-helpers/copilot-context.js.map +1 -0
- package/dist/test-helpers/copilot-context.mjs +74 -0
- package/dist/test-helpers/copilot-context.mjs.map +1 -0
- package/dist/types/index.mjs +1 -1
- package/package.json +5 -5
- package/src/components/copilot-provider/copilotkit.tsx +56 -0
- package/src/context/coagent-state-renders-context.tsx +1 -0
- package/src/hooks/__tests__/use-coagent-state-render-bridge.helpers.test.ts +100 -0
- package/src/hooks/__tests__/use-coagent-state-render.e2e.test.tsx +892 -37
- package/src/hooks/__tests__/use-coagent-state-render.test.tsx +334 -0
- package/src/hooks/use-coagent-state-render-bridge.helpers.ts +311 -0
- package/src/hooks/use-coagent-state-render-bridge.tsx +25 -120
- package/src/hooks/use-coagent-state-render-registry.ts +215 -0
- package/src/hooks/use-copilot-chat_internal.ts +93 -34
- package/src/setupTests.ts +1 -0
- package/src/test-helpers/copilot-context.ts +91 -0
- package/dist/chunk-3X3I7OJV.mjs +0 -172
- package/dist/chunk-3X3I7OJV.mjs.map +0 -1
- package/dist/chunk-FDOMAPJY.mjs.map +0 -1
- package/dist/chunk-GIU66J37.mjs.map +0 -1
- package/dist/chunk-HBMPXNW2.mjs.map +0 -1
- /package/dist/{chunk-3G4VFRVV.mjs.map → chunk-NXHQDCZF.mjs.map} +0 -0
- /package/dist/{chunk-YTQHRJUA.mjs.map → chunk-VKNLTZJE.mjs.map} +0 -0
- /package/dist/{chunk-4RRUJHCI.mjs.map → chunk-VP43SLSZ.mjs.map} +0 -0
- /package/dist/{chunk-MF2ZSLBV.mjs.map → chunk-XZFIJ7XF.mjs.map} +0 -0
|
@@ -1,10 +1,25 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
|
+
var __defProps = Object.defineProperties;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
7
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
6
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
9
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
10
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
11
|
+
var __spreadValues = (a, b) => {
|
|
12
|
+
for (var prop in b || (b = {}))
|
|
13
|
+
if (__hasOwnProp.call(b, prop))
|
|
14
|
+
__defNormalProp(a, prop, b[prop]);
|
|
15
|
+
if (__getOwnPropSymbols)
|
|
16
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
17
|
+
if (__propIsEnum.call(b, prop))
|
|
18
|
+
__defNormalProp(a, prop, b[prop]);
|
|
19
|
+
}
|
|
20
|
+
return a;
|
|
21
|
+
};
|
|
22
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
8
23
|
var __objRest = (source, exclude) => {
|
|
9
24
|
var target = {};
|
|
10
25
|
for (var prop in source)
|
|
@@ -38,8 +53,8 @@ __export(use_coagent_state_render_bridge_exports, {
|
|
|
38
53
|
useCoagentStateRenderBridge: () => useCoagentStateRenderBridge
|
|
39
54
|
});
|
|
40
55
|
module.exports = __toCommonJS(use_coagent_state_render_bridge_exports);
|
|
41
|
-
var
|
|
42
|
-
var
|
|
56
|
+
var import_react3 = require("@copilotkitnext/react");
|
|
57
|
+
var import_react4 = require("react");
|
|
43
58
|
|
|
44
59
|
// src/context/coagent-state-renders-context.tsx
|
|
45
60
|
var import_react = require("react");
|
|
@@ -56,6 +71,9 @@ function useCoAgentStateRenders() {
|
|
|
56
71
|
}
|
|
57
72
|
|
|
58
73
|
// src/hooks/use-coagent-state-render-bridge.tsx
|
|
74
|
+
var import_shared2 = require("@copilotkit/shared");
|
|
75
|
+
|
|
76
|
+
// src/hooks/use-coagent-state-render-bridge.helpers.ts
|
|
59
77
|
var import_shared = require("@copilotkit/shared");
|
|
60
78
|
function getStateWithoutConstantKeys(state) {
|
|
61
79
|
if (!state)
|
|
@@ -78,16 +96,294 @@ function areStatesEquals(a, b) {
|
|
|
78
96
|
]);
|
|
79
97
|
return JSON.stringify(aWithoutConstantKeys) === JSON.stringify(bWithoutConstantKeys);
|
|
80
98
|
}
|
|
99
|
+
function isPlaceholderMessageId(messageId) {
|
|
100
|
+
return !!messageId && messageId.startsWith("coagent-state-render-");
|
|
101
|
+
}
|
|
102
|
+
function isPlaceholderMessageName(messageName) {
|
|
103
|
+
return messageName === "coagent-state-render";
|
|
104
|
+
}
|
|
105
|
+
function readCachedMessageEntry(entry) {
|
|
106
|
+
if (!entry || typeof entry !== "object") {
|
|
107
|
+
return { snapshot: entry, runId: void 0 };
|
|
108
|
+
}
|
|
109
|
+
const snapshot = "snapshot" in entry ? entry.snapshot : entry;
|
|
110
|
+
const runId = "runId" in entry ? entry.runId : void 0;
|
|
111
|
+
return { snapshot, runId };
|
|
112
|
+
}
|
|
113
|
+
function getEffectiveRunId({
|
|
114
|
+
existingClaimRunId,
|
|
115
|
+
cachedMessageRunId,
|
|
116
|
+
runId
|
|
117
|
+
}) {
|
|
118
|
+
return existingClaimRunId || cachedMessageRunId || runId || "pending";
|
|
119
|
+
}
|
|
120
|
+
function resolveClaim({
|
|
121
|
+
claims,
|
|
122
|
+
context,
|
|
123
|
+
stateSnapshot
|
|
124
|
+
}) {
|
|
125
|
+
const { messageId, stateRenderId, runId, messageIndex } = context;
|
|
126
|
+
const existing = claims[messageId];
|
|
127
|
+
if (existing) {
|
|
128
|
+
const canRender = existing.stateRenderId === stateRenderId;
|
|
129
|
+
const shouldUpdateRunId = canRender && runId && (!existing.runId || existing.runId === "pending");
|
|
130
|
+
return {
|
|
131
|
+
canRender,
|
|
132
|
+
action: canRender ? "existing" /* Existing */ : "block" /* Block */,
|
|
133
|
+
updateRunId: shouldUpdateRunId ? runId : void 0
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
const normalizedRunId = runId != null ? runId : "pending";
|
|
137
|
+
const renderClaimedByOtherMessageEntry = Object.entries(claims).find(
|
|
138
|
+
([, claim]) => {
|
|
139
|
+
var _a;
|
|
140
|
+
return claim.stateRenderId === stateRenderId && ((_a = claim.runId) != null ? _a : "pending") === normalizedRunId && (0, import_shared.dataToUUID)(getStateWithoutConstantKeys(claim.stateSnapshot)) === (0, import_shared.dataToUUID)(getStateWithoutConstantKeys(stateSnapshot));
|
|
141
|
+
}
|
|
142
|
+
);
|
|
143
|
+
const renderClaimedByOtherMessage = renderClaimedByOtherMessageEntry == null ? void 0 : renderClaimedByOtherMessageEntry[1];
|
|
144
|
+
const claimedMessageId = renderClaimedByOtherMessageEntry == null ? void 0 : renderClaimedByOtherMessageEntry[0];
|
|
145
|
+
if (renderClaimedByOtherMessage) {
|
|
146
|
+
if (messageIndex !== void 0 && renderClaimedByOtherMessage.messageIndex !== void 0 && messageIndex > renderClaimedByOtherMessage.messageIndex) {
|
|
147
|
+
return {
|
|
148
|
+
canRender: true,
|
|
149
|
+
action: "override" /* Override */,
|
|
150
|
+
nextClaim: { stateRenderId, runId, messageIndex },
|
|
151
|
+
lockOthers: runId === renderClaimedByOtherMessage.runId || isPlaceholderMessageId(claimedMessageId)
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
if (runId && renderClaimedByOtherMessage.runId && runId !== renderClaimedByOtherMessage.runId) {
|
|
155
|
+
return {
|
|
156
|
+
canRender: true,
|
|
157
|
+
action: "override" /* Override */,
|
|
158
|
+
nextClaim: { stateRenderId, runId, messageIndex },
|
|
159
|
+
lockOthers: isPlaceholderMessageId(claimedMessageId)
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
if (isPlaceholderMessageId(claimedMessageId)) {
|
|
163
|
+
return {
|
|
164
|
+
canRender: true,
|
|
165
|
+
action: "override" /* Override */,
|
|
166
|
+
nextClaim: { stateRenderId, runId, messageIndex },
|
|
167
|
+
lockOthers: true
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
if (stateSnapshot && renderClaimedByOtherMessage.stateSnapshot && !areStatesEquals(renderClaimedByOtherMessage.stateSnapshot, stateSnapshot)) {
|
|
171
|
+
return {
|
|
172
|
+
canRender: true,
|
|
173
|
+
action: "override" /* Override */,
|
|
174
|
+
nextClaim: { stateRenderId, runId }
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
return { canRender: false, action: "block" /* Block */ };
|
|
178
|
+
}
|
|
179
|
+
if (!runId) {
|
|
180
|
+
return { canRender: false, action: "block" /* Block */ };
|
|
181
|
+
}
|
|
182
|
+
return {
|
|
183
|
+
canRender: true,
|
|
184
|
+
action: "create" /* Create */,
|
|
185
|
+
nextClaim: { stateRenderId, runId, messageIndex }
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
function selectSnapshot({
|
|
189
|
+
messageId,
|
|
190
|
+
messageName,
|
|
191
|
+
allowLiveState,
|
|
192
|
+
skipLatestCache,
|
|
193
|
+
stateRenderId,
|
|
194
|
+
effectiveRunId,
|
|
195
|
+
stateSnapshotProp,
|
|
196
|
+
agentState,
|
|
197
|
+
agentMessages,
|
|
198
|
+
existingClaim,
|
|
199
|
+
caches
|
|
200
|
+
}) {
|
|
201
|
+
var _a, _b, _c, _d, _e, _f;
|
|
202
|
+
const lastAssistantId = agentMessages ? (_a = [...agentMessages].reverse().find((msg) => msg.role === "assistant")) == null ? void 0 : _a.id : void 0;
|
|
203
|
+
const latestSnapshot = stateRenderId !== void 0 ? caches.byStateRenderAndRun[`${stateRenderId}::latest`] : void 0;
|
|
204
|
+
const messageIndex = agentMessages ? agentMessages.findIndex((msg) => msg.id === messageId) : -1;
|
|
205
|
+
const messageRole = messageIndex >= 0 && agentMessages ? (_b = agentMessages[messageIndex]) == null ? void 0 : _b.role : void 0;
|
|
206
|
+
let previousUserMessageId;
|
|
207
|
+
if (messageIndex > 0 && agentMessages) {
|
|
208
|
+
for (let i = messageIndex - 1; i >= 0; i -= 1) {
|
|
209
|
+
if (((_c = agentMessages[i]) == null ? void 0 : _c.role) === "user") {
|
|
210
|
+
previousUserMessageId = (_d = agentMessages[i]) == null ? void 0 : _d.id;
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
const liveStateIsStale = stateSnapshotProp === void 0 && latestSnapshot !== void 0 && agentState !== void 0 && areStatesEquals(latestSnapshot, agentState);
|
|
216
|
+
const shouldUseLiveState = (Boolean(allowLiveState) || !lastAssistantId || messageId === lastAssistantId) && !liveStateIsStale;
|
|
217
|
+
const snapshot = stateSnapshotProp ? (0, import_shared.parseJson)(stateSnapshotProp, stateSnapshotProp) : shouldUseLiveState ? agentState : void 0;
|
|
218
|
+
const hasSnapshotKeys = !!(snapshot && Object.keys(snapshot).length > 0);
|
|
219
|
+
const allowEmptySnapshot = snapshot !== void 0 && !hasSnapshotKeys && (stateSnapshotProp !== void 0 || shouldUseLiveState);
|
|
220
|
+
const messageCacheEntry = caches.byMessageId[messageId];
|
|
221
|
+
const cachedMessageSnapshot = readCachedMessageEntry(messageCacheEntry).snapshot;
|
|
222
|
+
const cacheKey = stateRenderId !== void 0 ? `${stateRenderId}::${effectiveRunId}` : void 0;
|
|
223
|
+
let cachedSnapshot = cachedMessageSnapshot != null ? cachedMessageSnapshot : caches.byMessageId[messageId];
|
|
224
|
+
if (cachedSnapshot === void 0 && cacheKey && caches.byStateRenderAndRun[cacheKey] !== void 0) {
|
|
225
|
+
cachedSnapshot = caches.byStateRenderAndRun[cacheKey];
|
|
226
|
+
}
|
|
227
|
+
if (cachedSnapshot === void 0 && stateRenderId && previousUserMessageId && caches.byStateRenderAndRun[`${stateRenderId}::pending:${previousUserMessageId}`] !== void 0) {
|
|
228
|
+
cachedSnapshot = caches.byStateRenderAndRun[`${stateRenderId}::pending:${previousUserMessageId}`];
|
|
229
|
+
}
|
|
230
|
+
if (cachedSnapshot === void 0 && !skipLatestCache && stateRenderId && messageRole !== "assistant" && (stateSnapshotProp !== void 0 || agentState && Object.keys(agentState).length > 0)) {
|
|
231
|
+
cachedSnapshot = caches.byStateRenderAndRun[`${stateRenderId}::latest`];
|
|
232
|
+
}
|
|
233
|
+
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;
|
|
234
|
+
return { snapshot, hasSnapshotKeys, cachedSnapshot, allowEmptySnapshot, snapshotForClaim };
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// src/hooks/use-coagent-state-render-registry.ts
|
|
238
|
+
var import_react2 = require("react");
|
|
239
|
+
var LAST_SNAPSHOTS_BY_RENDER_AND_RUN = "__lastSnapshotsByStateRenderIdAndRun";
|
|
240
|
+
var LAST_SNAPSHOTS_BY_MESSAGE = "__lastSnapshotsByMessageId";
|
|
241
|
+
function getClaimsStore(claimsRef) {
|
|
242
|
+
return claimsRef.current;
|
|
243
|
+
}
|
|
244
|
+
function getSnapshotCaches(claimsRef) {
|
|
245
|
+
var _a, _b;
|
|
246
|
+
const store = getClaimsStore(claimsRef);
|
|
247
|
+
return {
|
|
248
|
+
byStateRenderAndRun: (_a = store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN]) != null ? _a : {},
|
|
249
|
+
byMessageId: (_b = store[LAST_SNAPSHOTS_BY_MESSAGE]) != null ? _b : {}
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
function useStateRenderRegistry({
|
|
253
|
+
agentId,
|
|
254
|
+
stateRenderId,
|
|
255
|
+
message,
|
|
256
|
+
messageIndex,
|
|
257
|
+
stateSnapshot,
|
|
258
|
+
agentState,
|
|
259
|
+
agentMessages,
|
|
260
|
+
claimsRef
|
|
261
|
+
}) {
|
|
262
|
+
var _a, _b, _c, _d, _e, _f;
|
|
263
|
+
const store = getClaimsStore(claimsRef);
|
|
264
|
+
const runId = message.runId;
|
|
265
|
+
const cachedMessageEntry = (_a = store[LAST_SNAPSHOTS_BY_MESSAGE]) == null ? void 0 : _a[message.id];
|
|
266
|
+
const { runId: cachedMessageRunId } = readCachedMessageEntry(cachedMessageEntry);
|
|
267
|
+
const existingClaimRunId = (_b = claimsRef.current[message.id]) == null ? void 0 : _b.runId;
|
|
268
|
+
const effectiveRunId = getEffectiveRunId({
|
|
269
|
+
existingClaimRunId,
|
|
270
|
+
cachedMessageRunId,
|
|
271
|
+
runId
|
|
272
|
+
});
|
|
273
|
+
(0, import_react2.useEffect)(() => {
|
|
274
|
+
return () => {
|
|
275
|
+
var _a2, _b2, _c2, _d2;
|
|
276
|
+
const existingClaim2 = claimsRef.current[message.id];
|
|
277
|
+
if ((existingClaim2 == null ? void 0 : existingClaim2.stateSnapshot) && Object.keys(existingClaim2.stateSnapshot).length > 0) {
|
|
278
|
+
const snapshotCache = __spreadValues({}, (_a2 = store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN]) != null ? _a2 : {});
|
|
279
|
+
const cacheKey = `${existingClaim2.stateRenderId}::${(_b2 = existingClaim2.runId) != null ? _b2 : "pending"}`;
|
|
280
|
+
snapshotCache[cacheKey] = existingClaim2.stateSnapshot;
|
|
281
|
+
snapshotCache[`${existingClaim2.stateRenderId}::latest`] = existingClaim2.stateSnapshot;
|
|
282
|
+
store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN] = snapshotCache;
|
|
283
|
+
const messageCache = __spreadValues({}, (_c2 = store[LAST_SNAPSHOTS_BY_MESSAGE]) != null ? _c2 : {});
|
|
284
|
+
messageCache[message.id] = {
|
|
285
|
+
snapshot: existingClaim2.stateSnapshot,
|
|
286
|
+
runId: (_d2 = existingClaim2.runId) != null ? _d2 : effectiveRunId
|
|
287
|
+
};
|
|
288
|
+
store[LAST_SNAPSHOTS_BY_MESSAGE] = messageCache;
|
|
289
|
+
}
|
|
290
|
+
delete claimsRef.current[message.id];
|
|
291
|
+
};
|
|
292
|
+
}, [claimsRef, effectiveRunId, message.id]);
|
|
293
|
+
if (!stateRenderId) {
|
|
294
|
+
return { canRender: false };
|
|
295
|
+
}
|
|
296
|
+
const caches = getSnapshotCaches(claimsRef);
|
|
297
|
+
const existingClaim = claimsRef.current[message.id];
|
|
298
|
+
const { snapshot, hasSnapshotKeys, allowEmptySnapshot, snapshotForClaim } = selectSnapshot({
|
|
299
|
+
messageId: message.id,
|
|
300
|
+
messageName: message.name,
|
|
301
|
+
allowLiveState: isPlaceholderMessageName(message.name) || isPlaceholderMessageId(message.id),
|
|
302
|
+
skipLatestCache: isPlaceholderMessageName(message.name) || isPlaceholderMessageId(message.id),
|
|
303
|
+
stateRenderId,
|
|
304
|
+
effectiveRunId,
|
|
305
|
+
stateSnapshotProp: stateSnapshot,
|
|
306
|
+
agentState,
|
|
307
|
+
agentMessages,
|
|
308
|
+
existingClaim,
|
|
309
|
+
caches
|
|
310
|
+
});
|
|
311
|
+
const resolution = resolveClaim({
|
|
312
|
+
claims: claimsRef.current,
|
|
313
|
+
context: {
|
|
314
|
+
agentId,
|
|
315
|
+
messageId: message.id,
|
|
316
|
+
stateRenderId,
|
|
317
|
+
runId: effectiveRunId,
|
|
318
|
+
messageIndex
|
|
319
|
+
},
|
|
320
|
+
stateSnapshot: snapshotForClaim
|
|
321
|
+
});
|
|
322
|
+
if (resolution.action === "block" /* Block */) {
|
|
323
|
+
return { canRender: false };
|
|
324
|
+
}
|
|
325
|
+
if (resolution.updateRunId && claimsRef.current[message.id]) {
|
|
326
|
+
claimsRef.current[message.id].runId = resolution.updateRunId;
|
|
327
|
+
}
|
|
328
|
+
if (resolution.nextClaim) {
|
|
329
|
+
claimsRef.current[message.id] = resolution.nextClaim;
|
|
330
|
+
}
|
|
331
|
+
if (resolution.lockOthers) {
|
|
332
|
+
Object.entries(claimsRef.current).forEach(([id, claim]) => {
|
|
333
|
+
if (id !== message.id && claim.stateRenderId === stateRenderId) {
|
|
334
|
+
claim.locked = true;
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
if (existingClaim && !existingClaim.locked && (agentMessages == null ? void 0 : agentMessages.length)) {
|
|
339
|
+
const indexInAgentMessages = agentMessages.findIndex((msg) => msg.id === message.id);
|
|
340
|
+
if (indexInAgentMessages >= 0 && indexInAgentMessages < agentMessages.length - 1) {
|
|
341
|
+
existingClaim.locked = true;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
const existingSnapshot = claimsRef.current[message.id].stateSnapshot;
|
|
345
|
+
const snapshotChanged = stateSnapshot && existingSnapshot !== void 0 && !areStatesEquals(existingSnapshot, snapshot);
|
|
346
|
+
if (snapshot && (stateSnapshot || hasSnapshotKeys || allowEmptySnapshot) && (!claimsRef.current[message.id].locked || snapshotChanged)) {
|
|
347
|
+
if (!claimsRef.current[message.id].locked || snapshotChanged) {
|
|
348
|
+
claimsRef.current[message.id].stateSnapshot = snapshot;
|
|
349
|
+
const snapshotCache = __spreadValues({}, (_c = store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN]) != null ? _c : {});
|
|
350
|
+
const cacheKey = `${stateRenderId}::${effectiveRunId}`;
|
|
351
|
+
snapshotCache[cacheKey] = snapshot;
|
|
352
|
+
snapshotCache[`${stateRenderId}::latest`] = snapshot;
|
|
353
|
+
store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN] = snapshotCache;
|
|
354
|
+
const messageCache = __spreadValues({}, (_d = store[LAST_SNAPSHOTS_BY_MESSAGE]) != null ? _d : {});
|
|
355
|
+
messageCache[message.id] = { snapshot, runId: effectiveRunId };
|
|
356
|
+
store[LAST_SNAPSHOTS_BY_MESSAGE] = messageCache;
|
|
357
|
+
if (stateSnapshot) {
|
|
358
|
+
claimsRef.current[message.id].locked = true;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
} else if (snapshotForClaim) {
|
|
362
|
+
const existingSnapshot2 = claimsRef.current[message.id].stateSnapshot;
|
|
363
|
+
if (!existingSnapshot2) {
|
|
364
|
+
claimsRef.current[message.id].stateSnapshot = snapshotForClaim;
|
|
365
|
+
const snapshotCache = __spreadValues({}, (_e = store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN]) != null ? _e : {});
|
|
366
|
+
const cacheKey = `${stateRenderId}::${effectiveRunId}`;
|
|
367
|
+
snapshotCache[cacheKey] = snapshotForClaim;
|
|
368
|
+
snapshotCache[`${stateRenderId}::latest`] = snapshotForClaim;
|
|
369
|
+
store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN] = snapshotCache;
|
|
370
|
+
const messageCache = __spreadValues({}, (_f = store[LAST_SNAPSHOTS_BY_MESSAGE]) != null ? _f : {});
|
|
371
|
+
messageCache[message.id] = { snapshot: snapshotForClaim, runId: effectiveRunId };
|
|
372
|
+
store[LAST_SNAPSHOTS_BY_MESSAGE] = messageCache;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
return { canRender: true };
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
// src/hooks/use-coagent-state-render-bridge.tsx
|
|
81
379
|
function useCoagentStateRenderBridge(agentId, props) {
|
|
82
380
|
var _a;
|
|
83
|
-
const { stateSnapshot,
|
|
381
|
+
const { stateSnapshot, message } = props;
|
|
84
382
|
const { coAgentStateRenders, claimsRef } = useCoAgentStateRenders();
|
|
85
|
-
const { agent } = (0,
|
|
86
|
-
const [nodeName, setNodeName] = (0,
|
|
87
|
-
const [, forceUpdate] = (0,
|
|
88
|
-
|
|
89
|
-
const effectiveRunId = runId || "pending";
|
|
90
|
-
(0, import_react3.useEffect)(() => {
|
|
383
|
+
const { agent } = (0, import_react3.useAgent)({ agentId });
|
|
384
|
+
const [nodeName, setNodeName] = (0, import_react4.useState)(void 0);
|
|
385
|
+
const [, forceUpdate] = (0, import_react4.useState)(0);
|
|
386
|
+
(0, import_react4.useEffect)(() => {
|
|
91
387
|
if (!agent)
|
|
92
388
|
return;
|
|
93
389
|
const subscriber = {
|
|
@@ -110,103 +406,69 @@ function useCoagentStateRenderBridge(agentId, props) {
|
|
|
110
406
|
unsubscribe();
|
|
111
407
|
};
|
|
112
408
|
}, [agentId, nodeName]);
|
|
113
|
-
const getStateRender = (0,
|
|
409
|
+
const getStateRender = (0, import_react4.useCallback)(
|
|
114
410
|
(messageId) => {
|
|
115
|
-
return Object.entries(coAgentStateRenders).find(([
|
|
411
|
+
return Object.entries(coAgentStateRenders).find(([stateRenderId2, stateRender2]) => {
|
|
116
412
|
if (claimsRef.current[messageId]) {
|
|
117
|
-
return
|
|
413
|
+
return stateRenderId2 === claimsRef.current[messageId].stateRenderId;
|
|
118
414
|
}
|
|
119
|
-
const matchingAgentName =
|
|
120
|
-
const matchesNodeContext =
|
|
415
|
+
const matchingAgentName = stateRender2.name === agentId;
|
|
416
|
+
const matchesNodeContext = stateRender2.nodeName ? stateRender2.nodeName === nodeName : true;
|
|
121
417
|
return matchingAgentName && matchesNodeContext;
|
|
122
418
|
});
|
|
123
419
|
},
|
|
124
420
|
[coAgentStateRenders, nodeName, agentId]
|
|
125
421
|
);
|
|
126
|
-
const
|
|
422
|
+
const stateRenderEntry = (0, import_react4.useMemo)(() => getStateRender(message.id), [getStateRender, message.id]);
|
|
423
|
+
const stateRenderId = stateRenderEntry == null ? void 0 : stateRenderEntry[0];
|
|
424
|
+
const stateRender = stateRenderEntry == null ? void 0 : stateRenderEntry[1];
|
|
425
|
+
const registryMessage = __spreadProps(__spreadValues({}, message), {
|
|
426
|
+
runId: (_a = props.runId) != null ? _a : message.runId
|
|
427
|
+
});
|
|
428
|
+
const { canRender } = useStateRenderRegistry({
|
|
429
|
+
agentId,
|
|
127
430
|
stateRenderId,
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
stateSnapshot
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
return canRender;
|
|
138
|
-
}
|
|
139
|
-
const renderClaimedByOtherMessage = Object.values(claimsRef.current).find(
|
|
140
|
-
(c) => c.stateRenderId === stateRenderId && (0, import_shared.dataToUUID)(getStateWithoutConstantKeys(c.stateSnapshot)) === (0, import_shared.dataToUUID)(getStateWithoutConstantKeys(renderSnapshot))
|
|
141
|
-
);
|
|
142
|
-
if (renderClaimedByOtherMessage) {
|
|
143
|
-
if (renderSnapshot && renderClaimedByOtherMessage.stateSnapshot && !areStatesEquals(renderClaimedByOtherMessage.stateSnapshot, renderSnapshot)) {
|
|
144
|
-
claimsRef.current[messageId] = { stateRenderId, runId: runId2 };
|
|
145
|
-
return true;
|
|
146
|
-
}
|
|
147
|
-
return false;
|
|
148
|
-
}
|
|
149
|
-
if (!runId2) {
|
|
150
|
-
return false;
|
|
151
|
-
}
|
|
152
|
-
claimsRef.current[messageId] = { stateRenderId, runId: runId2 };
|
|
153
|
-
return true;
|
|
154
|
-
};
|
|
155
|
-
return (0, import_react3.useMemo)(() => {
|
|
156
|
-
var _a2, _b, _c;
|
|
157
|
-
if (messageIndexInRun !== 0) {
|
|
158
|
-
return null;
|
|
159
|
-
}
|
|
160
|
-
const [stateRenderId, stateRender] = (_a2 = getStateRender(message.id)) != null ? _a2 : [];
|
|
431
|
+
message: registryMessage,
|
|
432
|
+
messageIndex: props.messageIndex,
|
|
433
|
+
stateSnapshot,
|
|
434
|
+
agentState: agent == null ? void 0 : agent.state,
|
|
435
|
+
agentMessages: agent == null ? void 0 : agent.messages,
|
|
436
|
+
claimsRef
|
|
437
|
+
});
|
|
438
|
+
return (0, import_react4.useMemo)(() => {
|
|
439
|
+
var _a2, _b;
|
|
161
440
|
if (!stateRender || !stateRenderId) {
|
|
162
441
|
return null;
|
|
163
442
|
}
|
|
164
|
-
const snapshot = stateSnapshot ? (0, import_shared.parseJson)(stateSnapshot, stateSnapshot) : agent == null ? void 0 : agent.state;
|
|
165
|
-
const canRender = handleRenderRequest({
|
|
166
|
-
stateRenderId,
|
|
167
|
-
messageId: message.id,
|
|
168
|
-
runId: effectiveRunId,
|
|
169
|
-
stateSnapshot: snapshot
|
|
170
|
-
});
|
|
171
443
|
if (!canRender) {
|
|
172
444
|
return null;
|
|
173
445
|
}
|
|
174
|
-
if (snapshot) {
|
|
175
|
-
const existingSnapshot = claimsRef.current[message.id].stateSnapshot;
|
|
176
|
-
const snapshotChanged = stateSnapshot && existingSnapshot !== void 0 && !areStatesEquals(existingSnapshot, snapshot);
|
|
177
|
-
if (!claimsRef.current[message.id].locked || snapshotChanged) {
|
|
178
|
-
claimsRef.current[message.id].stateSnapshot = snapshot;
|
|
179
|
-
if (stateSnapshot) {
|
|
180
|
-
claimsRef.current[message.id].locked = true;
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
446
|
if (stateRender.handler) {
|
|
185
447
|
stateRender.handler({
|
|
186
|
-
state: stateSnapshot ? (0,
|
|
448
|
+
state: stateSnapshot ? (0, import_shared2.parseJson)(stateSnapshot, stateSnapshot) : (_a2 = agent == null ? void 0 : agent.state) != null ? _a2 : {},
|
|
187
449
|
nodeName: nodeName != null ? nodeName : ""
|
|
188
450
|
});
|
|
189
451
|
}
|
|
190
452
|
if (stateRender.render) {
|
|
191
|
-
const status = (agent == null ? void 0 : agent.isRunning) ? "inProgress" : "complete"
|
|
453
|
+
const status = (agent == null ? void 0 : agent.isRunning) ? "inProgress" /* InProgress */ : "complete" /* Complete */;
|
|
192
454
|
if (typeof stateRender.render === "string")
|
|
193
455
|
return stateRender.render;
|
|
194
456
|
return stateRender.render({
|
|
195
457
|
status,
|
|
196
458
|
// Always use state from claim, to make sure the state does not seem "wiped" for a fraction of a second
|
|
197
|
-
state: (
|
|
459
|
+
state: (_b = claimsRef.current[message.id].stateSnapshot) != null ? _b : {},
|
|
198
460
|
nodeName: nodeName != null ? nodeName : ""
|
|
199
461
|
});
|
|
200
462
|
}
|
|
201
463
|
}, [
|
|
202
|
-
|
|
203
|
-
|
|
464
|
+
stateRender,
|
|
465
|
+
stateRenderId,
|
|
204
466
|
agent == null ? void 0 : agent.state,
|
|
205
467
|
agent == null ? void 0 : agent.isRunning,
|
|
206
468
|
nodeName,
|
|
207
|
-
effectiveRunId,
|
|
208
469
|
message.id,
|
|
209
|
-
|
|
470
|
+
stateSnapshot,
|
|
471
|
+
canRender
|
|
210
472
|
]);
|
|
211
473
|
}
|
|
212
474
|
function CoAgentStateRenderBridge(props) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hooks/use-coagent-state-render-bridge.tsx","../../src/context/coagent-state-renders-context.tsx"],"sourcesContent":["import { ReactCustomMessageRendererPosition, useAgent } from \"@copilotkitnext/react\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport type { AgentSubscriber } from \"@ag-ui/client\";\nimport { useCoAgentStateRenders } from \"../context\";\nimport { dataToUUID, parseJson } from \"@copilotkit/shared\";\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\nfunction 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\n/**\n * Bridge hook that connects agent state renders to chat messages.\n *\n * ## Purpose\n * This hook finds matching state render configurations (registered via useCoAgentStateRender)\n * and returns UI to render in chat.\n * It ensures each state render appears bound to a specific message, preventing duplicates while\n * allowing re-binding when the underlying state changes significantly.\n *\n * ## Message-ID-Based Claiming System\n *\n * ### The Problem\n * Multiple bridge component instances render simultaneously (one per message). Without coordination,\n * they would all try to render the same state render, causing duplicates.\n *\n * ### The Solution: Message-ID Claims with State Comparison\n * Each state render is \"claimed\" by exactly one **message ID** (not runId):\n *\n * **Claim Structure**: `claimsRef.current[messageId] = { stateRenderId, runId, stateSnapshot, locked }`\n *\n * **Primary binding is by messageId because**:\n * - runId is not always available immediately (starts as \"pending\")\n * - messageId is the stable identifier throughout the message lifecycle\n * - Claims persist across component remounts via context ref\n *\n * ### Claiming Logic Flow\n *\n * 1. **Message already has a claim**:\n * - Check if the claim matches the current stateRenderId\n * - If yes → render (this message owns this render)\n * - Update runId if it was \"pending\" and now available\n *\n * 2. **State render claimed by another message**:\n * - Compare state snapshots (ignoring constant keys: messages, tools, copilotkit)\n * - If states are identical → block rendering (duplicate)\n * - **If states are different → allow claiming** (new data, new message)\n * - This handles cases where the same render type shows different states in different messages\n *\n * 3. **Unclaimed state render**:\n * - Only allow claiming if runId is \"pending\" (initial render)\n * - If runId is real but no claim exists → block (edge case protection)\n * - Create new claim: `claimsRef.current[messageId] = { stateRenderId, runId }`\n *\n * ### State Snapshot Locking\n *\n * Once a state snapshot is captured and locked for a message:\n * - The UI always renders with the locked snapshot (not live agent.state)\n * - Prevents UI from appearing \"wiped\" during state transitions\n * - Locked when: stateSnapshot prop is available (from message persistence)\n * - Unlocked state: can still update from live agent.state\n *\n * ### Synchronous Claiming (Ref-based)\n *\n * Claims are stored in a context-level ref (not React state):\n * - Multiple bridges render in the same tick\n * - State updates are async - would allow duplicates before update completes\n * - Ref provides immediate, synchronous claim checking\n * - Survives component remounts (stored in context, not component)\n *\n * ## Flow Example\n *\n * ```\n * Time 1: Message A renders, runId=undefined, state={progress: 50%}\n * → effectiveRunId = \"pending\"\n * → Claims: claimsRef[\"msgA\"] = { stateRenderId: \"tasks\", runId: \"pending\", stateSnapshot: {progress: 50%} }\n * → Renders UI with 50% progress\n *\n * Time 2: Message B renders, runId=undefined, same state\n * → Checks: \"tasks\" already claimed by msgA with same state\n * → Returns null (blocked - duplicate)\n *\n * Time 3: Real runId appears (e.g., \"run-123\")\n * → Updates claim: claimsRef[\"msgA\"].runId = \"run-123\"\n * → Message A continues rendering\n *\n * Time 4: Agent processes more, state={progress: 100%}\n * → Message A: locked to 50% (stateSnapshot locked)\n * → Message C renders with state={progress: 100%}\n * → Checks: \"tasks\" claimed by msgA but state is DIFFERENT (50% vs 100%)\n * → Allows new claim: claimsRef[\"msgC\"] = { stateRenderId: \"tasks\", runId: \"run-123\", stateSnapshot: {progress: 100%} }\n * → Both messages render independently with their own snapshots\n * ```\n */\nexport interface CoAgentStateRenderBridgeProps {\n message: any;\n position: ReactCustomMessageRendererPosition;\n runId: string;\n messageIndex: number;\n messageIndexInRun: number;\n numberOfMessagesInRun: number;\n agentId: string;\n stateSnapshot: any;\n}\n\nexport function useCoagentStateRenderBridge(agentId: string, props: CoAgentStateRenderBridgeProps) {\n const { stateSnapshot, messageIndexInRun, message } = props;\n const { coAgentStateRenders, claimsRef } = useCoAgentStateRenders();\n const { agent } = useAgent({ agentId });\n const [nodeName, setNodeName] = useState<string | undefined>(undefined);\n const [, forceUpdate] = useState(0);\n\n const runId = props.runId ?? message.runId;\n const effectiveRunId = runId || \"pending\";\n\n useEffect(() => {\n if (!agent) return;\n const subscriber: AgentSubscriber = {\n onStateChanged: () => {\n forceUpdate((value) => value + 1);\n },\n onStepStartedEvent: ({ event }) => {\n if (event.stepName !== nodeName) {\n setNodeName(event.stepName);\n }\n },\n onStepFinishedEvent: ({ event }) => {\n if (event.stepName === nodeName) {\n setNodeName(undefined);\n }\n },\n };\n\n const { unsubscribe } = agent.subscribe(subscriber);\n return () => {\n unsubscribe();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [agentId, nodeName]);\n\n const getStateRender = useCallback(\n (messageId: string) => {\n return Object.entries(coAgentStateRenders).find(([stateRenderId, stateRender]) => {\n if (claimsRef.current[messageId]) {\n return stateRenderId === claimsRef.current[messageId].stateRenderId;\n }\n const matchingAgentName = stateRender.name === agentId;\n const matchesNodeContext = stateRender.nodeName ? stateRender.nodeName === nodeName : true;\n return matchingAgentName && matchesNodeContext;\n });\n },\n [coAgentStateRenders, nodeName, agentId],\n );\n\n // Message ID-based claim system - A state render can only be claimed by one message ID\n const handleRenderRequest = ({\n stateRenderId,\n messageId,\n runId,\n stateSnapshot: renderSnapshot,\n }: {\n stateRenderId: string;\n messageId: string;\n runId?: string;\n stateSnapshot?: any;\n }): boolean => {\n // Check if this message has already claimed this state render\n if (claimsRef.current[messageId]) {\n const canRender = claimsRef.current[messageId].stateRenderId === stateRenderId;\n\n // Update runId if it doesn't exist\n if (\n canRender &&\n runId &&\n (!claimsRef.current[messageId].runId || claimsRef.current[messageId].runId === \"pending\")\n ) {\n claimsRef.current[messageId].runId = runId;\n }\n\n return canRender;\n }\n\n // Do not allow render if any other message has claimed this state render\n const renderClaimedByOtherMessage = Object.values(claimsRef.current).find(\n (c) =>\n c.stateRenderId === stateRenderId &&\n dataToUUID(getStateWithoutConstantKeys(c.stateSnapshot)) ===\n dataToUUID(getStateWithoutConstantKeys(renderSnapshot)),\n );\n if (renderClaimedByOtherMessage) {\n // If:\n // - state render already claimed\n // - snapshot exists in the claiming object and is different from current,\n if (\n renderSnapshot &&\n renderClaimedByOtherMessage.stateSnapshot &&\n !areStatesEquals(renderClaimedByOtherMessage.stateSnapshot, renderSnapshot)\n ) {\n claimsRef.current[messageId] = { stateRenderId, runId };\n return true;\n }\n return false;\n }\n\n // No existing claim anywhere yet – allow this message to claim even if we already know the runId.\n if (!runId) {\n return false;\n }\n\n claimsRef.current[messageId] = { stateRenderId, runId };\n return true;\n };\n\n return useMemo(() => {\n if (messageIndexInRun !== 0) {\n return null;\n }\n\n const [stateRenderId, stateRender] = getStateRender(message.id) ?? [];\n\n if (!stateRender || !stateRenderId) {\n return null;\n }\n\n // Is there any state we can use?\n const snapshot = stateSnapshot ? parseJson(stateSnapshot, stateSnapshot) : agent?.state;\n\n // Synchronously check/claim - returns true if this message can render\n const canRender = handleRenderRequest({\n stateRenderId,\n messageId: message.id,\n runId: effectiveRunId,\n stateSnapshot: snapshot,\n });\n if (!canRender) {\n return null;\n }\n\n // If we found state, and given that now there's a claim for the current message, let's save it in the claim\n if (snapshot) {\n const existingSnapshot = claimsRef.current[message.id].stateSnapshot;\n const snapshotChanged =\n stateSnapshot &&\n existingSnapshot !== undefined &&\n !areStatesEquals(existingSnapshot, snapshot);\n\n if (!claimsRef.current[message.id].locked || snapshotChanged) {\n claimsRef.current[message.id].stateSnapshot = snapshot;\n if (stateSnapshot) {\n claimsRef.current[message.id].locked = true;\n }\n }\n }\n\n if (stateRender.handler) {\n stateRender.handler({\n state: stateSnapshot ? parseJson(stateSnapshot, stateSnapshot) : (agent?.state ?? {}),\n nodeName: nodeName ?? \"\",\n });\n }\n\n if (stateRender.render) {\n const status = agent?.isRunning ? \"inProgress\" : \"complete\";\n\n if (typeof stateRender.render === \"string\") return stateRender.render;\n\n return stateRender.render({\n status,\n // Always use state from claim, to make sure the state does not seem \"wiped\" for a fraction of a second\n state: claimsRef.current[message.id].stateSnapshot ?? {},\n nodeName: nodeName ?? \"\",\n });\n }\n }, [\n getStateRender,\n stateSnapshot,\n agent?.state,\n agent?.isRunning,\n nodeName,\n effectiveRunId,\n message.id,\n messageIndexInRun,\n ]);\n}\n\nexport function CoAgentStateRenderBridge(props: CoAgentStateRenderBridgeProps) {\n return useCoagentStateRenderBridge(props.agentId, props);\n}\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","runId","_a"]}
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/use-coagent-state-render-bridge.tsx","../../src/context/coagent-state-renders-context.tsx","../../src/hooks/use-coagent-state-render-bridge.helpers.ts","../../src/hooks/use-coagent-state-render-registry.ts"],"sourcesContent":["import { ReactCustomMessageRendererPosition, useAgent } from \"@copilotkitnext/react\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport type { AgentSubscriber } from \"@ag-ui/client\";\nimport { useCoAgentStateRenders } from \"../context\";\nimport { parseJson } from \"@copilotkit/shared\";\nimport { RenderStatus } from \"./use-coagent-state-render-bridge.helpers\";\nimport { useStateRenderRegistry } from \"./use-coagent-state-render-registry\";\n\n/**\n * Bridge hook that connects agent state renders to chat messages.\n *\n * ## Purpose\n * This hook finds matching state render configurations (registered via useCoAgentStateRender)\n * and returns UI to render in chat.\n * It ensures each state render appears bound to a specific message, preventing duplicates while\n * allowing re-binding when the underlying state changes significantly.\n *\n * ## Message-ID-Based Claiming System\n *\n * ### The Problem\n * Multiple bridge component instances render simultaneously (one per message). Without coordination,\n * they would all try to render the same state render, causing duplicates.\n *\n * ### The Solution: Message-ID Claims with State Comparison\n * Each state render is \"claimed\" by exactly one **message ID** (not runId):\n *\n * **Claim Structure**: `claimsRef.current[messageId] = { stateRenderId, runId, stateSnapshot, locked }`\n *\n * **Primary binding is by messageId because**:\n * - runId is not always available immediately (starts as \"pending\")\n * - messageId is the stable identifier throughout the message lifecycle\n * - Claims persist across component remounts via context ref\n *\n * ### Claiming Logic Flow\n *\n * 1. **Message already has a claim**:\n * - Check if the claim matches the current stateRenderId\n * - If yes → render (this message owns this render)\n * - Update runId if it was \"pending\" and now available\n *\n * 2. **State render claimed by another message**:\n * - Compare state snapshots (ignoring constant keys: messages, tools, copilotkit)\n * - If states are identical → block rendering (duplicate)\n * - **If states are different → allow claiming** (new data, new message)\n * - This handles cases where the same render type shows different states in different messages\n *\n * 3. **Unclaimed state render**:\n * - Only allow claiming if runId is \"pending\" (initial render)\n * - If runId is real but no claim exists → block (edge case protection)\n * - Create new claim: `claimsRef.current[messageId] = { stateRenderId, runId }`\n *\n * ### State Snapshot Locking\n *\n * Once a state snapshot is captured and locked for a message:\n * - The UI always renders with the locked snapshot (not live agent.state)\n * - Prevents UI from appearing \"wiped\" during state transitions\n * - Locked when: stateSnapshot prop is available (from message persistence)\n * - Unlocked state: can still update from live agent.state\n *\n * ### Synchronous Claiming (Ref-based)\n *\n * Claims are stored in a context-level ref (not React state):\n * - Multiple bridges render in the same tick\n * - State updates are async - would allow duplicates before update completes\n * - Ref provides immediate, synchronous claim checking\n * - Survives component remounts (stored in context, not component)\n *\n * ## Flow Example\n *\n * ```\n * Time 1: Message A renders, runId=undefined, state={progress: 50%}\n * → effectiveRunId = \"pending\"\n * → Claims: claimsRef[\"msgA\"] = { stateRenderId: \"tasks\", runId: \"pending\", stateSnapshot: {progress: 50%} }\n * → Renders UI with 50% progress\n *\n * Time 2: Message B renders, runId=undefined, same state\n * → Checks: \"tasks\" already claimed by msgA with same state\n * → Returns null (blocked - duplicate)\n *\n * Time 3: Real runId appears (e.g., \"run-123\")\n * → Updates claim: claimsRef[\"msgA\"].runId = \"run-123\"\n * → Message A continues rendering\n *\n * Time 4: Agent processes more, state={progress: 100%}\n * → Message A: locked to 50% (stateSnapshot locked)\n * → Message C renders with state={progress: 100%}\n * → Checks: \"tasks\" claimed by msgA but state is DIFFERENT (50% vs 100%)\n * → Allows new claim: claimsRef[\"msgC\"] = { stateRenderId: \"tasks\", runId: \"run-123\", stateSnapshot: {progress: 100%} }\n * → Both messages render independently with their own snapshots\n * ```\n */\nexport interface CoAgentStateRenderBridgeProps {\n message: any;\n position: ReactCustomMessageRendererPosition;\n runId: string;\n messageIndex: number;\n messageIndexInRun: number;\n numberOfMessagesInRun: number;\n agentId: string;\n stateSnapshot: any;\n}\n\nexport function useCoagentStateRenderBridge(agentId: string, props: CoAgentStateRenderBridgeProps) {\n const { stateSnapshot, message } = props;\n const { coAgentStateRenders, claimsRef } = useCoAgentStateRenders();\n const { agent } = useAgent({ agentId });\n const [nodeName, setNodeName] = useState<string | undefined>(undefined);\n const [, forceUpdate] = useState(0);\n\n useEffect(() => {\n if (!agent) return;\n const subscriber: AgentSubscriber = {\n onStateChanged: () => {\n forceUpdate((value) => value + 1);\n },\n onStepStartedEvent: ({ event }) => {\n if (event.stepName !== nodeName) {\n setNodeName(event.stepName);\n }\n },\n onStepFinishedEvent: ({ event }) => {\n if (event.stepName === nodeName) {\n setNodeName(undefined);\n }\n },\n };\n\n const { unsubscribe } = agent.subscribe(subscriber);\n return () => {\n unsubscribe();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [agentId, nodeName]);\n\n const getStateRender = useCallback(\n (messageId: string) => {\n return Object.entries(coAgentStateRenders).find(([stateRenderId, stateRender]) => {\n if (claimsRef.current[messageId]) {\n return stateRenderId === claimsRef.current[messageId].stateRenderId;\n }\n const matchingAgentName = stateRender.name === agentId;\n const matchesNodeContext = stateRender.nodeName ? stateRender.nodeName === nodeName : true;\n return matchingAgentName && matchesNodeContext;\n });\n },\n [coAgentStateRenders, nodeName, agentId],\n );\n const stateRenderEntry = useMemo(() => getStateRender(message.id), [getStateRender, message.id]);\n const stateRenderId = stateRenderEntry?.[0];\n const stateRender = stateRenderEntry?.[1];\n\n const registryMessage = {\n ...message,\n runId: props.runId ?? message.runId,\n };\n const { canRender } = useStateRenderRegistry({\n agentId,\n stateRenderId,\n message: registryMessage,\n messageIndex: props.messageIndex,\n stateSnapshot,\n agentState: agent?.state,\n agentMessages: agent?.messages,\n claimsRef,\n });\n\n return useMemo(() => {\n if (!stateRender || !stateRenderId) {\n return null;\n }\n if (!canRender) {\n return null;\n }\n\n if (stateRender.handler) {\n stateRender.handler({\n state: stateSnapshot ? parseJson(stateSnapshot, stateSnapshot) : (agent?.state ?? {}),\n nodeName: nodeName ?? \"\",\n });\n }\n\n if (stateRender.render) {\n const status = agent?.isRunning ? RenderStatus.InProgress : RenderStatus.Complete;\n\n if (typeof stateRender.render === \"string\") return stateRender.render;\n\n return stateRender.render({\n status,\n // Always use state from claim, to make sure the state does not seem \"wiped\" for a fraction of a second\n state: claimsRef.current[message.id].stateSnapshot ?? {},\n nodeName: nodeName ?? \"\",\n });\n }\n }, [\n stateRender,\n stateRenderId,\n agent?.state,\n agent?.isRunning,\n nodeName,\n message.id,\n stateSnapshot,\n canRender,\n ]);\n}\n\nexport function CoAgentStateRenderBridge(props: CoAgentStateRenderBridgeProps) {\n return useCoagentStateRenderBridge(props.agentId, props);\n}\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","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","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"],"mappings":"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","names":["import_react","import_shared","import_react","_a","_b","_c","_d","existingClaim","existingSnapshot","stateRenderId","stateRender","_a"]}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CoAgentStateRenderBridge,
|
|
3
3
|
useCoagentStateRenderBridge
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-BKMJ4LC7.mjs";
|
|
5
5
|
import "../chunk-NB2FKV2V.mjs";
|
|
6
6
|
import "../chunk-LMHB2D4J.mjs";
|
|
7
|
-
import "../chunk-
|
|
7
|
+
import "../chunk-77IVITG3.mjs";
|
|
8
|
+
import "../chunk-C3YJYDK4.mjs";
|
|
9
|
+
import "../chunk-QD7EID4N.mjs";
|
|
8
10
|
import "../chunk-AFNWX62Q.mjs";
|
|
9
11
|
import "../chunk-DMLQZG75.mjs";
|
|
10
12
|
import "../chunk-SKC7AJIV.mjs";
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Claim } from './use-coagent-state-render-bridge.helpers.js';
|
|
2
|
+
|
|
3
|
+
interface StateRenderRegistryInput {
|
|
4
|
+
agentId: string;
|
|
5
|
+
stateRenderId?: string;
|
|
6
|
+
message: {
|
|
7
|
+
id: string;
|
|
8
|
+
runId?: string;
|
|
9
|
+
name?: string;
|
|
10
|
+
};
|
|
11
|
+
messageIndex?: number;
|
|
12
|
+
stateSnapshot?: any;
|
|
13
|
+
agentState?: any;
|
|
14
|
+
agentMessages?: Array<{
|
|
15
|
+
id: string;
|
|
16
|
+
role?: string;
|
|
17
|
+
}>;
|
|
18
|
+
claimsRef: React.MutableRefObject<Record<string, Claim>>;
|
|
19
|
+
}
|
|
20
|
+
interface StateRenderRegistryResult {
|
|
21
|
+
canRender: boolean;
|
|
22
|
+
}
|
|
23
|
+
declare function useStateRenderRegistry({ agentId, stateRenderId, message, messageIndex, stateSnapshot, agentState, agentMessages, claimsRef, }: StateRenderRegistryInput): StateRenderRegistryResult;
|
|
24
|
+
|
|
25
|
+
export { StateRenderRegistryInput, StateRenderRegistryResult, useStateRenderRegistry };
|