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.
@@ -1,40 +1,27 @@
1
- import * as dntShim from "../../_dnt.shims.js";
2
- import type { AgentResponse } from "../agent/index.js";
1
+ import type {
2
+ AgUiBrowserEncodedEvent,
3
+ AgUiBrowserEncoderState,
4
+ AgUiBrowserRunFinishedMetadata,
5
+ AgUiRuntimeStreamEvent,
6
+ } from "../agent/ag-ui-browser-encoder.js";
7
+ import {
8
+ createAgUiBrowserEncoderState,
9
+ finalizeAgUiBrowserEvents,
10
+ mapRuntimeStreamEventToAgUiBrowserEvents,
11
+ } from "../agent/ag-ui-browser-encoder.js";
3
12
  import { serverLogger } from "../utils/index.js";
4
13
  import { z } from "zod";
5
14
 
6
15
  const encoder = new TextEncoder();
7
16
  const logger = serverLogger.component("internal-agents-ag-ui-sse");
8
17
 
9
- type RuntimeDataEvent = Record<string, unknown> & { type: string };
10
-
11
- export interface RunFinishedMetadata {
12
- provider?: string;
13
- model?: string;
14
- inputTokens?: number;
15
- outputTokens?: number;
16
- totalTokens?: number;
17
- finishReason?: string;
18
- }
19
-
20
- export interface StreamTransformState {
21
- messageId: string | null;
22
- textOpen: boolean;
23
- reasoningMessageId: string | null;
24
- sawVisibleOutput: boolean;
25
- sawTerminalError: boolean;
26
- metadata: RunFinishedMetadata;
27
- }
18
+ type RuntimeDataEvent = AgUiRuntimeStreamEvent;
19
+ export type RunFinishedMetadata = AgUiBrowserRunFinishedMetadata;
20
+ export type StreamTransformState = AgUiBrowserEncoderState;
21
+ export type MappedAgUiEvent = AgUiBrowserEncodedEvent;
28
22
 
29
23
  export function createStreamTransformState(): StreamTransformState {
30
- return {
31
- messageId: null,
32
- textOpen: false,
33
- reasoningMessageId: null,
34
- sawVisibleOutput: false,
35
- sawTerminalError: false,
36
- metadata: {},
37
- };
24
+ return createAgUiBrowserEncoderState();
38
25
  }
39
26
 
