@copilotkit/runtime 1.66.2 → 1.66.4

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 (75) hide show
  1. package/dist/agent/converters/aisdk.cjs +17 -9
  2. package/dist/agent/converters/aisdk.cjs.map +1 -1
  3. package/dist/agent/converters/aisdk.d.cts +1 -1
  4. package/dist/agent/converters/aisdk.d.cts.map +1 -1
  5. package/dist/agent/converters/aisdk.d.mts +1 -1
  6. package/dist/agent/converters/aisdk.d.mts.map +1 -1
  7. package/dist/agent/converters/aisdk.mjs +17 -9
  8. package/dist/agent/converters/aisdk.mjs.map +1 -1
  9. package/dist/agent/converters/tanstack.cjs +17 -9
  10. package/dist/agent/converters/tanstack.cjs.map +1 -1
  11. package/dist/agent/converters/tanstack.d.cts +1 -1
  12. package/dist/agent/converters/tanstack.d.cts.map +1 -1
  13. package/dist/agent/converters/tanstack.d.mts +1 -1
  14. package/dist/agent/converters/tanstack.d.mts.map +1 -1
  15. package/dist/agent/converters/tanstack.mjs +17 -9
  16. package/dist/agent/converters/tanstack.mjs.map +1 -1
  17. package/dist/agent/index.cjs +6 -4
  18. package/dist/agent/index.cjs.map +1 -1
  19. package/dist/agent/index.d.cts.map +1 -1
  20. package/dist/agent/index.d.mts.map +1 -1
  21. package/dist/agent/index.mjs +6 -4
  22. package/dist/agent/index.mjs.map +1 -1
  23. package/dist/agent/state-delta.cjs +322 -0
  24. package/dist/agent/state-delta.cjs.map +1 -0
  25. package/dist/agent/state-delta.mjs +321 -0
  26. package/dist/agent/state-delta.mjs.map +1 -0
  27. package/dist/package.cjs +1 -1
  28. package/dist/runtime/package.mjs +1 -1
  29. package/dist/v2/index.cjs +6 -1
  30. package/dist/v2/index.d.cts +2 -2
  31. package/dist/v2/index.d.mts +2 -2
  32. package/dist/v2/index.mjs +2 -2
  33. package/dist/v2/runtime/core/channel-manager.cjs +110 -9
  34. package/dist/v2/runtime/core/channel-manager.cjs.map +1 -1
  35. package/dist/v2/runtime/core/channel-manager.d.cts +79 -8
  36. package/dist/v2/runtime/core/channel-manager.d.cts.map +1 -1
  37. package/dist/v2/runtime/core/channel-manager.d.mts +79 -8
  38. package/dist/v2/runtime/core/channel-manager.d.mts.map +1 -1
  39. package/dist/v2/runtime/core/channel-manager.mjs +110 -9
  40. package/dist/v2/runtime/core/channel-manager.mjs.map +1 -1
  41. package/dist/v2/runtime/core/runtime.cjs.map +1 -1
  42. package/dist/v2/runtime/core/runtime.d.cts +1 -0
  43. package/dist/v2/runtime/core/runtime.d.cts.map +1 -1
  44. package/dist/v2/runtime/core/runtime.d.mts +1 -0
  45. package/dist/v2/runtime/core/runtime.d.mts.map +1 -1
  46. package/dist/v2/runtime/core/runtime.mjs.map +1 -1
  47. package/dist/v2/runtime/handlers/shared/agent-utils.cjs +2 -5
  48. package/dist/v2/runtime/handlers/shared/agent-utils.cjs.map +1 -1
  49. package/dist/v2/runtime/handlers/shared/agent-utils.mjs +2 -5
  50. package/dist/v2/runtime/handlers/shared/agent-utils.mjs.map +1 -1
  51. package/dist/v2/runtime/handlers/shared/mcp-apps-servers.cjs +23 -0
  52. package/dist/v2/runtime/handlers/shared/mcp-apps-servers.cjs.map +1 -0
  53. package/dist/v2/runtime/handlers/shared/mcp-apps-servers.mjs +22 -0
  54. package/dist/v2/runtime/handlers/shared/mcp-apps-servers.mjs.map +1 -0
  55. package/dist/v2/runtime/index.d.cts +1 -1
  56. package/dist/v2/runtime/index.d.mts +1 -1
  57. package/dist/v2/runtime/open-generative-ui-middleware.cjs +1 -0
  58. package/dist/v2/runtime/open-generative-ui-middleware.cjs.map +1 -1
  59. package/dist/v2/runtime/open-generative-ui-middleware.mjs +1 -0
  60. package/dist/v2/runtime/open-generative-ui-middleware.mjs.map +1 -1
  61. package/dist/v2/runtime/runner/in-memory.cjs +335 -101
  62. package/dist/v2/runtime/runner/in-memory.cjs.map +1 -1
  63. package/dist/v2/runtime/runner/in-memory.d.cts +246 -6
  64. package/dist/v2/runtime/runner/in-memory.d.cts.map +1 -1
  65. package/dist/v2/runtime/runner/in-memory.d.mts +246 -6
  66. package/dist/v2/runtime/runner/in-memory.d.mts.map +1 -1
  67. package/dist/v2/runtime/runner/in-memory.mjs +331 -102
  68. package/dist/v2/runtime/runner/in-memory.mjs.map +1 -1
  69. package/dist/v2/runtime/runner/index.d.cts +1 -1
  70. package/dist/v2/runtime/runner/index.d.mts +1 -1
  71. package/dist/v2/runtime/runner/index.mjs +1 -1
  72. package/package.json +5 -5
  73. package/skills/runtime/references/agent-runners-in-memory.md +49 -34
  74. package/skills/runtime/references/agent-runners.md +47 -21
  75. package/skills/runtime/references/wiring-mcp-apps-middleware.md +5 -0
