@copilotkit/runtime 1.80.0 → 1.81.0

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 (119) hide show
  1. package/dist/_virtual/_rolldown/runtime.mjs +15 -1
  2. package/dist/agent/index.d.cts +1 -1
  3. package/dist/lib/runtime/copilot-runtime.cjs +17 -2
  4. package/dist/lib/runtime/copilot-runtime.cjs.map +1 -1
  5. package/dist/lib/runtime/copilot-runtime.d.cts +2 -2
  6. package/dist/lib/runtime/copilot-runtime.d.cts.map +1 -1
  7. package/dist/lib/runtime/copilot-runtime.d.mts +2 -2
  8. package/dist/lib/runtime/copilot-runtime.d.mts.map +1 -1
  9. package/dist/lib/runtime/copilot-runtime.mjs +18 -3
  10. package/dist/lib/runtime/copilot-runtime.mjs.map +1 -1
  11. package/dist/lib/runtime/legacy-service-adapter-agent.cjs +360 -0
  12. package/dist/lib/runtime/legacy-service-adapter-agent.cjs.map +1 -0
  13. package/dist/lib/runtime/legacy-service-adapter-agent.mjs +359 -0
  14. package/dist/lib/runtime/legacy-service-adapter-agent.mjs.map +1 -0
  15. package/dist/lib/telemetry-client.cjs +12 -1
  16. package/dist/lib/telemetry-client.cjs.map +1 -1
  17. package/dist/lib/telemetry-client.mjs +12 -1
  18. package/dist/lib/telemetry-client.mjs.map +1 -1
  19. package/dist/package.cjs +2 -2
  20. package/dist/package.mjs +2 -2
  21. package/dist/service-adapters/events.cjs +91 -0
  22. package/dist/service-adapters/events.cjs.map +1 -1
  23. package/dist/service-adapters/events.d.cts +6 -1
  24. package/dist/service-adapters/events.d.cts.map +1 -1
  25. package/dist/service-adapters/events.d.mts +6 -1
  26. package/dist/service-adapters/events.d.mts.map +1 -1
  27. package/dist/service-adapters/events.mjs +90 -1
  28. package/dist/service-adapters/events.mjs.map +1 -1
  29. package/dist/service-adapters/langchain/langchain-adapter.cjs +1 -1
  30. package/dist/service-adapters/langchain/langchain-adapter.cjs.map +1 -1
  31. package/dist/service-adapters/langchain/langchain-adapter.d.cts.map +1 -1
  32. package/dist/service-adapters/langchain/langchain-adapter.d.mts.map +1 -1
  33. package/dist/service-adapters/langchain/langchain-adapter.mjs +2 -2
  34. package/dist/service-adapters/langchain/langchain-adapter.mjs.map +1 -1
  35. package/dist/service-adapters/langchain/utils.cjs +53 -15
  36. package/dist/service-adapters/langchain/utils.cjs.map +1 -1
  37. package/dist/service-adapters/langchain/utils.mjs +53 -16
  38. package/dist/service-adapters/langchain/utils.mjs.map +1 -1
  39. package/dist/v2/index.cjs +5 -0
  40. package/dist/v2/index.d.cts +5 -2
  41. package/dist/v2/index.d.mts +5 -2
  42. package/dist/v2/index.mjs +4 -2
  43. package/dist/v2/runtime/core/package-info.cjs +1 -1
  44. package/dist/v2/runtime/core/package-info.mjs +1 -1
  45. package/dist/v2/runtime/core/runtime.cjs +5 -1
  46. package/dist/v2/runtime/core/runtime.cjs.map +1 -1
  47. package/dist/v2/runtime/core/runtime.d.cts +15 -0
  48. package/dist/v2/runtime/core/runtime.d.cts.map +1 -1
  49. package/dist/v2/runtime/core/runtime.d.mts +15 -0
  50. package/dist/v2/runtime/core/runtime.d.mts.map +1 -1
  51. package/dist/v2/runtime/core/runtime.mjs +5 -1
  52. package/dist/v2/runtime/core/runtime.mjs.map +1 -1
  53. package/dist/v2/runtime/endpoints/express.cjs +2 -2
  54. package/dist/v2/runtime/endpoints/express.cjs.map +1 -1
  55. package/dist/v2/runtime/endpoints/express.mjs +2 -2
  56. package/dist/v2/runtime/endpoints/express.mjs.map +1 -1
  57. package/dist/v2/runtime/endpoints/node-fetch-handler.cjs +51 -1
  58. package/dist/v2/runtime/endpoints/node-fetch-handler.cjs.map +1 -1
  59. package/dist/v2/runtime/endpoints/node-fetch-handler.d.cts.map +1 -1
  60. package/dist/v2/runtime/endpoints/node-fetch-handler.d.mts.map +1 -1
  61. package/dist/v2/runtime/endpoints/node-fetch-handler.mjs +52 -2
  62. package/dist/v2/runtime/endpoints/node-fetch-handler.mjs.map +1 -1
  63. package/dist/v2/runtime/generative-ui/generative-ui-middleware.cjs +394 -0
  64. package/dist/v2/runtime/generative-ui/generative-ui-middleware.cjs.map +1 -0
  65. package/dist/v2/runtime/generative-ui/generative-ui-middleware.d.cts +21 -0
  66. package/dist/v2/runtime/generative-ui/generative-ui-middleware.d.cts.map +1 -0
  67. package/dist/v2/runtime/generative-ui/generative-ui-middleware.d.mts +21 -0
  68. package/dist/v2/runtime/generative-ui/generative-ui-middleware.d.mts.map +1 -0
  69. package/dist/v2/runtime/generative-ui/generative-ui-middleware.mjs +393 -0
  70. package/dist/v2/runtime/generative-ui/generative-ui-middleware.mjs.map +1 -0
  71. package/dist/v2/runtime/generative-ui/index.d.cts +3 -0
  72. package/dist/v2/runtime/generative-ui/index.d.mts +3 -0
  73. package/dist/v2/runtime/generative-ui/surface-writer.cjs +86 -0
  74. package/dist/v2/runtime/generative-ui/surface-writer.cjs.map +1 -0
  75. package/dist/v2/runtime/generative-ui/surface-writer.d.cts +33 -0
  76. package/dist/v2/runtime/generative-ui/surface-writer.d.cts.map +1 -0
  77. package/dist/v2/runtime/generative-ui/surface-writer.d.mts +33 -0
  78. package/dist/v2/runtime/generative-ui/surface-writer.d.mts.map +1 -0
  79. package/dist/v2/runtime/generative-ui/surface-writer.mjs +85 -0
  80. package/dist/v2/runtime/generative-ui/surface-writer.mjs.map +1 -0
  81. package/dist/v2/runtime/handlers/handle-run.cjs +8 -3
  82. package/dist/v2/runtime/handlers/handle-run.cjs.map +1 -1
  83. package/dist/v2/runtime/handlers/handle-run.mjs +5 -1
  84. package/dist/v2/runtime/handlers/handle-run.mjs.map +1 -1
  85. package/dist/v2/runtime/handlers/shared/agent-utils.cjs +7 -0
  86. package/dist/v2/runtime/handlers/shared/agent-utils.cjs.map +1 -1
  87. package/dist/v2/runtime/handlers/shared/agent-utils.mjs +7 -0
  88. package/dist/v2/runtime/handlers/shared/agent-utils.mjs.map +1 -1
  89. package/dist/v2/runtime/index.d.cts +5 -1
  90. package/dist/v2/runtime/index.d.cts.map +1 -1
  91. package/dist/v2/runtime/index.d.mts +5 -1
  92. package/dist/v2/runtime/index.d.mts.map +1 -1
  93. package/dist/v2/runtime/intelligence-platform/client.cjs +84 -1
  94. package/dist/v2/runtime/intelligence-platform/client.cjs.map +1 -1
  95. package/dist/v2/runtime/intelligence-platform/client.d.cts +19 -1
  96. package/dist/v2/runtime/intelligence-platform/client.d.cts.map +1 -1
  97. package/dist/v2/runtime/intelligence-platform/client.d.mts +19 -1
  98. package/dist/v2/runtime/intelligence-platform/client.d.mts.map +1 -1
  99. package/dist/v2/runtime/intelligence-platform/client.mjs +84 -1
  100. package/dist/v2/runtime/intelligence-platform/client.mjs.map +1 -1
  101. package/dist/v2/runtime/intelligence-platform/experimental.d.cts +27 -0
  102. package/dist/v2/runtime/intelligence-platform/experimental.d.cts.map +1 -0
  103. package/dist/v2/runtime/intelligence-platform/experimental.d.mts +27 -0
  104. package/dist/v2/runtime/intelligence-platform/experimental.d.mts.map +1 -0
  105. package/dist/v2/runtime/intelligence-platform/index.d.cts +2 -1
  106. package/dist/v2/runtime/intelligence-platform/index.d.mts +2 -1
  107. package/dist/v2/runtime/intelligence-platform/learning-management.cjs +204 -0
  108. package/dist/v2/runtime/intelligence-platform/learning-management.cjs.map +1 -0
  109. package/dist/v2/runtime/intelligence-platform/learning-management.d.cts +112 -0
  110. package/dist/v2/runtime/intelligence-platform/learning-management.d.cts.map +1 -0
  111. package/dist/v2/runtime/intelligence-platform/learning-management.d.mts +112 -0
  112. package/dist/v2/runtime/intelligence-platform/learning-management.d.mts.map +1 -0
  113. package/dist/v2/runtime/intelligence-platform/learning-management.mjs +194 -0
  114. package/dist/v2/runtime/intelligence-platform/learning-management.mjs.map +1 -0
  115. package/package.json +5 -5
  116. package/dist/v2/runtime/endpoints/express-fetch-bridge.cjs +0 -82
  117. package/dist/v2/runtime/endpoints/express-fetch-bridge.cjs.map +0 -1
  118. package/dist/v2/runtime/endpoints/express-fetch-bridge.mjs +0 -81
  119. package/dist/v2/runtime/endpoints/express-fetch-bridge.mjs.map +0 -1
