import { Effect, Match, Option, Schema } from "effect";import * as Cause from "effect/Cause";import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";import type { ContentBlock } from "@modelcontextprotocol/sdk/types.js";import type { jsonSchemaValidator, JsonSchemaType, JsonSchemaValidator,} from "@modelcontextprotocol/sdk/validation/types.js";import { Validator } from "@cfworker/json-schema";import * as z from "zod/v4"; import { isToolFile, isToolResult } from "@executor-js/sdk";import type { ElicitationResponse, ElicitationHandler, ElicitationContext, ElicitationRequest, ToolFileValue,} from "@executor-js/sdk";import type * as Tracer from "effect/Tracer";import { createExecutionEngine, formatExecuteResult, formatPausedExecution, type ExecutionEngine, type ExecutionEngineConfig, type ResumeResponse,} from "@executor-js/execution"; // ---------------------------------------------------------------------------// Workers-compatible JSON Schema validator (replaces Ajv which uses new Function())// --------------------------------------------------------------------------- class CfWorkerJsonSchemaValidator implements jsonSchemaValidator { getValidator<T>(schema: JsonSchemaType): JsonSchemaValidator<T> { const validator = new Validator(schema as Record<string, unknown>, "2020-12", false); return (input: unknown) => { const result = validator.validate(input); if (result.valid) { return { valid: true, data: input as T, errorMessage: undefined }; } const errorMessage = result.errors.map((e) => `${e.instanceLocation}: ${e.error}`).join("; "); return { valid: false, data: undefined, errorMessage }; }; }} // ---------------------------------------------------------------------------// Config// --------------------------------------------------------------------------- type SharedMcpServerConfig = { /** * Pre-built `execute` tool description. When provided, the factory skips * its internal `engine.getDescription` yield. Useful when the caller * wants to compute the description inside its own Effect tracer context * so sub-spans (`executor.integrations.list`, `executor.tools.list`) nest as * children of the caller's root span. */ readonly description?: string; /** * Parent span override for engine calls. The factory captures the * caller's context at construction time, but `Effect.runPromiseWith` * starts a fresh fiber per SDK callback — so the `currentSpan` * FiberRef resets to root unless explicitly anchored. * * Accepts either a fixed span (per-request McpServer instances) or a * getter (session-scoped instances that need to anchor each callback * under whichever request triggered it; see the Cloud DO). */ readonly parentSpan?: Tracer.AnySpan | (() => Tracer.AnySpan | undefined); /** * Enable verbose MCP capability / elicitation debug logging. */ readonly debug?: boolean; /** * Controls how elicitation is handled for this MCP connection. The default * is model-managed resume, where paused executions expose interaction * metadata and the model can call `resume` with the user's response. */ readonly elicitationMode?: | { readonly mode: "browser"; readonly approvalUrl: (executionId: string) => string; } | { readonly mode: "model"; } | { readonly mode: "native"; }; readonly browserApprovalStore?: BrowserApprovalStore;}; export type ExecutorMcpServerConfig<E extends Cause.YieldableError = Cause.YieldableError> = | (ExecutionEngineConfig<E> & SharedMcpServerConfig) | ({ readonly engine: ExecutionEngine<E> } & SharedMcpServerConfig) | (ExecutionEngineConfig<E> & SharedMcpServerConfig & { readonly stateless: true }) | ({ readonly engine: ExecutionEngine<E>; readonly stateless: true } & SharedMcpServerConfig); export type BrowserApprovalStore = { readonly takeResponse: (executionId: string) => Effect.Effect<ResumeResponse | null>; readonly waitForResponse?: (executionId: string) => Effect.Effect<ResumeResponse | null>;}; // ---------------------------------------------------------------------------// Elicitation bridge// --------------------------------------------------------------------------- const getElicitationSupport = (server: McpServer): { form: boolean; url: boolean } => { const capabilities = server.server.getClientCapabilities(); if (capabilities === undefined || !capabilities.elicitation) return { form: false, url: false }; const elicitation = capabilities.elicitation as Record<string, unknown>; return { form: Boolean(elicitation.form), url: Boolean(elicitation.url) };}; const readDebugDefault = (): boolean => { if (typeof process === "undefined" || !process.env) return false; const value = process.env.EXECUTOR_MCP_DEBUG; return value === "1" || value === "true";}; const capabilitySnapshot = (server: McpServer) => ({ clientCapabilities: server.server.getClientCapabilities() ?? null, elicitationSupport: getElicitationSupport(server),}); type ElicitInputParams = | { mode?: "form"; message: string; requestedSchema: { readonly [key: string]: unknown }; } | { mode: "url"; message: string; url: string; elicitationId: string }; const elicitationRequestTag = (request: ElicitationRequest): ElicitationRequest["_tag"] => Match.value(request).pipe( Match.tag("UrlElicitation", () => "UrlElicitation" as const), Match.tag("FormElicitation", () => "FormElicitation" as const), Match.exhaustive, ); const requestedSchemaIsNonEmpty = (request: ElicitationRequest): boolean => Match.value(request).pipe( Match.tag("FormElicitation", (req) => Object.keys(req.requestedSchema).length > 0), Match.tag("UrlElicitation", () => false), Match.exhaustive, ); const elicitationRequestUrl = (request: ElicitationRequest): string | undefined => Match.value(request).pipe( Match.tag("UrlElicitation", (req): string | undefined => req.url), Match.tag("FormElicitation", (): string | undefined => undefined), Match.exhaustive, ); const pausedInteractionKind = (request: ElicitationRequest): ElicitationRequest["_tag"] => elicitationRequestTag(request); const elicitationRequestToParams: (request: ElicitationRequest) => ElicitInputParams = Match.type<ElicitationRequest>().pipe( Match.tag("UrlElicitation", (req) => ({ mode: "url" as const, message: req.message, url: req.url, elicitationId: req.elicitationId, })), Match.tag("FormElicitation", (req) => ({ message: req.message, // The MCP SDK validates requestedSchema as a JSON Schema with // `type: "object"` and `properties`. For approval-only elicitations // where no fields are needed, provide a minimal valid schema. requestedSchema: Object.keys(req.requestedSchema).length === 0 ? { type: "object" as const, properties: {} } : req.requestedSchema, })), Match.exhaustive, ); const makeMcpElicitationHandler = ( server: McpServer, debugLog?: (event: string, data: Record<string, unknown>) => void, ): ElicitationHandler => (ctx: ElicitationContext): Effect.Effect<typeof ElicitationResponse.Type> => { const { url: supportsUrl } = getElicitationSupport(server); // If client doesn't support url mode, fall back to a form asking the user // to visit the URL manually and confirm when done. const params = Match.value(ctx.request).pipe( Match.tag( "UrlElicitation", (req): ElicitInputParams => !supportsUrl ? { message: `${req.message}\n\nPlease visit this URL:\n${req.url}\n\nClick accept once you have completed the flow.`, requestedSchema: { type: "object" as const, properties: {} }, } : elicitationRequestToParams(req), ), Match.tag("FormElicitation", (req): ElicitInputParams => elicitationRequestToParams(req)), Match.exhaustive, ); return Effect.promise(async (): Promise<typeof ElicitationResponse.Type> => { const requestTag = elicitationRequestTag(ctx.request); debugLog?.("elicitation.request", { requestTag, supportsUrl, message: ctx.request.message, hasRequestedSchema: requestedSchemaIsNonEmpty(ctx.request), url: elicitationRequestUrl(ctx.request), clientCapabilities: server.server.getClientCapabilities() ?? null, }); // oxlint-disable-next-line executor/no-try-catch-or-throw -- boundary: MCP SDK elicitInput is a Promise API; failures become a cancel response try { const response = await server.server.elicitInput( params as Parameters<typeof server.server.elicitInput>[0], ); debugLog?.("elicitation.response", { requestTag, action: response.action, hasContent: typeof response.content === "object" && response.content !== null && Object.keys(response.content).length > 0, }); return { action: response.action as typeof ElicitationResponse.Type.action, content: response.content, }; } catch (err) { const error = formatBoundaryError(err); debugLog?.("elicitation.error", { requestTag, error, clientCapabilities: server.server.getClientCapabilities() ?? null, }); console.error( "[executor] elicitInput failed - falling back to cancel.", JSON.stringify({ error, requestTag, ...capabilitySnapshot(server), }), ); return { action: "cancel" as const } as ElicitationResponse; } }); }; const formatBoundaryError = (err: unknown): { name?: string; message: string; stack?: string } => { // oxlint-disable-next-line executor/no-instanceof-error, executor/no-unknown-error-message -- boundary: SDK Promise rejection supplies unknown JS errors for logging only if (err instanceof Error) return { name: err.name, message: err.message, stack: err.stack }; // oxlint-disable-next-line executor/no-unknown-error-message -- boundary: fallback log formatting for unknown SDK Promise rejection values return { message: String(err) };}; // ---------------------------------------------------------------------------// MCP result formatting// --------------------------------------------------------------------------- type McpToolResult = { content: ContentBlock[]; structuredContent?: Record<string, unknown>; isError?: boolean;}; type FormattedExecuteInput = Parameters<typeof formatExecuteResult>[0]; const TEXT_FILE_CONTENT_MAX_CHARS = 64_000; const isRecord = (value: unknown): value is Record<string, unknown> => typeof value === "object" && value !== null && !Array.isArray(value); const isTextContentBlock = (value: unknown): value is Extract<ContentBlock, { type: "text" }> => isRecord(value) && value.type === "text" && typeof value.text === "string"; const isImageContentBlock = (value: unknown): value is Extract<ContentBlock, { type: "image" }> => isRecord(value) && value.type === "image" && typeof value.data === "string" && typeof value.mimeType === "string"; const isResourceContentBlock = ( value: unknown,): value is Extract<ContentBlock, { type: "resource" }> => isRecord(value) && value.type === "resource" && isRecord(value.resource); const isNativeMcpContentBlock = (value: unknown): value is ContentBlock => isTextContentBlock(value) || isImageContentBlock(value) || isResourceContentBlock(value); const nativeMcpContentResult = (value: unknown): McpToolResult | null => { if (!isToolResult(value) || !value.ok || !isRecord(value.data)) return null; const content = value.data.content; if (!Array.isArray(content) || content.length === 0 || !content.every(isNativeMcpContentBlock)) { return null; } if (!content.some((block) => block.type !== "text")) return null; return { content, ...(isRecord(value.data.structuredContent) ? { structuredContent: value.data.structuredContent } : {}), isError: value.data.isError === true || undefined, };}; const redactToolFileBytes = (file: ToolFileValue): Record<string, unknown> => ({ _tag: "ToolFile", ...(file.name ? { name: file.name } : {}), mimeType: file.mimeType, encoding: file.encoding, byteLength: file.byteLength,}); type ToolFileExtraction = { readonly value: unknown; readonly files: readonly ToolFileValue[];}; const extractToolFiles = ( value: unknown, seen: WeakSet<object> = new WeakSet(),): ToolFileExtraction => { if (isToolFile(value)) { return { value: redactToolFileBytes(value), files: [value] }; } if (isToolResult(value) && value.ok) { const data = extractToolFiles(value.data, seen); if (data.files.length === 0) return { value, files: [] }; return { value: { ...value, data: data.value, }, files: data.files, }; } if (Array.isArray(value)) { const files: ToolFileValue[] = []; const items = value.map((item) => { const extracted = extractToolFiles(item, seen); files.push(...extracted.files); return extracted.value; }); return { value: files.length > 0 ? items : value, files }; } if (!isRecord(value)) return { value, files: [] }; if (seen.has(value)) return { value: "[Circular]", files: [] }; seen.add(value); const files: ToolFileValue[] = []; const entries = Object.entries(value).map(([key, item]) => { const extracted = extractToolFiles(item, seen); files.push(...extracted.files); return [key, extracted.value] as const; }); seen.delete(value); return { value: files.length > 0 ? Object.fromEntries(entries) : value, files };}; const directToolFile = (value: unknown): ToolFileValue | null => { if (isToolFile(value)) return value; if (isToolResult(value) && value.ok && isToolFile(value.data)) return value.data; return null;}; const toolFileName = (file: ToolFileValue): string => file.name ?? "tool-output"; const fileResourceUri = (file: ToolFileValue): string => `executor-file:///${encodeURIComponent(toolFileName(file))}`; const normalizedMimeType = (file: ToolFileValue): string => file.mimeType.split(";")[0]?.trim().toLowerCase() ?? ""; const toolFileKind = (file: ToolFileValue): "image" | "text" | "resource" => { const mimeType = normalizedMimeType(file); if (mimeType.startsWith("image/")) return "image"; if ( mimeType.startsWith("text/") || mimeType === "application/json" || mimeType.endsWith("+json") || mimeType === "application/xml" || mimeType.endsWith("+xml") || mimeType === "application/javascript" || mimeType === "application/x-javascript" || mimeType === "application/yaml" || mimeType === "application/x-yaml" ) { return "text"; } return "resource";}; const bytesFromBase64 = (base64: string): Uint8Array => { const binary = atob(base64); const bytes = new Uint8Array(binary.length); for (let index = 0; index < binary.length; index += 1) { bytes[index] = binary.charCodeAt(index); } return bytes;}; const decodeTextFile = (file: ToolFileValue): string => { const text = new TextDecoder("utf-8", { fatal: false }).decode(bytesFromBase64(file.data)); if (text.length <= TEXT_FILE_CONTENT_MAX_CHARS) return text; return `${text.slice(0, TEXT_FILE_CONTENT_MAX_CHARS)}\n\n[truncated ${ text.length - TEXT_FILE_CONTENT_MAX_CHARS } characters]`;}; const toolFileContent = (file: ToolFileValue): ContentBlock[] => { const kind = toolFileKind(file); if (kind === "image") { return [{ type: "image", data: file.data, mimeType: file.mimeType }]; } if (kind === "text") { return [{ type: "text", text: decodeTextFile(file) }]; } return [ { type: "resource", resource: { uri: fileResourceUri(file), mimeType: file.mimeType, blob: file.data, }, }, ];}; const toolFileSummaryLine = (file: ToolFileValue, index?: number): string => { const prefix = index === undefined ? "" : `${index + 1}. `; return `${prefix}${toolFileName(file)} (${file.mimeType}, ${file.byteLength} bytes)`;}; const toMcpFileResult = ( result: FormattedExecuteInput, extracted: ToolFileExtraction,): McpToolResult => { const files = extracted.files; const hasModelNativeFile = files.some((file) => toolFileKind(file) !== "resource"); const redactedResult = { ...result, result: extracted.value }; const formatted = formatExecuteResult(redactedResult); const directFile = directToolFile(result.result); const logText = result.logs && result.logs.length > 0 ? `\n\nLogs:\n${result.logs.join("\n")}` : ""; const summary = directFile && files.length === 1 ? `File output: ${toolFileName(directFile)}\n${directFile.mimeType}, ${ directFile.byteLength } bytes${logText}` : [ "File outputs:", ...files.map((file, index) => toolFileSummaryLine(file, index)), "", "Result metadata:", formatted.text, ].join("\n"); return { content: [ { type: "text", text: summary, }, ...files.flatMap(toolFileContent), ], ...(hasModelNativeFile ? {} : { structuredContent: formatted.structured, }), isError: formatted.isError || undefined, };}; const toMcpResult = (result: FormattedExecuteInput): McpToolResult => { const nativeMcpResult = result.error ? null : nativeMcpContentResult(result.result); if (nativeMcpResult) return nativeMcpResult; const extracted = result.error ? { value: result.result, files: [] } : extractToolFiles(result.result); if (extracted.files.length > 0) return toMcpFileResult(result, extracted); const formatted = formatExecuteResult(result); return { content: [{ type: "text", text: formatted.text }], structuredContent: formatted.structured, isError: formatted.isError || undefined, };Lines 1–500 of 882. Load more
import { Effect, Match, Option, Schema } from "effect"; import * as Cause from "effect/Cause"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import type { ContentBlock } from "@modelcontextprotocol/sdk/types.js"; import type { jsonSchemaValidator, JsonSchemaType, JsonSchemaValidator, } from "@modelcontextprotocol/sdk/validation/types.js"; import { Validator } from "@cfworker/json-schema"; import * as z from "zod/v4"; import { isToolFile, isToolResult } from "@executor-js/sdk"; import type { ElicitationResponse, ElicitationHandler, ElicitationContext, ElicitationRequest, ToolFileValue, } from "@executor-js/sdk"; import type * as Tracer from "effect/Tracer"; import { createExecutionEngine, formatExecuteResult, formatPausedExecution, type ExecutionEngine, type ExecutionEngineConfig, type ResumeResponse, } from "@executor-js/execution"; // --------------------------------------------------------------------------- // Workers-compatible JSON Schema validator (replaces Ajv which uses new Function()) // --------------------------------------------------------------------------- class CfWorkerJsonSchemaValidator implements jsonSchemaValidator { getValidator<T>(schema: JsonSchemaType): JsonSchemaValidator<T> { const validator = new Validator(schema as Record<string, unknown>, "2020-12", false); return (input: unknown) => { const result = validator.validate(input); if (result.valid) { return { valid: true, data: input as T, errorMessage: undefined }; } const errorMessage = result.errors.map((e) => `${e.instanceLocation}: ${e.error}`).join("; "); return { valid: false, data: undefined, errorMessage }; }; } } // --------------------------------------------------------------------------- // Config // --------------------------------------------------------------------------- type SharedMcpServerConfig = { /** * Pre-built `execute` tool description. When provided, the factory skips * its internal `engine.getDescription` yield. Useful when the caller * wants to compute the description inside its own Effect tracer context * so sub-spans (`executor.integrations.list`, `executor.tools.list`) nest as * children of the caller's root span. */ readonly description?: string; /** * Parent span override for engine calls. The factory captures the * caller's context at construction time, but `Effect.runPromiseWith` * starts a fresh fiber per SDK callback — so the `currentSpan` * FiberRef resets to root unless explicitly anchored. * * Accepts either a fixed span (per-request McpServer instances) or a * getter (session-scoped instances that need to anchor each callback * under whichever request triggered it; see the Cloud DO). */ readonly parentSpan?: Tracer.AnySpan | (() => Tracer.AnySpan | undefined); /** * Enable verbose MCP capability / elicitation debug logging. */ readonly debug?: boolean; /** * Controls how elicitation is handled for this MCP connection. The default * is model-managed resume, where paused executions expose interaction * metadata and the model can call `resume` with the user's response. */ readonly elicitationMode?: | { readonly mode: "browser"; readonly approvalUrl: (executionId: string) => string; } | { readonly mode: "model"; } | { readonly mode: "native"; }; readonly browserApprovalStore?: BrowserApprovalStore; }; export type ExecutorMcpServerConfig<E extends Cause.YieldableError = Cause.YieldableError> = | (ExecutionEngineConfig<E> & SharedMcpServerConfig) | ({ readonly engine: ExecutionEngine<E> } & SharedMcpServerConfig) | (ExecutionEngineConfig<E> & SharedMcpServerConfig & { readonly stateless: true }) | ({ readonly engine: ExecutionEngine<E>; readonly stateless: true } & SharedMcpServerConfig); export type BrowserApprovalStore = { readonly takeResponse: (executionId: string) => Effect.Effect<ResumeResponse | null>; readonly waitForResponse?: (executionId: string) => Effect.Effect<ResumeResponse | null>; }; // --------------------------------------------------------------------------- // Elicitation bridge // --------------------------------------------------------------------------- const getElicitationSupport = (server: McpServer): { form: boolean; url: boolean } => { const capabilities = server.server.getClientCapabilities(); if (capabilities === undefined || !capabilities.elicitation) return { form: false, url: false }; const elicitation = capabilities.elicitation as Record<string, unknown>; return { form: Boolean(elicitation.form), url: Boolean(elicitation.url) }; }; const readDebugDefault = (): boolean => { if (typeof process === "undefined" || !process.env) return false; const value = process.env.EXECUTOR_MCP_DEBUG; return value === "1" || value === "true"; }; const capabilitySnapshot = (server: McpServer) => ({ clientCapabilities: server.server.getClientCapabilities() ?? null, elicitationSupport: getElicitationSupport(server), }); type ElicitInputParams = | { mode?: "form"; message: string; requestedSchema: { readonly [key: string]: unknown }; } | { mode: "url"; message: string; url: string; elicitationId: string }; const elicitationRequestTag = (request: ElicitationRequest): ElicitationRequest["_tag"] => Match.value(request).pipe( Match.tag("UrlElicitation", () => "UrlElicitation" as const), Match.tag("FormElicitation", () => "FormElicitation" as const), Match.exhaustive, ); const requestedSchemaIsNonEmpty = (request: ElicitationRequest): boolean => Match.value(request).pipe( Match.tag("FormElicitation", (req) => Object.keys(req.requestedSchema).length > 0), Match.tag("UrlElicitation", () => false), Match.exhaustive, ); const elicitationRequestUrl = (request: ElicitationRequest): string | undefined => Match.value(request).pipe( Match.tag("UrlElicitation", (req): string | undefined => req.url), Match.tag("FormElicitation", (): string | undefined => undefined), Match.exhaustive, ); const pausedInteractionKind = (request: ElicitationRequest): ElicitationRequest["_tag"] => elicitationRequestTag(request); const elicitationRequestToParams: (request: ElicitationRequest) => ElicitInputParams = Match.type<ElicitationRequest>().pipe( Match.tag("UrlElicitation", (req) => ({ mode: "url" as const, message: req.message, url: req.url, elicitationId: req.elicitationId, })), Match.tag("FormElicitation", (req) => ({ message: req.message, // The MCP SDK validates requestedSchema as a JSON Schema with // `type: "object"` and `properties`. For approval-only elicitations // where no fields are needed, provide a minimal valid schema. requestedSchema: Object.keys(req.requestedSchema).length === 0 ? { type: "object" as const, properties: {} } : req.requestedSchema, })), Match.exhaustive, ); const makeMcpElicitationHandler = ( server: McpServer, debugLog?: (event: string, data: Record<string, unknown>) => void, ): ElicitationHandler => (ctx: ElicitationContext): Effect.Effect<typeof ElicitationResponse.Type> => { const { url: supportsUrl } = getElicitationSupport(server); // If client doesn't support url mode, fall back to a form asking the user // to visit the URL manually and confirm when done. const params = Match.value(ctx.request).pipe( Match.tag( "UrlElicitation", (req): ElicitInputParams => !supportsUrl ? { message: `${req.message}\n\nPlease visit this URL:\n${req.url}\n\nClick accept once you have completed the flow.`, requestedSchema: { type: "object" as const, properties: {} }, } : elicitationRequestToParams(req), ), Match.tag("FormElicitation", (req): ElicitInputParams => elicitationRequestToParams(req)), Match.exhaustive, ); return Effect.promise(async (): Promise<typeof ElicitationResponse.Type> => { const requestTag = elicitationRequestTag(ctx.request); debugLog?.("elicitation.request", { requestTag, supportsUrl, message: ctx.request.message, hasRequestedSchema: requestedSchemaIsNonEmpty(ctx.request), url: elicitationRequestUrl(ctx.request), clientCapabilities: server.server.getClientCapabilities() ?? null, }); // oxlint-disable-next-line executor/no-try-catch-or-throw -- boundary: MCP SDK elicitInput is a Promise API; failures become a cancel response try { const response = await server.server.elicitInput( params as Parameters<typeof server.server.elicitInput>[0], ); debugLog?.("elicitation.response", { requestTag, action: response.action, hasContent: typeof response.content === "object" && response.content !== null && Object.keys(response.content).length > 0, }); return { action: response.action as typeof ElicitationResponse.Type.action, content: response.content, }; } catch (err) { const error = formatBoundaryError(err); debugLog?.("elicitation.error", { requestTag, error, clientCapabilities: server.server.getClientCapabilities() ?? null, }); console.error( "[executor] elicitInput failed - falling back to cancel.", JSON.stringify({ error, requestTag, ...capabilitySnapshot(server), }), ); return { action: "cancel" as const } as ElicitationResponse; } }); }; const formatBoundaryError = (err: unknown): { name?: string; message: string; stack?: string } => { // oxlint-disable-next-line executor/no-instanceof-error, executor/no-unknown-error-message -- boundary: SDK Promise rejection supplies unknown JS errors for logging only if (err instanceof Error) return { name: err.name, message: err.message, stack: err.stack }; // oxlint-disable-next-line executor/no-unknown-error-message -- boundary: fallback log formatting for unknown SDK Promise rejection values return { message: String(err) }; }; // --------------------------------------------------------------------------- // MCP result formatting // --------------------------------------------------------------------------- type McpToolResult = { content: ContentBlock[]; structuredContent?: Record<string, unknown>; isError?: boolean; }; type FormattedExecuteInput = Parameters<typeof formatExecuteResult>[0]; const TEXT_FILE_CONTENT_MAX_CHARS = 64_000; const isRecord = (value: unknown): value is Record<string, unknown> => typeof value === "object" && value !== null && !Array.isArray(value); const isTextContentBlock = (value: unknown): value is Extract<ContentBlock, { type: "text" }> => isRecord(value) && value.type === "text" && typeof value.text === "string"; const isImageContentBlock = (value: unknown): value is Extract<ContentBlock, { type: "image" }> => isRecord(value) && value.type === "image" && typeof value.data === "string" && typeof value.mimeType === "string"; const isResourceContentBlock = ( value: unknown, ): value is Extract<ContentBlock, { type: "resource" }> => isRecord(value) && value.type === "resource" && isRecord(value.resource); const isNativeMcpContentBlock = (value: unknown): value is ContentBlock => isTextContentBlock(value) || isImageContentBlock(value) || isResourceContentBlock(value); const nativeMcpContentResult = (value: unknown): McpToolResult | null => { if (!isToolResult(value) || !value.ok || !isRecord(value.data)) return null; const content = value.data.content; if (!Array.isArray(content) || content.length === 0 || !content.every(isNativeMcpContentBlock)) { return null; } if (!content.some((block) => block.type !== "text")) return null; return { content, ...(isRecord(value.data.structuredContent) ? { structuredContent: value.data.structuredContent } : {}), isError: value.data.isError === true || undefined, }; }; const redactToolFileBytes = (file: ToolFileValue): Record<string, unknown> => ({ _tag: "ToolFile", ...(file.name ? { name: file.name } : {}), mimeType: file.mimeType, encoding: file.encoding, byteLength: file.byteLength, }); type ToolFileExtraction = { readonly value: unknown; readonly files: readonly ToolFileValue[]; }; const extractToolFiles = ( value: unknown, seen: WeakSet<object> = new WeakSet(), ): ToolFileExtraction => { if (isToolFile(value)) { return { value: redactToolFileBytes(value), files: [value] }; } if (isToolResult(value) && value.ok) { const data = extractToolFiles(value.data, seen); if (data.files.length === 0) return { value, files: [] }; return { value: { ...value, data: data.value, }, files: data.files, }; } if (Array.isArray(value)) { const files: ToolFileValue[] = []; const items = value.map((item) => { const extracted = extractToolFiles(item, seen); files.push(...extracted.files); return extracted.value; }); return { value: files.length > 0 ? items : value, files }; } if (!isRecord(value)) return { value, files: [] }; if (seen.has(value)) return { value: "[Circular]", files: [] }; seen.add(value); const files: ToolFileValue[] = []; const entries = Object.entries(value).map(([key, item]) => { const extracted = extractToolFiles(item, seen); files.push(...extracted.files); return [key, extracted.value] as const; }); seen.delete(value); return { value: files.length > 0 ? Object.fromEntries(entries) : value, files }; }; const directToolFile = (value: unknown): ToolFileValue | null => { if (isToolFile(value)) return value; if (isToolResult(value) && value.ok && isToolFile(value.data)) return value.data; return null; }; const toolFileName = (file: ToolFileValue): string => file.name ?? "tool-output"; const fileResourceUri = (file: ToolFileValue): string => `executor-file:///${encodeURIComponent(toolFileName(file))}`; const normalizedMimeType = (file: ToolFileValue): string => file.mimeType.split(";")[0]?.trim().toLowerCase() ?? ""; const toolFileKind = (file: ToolFileValue): "image" | "text" | "resource" => { const mimeType = normalizedMimeType(file); if (mimeType.startsWith("image/")) return "image"; if ( mimeType.startsWith("text/") || mimeType === "application/json" || mimeType.endsWith("+json") || mimeType === "application/xml" || mimeType.endsWith("+xml") || mimeType === "application/javascript" || mimeType === "application/x-javascript" || mimeType === "application/yaml" || mimeType === "application/x-yaml" ) { return "text"; } return "resource"; }; const bytesFromBase64 = (base64: string): Uint8Array => { const binary = atob(base64); const bytes = new Uint8Array(binary.length); for (let index = 0; index < binary.length; index += 1) { bytes[index] = binary.charCodeAt(index); } return bytes; }; const decodeTextFile = (file: ToolFileValue): string => { const text = new TextDecoder("utf-8", { fatal: false }).decode(bytesFromBase64(file.data)); if (text.length <= TEXT_FILE_CONTENT_MAX_CHARS) return text; return `${text.slice(0, TEXT_FILE_CONTENT_MAX_CHARS)}\n\n[truncated ${ text.length - TEXT_FILE_CONTENT_MAX_CHARS } characters]`; }; const toolFileContent = (file: ToolFileValue): ContentBlock[] => { const kind = toolFileKind(file); if (kind === "image") { return [{ type: "image", data: file.data, mimeType: file.mimeType }]; } if (kind === "text") { return [{ type: "text", text: decodeTextFile(file) }]; } return [ { type: "resource", resource: { uri: fileResourceUri(file), mimeType: file.mimeType, blob: file.data, }, }, ]; }; const toolFileSummaryLine = (file: ToolFileValue, index?: number): string => { const prefix = index === undefined ? "" : `${index + 1}. `; return `${prefix}${toolFileName(file)} (${file.mimeType}, ${file.byteLength} bytes)`; }; const toMcpFileResult = ( result: FormattedExecuteInput, extracted: ToolFileExtraction, ): McpToolResult => { const files = extracted.files; const hasModelNativeFile = files.some((file) => toolFileKind(file) !== "resource"); const redactedResult = { ...result, result: extracted.value }; const formatted = formatExecuteResult(redactedResult); const directFile = directToolFile(result.result); const logText = result.logs && result.logs.length > 0 ? `\n\nLogs:\n${result.logs.join("\n")}` : ""; const summary = directFile && files.length === 1 ? `File output: ${toolFileName(directFile)}\n${directFile.mimeType}, ${ directFile.byteLength } bytes${logText}` : [ "File outputs:", ...files.map((file, index) => toolFileSummaryLine(file, index)), "", "Result metadata:", formatted.text, ].join("\n"); return { content: [ { type: "text", text: summary, }, ...files.flatMap(toolFileContent), ], ...(hasModelNativeFile ? {} : { structuredContent: formatted.structured, }), isError: formatted.isError || undefined, }; }; const toMcpResult = (result: FormattedExecuteInput): McpToolResult => { const nativeMcpResult = result.error ? null : nativeMcpContentResult(result.result); if (nativeMcpResult) return nativeMcpResult; const extracted = result.error ? { value: result.result, files: [] } : extractToolFiles(result.result); if (extracted.files.length > 0) return toMcpFileResult(result, extracted); const formatted = formatExecuteResult(result); return { content: [{ type: "text", text: formatted.text }], structuredContent: formatted.structured, isError: formatted.isError || undefined, };