40
27
  const agUiEventPayloadSchemas = {
@@ -77,6 +64,12 @@ const agUiEventPayloadSchemas = {
77
64
  ReasoningMessageEnd: z.object({
78
65
  messageId: z.string().min(1),
79
66
  }),
67
+ StepStarted: z.object({
68
+ stepName: z.string().min(1),
69
+ }),
70
+ StepFinished: z.object({
71
+ stepName: z.string().min(1),
72
+ }),
80
73
  ToolCallStart: z.object({
81
74
  toolCallId: z.string().min(1),
82
75
  toolCallName: z.string().min(1),
@@ -93,6 +86,10 @@ const agUiEventPayloadSchemas = {
93
86
  result: z.unknown(),
94
87
  isError: z.boolean().optional(),
95
88
  }),
89
+ Custom: z.object({
90
+ name: z.string().min(1),
91
+ value: z.unknown(),
92
+ }),
96
93
  RunError: z.object({
97
94
  code: z.string().min(1).optional(),
98
95
  message: z.string().min(1),
@@ -147,254 +144,16 @@ export function parseSseJsonEvents(chunk: string): {
147
144
  return { events, remainder };
148
145
  }
149
146
 
150
- function getMessageId(state: StreamTransformState, event: RuntimeDataEvent): string {
151
- if (typeof event.messageId === "string") {
152
- state.messageId = event.messageId;
153
- return event.messageId;
154
- }
155
-
156
- if (!state.messageId && typeof event.id === "string") {
157
- state.messageId = event.id;
158
- }
159
-
160
- if (!state.messageId) {
161
- state.messageId = dntShim.crypto.randomUUID();
162
- }
163
-
164
- return state.messageId;
165
- }
166
-
167
- function getReasoningMessageId(state: StreamTransformState, event: RuntimeDataEvent): string {
168
- if (typeof event.id === "string" && event.id.length > 0) {
169
- state.reasoningMessageId = state.messageId
170
- ? `${state.messageId}:reasoning:${event.id}`
171
- : event.id;
172
- return state.reasoningMessageId;
173
- }
174
-
175
- if (!state.reasoningMessageId) {
176
- state.reasoningMessageId = state.messageId
177
- ? `${state.messageId}:reasoning:${dntShim.crypto.randomUUID()}`
178
- : dntShim.crypto.randomUUID();
179
- }
180
-
181
- return state.reasoningMessageId;
182
- }
183
-
184
- function applyDataMetadata(state: StreamTransformState, event: RuntimeDataEvent): void {
185
- const data = event.data && typeof event.data === "object" && !Array.isArray(event.data)
186
- ? event.data as Record<string, unknown>
187
- : event;
188
-
189
- if (typeof data.model === "string") {
190
- state.metadata.model = data.model;
191
- const provider = data.model.split("/")[0];
192
- if (provider) {
193
- state.metadata.provider = provider;
194
- }
195
- }
196
- }
197
-
198
- function applyResponseMetadata(state: StreamTransformState, response: AgentResponse | null): void {
199
- if (!response) return;
200
-
201
- if (response.usage) {
202
- state.metadata.inputTokens = response.usage.promptTokens;
203
- state.metadata.outputTokens = response.usage.completionTokens;
204
- state.metadata.totalTokens = response.usage.totalTokens;
205
- }
206
-
207
- const finishReason = response.metadata && typeof response.metadata === "object"
208
- ? response.metadata.finishReason
209
- : undefined;
210
- if (typeof finishReason === "string") {
211
- state.metadata.finishReason = finishReason;
212
- }
213
- }
214
-
215
147
  export function mapRuntimeEventToAgUi(
216
148
  state: StreamTransformState,
217
149
  event: RuntimeDataEvent,
218
- ): Array<{ event: string; payload: Record<string, unknown> }> {
219
- switch (event.type) {
220
- case "message-start":
221
- getMessageId(state, event);
222
- return [];
223
-
224
- case "text-start": {
225
- if (state.textOpen) return [];
226
- const messageId = getMessageId(state, event);
227
- state.textOpen = true;
228
- state.sawVisibleOutput = true;
229
- return [{
230
- event: "TextMessageStart",
231
- payload: { messageId, role: "assistant" },
232
- }];
233
- }
234
-
235
- case "text-delta": {
236
- const messageId = getMessageId(state, event);
237
- state.sawVisibleOutput = true;
238
- if (!state.textOpen) {
239
- state.textOpen = true;
240
- return [
241
- { event: "TextMessageStart", payload: { messageId, role: "assistant" } },
242
- {
243
- event: "TextMessageContent",
244
- payload: { messageId, delta: typeof event.delta === "string" ? event.delta : "" },
245
- },
246
- ];
247
- }
248
-
249
- return [{
250
- event: "TextMessageContent",
251
- payload: { messageId, delta: typeof event.delta === "string" ? event.delta : "" },
252
- }];
253
- }
254
-
255
- case "text-end": {
256
- if (!state.textOpen) return [];
257
- state.textOpen = false;
258
- return [{
259
- event: "TextMessageEnd",
260
- payload: { messageId: getMessageId(state, event) },
261
- }];
262
- }
263
-
264
- case "reasoning-start":
265
- state.sawVisibleOutput = true;
266
- return [{
267
- event: "ReasoningMessageStart",
268
- payload: { messageId: getReasoningMessageId(state, event), role: "reasoning" },
269
- }];
270
-
271
- case "reasoning-delta":
272
- state.sawVisibleOutput = true;
273
- return [{
274
- event: "ReasoningMessageContent",
275
- payload: {
276
- messageId: getReasoningMessageId(state, event),
277
- delta: typeof event.delta === "string" ? event.delta : "",
278
- },
279
- }];
280
-
281
- case "reasoning-end": {
282
- const messageId = getReasoningMessageId(state, event);
283
- state.reasoningMessageId = null;
284
- return [{
285
- event: "ReasoningMessageEnd",
286
- payload: { messageId },
287
- }];
288
- }
289
-
290
- case "tool-input-start":
291
- state.sawVisibleOutput = true;
292
- return [{
293
- event: "ToolCallStart",
294
- payload: {
295
- toolCallId: event.toolCallId,
296
- toolCallName: event.toolName,
297
- },
298
- }];
299
-
300
- case "tool-input-delta":
301
- state.sawVisibleOutput = true;
302
- return [{
303
- event: "ToolCallArgs",
304
- payload: {
305
- toolCallId: event.toolCallId,
306
- delta: typeof event.inputTextDelta === "string" ? event.inputTextDelta : "",
307
- },
308
- }];
309
-
310
- case "tool-input-available":
311
- state.sawVisibleOutput = true;
312
- return [{
313
- event: "ToolCallEnd",
314
- payload: { toolCallId: event.toolCallId },
315
- }];
316
-
317
- case "tool-output-available":
318
- state.sawVisibleOutput = true;
319
- return [{
320
- event: "ToolCallResult",
321
- payload: {
322
- toolCallId: event.toolCallId,
323
- result: event.output,
324
- },
325
- }];
326
-
327
- case "tool-output-error":
328
- state.sawVisibleOutput = true;
329
- return [{
330
- event: "ToolCallResult",
331
- payload: {
332
- toolCallId: event.toolCallId,
333
- result: { error: event.errorText },
334
- isError: true,
335
- },
336
- }];
337
-
338
- case "step-start":
339
- return [];
340
-
341
- case "step-end":
342
- return [];
343
-
344
- case "data":
345
- applyDataMetadata(state, event);
346
- return [];
347
-
348
- case "error":
349
- state.sawTerminalError = true;
350
- return [{
351
- event: "RunError",
352
- payload: {
353
- message: typeof event.error === "string" ? event.error : "Agent run failed",
354
- },
355
- }];
356
-
357
- default:
358
- return [];
359
- }
150
+ ): MappedAgUiEvent[] {
151
+ return mapRuntimeStreamEventToAgUiBrowserEvents(state, event);
360
152
  }
361
153
 
362
154
  export function finalizeRunEvents(
363
155
  state: StreamTransformState,
364
- response: AgentResponse | null,
365
- ): Array<{ event: string; payload: Record<string, unknown> }> {
366
- applyResponseMetadata(state, response);
367
-
368
- if (state.sawTerminalError) {
369
- return [];
370
- }
371
-
372
- if (!state.sawVisibleOutput) {
373
- state.sawTerminalError = true;
374
- return [{
375
- event: "RunError",
376
- payload: {
377
- code: "EMPTY_ASSISTANT_OUTPUT",
378
- message: "Agent run produced no assistant-visible output",
379
- },
380
- }];
381
- }
382
-
383
- const events: Array<{ event: string; payload: Record<string, unknown> }> = [];
384
- if (state.textOpen) {
385
- state.textOpen = false;
386
- events.push({
387
- event: "TextMessageEnd",
388
- payload: { messageId: getMessageId(state, { type: "text-end" }) },
389
- });
390
- }
391
-
392
- events.push({
393
- event: "RunFinished",
394
- payload: {
395
- metadata: state.metadata,
396
- },
397
- });
398
-
399
- return events;
156
+ response: Parameters<typeof finalizeAgUiBrowserEvents>[1],
157
+ ): MappedAgUiEvent[] {
158
+ return finalizeAgUiBrowserEvents(state, response);
400
159
  }
@@ -687,14 +687,7 @@ export class RenderPipeline {
687
687
 
688
688
  const providers: string[] = [];
689
689
 
690
- let projectUpdatedAt: string | undefined;
691
- const fs = this.config.adapter?.fs;
692
- if (fs && isExtendedFSAdapter(fs) && fs.isVeryfrontAdapter()) {
693
- const wrappedAdapter = fs.getUnderlyingAdapter() as {
694
- getProjectData?: () => { updated_at?: string } | undefined;
695
- };
696
- projectUpdatedAt = wrappedAdapter.getProjectData?.()?.updated_at;
697
- }
690
+ const projectUpdatedAt = this.resolveProjectUpdatedAt();
698
691
 
699
692
  const appPath = await this.resolveAppPath();
700
693
 
@@ -783,6 +776,18 @@ export class RenderPipeline {
783
776
  return undefined;
784
777
  }
785
778
 
779
+ private resolveProjectUpdatedAt(): string | undefined {
780
+ const fs = this.config.adapter?.fs;
781
+ if (!fs || !isExtendedFSAdapter(fs) || !fs.isVeryfrontAdapter()) {
782
+ return undefined;
783
+ }
784
+
785
+ const wrappedAdapter = fs.getUnderlyingAdapter() as {
786
+ getProjectData?: () => { updated_at?: string } | undefined;
787
+ };
788
+ return wrappedAdapter.getProjectData?.()?.updated_at;
789
+ }
790
+
786
791
  private async resolvePageDataCss(
787
792
  slug: string,
788
793
  options: RenderOptions | undefined,
@@ -1,3 +1,3 @@
1
1
  // Keep in sync with deno.json version.
2
2
  // scripts/release.ts updates this constant during releases.
3
- export const VERSION = "0.1.180";
3
+ export const VERSION = "0.1.181";