veryfront 0.1.222 → 0.1.223

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  export default {
2
2
  "name": "veryfront",
3
- "version": "0.1.222",
3
+ "version": "0.1.223",
4
4
  "license": "Apache-2.0",
5
5
  "nodeModulesDir": "auto",
6
6
  "workspace": [
@@ -0,0 +1,29 @@
1
+ import { type RunResumeSessionManager } from "./runtime/index.js";
2
+ import type { Agent } from "./types.js";
3
+ import { type AgUiRuntimeRequest } from "./runtime-ag-ui-contract.js";
4
+ type AgUiResumeValue = {
5
+ result: unknown;
6
+ isError: boolean;
7
+ };
8
+ export interface AgUiRuntimeHandlerExecuteInput {
9
+ request: Request;
10
+ agUiInput: AgUiRuntimeRequest;
11
+ context: Record<string, unknown>;
12
+ createDefaultResponse?: () => Promise<Response>;
13
+ }
14
+ export type AgUiRuntimeHandlerExecute = (input: AgUiRuntimeHandlerExecuteInput) => Promise<Response> | Response;
15
+ export interface AgUiRuntimeHandlerOptions {
16
+ context?: Record<string, unknown> | ((request: Request) => Record<string, unknown> | Promise<Record<string, unknown>>);
17
+ sessionManager?: RunResumeSessionManager<AgUiResumeValue>;
18
+ execute?: AgUiRuntimeHandlerExecute;
19
+ }
20
+ export interface AgUiRuntimeHandlerConfigWithAgent extends AgUiRuntimeHandlerOptions {
21
+ agent: Agent;
22
+ }
23
+ export type AgUiRuntimeHandlerConfig = AgUiRuntimeHandlerConfigWithAgent | (AgUiRuntimeHandlerOptions & {
24
+ agent?: undefined;
25
+ execute: AgUiRuntimeHandlerExecute;
26
+ });
27
+ export declare function createAgUiRuntimeHandler(config: AgUiRuntimeHandlerConfig): (requestOrCtx: unknown) => Promise<Response>;
28
+ export {};
29
+ //# sourceMappingURL=ag-ui-runtime-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ag-ui-runtime-handler.d.ts","sourceRoot":"","sources":["../../../src/src/agent/ag-ui-runtime-handler.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,KAAK,uBAAuB,EAC7B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAEL,KAAK,kBAAkB,EAExB,MAAM,6BAA6B,CAAC;AAgBrC,KAAK,eAAe,GAAG;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC;AA2T7D,MAAM,WAAW,8BAA8B;IAC7C,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,kBAAkB,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,qBAAqB,CAAC,EAAE,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAC;CACjD;AAED,MAAM,MAAM,yBAAyB,GAAG,CACtC,KAAK,EAAE,8BAA8B,KAClC,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC;AAElC,MAAM,WAAW,yBAAyB;IACxC,OAAO,CAAC,EACJ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACvB,CAAC,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IACvF,cAAc,CAAC,EAAE,uBAAuB,CAAC,eAAe,CAAC,CAAC;IAC1D,OAAO,CAAC,EAAE,yBAAyB,CAAC;CACrC;AAED,MAAM,WAAW,iCAAkC,SAAQ,yBAAyB;IAClF,KAAK,EAAE,KAAK,CAAC;CACd;AAED,MAAM,MAAM,wBAAwB,GAChC,iCAAiC,GACjC,CAAC,yBAAyB,GAAG;IAAE,KAAK,CAAC,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,yBAAyB,CAAA;CAAE,CAAC,CAAC;AAE5F,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,wBAAwB,GAC/B,CAAC,YAAY,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CA8E9C"}
@@ -0,0 +1,291 @@
1
+ import { z } from "zod";
2
+ import { INVALID_ARGUMENT } from "../errors/index.js";
3
+ import { SKILL_TOOL_IDS } from "../skill/types.js";
4
+ import { toolRegistry } from "../tool/index.js";
5
+ import { AgentRuntime, RunAlreadyExistsError, } from "./runtime/index.js";
6
+ import { parseAgUiRuntimeRequestOrError, } from "./runtime-ag-ui-contract.js";
7
+ import { normalizeAgUiRuntimeMessages } from "./ag-ui-runtime-support.js";
8
+ import { createStreamTransformState, finalizeRunEvents, formatAgUiEvent, mapRuntimeEventToAgUi, } from "../internal-agents/ag-ui-sse.js";
9
+ import { streamDataStreamEvents } from "./data-stream.js";
10
+ const AG_UI_HEADERS = {
11
+ "Content-Type": "text/event-stream",
12
+ "Cache-Control": "no-cache",
13
+ Connection: "keep-alive",
14
+ };
15
+ function isRequest(obj) {
16
+ return (typeof obj === "object" &&
17
+ obj !== null &&
18
+ "json" in obj &&
19
+ typeof obj.json === "function" &&
20
+ "url" in obj &&
21
+ typeof obj.url === "string" &&
22
+ "method" in obj &&
23
+ typeof obj.method === "string");
24
+ }
25
+ function isRecord(value) {
26
+ return typeof value === "object" && value !== null && !Array.isArray(value);
27
+ }
28
+ function extractRequest(requestOrCtx) {
29
+ if (isRequest(requestOrCtx))
30
+ return requestOrCtx;
31
+ if (typeof requestOrCtx === "object" && requestOrCtx !== null && "request" in requestOrCtx) {
32
+ const candidate = requestOrCtx.request;
33
+ if (isRequest(candidate))
34
+ return candidate;
35
+ }
36
+ throw INVALID_ARGUMENT.create({
37
+ detail: "Invalid handler argument: expected Request or APIContext",
38
+ });
39
+ }
40
+ function buildStreamContext(request, baseContext) {
41
+ return {
42
+ ...baseContext,
43
+ threadId: request.threadId,
44
+ runId: request.runId,
45
+ agUi: {
46
+ context: request.context,
47
+ forwardedProps: request.forwardedProps,
48
+ },
49
+ };
50
+ }
51
+ function closeController(controller) {
52
+ try {
53
+ controller.close();
54
+ }
55
+ catch {
56
+ return;
57
+ }
58
+ }
59
+ function enqueueEvent(controller, event, payload) {
60
+ try {
61
+ controller.enqueue(formatAgUiEvent(event, payload));
62
+ return true;
63
+ }
64
+ catch {
65
+ return false;
66
+ }
67
+ }
68
+ async function createAgUiRuntimeStreamResponse(options) {
69
+ const { agentId, request, upstreamBody, upstreamStatus, upstreamStatusText, onFinish, onError, onToolCallSeen, } = options;
70
+ const stream = new ReadableStream({
71
+ start: async (controller) => {
72
+ const state = createStreamTransformState();
73
+ const prepareToolResultIfNeeded = (event, payload) => {
74
+ if (event !== "ToolCallStart" && event !== "ToolCallArgs" &&
75
+ event !== "ToolCallEnd") {
76
+ return;
77
+ }
78
+ const toolCallId = typeof payload.toolCallId === "string" ? payload.toolCallId : null;
79
+ if (toolCallId) {
80
+ onToolCallSeen?.(toolCallId);
81
+ }
82
+ };
83
+ if (!enqueueEvent(controller, "RunStarted", {
84
+ runId: request.runId,
85
+ threadId: request.threadId,
86
+ agentId,
87
+ })) {
88
+ return;
89
+ }
90
+ if (!enqueueEvent(controller, "StateSnapshot", {
91
+ snapshot: isRecord(request.state) ? request.state : {},
92
+ })) {
93
+ return;
94
+ }
95
+ if (!enqueueEvent(controller, "MessagesSnapshot", {
96
+ messages: normalizeAgUiRuntimeMessages(request.messages),
97
+ })) {
98
+ return;
99
+ }
100
+ try {
101
+ if (!upstreamBody) {
102
+ for (const event of finalizeRunEvents(state, null)) {
103
+ if (!enqueueEvent(controller, event.event, event.payload)) {
104
+ return;
105
+ }
106
+ }
107
+ onFinish?.();
108
+ closeController(controller);
109
+ return;
110
+ }
111
+ for await (const event of streamDataStreamEvents(upstreamBody)) {
112
+ for (const mapped of mapRuntimeEventToAgUi(state, event)) {
113
+ prepareToolResultIfNeeded(mapped.event, mapped.payload);
114
+ if (!enqueueEvent(controller, mapped.event, mapped.payload)) {
115
+ return;
116
+ }
117
+ }
118
+ }
119
+ for (const event of finalizeRunEvents(state, null)) {
120
+ if (!enqueueEvent(controller, event.event, event.payload)) {
121
+ return;
122
+ }
123
+ }
124
+ onFinish?.();
125
+ }
126
+ catch (error) {
127
+ onError?.(error);
128
+ enqueueEvent(controller, "RunError", {
129
+ message: error instanceof Error ? error.message : "Agent run failed",
130
+ });
131
+ }
132
+ finally {
133
+ closeController(controller);
134
+ }
135
+ },
136
+ });
137
+ return new Response(stream, {
138
+ status: upstreamStatus,
139
+ statusText: upstreamStatusText,
140
+ headers: { ...AG_UI_HEADERS },
141
+ });
142
+ }
143
+ async function createAgUiRuntimeDirectStreamResponse(agent, request, baseContext) {
144
+ await agent.clearMemory();
145
+ const result = await agent.stream({
146
+ messages: normalizeAgUiRuntimeMessages(request.messages),
147
+ context: buildStreamContext(request, baseContext),
148
+ });
149
+ const upstream = result.toDataStreamResponse();
150
+ return await createAgUiRuntimeStreamResponse({
151
+ agentId: agent.id,
152
+ request,
153
+ upstreamBody: upstream.body,
154
+ upstreamStatus: upstream.status,
155
+ upstreamStatusText: upstream.statusText,
156
+ });
157
+ }
158
+ function createInjectedAgUiTool(runId, tool, sessionManager) {
159
+ return {
160
+ id: tool.name,
161
+ type: "function",
162
+ description: tool.description ?? tool.name,
163
+ inputSchema: z.record(z.string(), z.unknown()),
164
+ inputSchemaJson: (tool.parameters ??
165
+ { type: "object", properties: {}, additionalProperties: true }),
166
+ execute: async (_input, context) => {
167
+ const toolCallId = typeof context?.toolCallId === "string" ? context.toolCallId : null;
168
+ if (!toolCallId) {
169
+ throw new Error(`Missing toolCallId for injected tool "${tool.name}"`);
170
+ }
171
+ sessionManager.prepareForSignal(runId, toolCallId);
172
+ const submitted = await sessionManager.waitForSignal(runId, toolCallId);
173
+ if (submitted.isError) {
174
+ throw new Error(typeof submitted.result === "string"
175
+ ? submitted.result
176
+ : JSON.stringify(submitted.result));
177
+ }
178
+ return submitted.result;
179
+ },
180
+ };
181
+ }
182
+ function buildMergedTools(agent, request, sessionManager) {
183
+ const injectedTools = Object.fromEntries(request.tools.map((tool) => [
184
+ tool.name,
185
+ createInjectedAgUiTool(request.runId, tool, sessionManager),
186
+ ]));
187
+ if (!agent.config.tools) {
188
+ return Object.keys(injectedTools).length > 0 ? injectedTools : undefined;
189
+ }
190
+ if (agent.config.tools === true) {
191
+ const merged = {};
192
+ for (const [toolId] of toolRegistry.getAll()) {
193
+ if (!agent.config.skills && SKILL_TOOL_IDS.has(toolId)) {
194
+ continue;
195
+ }
196
+ merged[toolId] = true;
197
+ }
198
+ return { ...merged, ...injectedTools };
199
+ }
200
+ return { ...agent.config.tools, ...injectedTools };
201
+ }
202
+ async function createAgUiRuntimeInjectedToolsStreamResponse(agent, request, baseContext, sessionManager) {
203
+ try {
204
+ sessionManager.startRun({ runId: request.runId, threadId: request.threadId });
205
+ }
206
+ catch (error) {
207
+ if (error instanceof RunAlreadyExistsError) {
208
+ return Response.json({ error: "Run already active" }, { status: 409 });
209
+ }
210
+ throw error;
211
+ }
212
+ const runtime = new AgentRuntime(agent.id, {
213
+ ...agent.config,
214
+ tools: buildMergedTools(agent, request, sessionManager),
215
+ });
216
+ let upstreamBody;
217
+ try {
218
+ upstreamBody = await runtime.stream(normalizeAgUiRuntimeMessages(request.messages), buildStreamContext(request, baseContext), undefined, undefined, undefined);
219
+ }
220
+ catch (error) {
221
+ sessionManager.failRun(request.runId);
222
+ throw error;
223
+ }
224
+ return await createAgUiRuntimeStreamResponse({
225
+ agentId: agent.id,
226
+ request,
227
+ upstreamBody,
228
+ upstreamStatus: 200,
229
+ onFinish: () => {
230
+ sessionManager.completeRun(request.runId);
231
+ },
232
+ onError: () => {
233
+ sessionManager.failRun(request.runId);
234
+ },
235
+ onToolCallSeen: (toolCallId) => {
236
+ sessionManager.prepareForSignal(request.runId, toolCallId);
237
+ },
238
+ });
239
+ }
240
+ export function createAgUiRuntimeHandler(config) {
241
+ if (!config.agent && !config.execute) {
242
+ throw new Error("createAgUiRuntimeHandler requires either an agent or an execute handler.");
243
+ }
244
+ return async function POST(requestOrCtx) {
245
+ const request = extractRequest(requestOrCtx);
246
+ try {
247
+ const parsed = await parseAgUiRuntimeRequestOrError(request);
248
+ if (parsed instanceof Response) {
249
+ return parsed;
250
+ }
251
+ const context = typeof config.context === "function"
252
+ ? await config.context(request)
253
+ : config.context ?? {};
254
+ const createDefaultResponse = config.agent
255
+ ? () => parsed.tools.length > 0
256
+ ? config.sessionManager
257
+ ? createAgUiRuntimeInjectedToolsStreamResponse(config.agent, parsed, context, config.sessionManager)
258
+ : Promise.resolve(Response.json({
259
+ error: "Injected AG-UI tools require a public RunResumeSessionManager on createAgUiRuntimeHandler().",
260
+ }, { status: 501 }))
261
+ : createAgUiRuntimeDirectStreamResponse(config.agent, parsed, context)
262
+ : undefined;
263
+ if (config.execute) {
264
+ return await config.execute({
265
+ request,
266
+ agUiInput: parsed,
267
+ context,
268
+ createDefaultResponse,
269
+ });
270
+ }
271
+ if (createDefaultResponse) {
272
+ return await createDefaultResponse();
273
+ }
274
+ throw new Error("createAgUiRuntimeHandler configuration became invalid during execution.");
275
+ }
276
+ catch (error) {
277
+ if (error instanceof z.ZodError) {
278
+ return Response.json({
279
+ error: "Invalid AG-UI runtime request",
280
+ details: error.issues.map((issue) => ({
281
+ path: issue.path,
282
+ message: issue.message,
283
+ })),
284
+ }, { status: 400 });
285
+ }
286
+ return Response.json({
287
+ error: error instanceof Error ? error.message : "Internal server error",
288
+ }, { status: 500 });
289
+ }
290
+ };
291
+ }
@@ -0,0 +1,4 @@
1
+ import type { Message } from "./types.js";
2
+ import type { AgUiRuntimeRequest } from "./runtime-ag-ui-contract.js";
3
+ export declare function normalizeAgUiRuntimeMessages(messages: AgUiRuntimeRequest["messages"]): Message[];
4
+ //# sourceMappingURL=ag-ui-runtime-support.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ag-ui-runtime-support.d.ts","sourceRoot":"","sources":["../../../src/src/agent/ag-ui-runtime-support.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAetE,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,kBAAkB,CAAC,UAAU,CAAC,GACvC,OAAO,EAAE,CA6CX"}
@@ -0,0 +1,56 @@
1
+ function isRecord(value) {
2
+ return typeof value === "object" && value !== null && !Array.isArray(value);
3
+ }
4
+ function parseToolArguments(serializedArguments) {
5
+ try {
6
+ const parsed = JSON.parse(serializedArguments);
7
+ return isRecord(parsed) ? parsed : {};
8
+ }
9
+ catch {
10
+ return {};
11
+ }
12
+ }
13
+ export function normalizeAgUiRuntimeMessages(messages) {
14
+ return messages.map((message) => {
15
+ const parts = [];
16
+ switch (message.role) {
17
+ case "system":
18
+ case "user":
19
+ parts.push({ type: "text", text: message.content });
20
+ break;
21
+ case "assistant":
22
+ if (typeof message.content === "string" && message.content.length > 0) {
23
+ parts.push({ type: "text", text: message.content });
24
+ }
25
+ for (const toolCall of message.toolCalls ?? []) {
26
+ parts.push({
27
+ type: "tool-call",
28
+ toolCallId: toolCall.id,
29
+ toolName: toolCall.function.name,
30
+ args: parseToolArguments(toolCall.function.arguments),
31
+ });
32
+ }
33
+ break;
34
+ case "tool":
35
+ parts.push({
36
+ type: "tool-result",
37
+ toolCallId: message.toolCallId,
38
+ toolName: "unknown",
39
+ result: message.error
40
+ ? {
41
+ content: message.content,
42
+ error: message.error,
43
+ }
44
+ : message.content,
45
+ });
46
+ break;
47
+ }
48
+ return {
49
+ id: message.id,
50
+ role: message.role,
51
+ parts,
52
+ ...(message.createdAt ? { timestamp: Date.parse(message.createdAt) || undefined } : {}),
53
+ ...(message.metadata ? { metadata: message.metadata } : {}),
54
+ };
55
+ });
56
+ }
@@ -84,7 +84,9 @@ export { getTextFromParts, getToolArguments, hasArgs, hasInput } from "./types.j
84
84
  export { BufferMemory, ConversationMemory, createMemory, createRedisMemory, type Memory, type MemoryPersistence, type MemoryStats, type RedisClient, RedisMemory, type RedisMemoryConfig, SummaryMemory, } from "./memory/index.js";
85
85
  export { agentAsTool, createWorkflow, getAgent, getAgentsAsTools, getAllAgentIds, registerAgent, type WorkflowConfig, type WorkflowResult, type WorkflowStep, } from "./composition/index.js";
86
86
  export { agent } from "./factory.js";
87
+ export { type AgUiRuntimeHandlerConfig, type AgUiRuntimeHandlerConfigWithAgent, type AgUiRuntimeHandlerExecute, type AgUiRuntimeHandlerExecuteInput, type AgUiRuntimeHandlerOptions, createAgUiRuntimeHandler, } from "./ag-ui-runtime-handler.js";
87
88
  export { type AgUiRuntimeContextItem, AgUiRuntimeContextItemSchema, type AgUiRuntimeInjectedTool, AgUiRuntimeInjectedToolSchema, type AgUiRuntimeMessage, AgUiRuntimeMessageSchema, type AgUiRuntimeRequest, AgUiRuntimeRequestSchema, parseAgUiRuntimeRequest, parseAgUiRuntimeRequestOrError, } from "./runtime-ag-ui-contract.js";
89
+ export { normalizeAgUiRuntimeMessages } from "./ag-ui-runtime-support.js";
88
90
  export { type AgUiBrowserEncodedEvent, type AgUiBrowserEncoderState, type AgUiBrowserRunFinishedMetadata, type AgUiRuntimeStreamEvent, createAgUiBrowserEncoderState, finalizeAgUiBrowserEvents, mapRuntimeStreamEventToAgUiBrowserEvents, } from "./ag-ui-browser-encoder.js";
89
91
  export { mergeToolCallInput, mergeToolInputDelta, parseDataStreamSseEvents, parseToolInputObject, streamDataStreamEvents, stripLeadingEmptyObjectPlaceholder, } from "./data-stream.js";
90
92
  export { expandAllowedRemoteToolNames, getProviderNativeToolNames, type ProviderNativeToolInventoryOptions, } from "./provider-native-tool-inventory.js";
@@ -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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"}
@@ -83,7 +83,9 @@ export { getTextFromParts, getToolArguments, hasArgs, hasInput } from "./types.j
83
83
  export { BufferMemory, ConversationMemory, createMemory, createRedisMemory, RedisMemory, SummaryMemory, } from "./memory/index.js";
84
84
  export { agentAsTool, createWorkflow, getAgent, getAgentsAsTools, getAllAgentIds, registerAgent, } from "./composition/index.js";
85
85
  export { agent } from "./factory.js";
86
+ export { createAgUiRuntimeHandler, } from "./ag-ui-runtime-handler.js";
86
87
  export { AgUiRuntimeContextItemSchema, AgUiRuntimeInjectedToolSchema, AgUiRuntimeMessageSchema, AgUiRuntimeRequestSchema, parseAgUiRuntimeRequest, parseAgUiRuntimeRequestOrError, } from "./runtime-ag-ui-contract.js";
88
+ export { normalizeAgUiRuntimeMessages } from "./ag-ui-runtime-support.js";
87
89
  export { createAgUiBrowserEncoderState, finalizeAgUiBrowserEvents, mapRuntimeStreamEventToAgUiBrowserEvents, } from "./ag-ui-browser-encoder.js";
88
90
  export { mergeToolCallInput, mergeToolInputDelta, parseDataStreamSseEvents, parseToolInputObject, streamDataStreamEvents, stripLeadingEmptyObjectPlaceholder, } from "./data-stream.js";
89
91
  export { expandAllowedRemoteToolNames, getProviderNativeToolNames, } from "./provider-native-tool-inventory.js";
@@ -1 +1 @@
1
- {"version":3,"file":"run-stream.d.ts","sourceRoot":"","sources":["../../../src/src/internal-agents/run-stream.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,KAAK,EACV,KAAK,YAAY,IAAI,OAAO,EAC5B,KAAK,aAAa,EAEnB,MAAM,mBAAmB,CAAC;AAW3B,OAAO,EAA0B,KAAK,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC3F,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAYxD,MAAM,WAAW,+BAA+B;IAC9C,cAAc,EAAE,sBAAsB,CAAC;IACvC,aAAa,CAAC,EAAE,CACd,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,KAClC;QACH,MAAM,EAAE,CACN,QAAQ,EAAE,OAAO,EAAE,EACnB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,SAAS,CAAC,EAAE;YACV,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,IAAI,CAAC;SAC9C,EACD,aAAa,CAAC,EAAE,MAAM,EACtB,uBAAuB,CAAC,EAAE,MAAM,EAChC,WAAW,CAAC,EAAE,WAAW,KACtB,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC;KAC1C,CAAC;CACH;AAoJD,wBAAsB,gCAAgC,CACpD,KAAK,EAAE,oBAAoB,EAC3B,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,+BAA+B,GACpC,OAAO,CAAC,QAAQ,CAAC,CA8OnB"}
1
+ {"version":3,"file":"run-stream.d.ts","sourceRoot":"","sources":["../../../src/src/internal-agents/run-stream.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,KAAK,EACV,KAAK,YAAY,IAAI,OAAO,EAC5B,KAAK,aAAa,EAEnB,MAAM,mBAAmB,CAAC;AAY3B,OAAO,EAA0B,KAAK,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC3F,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAYxD,MAAM,WAAW,+BAA+B;IAC9C,cAAc,EAAE,sBAAsB,CAAC;IACvC,aAAa,CAAC,EAAE,CACd,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,KAClC;QACH,MAAM,EAAE,CACN,QAAQ,EAAE,OAAO,EAAE,EACnB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,SAAS,CAAC,EAAE;YACV,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,IAAI,CAAC;SAC9C,EACD,aAAa,CAAC,EAAE,MAAM,EACtB,uBAAuB,CAAC,EAAE,MAAM,EAChC,WAAW,CAAC,EAAE,WAAW,KACtB,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC;KAC1C,CAAC;CACH;AA4FD,wBAAsB,gCAAgC,CACpD,KAAK,EAAE,oBAAoB,EAC3B,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,+BAA+B,GACpC,OAAO,CAAC,QAAQ,CAAC,CA8OnB"}
@@ -1,4 +1,5 @@
1
1
  import { AgentRuntime, } from "../agent/index.js";
2
+ import { normalizeAgUiRuntimeMessages } from "../agent/ag-ui-runtime-support.js";
2
3
  import { SKILL_TOOL_IDS } from "../skill/types.js";
3
4
  import { toolRegistry } from "../tool/index.js";
4
5
  import { z } from "zod";
@@ -54,59 +55,6 @@ function buildMergedTools(agent, input, sessionManager) {
54
55
  function isRecord(value) {
55
56
  return typeof value === "object" && value !== null && !Array.isArray(value);
56
57
  }
57
- function parseToolArguments(serializedArguments) {
58
- try {
59
- const parsed = JSON.parse(serializedArguments);
60
- return isRecord(parsed) ? parsed : {};
61
- }
62
- catch {
63
- return {};
64
- }
65
- }
66
- function normalizeRuntimeMessages(messages) {
67
- return messages.map((message) => {
68
- const parts = [];
69
- switch (message.role) {
70
- case "system":
71
- case "user":
72
- parts.push({ type: "text", text: message.content });
73
- break;
74
- case "assistant":
75
- if (typeof message.content === "string" && message.content.length > 0) {
76
- parts.push({ type: "text", text: message.content });
77
- }
78
- for (const toolCall of message.toolCalls ?? []) {
79
- parts.push({
80
- type: "tool-call",
81
- toolCallId: toolCall.id,
82
- toolName: toolCall.function.name,
83
- args: parseToolArguments(toolCall.function.arguments),
84
- });
85
- }
86
- break;
87
- case "tool":
88
- parts.push({
89
- type: "tool-result",
90
- toolCallId: message.toolCallId,
91
- toolName: "unknown",
92
- result: message.error
93
- ? {
94
- content: message.content,
95
- error: message.error,
96
- }
97
- : message.content,
98
- });
99
- break;
100
- }
101
- return {
102
- id: message.id,
103
- role: message.role,
104
- parts,
105
- ...(message.createdAt ? { timestamp: Date.parse(message.createdAt) || undefined } : {}),
106
- ...(message.metadata ? { metadata: message.metadata } : {}),
107
- };
108
- });
109
- }
110
58
  function getAllowedRemoteToolNames(forwardedProps) {
111
59
  const runtimeOverrides = isRecord(forwardedProps?.runtimeOverrides)
112
60
  ? forwardedProps.runtimeOverrides
@@ -148,7 +96,7 @@ export async function createRuntimeAgentStreamResponse(input, agent, deps) {
148
96
  const runtime = deps.createRuntime?.(runtimeAgent, mergedTools) ??
149
97
  new AgentRuntime(runtimeAgent.id, runtimeAgent.config);
150
98
  let completedResponse = null;
151
- const runtimeMessages = normalizeRuntimeMessages(input.messages);
99
+ const runtimeMessages = normalizeAgUiRuntimeMessages(input.messages);
152
100
  let runtimeStream;
153
101
  let clientAttached = true;
154
102
  try {
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "0.1.222";
1
+ export declare const VERSION = "0.1.223";
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.222";
3
+ export const VERSION = "0.1.223";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "veryfront",
3
- "version": "0.1.222",
3
+ "version": "0.1.223",
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.222",
3
+ "version": "0.1.223",
4
4
  "license": "Apache-2.0",
5
5
  "nodeModulesDir": "auto",
6
6
  "workspace": [
@@ -0,0 +1,453 @@
1
+ import { z } from "zod";
2
+ import { INVALID_ARGUMENT } from "../errors/index.js";
3
+ import { SKILL_TOOL_IDS } from "../skill/types.js";
4
+ import { type Tool, toolRegistry } from "../tool/index.js";
5
+ import {
6
+ AgentRuntime,
7
+ RunAlreadyExistsError,
8
+ type RunResumeSessionManager,
9
+ } from "./runtime/index.js";
10
+ import type { Agent } from "./types.js";
11
+ import {
12
+ type AgUiRuntimeInjectedTool,
13
+ type AgUiRuntimeRequest,
14
+ parseAgUiRuntimeRequestOrError,
15
+ } from "./runtime-ag-ui-contract.js";
16
+ import { normalizeAgUiRuntimeMessages } from "./ag-ui-runtime-support.js";
17
+ import {
18
+ createStreamTransformState,
19
+ finalizeRunEvents,
20
+ formatAgUiEvent,
21
+ mapRuntimeEventToAgUi,
22
+ } from "../internal-agents/ag-ui-sse.js";
23
+ import { streamDataStreamEvents } from "./data-stream.js";
24
+
25
+ const AG_UI_HEADERS: Record<string, string> = {
26
+ "Content-Type": "text/event-stream",
27
+ "Cache-Control": "no-cache",
28
+ Connection: "keep-alive",
29
+ };
30
+
31
+ type AgUiResumeValue = { result: unknown; isError: boolean };
32
+ type AgUiRuntimePart = Record<string, unknown> & { type: string };
33
+
34
+ function isRequest(obj: unknown): obj is Request {
35
+ return (
36
+ typeof obj === "object" &&
37
+ obj !== null &&
38
+ "json" in obj &&
39
+ typeof obj.json === "function" &&
40
+ "url" in obj &&
41
+ typeof obj.url === "string" &&
42
+ "method" in obj &&
43
+ typeof obj.method === "string"
44
+ );
45
+ }
46
+
47
+ function isRecord(value: unknown): value is Record<string, unknown> {
48
+ return typeof value === "object" && value !== null && !Array.isArray(value);
49
+ }
50
+
51
+ function extractRequest(requestOrCtx: unknown): Request {
52
+ if (isRequest(requestOrCtx)) return requestOrCtx;
53
+
54
+ if (typeof requestOrCtx === "object" && requestOrCtx !== null && "request" in requestOrCtx) {
55
+ const candidate = (requestOrCtx as Record<string, unknown>).request;
56
+ if (isRequest(candidate)) return candidate;
57
+ }
58
+
59
+ throw INVALID_ARGUMENT.create({
60
+ detail: "Invalid handler argument: expected Request or APIContext",
61
+ });
62
+ }
63
+
64
+ function buildStreamContext(
65
+ request: AgUiRuntimeRequest,
66
+ baseContext: Record<string, unknown>,
67
+ ): Record<string, unknown> {
68
+ return {
69
+ ...baseContext,
70
+ threadId: request.threadId,
71
+ runId: request.runId,
72
+ agUi: {
73
+ context: request.context,
74
+ forwardedProps: request.forwardedProps,
75
+ },
76
+ };
77
+ }
78
+
79
+ function closeController(controller: ReadableStreamDefaultController<Uint8Array>): void {
80
+ try {
81
+ controller.close();
82
+ } catch {
83
+ return;
84
+ }
85
+ }
86
+
87
+ function enqueueEvent(
88
+ controller: ReadableStreamDefaultController<Uint8Array>,
89
+ event: string,
90
+ payload: Record<string, unknown>,
91
+ ): boolean {
92
+ try {
93
+ controller.enqueue(formatAgUiEvent(event, payload));
94
+ return true;
95
+ } catch {
96
+ return false;
97
+ }
98
+ }
99
+
100
+ async function createAgUiRuntimeStreamResponse(
101
+ options: {
102
+ agentId: string;
103
+ request: AgUiRuntimeRequest;
104
+ upstreamBody: ReadableStream<Uint8Array> | null;
105
+ upstreamStatus: number;
106
+ upstreamStatusText?: string;
107
+ onFinish?: () => void;
108
+ onError?: (error: unknown) => void;
109
+ onToolCallSeen?: (toolCallId: string) => void;
110
+ },
111
+ ): Promise<Response> {
112
+ const {
113
+ agentId,
114
+ request,
115
+ upstreamBody,
116
+ upstreamStatus,
117
+ upstreamStatusText,
118
+ onFinish,
119
+ onError,
120
+ onToolCallSeen,
121
+ } = options;
122
+
123
+ const stream = new ReadableStream<Uint8Array>({
124
+ start: async (controller) => {
125
+ const state = createStreamTransformState();
126
+ const prepareToolResultIfNeeded = (event: string, payload: Record<string, unknown>) => {
127
+ if (
128
+ event !== "ToolCallStart" && event !== "ToolCallArgs" &&
129
+ event !== "ToolCallEnd"
130
+ ) {
131
+ return;
132
+ }
133
+
134
+ const toolCallId = typeof payload.toolCallId === "string" ? payload.toolCallId : null;
135
+ if (toolCallId) {
136
+ onToolCallSeen?.(toolCallId);
137
+ }
138
+ };
139
+
140
+ if (
141
+ !enqueueEvent(controller, "RunStarted", {
142
+ runId: request.runId,
143
+ threadId: request.threadId,
144
+ agentId,
145
+ })
146
+ ) {
147
+ return;
148
+ }
149
+ if (
150
+ !enqueueEvent(controller, "StateSnapshot", {
151
+ snapshot: isRecord(request.state) ? request.state : {},
152
+ })
153
+ ) {
154
+ return;
155
+ }
156
+ if (
157
+ !enqueueEvent(controller, "MessagesSnapshot", {
158
+ messages: normalizeAgUiRuntimeMessages(request.messages),
159
+ })
160
+ ) {
161
+ return;
162
+ }
163
+
164
+ try {
165
+ if (!upstreamBody) {
166
+ for (const event of finalizeRunEvents(state, null)) {
167
+ if (!enqueueEvent(controller, event.event, event.payload)) {
168
+ return;
169
+ }
170
+ }
171
+ onFinish?.();
172
+ closeController(controller);
173
+ return;
174
+ }
175
+
176
+ for await (
177
+ const event of streamDataStreamEvents(upstreamBody) as AsyncIterable<AgUiRuntimePart>
178
+ ) {
179
+ for (const mapped of mapRuntimeEventToAgUi(state, event)) {
180
+ prepareToolResultIfNeeded(mapped.event, mapped.payload);
181
+ if (!enqueueEvent(controller, mapped.event, mapped.payload)) {
182
+ return;
183
+ }
184
+ }
185
+ }
186
+
187
+ for (const event of finalizeRunEvents(state, null)) {
188
+ if (!enqueueEvent(controller, event.event, event.payload)) {
189
+ return;
190
+ }
191
+ }
192
+ onFinish?.();
193
+ } catch (error) {
194
+ onError?.(error);
195
+ enqueueEvent(controller, "RunError", {
196
+ message: error instanceof Error ? error.message : "Agent run failed",
197
+ });
198
+ } finally {
199
+ closeController(controller);
200
+ }
201
+ },
202
+ });
203
+
204
+ return new Response(stream, {
205
+ status: upstreamStatus,
206
+ statusText: upstreamStatusText,
207
+ headers: { ...AG_UI_HEADERS },
208
+ });
209
+ }
210
+
211
+ async function createAgUiRuntimeDirectStreamResponse(
212
+ agent: Agent,
213
+ request: AgUiRuntimeRequest,
214
+ baseContext: Record<string, unknown>,
215
+ ): Promise<Response> {
216
+ await agent.clearMemory();
217
+
218
+ const result = await agent.stream({
219
+ messages: normalizeAgUiRuntimeMessages(request.messages),
220
+ context: buildStreamContext(request, baseContext),
221
+ });
222
+
223
+ const upstream = result.toDataStreamResponse();
224
+ return await createAgUiRuntimeStreamResponse({
225
+ agentId: agent.id,
226
+ request,
227
+ upstreamBody: upstream.body,
228
+ upstreamStatus: upstream.status,
229
+ upstreamStatusText: upstream.statusText,
230
+ });
231
+ }
232
+
233
+ function createInjectedAgUiTool(
234
+ runId: string,
235
+ tool: AgUiRuntimeInjectedTool,
236
+ sessionManager: RunResumeSessionManager<AgUiResumeValue>,
237
+ ): Tool {
238
+ return {
239
+ id: tool.name,
240
+ type: "function",
241
+ description: tool.description ?? tool.name,
242
+ inputSchema: z.record(z.string(), z.unknown()),
243
+ inputSchemaJson: (tool.parameters ??
244
+ { type: "object", properties: {}, additionalProperties: true }) as Tool["inputSchemaJson"],
245
+ execute: async (_input, context) => {
246
+ const toolCallId = typeof context?.toolCallId === "string" ? context.toolCallId : null;
247
+ if (!toolCallId) {
248
+ throw new Error(`Missing toolCallId for injected tool "${tool.name}"`);
249
+ }
250
+
251
+ sessionManager.prepareForSignal(runId, toolCallId);
252
+ const submitted = await sessionManager.waitForSignal(runId, toolCallId);
253
+ if (submitted.isError) {
254
+ throw new Error(
255
+ typeof submitted.result === "string"
256
+ ? submitted.result
257
+ : JSON.stringify(submitted.result),
258
+ );
259
+ }
260
+ return submitted.result;
261
+ },
262
+ };
263
+ }
264
+
265
+ function buildMergedTools(
266
+ agent: Agent,
267
+ request: AgUiRuntimeRequest,
268
+ sessionManager: RunResumeSessionManager<AgUiResumeValue>,
269
+ ): Agent["config"]["tools"] {
270
+ const injectedTools = Object.fromEntries(
271
+ request.tools.map((tool) => [
272
+ tool.name,
273
+ createInjectedAgUiTool(request.runId, tool, sessionManager),
274
+ ]),
275
+ );
276
+
277
+ if (!agent.config.tools) {
278
+ return Object.keys(injectedTools).length > 0 ? injectedTools : undefined;
279
+ }
280
+
281
+ if (agent.config.tools === true) {
282
+ const merged: Record<string, Tool | boolean> = {};
283
+ for (const [toolId] of toolRegistry.getAll()) {
284
+ if (!agent.config.skills && SKILL_TOOL_IDS.has(toolId)) {
285
+ continue;
286
+ }
287
+ merged[toolId] = true;
288
+ }
289
+ return { ...merged, ...injectedTools };
290
+ }
291
+
292
+ return { ...agent.config.tools, ...injectedTools };
293
+ }
294
+
295
+ async function createAgUiRuntimeInjectedToolsStreamResponse(
296
+ agent: Agent,
297
+ request: AgUiRuntimeRequest,
298
+ baseContext: Record<string, unknown>,
299
+ sessionManager: RunResumeSessionManager<AgUiResumeValue>,
300
+ ): Promise<Response> {
301
+ try {
302
+ sessionManager.startRun({ runId: request.runId, threadId: request.threadId });
303
+ } catch (error) {
304
+ if (error instanceof RunAlreadyExistsError) {
305
+ return Response.json({ error: "Run already active" }, { status: 409 });
306
+ }
307
+ throw error;
308
+ }
309
+
310
+ const runtime = new AgentRuntime(agent.id, {
311
+ ...agent.config,
312
+ tools: buildMergedTools(agent, request, sessionManager),
313
+ });
314
+
315
+ let upstreamBody: ReadableStream<Uint8Array>;
316
+ try {
317
+ upstreamBody = await runtime.stream(
318
+ normalizeAgUiRuntimeMessages(request.messages),
319
+ buildStreamContext(request, baseContext),
320
+ undefined,
321
+ undefined,
322
+ undefined,
323
+ );
324
+ } catch (error) {
325
+ sessionManager.failRun(request.runId);
326
+ throw error;
327
+ }
328
+
329
+ return await createAgUiRuntimeStreamResponse({
330
+ agentId: agent.id,
331
+ request,
332
+ upstreamBody,
333
+ upstreamStatus: 200,
334
+ onFinish: () => {
335
+ sessionManager.completeRun(request.runId);
336
+ },
337
+ onError: () => {
338
+ sessionManager.failRun(request.runId);
339
+ },
340
+ onToolCallSeen: (toolCallId) => {
341
+ sessionManager.prepareForSignal(request.runId, toolCallId);
342
+ },
343
+ });
344
+ }
345
+
346
+ export interface AgUiRuntimeHandlerExecuteInput {
347
+ request: Request;
348
+ agUiInput: AgUiRuntimeRequest;
349
+ context: Record<string, unknown>;
350
+ createDefaultResponse?: () => Promise<Response>;
351
+ }
352
+
353
+ export type AgUiRuntimeHandlerExecute = (
354
+ input: AgUiRuntimeHandlerExecuteInput,
355
+ ) => Promise<Response> | Response;
356
+
357
+ export interface AgUiRuntimeHandlerOptions {
358
+ context?:
359
+ | Record<string, unknown>
360
+ | ((request: Request) => Record<string, unknown> | Promise<Record<string, unknown>>);
361
+ sessionManager?: RunResumeSessionManager<AgUiResumeValue>;
362
+ execute?: AgUiRuntimeHandlerExecute;
363
+ }
364
+
365
+ export interface AgUiRuntimeHandlerConfigWithAgent extends AgUiRuntimeHandlerOptions {
366
+ agent: Agent;
367
+ }
368
+
369
+ export type AgUiRuntimeHandlerConfig =
370
+ | AgUiRuntimeHandlerConfigWithAgent
371
+ | (AgUiRuntimeHandlerOptions & { agent?: undefined; execute: AgUiRuntimeHandlerExecute });
372
+
373
+ export function createAgUiRuntimeHandler(
374
+ config: AgUiRuntimeHandlerConfig,
375
+ ): (requestOrCtx: unknown) => Promise<Response> {
376
+ if (!config.agent && !config.execute) {
377
+ throw new Error(
378
+ "createAgUiRuntimeHandler requires either an agent or an execute handler.",
379
+ );
380
+ }
381
+
382
+ return async function POST(requestOrCtx: unknown): Promise<Response> {
383
+ const request = extractRequest(requestOrCtx);
384
+
385
+ try {
386
+ const parsed = await parseAgUiRuntimeRequestOrError(request);
387
+ if (parsed instanceof Response) {
388
+ return parsed;
389
+ }
390
+
391
+ const context = typeof config.context === "function"
392
+ ? await config.context(request)
393
+ : config.context ?? {};
394
+
395
+ const createDefaultResponse = config.agent
396
+ ? () =>
397
+ parsed.tools.length > 0
398
+ ? config.sessionManager
399
+ ? createAgUiRuntimeInjectedToolsStreamResponse(
400
+ config.agent,
401
+ parsed,
402
+ context,
403
+ config.sessionManager,
404
+ )
405
+ : Promise.resolve(
406
+ Response.json(
407
+ {
408
+ error:
409
+ "Injected AG-UI tools require a public RunResumeSessionManager on createAgUiRuntimeHandler().",
410
+ },
411
+ { status: 501 },
412
+ ),
413
+ )
414
+ : createAgUiRuntimeDirectStreamResponse(config.agent, parsed, context)
415
+ : undefined;
416
+
417
+ if (config.execute) {
418
+ return await config.execute({
419
+ request,
420
+ agUiInput: parsed,
421
+ context,
422
+ createDefaultResponse,
423
+ });
424
+ }
425
+
426
+ if (createDefaultResponse) {
427
+ return await createDefaultResponse();
428
+ }
429
+
430
+ throw new Error("createAgUiRuntimeHandler configuration became invalid during execution.");
431
+ } catch (error) {
432
+ if (error instanceof z.ZodError) {
433
+ return Response.json(
434
+ {
435
+ error: "Invalid AG-UI runtime request",
436
+ details: error.issues.map((issue) => ({
437
+ path: issue.path,
438
+ message: issue.message,
439
+ })),
440
+ },
441
+ { status: 400 },
442
+ );
443
+ }
444
+
445
+ return Response.json(
446
+ {
447
+ error: error instanceof Error ? error.message : "Internal server error",
448
+ },
449
+ { status: 500 },
450
+ );
451
+ }
452
+ };
453
+ }
@@ -0,0 +1,64 @@
1
+ import type { Message } from "./types.js";
2
+ import type { AgUiRuntimeRequest } from "./runtime-ag-ui-contract.js";
3
+
4
+ function isRecord(value: unknown): value is Record<string, unknown> {
5
+ return typeof value === "object" && value !== null && !Array.isArray(value);
6
+ }
7
+
8
+ function parseToolArguments(serializedArguments: string): Record<string, unknown> {
9
+ try {
10
+ const parsed = JSON.parse(serializedArguments);
11
+ return isRecord(parsed) ? parsed : {};
12
+ } catch {
13
+ return {};
14
+ }
15
+ }
16
+
17
+ export function normalizeAgUiRuntimeMessages(
18
+ messages: AgUiRuntimeRequest["messages"],
19
+ ): Message[] {
20
+ return messages.map((message) => {
21
+ const parts: Message["parts"] = [];
22
+
23
+ switch (message.role) {
24
+ case "system":
25
+ case "user":
26
+ parts.push({ type: "text", text: message.content });
27
+ break;
28
+ case "assistant":
29
+ if (typeof message.content === "string" && message.content.length > 0) {
30
+ parts.push({ type: "text", text: message.content });
31
+ }
32
+ for (const toolCall of message.toolCalls ?? []) {
33
+ parts.push({
34
+ type: "tool-call",
35
+ toolCallId: toolCall.id,
36
+ toolName: toolCall.function.name,
37
+ args: parseToolArguments(toolCall.function.arguments),
38
+ });
39
+ }
40
+ break;
41
+ case "tool":
42
+ parts.push({
43
+ type: "tool-result",
44
+ toolCallId: message.toolCallId,
45
+ toolName: "unknown",
46
+ result: message.error
47
+ ? {
48
+ content: message.content,
49
+ error: message.error,
50
+ }
51
+ : message.content,
52
+ });
53
+ break;
54
+ }
55
+
56
+ return {
57
+ id: message.id,
58
+ role: message.role,
59
+ parts,
60
+ ...(message.createdAt ? { timestamp: Date.parse(message.createdAt) || undefined } : {}),
61
+ ...(message.metadata ? { metadata: message.metadata } : {}),
62
+ };
63
+ });
64
+ }
@@ -141,6 +141,14 @@ export {
141
141
  } from "./composition/index.js";
142
142
 
143
143
  export { agent } from "./factory.js";
144
+ export {
145
+ type AgUiRuntimeHandlerConfig,
146
+ type AgUiRuntimeHandlerConfigWithAgent,
147
+ type AgUiRuntimeHandlerExecute,
148
+ type AgUiRuntimeHandlerExecuteInput,
149
+ type AgUiRuntimeHandlerOptions,
150
+ createAgUiRuntimeHandler,
151
+ } from "./ag-ui-runtime-handler.js";
144
152
  export {
145
153
  type AgUiRuntimeContextItem,
146
154
  AgUiRuntimeContextItemSchema,
@@ -153,6 +161,7 @@ export {
153
161
  parseAgUiRuntimeRequest,
154
162
  parseAgUiRuntimeRequestOrError,
155
163
  } from "./runtime-ag-ui-contract.js";
164
+ export { normalizeAgUiRuntimeMessages } from "./ag-ui-runtime-support.js";
156
165
  export {
157
166
  type AgUiBrowserEncodedEvent,
158
167
  type AgUiBrowserEncoderState,
@@ -4,6 +4,7 @@ import {
4
4
  type AgentResponse,
5
5
  AgentRuntime,
6
6
  } from "../agent/index.js";
7
+ import { normalizeAgUiRuntimeMessages } from "../agent/ag-ui-runtime-support.js";
7
8
  import { SKILL_TOOL_IDS } from "../skill/types.js";
8
9
  import { type Tool, toolRegistry } from "../tool/index.js";
9
10
  import { z } from "zod";
@@ -120,62 +121,6 @@ function isRecord(value: unknown): value is Record<string, unknown> {
120
121
  return typeof value === "object" && value !== null && !Array.isArray(value);
121
122
  }
122
123
 
123
- function parseToolArguments(serializedArguments: string): Record<string, unknown> {
124
- try {
125
- const parsed = JSON.parse(serializedArguments);
126
- return isRecord(parsed) ? parsed : {};
127
- } catch {
128
- return {};
129
- }
130
- }
131
-
132
- function normalizeRuntimeMessages(messages: RuntimeRunAgentInput["messages"]): Message[] {
133
- return messages.map((message) => {
134
- const parts: Message["parts"] = [];
135
-
136
- switch (message.role) {
137
- case "system":
138
- case "user":
139
- parts.push({ type: "text", text: message.content });
140
- break;
141
- case "assistant":
142
- if (typeof message.content === "string" && message.content.length > 0) {
143
- parts.push({ type: "text", text: message.content });
144
- }
145
- for (const toolCall of message.toolCalls ?? []) {
146
- parts.push({
147
- type: "tool-call",
148
- toolCallId: toolCall.id,
149
- toolName: toolCall.function.name,
150
- args: parseToolArguments(toolCall.function.arguments),
151
- });
152
- }
153
- break;
154
- case "tool":
155
- parts.push({
156
- type: "tool-result",
157
- toolCallId: message.toolCallId,
158
- toolName: "unknown",
159
- result: message.error
160
- ? {
161
- content: message.content,
162
- error: message.error,
163
- }
164
- : message.content,
165
- });
166
- break;
167
- }
168
-
169
- return {
170
- id: message.id,
171
- role: message.role,
172
- parts,
173
- ...(message.createdAt ? { timestamp: Date.parse(message.createdAt) || undefined } : {}),
174
- ...(message.metadata ? { metadata: message.metadata } : {}),
175
- };
176
- });
177
- }
178
-
179
124
  function getAllowedRemoteToolNames(
180
125
  forwardedProps: RuntimeRunAgentInput["forwardedProps"],
181
126
  ): string[] | undefined {
@@ -226,7 +171,7 @@ export async function createRuntimeAgentStreamResponse(
226
171
  new AgentRuntime(runtimeAgent.id, runtimeAgent.config);
227
172
 
228
173
  let completedResponse: AgentResponse | null = null;
229
- const runtimeMessages = normalizeRuntimeMessages(input.messages);
174
+ const runtimeMessages = normalizeAgUiRuntimeMessages(input.messages);
230
175
  let runtimeStream: ReadableStream<Uint8Array>;
231
176
  let clientAttached = true;
232
177
  try {
@@ -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.222";
3
+ export const VERSION = "0.1.223";