veryfront 0.1.220 → 0.1.221

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 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/src/agent/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/src/agent/index.ts"],"names":[],"mappings":"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"}
@@ -89,6 +89,7 @@ export { mergeToolCallInput, mergeToolInputDelta, parseDataStreamSseEvents, pars
89
89
  export { expandAllowedRemoteToolNames, getProviderNativeToolNames, } from "./provider-native-tool-inventory.js";
90
90
  export { AgUiDetachedStartAcceptedSchema, AgUiDetachedStartRequestSchema, createAgUiDetachedStartHandler, } from "./ag-ui-detached-start.js";
91
91
  export { AgUiResumeSignalSchema, createAgUiCancelHandler, createAgUiResumeHandler, } from "./ag-ui-run-control.js";
92
+ export { createAgUiRunErrorEvent, createAgUiSseErrorResponse, normalizeAgUiMessages, parseAgUiRequest, parseAgUiRequestOrError, } from "./ag-ui-host-support.js";
92
93
  export { AgUiRequestSchema, createAgUiHandler, } from "./ag-ui-handler.js";
93
94
  export { HumanInputFieldSchema, HumanInputOptionSchema, HumanInputPendingRequestSchema, HumanInputRequestSchema, HumanInputResultSchema, HumanInputResumeError, InvalidHumanInputResultError, waitForHumanInput, } from "./human-input.js";
94
95
  export { createChatHandler, } from "./chat-handler.js";
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "0.1.220";
1
+ export declare const VERSION = "0.1.221";
2
2
  //# sourceMappingURL=version-constant.d.ts.map
@@ -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.220";
3
+ export const VERSION = "0.1.221";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "veryfront",
3
- "version": "0.1.220",
3
+ "version": "0.1.221",
4
4
  "description": "The simplest way to build AI-powered apps",
5
5
  "keywords": [
6
6
  "react",
package/src/deno.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export default {
2
2
  "name": "veryfront",
3
- "version": "0.1.220",
3
+ "version": "0.1.221",
4
4
  "license": "Apache-2.0",
5
5
  "nodeModulesDir": "auto",
6
6
  "workspace": [
@@ -3,18 +3,20 @@ import { INVALID_ARGUMENT } from "../errors/index.js";
3
3
  import { SKILL_TOOL_IDS } from "../skill/types.js";
4
4
  import { type Tool, toolRegistry } from "../tool/index.js";
5
5
  import { streamDataStreamEvents } from "./data-stream.js";
6
- import { type AgUiInjectedTool, type AgUiRequest, AgUiRequestSchema } from "./ag-ui-handler.js";
6
+ import {
7
+ type AgUiInjectedTool,
8
+ AgUiRequestSchema,
9
+ normalizeAgUiMessages,
10
+ } from "./ag-ui-host-support.js";
7
11
  import {
8
12
  AgentRuntime,
9
13
  RunAlreadyExistsError,
10
14
  type RunResumeSessionManager,
11
15
  } from "./runtime/index.js";
12
- import type { Agent, Message } from "./types.js";
16
+ import type { Agent } from "./types.js";
13
17
 
14
18
  const AGENT_ID_PATTERN = /^[a-zA-Z0-9_-]+$/;
15
19
  const AG_UI_DETACHED_RUN_ID_SCHEMA = z.string().min(1).max(128).regex(AGENT_ID_PATTERN);
16
- const MAX_TEXT_PART_LENGTH = 10_000;
17
-
18
20
  type AgUiResumeValue = {
19
21
  result: unknown;
20
22
  isError: boolean;
@@ -26,94 +28,6 @@ type AgUiContextValue =
26
28
 
27
29
  type AgUiRuntimePart = Record<string, unknown> & { type: string };
28
30
 
29
- function isRecord(value: unknown): value is Record<string, unknown> {
30
- return typeof value === "object" && value !== null && !Array.isArray(value);
31
- }
32
-
33
- function normalizeToolArgs(part: Record<string, unknown>): Record<string, unknown> {
34
- if (isRecord(part.args)) return part.args;
35
- if (isRecord(part.input)) return part.input;
36
- return {};
37
- }
38
-
39
- function normalizeMessagePart(part: Record<string, unknown>): Message["parts"][number] | null {
40
- if (
41
- part.type === "text" && typeof part.text === "string" &&
42
- part.text.length <= MAX_TEXT_PART_LENGTH
43
- ) {
44
- return { type: "text", text: part.text };
45
- }
46
-
47
- if (part.type === "tool_call" && typeof part.id === "string" && typeof part.name === "string") {
48
- return {
49
- type: "tool-call",
50
- toolCallId: part.id,
51
- toolName: part.name,
52
- args: normalizeToolArgs(part),
53
- };
54
- }
55
-
56
- if (
57
- part.type === "tool-call" &&
58
- typeof part.toolCallId === "string" &&
59
- typeof part.toolName === "string"
60
- ) {
61
- return {
62
- type: "tool-call",
63
- toolCallId: part.toolCallId,
64
- toolName: part.toolName,
65
- args: normalizeToolArgs(part),
66
- };
67
- }
68
-
69
- if (
70
- typeof part.type === "string" &&
71
- part.type.startsWith("tool-") &&
72
- part.type !== "tool-result" &&
73
- typeof part.toolCallId === "string" &&
74
- typeof part.toolName === "string"
75
- ) {
76
- return {
77
- type: part.type,
78
- toolCallId: part.toolCallId,
79
- toolName: part.toolName,
80
- args: normalizeToolArgs(part),
81
- };
82
- }
83
-
84
- if (part.type === "tool_result" && typeof part.tool_call_id === "string") {
85
- return {
86
- type: "tool-result",
87
- toolCallId: part.tool_call_id,
88
- toolName: typeof part.tool_name === "string" ? part.tool_name : "unknown",
89
- result: "output" in part ? part.output : undefined,
90
- };
91
- }
92
-
93
- if (part.type === "tool-result" && typeof part.toolCallId === "string") {
94
- return {
95
- type: "tool-result",
96
- toolCallId: part.toolCallId,
97
- toolName: typeof part.toolName === "string" ? part.toolName : "unknown",
98
- result: "result" in part ? part.result : undefined,
99
- };
100
- }
101
-
102
- return null;
103
- }
104
-
105
- function normalizeMessages(messages: AgUiRequest["messages"]): Message[] {
106
- return messages.map((message) => ({
107
- id: message.id,
108
- role: message.role,
109
- parts: message.parts
110
- .map((part) => normalizeMessagePart(part))
111
- .filter((part): part is Message["parts"][number] => part !== null),
112
- ...(message.createdAt ? { timestamp: Date.parse(message.createdAt) || undefined } : {}),
113
- ...(message.metadata ? { metadata: message.metadata } : {}),
114
- }));
115
- }
116
-
117
31
  function isRequest(obj: unknown): obj is Request {
118
32
  return (
119
33
  typeof obj === "object" &&
@@ -317,7 +231,7 @@ async function startDefaultDetachedExecution(input: {
317
231
  });
318
232
 
319
233
  const runtimeStream = await runtime.stream(
320
- normalizeMessages(input.request.messages),
234
+ normalizeAgUiMessages(input.request.messages),
321
235
  buildStreamContext(input.request, input.context, input.request.threadId, input.request.runId),
322
236
  undefined,
323
237
  input.request.model,
@@ -1,7 +1,7 @@
1
1
  import * as dntShim from "../../_dnt.shims.js";
2
2
  import { z } from "zod";
3
3
  import { getAgent } from "./composition/index.js";
4
- import type { Agent, Message } from "./types.js";
4
+ import type { Agent } from "./types.js";
5
5
  import {
6
6
  AgentRuntime,
7
7
  RunAlreadyExistsError,
@@ -17,16 +17,21 @@ import {
17
17
  mapRuntimeEventToAgUi,
18
18
  } from "../internal-agents/ag-ui-sse.js";
19
19
  import { streamDataStreamEvents } from "./data-stream.js";
20
-
21
- const AGENT_ID_PATTERN = /^[a-zA-Z0-9_-]+$/;
22
- const MAX_TOOL_PARAMETERS_BYTES = 16_384;
23
- const MAX_CONTEXT_ITEM_BYTES = 16_384;
24
- const MAX_CONTEXT_TOTAL_BYTES = 65_536;
25
- const MAX_FORWARDED_PROPS_BYTES = 65_536;
26
- const MAX_TEXT_PART_LENGTH = 10_000;
27
- const MAX_MESSAGES_PER_REQUEST = 100;
28
-
29
- const encoder = new TextEncoder();
20
+ import {
21
+ type AgUiInjectedTool,
22
+ type AgUiRequest,
23
+ normalizeAgUiMessages,
24
+ parseAgUiRequestOrError,
25
+ } from "./ag-ui-host-support.js";
26
+
27
+ export {
28
+ type AgUiContextItem,
29
+ AgUiContextItemSchema,
30
+ type AgUiInjectedTool,
31
+ AgUiInjectedToolSchema,
32
+ type AgUiRequest,
33
+ AgUiRequestSchema,
34
+ } from "./ag-ui-host-support.js";
30
35
 
31
36
  const AG_UI_HEADERS: Record<string, string> = {
32
37
  "Content-Type": "text/event-stream",
@@ -34,169 +39,8 @@ const AG_UI_HEADERS: Record<string, string> = {
34
39
  Connection: "keep-alive",
35
40
  };
36
41
 
37
- function isWithinJsonSizeLimit(value: unknown, maxBytes: number): boolean {
38
- try {
39
- return encoder.encode(JSON.stringify(value)).byteLength <= maxBytes;
40
- } catch {
41
- return false;
42
- }
43
- }
44
-
45
- const AgUiRunIdSchema = z.string().min(1).max(128).regex(AGENT_ID_PATTERN);
46
-
47
- const AgUiInjectedToolSchema = z.object({
48
- name: z.string().min(1).max(128),
49
- description: z.string().max(1024).optional(),
50
- parameters: z.record(z.string(), z.unknown()).optional().refine(
51
- (value) => value === undefined || isWithinJsonSizeLimit(value, MAX_TOOL_PARAMETERS_BYTES),
52
- { message: "Tool parameters must be less than 16 KB" },
53
- ),
54
- });
55
-
56
- const AgUiContextItemSchema = z.discriminatedUnion("type", [
57
- z.object({
58
- type: z.literal("text"),
59
- title: z.string().max(256).optional(),
60
- text: z.string().max(MAX_CONTEXT_ITEM_BYTES),
61
- }),
62
- z.object({
63
- type: z.literal("json"),
64
- title: z.string().max(256).optional(),
65
- data: z.record(z.string(), z.unknown()).refine(
66
- (value) => isWithinJsonSizeLimit(value, MAX_CONTEXT_ITEM_BYTES),
67
- { message: "JSON context item must be less than 16 KB" },
68
- ),
69
- }),
70
- z.object({
71
- type: z.literal("resource"),
72
- title: z.string().max(256).optional(),
73
- uri: z.string().max(2048),
74
- mimeType: z.string().max(256).optional(),
75
- text: z.string().max(MAX_CONTEXT_ITEM_BYTES).optional(),
76
- }),
77
- ]);
78
-
79
- const AgUiMessagePartSchema = z.object({ type: z.string().min(1) }).passthrough();
80
-
81
- const AgUiMessageSchema = z.object({
82
- id: z.string().min(1),
83
- role: z.enum(["user", "assistant", "system", "tool"]),
84
- parts: z.array(AgUiMessagePartSchema).default([]),
85
- metadata: z.record(z.string(), z.unknown()).optional(),
86
- createdAt: z.string().optional(),
87
- });
88
-
89
- export const AgUiRequestSchema = z.object({
90
- threadId: z.string().uuid().optional(),
91
- runId: AgUiRunIdSchema.optional(),
92
- messages: z.array(AgUiMessageSchema).min(1).max(MAX_MESSAGES_PER_REQUEST),
93
- tools: z.array(AgUiInjectedToolSchema).max(50).default([]),
94
- context: z.array(AgUiContextItemSchema).max(10).default([]).refine(
95
- (value) => isWithinJsonSizeLimit(value, MAX_CONTEXT_TOTAL_BYTES),
96
- { message: "context must be less than 64 KB total" },
97
- ),
98
- forwardedProps: z.record(z.string(), z.unknown()).optional().refine(
99
- (value) => value === undefined || isWithinJsonSizeLimit(value, MAX_FORWARDED_PROPS_BYTES),
100
- { message: "forwardedProps must be less than 64 KB" },
101
- ),
102
- model: z.string().optional(),
103
- maxOutputTokens: z.number().int().positive().optional(),
104
- });
105
-
106
- export type AgUiInjectedTool = z.infer<typeof AgUiInjectedToolSchema>;
107
- export type AgUiContextItem = z.infer<typeof AgUiContextItemSchema>;
108
- export type AgUiRequest = z.infer<typeof AgUiRequestSchema>;
109
-
110
- type AgUiRuntimePart = Record<string, unknown> & { type: string };
111
42
  type AgUiResumeValue = { result: unknown; isError: boolean };
112
-
113
- function isRecord(value: unknown): value is Record<string, unknown> {
114
- return typeof value === "object" && value !== null && !Array.isArray(value);
115
- }
116
-
117
- function normalizeToolArgs(part: Record<string, unknown>): Record<string, unknown> {
118
- if (isRecord(part.args)) return part.args;
119
- if (isRecord(part.input)) return part.input;
120
- return {};
121
- }
122
-
123
- function normalizeMessagePart(part: Record<string, unknown>): Message["parts"][number] | null {
124
- if (
125
- part.type === "text" && typeof part.text === "string" &&
126
- part.text.length <= MAX_TEXT_PART_LENGTH
127
- ) {
128
- return { type: "text", text: part.text };
129
- }
130
-
131
- if (part.type === "tool_call" && typeof part.id === "string" && typeof part.name === "string") {
132
- return {
133
- type: "tool-call",
134
- toolCallId: part.id,
135
- toolName: part.name,
136
- args: normalizeToolArgs(part),
137
- };
138
- }
139
-
140
- if (
141
- part.type === "tool-call" &&
142
- typeof part.toolCallId === "string" &&
143
- typeof part.toolName === "string"
144
- ) {
145
- return {
146
- type: "tool-call",
147
- toolCallId: part.toolCallId,
148
- toolName: part.toolName,
149
- args: normalizeToolArgs(part),
150
- };
151
- }
152
-
153
- if (
154
- typeof part.type === "string" &&
155
- part.type.startsWith("tool-") &&
156
- part.type !== "tool-result" &&
157
- typeof part.toolCallId === "string" &&
158
- typeof part.toolName === "string"
159
- ) {
160
- return {
161
- type: part.type,
162
- toolCallId: part.toolCallId,
163
- toolName: part.toolName,
164
- args: normalizeToolArgs(part),
165
- };
166
- }
167
-
168
- if (part.type === "tool_result" && typeof part.tool_call_id === "string") {
169
- return {
170
- type: "tool-result",
171
- toolCallId: part.tool_call_id,
172
- toolName: typeof part.tool_name === "string" ? part.tool_name : "unknown",
173
- result: "output" in part ? part.output : undefined,
174
- };
175
- }
176
-
177
- if (part.type === "tool-result" && typeof part.toolCallId === "string") {
178
- return {
179
- type: "tool-result",
180
- toolCallId: part.toolCallId,
181
- toolName: typeof part.toolName === "string" ? part.toolName : "unknown",
182
- result: "result" in part ? part.result : undefined,
183
- };
184
- }
185
-
186
- return null;
187
- }
188
-
189
- function normalizeMessages(messages: AgUiRequest["messages"]): Message[] {
190
- return messages.map((message) => ({
191
- id: message.id,
192
- role: message.role,
193
- parts: message.parts
194
- .map((part) => normalizeMessagePart(part))
195
- .filter((part): part is Message["parts"][number] => part !== null),
196
- ...(message.createdAt ? { timestamp: Date.parse(message.createdAt) || undefined } : {}),
197
- ...(message.metadata ? { metadata: message.metadata } : {}),
198
- }));
199
- }
43
+ type AgUiRuntimePart = Record<string, unknown> & { type: string };
200
44
 
201
45
  function isRequest(obj: unknown): obj is Request {
202
46
  return (
@@ -378,7 +222,7 @@ async function createAgUiDirectStreamResponse(
378
222
  await agent.clearMemory();
379
223
 
380
224
  const result = await agent.stream({
381
- messages: normalizeMessages(request.messages),
225
+ messages: normalizeAgUiMessages(request.messages),
382
226
  context: buildStreamContext(request, baseContext, threadId, runId),
383
227
  ...(request.model ? { model: request.model } : {}),
384
228
  ...(request.maxOutputTokens ? { maxOutputTokens: request.maxOutputTokens } : {}),
@@ -471,7 +315,7 @@ async function createAgUiInjectedToolsStreamResponse(
471
315
  let upstreamBody: ReadableStream<Uint8Array>;
472
316
  try {
473
317
  upstreamBody = await runtime.stream(
474
- normalizeMessages(request.messages),
318
+ normalizeAgUiMessages(request.messages),
475
319
  buildStreamContext(request, baseContext, threadId, runId),
476
320
  undefined,
477
321
  request.model,
@@ -559,7 +403,10 @@ export function createAgUiHandler(
559
403
  }
560
404
 
561
405
  try {
562
- const parsed = AgUiRequestSchema.parse(await request.json());
406
+ const parsed = await parseAgUiRequestOrError(request);
407
+ if (parsed instanceof Response) {
408
+ return parsed;
409
+ }
563
410
 
564
411
  if (parsed.tools.length > 0) {
565
412
  if (!options?.sessionManager) {
@@ -0,0 +1,238 @@
1
+ import { z } from "zod";
2
+ import { formatAgUiEvent } from "../internal-agents/ag-ui-sse.js";
3
+ import type { Message } from "./types.js";
4
+
5
+ const AGENT_ID_PATTERN = /^[a-zA-Z0-9_-]+$/;
6
+ const MAX_TOOL_PARAMETERS_BYTES = 16_384;
7
+ const MAX_CONTEXT_ITEM_BYTES = 16_384;
8
+ const MAX_CONTEXT_TOTAL_BYTES = 65_536;
9
+ const MAX_FORWARDED_PROPS_BYTES = 65_536;
10
+ const MAX_TEXT_PART_LENGTH = 10_000;
11
+ const MAX_MESSAGES_PER_REQUEST = 100;
12
+ const encoder = new TextEncoder();
13
+ const decoder = new TextDecoder();
14
+
15
+ export interface AgUiSseEvent {
16
+ event: string;
17
+ payload: Record<string, unknown>;
18
+ }
19
+
20
+ function isWithinJsonSizeLimit(value: unknown, maxBytes: number): boolean {
21
+ try {
22
+ return encoder.encode(JSON.stringify(value)).byteLength <= maxBytes;
23
+ } catch {
24
+ return false;
25
+ }
26
+ }
27
+
28
+ function isRecord(value: unknown): value is Record<string, unknown> {
29
+ return typeof value === "object" && value !== null && !Array.isArray(value);
30
+ }
31
+
32
+ const AgUiRunIdSchema = z.string().min(1).max(128).regex(AGENT_ID_PATTERN);
33
+
34
+ export const AgUiInjectedToolSchema = z.object({
35
+ name: z.string().min(1).max(128),
36
+ description: z.string().max(1024).optional(),
37
+ parameters: z.record(z.string(), z.unknown()).optional().refine(
38
+ (value) => value === undefined || isWithinJsonSizeLimit(value, MAX_TOOL_PARAMETERS_BYTES),
39
+ { message: "Tool parameters must be less than 16 KB" },
40
+ ),
41
+ });
42
+
43
+ export const AgUiContextItemSchema = z.discriminatedUnion("type", [
44
+ z.object({
45
+ type: z.literal("text"),
46
+ title: z.string().max(256).optional(),
47
+ text: z.string().max(MAX_CONTEXT_ITEM_BYTES),
48
+ }),
49
+ z.object({
50
+ type: z.literal("json"),
51
+ title: z.string().max(256).optional(),
52
+ data: z.record(z.string(), z.unknown()).refine(
53
+ (value) => isWithinJsonSizeLimit(value, MAX_CONTEXT_ITEM_BYTES),
54
+ { message: "JSON context item must be less than 16 KB" },
55
+ ),
56
+ }),
57
+ z.object({
58
+ type: z.literal("resource"),
59
+ title: z.string().max(256).optional(),
60
+ uri: z.string().max(2048),
61
+ mimeType: z.string().max(256).optional(),
62
+ text: z.string().max(MAX_CONTEXT_ITEM_BYTES).optional(),
63
+ }),
64
+ ]);
65
+
66
+ const AgUiMessagePartSchema = z.object({ type: z.string().min(1) }).passthrough();
67
+
68
+ const AgUiMessageSchema = z.object({
69
+ id: z.string().min(1),
70
+ role: z.enum(["user", "assistant", "system", "tool"]),
71
+ parts: z.array(AgUiMessagePartSchema).default([]),
72
+ metadata: z.record(z.string(), z.unknown()).optional(),
73
+ createdAt: z.string().optional(),
74
+ });
75
+
76
+ export const AgUiRequestSchema = z.object({
77
+ threadId: z.string().uuid().optional(),
78
+ runId: AgUiRunIdSchema.optional(),
79
+ messages: z.array(AgUiMessageSchema).min(1).max(MAX_MESSAGES_PER_REQUEST),
80
+ tools: z.array(AgUiInjectedToolSchema).max(50).default([]),
81
+ context: z.array(AgUiContextItemSchema).max(10).default([]).refine(
82
+ (value) => isWithinJsonSizeLimit(value, MAX_CONTEXT_TOTAL_BYTES),
83
+ { message: "context must be less than 64 KB total" },
84
+ ),
85
+ forwardedProps: z.record(z.string(), z.unknown()).optional().refine(
86
+ (value) => value === undefined || isWithinJsonSizeLimit(value, MAX_FORWARDED_PROPS_BYTES),
87
+ { message: "forwardedProps must be less than 64 KB" },
88
+ ),
89
+ model: z.string().optional(),
90
+ maxOutputTokens: z.number().int().positive().optional(),
91
+ });
92
+
93
+ export type AgUiInjectedTool = z.infer<typeof AgUiInjectedToolSchema>;
94
+ export type AgUiContextItem = z.infer<typeof AgUiContextItemSchema>;
95
+ export type AgUiRequest = z.infer<typeof AgUiRequestSchema>;
96
+
97
+ function normalizeToolArgs(part: Record<string, unknown>): Record<string, unknown> {
98
+ if (isRecord(part.args)) return part.args;
99
+ if (isRecord(part.input)) return part.input;
100
+ return {};
101
+ }
102
+
103
+ function normalizeMessagePart(part: Record<string, unknown>): Message["parts"][number] | null {
104
+ if (
105
+ part.type === "text" && typeof part.text === "string" &&
106
+ part.text.length <= MAX_TEXT_PART_LENGTH
107
+ ) {
108
+ return { type: "text", text: part.text };
109
+ }
110
+
111
+ if (part.type === "tool_call" && typeof part.id === "string" && typeof part.name === "string") {
112
+ return {
113
+ type: "tool-call",
114
+ toolCallId: part.id,
115
+ toolName: part.name,
116
+ args: normalizeToolArgs(part),
117
+ };
118
+ }
119
+
120
+ if (
121
+ part.type === "tool-call" &&
122
+ typeof part.toolCallId === "string" &&
123
+ typeof part.toolName === "string"
124
+ ) {
125
+ return {
126
+ type: "tool-call",
127
+ toolCallId: part.toolCallId,
128
+ toolName: part.toolName,
129
+ args: normalizeToolArgs(part),
130
+ };
131
+ }
132
+
133
+ if (
134
+ typeof part.type === "string" &&
135
+ part.type.startsWith("tool-") &&
136
+ part.type !== "tool-result" &&
137
+ typeof part.toolCallId === "string" &&
138
+ typeof part.toolName === "string"
139
+ ) {
140
+ return {
141
+ type: part.type,
142
+ toolCallId: part.toolCallId,
143
+ toolName: part.toolName,
144
+ args: normalizeToolArgs(part),
145
+ };
146
+ }
147
+
148
+ if (part.type === "tool_result" && typeof part.tool_call_id === "string") {
149
+ return {
150
+ type: "tool-result",
151
+ toolCallId: part.tool_call_id,
152
+ toolName: typeof part.tool_name === "string" ? part.tool_name : "unknown",
153
+ result: "output" in part ? part.output : undefined,
154
+ };
155
+ }
156
+
157
+ if (part.type === "tool-result" && typeof part.toolCallId === "string") {
158
+ return {
159
+ type: "tool-result",
160
+ toolCallId: part.toolCallId,
161
+ toolName: typeof part.toolName === "string" ? part.toolName : "unknown",
162
+ result: "result" in part ? part.result : undefined,
163
+ };
164
+ }
165
+
166
+ return null;
167
+ }
168
+
169
+ export async function parseAgUiRequest(request: Request): Promise<AgUiRequest> {
170
+ return AgUiRequestSchema.parse(await request.json());
171
+ }
172
+
173
+ export async function parseAgUiRequestOrError(
174
+ request: Request,
175
+ ): Promise<AgUiRequest | Response> {
176
+ try {
177
+ return await parseAgUiRequest(request);
178
+ } catch (error) {
179
+ if (error instanceof z.ZodError) {
180
+ return Response.json(
181
+ {
182
+ error: "Invalid AG-UI request",
183
+ details: error.issues.map((issue) => ({
184
+ path: issue.path,
185
+ message: issue.message,
186
+ })),
187
+ },
188
+ { status: 400 },
189
+ );
190
+ }
191
+
192
+ if (error instanceof SyntaxError || error instanceof TypeError) {
193
+ return Response.json(
194
+ {
195
+ error: "Invalid AG-UI request",
196
+ details: [{ path: [], message: "Malformed JSON request body" }],
197
+ },
198
+ { status: 400 },
199
+ );
200
+ }
201
+
202
+ throw error;
203
+ }
204
+ }
205
+
206
+ export function normalizeAgUiMessages(messages: AgUiRequest["messages"]): Message[] {
207
+ return messages.map((message) => ({
208
+ id: message.id,
209
+ role: message.role,
210
+ parts: message.parts
211
+ .map((part) => normalizeMessagePart(part))
212
+ .filter((part): part is Message["parts"][number] => part !== null),
213
+ ...(message.createdAt ? { timestamp: Date.parse(message.createdAt) || undefined } : {}),
214
+ ...(message.metadata ? { metadata: message.metadata } : {}),
215
+ }));
216
+ }
217
+
218
+ export function createAgUiRunErrorEvent(message: string, code?: string): AgUiSseEvent {
219
+ return {
220
+ event: "RunError",
221
+ payload: {
222
+ message,
223
+ ...(code ? { code } : {}),
224
+ },
225
+ };
226
+ }
227
+
228
+ export function createAgUiSseErrorResponse(event: AgUiSseEvent, status: number): Response {
229
+ return new Response(decoder.decode(formatAgUiEvent(event.event, event.payload)), {
230
+ status,
231
+ headers: {
232
+ "Content-Type": "text/event-stream; charset=utf-8",
233
+ "Cache-Control": "no-cache, no-transform",
234
+ "Connection": "keep-alive",
235
+ "X-Accel-Buffering": "no",
236
+ },
237
+ });
238
+ }
@@ -189,6 +189,14 @@ export {
189
189
  createAgUiCancelHandler,
190
190
  createAgUiResumeHandler,
191
191
  } from "./ag-ui-run-control.js";
192
+ export {
193
+ type AgUiSseEvent,
194
+ createAgUiRunErrorEvent,
195
+ createAgUiSseErrorResponse,
196
+ normalizeAgUiMessages,
197
+ parseAgUiRequest,
198
+ parseAgUiRequestOrError,
199
+ } from "./ag-ui-host-support.js";
192
200
  export {
193
201
  type AgUiContextItem,
194
202
  type AgUiHandlerConfigWithAgent,
@@ -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.220";
3
+ export const VERSION = "0.1.221";