veryfront 0.1.180 → 0.1.181
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/esm/deno.js +1 -1
- package/esm/src/agent/ag-ui-browser-encoder.d.ts +31 -0
- package/esm/src/agent/ag-ui-browser-encoder.d.ts.map +1 -0
- package/esm/src/agent/ag-ui-browser-encoder.js +330 -0
- package/esm/src/agent/index.d.ts +1 -0
- package/esm/src/agent/index.d.ts.map +1 -1
- package/esm/src/agent/index.js +1 -0
- package/esm/src/internal-agents/ag-ui-sse.d.ts +8 -28
- package/esm/src/internal-agents/ag-ui-sse.d.ts.map +1 -1
- package/esm/src/internal-agents/ag-ui-sse.js +14 -218
- package/esm/src/rendering/orchestrator/pipeline.d.ts +1 -0
- package/esm/src/rendering/orchestrator/pipeline.d.ts.map +1 -1
- package/esm/src/rendering/orchestrator/pipeline.js +9 -6
- package/esm/src/utils/version-constant.d.ts +1 -1
- package/esm/src/utils/version-constant.js +1 -1
- package/package.json +1 -1
- package/src/deno.js +1 -1
- package/src/src/agent/ag-ui-browser-encoder.ts +417 -0
- package/src/src/agent/index.ts +9 -0
- package/src/src/internal-agents/ag-ui-sse.ts +31 -272
- package/src/src/rendering/orchestrator/pipeline.ts +13 -8
- package/src/src/utils/version-constant.ts +1 -1
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
import * as dntShim from "../../_dnt.shims.js";
|
|
2
|
+
import type { AgentResponse } from "./types.js";
|
|
3
|
+
|
|
4
|
+
export type AgUiRuntimeStreamEvent = Record<string, unknown> & { type: string };
|
|
5
|
+
|
|
6
|
+
export interface AgUiBrowserRunFinishedMetadata {
|
|
7
|
+
provider?: string;
|
|
8
|
+
model?: string;
|
|
9
|
+
inputTokens?: number;
|
|
10
|
+
outputTokens?: number;
|
|
11
|
+
totalTokens?: number;
|
|
12
|
+
finishReason?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface AgUiBrowserEncoderState {
|
|
16
|
+
messageId: string | null;
|
|
17
|
+
textOpen: boolean;
|
|
18
|
+
reasoningMessageId: string | null;
|
|
19
|
+
activeStepName: string | null;
|
|
20
|
+
stepCount: number;
|
|
21
|
+
streamedToolInputIds: Set<string>;
|
|
22
|
+
sawVisibleOutput: boolean;
|
|
23
|
+
sawTerminalError: boolean;
|
|
24
|
+
metadata: AgUiBrowserRunFinishedMetadata;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface AgUiBrowserEncodedEvent {
|
|
28
|
+
event: string;
|
|
29
|
+
payload: Record<string, unknown>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function createAgUiBrowserEncoderState(): AgUiBrowserEncoderState {
|
|
33
|
+
return {
|
|
34
|
+
messageId: null,
|
|
35
|
+
textOpen: false,
|
|
36
|
+
reasoningMessageId: null,
|
|
37
|
+
activeStepName: null,
|
|
38
|
+
stepCount: 0,
|
|
39
|
+
streamedToolInputIds: new Set<string>(),
|
|
40
|
+
sawVisibleOutput: false,
|
|
41
|
+
sawTerminalError: false,
|
|
42
|
+
metadata: {},
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function serializeToolInput(input: unknown): string {
|
|
47
|
+
try {
|
|
48
|
+
return JSON.stringify(input ?? {});
|
|
49
|
+
} catch {
|
|
50
|
+
return "{}";
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function getMessageId(state: AgUiBrowserEncoderState, event: AgUiRuntimeStreamEvent): string {
|
|
55
|
+
if (typeof event.messageId === "string") {
|
|
56
|
+
state.messageId = event.messageId;
|
|
57
|
+
return event.messageId;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (!state.messageId && typeof event.id === "string") {
|
|
61
|
+
state.messageId = event.id;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (!state.messageId) {
|
|
65
|
+
state.messageId = dntShim.crypto.randomUUID();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return state.messageId;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function getReasoningMessageId(
|
|
72
|
+
state: AgUiBrowserEncoderState,
|
|
73
|
+
event: AgUiRuntimeStreamEvent,
|
|
74
|
+
): string {
|
|
75
|
+
if (typeof event.id === "string" && event.id.length > 0) {
|
|
76
|
+
state.reasoningMessageId = state.messageId
|
|
77
|
+
? `${state.messageId}:reasoning:${event.id}`
|
|
78
|
+
: event.id;
|
|
79
|
+
return state.reasoningMessageId;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (!state.reasoningMessageId) {
|
|
83
|
+
state.reasoningMessageId = state.messageId
|
|
84
|
+
? `${state.messageId}:reasoning:${dntShim.crypto.randomUUID()}`
|
|
85
|
+
: dntShim.crypto.randomUUID();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return state.reasoningMessageId;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function nextStepName(state: AgUiBrowserEncoderState): string {
|
|
92
|
+
state.stepCount += 1;
|
|
93
|
+
state.activeStepName = `step-${state.stepCount}`;
|
|
94
|
+
return state.activeStepName;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function finishStepName(state: AgUiBrowserEncoderState): string {
|
|
98
|
+
const stepName = state.activeStepName ?? `step-${Math.max(state.stepCount, 1)}`;
|
|
99
|
+
state.activeStepName = null;
|
|
100
|
+
return stepName;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function applyDataMetadata(state: AgUiBrowserEncoderState, event: AgUiRuntimeStreamEvent): void {
|
|
104
|
+
const data = event.data && typeof event.data === "object" && !Array.isArray(event.data)
|
|
105
|
+
? event.data as Record<string, unknown>
|
|
106
|
+
: event;
|
|
107
|
+
|
|
108
|
+
if (typeof data.model === "string") {
|
|
109
|
+
state.metadata.model = data.model;
|
|
110
|
+
const provider = data.model.split("/")[0];
|
|
111
|
+
if (provider) {
|
|
112
|
+
state.metadata.provider = provider;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function applyResponseMetadata(
|
|
118
|
+
state: AgUiBrowserEncoderState,
|
|
119
|
+
response: AgentResponse | null,
|
|
120
|
+
): void {
|
|
121
|
+
if (!response) return;
|
|
122
|
+
|
|
123
|
+
if (response.usage) {
|
|
124
|
+
state.metadata.inputTokens = response.usage.promptTokens;
|
|
125
|
+
state.metadata.outputTokens = response.usage.completionTokens;
|
|
126
|
+
state.metadata.totalTokens = response.usage.totalTokens;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const finishReason = response.metadata && typeof response.metadata === "object"
|
|
130
|
+
? response.metadata.finishReason
|
|
131
|
+
: undefined;
|
|
132
|
+
if (typeof finishReason === "string") {
|
|
133
|
+
state.metadata.finishReason = finishReason;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export function mapRuntimeStreamEventToAgUiBrowserEvents(
|
|
138
|
+
state: AgUiBrowserEncoderState,
|
|
139
|
+
event: AgUiRuntimeStreamEvent,
|
|
140
|
+
): AgUiBrowserEncodedEvent[] {
|
|
141
|
+
if (event.type.startsWith("data-")) {
|
|
142
|
+
const name = event.type.slice("data-".length);
|
|
143
|
+
if (name.length === 0) {
|
|
144
|
+
return [];
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
state.sawVisibleOutput = true;
|
|
148
|
+
return [{
|
|
149
|
+
event: "Custom",
|
|
150
|
+
payload: {
|
|
151
|
+
name,
|
|
152
|
+
value: "data" in event ? event.data : null,
|
|
153
|
+
},
|
|
154
|
+
}];
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
switch (event.type) {
|
|
158
|
+
case "message-start":
|
|
159
|
+
getMessageId(state, event);
|
|
160
|
+
return [];
|
|
161
|
+
|
|
162
|
+
case "text-start": {
|
|
163
|
+
if (state.textOpen) return [];
|
|
164
|
+
const messageId = getMessageId(state, event);
|
|
165
|
+
state.textOpen = true;
|
|
166
|
+
state.sawVisibleOutput = true;
|
|
167
|
+
return [{
|
|
168
|
+
event: "TextMessageStart",
|
|
169
|
+
payload: { messageId, role: "assistant" },
|
|
170
|
+
}];
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
case "text-delta": {
|
|
174
|
+
const messageId = getMessageId(state, event);
|
|
175
|
+
state.sawVisibleOutput = true;
|
|
176
|
+
if (!state.textOpen) {
|
|
177
|
+
state.textOpen = true;
|
|
178
|
+
return [
|
|
179
|
+
{ event: "TextMessageStart", payload: { messageId, role: "assistant" } },
|
|
180
|
+
{
|
|
181
|
+
event: "TextMessageContent",
|
|
182
|
+
payload: { messageId, delta: typeof event.delta === "string" ? event.delta : "" },
|
|
183
|
+
},
|
|
184
|
+
];
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return [{
|
|
188
|
+
event: "TextMessageContent",
|
|
189
|
+
payload: { messageId, delta: typeof event.delta === "string" ? event.delta : "" },
|
|
190
|
+
}];
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
case "text-end": {
|
|
194
|
+
if (!state.textOpen) return [];
|
|
195
|
+
state.textOpen = false;
|
|
196
|
+
return [{
|
|
197
|
+
event: "TextMessageEnd",
|
|
198
|
+
payload: { messageId: getMessageId(state, event) },
|
|
199
|
+
}];
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
case "reasoning-start":
|
|
203
|
+
state.sawVisibleOutput = true;
|
|
204
|
+
return [{
|
|
205
|
+
event: "ReasoningMessageStart",
|
|
206
|
+
payload: { messageId: getReasoningMessageId(state, event), role: "reasoning" },
|
|
207
|
+
}];
|
|
208
|
+
|
|
209
|
+
case "reasoning-delta":
|
|
210
|
+
state.sawVisibleOutput = true;
|
|
211
|
+
return [{
|
|
212
|
+
event: "ReasoningMessageContent",
|
|
213
|
+
payload: {
|
|
214
|
+
messageId: getReasoningMessageId(state, event),
|
|
215
|
+
delta: typeof event.delta === "string" ? event.delta : "",
|
|
216
|
+
},
|
|
217
|
+
}];
|
|
218
|
+
|
|
219
|
+
case "reasoning-end": {
|
|
220
|
+
const messageId = getReasoningMessageId(state, event);
|
|
221
|
+
state.reasoningMessageId = null;
|
|
222
|
+
return [{
|
|
223
|
+
event: "ReasoningMessageEnd",
|
|
224
|
+
payload: { messageId },
|
|
225
|
+
}];
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
case "tool-input-start":
|
|
229
|
+
state.sawVisibleOutput = true;
|
|
230
|
+
return [{
|
|
231
|
+
event: "ToolCallStart",
|
|
232
|
+
payload: {
|
|
233
|
+
toolCallId: event.toolCallId,
|
|
234
|
+
toolCallName: event.toolName,
|
|
235
|
+
},
|
|
236
|
+
}];
|
|
237
|
+
|
|
238
|
+
case "tool-input-delta":
|
|
239
|
+
state.sawVisibleOutput = true;
|
|
240
|
+
if (typeof event.toolCallId === "string") {
|
|
241
|
+
state.streamedToolInputIds.add(event.toolCallId);
|
|
242
|
+
}
|
|
243
|
+
return [{
|
|
244
|
+
event: "ToolCallArgs",
|
|
245
|
+
payload: {
|
|
246
|
+
toolCallId: event.toolCallId,
|
|
247
|
+
delta: typeof event.inputTextDelta === "string" ? event.inputTextDelta : "",
|
|
248
|
+
},
|
|
249
|
+
}];
|
|
250
|
+
|
|
251
|
+
case "tool-input-available": {
|
|
252
|
+
state.sawVisibleOutput = true;
|
|
253
|
+
const toolCallId = typeof event.toolCallId === "string" ? event.toolCallId : "";
|
|
254
|
+
const events: AgUiBrowserEncodedEvent[] = [];
|
|
255
|
+
|
|
256
|
+
if (toolCallId.length > 0 && !state.streamedToolInputIds.has(toolCallId)) {
|
|
257
|
+
events.push({
|
|
258
|
+
event: "ToolCallArgs",
|
|
259
|
+
payload: {
|
|
260
|
+
toolCallId,
|
|
261
|
+
delta: serializeToolInput("input" in event ? event.input : {}),
|
|
262
|
+
},
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (toolCallId.length > 0) {
|
|
267
|
+
state.streamedToolInputIds.delete(toolCallId);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
events.push({
|
|
271
|
+
event: "ToolCallEnd",
|
|
272
|
+
payload: { toolCallId: event.toolCallId },
|
|
273
|
+
});
|
|
274
|
+
return events;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
case "tool-input-error": {
|
|
278
|
+
state.sawVisibleOutput = true;
|
|
279
|
+
const toolCallId = typeof event.toolCallId === "string" ? event.toolCallId : "";
|
|
280
|
+
const events: AgUiBrowserEncodedEvent[] = [];
|
|
281
|
+
|
|
282
|
+
if (toolCallId.length > 0 && !state.streamedToolInputIds.has(toolCallId)) {
|
|
283
|
+
events.push({
|
|
284
|
+
event: "ToolCallArgs",
|
|
285
|
+
payload: {
|
|
286
|
+
toolCallId,
|
|
287
|
+
delta: serializeToolInput("input" in event ? event.input : {}),
|
|
288
|
+
},
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
if (toolCallId.length > 0) {
|
|
293
|
+
state.streamedToolInputIds.delete(toolCallId);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
events.push({
|
|
297
|
+
event: "ToolCallEnd",
|
|
298
|
+
payload: { toolCallId: event.toolCallId },
|
|
299
|
+
});
|
|
300
|
+
events.push({
|
|
301
|
+
event: "ToolCallResult",
|
|
302
|
+
payload: {
|
|
303
|
+
toolCallId: event.toolCallId,
|
|
304
|
+
result: {
|
|
305
|
+
error: typeof event.errorText === "string" ? event.errorText : "Tool input failed",
|
|
306
|
+
},
|
|
307
|
+
isError: true,
|
|
308
|
+
},
|
|
309
|
+
});
|
|
310
|
+
return events;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
case "tool-output-available":
|
|
314
|
+
state.sawVisibleOutput = true;
|
|
315
|
+
return [{
|
|
316
|
+
event: "ToolCallResult",
|
|
317
|
+
payload: {
|
|
318
|
+
toolCallId: event.toolCallId,
|
|
319
|
+
result: event.output,
|
|
320
|
+
},
|
|
321
|
+
}];
|
|
322
|
+
|
|
323
|
+
case "tool-output-error":
|
|
324
|
+
state.sawVisibleOutput = true;
|
|
325
|
+
return [{
|
|
326
|
+
event: "ToolCallResult",
|
|
327
|
+
payload: {
|
|
328
|
+
toolCallId: event.toolCallId,
|
|
329
|
+
result: { error: event.errorText },
|
|
330
|
+
isError: true,
|
|
331
|
+
},
|
|
332
|
+
}];
|
|
333
|
+
|
|
334
|
+
case "tool-output-denied":
|
|
335
|
+
state.sawVisibleOutput = true;
|
|
336
|
+
return [{
|
|
337
|
+
event: "ToolCallResult",
|
|
338
|
+
payload: {
|
|
339
|
+
toolCallId: event.toolCallId,
|
|
340
|
+
result: { error: "Tool output denied" },
|
|
341
|
+
isError: true,
|
|
342
|
+
},
|
|
343
|
+
}];
|
|
344
|
+
|
|
345
|
+
case "step-start":
|
|
346
|
+
case "start-step":
|
|
347
|
+
state.sawVisibleOutput = true;
|
|
348
|
+
return [{
|
|
349
|
+
event: "StepStarted",
|
|
350
|
+
payload: { stepName: nextStepName(state) },
|
|
351
|
+
}];
|
|
352
|
+
|
|
353
|
+
case "step-end":
|
|
354
|
+
case "finish-step":
|
|
355
|
+
state.sawVisibleOutput = true;
|
|
356
|
+
return [{
|
|
357
|
+
event: "StepFinished",
|
|
358
|
+
payload: { stepName: finishStepName(state) },
|
|
359
|
+
}];
|
|
360
|
+
|
|
361
|
+
case "data":
|
|
362
|
+
applyDataMetadata(state, event);
|
|
363
|
+
return [];
|
|
364
|
+
|
|
365
|
+
case "error":
|
|
366
|
+
state.sawTerminalError = true;
|
|
367
|
+
return [{
|
|
368
|
+
event: "RunError",
|
|
369
|
+
payload: {
|
|
370
|
+
message: typeof event.error === "string" ? event.error : "Agent run failed",
|
|
371
|
+
},
|
|
372
|
+
}];
|
|
373
|
+
|
|
374
|
+
default:
|
|
375
|
+
return [];
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
export function finalizeAgUiBrowserEvents(
|
|
380
|
+
state: AgUiBrowserEncoderState,
|
|
381
|
+
response: AgentResponse | null,
|
|
382
|
+
): AgUiBrowserEncodedEvent[] {
|
|
383
|
+
applyResponseMetadata(state, response);
|
|
384
|
+
|
|
385
|
+
if (state.sawTerminalError) {
|
|
386
|
+
return [];
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
if (!state.sawVisibleOutput) {
|
|
390
|
+
state.sawTerminalError = true;
|
|
391
|
+
return [{
|
|
392
|
+
event: "RunError",
|
|
393
|
+
payload: {
|
|
394
|
+
code: "EMPTY_ASSISTANT_OUTPUT",
|
|
395
|
+
message: "Agent run produced no assistant-visible output",
|
|
396
|
+
},
|
|
397
|
+
}];
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
const events: AgUiBrowserEncodedEvent[] = [];
|
|
401
|
+
if (state.textOpen) {
|
|
402
|
+
state.textOpen = false;
|
|
403
|
+
events.push({
|
|
404
|
+
event: "TextMessageEnd",
|
|
405
|
+
payload: { messageId: getMessageId(state, { type: "text-end" }) },
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
events.push({
|
|
410
|
+
event: "RunFinished",
|
|
411
|
+
payload: {
|
|
412
|
+
metadata: state.metadata,
|
|
413
|
+
},
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
return events;
|
|
417
|
+
}
|
package/src/src/agent/index.ts
CHANGED
|
@@ -151,6 +151,15 @@ export {
|
|
|
151
151
|
type AgUiRuntimeRequest,
|
|
152
152
|
AgUiRuntimeRequestSchema,
|
|
153
153
|
} from "./runtime-ag-ui-contract.js";
|
|
154
|
+
export {
|
|
155
|
+
type AgUiBrowserEncodedEvent,
|
|
156
|
+
type AgUiBrowserEncoderState,
|
|
157
|
+
type AgUiBrowserRunFinishedMetadata,
|
|
158
|
+
type AgUiRuntimeStreamEvent,
|
|
159
|
+
createAgUiBrowserEncoderState,
|
|
160
|
+
finalizeAgUiBrowserEvents,
|
|
161
|
+
mapRuntimeStreamEventToAgUiBrowserEvents,
|
|
162
|
+
} from "./ag-ui-browser-encoder.js";
|
|
154
163
|
export {
|
|
155
164
|
type AgUiCancelHandlerOptions,
|
|
156
165
|
type AgUiResumeHandlerOptions,
|