@copilotkit/runtime 1.79.2-canary.1792172552 → 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.
- package/dist/_virtual/_rolldown/runtime.mjs +15 -1
- package/dist/agent/index.cjs.map +1 -1
- package/dist/agent/index.d.cts +5 -3
- package/dist/agent/index.d.cts.map +1 -1
- package/dist/agent/index.d.mts +4 -2
- package/dist/agent/index.d.mts.map +1 -1
- package/dist/agent/index.mjs.map +1 -1
- package/dist/lib/runtime/agent-integrations/langgraph/agent.cjs +25 -1
- package/dist/lib/runtime/agent-integrations/langgraph/agent.cjs.map +1 -1
- package/dist/lib/runtime/agent-integrations/langgraph/agent.d.cts.map +1 -1
- package/dist/lib/runtime/agent-integrations/langgraph/agent.d.mts.map +1 -1
- package/dist/lib/runtime/agent-integrations/langgraph/agent.mjs +25 -1
- package/dist/lib/runtime/agent-integrations/langgraph/agent.mjs.map +1 -1
- package/dist/lib/runtime/copilot-runtime.cjs +17 -3
- package/dist/lib/runtime/copilot-runtime.cjs.map +1 -1
- package/dist/lib/runtime/copilot-runtime.d.cts +2 -3
- package/dist/lib/runtime/copilot-runtime.d.cts.map +1 -1
- package/dist/lib/runtime/copilot-runtime.d.mts +2 -3
- package/dist/lib/runtime/copilot-runtime.d.mts.map +1 -1
- package/dist/lib/runtime/copilot-runtime.mjs +18 -4
- package/dist/lib/runtime/copilot-runtime.mjs.map +1 -1
- package/dist/lib/runtime/legacy-service-adapter-agent.cjs +360 -0
- package/dist/lib/runtime/legacy-service-adapter-agent.cjs.map +1 -0
- package/dist/lib/runtime/legacy-service-adapter-agent.mjs +359 -0
- package/dist/lib/runtime/legacy-service-adapter-agent.mjs.map +1 -0
- package/dist/lib/telemetry-client.cjs +12 -1
- package/dist/lib/telemetry-client.cjs.map +1 -1
- package/dist/lib/telemetry-client.mjs +12 -1
- package/dist/lib/telemetry-client.mjs.map +1 -1
- package/dist/package.cjs +6 -6
- package/dist/package.mjs +6 -6
- package/dist/service-adapters/events.cjs +91 -0
- package/dist/service-adapters/events.cjs.map +1 -1
- package/dist/service-adapters/events.d.cts +6 -1
- package/dist/service-adapters/events.d.cts.map +1 -1
- package/dist/service-adapters/events.d.mts +6 -1
- package/dist/service-adapters/events.d.mts.map +1 -1
- package/dist/service-adapters/events.mjs +90 -1
- package/dist/service-adapters/events.mjs.map +1 -1
- package/dist/service-adapters/langchain/langchain-adapter.cjs +1 -1
- package/dist/service-adapters/langchain/langchain-adapter.cjs.map +1 -1
- package/dist/service-adapters/langchain/langchain-adapter.d.cts.map +1 -1
- package/dist/service-adapters/langchain/langchain-adapter.d.mts.map +1 -1
- package/dist/service-adapters/langchain/langchain-adapter.mjs +2 -2
- package/dist/service-adapters/langchain/langchain-adapter.mjs.map +1 -1
- package/dist/service-adapters/langchain/utils.cjs +53 -15
- package/dist/service-adapters/langchain/utils.cjs.map +1 -1
- package/dist/service-adapters/langchain/utils.mjs +53 -16
- package/dist/service-adapters/langchain/utils.mjs.map +1 -1
- package/dist/v2/index.cjs +6 -0
- package/dist/v2/index.d.cts +7 -4
- package/dist/v2/index.d.mts +7 -4
- package/dist/v2/index.mjs +5 -3
- package/dist/v2/runtime/core/middleware-sse-parser.cjs +11 -2
- package/dist/v2/runtime/core/middleware-sse-parser.cjs.map +1 -1
- package/dist/v2/runtime/core/middleware-sse-parser.mjs +11 -2
- package/dist/v2/runtime/core/middleware-sse-parser.mjs.map +1 -1
- package/dist/v2/runtime/core/package-info.cjs +1 -1
- package/dist/v2/runtime/core/package-info.mjs +1 -1
- package/dist/v2/runtime/core/runtime.cjs +6 -3
- package/dist/v2/runtime/core/runtime.cjs.map +1 -1
- package/dist/v2/runtime/core/runtime.d.cts +15 -3
- package/dist/v2/runtime/core/runtime.d.cts.map +1 -1
- package/dist/v2/runtime/core/runtime.d.mts +15 -3
- package/dist/v2/runtime/core/runtime.d.mts.map +1 -1
- package/dist/v2/runtime/core/runtime.mjs +6 -3
- package/dist/v2/runtime/core/runtime.mjs.map +1 -1
- package/dist/v2/runtime/endpoints/express.cjs +2 -2
- package/dist/v2/runtime/endpoints/express.cjs.map +1 -1
- package/dist/v2/runtime/endpoints/express.mjs +2 -2
- package/dist/v2/runtime/endpoints/express.mjs.map +1 -1
- package/dist/v2/runtime/endpoints/node-fetch-handler.cjs +51 -1
- package/dist/v2/runtime/endpoints/node-fetch-handler.cjs.map +1 -1
- package/dist/v2/runtime/endpoints/node-fetch-handler.d.cts.map +1 -1
- package/dist/v2/runtime/endpoints/node-fetch-handler.d.mts.map +1 -1
- package/dist/v2/runtime/endpoints/node-fetch-handler.mjs +52 -2
- package/dist/v2/runtime/endpoints/node-fetch-handler.mjs.map +1 -1
- package/dist/v2/runtime/generative-ui/generative-ui-middleware.cjs +394 -0
- package/dist/v2/runtime/generative-ui/generative-ui-middleware.cjs.map +1 -0
- package/dist/v2/runtime/generative-ui/generative-ui-middleware.d.cts +21 -0
- package/dist/v2/runtime/generative-ui/generative-ui-middleware.d.cts.map +1 -0
- package/dist/v2/runtime/generative-ui/generative-ui-middleware.d.mts +21 -0
- package/dist/v2/runtime/generative-ui/generative-ui-middleware.d.mts.map +1 -0
- package/dist/v2/runtime/generative-ui/generative-ui-middleware.mjs +393 -0
- package/dist/v2/runtime/generative-ui/generative-ui-middleware.mjs.map +1 -0
- package/dist/v2/runtime/generative-ui/index.d.cts +3 -0
- package/dist/v2/runtime/generative-ui/index.d.mts +3 -0
- package/dist/v2/runtime/generative-ui/surface-writer.cjs +86 -0
- package/dist/v2/runtime/generative-ui/surface-writer.cjs.map +1 -0
- package/dist/v2/runtime/generative-ui/surface-writer.d.cts +33 -0
- package/dist/v2/runtime/generative-ui/surface-writer.d.cts.map +1 -0
- package/dist/v2/runtime/generative-ui/surface-writer.d.mts +33 -0
- package/dist/v2/runtime/generative-ui/surface-writer.d.mts.map +1 -0
- package/dist/v2/runtime/generative-ui/surface-writer.mjs +85 -0
- package/dist/v2/runtime/generative-ui/surface-writer.mjs.map +1 -0
- package/dist/v2/runtime/handlers/handle-run.cjs +8 -3
- package/dist/v2/runtime/handlers/handle-run.cjs.map +1 -1
- package/dist/v2/runtime/handlers/handle-run.mjs +5 -1
- package/dist/v2/runtime/handlers/handle-run.mjs.map +1 -1
- package/dist/v2/runtime/handlers/intelligence/run.cjs +2 -3
- package/dist/v2/runtime/handlers/intelligence/run.cjs.map +1 -1
- package/dist/v2/runtime/handlers/intelligence/run.mjs +2 -3
- package/dist/v2/runtime/handlers/intelligence/run.mjs.map +1 -1
- package/dist/v2/runtime/handlers/shared/agent-utils.cjs +7 -0
- package/dist/v2/runtime/handlers/shared/agent-utils.cjs.map +1 -1
- package/dist/v2/runtime/handlers/shared/agent-utils.mjs +7 -0
- package/dist/v2/runtime/handlers/shared/agent-utils.mjs.map +1 -1
- package/dist/v2/runtime/handlers/shared/sse-response.cjs +39 -0
- package/dist/v2/runtime/handlers/shared/sse-response.cjs.map +1 -1
- package/dist/v2/runtime/handlers/shared/sse-response.mjs +39 -0
- package/dist/v2/runtime/handlers/shared/sse-response.mjs.map +1 -1
- package/dist/v2/runtime/index.d.cts +7 -3
- package/dist/v2/runtime/index.d.cts.map +1 -1
- package/dist/v2/runtime/index.d.mts +7 -3
- package/dist/v2/runtime/index.d.mts.map +1 -1
- package/dist/v2/runtime/intelligence-platform/client.cjs +100 -1
- package/dist/v2/runtime/intelligence-platform/client.cjs.map +1 -1
- package/dist/v2/runtime/intelligence-platform/client.d.cts +33 -1
- package/dist/v2/runtime/intelligence-platform/client.d.cts.map +1 -1
- package/dist/v2/runtime/intelligence-platform/client.d.mts +33 -1
- package/dist/v2/runtime/intelligence-platform/client.d.mts.map +1 -1
- package/dist/v2/runtime/intelligence-platform/client.mjs +100 -1
- package/dist/v2/runtime/intelligence-platform/client.mjs.map +1 -1
- package/dist/v2/runtime/intelligence-platform/experimental.d.cts +27 -0
- package/dist/v2/runtime/intelligence-platform/experimental.d.cts.map +1 -0
- package/dist/v2/runtime/intelligence-platform/experimental.d.mts +27 -0
- package/dist/v2/runtime/intelligence-platform/experimental.d.mts.map +1 -0
- package/dist/v2/runtime/intelligence-platform/index.d.cts +2 -1
- package/dist/v2/runtime/intelligence-platform/index.d.mts +2 -1
- package/dist/v2/runtime/intelligence-platform/learning-management.cjs +204 -0
- package/dist/v2/runtime/intelligence-platform/learning-management.cjs.map +1 -0
- package/dist/v2/runtime/intelligence-platform/learning-management.d.cts +112 -0
- package/dist/v2/runtime/intelligence-platform/learning-management.d.cts.map +1 -0
- package/dist/v2/runtime/intelligence-platform/learning-management.d.mts +112 -0
- package/dist/v2/runtime/intelligence-platform/learning-management.d.mts.map +1 -0
- package/dist/v2/runtime/intelligence-platform/learning-management.mjs +194 -0
- package/dist/v2/runtime/intelligence-platform/learning-management.mjs.map +1 -0
- package/dist/v2/runtime/runner/agent-runner.cjs +16 -0
- package/dist/v2/runtime/runner/agent-runner.cjs.map +1 -1
- package/dist/v2/runtime/runner/agent-runner.d.cts +11 -1
- package/dist/v2/runtime/runner/agent-runner.d.cts.map +1 -1
- package/dist/v2/runtime/runner/agent-runner.d.mts +11 -1
- package/dist/v2/runtime/runner/agent-runner.d.mts.map +1 -1
- package/dist/v2/runtime/runner/agent-runner.mjs +16 -1
- package/dist/v2/runtime/runner/agent-runner.mjs.map +1 -1
- package/dist/v2/runtime/runner/in-memory.cjs +1 -1
- package/dist/v2/runtime/runner/in-memory.cjs.map +1 -1
- package/dist/v2/runtime/runner/in-memory.mjs +2 -2
- package/dist/v2/runtime/runner/in-memory.mjs.map +1 -1
- package/dist/v2/runtime/runner/index.d.cts +2 -2
- package/dist/v2/runtime/runner/index.d.mts +2 -2
- package/dist/v2/runtime/runner/index.mjs +1 -1
- package/dist/v2/runtime/runner/intelligence.cjs +25 -85
- package/dist/v2/runtime/runner/intelligence.cjs.map +1 -1
- package/dist/v2/runtime/runner/intelligence.d.cts +2 -31
- package/dist/v2/runtime/runner/intelligence.d.cts.map +1 -1
- package/dist/v2/runtime/runner/intelligence.d.mts +2 -31
- package/dist/v2/runtime/runner/intelligence.d.mts.map +1 -1
- package/dist/v2/runtime/runner/intelligence.mjs +27 -87
- package/dist/v2/runtime/runner/intelligence.mjs.map +1 -1
- package/package.json +8 -8
- package/dist/v2/runtime/endpoints/express-fetch-bridge.cjs +0 -82
- package/dist/v2/runtime/endpoints/express-fetch-bridge.cjs.map +0 -1
- package/dist/v2/runtime/endpoints/express-fetch-bridge.mjs +0 -81
- package/dist/v2/runtime/endpoints/express-fetch-bridge.mjs.map +0 -1
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
require("reflect-metadata");
|
|
2
|
+
const require_runtime = require('../../../_virtual/_rolldown/runtime.cjs');
|
|
3
|
+
let _copilotkit_shared = require("@copilotkit/shared");
|
|
4
|
+
let rxjs = require("rxjs");
|
|
5
|
+
let _ag_ui_client = require("@ag-ui/client");
|
|
6
|
+
|
|
7
|
+
//#region src/v2/runtime/generative-ui/generative-ui-middleware.ts
|
|
8
|
+
function isRecord(value) {
|
|
9
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Builds the manifest from the generative UI envelope
|
|
13
|
+
* (`forwardedProps.copilotkit.ui`). The client sends the envelope, so it is
|
|
14
|
+
* not trusted: `readCopilotKitUIEnvelope` checks every field, and
|
|
15
|
+
* `envelopeToManifest` turns it into the manifest. Returns
|
|
16
|
+
* `undefined` (the run passes through) when:
|
|
17
|
+
* - there is no valid envelope;
|
|
18
|
+
* - the transport is "markdown" (the model writes fences, not render_ui);
|
|
19
|
+
* - the catalog has no components (the server cannot validate operations).
|
|
20
|
+
*/
|
|
21
|
+
function readManifest(forwardedProps) {
|
|
22
|
+
const envelope = (0, _copilotkit_shared.readCopilotKitUIEnvelope)(forwardedProps);
|
|
23
|
+
if (!envelope) return void 0;
|
|
24
|
+
const manifest = (0, _copilotkit_shared.envelopeToManifest)(envelope);
|
|
25
|
+
return manifest.transport === "tool" && manifest.hasComponents ? manifest : void 0;
|
|
26
|
+
}
|
|
27
|
+
function prepareInput(input, manifest) {
|
|
28
|
+
const tools = (input.tools ?? []).filter((t) => t.name !== _copilotkit_shared.GENERATIVE_UI_RENDER_TOOL);
|
|
29
|
+
tools.push({
|
|
30
|
+
name: _copilotkit_shared.GENERATIVE_UI_RENDER_TOOL,
|
|
31
|
+
description: "Render or update generative UI surfaces, or call app functions, with A2UI v1.0 operations. Follow the generative UI guide in context.",
|
|
32
|
+
parameters: {
|
|
33
|
+
type: "object",
|
|
34
|
+
properties: {
|
|
35
|
+
target: {
|
|
36
|
+
type: "string",
|
|
37
|
+
enum: manifest.targets.map((t) => t.id),
|
|
38
|
+
description: "Where the surface is shown: \"chat\" or a named inline target."
|
|
39
|
+
},
|
|
40
|
+
operations: {
|
|
41
|
+
type: "array",
|
|
42
|
+
description: "A2UI v1.0 operations, applied in order.",
|
|
43
|
+
items: { type: "object" }
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
required: ["target", "operations"]
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
const context = (input.context ?? []).filter((c) => c.description !== _copilotkit_shared.GENERATIVE_UI_CONTEXT_DESCRIPTION);
|
|
50
|
+
context.push({
|
|
51
|
+
description: _copilotkit_shared.GENERATIVE_UI_CONTEXT_DESCRIPTION,
|
|
52
|
+
value: (0, _copilotkit_shared.buildGenerativeUIPrompt)(manifest)
|
|
53
|
+
});
|
|
54
|
+
return {
|
|
55
|
+
...input,
|
|
56
|
+
tools,
|
|
57
|
+
context
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Experimental. Lets an agent render CopilotKit generative UI surfaces via the
|
|
62
|
+
* `render_ui` tool. It applies only to runs whose generative UI envelope uses
|
|
63
|
+
* the "tool" transport. Each complete operation in the streamed arguments is
|
|
64
|
+
* validated against the catalog in the envelope and committed immediately:
|
|
65
|
+
* - `ACTIVITY_SNAPSHOT` for a new surface, `ACTIVITY_DELTA` for every further
|
|
66
|
+
* operation on it.
|
|
67
|
+
* - One `ACTIVITY_SNAPSHOT` of type `generative-ui-function-call` for each
|
|
68
|
+
* `callRendererFunction`. The client runs the function.
|
|
69
|
+
*/
|
|
70
|
+
var GenerativeUIMiddleware = class extends _ag_ui_client.Middleware {
|
|
71
|
+
run(input, next) {
|
|
72
|
+
const manifest = readManifest(input.forwardedProps);
|
|
73
|
+
if (!manifest) return this.runNext(input, next);
|
|
74
|
+
return processStream(this.runNextWithState(prepareInput(input, manifest), next), manifest);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* The first time a render_ui call touches an existing surface, mark it
|
|
79
|
+
* streaming and clear its rejection list: earlier calls' rejections were
|
|
80
|
+
* already reported to the model in their own tool results, and a repaired
|
|
81
|
+
* surface must not keep showing them. A surface created by this call starts
|
|
82
|
+
* with an empty list in its snapshot.
|
|
83
|
+
*/
|
|
84
|
+
function beginSurfaceUpdate(state, surfaceId) {
|
|
85
|
+
if (state.touched.has(surfaceId)) return [];
|
|
86
|
+
state.touched.add(surfaceId);
|
|
87
|
+
return [{
|
|
88
|
+
op: "replace",
|
|
89
|
+
path: "/status",
|
|
90
|
+
value: "streaming"
|
|
91
|
+
}, {
|
|
92
|
+
op: "replace",
|
|
93
|
+
path: "/rejected",
|
|
94
|
+
value: []
|
|
95
|
+
}];
|
|
96
|
+
}
|
|
97
|
+
function processStream(source, manifest) {
|
|
98
|
+
return new rxjs.Observable((subscriber) => {
|
|
99
|
+
const entries = Object.entries(manifest.surfaces);
|
|
100
|
+
const surfaces = new Map(entries.filter(([, s]) => !s.status).map(([id, s]) => [id, s.target]));
|
|
101
|
+
const createdSurfaces = new Set(entries.filter(([, s]) => s.status !== "failed").map(([id]) => id));
|
|
102
|
+
const targetComponents = new Map(manifest.targets.filter((t) => t.components !== void 0).map((t) => [t.id, new Set(t.components)]));
|
|
103
|
+
const functionCallIds = /* @__PURE__ */ new Set();
|
|
104
|
+
const calls = /* @__PURE__ */ new Map();
|
|
105
|
+
let heldFinish = null;
|
|
106
|
+
const emit = (event) => subscriber.next(event);
|
|
107
|
+
const patch = (surfaceId, ops) => emit({
|
|
108
|
+
type: _ag_ui_client.EventType.ACTIVITY_DELTA,
|
|
109
|
+
messageId: (0, _copilotkit_shared.generativeUISurfaceMessageId)(surfaceId),
|
|
110
|
+
activityType: _copilotkit_shared.GENERATIVE_UI_ACTIVITY_TYPE,
|
|
111
|
+
patch: ops
|
|
112
|
+
});
|
|
113
|
+
const processOperation = (state, op) => {
|
|
114
|
+
const index = state.nextIndex++;
|
|
115
|
+
const reject = (reason, surfaceId) => {
|
|
116
|
+
const entry = {
|
|
117
|
+
index,
|
|
118
|
+
reason
|
|
119
|
+
};
|
|
120
|
+
state.rejected.push(entry);
|
|
121
|
+
if (surfaceId && surfaces.has(surfaceId)) patch(surfaceId, [...beginSurfaceUpdate(state, surfaceId), {
|
|
122
|
+
op: "add",
|
|
123
|
+
path: "/rejected/-",
|
|
124
|
+
value: entry
|
|
125
|
+
}]);
|
|
126
|
+
};
|
|
127
|
+
if (op === null) return reject("operation is not valid JSON");
|
|
128
|
+
let surfaceId;
|
|
129
|
+
try {
|
|
130
|
+
surfaceId = (0, _copilotkit_shared.getOperationSurfaceId)(op);
|
|
131
|
+
applyOperation(state, withCatalogId(op), surfaceId, reject);
|
|
132
|
+
} catch (error) {
|
|
133
|
+
reject(`operation could not be processed: ${error instanceof Error ? error.message : String(error)}`, surfaceId);
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
/**
|
|
137
|
+
* The model does not have to name the catalog. A createSurface keeps a
|
|
138
|
+
* catalogId that the envelope lists, and gets the catalog id of the run
|
|
139
|
+
* for any other value. The whole operation, with its inline components
|
|
140
|
+
* and data model, stays in the snapshot.
|
|
141
|
+
*/
|
|
142
|
+
const catalogIds = manifest.catalogIds ?? [manifest.catalogId];
|
|
143
|
+
const withCatalogId = (op) => {
|
|
144
|
+
const create = op.createSurface;
|
|
145
|
+
if (!isRecord(create)) return op;
|
|
146
|
+
const catalogId = catalogIds.includes(create.catalogId) ? create.catalogId : manifest.catalogId;
|
|
147
|
+
return {
|
|
148
|
+
...op,
|
|
149
|
+
createSurface: {
|
|
150
|
+
...create,
|
|
151
|
+
catalogId
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
};
|
|
155
|
+
/**
|
|
156
|
+
* The components that the target of the surface takes. A createSurface
|
|
157
|
+
* goes to the target of the render_ui call. Every other operation goes to
|
|
158
|
+
* the target that the surface was created on.
|
|
159
|
+
*/
|
|
160
|
+
const allowedComponentsFor = (state, op, surfaceId) => {
|
|
161
|
+
const target = (0, _copilotkit_shared.getOperationKind)(op) === "createSurface" ? state.target : surfaces.get(surfaceId);
|
|
162
|
+
const names = targetComponents.get(target);
|
|
163
|
+
return names && {
|
|
164
|
+
target,
|
|
165
|
+
names
|
|
166
|
+
};
|
|
167
|
+
};
|
|
168
|
+
const applyOperation = (state, op, surfaceId, reject) => {
|
|
169
|
+
const validation = (0, _copilotkit_shared.validateOperation)(op, {
|
|
170
|
+
manifest,
|
|
171
|
+
knownSurfaces: new Set(surfaces.keys()),
|
|
172
|
+
createdSurfaces,
|
|
173
|
+
functions: manifest.functions,
|
|
174
|
+
allowedComponents: allowedComponentsFor(state, op, surfaceId)
|
|
175
|
+
});
|
|
176
|
+
if (validation.ok === false) return reject(validation.reason, surfaceId);
|
|
177
|
+
const accepted = op;
|
|
178
|
+
if ("callRendererFunction" in accepted) return callRendererFunction(state, accepted.callRendererFunction, reject);
|
|
179
|
+
if ("createSurface" in accepted) return createSurface(state, surfaceId, accepted, reject);
|
|
180
|
+
patch(surfaceId, [...beginSurfaceUpdate(state, surfaceId), {
|
|
181
|
+
op: "add",
|
|
182
|
+
path: "/operations/-",
|
|
183
|
+
value: accepted
|
|
184
|
+
}]);
|
|
185
|
+
if ("deleteSurface" in accepted) surfaces.delete(surfaceId);
|
|
186
|
+
state.applied++;
|
|
187
|
+
};
|
|
188
|
+
const createSurface = (state, surfaceId, op, reject) => {
|
|
189
|
+
const { target } = state;
|
|
190
|
+
if (target === void 0) return reject("render_ui was called without a target");
|
|
191
|
+
if (!manifest.targets.some((t) => t.id === target)) return reject(`target "${target}" is not mounted`);
|
|
192
|
+
surfaces.set(surfaceId, target);
|
|
193
|
+
createdSurfaces.add(surfaceId);
|
|
194
|
+
const content = {
|
|
195
|
+
surfaceId,
|
|
196
|
+
target,
|
|
197
|
+
catalogId: "createSurface" in op && op.createSurface.catalogId || manifest.catalogId,
|
|
198
|
+
operations: [op],
|
|
199
|
+
status: "streaming",
|
|
200
|
+
rejected: []
|
|
201
|
+
};
|
|
202
|
+
emit({
|
|
203
|
+
type: _ag_ui_client.EventType.ACTIVITY_SNAPSHOT,
|
|
204
|
+
messageId: (0, _copilotkit_shared.generativeUISurfaceMessageId)(surfaceId),
|
|
205
|
+
activityType: _copilotkit_shared.GENERATIVE_UI_ACTIVITY_TYPE,
|
|
206
|
+
content,
|
|
207
|
+
replace: true
|
|
208
|
+
});
|
|
209
|
+
state.touched.add(surfaceId);
|
|
210
|
+
state.applied++;
|
|
211
|
+
};
|
|
212
|
+
/**
|
|
213
|
+
* Sends one function call to the client, which runs it. A function call
|
|
214
|
+
* needs no target and no surface. Each `functionCallId` runs once.
|
|
215
|
+
*/
|
|
216
|
+
const callRendererFunction = (state, content, reject) => {
|
|
217
|
+
const { functionCallId } = content;
|
|
218
|
+
if (functionCallIds.has(functionCallId)) return reject(`functionCallId "${functionCallId}" was used before; use a new functionCallId`);
|
|
219
|
+
functionCallIds.add(functionCallId);
|
|
220
|
+
emit({
|
|
221
|
+
type: _ag_ui_client.EventType.ACTIVITY_SNAPSHOT,
|
|
222
|
+
messageId: (0, _copilotkit_shared.generativeUIFunctionCallMessageId)(functionCallId),
|
|
223
|
+
activityType: _copilotkit_shared.GENERATIVE_UI_FUNCTION_CALL_ACTIVITY_TYPE,
|
|
224
|
+
content: {
|
|
225
|
+
functionCallId,
|
|
226
|
+
callFunction: content.callFunction
|
|
227
|
+
},
|
|
228
|
+
replace: true
|
|
229
|
+
});
|
|
230
|
+
state.calls++;
|
|
231
|
+
};
|
|
232
|
+
/** Same buffering rule as streamed ops: hold them until the target is known. */
|
|
233
|
+
const acceptOperation = (state, op) => {
|
|
234
|
+
if (state.target === void 0) state.buffered.push(op);
|
|
235
|
+
else processOperation(state, op);
|
|
236
|
+
};
|
|
237
|
+
/**
|
|
238
|
+
* The streaming parser found no operations at all. Models sometimes send
|
|
239
|
+
* `operations` as a JSON-encoded string; recover those from the complete
|
|
240
|
+
* arguments. Anything still unusable leaves the call with zero operations,
|
|
241
|
+
* which the tool result reports as an error.
|
|
242
|
+
*/
|
|
243
|
+
const recoverOperations = (state) => {
|
|
244
|
+
let args;
|
|
245
|
+
try {
|
|
246
|
+
args = JSON.parse(state.stream.text);
|
|
247
|
+
} catch {
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
if (!isRecord(args)) return;
|
|
251
|
+
if (state.target === void 0 && typeof args.target === "string") state.target = args.target;
|
|
252
|
+
let operations = args.operations;
|
|
253
|
+
if (typeof operations === "string") try {
|
|
254
|
+
operations = JSON.parse(operations);
|
|
255
|
+
} catch {
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
if (!Array.isArray(operations)) return;
|
|
259
|
+
for (const op of operations) acceptOperation(state, isRecord(op) ? op : null);
|
|
260
|
+
};
|
|
261
|
+
const finishCall = (state) => {
|
|
262
|
+
if (state.finished) return;
|
|
263
|
+
state.finished = true;
|
|
264
|
+
if (state.nextIndex === 0 && state.buffered.length === 0) recoverOperations(state);
|
|
265
|
+
if (state.target === void 0) {
|
|
266
|
+
const buffered = state.buffered;
|
|
267
|
+
state.buffered = [];
|
|
268
|
+
for (const op of buffered) {
|
|
269
|
+
if ((0, _copilotkit_shared.getOperationKind)(op) === "callRendererFunction") {
|
|
270
|
+
processOperation(state, op);
|
|
271
|
+
continue;
|
|
272
|
+
}
|
|
273
|
+
state.rejected.push({
|
|
274
|
+
index: state.nextIndex++,
|
|
275
|
+
reason: "render_ui was called without a target"
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
if (state.stream.hasIncompleteOperation) state.rejected.push({
|
|
280
|
+
index: state.nextIndex++,
|
|
281
|
+
reason: "operation was truncated"
|
|
282
|
+
});
|
|
283
|
+
for (const id of state.touched) patch(id, [{
|
|
284
|
+
op: "replace",
|
|
285
|
+
path: "/status",
|
|
286
|
+
value: "ready"
|
|
287
|
+
}]);
|
|
288
|
+
};
|
|
289
|
+
const flushFinish = () => {
|
|
290
|
+
if (heldFinish) {
|
|
291
|
+
emit(heldFinish.event);
|
|
292
|
+
heldFinish = null;
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
const handleEvent = ({ event, messages }) => {
|
|
296
|
+
flushFinish();
|
|
297
|
+
if (event.type === _ag_ui_client.EventType.RUN_FINISHED) {
|
|
298
|
+
heldFinish = {
|
|
299
|
+
event,
|
|
300
|
+
messages
|
|
301
|
+
};
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
emit(event);
|
|
305
|
+
if (event.type === _ag_ui_client.EventType.TOOL_CALL_START) {
|
|
306
|
+
const start = event;
|
|
307
|
+
if (start.toolCallName === _copilotkit_shared.GENERATIVE_UI_RENDER_TOOL) calls.set(start.toolCallId, {
|
|
308
|
+
stream: new _copilotkit_shared.RenderUIArgsStream(),
|
|
309
|
+
buffered: [],
|
|
310
|
+
nextIndex: 0,
|
|
311
|
+
applied: 0,
|
|
312
|
+
calls: 0,
|
|
313
|
+
rejected: [],
|
|
314
|
+
touched: /* @__PURE__ */ new Set(),
|
|
315
|
+
finished: false
|
|
316
|
+
});
|
|
317
|
+
} else if (event.type === _ag_ui_client.EventType.TOOL_CALL_ARGS) {
|
|
318
|
+
const args = event;
|
|
319
|
+
const state = calls.get(args.toolCallId);
|
|
320
|
+
if (!state || state.finished) return;
|
|
321
|
+
const { target, newOperations } = state.stream.push(args.delta);
|
|
322
|
+
if (target !== void 0 && state.target === void 0) {
|
|
323
|
+
state.target = target;
|
|
324
|
+
const buffered = state.buffered;
|
|
325
|
+
state.buffered = [];
|
|
326
|
+
for (const op of buffered) processOperation(state, op);
|
|
327
|
+
}
|
|
328
|
+
for (const op of newOperations) acceptOperation(state, op);
|
|
329
|
+
} else if (event.type === _ag_ui_client.EventType.TOOL_CALL_END) {
|
|
330
|
+
const state = calls.get(event.toolCallId);
|
|
331
|
+
if (state) finishCall(state);
|
|
332
|
+
}
|
|
333
|
+
};
|
|
334
|
+
const completeRun = () => {
|
|
335
|
+
for (const state of calls.values()) finishCall(state);
|
|
336
|
+
if (heldFinish) {
|
|
337
|
+
const answered = new Set(heldFinish.messages.filter((m) => m.role === "tool").map((m) => m.toolCallId));
|
|
338
|
+
for (const [toolCallId, state] of calls) {
|
|
339
|
+
if (answered.has(toolCallId)) continue;
|
|
340
|
+
const nothingParsed = state.applied === 0 && state.calls === 0 && state.rejected.length === 0;
|
|
341
|
+
emit({
|
|
342
|
+
type: _ag_ui_client.EventType.TOOL_CALL_RESULT,
|
|
343
|
+
messageId: (0, _copilotkit_shared.randomUUID)(),
|
|
344
|
+
toolCallId,
|
|
345
|
+
content: JSON.stringify(nothingParsed ? {
|
|
346
|
+
status: "error",
|
|
347
|
+
applied: 0,
|
|
348
|
+
calls: 0,
|
|
349
|
+
rejected: [],
|
|
350
|
+
reason: "operations must be a JSON array of A2UI operation objects; nothing was rendered"
|
|
351
|
+
} : {
|
|
352
|
+
status: "rendered",
|
|
353
|
+
applied: state.applied,
|
|
354
|
+
calls: state.calls,
|
|
355
|
+
rejected: state.rejected
|
|
356
|
+
})
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
flushFinish();
|
|
360
|
+
}
|
|
361
|
+
subscriber.complete();
|
|
362
|
+
};
|
|
363
|
+
let failed = false;
|
|
364
|
+
const subscription = source.subscribe({
|
|
365
|
+
next: (item) => {
|
|
366
|
+
if (failed) return;
|
|
367
|
+
try {
|
|
368
|
+
handleEvent(item);
|
|
369
|
+
} catch (error) {
|
|
370
|
+
failed = true;
|
|
371
|
+
subscriber.error(error);
|
|
372
|
+
}
|
|
373
|
+
},
|
|
374
|
+
error: (error) => {
|
|
375
|
+
flushFinish();
|
|
376
|
+
subscriber.error(error);
|
|
377
|
+
},
|
|
378
|
+
complete: () => {
|
|
379
|
+
if (failed) return;
|
|
380
|
+
try {
|
|
381
|
+
completeRun();
|
|
382
|
+
} catch (error) {
|
|
383
|
+
failed = true;
|
|
384
|
+
subscriber.error(error);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
return () => subscription.unsubscribe();
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
//#endregion
|
|
393
|
+
exports.GenerativeUIMiddleware = GenerativeUIMiddleware;
|
|
394
|
+
//# sourceMappingURL=generative-ui-middleware.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generative-ui-middleware.cjs","names":["GENERATIVE_UI_RENDER_TOOL","GENERATIVE_UI_CONTEXT_DESCRIPTION","Middleware","Observable","EventType","GENERATIVE_UI_ACTIVITY_TYPE","GENERATIVE_UI_FUNCTION_CALL_ACTIVITY_TYPE","RenderUIArgsStream"],"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,21 @@
|
|
|
1
|
+
|
|
2
|
+
import { AbstractAgent, BaseEvent, Middleware, RunAgentInput } from "@ag-ui/client";
|
|
3
|
+
import { Observable } from "rxjs";
|
|
4
|
+
|
|
5
|
+
//#region src/v2/runtime/generative-ui/generative-ui-middleware.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Experimental. Lets an agent render CopilotKit generative UI surfaces via the
|
|
8
|
+
* `render_ui` tool. It applies only to runs whose generative UI envelope uses
|
|
9
|
+
* the "tool" transport. Each complete operation in the streamed arguments is
|
|
10
|
+
* validated against the catalog in the envelope and committed immediately:
|
|
11
|
+
* - `ACTIVITY_SNAPSHOT` for a new surface, `ACTIVITY_DELTA` for every further
|
|
12
|
+
* operation on it.
|
|
13
|
+
* - One `ACTIVITY_SNAPSHOT` of type `generative-ui-function-call` for each
|
|
14
|
+
* `callRendererFunction`. The client runs the function.
|
|
15
|
+
*/
|
|
16
|
+
declare class GenerativeUIMiddleware extends Middleware {
|
|
17
|
+
run(input: RunAgentInput, next: AbstractAgent): Observable<BaseEvent>;
|
|
18
|
+
}
|
|
19
|
+
//#endregion
|
|
20
|
+
export { GenerativeUIMiddleware };
|
|
21
|
+
//# sourceMappingURL=generative-ui-middleware.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generative-ui-middleware.d.cts","names":[],"sources":["../../../../src/v2/runtime/generative-ui/generative-ui-middleware.ts"],"mappings":";;;;;;AA4HA;;;;;;;;;cAAa,sBAAA,SAA+B,UAAA;EAC1C,GAAA,CAAI,KAAA,EAAO,aAAA,EAAe,IAAA,EAAM,aAAA,GAAgB,UAAA,CAAW,SAAA;AAAA"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
|
|
2
|
+
import { Observable } from "rxjs";
|
|
3
|
+
import { AbstractAgent, BaseEvent, Middleware, RunAgentInput } from "@ag-ui/client";
|
|
4
|
+
|
|
5
|
+
//#region src/v2/runtime/generative-ui/generative-ui-middleware.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Experimental. Lets an agent render CopilotKit generative UI surfaces via the
|
|
8
|
+
* `render_ui` tool. It applies only to runs whose generative UI envelope uses
|
|
9
|
+
* the "tool" transport. Each complete operation in the streamed arguments is
|
|
10
|
+
* validated against the catalog in the envelope and committed immediately:
|
|
11
|
+
* - `ACTIVITY_SNAPSHOT` for a new surface, `ACTIVITY_DELTA` for every further
|
|
12
|
+
* operation on it.
|
|
13
|
+
* - One `ACTIVITY_SNAPSHOT` of type `generative-ui-function-call` for each
|
|
14
|
+
* `callRendererFunction`. The client runs the function.
|
|
15
|
+
*/
|
|
16
|
+
declare class GenerativeUIMiddleware extends Middleware {
|
|
17
|
+
run(input: RunAgentInput, next: AbstractAgent): Observable<BaseEvent>;
|
|
18
|
+
}
|
|
19
|
+
//#endregion
|
|
20
|
+
export { GenerativeUIMiddleware };
|
|
21
|
+
//# sourceMappingURL=generative-ui-middleware.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generative-ui-middleware.d.mts","names":[],"sources":["../../../../src/v2/runtime/generative-ui/generative-ui-middleware.ts"],"mappings":";;;;;;AA4HA;;;;;;;;;cAAa,sBAAA,SAA+B,UAAA;EAC1C,GAAA,CAAI,KAAA,EAAO,aAAA,EAAe,IAAA,EAAM,aAAA,GAAgB,UAAA,CAAW,SAAA;AAAA"}
|