@@ -0,0 +1,322 @@
1
+ require("reflect-metadata");
2
+ const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
3
+ let _ag_ui_client = require("@ag-ui/client");
4
+
5
+ //#region src/agent/state-delta.ts
6
+ function parseJsonPointer(pointer) {
7
+ if (pointer === "") return [];
8
+ if (!pointer.startsWith("/")) return void 0;
9
+ const segments = pointer.slice(1).split("/");
10
+ if (segments.some((segment) => /~(?![01])/.test(segment))) return;
11
+ return segments.map((segment) => segment.replace(/~1/g, "/").replace(/~0/g, "~"));
12
+ }
13
+ function encodeJsonPointer(segments) {
14
+ if (segments.length === 0) return "";
15
+ return `/${segments.map((segment) => segment.replace(/~/g, "~0").replace(/\//g, "~1")).join("/")}`;
16
+ }
17
+ function getArrayIndex(segment, length) {
18
+ if (segment !== "0" && !/^[1-9]\d*$/.test(segment)) return void 0;
19
+ const index = Number(segment);
20
+ return Number.isSafeInteger(index) && index < length ? index : void 0;
21
+ }
22
+ function getJsonPointerValue(root, pointer) {
23
+ const segments = parseJsonPointer(pointer);
24
+ if (segments === void 0) return { exists: false };
25
+ let current = root;
26
+ for (const segment of segments) {
27
+ if (current === null || typeof current !== "object") return { exists: false };
28
+ if (Array.isArray(current)) {
29
+ const index = getArrayIndex(segment, current.length);
30
+ if (index === void 0) return { exists: false };
31
+ current = current[index];
32
+ } else {
33
+ if (!Object.prototype.hasOwnProperty.call(current, segment)) return { exists: false };
34
+ current = current[segment];
35
+ }
36
+ }
37
+ return {
38
+ exists: true,
39
+ value: current
40
+ };
41
+ }
42
+ function getParent(root, segments) {
43
+ return getJsonPointerValue(root, encodeJsonPointer(segments.slice(0, -1)));
44
+ }
45
+ function cloneStateFallback(state, seen = /* @__PURE__ */ new WeakMap()) {
46
+ if (state === null || typeof state !== "object") return state;
47
+ const existing = seen.get(state);
48
+ if (existing !== void 0) return existing;
49
+ let clone;
50
+ try {
51
+ clone = Array.isArray(state) ? [] : Object.create(Object.getPrototypeOf(state));
52
+ } catch {
53
+ clone = Array.isArray(state) ? [] : {};
54
+ }
55
+ seen.set(state, clone);
56
+ let keys = [];
57
+ try {
58
+ keys = Reflect.ownKeys(state);
59
+ } catch {
60
+ return clone;
61
+ }
62
+ for (const key of keys) try {
63
+ const descriptor = Object.getOwnPropertyDescriptor(state, key);
64
+ if (!descriptor) continue;
65
+ if ("value" in descriptor) descriptor.value = cloneStateFallback(descriptor.value, seen);
66
+ Object.defineProperty(clone, key, descriptor);
67
+ } catch {}
68
+ return clone;
69
+ }
70
+ function cloneState(state) {
71
+ try {
72
+ return structuredClone(state);
73
+ } catch {
74
+ return cloneStateFallback(state);
75
+ }
76
+ }
77
+ function addValue(root, segments, value) {
78
+ if (segments.length === 0) return {
79
+ root: cloneState(value),
80
+ applied: true
81
+ };
82
+ const parent = getParent(root, segments);
83
+ if (!parent.exists || parent.value === null || typeof parent.value !== "object") return {
84
+ root,
85
+ applied: false
86
+ };
87
+ const segment = segments[segments.length - 1];
88
+ if (Array.isArray(parent.value)) {
89
+ if (segment === "-") {
90
+ parent.value.push(cloneState(value));
91
+ return {
92
+ root,
93
+ applied: true
94
+ };
95
+ }
96
+ const index = segment === "0" ? 0 : /^[1-9]\d*$/.test(segment) ? Number(segment) : void 0;
97
+ if (index === void 0 || !Number.isSafeInteger(index) || index > parent.value.length) return {
98
+ root,
99
+ applied: false
100
+ };
101
+ parent.value.splice(index, 0, cloneState(value));
102
+ return {
103
+ root,
104
+ applied: true
105
+ };
106
+ }
107
+ parent.value[segment] = cloneState(value);
108
+ return {
109
+ root,
110
+ applied: true
111
+ };
112
+ }
113
+ function removeValue(root, segments) {
114
+ if (segments.length === 0) return {
115
+ root: void 0,
116
+ applied: true
117
+ };
118
+ const parent = getParent(root, segments);
119
+ if (!parent.exists || parent.value === null || typeof parent.value !== "object") return {
120
+ root,
121
+ applied: false
122
+ };
123
+ const segment = segments[segments.length - 1];
124
+ if (Array.isArray(parent.value)) {
125
+ const index = getArrayIndex(segment, parent.value.length);
126
+ if (index === void 0) return {
127
+ root,
128
+ applied: false
129
+ };
130
+ parent.value.splice(index, 1);
131
+ return {
132
+ root,
133
+ applied: true
134
+ };
135
+ }
136
+ if (!Object.prototype.hasOwnProperty.call(parent.value, segment)) return {
137
+ root,
138
+ applied: false
139
+ };
140
+ delete parent.value[segment];
141
+ return {
142
+ root,
143
+ applied: true
144
+ };
145
+ }
146
+ function replaceValue(root, segments, value) {
147
+ if (segments.length === 0) return {
148
+ root: cloneState(value),
149
+ applied: true
150
+ };
151
+ const parent = getParent(root, segments);
152
+ if (!parent.exists || parent.value === null || typeof parent.value !== "object") return {
153
+ root,
154
+ applied: false
155
+ };
156
+ const segment = segments[segments.length - 1];
157
+ if (Array.isArray(parent.value)) {
158
+ const index = getArrayIndex(segment, parent.value.length);
159
+ if (index === void 0) return {
160
+ root,
161
+ applied: false
162
+ };
163
+ parent.value[index] = cloneState(value);
164
+ return {
165
+ root,
166
+ applied: true
167
+ };
168
+ }
169
+ if (!Object.prototype.hasOwnProperty.call(parent.value, segment)) return {
170
+ root,
171
+ applied: false
172
+ };
173
+ parent.value[segment] = cloneState(value);
174
+ return {
175
+ root,
176
+ applied: true
177
+ };
178
+ }
179
+ function jsonValueEqual(left, right) {
180
+ if (Object.is(left, right)) return true;
181
+ if (left === null || right === null || typeof left !== "object" || typeof right !== "object") return false;
182
+ if (Array.isArray(left) !== Array.isArray(right)) return false;
183
+ const leftKeys = Object.keys(left);
184
+ const rightKeys = Object.keys(right);
185
+ if (leftKeys.length !== rightKeys.length) return false;
186
+ return leftKeys.every((key) => Object.prototype.hasOwnProperty.call(right, key) && jsonValueEqual(left[key], right[key]));
187
+ }
188
+ function applyStateDeltaOperation(root, operation) {
189
+ if (typeof operation.path !== "string") return {
190
+ root,
191
+ applied: false
192
+ };
193
+ const path = parseJsonPointer(operation.path);
194
+ if (path === void 0) return {
195
+ root,
196
+ applied: false
197
+ };
198
+ switch (operation.op) {
199
+ case "add": return addValue(root, path, operation.value);
200
+ case "remove": return removeValue(root, path);
201
+ case "replace": return replaceValue(root, path, operation.value);
202
+ case "test": {
203
+ const actual = getJsonPointerValue(root, operation.path);
204
+ return {
205
+ root,
206
+ applied: actual.exists && jsonValueEqual(actual.value, operation.value)
207
+ };
208
+ }
209
+ case "copy": {
210
+ if (typeof operation.from !== "string") return {
211
+ root,
212
+ applied: false
213
+ };
214
+ const source = getJsonPointerValue(root, operation.from);
215
+ if (!source.exists) return {
216
+ root,
217
+ applied: false
218
+ };
219
+ return addValue(root, path, source.value);
220
+ }
221
+ case "move": {
222
+ if (typeof operation.from !== "string") return {
223
+ root,
224
+ applied: false
225
+ };
226
+ const from = parseJsonPointer(operation.from);
227
+ if (from === void 0) return {
228
+ root,
229
+ applied: false
230
+ };
231
+ const source = getJsonPointerValue(root, operation.from);
232
+ if (!source.exists) return {
233
+ root,
234
+ applied: false
235
+ };
236
+ if (operation.from === operation.path) return {
237
+ root,
238
+ applied: true
239
+ };
240
+ const removed = removeValue(cloneState(root), from);
241
+ if (!removed.applied) return {
242
+ root,
243
+ applied: false
244
+ };
245
+ const added = addValue(removed.root, path, source.value);
246
+ return added.applied ? added : {
247
+ root,
248
+ applied: false
249
+ };
250
+ }
251
+ default: return {
252
+ root,
253
+ applied: false
254
+ };
255
+ }
256
+ }
257
+ function normalizeStateDelta(delta, initialState) {
258
+ let state = cloneState(initialState);
259
+ const normalized = [];
260
+ for (const operation of delta) {
261
+ const candidate = operation !== null && typeof operation === "object" ? operation : void 0;
262
+ if (candidate?.op === "add" && typeof candidate.path === "string" && candidate.path.endsWith("/-")) {
263
+ const arrayPath = candidate.path.slice(0, -2);
264
+ if (!getJsonPointerValue(state, arrayPath).exists) {
265
+ const lastSlash = arrayPath.lastIndexOf("/");
266
+ const parentPath = lastSlash > 0 ? arrayPath.slice(0, lastSlash) : "";
267
+ if (getJsonPointerValue(state, parentPath).exists) {
268
+ const initializer = {
269
+ op: "add",
270
+ path: arrayPath,
271
+ value: []
272
+ };
273
+ const applied = applyStateDeltaOperation(state, initializer);
274
+ if (applied.applied) {
275
+ normalized.push(initializer);
276
+ state = applied.root;
277
+ }
278
+ }
279
+ }
280
+ }
281
+ normalized.push(operation);
282
+ if (candidate) {
283
+ const applied = applyStateDeltaOperation(state, candidate);
284
+ if (applied.applied) state = applied.root;
285
+ }
286
+ }
287
+ return {
288
+ delta: normalized,
289
+ state
290
+ };
291
+ }
292
+ function createStateEventNormalizer(initialState) {
293
+ let state = cloneState(initialState);
294
+ let hasEmittedState = false;
295
+ return (event) => {
296
+ if (event.type === _ag_ui_client.EventType.STATE_SNAPSHOT) {
297
+ state = cloneState(event.snapshot);
298
+ hasEmittedState = true;
299
+ return [event];
300
+ }
301
+ if (event.type !== _ag_ui_client.EventType.STATE_DELTA) return [event];
302
+ const stateDeltaEvent = event;
303
+ const initialSnapshot = !hasEmittedState && initialState !== void 0 ? [{
304
+ type: _ag_ui_client.EventType.STATE_SNAPSHOT,
305
+ snapshot: cloneState(state)
306
+ }] : [];
307
+ const normalized = Array.isArray(stateDeltaEvent.delta) ? normalizeStateDelta(stateDeltaEvent.delta, state) : {
308
+ delta: stateDeltaEvent.delta,
309
+ state
310
+ };
311
+ state = normalized.state;
312
+ hasEmittedState = true;
313
+ return [...initialSnapshot, {
314
+ ...stateDeltaEvent,
315
+ delta: normalized.delta
316
+ }];
317
+ };
318
+ }
319
+
320
+ //#endregion
321
+ exports.createStateEventNormalizer = createStateEventNormalizer;
322
+ //# sourceMappingURL=state-delta.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-delta.cjs","names":["EventType"],"sources":["../../src/agent/state-delta.ts"],"sourcesContent":["import type {\n BaseEvent,\n StateDeltaEvent,\n StateSnapshotEvent,\n} from \"@ag-ui/client\";\nimport { EventType } from \"@ag-ui/client\";\n\ntype StateDeltaOperation = {\n op?: string;\n path?: string;\n from?: string;\n value?: unknown;\n};\n\ntype PointerResult = {\n exists: boolean;\n value?: unknown;\n};\n\ntype OperationResult = {\n root: unknown;\n applied: boolean;\n};\n\nfunction parseJsonPointer(pointer: string): string[] | undefined {\n if (pointer === \"\") return [];\n if (!pointer.startsWith(\"/\")) return undefined;\n\n const segments = pointer.slice(1).split(\"/\");\n if (segments.some((segment) => /~(?![01])/.test(segment))) {\n return undefined;\n }\n\n return segments.map((segment) =>\n segment.replace(/~1/g, \"/\").replace(/~0/g, \"~\"),\n );\n}\n\nfunction encodeJsonPointer(segments: string[]): string {\n if (segments.length === 0) return \"\";\n return `/${segments\n .map((segment) => segment.replace(/~/g, \"~0\").replace(/\\//g, \"~1\"))\n .join(\"/\")}`;\n}\n\nfunction getArrayIndex(segment: string, length: number): number | undefined {\n if (segment !== \"0\" && !/^[1-9]\\d*$/.test(segment)) return undefined;\n const index = Number(segment);\n return Number.isSafeInteger(index) && index < length ? index : undefined;\n}\n\nfunction getJsonPointerValue(root: unknown, pointer: string): PointerResult {\n const segments = parseJsonPointer(pointer);\n if (segments === undefined) return { exists: false };\n\n let current = root;\n for (const segment of segments) {\n if (current === null || typeof current !== \"object\") {\n return { exists: false };\n }\n\n if (Array.isArray(current)) {\n const index = getArrayIndex(segment, current.length);\n if (index === undefined) return { exists: false };\n current = current[index];\n } else {\n if (!Object.prototype.hasOwnProperty.call(current, segment)) {\n return { exists: false };\n }\n current = (current as Record<string, unknown>)[segment];\n }\n }\n\n return { exists: true, value: current };\n}\n\nfunction getParent(root: unknown, segments: string[]): PointerResult {\n return getJsonPointerValue(root, encodeJsonPointer(segments.slice(0, -1)));\n}\n\nfunction cloneStateFallback(\n state: unknown,\n seen = new WeakMap<object, unknown>(),\n): unknown {\n if (state === null || typeof state !== \"object\") return state;\n\n const existing = seen.get(state);\n if (existing !== undefined) return existing;\n\n let clone: object;\n try {\n clone = Array.isArray(state)\n ? []\n : Object.create(Object.getPrototypeOf(state));\n } catch {\n clone = Array.isArray(state) ? [] : {};\n }\n seen.set(state, clone);\n\n let keys: (string | symbol)[] = [];\n try {\n keys = Reflect.ownKeys(state);\n } catch {\n return clone;\n }\n\n for (const key of keys) {\n try {\n const descriptor = Object.getOwnPropertyDescriptor(state, key);\n if (!descriptor) continue;\n if (\"value\" in descriptor) {\n descriptor.value = cloneStateFallback(descriptor.value, seen);\n }\n Object.defineProperty(clone, key, descriptor);\n } catch {\n // Keep the cloned container distinct when a property is inaccessible.\n }\n }\n\n return clone;\n}\n\nfunction cloneState(state: unknown): unknown {\n try {\n return structuredClone(state);\n } catch {\n return cloneStateFallback(state);\n }\n}\n\nfunction addValue(\n root: unknown,\n segments: string[],\n value: unknown,\n): OperationResult {\n if (segments.length === 0) {\n return { root: cloneState(value), applied: true };\n }\n\n const parent = getParent(root, segments);\n if (\n !parent.exists ||\n parent.value === null ||\n typeof parent.value !== \"object\"\n ) {\n return { root, applied: false };\n }\n\n const segment = segments[segments.length - 1];\n if (Array.isArray(parent.value)) {\n if (segment === \"-\") {\n parent.value.push(cloneState(value));\n return { root, applied: true };\n }\n\n const index =\n segment === \"0\"\n ? 0\n : /^[1-9]\\d*$/.test(segment)\n ? Number(segment)\n : undefined;\n if (\n index === undefined ||\n !Number.isSafeInteger(index) ||\n index > parent.value.length\n ) {\n return { root, applied: false };\n }\n parent.value.splice(index, 0, cloneState(value));\n return { root, applied: true };\n }\n\n (parent.value as Record<string, unknown>)[segment] = cloneState(value);\n return { root, applied: true };\n}\n\nfunction removeValue(root: unknown, segments: string[]): OperationResult {\n if (segments.length === 0) return { root: undefined, applied: true };\n\n const parent = getParent(root, segments);\n if (\n !parent.exists ||\n parent.value === null ||\n typeof parent.value !== \"object\"\n ) {\n return { root, applied: false };\n }\n\n const segment = segments[segments.length - 1];\n if (Array.isArray(parent.value)) {\n const index = getArrayIndex(segment, parent.value.length);\n if (index === undefined) return { root, applied: false };\n parent.value.splice(index, 1);\n return { root, applied: true };\n }\n\n if (!Object.prototype.hasOwnProperty.call(parent.value, segment)) {\n return { root, applied: false };\n }\n delete (parent.value as Record<string, unknown>)[segment];\n return { root, applied: true };\n}\n\nfunction replaceValue(\n root: unknown,\n segments: string[],\n value: unknown,\n): OperationResult {\n if (segments.length === 0) {\n return { root: cloneState(value), applied: true };\n }\n\n const parent = getParent(root, segments);\n if (\n !parent.exists ||\n parent.value === null ||\n typeof parent.value !== \"object\"\n ) {\n return { root, applied: false };\n }\n\n const segment = segments[segments.length - 1];\n if (Array.isArray(parent.value)) {\n const index = getArrayIndex(segment, parent.value.length);\n if (index === undefined) return { root, applied: false };\n parent.value[index] = cloneState(value);\n return { root, applied: true };\n }\n\n if (!Object.prototype.hasOwnProperty.call(parent.value, segment)) {\n return { root, applied: false };\n }\n (parent.value as Record<string, unknown>)[segment] = cloneState(value);\n return { root, applied: true };\n}\n\nfunction jsonValueEqual(left: unknown, right: unknown): boolean {\n if (Object.is(left, right)) return true;\n if (\n left === null ||\n right === null ||\n typeof left !== \"object\" ||\n typeof right !== \"object\"\n ) {\n return false;\n }\n if (Array.isArray(left) !== Array.isArray(right)) return false;\n\n const leftKeys = Object.keys(left as object);\n const rightKeys = Object.keys(right as object);\n if (leftKeys.length !== rightKeys.length) return false;\n\n return leftKeys.every(\n (key) =>\n Object.prototype.hasOwnProperty.call(right, key) &&\n jsonValueEqual(\n (left as Record<string, unknown>)[key],\n (right as Record<string, unknown>)[key],\n ),\n );\n}\n\nfunction applyStateDeltaOperation(\n root: unknown,\n operation: StateDeltaOperation,\n): OperationResult {\n if (typeof operation.path !== \"string\") return { root, applied: false };\n\n const path = parseJsonPointer(operation.path);\n if (path === undefined) return { root, applied: false };\n\n switch (operation.op) {\n case \"add\":\n return addValue(root, path, operation.value);\n case \"remove\":\n return removeValue(root, path);\n case \"replace\":\n return replaceValue(root, path, operation.value);\n case \"test\": {\n const actual = getJsonPointerValue(root, operation.path);\n return {\n root,\n applied: actual.exists && jsonValueEqual(actual.value, operation.value),\n };\n }\n case \"copy\": {\n if (typeof operation.from !== \"string\") return { root, applied: false };\n const source = getJsonPointerValue(root, operation.from);\n if (!source.exists) return { root, applied: false };\n return addValue(root, path, source.value);\n }\n case \"move\": {\n if (typeof operation.from !== \"string\") return { root, applied: false };\n const from = parseJsonPointer(operation.from);\n if (from === undefined) return { root, applied: false };\n const source = getJsonPointerValue(root, operation.from);\n if (!source.exists) return { root, applied: false };\n if (operation.from === operation.path) return { root, applied: true };\n\n const nextRoot = cloneState(root);\n const removed = removeValue(nextRoot, from);\n if (!removed.applied) return { root, applied: false };\n const added = addValue(removed.root, path, source.value);\n return added.applied ? added : { root, applied: false };\n }\n default:\n return { root, applied: false };\n }\n}\n\nfunction normalizeStateDelta(\n delta: unknown[],\n initialState: unknown,\n): { delta: unknown[]; state: unknown } {\n let state = cloneState(initialState);\n const normalized: unknown[] = [];\n\n for (const operation of delta) {\n const candidate =\n operation !== null && typeof operation === \"object\"\n ? (operation as StateDeltaOperation)\n : undefined;\n if (\n candidate?.op === \"add\" &&\n typeof candidate.path === \"string\" &&\n candidate.path.endsWith(\"/-\")\n ) {\n const arrayPath = candidate.path.slice(0, -2);\n const array = getJsonPointerValue(state, arrayPath);\n if (!array.exists) {\n const lastSlash = arrayPath.lastIndexOf(\"/\");\n const parentPath = lastSlash > 0 ? arrayPath.slice(0, lastSlash) : \"\";\n if (getJsonPointerValue(state, parentPath).exists) {\n const initializer: StateDeltaOperation = {\n op: \"add\",\n path: arrayPath,\n value: [],\n };\n const applied = applyStateDeltaOperation(state, initializer);\n if (applied.applied) {\n normalized.push(initializer);\n state = applied.root;\n }\n }\n }\n }\n\n normalized.push(operation);\n if (candidate) {\n const applied = applyStateDeltaOperation(state, candidate);\n if (applied.applied) state = applied.root;\n }\n }\n\n return { delta: normalized, state };\n}\n\nexport function createStateEventNormalizer(\n initialState: unknown,\n): (event: BaseEvent) => BaseEvent[] {\n let state = cloneState(initialState);\n let hasEmittedState = false;\n\n return (event) => {\n if (event.type === EventType.STATE_SNAPSHOT) {\n state = cloneState((event as StateSnapshotEvent).snapshot);\n hasEmittedState = true;\n return [event];\n }\n\n if (event.type !== EventType.STATE_DELTA) return [event];\n\n const stateDeltaEvent = event as StateDeltaEvent;\n const initialSnapshot: StateSnapshotEvent[] =\n !hasEmittedState && initialState !== undefined\n ? [\n {\n type: EventType.STATE_SNAPSHOT,\n snapshot: cloneState(state),\n },\n ]\n : [];\n const normalized = Array.isArray(stateDeltaEvent.delta)\n ? normalizeStateDelta(stateDeltaEvent.delta, state)\n : { delta: stateDeltaEvent.delta, state };\n state = normalized.state;\n hasEmittedState = true;\n\n return [\n ...initialSnapshot,\n {\n ...stateDeltaEvent,\n delta: normalized.delta as StateDeltaEvent[\"delta\"],\n },\n ];\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,321 @@
1
+ import "reflect-metadata";
2
+ import { EventType } from "@ag-ui/client";
3
+
4
+ //#region src/agent/state-delta.ts
5
+ function parseJsonPointer(pointer) {
6
+ if (pointer === "") return [];
7
+ if (!pointer.startsWith("/")) return void 0;
8
+ const segments = pointer.slice(1).split("/");
9
+ if (segments.some((segment) => /~(?![01])/.test(segment))) return;
10
+ return segments.map((segment) => segment.replace(/~1/g, "/").replace(/~0/g, "~"));
11
+ }
12
+ function encodeJsonPointer(segments) {
13
+ if (segments.length === 0) return "";
14
+ return `/${segments.map((segment) => segment.replace(/~/g, "~0").replace(/\//g, "~1")).join("/")}`;
15
+ }
16
+ function getArrayIndex(segment, length) {
17
+ if (segment !== "0" && !/^[1-9]\d*$/.test(segment)) return void 0;
18
+ const index = Number(segment);
19
+ return Number.isSafeInteger(index) && index < length ? index : void 0;
20
+ }
21
+ function getJsonPointerValue(root, pointer) {
22
+ const segments = parseJsonPointer(pointer);
23
+ if (segments === void 0) return { exists: false };
24
+ let current = root;
25
+ for (const segment of segments) {
26
+ if (current === null || typeof current !== "object") return { exists: false };
27
+ if (Array.isArray(current)) {
28
+ const index = getArrayIndex(segment, current.length);
29
+ if (index === void 0) return { exists: false };
30
+ current = current[index];
31
+ } else {
32
+ if (!Object.prototype.hasOwnProperty.call(current, segment)) return { exists: false };
33
+ current = current[segment];
34
+ }
35
+ }
36
+ return {
37
+ exists: true,
38
+ value: current
39
+ };
40
+ }
41
+ function getParent(root, segments) {
42
+ return getJsonPointerValue(root, encodeJsonPointer(segments.slice(0, -1)));
43
+ }
44
+ function cloneStateFallback(state, seen = /* @__PURE__ */ new WeakMap()) {
45
+ if (state === null || typeof state !== "object") return state;
46
+ const existing = seen.get(state);
47
+ if (existing !== void 0) return existing;
48
+ let clone;
49
+ try {
50
+ clone = Array.isArray(state) ? [] : Object.create(Object.getPrototypeOf(state));
51
+ } catch {
52
+ clone = Array.isArray(state) ? [] : {};
53
+ }
54
+ seen.set(state, clone);
55
+ let keys = [];
56
+ try {
57
+ keys = Reflect.ownKeys(state);
58
+ } catch {
59
+ return clone;
60
+ }
61
+ for (const key of keys) try {
62
+ const descriptor = Object.getOwnPropertyDescriptor(state, key);
63
+ if (!descriptor) continue;
64
+ if ("value" in descriptor) descriptor.value = cloneStateFallback(descriptor.value, seen);
65
+ Object.defineProperty(clone, key, descriptor);
66
+ } catch {}
67
+ return clone;
68
+ }
69
+ function cloneState(state) {
70
+ try {
71
+ return structuredClone(state);
72
+ } catch {
73
+ return cloneStateFallback(state);
74
+ }
75
+ }
76
+ function addValue(root, segments, value) {
77
+ if (segments.length === 0) return {
78
+ root: cloneState(value),
79
+ applied: true
80
+ };
81
+ const parent = getParent(root, segments);
82
+ if (!parent.exists || parent.value === null || typeof parent.value !== "object") return {
83
+ root,
84
+ applied: false
85
+ };
86
+ const segment = segments[segments.length - 1];
87
+ if (Array.isArray(parent.value)) {
88
+ if (segment === "-") {
89
+ parent.value.push(cloneState(value));
90
+ return {
91
+ root,
92
+ applied: true
93
+ };
94
+ }
95
+ const index = segment === "0" ? 0 : /^[1-9]\d*$/.test(segment) ? Number(segment) : void 0;
96
+ if (index === void 0 || !Number.isSafeInteger(index) || index > parent.value.length) return {
97
+ root,
98
+ applied: false
99
+ };
100
+ parent.value.splice(index, 0, cloneState(value));
101
+ return {
102
+ root,
103
+ applied: true
104
+ };
105
+ }
106
+ parent.value[segment] = cloneState(value);
107
+ return {
108
+ root,
109
+ applied: true
110
+ };
111
+ }
112
+ function removeValue(root, segments) {
113
+ if (segments.length === 0) return {
114
+ root: void 0,
115
+ applied: true
116
+ };
117
+ const parent = getParent(root, segments);
118
+ if (!parent.exists || parent.value === null || typeof parent.value !== "object") return {
119
+ root,
120
+ applied: false
121
+ };
122
+ const segment = segments[segments.length - 1];
123
+ if (Array.isArray(parent.value)) {
124
+ const index = getArrayIndex(segment, parent.value.length);
125
+ if (index === void 0) return {
126
+ root,
127
+ applied: false
128
+ };
129
+ parent.value.splice(index, 1);
130
+ return {
131
+ root,
132
+ applied: true
133
+ };
134
+ }
135
+ if (!Object.prototype.hasOwnProperty.call(parent.value, segment)) return {
136
+ root,
137
+ applied: false
138
+ };
139
+ delete parent.value[segment];
140
+ return {
141
+ root,
142
+ applied: true
143
+ };
144
+ }
145
+ function replaceValue(root, segments, value) {
146
+ if (segments.length === 0) return {
147
+ root: cloneState(value),
148
+ applied: true
149
+ };
150
+ const parent = getParent(root, segments);
151
+ if (!parent.exists || parent.value === null || typeof parent.value !== "object") return {
152
+ root,
153
+ applied: false
154
+ };
155
+ const segment = segments[segments.length - 1];
156
+ if (Array.isArray(parent.value)) {
157
+ const index = getArrayIndex(segment, parent.value.length);
158
+ if (index === void 0) return {
159
+ root,
160
+ applied: false
161
+ };
162
+ parent.value[index] = cloneState(value);
163
+ return {
164
+ root,
165
+ applied: true
166
+ };
167
+ }
168
+ if (!Object.prototype.hasOwnProperty.call(parent.value, segment)) return {
169
+ root,
170
+ applied: false
171
+ };
172
+ parent.value[segment] = cloneState(value);
173
+ return {
174
+ root,
175
+ applied: true
176
+ };
177
+ }
178
+ function jsonValueEqual(left, right) {
179
+ if (Object.is(left, right)) return true;
180
+ if (left === null || right === null || typeof left !== "object" || typeof right !== "object") return false;
181
+ if (Array.isArray(left) !== Array.isArray(right)) return false;
182
+ const leftKeys = Object.keys(left);
183
+ const rightKeys = Object.keys(right);
184
+ if (leftKeys.length !== rightKeys.length) return false;
185
+ return leftKeys.every((key) => Object.prototype.hasOwnProperty.call(right, key) && jsonValueEqual(left[key], right[key]));
186
+ }
187
+ function applyStateDeltaOperation(root, operation) {
188
+ if (typeof operation.path !== "string") return {
189
+ root,
190
+ applied: false
191
+ };
192
+ const path = parseJsonPointer(operation.path);
193
+ if (path === void 0) return {
194
+ root,
195
+ applied: false
196
+ };
197
+ switch (operation.op) {
198
+ case "add": return addValue(root, path, operation.value);
199
+ case "remove": return removeValue(root, path);
200
+ case "replace": return replaceValue(root, path, operation.value);
201
+ case "test": {
202
+ const actual = getJsonPointerValue(root, operation.path);
203
+ return {
204
+ root,
205
+ applied: actual.exists && jsonValueEqual(actual.value, operation.value)
206
+ };
207
+ }
208
+ case "copy": {
209
+ if (typeof operation.from !== "string") return {
210
+ root,
211
+ applied: false
212
+ };
213
+ const source = getJsonPointerValue(root, operation.from);
214
+ if (!source.exists) return {
215
+ root,
216
+ applied: false
217
+ };
218
+ return addValue(root, path, source.value);
219
+ }
220
+ case "move": {
221
+ if (typeof operation.from !== "string") return {
222
+ root,
223
+ applied: false
224
+ };
225
+ const from = parseJsonPointer(operation.from);
226
+ if (from === void 0) return {
227
+ root,
228
+ applied: false
229
+ };
230
+ const source = getJsonPointerValue(root, operation.from);
231
+ if (!source.exists) return {
232
+ root,
233
+ applied: false
234
+ };
235
+ if (operation.from === operation.path) return {
236
+ root,
237
+ applied: true
238
+ };
239
+ const removed = removeValue(cloneState(root), from);
240
+ if (!removed.applied) return {
241
+ root,
242
+ applied: false
243
+ };
244
+ const added = addValue(removed.root, path, source.value);
245
+ return added.applied ? added : {
246
+ root,
247
+ applied: false
248
+ };
249
+ }
250
+ default: return {
251
+ root,
252
+ applied: false
253
+ };
254
+ }
255
+ }
256
+ function normalizeStateDelta(delta, initialState) {
257
+ let state = cloneState(initialState);
258
+ const normalized = [];
259
+ for (const operation of delta) {
260
+ const candidate = operation !== null && typeof operation === "object" ? operation : void 0;
261
+ if (candidate?.op === "add" && typeof candidate.path === "string" && candidate.path.endsWith("/-")) {
262
+ const arrayPath = candidate.path.slice(0, -2);
263
+ if (!getJsonPointerValue(state, arrayPath).exists) {
264
+ const lastSlash = arrayPath.lastIndexOf("/");
265
+ const parentPath = lastSlash > 0 ? arrayPath.slice(0, lastSlash) : "";
266
+ if (getJsonPointerValue(state, parentPath).exists) {
267
+ const initializer = {
268
+ op: "add",
269
+ path: arrayPath,
270
+ value: []
271
+ };
272
+ const applied = applyStateDeltaOperation(state, initializer);
273
+ if (applied.applied) {
274
+ normalized.push(initializer);
275
+ state = applied.root;
276
+ }
277
+ }
278
+ }
279
+ }
280
+ normalized.push(operation);
281
+ if (candidate) {
282
+ const applied = applyStateDeltaOperation(state, candidate);
283
+ if (applied.applied) state = applied.root;
284
+ }
285
+ }
286
+ return {
287
+ delta: normalized,
288
+ state
289
+ };
290
+ }
291
+ function createStateEventNormalizer(initialState) {
292
+ let state = cloneState(initialState);
293
+ let hasEmittedState = false;
294
+ return (event) => {
295
+ if (event.type === EventType.STATE_SNAPSHOT) {
296
+ state = cloneState(event.snapshot);
297
+ hasEmittedState = true;
298
+ return [event];
299
+ }
300
+ if (event.type !== EventType.STATE_DELTA) return [event];
301
+ const stateDeltaEvent = event;
302
+ const initialSnapshot = !hasEmittedState && initialState !== void 0 ? [{
303
+ type: EventType.STATE_SNAPSHOT,
304
+ snapshot: cloneState(state)
305
+ }] : [];
306
+ const normalized = Array.isArray(stateDeltaEvent.delta) ? normalizeStateDelta(stateDeltaEvent.delta, state) : {
307
+ delta: stateDeltaEvent.delta,
308
+ state
309
+ };
310
+ state = normalized.state;
311
+ hasEmittedState = true;
312
+ return [...initialSnapshot, {
313
+ ...stateDeltaEvent,
314
+ delta: normalized.delta
315
+ }];
316
+ };
317
+ }
318
+
319
+ //#endregion
320
+ export { createStateEventNormalizer };
321
+ //# sourceMappingURL=state-delta.mjs.map