History

Add discover tool and external MCP/OpenAPI source loading

Rhys Sullivan committed 9 months ago

Commit 90471fb1 parent adf27f19 files · +760 −2Browse files

Unified · Split

9 files
  1. executor/README.md +30 −0
  2. executor/apps/server/package.json +2 −0
  3. executor/apps/server/src/index.ts +18 −1
  4. executor/apps/server/src/service.ts +3 −0
  5. executor/apps/server/src/tool-discovery.ts +101 −0
  6. executor/apps/server/src/tool-sources.ts +390 −0
  7. executor/apps/server/src/types.ts +10 −0
  8. executor/bun.lock +203 −1
  9. executor/packages/contracts/src/index.ts +3 −0
executor/README.md+30−0
@@ -24,10 +24,40 @@ Prototype executor control plane for running AI-generated code with tool-call ap · 23 unmodified lines
24- Current default uses an in-process adapter; an HTTP adapter is also included for process/network boundaries.24- Current default uses an in-process adapter; an HTTP adapter is also included for process/network boundaries.
25- Tools can be marked `auto` or `required` approval.25- Tools can be marked `auto` or `required` approval.
26- Required tools create approval records per function call (`toolPath` + `input`).26- Required tools create approval records per function call (`toolPath` + `input`).
27- A built-in `tools.discover({ query, depth?, limit? })` helper is available so agents can search available tools at runtime.
27- Task execution pauses on required tool calls until that specific call is approved or denied.28- Task execution pauses on required tool calls until that specific call is approved or denied.
28- Runtime targets are swappable by ID (`runtimeId`) so sandbox backends can change later.29- Runtime targets are swappable by ID (`runtimeId`) so sandbox backends can change later.
29- SQLite is used as a prototype event/history store.30- SQLite is used as a prototype event/history store.
30 31
32## External Tool Sources (MCP + OpenAPI)
33
34You can load callable tools automatically from MCP servers and OpenAPI specs via env config:
35
36`EXECUTOR_TOOL_SOURCES` accepts a JSON array of source definitions.
37
38Example:
39
40```json
41[
42 {
43 "type": "mcp",
44 "name": "answeroverflow",
45 "url": "https://www.answeroverflow.com/mcp",
46 "defaultApproval": "auto"
47 },
48 {
49 "type": "openapi",
50 "name": "billing",
51 "spec": "https://example.com/openapi.json",
52 "baseUrl": "https://api.example.com",
53 "defaultReadApproval": "auto",
54 "defaultWriteApproval": "required"
55 }
56]
57```
58
59OpenAPI tools are generated as namespaced callables (`tools.<name>.<tag>.<operation>`), and MCP tools are generated as (`tools.<name>.<tool>`).
60
31## Vercel Sandbox Runtime61## Vercel Sandbox Runtime
32 62
33This repo includes a `vercel-sandbox` runtime that runs generated code in Vercel Sandbox VMs while keeping the same `await tools.*(...)` flow.63This repo includes a `vercel-sandbox` runtime that runs generated code in Vercel Sandbox VMs while keeping the same `await tools.*(...)` flow.
executor/apps/server/package.json+2−0
@@ -3,6 +3,8 @@ · 2 unmodified lines
3 "private": true,3 "private": true,
4 "type": "module",4 "type": "module",
5 "dependencies": {5 "dependencies": {
6 "@apidevtools/swagger-parser": "^12.1.0",
7 "@modelcontextprotocol/sdk": "^1.26.0",
6 "@vercel/sandbox": "latest"8 "@vercel/sandbox": "latest"
7 },9 },
8 "scripts": {10 "scripts": {
executor/apps/server/src/index.ts+18−1
@@ -5,6 +5,8 @@ import { LocalBunRuntime } from "./runtimes/local-bun-runtime"; · 4 unmodified lines
5import { VercelSandboxRuntime } from "./runtimes/vercel-sandbox-runtime";5import { VercelSandboxRuntime } from "./runtimes/vercel-sandbox-runtime";
6import { ExecutorService, getTaskTerminalState } from "./service";6import { ExecutorService, getTaskTerminalState } from "./service";
7import { ensureTailscaleFunnel } from "./tailscale-funnel";7import { ensureTailscaleFunnel } from "./tailscale-funnel";
8import { createDiscoverTool } from "./tool-discovery";
9import { loadExternalTools, parseToolSourcesFromEnv } from "./tool-sources";
8import { DEFAULT_TOOLS } from "./tools";10import { DEFAULT_TOOLS } from "./tools";
9import type {11import type {
10 ApprovalStatus,12 ApprovalStatus,
@@ -35,6 +37,20 @@ if (!explicitInternalBaseUrl && autoFunnelEnabled) { · 24 unmodified lines
35 }37 }
36}38}
37 39
40const toolSourceConfigs = (() => {
41 try {
42 return parseToolSourcesFromEnv(Bun.env.EXECUTOR_TOOL_SOURCES);
43 } catch (error) {
44 const message = error instanceof Error ? error.message : String(error);
45 console.warn(`[executor] invalid EXECUTOR_TOOL_SOURCES: ${message}`);
46 return [];
47 }
48})();
49
50const externalTools = await loadExternalTools(toolSourceConfigs);
51const baseTools = [...DEFAULT_TOOLS, ...externalTools];
52const tools = [...baseTools, createDiscoverTool(baseTools)];
53
38const service = new ExecutorService(new ExecutorDatabase(), new TaskEventHub(), [54const service = new ExecutorService(new ExecutorDatabase(), new TaskEventHub(), [
39 new LocalBunRuntime(),55 new LocalBunRuntime(),
40 new VercelSandboxRuntime({56 new VercelSandboxRuntime({
@@ -42,7 +58,7 @@ const service = new ExecutorService(new ExecutorDatabase(), new TaskEventHub(), · 1 unmodified line
42 internalToken,58 internalToken,
43 runtime: Bun.env.EXECUTOR_VERCEL_SANDBOX_RUNTIME as "node24" | "node22" | undefined,59 runtime: Bun.env.EXECUTOR_VERCEL_SANDBOX_RUNTIME as "node24" | "node22" | undefined,
44 }),60 }),
45], DEFAULT_TOOLS);61], tools);
46 62
47const jsonHeaders = {63const jsonHeaders = {
48 "content-type": "application/json; charset=utf-8",64 "content-type": "application/json; charset=utf-8",
@@ -313,3 +329,4 @@ const server = Bun.serve({ · 264 unmodified lines
313console.log(`executor server listening on http://localhost:${server.port}`);329console.log(`executor server listening on http://localhost:${server.port}`);
314console.log(`[executor] internal callback base: ${internalBaseUrl} (${internalBaseSource})`);330console.log(`[executor] internal callback base: ${internalBaseUrl} (${internalBaseSource})`);
315console.log(`[executor] internal callback auth token enabled: yes`);331console.log(`[executor] internal callback auth token enabled: yes`);
332console.log(`[executor] tools loaded: ${tools.length} (${externalTools.length} external)`);
executor/apps/server/src/service.ts+3−0
@@ -94,6 +94,9 @@ export class ExecutorService { · 93 unmodified lines
94 path: tool.path,94 path: tool.path,
95 description: tool.description,95 description: tool.description,
96 approval: tool.approval,96 approval: tool.approval,
97 source: tool.source,
98 argsType: tool.metadata?.argsType,
99 returnsType: tool.metadata?.returnsType,
97 }));100 }));
98 }101 }
99 102
executor/apps/server/src/tool-discovery.ts+101−0
@@ -0,0 +1,101 @@
1import type { ToolDefinition } from "./types";
2
3interface DiscoverIndexEntry {
4 path: string;
5 description: string;
6 approval: ToolDefinition["approval"];
7 source: string;
8 argsType: string;
9 returnsType: string;
10 searchText: string;
11}
12
13function normalizeType(type?: string): string {
14 return type && type.trim().length > 0 ? type : "unknown";
15}
16
17function buildIndex(tools: ToolDefinition[]): DiscoverIndexEntry[] {
18 return tools
19 .filter((tool) => tool.path !== "discover")
20 .map((tool) => ({
21 path: tool.path,
22 description: tool.description,
23 approval: tool.approval,
24 source: tool.source ?? "local",
25 argsType: normalizeType(tool.metadata?.argsType),
26 returnsType: normalizeType(tool.metadata?.returnsType),
27 searchText: `${tool.path} ${tool.description} ${tool.source ?? ""}`.toLowerCase(),
28 }));
29}
30
31function scoreEntry(entry: DiscoverIndexEntry, terms: string[]): number {
32 let score = 0;
33 let matched = 0;
34
35 for (const term of terms) {
36 const inPath = entry.path.toLowerCase().includes(term);
37 const inText = entry.searchText.includes(term);
38 if (!inPath && !inText) continue;
39 matched += 1;
40 score += 1;
41 if (inPath) score += 2;
42 }
43
44 if (terms.length > 0 && matched < Math.max(1, Math.ceil(terms.length / 2))) {
45 return -1;
46 }
47
48 return score + matched * 2;
49}
50
51function formatSignature(entry: DiscoverIndexEntry, depth: number): string {
52 if (depth <= 0) {
53 return `(input: ${entry.argsType}): Promise<...>`;
54 }
55 if (depth === 1) {
56 return `(input: ${entry.argsType}): Promise<${entry.returnsType}>`;
57 }
58 return `(input: ${entry.argsType}): Promise<${entry.returnsType}> [source=${entry.source}]`;
59}
60
61export function createDiscoverTool(tools: ToolDefinition[]): ToolDefinition {
62 const index = buildIndex(tools);
63
64 return {
65 path: "discover",
66 source: "system",
67 approval: "auto",
68 description:
69 "Search available tools by keyword. Returns tool path, source, approval mode, and signature hints so code can call tools accurately.",
70 metadata: {
71 argsType: "{ query: string; depth?: number; limit?: number }",
72 returnsType:
73 "{ results: Array<{ path: string; source: string; approval: 'auto' | 'required'; description: string; signature: string }>; total: number }",
74 },
75 run: async (input: unknown) => {
76 const payload = input && typeof input === "object" ? (input as Record<string, unknown>) : {};
77 const query = String(payload.query ?? "").trim().toLowerCase();
78 const depth = Math.max(0, Math.min(2, Number(payload.depth ?? 1)));
79 const limit = Math.max(1, Math.min(50, Number(payload.limit ?? 8)));
80 const terms = query.length > 0 ? query.split(/\s+/).filter(Boolean) : [];
81
82 const ranked = index
83 .map((entry) => ({ entry, score: scoreEntry(entry, terms) }))
84 .filter((item) => item.score > 0 || terms.length === 0)
85 .sort((a, b) => b.score - a.score)
86 .slice(0, limit)
87 .map(({ entry }) => ({
88 path: entry.path,
89 source: entry.source,
90 approval: entry.approval,
91 description: entry.description,
92 signature: formatSignature(entry, depth),
93 }));
94
95 return {
96 results: ranked,
97 total: ranked.length,
98 };
99 },
100 };
101}
executor/apps/server/src/tool-sources.ts+390−0
@@ -0,0 +1,390 @@
1import SwaggerParser from "@apidevtools/swagger-parser";
2import { Client } from "@modelcontextprotocol/sdk/client/index.js";
3import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
4import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
5import type { ToolApprovalMode, ToolDefinition } from "./types";
6
7type JsonSchema = Record<string, unknown>;
8
9export interface McpToolSourceConfig {
10 type: "mcp";
11 name: string;
12 url: string;
13 transport?: "sse" | "streamable-http";
14 defaultApproval?: ToolApprovalMode;
15 overrides?: Record<string, { approval?: ToolApprovalMode }>;
16}
17
18export type OpenApiAuth =
19 | { type: "basic"; username: string; password: string }
20 | { type: "bearer"; token: string }
21 | { type: "apiKey"; header: string; value: string };
22
23export interface OpenApiToolSourceConfig {
24 type: "openapi";
25 name: string;
26 spec: string | Record<string, unknown>;
27 baseUrl?: string;
28 auth?: OpenApiAuth;
29 defaultReadApproval?: ToolApprovalMode;
30 defaultWriteApproval?: ToolApprovalMode;
31 overrides?: Record<string, { approval?: ToolApprovalMode }>;
32}
33
34export type ExternalToolSourceConfig = McpToolSourceConfig | OpenApiToolSourceConfig;
35
36function toObject(value: unknown): Record<string, unknown> {
37 return value && typeof value === "object" && !Array.isArray(value)
38 ? (value as Record<string, unknown>)
39 : {};
40}
41
42function sanitizeSegment(value: string): string {
43 const cleaned = value
44 .toLowerCase()
45 .replace(/[^a-z0-9_]/g, "_")
46 .replace(/_+/g, "_")
47 .replace(/^_|_$/g, "");
48 return cleaned.length > 0 ? cleaned : "default";
49}
50
51function jsonSchemaTypeHint(schema: unknown, depth = 0): string {
52 if (!schema || typeof schema !== "object") return "unknown";
53 if (depth > 4) return "unknown";
54
55 const shape = schema as JsonSchema;
56 const enumValues = Array.isArray(shape.enum) ? shape.enum : undefined;
57 if (enumValues && enumValues.length > 0) {
58 return enumValues.map((value) => JSON.stringify(value)).join(" | ");
59 }
60
61 const oneOf = Array.isArray(shape.oneOf) ? shape.oneOf : undefined;
62 if (oneOf && oneOf.length > 0) {
63 return oneOf.map((entry) => jsonSchemaTypeHint(entry, depth + 1)).join(" | ");
64 }
65
66 const anyOf = Array.isArray(shape.anyOf) ? shape.anyOf : undefined;
67 if (anyOf && anyOf.length > 0) {
68 return anyOf.map((entry) => jsonSchemaTypeHint(entry, depth + 1)).join(" | ");
69 }
70
71 const type = typeof shape.type === "string" ? shape.type : undefined;
72 if (type === "string" || type === "number" || type === "boolean" || type === "null") {
73 return type;
74 }
75
76 if (type === "array") {
77 return `${jsonSchemaTypeHint(shape.items, depth + 1)}[]`;
78 }
79
80 const props = toObject(shape.properties);
81 const requiredRaw = Array.isArray(shape.required) ? shape.required : [];
82 const required = new Set(requiredRaw.filter((item): item is string => typeof item === "string"));
83 const propEntries = Object.entries(props);
84 if (type === "object" || propEntries.length > 0) {
85 if (propEntries.length === 0) {
86 return "Record<string, unknown>";
87 }
88 const inner = propEntries
89 .slice(0, 12)
90 .map(([key, value]) => `${key}${required.has(key) ? "" : "?"}: ${jsonSchemaTypeHint(value, depth + 1)}`)
91 .join("; ");
92 return `{ ${inner} }`;
93 }
94
95 return "unknown";
96}
97
98async function connectMcp(
99 url: string,
100 preferredTransport?: "sse" | "streamable-http",
101): Promise<{ client: Client; close: () => Promise<void> }> {
102 const endpoint = new URL(url);
103 const client = new Client(
104 { name: "executor-tool-loader", version: "0.1.0" },
105 { capabilities: {} },
106 );
107
108 if (preferredTransport === "sse") {
109 await client.connect(new SSEClientTransport(endpoint));
110 return { client, close: () => client.close() };
111 }
112
113 if (preferredTransport === "streamable-http") {
114 await client.connect(new StreamableHTTPClientTransport(endpoint) as Parameters<Client["connect"]>[0]);
115 return { client, close: () => client.close() };
116 }
117
118 try {
119 await client.connect(new StreamableHTTPClientTransport(endpoint) as Parameters<Client["connect"]>[0]);
120 return { client, close: () => client.close() };
121 } catch {
122 await client.connect(new SSEClientTransport(endpoint));
123 return { client, close: () => client.close() };
124 }
125}
126
127async function loadMcpTools(config: McpToolSourceConfig): Promise<ToolDefinition[]> {
128 let connection = await connectMcp(config.url, config.transport);
129
130 async function callToolWithReconnect(name: string, input: Record<string, unknown>): Promise<unknown> {
131 try {
132 return await connection.client.callTool({ name, arguments: input });
133 } catch (error) {
134 const message = error instanceof Error ? error.message : String(error);
135 if (!/(socket|closed|ECONNRESET|fetch failed)/i.test(message)) {
136 throw error;
137 }
138
139 try {
140 await connection.close();
141 } catch {
142 // ignore
143 }
144
145 connection = await connectMcp(config.url, config.transport);
146 return await connection.client.callTool({ name, arguments: input });
147 }
148 }
149
150 const listed = await connection.client.listTools();
151 const tools = Array.isArray((listed as { tools?: unknown }).tools)
152 ? ((listed as { tools: Array<Record<string, unknown>> }).tools)
153 : [];
154
155 return tools.map((tool) => {
156 const toolName = String(tool.name ?? "tool");
157 const inputSchema = toObject(tool.inputSchema);
158 return {
159 path: `${sanitizeSegment(config.name)}.${sanitizeSegment(toolName)}`,
160 source: `mcp:${config.name}`,
161 approval: config.overrides?.[toolName]?.approval ?? config.defaultApproval ?? "auto",
162 description: String(tool.description ?? `MCP tool ${toolName}`),
163 metadata: {
164 argsType: jsonSchemaTypeHint(inputSchema),
165 returnsType: "unknown",
166 },
167 run: async (input: unknown) => {
168 const payload = toObject(input);
169 const result = await callToolWithReconnect(toolName, payload);
170 if (!result || typeof result !== "object") return result;
171
172 const content = (result as { content?: unknown }).content;
173 if (!Array.isArray(content)) {
174 return result;
175 }
176
177 const texts = content
178 .map((item) => (item && typeof item === "object" ? (item as { text?: unknown }).text : undefined))
179 .filter((item): item is string => typeof item === "string");
180
181 if (texts.length === 0) return content;
182 if (texts.length === 1) return texts[0];
183 return texts;
184 },
185 } satisfies ToolDefinition;
186 });
187}
188
189function buildAuthHeaders(auth?: OpenApiAuth): Record<string, string> {
190 if (!auth) return {};
191 if (auth.type === "basic") {
192 const encoded = Buffer.from(`${auth.username}:${auth.password}`, "utf8").toString("base64");
193 return { authorization: `Basic ${encoded}` };
194 }
195 if (auth.type === "bearer") {
196 return { authorization: `Bearer ${auth.token}` };
197 }
198 return { [auth.header]: auth.value };
199}
200
201function buildOpenApiUrl(
202 baseUrl: string,
203 pathTemplate: string,
204 parameters: Array<{ name: string; in: string }>,
205 input: Record<string, unknown>,
206): { url: string; bodyInput: Record<string, unknown> } {
207 let resolvedPath = pathTemplate;
208 const bodyInput = { ...input };
209 const searchParams = new URLSearchParams();
210
211 for (const parameter of parameters) {
212 const value = input[parameter.name];
213 if (value === undefined) continue;
214
215 if (parameter.in === "path") {
216 resolvedPath = resolvedPath.replace(`{${parameter.name}}`, encodeURIComponent(String(value)));
217 delete bodyInput[parameter.name];
218 continue;
219 }
220
221 if (parameter.in === "query") {
222 searchParams.set(parameter.name, String(value));
223 delete bodyInput[parameter.name];
224 }
225 }
226
227 const url = new URL(`${baseUrl.replace(/\/$/, "")}${resolvedPath}`);
228 for (const [key, value] of searchParams.entries()) {
229 url.searchParams.set(key, value);
230 }
231
232 return {
233 url: url.toString(),
234 bodyInput,
235 };
236}
237
238async function loadOpenApiTools(config: OpenApiToolSourceConfig): Promise<ToolDefinition[]> {
239 const api = (await (SwaggerParser as unknown as {
240 dereference(spec: unknown): Promise<unknown>;
241 }).dereference(config.spec)) as Record<string, unknown>;
242 const servers = Array.isArray(api.servers) ? (api.servers as Array<{ url?: unknown }>) : [];
243 const baseUrl = config.baseUrl ?? String(servers[0]?.url ?? "");
244 if (!baseUrl) {
245 throw new Error(`OpenAPI source ${config.name} has no base URL (set baseUrl)`);
246 }
247
248 const authHeaders = buildAuthHeaders(config.auth);
249 const paths = toObject(api.paths);
250 const tools: ToolDefinition[] = [];
251
252 const methods = ["get", "post", "put", "delete", "patch", "head", "options"] as const;
253 const readMethods = new Set(["get", "head", "options"]);
254
255 for (const [pathTemplate, pathValue] of Object.entries(paths)) {
256 const pathObject = toObject(pathValue);
257 const sharedParameters = Array.isArray(pathObject.parameters)
258 ? (pathObject.parameters as Array<Record<string, unknown>>)
259 : [];
260
261 for (const method of methods) {
262 const operation = toObject(pathObject[method]);
263 if (Object.keys(operation).length === 0) continue;
264
265 const tags = Array.isArray(operation.tags) ? (operation.tags as unknown[]) : [];
266 const tag = sanitizeSegment(String(tags[0] ?? "default"));
267 const operationIdRaw = String(operation.operationId ?? `${method}_${pathTemplate}`);
268 const operationId = sanitizeSegment(operationIdRaw);
269 const parameters = [
270 ...sharedParameters,
271 ...(Array.isArray(operation.parameters)
272 ? (operation.parameters as Array<Record<string, unknown>>)
273 : []),
274 ].map((entry) => ({
275 name: String(entry.name ?? ""),
276 in: String(entry.in ?? "query"),
277 required: Boolean(entry.required),
278 schema: toObject(entry.schema),
279 }));
280
281 const requestBody = toObject(operation.requestBody);
282 const requestBodyContent = toObject(requestBody.content);
283 const requestBodySchema = toObject(
284 toObject(requestBodyContent["application/json"])["schema"] ??
285 toObject(requestBodyContent["*/*"])["schema"],
286 );
287
288 const responses = toObject(operation.responses);
289 let responseSchema: Record<string, unknown> = {};
290 for (const [status, responseValue] of Object.entries(responses)) {
291 if (!status.startsWith("2")) continue;
292 const responseContent = toObject(toObject(responseValue).content);
293 responseSchema = toObject(
294 toObject(responseContent["application/json"])["schema"] ??
295 toObject(responseContent["*/*"])["schema"],
296 );
297 if (Object.keys(responseSchema).length > 0) break;
298 }
299
300 const combinedSchema: JsonSchema = {
301 type: "object",
302 properties: {
303 ...Object.fromEntries(parameters.map((param) => [param.name, param.schema])),
304 ...toObject(requestBodySchema.properties),
305 },
306 required: [
307 ...parameters.filter((param) => param.required).map((param) => param.name),
308 ...((Array.isArray(requestBodySchema.required)
309 ? requestBodySchema.required.filter((item): item is string => typeof item === "string")
310 : []) as string[]),
311 ],
312 };
313
314 const approval = config.overrides?.[operationIdRaw]?.approval
315 ?? (readMethods.has(method)
316 ? config.defaultReadApproval ?? "auto"
317 : config.defaultWriteApproval ?? "required");
318
319 tools.push({
320 path: `${sanitizeSegment(config.name)}.${tag}.${operationId}`,
321 source: `openapi:${config.name}`,
322 approval,
323 description: String(operation.summary ?? operation.description ?? `${method.toUpperCase()} ${pathTemplate}`),
324 metadata: {
325 argsType: jsonSchemaTypeHint(combinedSchema),
326 returnsType: jsonSchemaTypeHint(responseSchema),
327 },
328 run: async (input: unknown) => {
329 const payload = toObject(input);
330 const { url, bodyInput } = buildOpenApiUrl(baseUrl, pathTemplate, parameters, payload);
331 const hasBody = !readMethods.has(method) && Object.keys(bodyInput).length > 0;
332
333 const response = await fetch(url, {
334 method: method.toUpperCase(),
335 headers: {
336 ...authHeaders,
337 ...(hasBody ? { "content-type": "application/json" } : {}),
338 },
339 body: hasBody ? JSON.stringify(bodyInput) : undefined,
340 });
341
342 if (!response.ok) {
343 const text = await response.text().catch(() => "");
344 throw new Error(`HTTP ${response.status} ${response.statusText}: ${text.slice(0, 500)}`);
345 }
346
347 const contentType = response.headers.get("content-type") ?? "";
348 if (contentType.includes("json")) {
349 return await response.json();
350 }
351 return await response.text();
352 },
353 });
354 }
355 }
356
357 return tools;
358}
359
360export function parseToolSourcesFromEnv(raw: string | undefined): ExternalToolSourceConfig[] {
361 if (!raw || raw.trim().length === 0) {
362 return [];
363 }
364
365 const parsed = JSON.parse(raw) as unknown;
366 if (!Array.isArray(parsed)) {
367 throw new Error("EXECUTOR_TOOL_SOURCES must be a JSON array");
368 }
369
370 return parsed as ExternalToolSourceConfig[];
371}
372
373export async function loadExternalTools(sources: ExternalToolSourceConfig[]): Promise<ToolDefinition[]> {
374 const loaded: ToolDefinition[] = [];
375
376 for (const source of sources) {
377 try {
378 if (source.type === "mcp") {
379 loaded.push(...(await loadMcpTools(source)));
380 } else if (source.type === "openapi") {
381 loaded.push(...(await loadOpenApiTools(source)));
382 }
383 } catch (error) {
384 const message = error instanceof Error ? error.message : String(error);
385 console.warn(`[executor] failed to load tool source ${source.type}:${source.name}: ${message}`);
386 }
387 }
388
389 return loaded;
390}
executor/apps/server/src/types.ts+10−0
@@ -109,10 +109,17 @@ export interface SandboxRuntime { · 108 unmodified lines
109 109
110export type ToolApprovalMode = "auto" | "required";110export type ToolApprovalMode = "auto" | "required";
111 111
112export interface ToolTypeMetadata {
113 argsType?: string;
114 returnsType?: string;
115}
116
112export interface ToolDefinition {117export interface ToolDefinition {
113 path: string;118 path: string;
114 description: string;119 description: string;
115 approval: ToolApprovalMode;120 approval: ToolApprovalMode;
121 source?: string;
122 metadata?: ToolTypeMetadata;
116 run(input: unknown): Promise<unknown>;123 run(input: unknown): Promise<unknown>;
117}124}
118 125
@@ -120,4 +127,7 @@ export interface ToolDescriptor { · 1 unmodified line
120 path: string;127 path: string;
121 description: string;128 description: string;
122 approval: ToolApprovalMode;129 approval: ToolApprovalMode;
130 source?: string;
131 argsType?: string;
132 returnsType?: string;
123}133}
executor/bun.lock+203−1
@@ -12,6 +12,8 @@ · 11 unmodified lines
12 "apps/server": {12 "apps/server": {
13 "name": "@executor/server",13 "name": "@executor/server",
14 "dependencies": {14 "dependencies": {
15 "@apidevtools/swagger-parser": "^12.1.0",
16 "@modelcontextprotocol/sdk": "^1.26.0",
15 "@vercel/sandbox": "latest",17 "@vercel/sandbox": "latest",
16 },18 },
17 "devDependencies": {19 "devDependencies": {
@@ -33,6 +35,14 @@ · 15 unmodified lines
33 },35 },
34 },36 },
35 "packages": {37 "packages": {
38 "@apidevtools/json-schema-ref-parser": ["@apidevtools/json-schema-ref-parser@14.0.1", "", { "dependencies": { "@types/json-schema": "^7.0.15", "js-yaml": "^4.1.0" } }, "sha512-Oc96zvmxx1fqoSEdUmfmvvb59/KDOnUoJ7s2t7bISyAn0XEz57LCCw8k2Y4Pf3mwKaZLMciESALORLgfe2frCw=="],
39
40 "@apidevtools/openapi-schemas": ["@apidevtools/openapi-schemas@2.1.0", "", {}, "sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ=="],
41
42 "@apidevtools/swagger-methods": ["@apidevtools/swagger-methods@3.0.2", "", {}, "sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg=="],
43
44 "@apidevtools/swagger-parser": ["@apidevtools/swagger-parser@12.1.0", "", { "dependencies": { "@apidevtools/json-schema-ref-parser": "14.0.1", "@apidevtools/openapi-schemas": "^2.1.0", "@apidevtools/swagger-methods": "^3.0.2", "ajv": "^8.17.1", "ajv-draft-04": "^1.0.0", "call-me-maybe": "^1.0.2" }, "peerDependencies": { "openapi-types": ">=7" } }, "sha512-e5mJoswsnAX0jG+J09xHFYQXb/bUc5S3pLpMxUuRUA2H8T2kni3yEoyz2R3Dltw5f4A6j6rPNMpWTK+iVDFlng=="],
45
36 "@executor/client": ["@executor/client@workspace:packages/client"],46 "@executor/client": ["@executor/client@workspace:packages/client"],
37 47
38 "@executor/contracts": ["@executor/contracts@workspace:packages/contracts"],48 "@executor/contracts": ["@executor/contracts@workspace:packages/contracts"],
@@ -41,52 +51,244 @@ · 2 unmodified lines
41 51
42 "@executor/web": ["@executor/web@workspace:apps/web"],52 "@executor/web": ["@executor/web@workspace:apps/web"],
43 53
54 "@hono/node-server": ["@hono/node-server@1.19.9", "", { "peerDependencies": { "hono": "^4" } }, "sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw=="],
55
56 "@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.26.0", "", { "dependencies": { "@hono/node-server": "^1.19.9", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", "express": "^5.2.1", "express-rate-limit": "^8.2.1", "hono": "^4.11.4", "jose": "^6.1.3", "json-schema-typed": "^8.0.2", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.25 || ^4.0", "zod-to-json-schema": "^3.25.1" }, "peerDependencies": { "@cfworker/json-schema": "^4.1.1" }, "optionalPeers": ["@cfworker/json-schema"] }, "sha512-Y5RmPncpiDtTXDbLKswIJzTqu2hyBKxTNsgKqKclDbhIgg1wgtf1fRuvxgTnRfcnxtvvgbIEcqUOzZrJ6iSReg=="],
57
44 "@types/bun": ["@types/bun@1.3.8", "", { "dependencies": { "bun-types": "1.3.8" } }, "sha512-3LvWJ2q5GerAXYxO2mffLTqOzEu5qnhEAlh48Vnu8WQfnmSwbgagjGZV6BoHKJztENYEDn6QmVd949W4uESRJA=="],58 "@types/bun": ["@types/bun@1.3.8", "", { "dependencies": { "bun-types": "1.3.8" } }, "sha512-3LvWJ2q5GerAXYxO2mffLTqOzEu5qnhEAlh48Vnu8WQfnmSwbgagjGZV6BoHKJztENYEDn6QmVd949W4uESRJA=="],
45 59
60 "@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
61
46 "@types/node": ["@types/node@25.2.1", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-CPrnr8voK8vC6eEtyRzvMpgp3VyVRhgclonE7qYi6P9sXwYb59ucfrnmFBTaP0yUi8Gk4yZg/LlTJULGxvTNsg=="],62 "@types/node": ["@types/node@25.2.1", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-CPrnr8voK8vC6eEtyRzvMpgp3VyVRhgclonE7qYi6P9sXwYb59ucfrnmFBTaP0yUi8Gk4yZg/LlTJULGxvTNsg=="],
47 63
48 "@vercel/oidc": ["@vercel/oidc@3.1.0", "", {}, "sha512-Fw28YZpRnA3cAHHDlkt7xQHiJ0fcL+NRcIqsocZQUSmbzeIKRpwttJjik5ZGanXP+vlA4SbTg+AbA3bP363l+w=="],64 "@vercel/oidc": ["@vercel/oidc@3.1.0", "", {}, "sha512-Fw28YZpRnA3cAHHDlkt7xQHiJ0fcL+NRcIqsocZQUSmbzeIKRpwttJjik5ZGanXP+vlA4SbTg+AbA3bP363l+w=="],
49 65
50 "@vercel/sandbox": ["@vercel/sandbox@1.4.1", "", { "dependencies": { "@vercel/oidc": "^3.1.0", "async-retry": "1.3.3", "jsonlines": "0.1.1", "ms": "2.1.3", "picocolors": "^1.1.1", "tar-stream": "3.1.7", "undici": "^7.16.0", "xdg-app-paths": "5.1.0", "zod": "3.24.4" } }, "sha512-5jaNLv6QJ0112ZFhCv9hQDCV3IYogpbEn5LzMcY5E8TZsf5tF0avat2tBe7McOJvgVs0SDkuzjvGjUMKtTkjrA=="],66 "@vercel/sandbox": ["@vercel/sandbox@1.4.1", "", { "dependencies": { "@vercel/oidc": "^3.1.0", "async-retry": "1.3.3", "jsonlines": "0.1.1", "ms": "2.1.3", "picocolors": "^1.1.1", "tar-stream": "3.1.7", "undici": "^7.16.0", "xdg-app-paths": "5.1.0", "zod": "3.24.4" } }, "sha512-5jaNLv6QJ0112ZFhCv9hQDCV3IYogpbEn5LzMcY5E8TZsf5tF0avat2tBe7McOJvgVs0SDkuzjvGjUMKtTkjrA=="],
51 67
68 "accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="],
69
70 "ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="],
71
72 "ajv-draft-04": ["ajv-draft-04@1.0.0", "", { "peerDependencies": { "ajv": "^8.5.0" }, "optionalPeers": ["ajv"] }, "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw=="],
73
74 "ajv-formats": ["ajv-formats@3.0.1", "", { "dependencies": { "ajv": "^8.0.0" } }, "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ=="],
75
76 "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
77
52 "async-retry": ["async-retry@1.3.3", "", { "dependencies": { "retry": "0.13.1" } }, "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw=="],78 "async-retry": ["async-retry@1.3.3", "", { "dependencies": { "retry": "0.13.1" } }, "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw=="],
53 79
54 "b4a": ["b4a@1.7.3", "", { "peerDependencies": { "react-native-b4a": "*" }, "optionalPeers": ["react-native-b4a"] }, "sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q=="],80 "b4a": ["b4a@1.7.3", "", { "peerDependencies": { "react-native-b4a": "*" }, "optionalPeers": ["react-native-b4a"] }, "sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q=="],
55 81
56 "bare-events": ["bare-events@2.8.2", "", { "peerDependencies": { "bare-abort-controller": "*" }, "optionalPeers": ["bare-abort-controller"] }, "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ=="],82 "bare-events": ["bare-events@2.8.2", "", { "peerDependencies": { "bare-abort-controller": "*" }, "optionalPeers": ["bare-abort-controller"] }, "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ=="],
57 83
84 "body-parser": ["body-parser@2.2.2", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.3", "http-errors": "^2.0.0", "iconv-lite": "^0.7.0", "on-finished": "^2.4.1", "qs": "^6.14.1", "raw-body": "^3.0.1", "type-is": "^2.0.1" } }, "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA=="],
85
58 "bun-types": ["bun-types@1.3.8", "", { "dependencies": { "@types/node": "*" } }, "sha512-fL99nxdOWvV4LqjmC+8Q9kW3M4QTtTR1eePs94v5ctGqU8OeceWrSUaRw3JYb7tU3FkMIAjkueehrHPPPGKi5Q=="],86 "bun-types": ["bun-types@1.3.8", "", { "dependencies": { "@types/node": "*" } }, "sha512-fL99nxdOWvV4LqjmC+8Q9kW3M4QTtTR1eePs94v5ctGqU8OeceWrSUaRw3JYb7tU3FkMIAjkueehrHPPPGKi5Q=="],
59 87
88 "bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="],
89
90 "call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="],
91
92 "call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="],
93
94 "call-me-maybe": ["call-me-maybe@1.0.2", "", {}, "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ=="],
95
96 "content-disposition": ["content-disposition@1.0.1", "", {}, "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q=="],
97
98 "content-type": ["content-type@1.0.5", "", {}, "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="],
99
100 "cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="],
101
102 "cookie-signature": ["cookie-signature@1.2.2", "", {}, "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg=="],
103
104 "cors": ["cors@2.8.6", "", { "dependencies": { "object-assign": "^4", "vary": "^1" } }, "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw=="],
105
106 "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
107
108 "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
109
110 "depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="],
111
112 "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
113
114 "ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="],
115
116 "encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="],
117
118 "es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="],
119
120 "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
121
122 "es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="],
123
124 "escape-html": ["escape-html@1.0.3", "", {}, "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="],
125
126 "etag": ["etag@1.8.1", "", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="],
127
60 "events-universal": ["events-universal@1.0.1", "", { "dependencies": { "bare-events": "^2.7.0" } }, "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw=="],128 "events-universal": ["events-universal@1.0.1", "", { "dependencies": { "bare-events": "^2.7.0" } }, "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw=="],
61 129
130 "eventsource": ["eventsource@3.0.7", "", { "dependencies": { "eventsource-parser": "^3.0.1" } }, "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA=="],
131
132 "eventsource-parser": ["eventsource-parser@3.0.6", "", {}, "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg=="],
133
134 "express": ["express@5.2.1", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "depd": "^2.0.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" } }, "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw=="],
135
136 "express-rate-limit": ["express-rate-limit@8.2.1", "", { "dependencies": { "ip-address": "10.0.1" }, "peerDependencies": { "express": ">= 4.11" } }, "sha512-PCZEIEIxqwhzw4KF0n7QF4QqruVTcF73O5kFKUnGOyjbCCgizBBiFaYpd/fnBLUMPw/BWw9OsiN7GgrNYr7j6g=="],
137
138 "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
139
62 "fast-fifo": ["fast-fifo@1.3.2", "", {}, "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ=="],140 "fast-fifo": ["fast-fifo@1.3.2", "", {}, "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ=="],
63 141
142 "fast-uri": ["fast-uri@3.1.0", "", {}, "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA=="],
143
144 "finalhandler": ["finalhandler@2.1.1", "", { "dependencies": { "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "on-finished": "^2.4.1", "parseurl": "^1.3.3", "statuses": "^2.0.1" } }, "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA=="],
145
146 "forwarded": ["forwarded@0.2.0", "", {}, "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="],
147
148 "fresh": ["fresh@2.0.0", "", {}, "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A=="],
149
150 "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
151
152 "get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="],
153
154 "get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="],
155
156 "gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
157
158 "has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="],
159
160 "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
161
162 "hono": ["hono@4.11.8", "", {}, "sha512-eVkB/CYCCei7K2WElZW9yYQFWssG0DhaDhVvr7wy5jJ22K+ck8fWW0EsLpB0sITUTvPnc97+rrbQqIr5iqiy9Q=="],
163
164 "http-errors": ["http-errors@2.0.1", "", { "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", "setprototypeof": "~1.2.0", "statuses": "~2.0.2", "toidentifier": "~1.0.1" } }, "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ=="],
165
166 "iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="],
167
168 "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
169
170 "ip-address": ["ip-address@10.0.1", "", {}, "sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA=="],
171
172 "ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="],
173
174 "is-promise": ["is-promise@4.0.0", "", {}, "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ=="],
175
176 "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
177
178 "jose": ["jose@6.1.3", "", {}, "sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ=="],
179
180 "js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="],
181
182 "json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="],
183
184 "json-schema-typed": ["json-schema-typed@8.0.2", "", {}, "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA=="],
185
64 "jsonlines": ["jsonlines@0.1.1", "", {}, "sha512-ekDrAGso79Cvf+dtm+mL8OBI2bmAOt3gssYs833De/C9NmIpWDWyUO4zPgB5x2/OhY366dkhgfPMYfwZF7yOZA=="],186 "jsonlines": ["jsonlines@0.1.1", "", {}, "sha512-ekDrAGso79Cvf+dtm+mL8OBI2bmAOt3gssYs833De/C9NmIpWDWyUO4zPgB5x2/OhY366dkhgfPMYfwZF7yOZA=="],
65 187
188 "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
189
190 "media-typer": ["media-typer@1.1.0", "", {}, "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw=="],
191
192 "merge-descriptors": ["merge-descriptors@2.0.0", "", {}, "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g=="],
193
194 "mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="],
195
196 "mime-types": ["mime-types@3.0.2", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="],
197
66 "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],198 "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
67 199
200 "negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="],
201
202 "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="],
203
204 "object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="],
205
206 "on-finished": ["on-finished@2.4.1", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg=="],
207
208 "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="],
209
210 "openapi-types": ["openapi-types@12.1.3", "", {}, "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw=="],
211
68 "os-paths": ["os-paths@4.4.0", "", {}, "sha512-wrAwOeXp1RRMFfQY8Sy7VaGVmPocaLwSFOYCGKSyo8qmJ+/yaafCl5BCA1IQZWqFSRBrKDYFeR9d/VyQzfH/jg=="],212 "os-paths": ["os-paths@4.4.0", "", {}, "sha512-wrAwOeXp1RRMFfQY8Sy7VaGVmPocaLwSFOYCGKSyo8qmJ+/yaafCl5BCA1IQZWqFSRBrKDYFeR9d/VyQzfH/jg=="],
69 213
214 "parseurl": ["parseurl@1.3.3", "", {}, "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="],
215
216 "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
217
218 "path-to-regexp": ["path-to-regexp@8.3.0", "", {}, "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA=="],
219
70 "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],220 "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
71 221
222 "pkce-challenge": ["pkce-challenge@5.0.1", "", {}, "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ=="],
223
224 "proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="],
225
226 "qs": ["qs@6.14.1", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ=="],
227
228 "range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="],
229
230 "raw-body": ["raw-body@3.0.2", "", { "dependencies": { "bytes": "~3.1.2", "http-errors": "~2.0.1", "iconv-lite": "~0.7.0", "unpipe": "~1.0.0" } }, "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA=="],
231
232 "require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="],
233
72 "retry": ["retry@0.13.1", "", {}, "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg=="],234 "retry": ["retry@0.13.1", "", {}, "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg=="],
73 235
236 "router": ["router@2.2.0", "", { "dependencies": { "debug": "^4.4.0", "depd": "^2.0.0", "is-promise": "^4.0.0", "parseurl": "^1.3.3", "path-to-regexp": "^8.0.0" } }, "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ=="],
237
238 "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
239
240 "send": ["send@1.2.1", "", { "dependencies": { "debug": "^4.4.3", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", "http-errors": "^2.0.1", "mime-types": "^3.0.2", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.2" } }, "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ=="],
241
242 "serve-static": ["serve-static@2.2.1", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw=="],
243
244 "setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="],
245
246 "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
247
248 "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
249
250 "side-channel": ["side-channel@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="],
251
252 "side-channel-list": ["side-channel-list@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" } }, "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA=="],
253
254 "side-channel-map": ["side-channel-map@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" } }, "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA=="],
255
256 "side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="],
257
258 "statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="],
259
74 "streamx": ["streamx@2.23.0", "", { "dependencies": { "events-universal": "^1.0.0", "fast-fifo": "^1.3.2", "text-decoder": "^1.1.0" } }, "sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg=="],260 "streamx": ["streamx@2.23.0", "", { "dependencies": { "events-universal": "^1.0.0", "fast-fifo": "^1.3.2", "text-decoder": "^1.1.0" } }, "sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg=="],
75 261
76 "tar-stream": ["tar-stream@3.1.7", "", { "dependencies": { "b4a": "^1.6.4", "fast-fifo": "^1.2.0", "streamx": "^2.15.0" } }, "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ=="],262 "tar-stream": ["tar-stream@3.1.7", "", { "dependencies": { "b4a": "^1.6.4", "fast-fifo": "^1.2.0", "streamx": "^2.15.0" } }, "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ=="],
77 263
78 "text-decoder": ["text-decoder@1.2.3", "", { "dependencies": { "b4a": "^1.6.4" } }, "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA=="],264 "text-decoder": ["text-decoder@1.2.3", "", { "dependencies": { "b4a": "^1.6.4" } }, "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA=="],
79 265
266 "toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="],
267
268 "type-is": ["type-is@2.0.1", "", { "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw=="],
269
80 "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],270 "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
81 271
82 "undici": ["undici@7.21.0", "", {}, "sha512-Hn2tCQpoDt1wv23a68Ctc8Cr/BHpUSfaPYrkajTXOS9IKpxVRx/X5m1K2YkbK2ipgZgxXSgsUinl3x+2YdSSfg=="],272 "undici": ["undici@7.21.0", "", {}, "sha512-Hn2tCQpoDt1wv23a68Ctc8Cr/BHpUSfaPYrkajTXOS9IKpxVRx/X5m1K2YkbK2ipgZgxXSgsUinl3x+2YdSSfg=="],
83 273
84 "undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],274 "undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
85 275
276 "unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="],
277
278 "vary": ["vary@1.1.2", "", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="],
279
280 "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
281
282 "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="],
283
86 "xdg-app-paths": ["xdg-app-paths@5.1.0", "", { "dependencies": { "xdg-portable": "^7.0.0" } }, "sha512-RAQ3WkPf4KTU1A8RtFx3gWywzVKe00tfOPFfl2NDGqbIFENQO4kqAJp7mhQjNj/33W5x5hiWWUdyfPq/5SU3QA=="],284 "xdg-app-paths": ["xdg-app-paths@5.1.0", "", { "dependencies": { "xdg-portable": "^7.0.0" } }, "sha512-RAQ3WkPf4KTU1A8RtFx3gWywzVKe00tfOPFfl2NDGqbIFENQO4kqAJp7mhQjNj/33W5x5hiWWUdyfPq/5SU3QA=="],
87 285
88 "xdg-portable": ["xdg-portable@7.3.0", "", { "dependencies": { "os-paths": "^4.0.1" } }, "sha512-sqMMuL1rc0FmMBOzCpd0yuy9trqF2yTTVe+E9ogwCSWQCdDEtQUwrZPT6AxqtsFGRNxycgncbP/xmOOSPw5ZUw=="],286 "xdg-portable": ["xdg-portable@7.3.0", "", { "dependencies": { "os-paths": "^4.0.1" } }, "sha512-sqMMuL1rc0FmMBOzCpd0yuy9trqF2yTTVe+E9ogwCSWQCdDEtQUwrZPT6AxqtsFGRNxycgncbP/xmOOSPw5ZUw=="],
89 287
90 "zod": ["zod@3.24.4", "", {}, "sha512-OdqJE9UDRPwWsrHjLN2F8bPxvwJBK22EHLWtanu0LSYr5YqzsaaW3RMgmjwr8Rypg5k+meEJdSPXJZXE/yqOMg=="],288 "zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="],
289
290 "zod-to-json-schema": ["zod-to-json-schema@3.25.1", "", { "peerDependencies": { "zod": "^3.25 || ^4" } }, "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA=="],
291
292 "@vercel/sandbox/zod": ["zod@3.24.4", "", {}, "sha512-OdqJE9UDRPwWsrHjLN2F8bPxvwJBK22EHLWtanu0LSYr5YqzsaaW3RMgmjwr8Rypg5k+meEJdSPXJZXE/yqOMg=="],
91 }293 }
92}294}
executor/packages/contracts/src/index.ts+3−0
@@ -70,6 +70,9 @@ export interface ToolDescriptor { · 69 unmodified lines
70 path: string;70 path: string;
71 description: string;71 description: string;
72 approval: "auto" | "required";72 approval: "auto" | "required";
73 source?: string;
74 argsType?: string;
75 returnsType?: string;
73}76}
74 77
75export interface TaskEventRecord {78export interface TaskEventRecord {