@@ -0,0 +1,393 @@
1
+ import "reflect-metadata";
2
+ import { GENERATIVE_UI_ACTIVITY_TYPE, GENERATIVE_UI_CONTEXT_DESCRIPTION, GENERATIVE_UI_FUNCTION_CALL_ACTIVITY_TYPE, GENERATIVE_UI_RENDER_TOOL, RenderUIArgsStream, buildGenerativeUIPrompt, envelopeToManifest, generativeUIFunctionCallMessageId, generativeUISurfaceMessageId, getOperationKind, getOperationSurfaceId, randomUUID, readCopilotKitUIEnvelope, validateOperation } from "@copilotkit/shared";
3
+ import { Observable } from "rxjs";
4
+ import { EventType, Middleware } from "@ag-ui/client";
5
+
6
+ //#region src/v2/runtime/generative-ui/generative-ui-middleware.ts
7
+ function isRecord(value) {
8
+ return typeof value === "object" && value !== null && !Array.isArray(value);
9
+ }
10
+ /**
11
+ * Builds the manifest from the generative UI envelope
12
+ * (`forwardedProps.copilotkit.ui`). The client sends the envelope, so it is
13
+ * not trusted: `readCopilotKitUIEnvelope` checks every field, and
14
+ * `envelopeToManifest` turns it into the manifest. Returns
15
+ * `undefined` (the run passes through) when:
16
+ * - there is no valid envelope;
17
+ * - the transport is "markdown" (the model writes fences, not render_ui);
18
+ * - the catalog has no components (the server cannot validate operations).
19
+ */
20
+ function readManifest(forwardedProps) {
21
+ const envelope = readCopilotKitUIEnvelope(forwardedProps);
22
+ if (!envelope) return void 0;
23
+ const manifest = envelopeToManifest(envelope);
24
+ return manifest.transport === "tool" && manifest.hasComponents ? manifest : void 0;
25
+ }
26
+ function prepareInput(input, manifest) {
27
+ const tools = (input.tools ?? []).filter((t) => t.name !== GENERATIVE_UI_RENDER_TOOL);
28
+ tools.push({
29
+ name: GENERATIVE_UI_RENDER_TOOL,
30
+ description: "Render or update generative UI surfaces, or call app functions, with A2UI v1.0 operations. Follow the generative UI guide in context.",
31
+ parameters: {
32
+ type: "object",
33
+ properties: {
34
+ target: {
35
+ type: "string",
36
+ enum: manifest.targets.map((t) => t.id),
37
+ description: "Where the surface is shown: \"chat\" or a named inline target."
38
+ },
39
+ operations: {
40
+ type: "array",
41
+ description: "A2UI v1.0 operations, applied in order.",
42
+ items: { type: "object" }
43
+ }
44
+ },
45
+ required: ["target", "operations"]
46
+ }
47
+ });
48
+ const context = (input.context ?? []).filter((c) => c.description !== GENERATIVE_UI_CONTEXT_DESCRIPTION);
49
+ context.push({
50
+ description: GENERATIVE_UI_CONTEXT_DESCRIPTION,
51
+ value: buildGenerativeUIPrompt(manifest)
52
+ });
53
+ return {
54
+ ...input,
55
+ tools,
56
+ context
57
+ };
58
+ }
59
+ /**
60
+ * Experimental. Lets an agent render CopilotKit generative UI surfaces via the
61
+ * `render_ui` tool. It applies only to runs whose generative UI envelope uses
62
+ * the "tool" transport. Each complete operation in the streamed arguments is
63
+ * validated against the catalog in the envelope and committed immediately:
64
+ * - `ACTIVITY_SNAPSHOT` for a new surface, `ACTIVITY_DELTA` for every further
65
+ * operation on it.
66
+ * - One `ACTIVITY_SNAPSHOT` of type `generative-ui-function-call` for each
67
+ * `callRendererFunction`. The client runs the function.
68
+ */
69
+ var GenerativeUIMiddleware = class extends Middleware {
70
+ run(input, next) {
71
+ const manifest = readManifest(input.forwardedProps);
72
+ if (!manifest) return this.runNext(input, next);
73
+ return processStream(this.runNextWithState(prepareInput(input, manifest), next), manifest);
74
+ }
75
+ };
76
+ /**
77
+ * The first time a render_ui call touches an existing surface, mark it
78
+ * streaming and clear its rejection list: earlier calls' rejections were
79
+ * already reported to the model in their own tool results, and a repaired
80
+ * surface must not keep showing them. A surface created by this call starts
81
+ * with an empty list in its snapshot.
82
+ */
83
+ function beginSurfaceUpdate(state, surfaceId) {
84
+ if (state.touched.has(surfaceId)) return [];
85
+ state.touched.add(surfaceId);
86
+ return [{
87
+ op: "replace",
88
+ path: "/status",
89
+ value: "streaming"
90
+ }, {
91
+ op: "replace",
92
+ path: "/rejected",
93
+ value: []
94
+ }];
95
+ }
96
+ function processStream(source, manifest) {
97
+ return new Observable((subscriber) => {
98
+ const entries = Object.entries(manifest.surfaces);
99
+ const surfaces = new Map(entries.filter(([, s]) => !s.status).map(([id, s]) => [id, s.target]));
100
+ const createdSurfaces = new Set(entries.filter(([, s]) => s.status !== "failed").map(([id]) => id));
101
+ const targetComponents = new Map(manifest.targets.filter((t) => t.components !== void 0).map((t) => [t.id, new Set(t.components)]));
102
+ const functionCallIds = /* @__PURE__ */ new Set();
103
+ const calls = /* @__PURE__ */ new Map();
104
+ let heldFinish = null;
105
+ const emit = (event) => subscriber.next(event);
106
+ const patch = (surfaceId, ops) => emit({
107
+ type: EventType.ACTIVITY_DELTA,
108
+ messageId: generativeUISurfaceMessageId(surfaceId),
109
+ activityType: GENERATIVE_UI_ACTIVITY_TYPE,
110
+ patch: ops
111
+ });
112
+ const processOperation = (state, op) => {
113
+ const index = state.nextIndex++;
114
+ const reject = (reason, surfaceId) => {
115
+ const entry = {
116
+ index,
117
+ reason
118
+ };
119
+ state.rejected.push(entry);
120
+ if (surfaceId && surfaces.has(surfaceId)) patch(surfaceId, [...beginSurfaceUpdate(state, surfaceId), {
121
+ op: "add",
122
+ path: "/rejected/-",
123
+ value: entry
124
+ }]);
125
+ };
126
+ if (op === null) return reject("operation is not valid JSON");
127
+ let surfaceId;
128
+ try {
129
+ surfaceId = getOperationSurfaceId(op);
130
+ applyOperation(state, withCatalogId(op), surfaceId, reject);
131
+ } catch (error) {
132
+ reject(`operation could not be processed: ${error instanceof Error ? error.message : String(error)}`, surfaceId);
133
+ }
134
+ };
135
+ /**
136
+ * The model does not have to name the catalog. A createSurface keeps a
137
+ * catalogId that the envelope lists, and gets the catalog id of the run
138
+ * for any other value. The whole operation, with its inline components
139
+ * and data model, stays in the snapshot.
140
+ */
141
+ const catalogIds = manifest.catalogIds ?? [manifest.catalogId];
142
+ const withCatalogId = (op) => {
143
+ const create = op.createSurface;
144
+ if (!isRecord(create)) return op;
145
+ const catalogId = catalogIds.includes(create.catalogId) ? create.catalogId : manifest.catalogId;
146
+ return {
147
+ ...op,
148
+ createSurface: {
149
+ ...create,
150
+ catalogId
151
+ }
152
+ };
153
+ };
154
+ /**
155
+ * The components that the target of the surface takes. A createSurface
156
+ * goes to the target of the render_ui call. Every other operation goes to
157
+ * the target that the surface was created on.
158
+ */
159
+ const allowedComponentsFor = (state, op, surfaceId) => {
160
+ const target = getOperationKind(op) === "createSurface" ? state.target : surfaces.get(surfaceId);
161
+ const names = targetComponents.get(target);
162
+ return names && {
163
+ target,
164
+ names
165
+ };
166
+ };
167
+ const applyOperation = (state, op, surfaceId, reject) => {
168
+ const validation = validateOperation(op, {
169
+ manifest,
170
+ knownSurfaces: new Set(surfaces.keys()),
171
+ createdSurfaces,
172
+ functions: manifest.functions,
173
+ allowedComponents: allowedComponentsFor(state, op, surfaceId)
174
+ });
175
+ if (validation.ok === false) return reject(validation.reason, surfaceId);
176
+ const accepted = op;
177
+ if ("callRendererFunction" in accepted) return callRendererFunction(state, accepted.callRendererFunction, reject);
178
+ if ("createSurface" in accepted) return createSurface(state, surfaceId, accepted, reject);
179
+ patch(surfaceId, [...beginSurfaceUpdate(state, surfaceId), {
180
+ op: "add",
181
+ path: "/operations/-",
182
+ value: accepted
183
+ }]);
184
+ if ("deleteSurface" in accepted) surfaces.delete(surfaceId);
185
+ state.applied++;
186
+ };
187
+ const createSurface = (state, surfaceId, op, reject) => {
188
+ const { target } = state;
189
+ if (target === void 0) return reject("render_ui was called without a target");
190
+ if (!manifest.targets.some((t) => t.id === target)) return reject(`target "${target}" is not mounted`);
191
+ surfaces.set(surfaceId, target);
192
+ createdSurfaces.add(surfaceId);
193
+ const content = {
194
+ surfaceId,
195
+ target,
196
+ catalogId: "createSurface" in op && op.createSurface.catalogId || manifest.catalogId,
197
+ operations: [op],
198
+ status: "streaming",
199
+ rejected: []
200
+ };
201
+ emit({
202
+ type: EventType.ACTIVITY_SNAPSHOT,
203
+ messageId: generativeUISurfaceMessageId(surfaceId),
204
+ activityType: GENERATIVE_UI_ACTIVITY_TYPE,
205
+ content,
206
+ replace: true
207
+ });
208
+ state.touched.add(surfaceId);
209
+ state.applied++;
210
+ };
211
+ /**
212
+ * Sends one function call to the client, which runs it. A function call
213
+ * needs no target and no surface. Each `functionCallId` runs once.
214
+ */
215
+ const callRendererFunction = (state, content, reject) => {
216
+ const { functionCallId } = content;
217
+ if (functionCallIds.has(functionCallId)) return reject(`functionCallId "${functionCallId}" was used before; use a new functionCallId`);
218
+ functionCallIds.add(functionCallId);
219
+ emit({
220
+ type: EventType.ACTIVITY_SNAPSHOT,
221
+ messageId: generativeUIFunctionCallMessageId(functionCallId),
222
+ activityType: GENERATIVE_UI_FUNCTION_CALL_ACTIVITY_TYPE,
223
+ content: {
224
+ functionCallId,
225
+ callFunction: content.callFunction
226
+ },
227
+ replace: true
228
+ });
229
+ state.calls++;
230
+ };
231
+ /** Same buffering rule as streamed ops: hold them until the target is known. */
232
+ const acceptOperation = (state, op) => {
233
+ if (state.target === void 0) state.buffered.push(op);
234
+ else processOperation(state, op);
235
+ };
236
+ /**
237
+ * The streaming parser found no operations at all. Models sometimes send
238
+ * `operations` as a JSON-encoded string; recover those from the complete
239
+ * arguments. Anything still unusable leaves the call with zero operations,
240
+ * which the tool result reports as an error.
241
+ */
242
+ const recoverOperations = (state) => {
243
+ let args;
244
+ try {
245
+ args = JSON.parse(state.stream.text);
246
+ } catch {
247
+ return;
248
+ }
249
+ if (!isRecord(args)) return;
250
+ if (state.target === void 0 && typeof args.target === "string") state.target = args.target;
251
+ let operations = args.operations;
252
+ if (typeof operations === "string") try {
253
+ operations = JSON.parse(operations);
254
+ } catch {
255
+ return;
256
+ }
257
+ if (!Array.isArray(operations)) return;
258
+ for (const op of operations) acceptOperation(state, isRecord(op) ? op : null);
259
+ };
260
+ const finishCall = (state) => {
261
+ if (state.finished) return;
262
+ state.finished = true;
263
+ if (state.nextIndex === 0 && state.buffered.length === 0) recoverOperations(state);
264
+ if (state.target === void 0) {
265
+ const buffered = state.buffered;
266
+ state.buffered = [];
267
+ for (const op of buffered) {
268
+ if (getOperationKind(op) === "callRendererFunction") {
269
+ processOperation(state, op);
270
+ continue;
271
+ }
272
+ state.rejected.push({
273
+ index: state.nextIndex++,
274
+ reason: "render_ui was called without a target"
275
+ });
276
+ }
277
+ }
278
+ if (state.stream.hasIncompleteOperation) state.rejected.push({
279
+ index: state.nextIndex++,
280
+ reason: "operation was truncated"
281
+ });
282
+ for (const id of state.touched) patch(id, [{
283
+ op: "replace",
284
+ path: "/status",
285
+ value: "ready"
286
+ }]);
287
+ };
288
+ const flushFinish = () => {
289
+ if (heldFinish) {
290
+ emit(heldFinish.event);
291
+ heldFinish = null;
292
+ }
293
+ };
294
+ const handleEvent = ({ event, messages }) => {
295
+ flushFinish();
296
+ if (event.type === EventType.RUN_FINISHED) {
297
+ heldFinish = {
298
+ event,
299
+ messages
300
+ };
301
+ return;
302
+ }
303
+ emit(event);
304
+ if (event.type === EventType.TOOL_CALL_START) {
305
+ const start = event;
306
+ if (start.toolCallName === GENERATIVE_UI_RENDER_TOOL) calls.set(start.toolCallId, {
307
+ stream: new RenderUIArgsStream(),
308
+ buffered: [],
309
+ nextIndex: 0,
310
+ applied: 0,
311
+ calls: 0,
312
+ rejected: [],
313
+ touched: /* @__PURE__ */ new Set(),
314
+ finished: false
315
+ });
316
+ } else if (event.type === EventType.TOOL_CALL_ARGS) {
317
+ const args = event;
318
+ const state = calls.get(args.toolCallId);
319
+ if (!state || state.finished) return;
320
+ const { target, newOperations } = state.stream.push(args.delta);
321
+ if (target !== void 0 && state.target === void 0) {
322
+ state.target = target;
323
+ const buffered = state.buffered;
324
+ state.buffered = [];
325
+ for (const op of buffered) processOperation(state, op);
326
+ }
327
+ for (const op of newOperations) acceptOperation(state, op);
328
+ } else if (event.type === EventType.TOOL_CALL_END) {
329
+ const state = calls.get(event.toolCallId);
330
+ if (state) finishCall(state);
331
+ }
332
+ };
333
+ const completeRun = () => {
334
+ for (const state of calls.values()) finishCall(state);
335
+ if (heldFinish) {
336
+ const answered = new Set(heldFinish.messages.filter((m) => m.role === "tool").map((m) => m.toolCallId));
337
+ for (const [toolCallId, state] of calls) {
338
+ if (answered.has(toolCallId)) continue;
339
+ const nothingParsed = state.applied === 0 && state.calls === 0 && state.rejected.length === 0;
340
+ emit({
341
+ type: EventType.TOOL_CALL_RESULT,
342
+ messageId: randomUUID(),
343
+ toolCallId,
344
+ content: JSON.stringify(nothingParsed ? {
345
+ status: "error",
346
+ applied: 0,
347
+ calls: 0,
348
+ rejected: [],
349
+ reason: "operations must be a JSON array of A2UI operation objects; nothing was rendered"
350
+ } : {
351
+ status: "rendered",
352
+ applied: state.applied,
353
+ calls: state.calls,
354
+ rejected: state.rejected
355
+ })
356
+ });
357
+ }
358
+ flushFinish();
359
+ }
360
+ subscriber.complete();
361
+ };
362
+ let failed = false;
363
+ const subscription = source.subscribe({
364
+ next: (item) => {
365
+ if (failed) return;
366
+ try {
367
+ handleEvent(item);
368
+ } catch (error) {
369
+ failed = true;
370
+ subscriber.error(error);
371
+ }
372
+ },
373
+ error: (error) => {
374
+ flushFinish();
375
+ subscriber.error(error);
376
+ },
377
+ complete: () => {
378
+ if (failed) return;
379
+ try {
380
+ completeRun();
381
+ } catch (error) {
382
+ failed = true;
383
+ subscriber.error(error);
384
+ }
385
+ }
386
+ });
387
+ return () => subscription.unsubscribe();
388
+ });
389
+ }
390
+
391
+ //#endregion
392
+ export { GenerativeUIMiddleware };
393
+ //# sourceMappingURL=generative-ui-middleware.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generative-ui-middleware.mjs","names":[],"sources":["../../../../src/v2/runtime/generative-ui/generative-ui-middleware.ts"],"sourcesContent":["import { EventType, Middleware } from \"@ag-ui/client\";\nimport type {\n AbstractAgent,\n BaseEvent,\n Message,\n RunAgentInput,\n ToolCallArgsEvent,\n ToolCallEndEvent,\n ToolCallStartEvent,\n} from \"@ag-ui/client\";\nimport { Observable } from \"rxjs\";\nimport {\n GENERATIVE_UI_ACTIVITY_TYPE,\n GENERATIVE_UI_CONTEXT_DESCRIPTION,\n GENERATIVE_UI_FUNCTION_CALL_ACTIVITY_TYPE,\n GENERATIVE_UI_RENDER_TOOL,\n RenderUIArgsStream,\n buildGenerativeUIPrompt,\n envelopeToManifest,\n generativeUIFunctionCallMessageId,\n generativeUISurfaceMessageId,\n getOperationKind,\n getOperationSurfaceId,\n randomUUID,\n readCopilotKitUIEnvelope,\n validateOperation,\n} from \"@copilotkit/shared\";\nimport type {\n A2UIOperation,\n GenerativeUIFunctionCallContent,\n GenerativeUIManifest,\n GenerativeUIRejectedOperation,\n GenerativeUISurfaceContent,\n} from \"@copilotkit/shared\";\n\ntype EventWithState = { event: BaseEvent; messages: Message[] };\ntype JsonPatchOperation = {\n op: \"add\" | \"replace\";\n path: string;\n value: unknown;\n};\n\ninterface RenderCallState {\n stream: RenderUIArgsStream;\n target?: string;\n buffered: Array<Record<string, unknown> | null>;\n nextIndex: number;\n /** Accepted surface operations. */\n applied: number;\n /** Accepted `callRendererFunction` operations. */\n calls: number;\n rejected: GenerativeUIRejectedOperation[];\n touched: Set<string>;\n finished: boolean;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * Builds the manifest from the generative UI envelope\n * (`forwardedProps.copilotkit.ui`). The client sends the envelope, so it is\n * not trusted: `readCopilotKitUIEnvelope` checks every field, and\n * `envelopeToManifest` turns it into the manifest. Returns\n * `undefined` (the run passes through) when:\n * - there is no valid envelope;\n * - the transport is \"markdown\" (the model writes fences, not render_ui);\n * - the catalog has no components (the server cannot validate operations).\n */\nfunction readManifest(forwardedProps: unknown) {\n const envelope = readCopilotKitUIEnvelope(forwardedProps);\n if (!envelope) return undefined;\n const manifest = envelopeToManifest(envelope);\n const isToolRun = manifest.transport === \"tool\" && manifest.hasComponents;\n return isToolRun ? manifest : undefined;\n}\n\nfunction prepareInput(input: RunAgentInput, manifest: GenerativeUIManifest) {\n const tools = (input.tools ?? []).filter(\n (t) => t.name !== GENERATIVE_UI_RENDER_TOOL,\n );\n tools.push({\n name: GENERATIVE_UI_RENDER_TOOL,\n description:\n \"Render or update generative UI surfaces, or call app functions, with A2UI v1.0 operations. Follow the generative UI guide in context.\",\n parameters: {\n type: \"object\",\n properties: {\n target: {\n type: \"string\",\n enum: manifest.targets.map((t) => t.id),\n description:\n 'Where the surface is shown: \"chat\" or a named inline target.',\n },\n operations: {\n type: \"array\",\n description: \"A2UI v1.0 operations, applied in order.\",\n items: { type: \"object\" },\n },\n },\n required: [\"target\", \"operations\"],\n },\n });\n const context = (input.context ?? []).filter(\n (c) => c.description !== GENERATIVE_UI_CONTEXT_DESCRIPTION,\n );\n context.push({\n description: GENERATIVE_UI_CONTEXT_DESCRIPTION,\n value: buildGenerativeUIPrompt(manifest),\n });\n return { ...input, tools, context };\n}\n\n/**\n * Experimental. Lets an agent render CopilotKit generative UI surfaces via the\n * `render_ui` tool. It applies only to runs whose generative UI envelope uses\n * the \"tool\" transport. Each complete operation in the streamed arguments is\n * validated against the catalog in the envelope and committed immediately:\n * - `ACTIVITY_SNAPSHOT` for a new surface, `ACTIVITY_DELTA` for every further\n * operation on it.\n * - One `ACTIVITY_SNAPSHOT` of type `generative-ui-function-call` for each\n * `callRendererFunction`. The client runs the function.\n */\nexport class GenerativeUIMiddleware extends Middleware {\n run(input: RunAgentInput, next: AbstractAgent): Observable<BaseEvent> {\n const manifest = readManifest(input.forwardedProps);\n if (!manifest) return this.runNext(input, next);\n return processStream(\n this.runNextWithState(\n prepareInput(input, manifest),\n next,\n ) as Observable<EventWithState>,\n manifest,\n );\n }\n}\n\n/**\n * The first time a render_ui call touches an existing surface, mark it\n * streaming and clear its rejection list: earlier calls' rejections were\n * already reported to the model in their own tool results, and a repaired\n * surface must not keep showing them. A surface created by this call starts\n * with an empty list in its snapshot.\n */\nfunction beginSurfaceUpdate(\n state: RenderCallState,\n surfaceId: string,\n): JsonPatchOperation[] {\n if (state.touched.has(surfaceId)) return [];\n state.touched.add(surfaceId);\n return [\n { op: \"replace\", path: \"/status\", value: \"streaming\" },\n { op: \"replace\", path: \"/rejected\", value: [] },\n ];\n}\n\nfunction processStream(\n source: Observable<EventWithState>,\n manifest: GenerativeUIManifest,\n) {\n return new Observable<BaseEvent>((subscriber) => {\n const entries = Object.entries(manifest.surfaces);\n // Only live surfaces take updates. A surface that the client deleted, or\n // that was never created, has a `status`.\n const surfaces = new Map<string, string>(\n entries.filter(([, s]) => !s.status).map(([id, s]) => [id, s.target]),\n );\n // A surface id is unique for the life of the page. Keep the ids that were\n // created, also after deleteSurface (in this run or an earlier one), so a\n // second createSurface is rejected. A failed create can be sent again.\n const createdSurfaces = new Set(\n entries.filter(([, s]) => s.status !== \"failed\").map(([id]) => id),\n );\n // The targets that limit their components, by target id.\n const targetComponents = new Map(\n manifest.targets\n .filter((t) => t.components !== undefined)\n .map((t) => [t.id, new Set(t.components)]),\n );\n const functionCallIds = new Set<string>();\n const calls = new Map<string, RenderCallState>();\n let heldFinish: EventWithState | null = null;\n\n const emit = (event: BaseEvent) => subscriber.next(event);\n const patch = (surfaceId: string, ops: JsonPatchOperation[]) =>\n emit({\n type: EventType.ACTIVITY_DELTA,\n messageId: generativeUISurfaceMessageId(surfaceId),\n activityType: GENERATIVE_UI_ACTIVITY_TYPE,\n patch: ops,\n });\n\n const processOperation = (\n state: RenderCallState,\n op: Record<string, unknown> | null,\n ) => {\n const index = state.nextIndex++;\n const reject = (reason: string, surfaceId?: string) => {\n const entry = { index, reason };\n state.rejected.push(entry);\n if (surfaceId && surfaces.has(surfaceId)) {\n patch(surfaceId, [\n ...beginSurfaceUpdate(state, surfaceId),\n { op: \"add\", path: \"/rejected/-\", value: entry },\n ]);\n }\n };\n if (op === null) return reject(\"operation is not valid JSON\");\n let surfaceId: string | undefined;\n try {\n surfaceId = getOperationSurfaceId(op);\n applyOperation(state, withCatalogId(op), surfaceId, reject);\n } catch (error) {\n // Never let one bad operation take down the run: report it to the\n // model through the tool result instead.\n reject(\n `operation could not be processed: ${error instanceof Error ? error.message : String(error)}`,\n surfaceId,\n );\n }\n };\n\n /**\n * The model does not have to name the catalog. A createSurface keeps a\n * catalogId that the envelope lists, and gets the catalog id of the run\n * for any other value. The whole operation, with its inline components\n * and data model, stays in the snapshot.\n */\n const catalogIds = manifest.catalogIds ?? [manifest.catalogId];\n const withCatalogId = (op: Record<string, unknown>) => {\n const create = op.createSurface;\n if (!isRecord(create)) return op;\n const catalogId = catalogIds.includes(create.catalogId as string)\n ? create.catalogId\n : manifest.catalogId;\n return { ...op, createSurface: { ...create, catalogId } };\n };\n\n /**\n * The components that the target of the surface takes. A createSurface\n * goes to the target of the render_ui call. Every other operation goes to\n * the target that the surface was created on.\n */\n const allowedComponentsFor = (\n state: RenderCallState,\n op: Record<string, unknown>,\n surfaceId: string | undefined,\n ) => {\n const target =\n getOperationKind(op) === \"createSurface\"\n ? state.target\n : surfaces.get(surfaceId);\n const names = targetComponents.get(target);\n return names && { target, names };\n };\n\n const applyOperation = (\n state: RenderCallState,\n op: Record<string, unknown>,\n surfaceId: string | undefined,\n reject: (reason: string, surfaceId?: string) => void,\n ) => {\n const validation = validateOperation(op, {\n manifest,\n knownSurfaces: new Set(surfaces.keys()),\n createdSurfaces,\n functions: manifest.functions,\n allowedComponents: allowedComponentsFor(state, op, surfaceId),\n });\n // `=== false` (not `!ok`): runtime is compiled non-strict, where `!ok`\n // does not narrow the discriminated union.\n if (validation.ok === false) return reject(validation.reason, surfaceId);\n // validateOperation checked the shape of the operation.\n const accepted = op as A2UIOperation;\n if (\"callRendererFunction\" in accepted) {\n return callRendererFunction(\n state,\n accepted.callRendererFunction,\n reject,\n );\n }\n if (\"createSurface\" in accepted) {\n return createSurface(state, surfaceId, accepted, reject);\n }\n patch(surfaceId, [\n ...beginSurfaceUpdate(state, surfaceId),\n { op: \"add\", path: \"/operations/-\", value: accepted },\n ]);\n if (\"deleteSurface\" in accepted) surfaces.delete(surfaceId);\n state.applied++;\n };\n\n const createSurface = (\n state: RenderCallState,\n surfaceId: string,\n op: A2UIOperation,\n reject: (reason: string) => void,\n ) => {\n const { target } = state;\n if (target === undefined) {\n return reject(\"render_ui was called without a target\");\n }\n if (!manifest.targets.some((t) => t.id === target)) {\n return reject(`target \"${target}\" is not mounted`);\n }\n surfaces.set(surfaceId, target);\n createdSurfaces.add(surfaceId);\n const content: GenerativeUISurfaceContent = {\n surfaceId,\n target,\n catalogId:\n (\"createSurface\" in op && op.createSurface.catalogId) ||\n manifest.catalogId,\n operations: [op],\n status: \"streaming\",\n rejected: [],\n };\n emit({\n type: EventType.ACTIVITY_SNAPSHOT,\n messageId: generativeUISurfaceMessageId(surfaceId),\n activityType: GENERATIVE_UI_ACTIVITY_TYPE,\n content,\n replace: true,\n });\n state.touched.add(surfaceId);\n state.applied++;\n };\n\n /**\n * Sends one function call to the client, which runs it. A function call\n * needs no target and no surface. Each `functionCallId` runs once.\n */\n const callRendererFunction = (\n state: RenderCallState,\n content: GenerativeUIFunctionCallContent,\n reject: (reason: string) => void,\n ) => {\n const { functionCallId } = content;\n if (functionCallIds.has(functionCallId)) {\n return reject(\n `functionCallId \"${functionCallId}\" was used before; use a new functionCallId`,\n );\n }\n functionCallIds.add(functionCallId);\n emit({\n type: EventType.ACTIVITY_SNAPSHOT,\n messageId: generativeUIFunctionCallMessageId(functionCallId),\n activityType: GENERATIVE_UI_FUNCTION_CALL_ACTIVITY_TYPE,\n content: {\n functionCallId,\n callFunction: content.callFunction,\n } satisfies GenerativeUIFunctionCallContent,\n replace: true,\n });\n state.calls++;\n };\n\n /** Same buffering rule as streamed ops: hold them until the target is known. */\n const acceptOperation = (\n state: RenderCallState,\n op: Record<string, unknown> | null,\n ) => {\n if (state.target === undefined) state.buffered.push(op);\n else processOperation(state, op);\n };\n\n /**\n * The streaming parser found no operations at all. Models sometimes send\n * `operations` as a JSON-encoded string; recover those from the complete\n * arguments. Anything still unusable leaves the call with zero operations,\n * which the tool result reports as an error.\n */\n const recoverOperations = (state: RenderCallState) => {\n let args: unknown;\n try {\n args = JSON.parse(state.stream.text);\n } catch {\n return;\n }\n if (!isRecord(args)) return;\n if (state.target === undefined && typeof args.target === \"string\") {\n state.target = args.target;\n }\n let operations = args.operations;\n if (typeof operations === \"string\") {\n try {\n operations = JSON.parse(operations);\n } catch {\n return;\n }\n }\n if (!Array.isArray(operations)) return;\n for (const op of operations)\n acceptOperation(state, isRecord(op) ? op : null);\n };\n\n const finishCall = (state: RenderCallState) => {\n if (state.finished) return;\n state.finished = true;\n if (state.nextIndex === 0 && state.buffered.length === 0)\n recoverOperations(state);\n if (state.target === undefined) {\n // A function call needs no target, so it still runs. Every other\n // operation is rejected.\n const buffered = state.buffered;\n state.buffered = [];\n for (const op of buffered) {\n if (getOperationKind(op) === \"callRendererFunction\") {\n processOperation(state, op);\n continue;\n }\n state.rejected.push({\n index: state.nextIndex++,\n reason: \"render_ui was called without a target\",\n });\n }\n }\n if (state.stream.hasIncompleteOperation) {\n // The arguments ended inside an element (for example the model hit its\n // output limit): report it instead of silently dropping it.\n state.rejected.push({\n index: state.nextIndex++,\n reason: \"operation was truncated\",\n });\n }\n for (const id of state.touched) {\n patch(id, [{ op: \"replace\", path: \"/status\", value: \"ready\" }]);\n }\n };\n\n const flushFinish = () => {\n if (heldFinish) {\n emit(heldFinish.event);\n heldFinish = null;\n }\n };\n\n const handleEvent = ({ event, messages }: EventWithState) => {\n flushFinish();\n if (event.type === EventType.RUN_FINISHED) {\n heldFinish = { event, messages };\n return;\n }\n emit(event);\n if (event.type === EventType.TOOL_CALL_START) {\n const start = event as ToolCallStartEvent;\n if (start.toolCallName === GENERATIVE_UI_RENDER_TOOL) {\n calls.set(start.toolCallId, {\n stream: new RenderUIArgsStream(),\n buffered: [],\n nextIndex: 0,\n applied: 0,\n calls: 0,\n rejected: [],\n touched: new Set(),\n finished: false,\n });\n }\n } else if (event.type === EventType.TOOL_CALL_ARGS) {\n const args = event as ToolCallArgsEvent;\n const state = calls.get(args.toolCallId);\n if (!state || state.finished) return;\n const { target, newOperations } = state.stream.push(args.delta);\n if (target !== undefined && state.target === undefined) {\n state.target = target;\n const buffered = state.buffered;\n state.buffered = [];\n for (const op of buffered) processOperation(state, op);\n }\n for (const op of newOperations) acceptOperation(state, op);\n } else if (event.type === EventType.TOOL_CALL_END) {\n const state = calls.get((event as ToolCallEndEvent).toolCallId);\n if (state) finishCall(state);\n }\n };\n\n const completeRun = () => {\n for (const state of calls.values()) finishCall(state);\n if (heldFinish) {\n const answered = new Set(\n heldFinish.messages\n .filter((m) => m.role === \"tool\")\n .map((m) => (m as { toolCallId: string }).toolCallId),\n );\n for (const [toolCallId, state] of calls) {\n if (answered.has(toolCallId)) continue;\n const nothingParsed =\n state.applied === 0 &&\n state.calls === 0 &&\n state.rejected.length === 0;\n // `applied` counts the surface operations, `calls` the function calls.\n emit({\n type: EventType.TOOL_CALL_RESULT,\n messageId: randomUUID(),\n toolCallId,\n content: JSON.stringify(\n nothingParsed\n ? {\n status: \"error\",\n applied: 0,\n calls: 0,\n rejected: [],\n reason:\n \"operations must be a JSON array of A2UI operation objects; nothing was rendered\",\n }\n : {\n status: \"rendered\",\n applied: state.applied,\n calls: state.calls,\n rejected: state.rejected,\n },\n ),\n });\n }\n flushFinish();\n }\n subscriber.complete();\n };\n\n let failed = false;\n const subscription = source.subscribe({\n next: (item) => {\n if (failed) return;\n try {\n handleEvent(item);\n } catch (error) {\n // Anything unexpected must reach the consumer as an error instead of\n // escaping this callback, where RxJS would rethrow it asynchronously\n // as an uncaught exception.\n failed = true;\n subscriber.error(error);\n }\n },\n error: (error) => {\n flushFinish();\n subscriber.error(error);\n },\n complete: () => {\n if (failed) return;\n try {\n completeRun();\n } catch (error) {\n failed = true;\n subscriber.error(error);\n }\n },\n });\n return () => subscription.unsubscribe();\n });\n}\n"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+
2
+ import { GenerativeUIMiddleware } from "./generative-ui-middleware.cjs";
3
+ import { GenerativeUISurfaceWriter, createSurfaceWriter } from "./surface-writer.cjs";
@@ -0,0 +1,3 @@
1
+
2
+ import { GenerativeUIMiddleware } from "./generative-ui-middleware.mjs";
3
+ import { GenerativeUISurfaceWriter, createSurfaceWriter } from "./surface-writer.mjs";
@@ -0,0 +1,86 @@
1
+ require("reflect-metadata");
2
+ const require_runtime = require('../../../_virtual/_rolldown/runtime.cjs');
3
+ let _copilotkit_shared = require("@copilotkit/shared");
4
+ let _ag_ui_client = require("@ag-ui/client");
5
+
6
+ //#region src/v2/runtime/generative-ui/surface-writer.ts
7
+ /**
8
+ * Experimental. Programmatic façade for custom agents and workflows: emits the
9
+ * same `generative-ui-surface` activity events as `render_ui`, one per call.
10
+ * Every operation is A2UI v1.0.
11
+ * Does not validate against the browser manifest; the client still validates
12
+ * every operation before applying it.
13
+ */
14
+ function createSurfaceWriter(emit) {
15
+ return { openSurface({ target, surfaceId, catalog }) {
16
+ const messageId = (0, _copilotkit_shared.generativeUISurfaceMessageId)(surfaceId);
17
+ const patch = (ops) => emit({
18
+ type: _ag_ui_client.EventType.ACTIVITY_DELTA,
19
+ messageId,
20
+ activityType: _copilotkit_shared.GENERATIVE_UI_ACTIVITY_TYPE,
21
+ patch: ops
22
+ });
23
+ const append = (op) => patch([{
24
+ op: "add",
25
+ path: "/operations/-",
26
+ value: op
27
+ }]);
28
+ const content = {
29
+ surfaceId,
30
+ target,
31
+ catalogId: catalog,
32
+ operations: [{
33
+ version: "v1.0",
34
+ createSurface: {
35
+ surfaceId,
36
+ catalogId: catalog
37
+ }
38
+ }],
39
+ status: "streaming",
40
+ rejected: []
41
+ };
42
+ emit({
43
+ type: _ag_ui_client.EventType.ACTIVITY_SNAPSHOT,
44
+ messageId,
45
+ activityType: _copilotkit_shared.GENERATIVE_UI_ACTIVITY_TYPE,
46
+ content,
47
+ replace: true
48
+ });
49
+ return {
50
+ setRoot: (node) => append({
51
+ version: "v1.0",
52
+ updateComponents: {
53
+ surfaceId,
54
+ components: [{
55
+ ...node,
56
+ id: _copilotkit_shared.GENERATIVE_UI_ROOT_ID
57
+ }]
58
+ }
59
+ }),
60
+ upsert: (...nodes) => append({
61
+ version: "v1.0",
62
+ updateComponents: {
63
+ surfaceId,
64
+ components: nodes
65
+ }
66
+ }),
67
+ updateData: (path, value) => append({
68
+ version: "v1.0",
69
+ updateDataModel: {
70
+ surfaceId,
71
+ path,
72
+ value
73
+ }
74
+ }),
75
+ close: () => patch([{
76
+ op: "replace",
77
+ path: "/status",
78
+ value: "ready"
79
+ }])
80
+ };
81
+ } };
82
+ }
83
+
84
+ //#endregion
85
+ exports.createSurfaceWriter = createSurfaceWriter;
86
+ //# sourceMappingURL=surface-writer.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"surface-writer.cjs","names":["EventType","GENERATIVE_UI_ACTIVITY_TYPE","GENERATIVE_UI_ROOT_ID"],"sources":["../../../../src/v2/runtime/generative-ui/surface-writer.ts"],"sourcesContent":["import { EventType } from \"@ag-ui/client\";\nimport type { BaseEvent } from \"@ag-ui/client\";\nimport {\n GENERATIVE_UI_ACTIVITY_TYPE,\n GENERATIVE_UI_ROOT_ID,\n generativeUISurfaceMessageId,\n} from \"@copilotkit/shared\";\nimport type {\n A2UIComponentNode,\n A2UIOperation,\n GenerativeUISurfaceContent,\n} from \"@copilotkit/shared\";\n\nexport interface GenerativeUISurfaceWriter {\n setRoot(node: Omit<A2UIComponentNode, \"id\">): void;\n upsert(...nodes: A2UIComponentNode[]): void;\n /** Sets `value` at `path`. A `null` value deletes the key at `path`. */\n updateData(path: string, value: unknown): void;\n close(): void;\n}\n\n/**\n * Experimental. Programmatic façade for custom agents and workflows: emits the\n * same `generative-ui-surface` activity events as `render_ui`, one per call.\n * Every operation is A2UI v1.0.\n * Does not validate against the browser manifest; the client still validates\n * every operation before applying it.\n */\nexport function createSurfaceWriter(emit: (event: BaseEvent) => void) {\n return {\n openSurface({\n target,\n surfaceId,\n catalog,\n }: {\n target: string;\n surfaceId: string;\n catalog: string;\n }): GenerativeUISurfaceWriter {\n const messageId = generativeUISurfaceMessageId(surfaceId);\n const patch = (ops: unknown[]) =>\n emit({\n type: EventType.ACTIVITY_DELTA,\n messageId,\n activityType: GENERATIVE_UI_ACTIVITY_TYPE,\n patch: ops,\n });\n const append = (op: A2UIOperation) =>\n patch([{ op: \"add\", path: \"/operations/-\", value: op }]);\n const content: GenerativeUISurfaceContent = {\n surfaceId,\n target,\n catalogId: catalog,\n operations: [\n { version: \"v1.0\", createSurface: { surfaceId, catalogId: catalog } },\n ],\n status: \"streaming\",\n rejected: [],\n };\n emit({\n type: EventType.ACTIVITY_SNAPSHOT,\n messageId,\n activityType: GENERATIVE_UI_ACTIVITY_TYPE,\n content,\n replace: true,\n });\n return {\n setRoot: (node) =>\n append({\n version: \"v1.0\",\n updateComponents: {\n surfaceId,\n components: [\n { ...node, id: GENERATIVE_UI_ROOT_ID } as A2UIComponentNode,\n ],\n },\n }),\n upsert: (...nodes) =>\n append({\n version: \"v1.0\",\n updateComponents: { surfaceId, components: nodes },\n }),\n updateData: (path, value) =>\n append({\n version: \"v1.0\",\n updateDataModel: { surfaceId, path, value },\n }),\n close: () =>\n patch([{ op: \"replace\", path: \"/status\", value: \"ready\" }]),\n };\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;AA4BA,SAAgB,oBAAoB,MAAkC;AACpE,QAAO,EACL,YAAY,EACV,QACA,WACA,WAK4B;EAC5B,MAAM,iEAAyC,UAAU;EACzD,MAAM,SAAS,QACb,KAAK;GACH,MAAMA,wBAAU;GAChB;GACA,cAAcC;GACd,OAAO;GACR,CAAC;EACJ,MAAM,UAAU,OACd,MAAM,CAAC;GAAE,IAAI;GAAO,MAAM;GAAiB,OAAO;GAAI,CAAC,CAAC;EAC1D,MAAM,UAAsC;GAC1C;GACA;GACA,WAAW;GACX,YAAY,CACV;IAAE,SAAS;IAAQ,eAAe;KAAE;KAAW,WAAW;KAAS;IAAE,CACtE;GACD,QAAQ;GACR,UAAU,EAAE;GACb;AACD,OAAK;GACH,MAAMD,wBAAU;GAChB;GACA,cAAcC;GACd;GACA,SAAS;GACV,CAAC;AACF,SAAO;GACL,UAAU,SACR,OAAO;IACL,SAAS;IACT,kBAAkB;KAChB;KACA,YAAY,CACV;MAAE,GAAG;MAAM,IAAIC;MAAuB,CACvC;KACF;IACF,CAAC;GACJ,SAAS,GAAG,UACV,OAAO;IACL,SAAS;IACT,kBAAkB;KAAE;KAAW,YAAY;KAAO;IACnD,CAAC;GACJ,aAAa,MAAM,UACjB,OAAO;IACL,SAAS;IACT,iBAAiB;KAAE;KAAW;KAAM;KAAO;IAC5C,CAAC;GACJ,aACE,MAAM,CAAC;IAAE,IAAI;IAAW,MAAM;IAAW,OAAO;IAAS,CAAC,CAAC;GAC9D;IAEJ"}
@@ -0,0 +1,33 @@
1
+
2
+ import { A2UIComponentNode } from "@copilotkit/shared";
3
+ import { BaseEvent } from "@ag-ui/client";
4
+
5
+ //#region src/v2/runtime/generative-ui/surface-writer.d.ts
6
+ interface GenerativeUISurfaceWriter {
7
+ setRoot(node: Omit<A2UIComponentNode, "id">): void;
8
+ upsert(...nodes: A2UIComponentNode[]): void;
9
+ /** Sets `value` at `path`. A `null` value deletes the key at `path`. */
10
+ updateData(path: string, value: unknown): void;
11
+ close(): void;
12
+ }
13
+ /**
14
+ * Experimental. Programmatic façade for custom agents and workflows: emits the
15
+ * same `generative-ui-surface` activity events as `render_ui`, one per call.
16
+ * Every operation is A2UI v1.0.
17
+ * Does not validate against the browser manifest; the client still validates
18
+ * every operation before applying it.
19
+ */
20
+ declare function createSurfaceWriter(emit: (event: BaseEvent) => void): {
21
+ openSurface({
22
+ target,
23
+ surfaceId,
24
+ catalog
25
+ }: {
26
+ target: string;
27
+ surfaceId: string;
28
+ catalog: string;
29
+ }): GenerativeUISurfaceWriter;
30
+ };
31
+ //#endregion
32
+ export { GenerativeUISurfaceWriter, createSurfaceWriter };
33
+ //# sourceMappingURL=surface-writer.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"surface-writer.d.cts","names":[],"sources":["../../../../src/v2/runtime/generative-ui/surface-writer.ts"],"mappings":";;;;;UAaiB,yBAAA;EACf,OAAA,CAAQ,IAAA,EAAM,IAAA,CAAK,iBAAA;EACnB,MAAA,IAAU,KAAA,EAAO,iBAAA;EAFuB;EAIxC,UAAA,CAAW,IAAA,UAAc,KAAA;EACzB,KAAA;AAAA;;;;;;;;iBAUc,mBAAA,CAAoB,IAAA,GAAO,KAAA,EAAO,SAAA;;;;;;IAO5C,MAAA;IACA,SAAA;IACA,OAAA;EAAA,IACE,yBAAA;AAAA"}
@@ -0,0 +1,33 @@
1
+
2
+ import { A2UIComponentNode } from "@copilotkit/shared";
3
+ import { BaseEvent } from "@ag-ui/client";
4
+
5
+ //#region src/v2/runtime/generative-ui/surface-writer.d.ts
6
+ interface GenerativeUISurfaceWriter {
7
+ setRoot(node: Omit<A2UIComponentNode, "id">): void;
8
+ upsert(...nodes: A2UIComponentNode[]): void;
9
+ /** Sets `value` at `path`. A `null` value deletes the key at `path`. */
10
+ updateData(path: string, value: unknown): void;
11
+ close(): void;
12
+ }
13
+ /**
14
+ * Experimental. Programmatic façade for custom agents and workflows: emits the
15
+ * same `generative-ui-surface` activity events as `render_ui`, one per call.
16
+ * Every operation is A2UI v1.0.
17
+ * Does not validate against the browser manifest; the client still validates
18
+ * every operation before applying it.
19
+ */
20
+ declare function createSurfaceWriter(emit: (event: BaseEvent) => void): {
21
+ openSurface({
22
+ target,
23
+ surfaceId,
24
+ catalog
25
+ }: {
26
+ target: string;
27
+ surfaceId: string;
28
+ catalog: string;
29
+ }): GenerativeUISurfaceWriter;
30
+ };
31
+ //#endregion
32
+ export { GenerativeUISurfaceWriter, createSurfaceWriter };
33
+ //# sourceMappingURL=surface-writer.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"surface-writer.d.mts","names":[],"sources":["../../../../src/v2/runtime/generative-ui/surface-writer.ts"],"mappings":";;;;;UAaiB,yBAAA;EACf,OAAA,CAAQ,IAAA,EAAM,IAAA,CAAK,iBAAA;EACnB,MAAA,IAAU,KAAA,EAAO,iBAAA;EAFuB;EAIxC,UAAA,CAAW,IAAA,UAAc,KAAA;EACzB,KAAA;AAAA;;;;;;;;iBAUc,mBAAA,CAAoB,IAAA,GAAO,KAAA,EAAO,SAAA;;;;;;IAO5C,MAAA;IACA,SAAA;IACA,OAAA;EAAA,IACE,yBAAA;AAAA"}