veryfront 0.1.261 → 0.1.262
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/cli/commands/knowledge/command.d.ts.map +1 -1
- package/esm/cli/commands/knowledge/command.js +19 -26
- package/esm/deno.js +1 -1
- package/esm/src/agent/ag-ui-detached-start.d.ts +1 -4
- package/esm/src/agent/ag-ui-detached-start.d.ts.map +1 -1
- package/esm/src/agent/ag-ui-detached-start.js +4 -67
- package/esm/src/agent/ag-ui-handler.d.ts +1 -4
- package/esm/src/agent/ag-ui-handler.d.ts.map +1 -1
- package/esm/src/agent/ag-ui-handler.js +3 -61
- package/esm/src/agent/ag-ui-host-support.d.ts.map +1 -1
- package/esm/src/agent/ag-ui-host-support.js +2 -21
- package/esm/src/agent/ag-ui-request-shared.d.ts +4 -0
- package/esm/src/agent/ag-ui-request-shared.d.ts.map +1 -0
- package/esm/src/agent/ag-ui-request-shared.js +47 -0
- package/esm/src/agent/ag-ui-run-control.d.ts.map +1 -1
- package/esm/src/agent/ag-ui-run-control.js +1 -23
- package/esm/src/agent/ag-ui-runtime-handler.d.ts +1 -5
- package/esm/src/agent/ag-ui-runtime-handler.d.ts.map +1 -1
- package/esm/src/agent/ag-ui-runtime-handler.js +3 -67
- package/esm/src/agent/ag-ui-tool-shared.d.ts +15 -0
- package/esm/src/agent/ag-ui-tool-shared.d.ts.map +1 -0
- package/esm/src/agent/ag-ui-tool-shared.js +47 -0
- package/esm/src/agent/index.d.ts +2 -0
- package/esm/src/agent/index.d.ts.map +1 -1
- package/esm/src/agent/index.js +1 -0
- package/esm/src/agent/runtime-ag-ui-contract.d.ts.map +1 -1
- package/esm/src/agent/runtime-ag-ui-contract.js +2 -21
- package/esm/src/chat/chat-ui-message-helpers.d.ts +18 -0
- package/esm/src/chat/chat-ui-message-helpers.d.ts.map +1 -0
- package/esm/src/chat/chat-ui-message-helpers.js +84 -0
- package/esm/src/chat/index.d.ts +2 -0
- package/esm/src/chat/index.d.ts.map +1 -1
- package/esm/src/chat/index.js +1 -0
- package/esm/src/chat/protocol.d.ts +109 -0
- package/esm/src/chat/protocol.d.ts.map +1 -1
- 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/cli/commands/knowledge/command.ts +27 -32
- package/src/deno.js +1 -1
- package/src/src/agent/ag-ui-detached-start.ts +4 -92
- package/src/src/agent/ag-ui-handler.ts +3 -81
- package/src/src/agent/ag-ui-host-support.ts +5 -28
- package/src/src/agent/ag-ui-request-shared.ts +62 -0
- package/src/src/agent/ag-ui-run-control.ts +1 -27
- package/src/src/agent/ag-ui-runtime-handler.ts +3 -86
- package/src/src/agent/ag-ui-tool-shared.ts +77 -0
- package/src/src/agent/index.ts +15 -0
- package/src/src/agent/runtime-ag-ui-contract.ts +5 -28
- package/src/src/chat/chat-ui-message-helpers.ts +114 -0
- package/src/src/chat/index.ts +17 -0
- package/src/src/chat/protocol.ts +148 -0
- package/src/src/utils/version-constant.ts +1 -1
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
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
3
|
import { streamDataStreamEvents } from "./data-stream.js";
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
normalizeAgUiMessages,
|
|
10
|
-
} from "./ag-ui-host-support.js";
|
|
4
|
+
import { AgUiRequestSchema, normalizeAgUiMessages } from "./ag-ui-host-support.js";
|
|
5
|
+
import { extractRequest } from "./ag-ui-request-shared.js";
|
|
6
|
+
import { type AgUiResumeValue, buildMergedAgUiTools } from "./ag-ui-tool-shared.js";
|
|
11
7
|
import {
|
|
12
8
|
AgentRuntime,
|
|
13
9
|
RunAlreadyExistsError,
|
|
@@ -17,10 +13,6 @@ import type { Agent } from "./types.js";
|
|
|
17
13
|
|
|
18
14
|
const AGENT_ID_PATTERN = /^[a-zA-Z0-9_-]+$/;
|
|
19
15
|
const AG_UI_DETACHED_RUN_ID_SCHEMA = z.string().min(1).max(128).regex(AGENT_ID_PATTERN);
|
|
20
|
-
type AgUiResumeValue = {
|
|
21
|
-
result: unknown;
|
|
22
|
-
isError: boolean;
|
|
23
|
-
};
|
|
24
16
|
|
|
25
17
|
type AgUiContextValue =
|
|
26
18
|
| Record<string, unknown>
|
|
@@ -28,32 +20,6 @@ type AgUiContextValue =
|
|
|
28
20
|
|
|
29
21
|
type AgUiRuntimePart = Record<string, unknown> & { type: string };
|
|
30
22
|
|
|
31
|
-
function isRequest(obj: unknown): obj is Request {
|
|
32
|
-
return (
|
|
33
|
-
typeof obj === "object" &&
|
|
34
|
-
obj !== null &&
|
|
35
|
-
"json" in obj &&
|
|
36
|
-
typeof obj.json === "function" &&
|
|
37
|
-
"url" in obj &&
|
|
38
|
-
typeof obj.url === "string" &&
|
|
39
|
-
"method" in obj &&
|
|
40
|
-
typeof obj.method === "string"
|
|
41
|
-
);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function extractRequest(requestOrCtx: unknown): Request {
|
|
45
|
-
if (isRequest(requestOrCtx)) return requestOrCtx;
|
|
46
|
-
|
|
47
|
-
if (typeof requestOrCtx === "object" && requestOrCtx !== null && "request" in requestOrCtx) {
|
|
48
|
-
const candidate = (requestOrCtx as Record<string, unknown>).request;
|
|
49
|
-
if (isRequest(candidate)) return candidate;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
throw INVALID_ARGUMENT.create({
|
|
53
|
-
detail: "Invalid handler argument: expected Request or APIContext",
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
|
|
57
23
|
function buildStreamContext(
|
|
58
24
|
request: AgUiDetachedStartRequest,
|
|
59
25
|
baseContext: Record<string, unknown>,
|
|
@@ -71,66 +37,12 @@ function buildStreamContext(
|
|
|
71
37
|
};
|
|
72
38
|
}
|
|
73
39
|
|
|
74
|
-
function createInjectedAgUiTool(
|
|
75
|
-
runId: string,
|
|
76
|
-
tool: AgUiInjectedTool,
|
|
77
|
-
sessionManager: RunResumeSessionManager<AgUiResumeValue>,
|
|
78
|
-
): Tool {
|
|
79
|
-
return {
|
|
80
|
-
id: tool.name,
|
|
81
|
-
type: "function",
|
|
82
|
-
description: tool.description ?? tool.name,
|
|
83
|
-
inputSchema: z.record(z.string(), z.unknown()),
|
|
84
|
-
inputSchemaJson: (tool.parameters ??
|
|
85
|
-
{ type: "object", properties: {}, additionalProperties: true }) as Tool["inputSchemaJson"],
|
|
86
|
-
execute: async (_input, context) => {
|
|
87
|
-
const toolCallId = typeof context?.toolCallId === "string" ? context.toolCallId : null;
|
|
88
|
-
if (!toolCallId) {
|
|
89
|
-
throw new Error(`Missing toolCallId for injected tool "${tool.name}"`);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
sessionManager.prepareForSignal(runId, toolCallId);
|
|
93
|
-
const submitted = await sessionManager.waitForSignal(runId, toolCallId);
|
|
94
|
-
if (submitted.isError) {
|
|
95
|
-
throw new Error(
|
|
96
|
-
typeof submitted.result === "string"
|
|
97
|
-
? submitted.result
|
|
98
|
-
: JSON.stringify(submitted.result),
|
|
99
|
-
);
|
|
100
|
-
}
|
|
101
|
-
return submitted.result;
|
|
102
|
-
},
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
|
|
106
40
|
function buildMergedTools(
|
|
107
41
|
agent: Agent,
|
|
108
42
|
request: AgUiDetachedStartRequest,
|
|
109
43
|
sessionManager: RunResumeSessionManager<AgUiResumeValue>,
|
|
110
44
|
): Agent["config"]["tools"] {
|
|
111
|
-
|
|
112
|
-
request.tools.map((tool) => [
|
|
113
|
-
tool.name,
|
|
114
|
-
createInjectedAgUiTool(request.runId, tool, sessionManager),
|
|
115
|
-
]),
|
|
116
|
-
);
|
|
117
|
-
|
|
118
|
-
if (!agent.config.tools) {
|
|
119
|
-
return Object.keys(injectedTools).length > 0 ? injectedTools : undefined;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
if (agent.config.tools === true) {
|
|
123
|
-
const merged: Record<string, Tool | boolean> = {};
|
|
124
|
-
for (const [toolId] of toolRegistry.getAll()) {
|
|
125
|
-
if (!agent.config.skills && SKILL_TOOL_IDS.has(toolId)) {
|
|
126
|
-
continue;
|
|
127
|
-
}
|
|
128
|
-
merged[toolId] = true;
|
|
129
|
-
}
|
|
130
|
-
return { ...merged, ...injectedTools };
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
return { ...agent.config.tools, ...injectedTools };
|
|
45
|
+
return buildMergedAgUiTools(agent, request.runId, request.tools, sessionManager);
|
|
134
46
|
}
|
|
135
47
|
|
|
136
48
|
function scheduleDetachedTask(requestOrCtx: unknown, task: Promise<void>): void {
|
|
@@ -7,9 +7,6 @@ import {
|
|
|
7
7
|
RunAlreadyExistsError,
|
|
8
8
|
type RunResumeSessionManager,
|
|
9
9
|
} from "./runtime/index.js";
|
|
10
|
-
import { INVALID_ARGUMENT } from "../errors/index.js";
|
|
11
|
-
import { SKILL_TOOL_IDS } from "../skill/types.js";
|
|
12
|
-
import { type Tool, toolRegistry } from "../tool/index.js";
|
|
13
10
|
import {
|
|
14
11
|
createStreamTransformState,
|
|
15
12
|
finalizeRunEvents,
|
|
@@ -18,11 +15,12 @@ import {
|
|
|
18
15
|
} from "../internal-agents/ag-ui-sse.js";
|
|
19
16
|
import { streamDataStreamEvents } from "./data-stream.js";
|
|
20
17
|
import {
|
|
21
|
-
type AgUiInjectedTool,
|
|
22
18
|
type AgUiRequest,
|
|
23
19
|
normalizeAgUiMessages,
|
|
24
20
|
parseAgUiRequestOrError,
|
|
25
21
|
} from "./ag-ui-host-support.js";
|
|
22
|
+
import { extractRequest } from "./ag-ui-request-shared.js";
|
|
23
|
+
import { type AgUiResumeValue, buildMergedAgUiTools } from "./ag-ui-tool-shared.js";
|
|
26
24
|
|
|
27
25
|
export {
|
|
28
26
|
type AgUiContextItem,
|
|
@@ -39,35 +37,8 @@ const AG_UI_HEADERS: Record<string, string> = {
|
|
|
39
37
|
Connection: "keep-alive",
|
|
40
38
|
};
|
|
41
39
|
|
|
42
|
-
type AgUiResumeValue = { result: unknown; isError: boolean };
|
|
43
40
|
type AgUiRuntimePart = Record<string, unknown> & { type: string };
|
|
44
41
|
|
|
45
|
-
function isRequest(obj: unknown): obj is Request {
|
|
46
|
-
return (
|
|
47
|
-
typeof obj === "object" &&
|
|
48
|
-
obj !== null &&
|
|
49
|
-
"json" in obj &&
|
|
50
|
-
typeof obj.json === "function" &&
|
|
51
|
-
"url" in obj &&
|
|
52
|
-
typeof obj.url === "string" &&
|
|
53
|
-
"method" in obj &&
|
|
54
|
-
typeof obj.method === "string"
|
|
55
|
-
);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function extractRequest(requestOrCtx: unknown): Request {
|
|
59
|
-
if (isRequest(requestOrCtx)) return requestOrCtx;
|
|
60
|
-
|
|
61
|
-
if (typeof requestOrCtx === "object" && requestOrCtx !== null && "request" in requestOrCtx) {
|
|
62
|
-
const candidate = (requestOrCtx as Record<string, unknown>).request;
|
|
63
|
-
if (isRequest(candidate)) return candidate;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
throw INVALID_ARGUMENT.create({
|
|
67
|
-
detail: "Invalid handler argument: expected Request or APIContext",
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
|
|
71
42
|
function generateRunId(): string {
|
|
72
43
|
return `run_${dntShim.crypto.randomUUID().replaceAll("-", "")}`;
|
|
73
44
|
}
|
|
@@ -240,38 +211,6 @@ async function createAgUiDirectStreamResponse(
|
|
|
240
211
|
});
|
|
241
212
|
}
|
|
242
213
|
|
|
243
|
-
function createInjectedAgUiTool(
|
|
244
|
-
runId: string,
|
|
245
|
-
tool: AgUiInjectedTool,
|
|
246
|
-
sessionManager: RunResumeSessionManager<AgUiResumeValue>,
|
|
247
|
-
): Tool {
|
|
248
|
-
return {
|
|
249
|
-
id: tool.name,
|
|
250
|
-
type: "function",
|
|
251
|
-
description: tool.description ?? tool.name,
|
|
252
|
-
inputSchema: z.record(z.string(), z.unknown()),
|
|
253
|
-
inputSchemaJson: (tool.parameters ??
|
|
254
|
-
{ type: "object", properties: {}, additionalProperties: true }) as Tool["inputSchemaJson"],
|
|
255
|
-
execute: async (_input, context) => {
|
|
256
|
-
const toolCallId = typeof context?.toolCallId === "string" ? context.toolCallId : null;
|
|
257
|
-
if (!toolCallId) {
|
|
258
|
-
throw new Error(`Missing toolCallId for injected tool "${tool.name}"`);
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
sessionManager.prepareForSignal(runId, toolCallId);
|
|
262
|
-
const submitted = await sessionManager.waitForSignal(runId, toolCallId);
|
|
263
|
-
if (submitted.isError) {
|
|
264
|
-
throw new Error(
|
|
265
|
-
typeof submitted.result === "string"
|
|
266
|
-
? submitted.result
|
|
267
|
-
: JSON.stringify(submitted.result),
|
|
268
|
-
);
|
|
269
|
-
}
|
|
270
|
-
return submitted.result;
|
|
271
|
-
},
|
|
272
|
-
};
|
|
273
|
-
}
|
|
274
|
-
|
|
275
214
|
async function createAgUiInjectedToolsStreamResponse(
|
|
276
215
|
agent: Agent,
|
|
277
216
|
request: AgUiRequest,
|
|
@@ -290,26 +229,9 @@ async function createAgUiInjectedToolsStreamResponse(
|
|
|
290
229
|
throw error;
|
|
291
230
|
}
|
|
292
231
|
|
|
293
|
-
const injectedTools = Object.fromEntries(
|
|
294
|
-
request.tools.map((tool) => [tool.name, createInjectedAgUiTool(runId, tool, sessionManager)]),
|
|
295
|
-
);
|
|
296
|
-
|
|
297
|
-
const mergedTools: Agent["config"]["tools"] = !agent.config.tools
|
|
298
|
-
? injectedTools
|
|
299
|
-
: agent.config.tools === true
|
|
300
|
-
? {
|
|
301
|
-
...Object.fromEntries(
|
|
302
|
-
[...toolRegistry.getAll()]
|
|
303
|
-
.filter(([toolId]) => agent.config.skills || !SKILL_TOOL_IDS.has(toolId))
|
|
304
|
-
.map(([toolId]) => [toolId, true]),
|
|
305
|
-
),
|
|
306
|
-
...injectedTools,
|
|
307
|
-
}
|
|
308
|
-
: { ...agent.config.tools, ...injectedTools };
|
|
309
|
-
|
|
310
232
|
const runtime = new AgentRuntime(agent.id, {
|
|
311
233
|
...agent.config,
|
|
312
|
-
tools:
|
|
234
|
+
tools: buildMergedAgUiTools(agent, runId, request.tools, sessionManager),
|
|
313
235
|
});
|
|
314
236
|
|
|
315
237
|
let upstreamBody: ReadableStream<Uint8Array>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { formatAgUiEvent } from "../internal-agents/ag-ui-sse.js";
|
|
3
3
|
import type { Message } from "./types.js";
|
|
4
|
+
import { parseAgUiJsonRequestOrError } from "./ag-ui-request-shared.js";
|
|
4
5
|
|
|
5
6
|
const AGENT_ID_PATTERN = /^[a-zA-Z0-9_-]+$/;
|
|
6
7
|
const MAX_TOOL_PARAMETERS_BYTES = 16_384;
|
|
@@ -173,34 +174,10 @@ export async function parseAgUiRequest(request: Request): Promise<AgUiRequest> {
|
|
|
173
174
|
export async function parseAgUiRequestOrError(
|
|
174
175
|
request: Request,
|
|
175
176
|
): Promise<AgUiRequest | Response> {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
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
|
-
}
|
|
177
|
+
return await parseAgUiJsonRequestOrError(
|
|
178
|
+
() => parseAgUiRequest(request),
|
|
179
|
+
"Invalid AG-UI request",
|
|
180
|
+
);
|
|
204
181
|
}
|
|
205
182
|
|
|
206
183
|
export function normalizeAgUiMessages(messages: AgUiRequest["messages"]): Message[] {
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { INVALID_ARGUMENT } from "../errors/index.js";
|
|
3
|
+
|
|
4
|
+
export function isRequest(value: unknown): value is Request {
|
|
5
|
+
return (
|
|
6
|
+
typeof value === "object" &&
|
|
7
|
+
value !== null &&
|
|
8
|
+
"json" in value &&
|
|
9
|
+
typeof value.json === "function" &&
|
|
10
|
+
"url" in value &&
|
|
11
|
+
typeof value.url === "string" &&
|
|
12
|
+
"method" in value &&
|
|
13
|
+
typeof value.method === "string"
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function extractRequest(requestOrCtx: unknown): Request {
|
|
18
|
+
if (isRequest(requestOrCtx)) return requestOrCtx;
|
|
19
|
+
|
|
20
|
+
if (typeof requestOrCtx === "object" && requestOrCtx !== null && "request" in requestOrCtx) {
|
|
21
|
+
const candidate = (requestOrCtx as Record<string, unknown>).request;
|
|
22
|
+
if (isRequest(candidate)) return candidate;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
throw INVALID_ARGUMENT.create({
|
|
26
|
+
detail: "Invalid handler argument: expected Request or APIContext",
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export async function parseAgUiJsonRequestOrError<T>(
|
|
31
|
+
parseRequest: () => Promise<T>,
|
|
32
|
+
errorLabel: string,
|
|
33
|
+
): Promise<T | Response> {
|
|
34
|
+
try {
|
|
35
|
+
return await parseRequest();
|
|
36
|
+
} catch (error) {
|
|
37
|
+
if (error instanceof z.ZodError) {
|
|
38
|
+
return Response.json(
|
|
39
|
+
{
|
|
40
|
+
error: errorLabel,
|
|
41
|
+
details: error.issues.map((issue) => ({
|
|
42
|
+
path: issue.path,
|
|
43
|
+
message: issue.message,
|
|
44
|
+
})),
|
|
45
|
+
},
|
|
46
|
+
{ status: 400 },
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (error instanceof SyntaxError || error instanceof TypeError) {
|
|
51
|
+
return Response.json(
|
|
52
|
+
{
|
|
53
|
+
error: errorLabel,
|
|
54
|
+
details: [{ path: [], message: "Malformed JSON request body" }],
|
|
55
|
+
},
|
|
56
|
+
{ status: 400 },
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
throw error;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import {
|
|
2
|
+
import { extractRequest } from "./ag-ui-request-shared.js";
|
|
3
3
|
import {
|
|
4
4
|
RunNotActiveError,
|
|
5
5
|
RunResumeSessionManager,
|
|
@@ -26,32 +26,6 @@ type ResumeValue = {
|
|
|
26
26
|
isError: boolean;
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
-
function isRequest(value: unknown): value is Request {
|
|
30
|
-
return (
|
|
31
|
-
typeof value === "object" &&
|
|
32
|
-
value !== null &&
|
|
33
|
-
"json" in value &&
|
|
34
|
-
typeof value.json === "function" &&
|
|
35
|
-
"url" in value &&
|
|
36
|
-
typeof value.url === "string" &&
|
|
37
|
-
"method" in value &&
|
|
38
|
-
typeof value.method === "string"
|
|
39
|
-
);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function extractRequest(requestOrCtx: unknown): Request {
|
|
43
|
-
if (isRequest(requestOrCtx)) return requestOrCtx;
|
|
44
|
-
|
|
45
|
-
if (typeof requestOrCtx === "object" && requestOrCtx !== null && "request" in requestOrCtx) {
|
|
46
|
-
const candidate = (requestOrCtx as Record<string, unknown>).request;
|
|
47
|
-
if (isRequest(candidate)) return candidate;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
throw INVALID_ARGUMENT.create({
|
|
51
|
-
detail: "Invalid handler argument: expected Request or APIContext",
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
|
|
55
29
|
function getRunId(pathname: string, regex: RegExp): string | null {
|
|
56
30
|
return regex.exec(pathname)?.[1] ?? null;
|
|
57
31
|
}
|
|
@@ -1,7 +1,4 @@
|
|
|
1
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
2
|
import {
|
|
6
3
|
AgentRuntime,
|
|
7
4
|
RunAlreadyExistsError,
|
|
@@ -9,10 +6,11 @@ import {
|
|
|
9
6
|
} from "./runtime/index.js";
|
|
10
7
|
import type { Agent } from "./types.js";
|
|
11
8
|
import {
|
|
12
|
-
type AgUiRuntimeInjectedTool,
|
|
13
9
|
type AgUiRuntimeRequest,
|
|
14
10
|
parseAgUiRuntimeRequestOrError,
|
|
15
11
|
} from "./runtime-ag-ui-contract.js";
|
|
12
|
+
import { extractRequest } from "./ag-ui-request-shared.js";
|
|
13
|
+
import { type AgUiResumeValue, buildMergedAgUiTools } from "./ag-ui-tool-shared.js";
|
|
16
14
|
import { normalizeAgUiRuntimeMessages } from "./ag-ui-runtime-support.js";
|
|
17
15
|
import {
|
|
18
16
|
createStreamTransformState,
|
|
@@ -28,7 +26,6 @@ const AG_UI_HEADERS: Record<string, string> = {
|
|
|
28
26
|
Connection: "keep-alive",
|
|
29
27
|
};
|
|
30
28
|
|
|
31
|
-
type AgUiResumeValue = { result: unknown; isError: boolean };
|
|
32
29
|
type AgUiRuntimePart = Record<string, unknown> & { type: string };
|
|
33
30
|
|
|
34
31
|
export interface AgUiRuntimeLifecycleContext {
|
|
@@ -64,36 +61,10 @@ async function invokeLifecycleCallbackAndWait(
|
|
|
64
61
|
}
|
|
65
62
|
}
|
|
66
63
|
|
|
67
|
-
function isRequest(obj: unknown): obj is Request {
|
|
68
|
-
return (
|
|
69
|
-
typeof obj === "object" &&
|
|
70
|
-
obj !== null &&
|
|
71
|
-
"json" in obj &&
|
|
72
|
-
typeof obj.json === "function" &&
|
|
73
|
-
"url" in obj &&
|
|
74
|
-
typeof obj.url === "string" &&
|
|
75
|
-
"method" in obj &&
|
|
76
|
-
typeof obj.method === "string"
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
64
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
81
65
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
82
66
|
}
|
|
83
67
|
|
|
84
|
-
function extractRequest(requestOrCtx: unknown): Request {
|
|
85
|
-
if (isRequest(requestOrCtx)) return requestOrCtx;
|
|
86
|
-
|
|
87
|
-
if (typeof requestOrCtx === "object" && requestOrCtx !== null && "request" in requestOrCtx) {
|
|
88
|
-
const candidate = (requestOrCtx as Record<string, unknown>).request;
|
|
89
|
-
if (isRequest(candidate)) return candidate;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
throw INVALID_ARGUMENT.create({
|
|
93
|
-
detail: "Invalid handler argument: expected Request or APIContext",
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
|
|
97
68
|
function buildStreamContext(
|
|
98
69
|
request: AgUiRuntimeRequest,
|
|
99
70
|
baseContext: Record<string, unknown>,
|
|
@@ -271,66 +242,12 @@ async function createAgUiRuntimeDirectStreamResponse(
|
|
|
271
242
|
});
|
|
272
243
|
}
|
|
273
244
|
|
|
274
|
-
function createInjectedAgUiTool(
|
|
275
|
-
runId: string,
|
|
276
|
-
tool: AgUiRuntimeInjectedTool,
|
|
277
|
-
sessionManager: RunResumeSessionManager<AgUiResumeValue>,
|
|
278
|
-
): Tool {
|
|
279
|
-
return {
|
|
280
|
-
id: tool.name,
|
|
281
|
-
type: "function",
|
|
282
|
-
description: tool.description ?? tool.name,
|
|
283
|
-
inputSchema: z.record(z.string(), z.unknown()),
|
|
284
|
-
inputSchemaJson: (tool.parameters ??
|
|
285
|
-
{ type: "object", properties: {}, additionalProperties: true }) as Tool["inputSchemaJson"],
|
|
286
|
-
execute: async (_input, context) => {
|
|
287
|
-
const toolCallId = typeof context?.toolCallId === "string" ? context.toolCallId : null;
|
|
288
|
-
if (!toolCallId) {
|
|
289
|
-
throw new Error(`Missing toolCallId for injected tool "${tool.name}"`);
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
sessionManager.prepareForSignal(runId, toolCallId);
|
|
293
|
-
const submitted = await sessionManager.waitForSignal(runId, toolCallId);
|
|
294
|
-
if (submitted.isError) {
|
|
295
|
-
throw new Error(
|
|
296
|
-
typeof submitted.result === "string"
|
|
297
|
-
? submitted.result
|
|
298
|
-
: JSON.stringify(submitted.result),
|
|
299
|
-
);
|
|
300
|
-
}
|
|
301
|
-
return submitted.result;
|
|
302
|
-
},
|
|
303
|
-
};
|
|
304
|
-
}
|
|
305
|
-
|
|
306
245
|
function buildMergedTools(
|
|
307
246
|
agent: Agent,
|
|
308
247
|
request: AgUiRuntimeRequest,
|
|
309
248
|
sessionManager: RunResumeSessionManager<AgUiResumeValue>,
|
|
310
249
|
): Agent["config"]["tools"] {
|
|
311
|
-
|
|
312
|
-
request.tools.map((tool) => [
|
|
313
|
-
tool.name,
|
|
314
|
-
createInjectedAgUiTool(request.runId, tool, sessionManager),
|
|
315
|
-
]),
|
|
316
|
-
);
|
|
317
|
-
|
|
318
|
-
if (!agent.config.tools) {
|
|
319
|
-
return Object.keys(injectedTools).length > 0 ? injectedTools : undefined;
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
if (agent.config.tools === true) {
|
|
323
|
-
const merged: Record<string, Tool | boolean> = {};
|
|
324
|
-
for (const [toolId] of toolRegistry.getAll()) {
|
|
325
|
-
if (!agent.config.skills && SKILL_TOOL_IDS.has(toolId)) {
|
|
326
|
-
continue;
|
|
327
|
-
}
|
|
328
|
-
merged[toolId] = true;
|
|
329
|
-
}
|
|
330
|
-
return { ...merged, ...injectedTools };
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
return { ...agent.config.tools, ...injectedTools };
|
|
250
|
+
return buildMergedAgUiTools(agent, request.runId, request.tools, sessionManager);
|
|
334
251
|
}
|
|
335
252
|
|
|
336
253
|
async function createAgUiRuntimeInjectedToolsStreamResponse(
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { SKILL_TOOL_IDS } from "../skill/types.js";
|
|
3
|
+
import { toolRegistry } from "../tool/registry.js";
|
|
4
|
+
import type { Tool } from "../tool/types.js";
|
|
5
|
+
import type { RunResumeSessionManager } from "./runtime/index.js";
|
|
6
|
+
import type { Agent } from "./types.js";
|
|
7
|
+
|
|
8
|
+
export type AgUiResumeValue = { result: unknown; isError: boolean };
|
|
9
|
+
|
|
10
|
+
export interface AgUiInjectedToolLike {
|
|
11
|
+
name: string;
|
|
12
|
+
description?: string;
|
|
13
|
+
parameters?: unknown;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function createInjectedAgUiTool(
|
|
17
|
+
runId: string,
|
|
18
|
+
tool: AgUiInjectedToolLike,
|
|
19
|
+
sessionManager: RunResumeSessionManager<AgUiResumeValue>,
|
|
20
|
+
): Tool {
|
|
21
|
+
return {
|
|
22
|
+
id: tool.name,
|
|
23
|
+
type: "function",
|
|
24
|
+
description: tool.description ?? tool.name,
|
|
25
|
+
inputSchema: z.record(z.string(), z.unknown()),
|
|
26
|
+
inputSchemaJson: (tool.parameters ??
|
|
27
|
+
{ type: "object", properties: {}, additionalProperties: true }) as Tool["inputSchemaJson"],
|
|
28
|
+
execute: async (_input, context) => {
|
|
29
|
+
const toolCallId = typeof context?.toolCallId === "string" ? context.toolCallId : null;
|
|
30
|
+
if (!toolCallId) {
|
|
31
|
+
throw new Error(`Missing toolCallId for injected tool "${tool.name}"`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
sessionManager.prepareForSignal(runId, toolCallId);
|
|
35
|
+
const submitted = await sessionManager.waitForSignal(runId, toolCallId);
|
|
36
|
+
if (submitted.isError) {
|
|
37
|
+
throw new Error(
|
|
38
|
+
typeof submitted.result === "string"
|
|
39
|
+
? submitted.result
|
|
40
|
+
: JSON.stringify(submitted.result),
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
return submitted.result;
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function buildMergedAgUiTools(
|
|
49
|
+
agent: Agent,
|
|
50
|
+
runId: string,
|
|
51
|
+
tools: AgUiInjectedToolLike[],
|
|
52
|
+
sessionManager: RunResumeSessionManager<AgUiResumeValue>,
|
|
53
|
+
): Agent["config"]["tools"] {
|
|
54
|
+
const injectedTools = Object.fromEntries(
|
|
55
|
+
tools.map((tool) => [
|
|
56
|
+
tool.name,
|
|
57
|
+
createInjectedAgUiTool(runId, tool, sessionManager),
|
|
58
|
+
]),
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
if (!agent.config.tools) {
|
|
62
|
+
return Object.keys(injectedTools).length > 0 ? injectedTools : undefined;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (agent.config.tools === true) {
|
|
66
|
+
const merged: Record<string, Tool | boolean> = {};
|
|
67
|
+
for (const [toolId] of toolRegistry.getAll()) {
|
|
68
|
+
if (!agent.config.skills && SKILL_TOOL_IDS.has(toolId)) {
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
merged[toolId] = true;
|
|
72
|
+
}
|
|
73
|
+
return { ...merged, ...injectedTools };
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return { ...agent.config.tools, ...injectedTools };
|
|
77
|
+
}
|
package/src/src/agent/index.ts
CHANGED
|
@@ -379,6 +379,21 @@ export {
|
|
|
379
379
|
streamDataStreamEvents,
|
|
380
380
|
stripLeadingEmptyObjectPlaceholder,
|
|
381
381
|
} from "./data-stream.js";
|
|
382
|
+
export type {
|
|
383
|
+
ChatMessageMetadata,
|
|
384
|
+
ChatMessageMetadataUsage,
|
|
385
|
+
ChatUiMessageChunk,
|
|
386
|
+
ChildRunAudit,
|
|
387
|
+
ChildRunAuditToolCall,
|
|
388
|
+
ChildRunAuditToolResult,
|
|
389
|
+
} from "../chat/protocol.js";
|
|
390
|
+
export {
|
|
391
|
+
buildChatStreamChunkMessageMetadata,
|
|
392
|
+
type BuildChatStreamChunkMessageMetadataInput,
|
|
393
|
+
extractChatMessageMetadata,
|
|
394
|
+
normalizeChatMessageMetadata,
|
|
395
|
+
normalizeChatUiMessageChunk,
|
|
396
|
+
} from "../chat/chat-ui-message-helpers.js";
|
|
382
397
|
export {
|
|
383
398
|
expandAllowedRemoteToolNames,
|
|
384
399
|
getProviderNativeToolNames,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import { parseAgUiJsonRequestOrError } from "./ag-ui-request-shared.js";
|
|
2
3
|
|
|
3
4
|
const AGENT_ID_PATTERN = /^[a-zA-Z0-9_-]+$/;
|
|
4
5
|
const MAX_TOOL_PARAMETERS_BYTES = 16_384;
|
|
@@ -172,32 +173,8 @@ export async function parseAgUiRuntimeRequest(request: Request): Promise<AgUiRun
|
|
|
172
173
|
export async function parseAgUiRuntimeRequestOrError(
|
|
173
174
|
request: Request,
|
|
174
175
|
): Promise<AgUiRuntimeRequest | Response> {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
return Response.json(
|
|
180
|
-
{
|
|
181
|
-
error: "Invalid AG-UI runtime request",
|
|
182
|
-
details: error.issues.map((issue) => ({
|
|
183
|
-
path: issue.path,
|
|
184
|
-
message: issue.message,
|
|
185
|
-
})),
|
|
186
|
-
},
|
|
187
|
-
{ status: 400 },
|
|
188
|
-
);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
if (error instanceof SyntaxError || error instanceof TypeError) {
|
|
192
|
-
return Response.json(
|
|
193
|
-
{
|
|
194
|
-
error: "Invalid AG-UI runtime request",
|
|
195
|
-
details: [{ path: [], message: "Malformed JSON request body" }],
|
|
196
|
-
},
|
|
197
|
-
{ status: 400 },
|
|
198
|
-
);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
throw error;
|
|
202
|
-
}
|
|
176
|
+
return await parseAgUiJsonRequestOrError(
|
|
177
|
+
() => parseAgUiRuntimeRequest(request),
|
|
178
|
+
"Invalid AG-UI runtime request",
|
|
179
|
+
);
|
|
203
180
|
}
|