@executor-js/execution 1.5.15 → 1.5.16
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.
|
@@ -528,6 +528,12 @@ var formatDescription = (connectionEntries) => {
|
|
|
528
528
|
"- `tools.executor.coreTools.connections.list({})` returns saved connections with `{ address, integration, owner, name, ... }`. The `address` field includes the leading `tools.` root.",
|
|
529
529
|
"- Tool calls return a value union: `{ ok: true, data }` for success or `{ ok: false, error: { code, message, status?, details?, retryable? } }` for expected tool/domain failures. Branch on `result.ok`.",
|
|
530
530
|
"- `data` is the upstream payload itself. HTTP-backed tools (OpenAPI) also set `http: { status, headers }` beside `data` \u2014 read `result.http?.headers` for pagination (Link) or rate-limit headers.",
|
|
531
|
+
"- Use `emit(value)` to append user-visible output and return `undefined`. Plain values become MCP text content. MCP content blocks are forwarded as-is. `ToolFile` values are rendered by MIME.",
|
|
532
|
+
'- File-returning tools may return `ToolFile` values: `{ _tag: "ToolFile", name?, mimeType, encoding: "base64", data, byteLength }`. Emit any attachment with `emit(result.data)`.',
|
|
533
|
+
'- To emit MCP-native content directly, pass an MCP content block to `emit(...)`, such as `{ type: "image", data, mimeType }`, `{ type: "audio", data, mimeType }`, `{ type: "text", text }`, `{ type: "resource", resource }`, or `{ type: "resource_link", uri, name, ... }`.',
|
|
534
|
+
"- `emit(ToolFile)` is MIME-based: `image/*` becomes MCP image content, `audio/*` becomes MCP audio content, text-like files become decoded text, and other binary files become embedded MCP resources.",
|
|
535
|
+
"- `return` is only for ordinary structured data. Returning a `ToolFile`, a `ToolResult`, an MCP content block, or a bare base64 string does not emit content to the MCP client.",
|
|
536
|
+
"- Some providers, including Gmail, return attachment bytes without a public URL. To send that attachment to another API from code, decode `ToolFile.data` from base64 and pass the bytes to that API's upload/file input.",
|
|
531
537
|
"- If `tools.search()` returns `hasMore: true` and you didn't find what you need, fetch the next page: `tools.search({ query, offset: nextOffset, limit })`.",
|
|
532
538
|
"- Always use the full address when calling tools: `tools.<integration>.<owner>.<connection>.<tool>(args)`. The `path` returned by `tools.search()` / `tools.describe.tool()` is already the exact path under `tools` \u2014 call `tools[path]` rather than guessing segments.",
|
|
533
539
|
"- The `tools` object is a lazy proxy \u2014 `Object.keys(tools)` won't work. Use `tools.search()` or `tools.executor.coreTools.connections.list({})` instead.",
|
|
@@ -912,4 +918,4 @@ export {
|
|
|
912
918
|
formatPausedExecution,
|
|
913
919
|
createExecutionEngine
|
|
914
920
|
};
|
|
915
|
-
//# sourceMappingURL=chunk-
|
|
921
|
+
//# sourceMappingURL=chunk-WAYRFG5Q.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/tool-invoker.ts","../src/description.ts","../src/engine.ts"],"sourcesContent":["import * as Data from \"effect/Data\";\n\nexport class ExecutionToolError extends Data.TaggedError(\"ExecutionToolError\")<{\n readonly message: string;\n readonly cause?: unknown;\n}> {}\n\n// `CodeExecutionError` lives in `@executor-js/codemode-core` — the `CodeExecutor`\n// interface uses it as the default error channel, so the runtime packages\n// can import the same class directly.\nexport { CodeExecutionError } from \"@executor-js/codemode-core\";\n","import { Effect, Predicate } from \"effect\";\nimport * as Cause from \"effect/Cause\";\nimport type {\n Executor,\n InvokeOptions,\n Integration,\n ToolError,\n Tool,\n ToolSchemaView,\n} from \"@executor-js/sdk/core\";\nimport {\n annotateToolResultOutcome,\n authToolFailure,\n isToolResult,\n ToolResult,\n ToolAddress,\n parseToolAddress,\n} from \"@executor-js/sdk/core\";\nimport type { SandboxToolInvoker } from \"@executor-js/codemode-core\";\nimport { ExecutionToolError } from \"./errors\";\n\nconst OPAQUE_DEFECT_MESSAGE = \"Internal tool error\";\nconst TOOL_DESCRIBE_SUGGESTION_LIMIT = 5;\nconst TOOL_ERROR_TYPESCRIPT =\n \"{ code: string; message: string; status?: number; details?: unknown; retryable?: boolean }\";\n// Present on HTTP-backed tools (OpenAPI): transport facts beside the payload\n// so callers can read pagination/rate-limit headers without the payload\n// being wrapped in an envelope.\nconst TOOL_HTTP_META_TYPESCRIPT = \"{ status: number; headers: { [k: string]: string; } }\";\nconst TOOL_FILE_TYPESCRIPT =\n '{ _tag: \"ToolFile\"; name?: string; mimeType: string; encoding: \"base64\"; data: string; byteLength: number; }';\n\nconst wrapOutputTypeScript = (outputTypeScript?: string): string =>\n `{ ok: true; data: ${outputTypeScript ?? \"unknown\"}; http?: ToolHttpMeta } | { ok: false; error: ToolError }`;\n\nconst withToolResultDefinitions = (\n definitions?: Record<string, string>,\n): Record<string, string> => ({\n ...(definitions ?? {}),\n ToolError: TOOL_ERROR_TYPESCRIPT,\n ToolHttpMeta: TOOL_HTTP_META_TYPESCRIPT,\n ToolFile: TOOL_FILE_TYPESCRIPT,\n});\n\nconst ADDRESS_PREFIX = \"tools.\";\n\n/**\n * Map a sandbox tool path to the executor's `execute` address.\n *\n * v2 dynamic tools are addressed `tools.<integration>.<owner>.<connection>.<tool>`.\n * The sandbox proxy strips the leading `tools.` (the proxy root), so a model\n * writing `tools.github.org.main.getRepo(args)` produces the path\n * `github.org.main.getRepo`. Re-prefix it so it parses as a 5-segment address.\n *\n * Plugin-contributed static tools (core-tools under `executor`, plugin executor\n * namespaces) are addressed by their fqid with no prefix; the executor resolves\n * those from its static map directly, so leave them untouched.\n */\nconst pathToAddress = (path: string): ToolAddress => {\n if (path.startsWith(ADDRESS_PREFIX)) return ToolAddress.make(path);\n if (parseToolAddress(`${ADDRESS_PREFIX}${path}`)) {\n return ToolAddress.make(`${ADDRESS_PREFIX}${path}`);\n }\n return ToolAddress.make(path);\n};\n\n/** Strip the proxy-root `tools.` prefix from a full address so it becomes the\n * sandbox-callable path the model writes after `tools.`. */\nconst addressToPath = (address: string): string =>\n address.startsWith(ADDRESS_PREFIX) ? address.slice(ADDRESS_PREFIX.length) : address;\n\ntype DescribedTool = {\n readonly path: string;\n readonly name: string;\n readonly description?: string;\n readonly inputTypeScript?: string;\n readonly outputTypeScript?: string;\n readonly typeScriptDefinitions?: Record<string, string>;\n /** Set when the path resolves to no tool — mirrors invoke's tool_not_found. */\n readonly error?: {\n readonly code: \"tool_not_found\";\n readonly message: string;\n readonly suggestions?: readonly string[];\n };\n};\n\nconst BUILTIN_TOOL_DESCRIPTIONS: ReadonlyMap<string, DescribedTool> = new Map<\n string,\n DescribedTool\n>([\n [\n \"search\",\n {\n path: \"search\",\n name: \"search\",\n description: \"Search available Executor tools.\",\n inputTypeScript: \"{ query: string; namespace?: string; limit?: number; offset?: number; }\",\n outputTypeScript:\n \"{ items: ToolDiscoveryResult[]; total: number; hasMore: boolean; nextOffset: number | null; }\",\n typeScriptDefinitions: {\n ToolDiscoveryResult:\n \"{ path: string; name: string; description?: string; integration: string; score: number; }\",\n },\n },\n ],\n [\n \"executor.sources.list\",\n {\n path: \"executor.sources.list\",\n name: \"executor.sources.list\",\n description: \"List configured Executor integrations.\",\n inputTypeScript: \"{ query?: string; limit?: number; offset?: number; }\",\n outputTypeScript:\n \"{ items: ExecutorSourceListItem[]; total: number; hasMore: boolean; nextOffset: number | null; }\",\n typeScriptDefinitions: {\n ExecutorSourceListItem:\n \"{ id: string; name: string; description?: string; kind: string; canRemove?: boolean; canRefresh?: boolean; toolCount: number; }\",\n },\n },\n ],\n [\n \"describe.tool\",\n {\n path: \"describe.tool\",\n name: \"describe.tool\",\n description: \"Describe a tool's compact TypeScript input and output shapes.\",\n inputTypeScript: \"{ path: string; }\",\n outputTypeScript: \"DescribedTool\",\n typeScriptDefinitions: {\n DescribedTool:\n '{ path: string; name: string; description?: string; inputTypeScript?: string; outputTypeScript?: string; typeScriptDefinitions?: { [k: string]: string; }; error?: { code: \"tool_not_found\"; message: string; suggestions?: string[]; }; }',\n },\n },\n ],\n]);\n\nconst newCorrelationId = (): string => {\n // 8-hex-char correlation id; enough entropy to disambiguate within a\n // single deployment without leaking host process info.\n return Math.floor(Math.random() * 0x1_0000_0000)\n .toString(16)\n .padStart(8, \"0\");\n};\n\nconst validationIssues = (value: unknown): readonly unknown[] | null => {\n if (typeof value !== \"object\" || value === null) return null;\n const issues = (value as { readonly issues?: unknown }).issues;\n return Array.isArray(issues) ? issues : null;\n};\n\nconst credentialResolutionToolFailure = (input: {\n readonly label: string;\n readonly message: string;\n readonly reauthRequired?: boolean;\n}) =>\n authToolFailure({\n code: input.reauthRequired === true ? \"oauth_reauth_required\" : \"oauth_refresh_failed\",\n message:\n input.reauthRequired === true\n ? `OAuth connection \"${input.label}\" requires reauthorization: ${input.message}`\n : `OAuth connection \"${input.label}\" could not be resolved: ${input.message}`,\n credential: {\n kind: \"oauth\",\n label: input.label,\n },\n });\n\nconst expectedToolFailure = (value: unknown): ToolError | null => {\n if (Predicate.isTagged(value, \"ToolNotFoundError\") && \"address\" in value) {\n const suggestions =\n \"suggestions\" in value && Array.isArray(value.suggestions)\n ? value.suggestions.map((suggestion) => addressToPath(String(suggestion)))\n : undefined;\n const address = addressToPath(String(value.address));\n return {\n code: \"tool_not_found\",\n message: `Tool not found: ${address}`,\n details: { path: address, ...(suggestions ? { suggestions } : {}) },\n };\n }\n if (Predicate.isTagged(value, \"ToolBlockedError\") && \"address\" in value) {\n return {\n code: \"tool_blocked\",\n message: `Tool blocked by policy: ${addressToPath(String(value.address))}`,\n details: value,\n };\n }\n if (Predicate.isTagged(value, \"ToolInvocationError\")) {\n const issues = validationIssues((value as { readonly cause?: unknown }).cause);\n if (issues) {\n return {\n code: \"invalid_tool_arguments\",\n message: \"Tool arguments did not match the input schema.\",\n details: { issues },\n };\n }\n }\n return null;\n};\n\n/**\n * Extract the integration namespace from a tool path. v2 addresses look like\n * `<integration>.<owner>.<connection>.<tool>`; static fqids look like\n * `<source>.<op>`. We take the first segment as a cheap, non-lookup namespace\n * for the span attribute so it's always populated without a catalog read.\n */\nconst extractNamespace = (path: string): string => {\n const normalized = addressToPath(path);\n const idx = normalized.indexOf(\".\");\n return idx === -1 ? normalized : normalized.slice(0, idx);\n};\n\n/**\n * Bridges QuickJS `tools.<integration>.<owner>.<connection>.<tool>(args)` calls\n * into `executor.execute(address, args)`.\n *\n * Wrapped in `Effect.fn(\"mcp.tool.dispatch\")` so every tool call becomes a\n * span in the Effect tracer. Attributes:\n * - `mcp.tool.name` — full tool path (e.g. \"github.org.main.getRepo\")\n * - `mcp.tool.integration` — first segment of the path (namespace)\n *\n * `mcp.tool.kind` (openapi | mcp | graphql | code) is NOT annotated here\n * because it would require an `integrations.list()` lookup on every invocation.\n * Callers that already know the integration kind can annotate at their own span.\n */\nexport const makeExecutorToolInvoker = (\n executor: Executor,\n options: { readonly invokeOptions: InvokeOptions },\n): SandboxToolInvoker => ({\n invoke: Effect.fn(\"mcp.tool.dispatch\")(function* ({ path, args }) {\n yield* Effect.annotateCurrentSpan({\n \"mcp.tool.name\": path,\n \"mcp.tool.integration\": extractNamespace(path),\n });\n\n const address = pathToAddress(path);\n const result = yield* executor.execute(address, args, options.invokeOptions).pipe(\n Effect.catchTag(\"CredentialResolutionError\", (err) =>\n Effect.succeed(\n credentialResolutionToolFailure({\n label: `${err.integration}.${err.owner}.${err.name}`,\n message: err.message,\n reauthRequired: err.reauthRequired,\n }),\n ),\n ),\n Effect.catchCause((cause) => {\n const err = cause.reasons.find(Cause.isFailReason)?.error;\n const expected = expectedToolFailure(err);\n if (expected) {\n return Effect.succeed(ToolResult.fail(expected));\n }\n if (isElicitationDeclinedError(err)) {\n return Effect.fail(\n new ExecutionToolError({\n message: `Tool \"${addressToPath(String(err.address))}\" requires approval but the request was ${err.action === \"cancel\" ? \"cancelled\" : \"declined\"} by the user.`,\n cause: err,\n }),\n );\n }\n // Any other failure here is an infra/plugin defect. Emit an\n // opaque generic with a correlation id so internal context (URLs\n // with tokens, DB connection strings, file paths in stacks)\n // can't leak through Error.message into the sandbox. The full\n // cause is logged with the same correlation id so operators can\n // still trace the failure.\n const correlationId = newCorrelationId();\n return Effect.logError(\"tool dispatch failed\", cause).pipe(\n Effect.annotateLogs({\n \"executor.correlation_id\": correlationId,\n \"mcp.tool.name\": path,\n }),\n Effect.flatMap(() =>\n Effect.fail(\n new ExecutionToolError({\n message: `${OPAQUE_DEFECT_MESSAGE} [${correlationId}]`,\n cause: err ?? cause,\n }),\n ),\n ),\n );\n }),\n );\n\n // Strict: plugins emit ToolResult<T>. Anything else is treated as a\n // raw success value and wrapped — keeps the sandbox-facing contract\n // uniform without forcing every tiny test plugin to import\n // `ToolResult.ok`.\n // Expected failures resolve through the success channel, so without the\n // outcome annotation the dispatch span reads as healthy even when the\n // caller hit an upstream error or auth wall.\n yield* annotateToolResultOutcome(result);\n if (isToolResult(result)) {\n return result;\n }\n return { ok: true, data: result };\n }),\n});\n\nconst isElicitationDeclinedError = (\n value: unknown,\n): value is {\n readonly _tag: \"ElicitationDeclinedError\";\n readonly address: string;\n readonly action: \"cancel\" | \"decline\";\n} =>\n Predicate.isTagged(value, \"ElicitationDeclinedError\") &&\n value !== null &&\n typeof value === \"object\" &&\n \"address\" in value &&\n typeof value.address === \"string\" &&\n \"action\" in value &&\n (value.action === \"cancel\" || value.action === \"decline\");\n\nexport type ToolDiscoveryResult = {\n readonly path: string;\n readonly name: string;\n readonly description?: string;\n readonly integration: string;\n readonly score: number;\n};\n\nexport type ExecutorSourceListItem = {\n readonly id: string;\n readonly name: string;\n readonly description?: string;\n readonly kind: string;\n readonly canRemove?: boolean;\n readonly canRefresh?: boolean;\n readonly toolCount: number;\n};\n\nexport type ToolDiscoveryInput = {\n readonly executor: Executor;\n readonly query: string;\n readonly namespace?: string;\n readonly limit: number;\n readonly offset: number;\n};\n\nexport interface ToolDiscoveryProvider {\n readonly searchTools: (\n input: ToolDiscoveryInput,\n ) => Effect.Effect<PagedResult<ToolDiscoveryResult>, ExecutionToolError>;\n}\n\n/**\n * Page of results from a list-style discovery tool. Shared by\n * `tools.search` and `tools.executor.sources.list` so the model sees one\n * consistent shape:\n *\n * - `items` — the page (slice).\n * - `total` — count after filtering, before pagination. The model\n * can use this to detect truncation.\n * - `hasMore` — convenience flag for `(offset + items.length) < total`.\n * - `nextOffset` — concrete offset for the next page when `hasMore`,\n * `null` otherwise. Pre-computing it removes a class of\n * off-by-one mistakes when the model paginates.\n */\nexport type PagedResult<T> = {\n readonly items: readonly T[];\n readonly total: number;\n readonly hasMore: boolean;\n readonly nextOffset: number | null;\n};\n\nconst paginate = <T>(all: readonly T[], offset: number, limit: number): PagedResult<T> => {\n const total = all.length;\n const start = Math.min(Math.max(offset, 0), total);\n const items = all.slice(start, start + limit);\n const consumed = start + items.length;\n const hasMore = consumed < total;\n return {\n items,\n total,\n hasMore,\n nextOffset: hasMore ? consumed : null,\n };\n};\n\n/** What `searchTools` ranks over — the sandbox-callable path plus the v2\n * identity fields a query can match against. */\ntype SearchableTool = {\n readonly path: string;\n readonly integration: string;\n readonly name: string;\n readonly description?: string;\n};\n\nconst toSearchableTool = (tool: Tool): SearchableTool => ({\n path: addressToPath(String(tool.address)),\n integration: String(tool.integration),\n name: String(tool.name),\n description: tool.description,\n});\n\ntype PreparedField = {\n readonly raw: string;\n readonly tokens: readonly string[];\n};\n\nconst SEARCH_FIELD_WEIGHTS = {\n path: 12,\n integration: 8,\n name: 10,\n description: 5,\n} as const;\n\nconst normalizeSearchText = (value: string): string =>\n value\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .replace(/[_./:-]+/g, \" \")\n .toLowerCase()\n .trim();\n\nconst tokenizeSearchText = (value: string): string[] =>\n normalizeSearchText(value)\n .split(/[^a-z0-9]+/)\n .map((token) => token.trim())\n .filter(Boolean);\n\nconst prepareField = (value?: string): PreparedField => ({\n raw: normalizeSearchText(value ?? \"\"),\n tokens: tokenizeSearchText(value ?? \"\"),\n});\n\nconst scorePreparedField = (\n query: string,\n queryTokens: readonly string[],\n field: PreparedField,\n weight: number,\n): {\n readonly score: number;\n readonly matchedTokens: ReadonlySet<string>;\n readonly exactPhraseMatch: boolean;\n} => {\n if (field.raw.length === 0) {\n return {\n score: 0,\n matchedTokens: new Set<string>(),\n exactPhraseMatch: false,\n };\n }\n\n let score = 0;\n const matchedTokens = new Set<string>();\n const exactPhraseMatch = query.length > 0 && field.raw.includes(query);\n\n if (query.length > 0) {\n if (field.raw === query) {\n score += weight * 14;\n } else if (field.raw.startsWith(query)) {\n score += weight * 9;\n } else if (exactPhraseMatch) {\n score += weight * 6;\n }\n }\n\n for (const token of queryTokens) {\n if (field.tokens.includes(token)) {\n score += weight * 4;\n matchedTokens.add(token);\n continue;\n }\n\n if (\n field.tokens.some((candidate) => candidate.startsWith(token) || token.startsWith(candidate))\n ) {\n score += weight * 2;\n matchedTokens.add(token);\n continue;\n }\n\n if (field.raw.includes(token)) {\n score += weight;\n matchedTokens.add(token);\n }\n }\n\n return {\n score,\n matchedTokens,\n exactPhraseMatch,\n };\n};\n\nconst matchesNamespace = (tool: SearchableTool, namespace?: string): boolean => {\n if (!namespace || normalizeSearchText(namespace).length === 0) {\n return true;\n }\n\n const namespaceTokens = tokenizeSearchText(namespace);\n if (namespaceTokens.length === 0) {\n return true;\n }\n\n const integrationTokens = tokenizeSearchText(tool.integration);\n const pathTokens = tokenizeSearchText(tool.path);\n\n const isPrefixMatch = (tokens: readonly string[]): boolean =>\n namespaceTokens.every((token, index) => tokens[index] === token);\n\n return isPrefixMatch(integrationTokens) || isPrefixMatch(pathTokens);\n};\n\nconst scoreToolMatch = (tool: SearchableTool, query: string): ToolDiscoveryResult | null => {\n const normalizedQuery = normalizeSearchText(query);\n const queryTokens = tokenizeSearchText(query);\n\n if (normalizedQuery.length === 0 || queryTokens.length === 0) {\n return null;\n }\n\n const path = prepareField(tool.path);\n const integration = prepareField(tool.integration);\n const name = prepareField(tool.name);\n const description = prepareField(tool.description);\n\n const fieldScores = [\n scorePreparedField(normalizedQuery, queryTokens, path, SEARCH_FIELD_WEIGHTS.path),\n scorePreparedField(normalizedQuery, queryTokens, integration, SEARCH_FIELD_WEIGHTS.integration),\n scorePreparedField(normalizedQuery, queryTokens, name, SEARCH_FIELD_WEIGHTS.name),\n scorePreparedField(normalizedQuery, queryTokens, description, SEARCH_FIELD_WEIGHTS.description),\n ];\n\n const matchedTokens = new Set<string>();\n let score = 0;\n let exactPhraseMatch = false;\n\n for (const fieldScore of fieldScores) {\n score += fieldScore.score;\n exactPhraseMatch ||= fieldScore.exactPhraseMatch;\n for (const token of fieldScore.matchedTokens) {\n matchedTokens.add(token);\n }\n }\n\n if (matchedTokens.size === 0) {\n return null;\n }\n\n const coverage = matchedTokens.size / queryTokens.length;\n const minimumCoverage = queryTokens.length <= 2 ? 1 : 0.6;\n\n if (coverage < minimumCoverage && !exactPhraseMatch) {\n return null;\n }\n\n if (coverage === 1) {\n score += 25;\n } else {\n score += Math.round(coverage * 10);\n }\n\n if (path.tokens[0] === queryTokens[0] || name.tokens[0] === queryTokens[0]) {\n score += 8;\n }\n\n if (\n normalizeSearchText(tool.path) === normalizedQuery ||\n normalizeSearchText(tool.name) === normalizedQuery\n ) {\n score += 20;\n }\n\n return {\n path: tool.path,\n name: tool.name,\n description: tool.description,\n integration: tool.integration,\n score,\n };\n};\n\n/** What `tools.search()` calls inside the sandbox. */\nexport const searchTools = Effect.fn(\"executor.tools.search\")(function* (\n executor: Executor,\n query: string,\n limit = 12,\n options?: { readonly namespace?: string; readonly offset?: number },\n) {\n const offset = options?.offset ?? 0;\n yield* Effect.annotateCurrentSpan({\n \"executor.search.query_length\": query.length,\n \"executor.search.limit\": limit,\n \"executor.search.offset\": offset,\n ...(options?.namespace ? { \"executor.search.namespace\": options.namespace } : {}),\n });\n\n const empty: PagedResult<ToolDiscoveryResult> = {\n items: [],\n total: 0,\n hasMore: false,\n nextOffset: null,\n };\n\n if (normalizeSearchText(query).length === 0) {\n return empty;\n }\n\n const all = yield* executor.tools.list({ includeAnnotations: false }).pipe(\n Effect.mapError(\n (cause) =>\n new ExecutionToolError({\n message: \"Failed to list tools for search\",\n cause,\n }),\n ),\n );\n const searchable = all.map(toSearchableTool);\n const ranked = searchable\n .filter((tool: SearchableTool) => matchesNamespace(tool, options?.namespace))\n .map((tool: SearchableTool) => scoreToolMatch(tool, query))\n .filter(Predicate.isNotNull)\n .sort((left, right) => right.score - left.score || left.path.localeCompare(right.path));\n\n const page = paginate(ranked, offset, limit);\n\n yield* Effect.annotateCurrentSpan({\n \"executor.search.candidate_count\": all.length,\n \"executor.search.match_count\": ranked.length,\n \"executor.search.result_count\": page.items.length,\n \"executor.search.has_more\": page.hasMore,\n });\n return page;\n});\n\nexport const defaultToolDiscoveryProvider: ToolDiscoveryProvider = {\n searchTools: ({ executor, query, namespace, limit, offset }) =>\n searchTools(executor, query, limit, { namespace, offset }),\n};\n\n/** What `tools.executor.sources.list()` calls inside the sandbox. v2: the\n * \"sources\" are the integration catalog; tool counts come from the\n * per-connection tool list. */\nexport const listExecutorSources = Effect.fn(\"executor.sources.list\")(function* (\n executor: Executor,\n options?: {\n readonly query?: string;\n readonly limit?: number;\n readonly offset?: number;\n },\n) {\n const normalizedQuery = normalizeSearchText(options?.query ?? \"\");\n const limit = options?.limit ?? 50;\n const offset = options?.offset ?? 0;\n const integrations = yield* executor.integrations.list().pipe(\n Effect.mapError(\n (cause) =>\n new ExecutionToolError({\n message: \"Failed to list executor integrations\",\n cause,\n }),\n ),\n );\n\n const filtered =\n normalizedQuery.length === 0\n ? integrations\n : integrations.filter((integration: Integration) => {\n const haystack = normalizeSearchText(\n [String(integration.slug), integration.description, integration.kind].join(\" \"),\n );\n return tokenizeSearchText(normalizedQuery).every((token) => haystack.includes(token));\n });\n\n // Single query for all tools, then count per integration in memory.\n const allTools = yield* executor.tools.list({ includeAnnotations: false }).pipe(\n Effect.mapError(\n (cause) =>\n new ExecutionToolError({\n message: \"Failed to list tools for integration counts\",\n cause,\n }),\n ),\n );\n const toolCountByIntegration = new Map<string, number>();\n for (const tool of allTools) {\n const key = String(tool.integration);\n toolCountByIntegration.set(key, (toolCountByIntegration.get(key) ?? 0) + 1);\n }\n\n const sortedWithCounts = filtered\n .map(\n (integration: Integration) =>\n ({\n id: String(integration.slug),\n name: String(integration.slug),\n // The integration's catalog description — user-editable context the\n // agent can use to pick a source. Omitted when it just repeats the\n // slug or display name (no information beyond identity).\n ...(integration.description &&\n integration.description.toLowerCase() !== String(integration.slug).toLowerCase() &&\n integration.description.toLowerCase() !== integration.name.toLowerCase()\n ? { description: integration.description }\n : {}),\n kind: integration.kind,\n canRemove: integration.canRemove,\n canRefresh: integration.canRefresh,\n toolCount: toolCountByIntegration.get(String(integration.slug)) ?? 0,\n }) satisfies ExecutorSourceListItem,\n )\n .sort((left, right) => left.name.localeCompare(right.name) || left.id.localeCompare(right.id));\n\n const page = paginate(sortedWithCounts, offset, limit);\n\n yield* Effect.annotateCurrentSpan({\n \"executor.sources.candidate_count\": integrations.length,\n \"executor.sources.match_count\": sortedWithCounts.length,\n \"executor.sources.result_count\": page.items.length,\n \"executor.sources.has_more\": page.hasMore,\n });\n return page;\n});\n\n/** What `tools.describe.tool()` calls inside the sandbox. */\nexport const describeTool = Effect.fn(\"executor.tools.describe\")(function* (\n executor: Executor,\n path: string,\n) {\n yield* Effect.annotateCurrentSpan({ \"mcp.tool.name\": path });\n\n const builtin = BUILTIN_TOOL_DESCRIPTIONS.get(path);\n if (builtin) return builtin;\n\n const address = pathToAddress(path);\n\n // Single tools.schema() call — it already fetches the tool row\n // internally. No need to also call tools.list() just for name/description.\n const schema: ToolSchemaView | null = yield* executor.tools.schema(address);\n\n // tools.schema() returns null if the tool doesn't exist. Mirror the\n // invoke path's tool_not_found shape (error + suggestions) instead of a\n // bare stub — a silent `{ path, name }` reads as \"tool exists, schema\n // unavailable\" and sends callers down the wrong debugging path.\n if (schema === null) {\n const lastDot = path.lastIndexOf(\".\");\n const leaf = lastDot === -1 ? path : path.slice(lastDot + 1);\n const scoped = yield* searchTools(executor, leaf, TOOL_DESCRIBE_SUGGESTION_LIMIT, {\n namespace: extractNamespace(path),\n });\n const matches =\n scoped.items.length > 0\n ? scoped.items\n : (yield* searchTools(executor, leaf, TOOL_DESCRIBE_SUGGESTION_LIMIT)).items;\n const suggestions = matches.map((item) => item.path);\n const notFound: DescribedTool = {\n path,\n name: path,\n error: {\n code: \"tool_not_found\",\n message: `Tool not found: ${path}`,\n ...(suggestions.length > 0 ? { suggestions } : {}),\n },\n };\n return notFound;\n }\n\n // The schema's address is the tool address; name/description come from the\n // tool row which tools.schema() already loaded.\n const described: DescribedTool = {\n path,\n name: schema.name ?? path,\n description: schema.description,\n inputTypeScript: schema.inputTypeScript,\n outputTypeScript: wrapOutputTypeScript(schema.outputTypeScript),\n typeScriptDefinitions: withToolResultDefinitions(schema.typeScriptDefinitions),\n };\n return described;\n});\n","import { Effect } from \"effect\";\nimport type { Connection, Integration, Executor } from \"@executor-js/sdk/core\";\n\n/**\n * Builds a tool description dynamically.\n *\n * Structure:\n * 1. Workflow (top — critical, least likely to be truncated)\n * 2. Available connection prefixes (bottom)\n *\n * v2: callable API tools are scoped by saved connections. A tool's sandbox\n * address is `tools.<integration>.<owner>.<connection>.<tool>`, so the useful\n * inventory is the connection prefix rather than only the integration slug.\n */\nexport const buildExecuteDescription = (executor: Executor): Effect.Effect<string> =>\n Effect.gen(function* () {\n const connections: readonly Connection[] = yield* executor.connections.list().pipe(\n // oxlint-disable-next-line executor/no-effect-escape-hatch -- boundary: ExecutionEngine.getDescription currently exposes no error channel; engine typed-error widening is covered separately\n Effect.orDie,\n Effect.withSpan(\"executor.connections.list\"),\n );\n const integrations: readonly Integration[] = yield* executor.integrations.list().pipe(\n // oxlint-disable-next-line executor/no-effect-escape-hatch -- boundary: same getDescription error-channel constraint as connections.list above\n Effect.orDie,\n Effect.withSpan(\"executor.integrations.list\"),\n );\n\n const description = yield* Effect.sync(() =>\n formatDescription(connections.map((connection) => connectionEntry(connection, integrations))),\n ).pipe(\n Effect.withSpan(\"schema.compile.description\", {\n attributes: { \"executor.connection_count\": connections.length },\n }),\n );\n\n yield* Effect.annotateCurrentSpan({\n \"executor.connection_count\": connections.length,\n \"schema.kind\": \"execute\",\n // Connection inventory so a failing session build (which runs this during\n // init) names the callable prefixes it resolved without listing tools.\n \"executor.connection_addresses\": connections\n .map((connection) => connectionPath(connection))\n .slice(0, 50)\n .join(\",\"),\n \"executor.connection_integrations\": [\n ...new Set(connections.map((connection) => String(connection.integration))),\n ].join(\",\"),\n \"executor.connection_owners\": [\n ...new Set(connections.map((connection) => connection.owner)),\n ].join(\",\"),\n });\n\n return description;\n }).pipe(Effect.withSpan(\"schema.describe.execute\"));\n\nconst connectionPath = (connection: Connection): string => {\n const address = String(connection.address);\n return address.startsWith(\"tools.\") ? address.slice(\"tools.\".length) : address;\n};\n\n/** One inventory line: the callable prefix plus the best available context.\n * Connection description wins (the user wrote it about THIS credential);\n * otherwise the integration description, unless it is just the slug again. */\ninterface ConnectionInventoryEntry {\n readonly prefix: string;\n readonly description?: string;\n}\n\nconst inventoryNote = (\n text: string | null | undefined,\n identityEchoes: readonly string[],\n): string | undefined => {\n const firstLine = (text ?? \"\").split(\"\\n\", 1)[0]!.trim();\n if (firstLine.length === 0) return undefined;\n // A description that just restates the slug or display name carries no\n // information beyond identity — drop it from the inventory line.\n if (identityEchoes.some((echo) => firstLine.toLowerCase() === echo.toLowerCase())) {\n return undefined;\n }\n return firstLine.length > 140 ? `${firstLine.slice(0, 139)}…` : firstLine;\n};\n\nconst connectionEntry = (\n connection: Connection,\n integrations: readonly Integration[],\n): ConnectionInventoryEntry => {\n const slug = String(connection.integration);\n const integration = integrations.find((candidate) => String(candidate.slug) === slug);\n const identityEchoes = [slug, ...(integration ? [integration.name] : [])];\n return {\n prefix: connectionPath(connection),\n description:\n inventoryNote(connection.description, identityEchoes) ??\n inventoryNote(integration?.description, identityEchoes),\n };\n};\n\nconst formatDescription = (connectionEntries: readonly ConnectionInventoryEntry[]): string => {\n const lines: string[] = [\n \"Execute TypeScript in a sandboxed runtime with access to configured API tools.\",\n \"\",\n \"## Workflow\",\n \"\",\n '1. `const { items: matches } = await tools.search({ query: \"<intent + key nouns>\", limit: 12 });`',\n '2. `const path = matches[0]?.path; if (!path) return \"No matching tools found.\";`',\n \"3. `const details = await tools.describe.tool({ path });`\",\n \"4. Use `details.inputTypeScript` / `details.outputTypeScript` and `details.typeScriptDefinitions` for compact shapes.\",\n \"5. Use `tools.executor.coreTools.connections.list({})` when you need live saved-connection inventory.\",\n \"6. Call the tool: `const result = await tools.<path>(input);`\",\n \"\",\n \"## Rules\",\n \"\",\n \"- `tools.search()` returns paginated, ranked matches: `{ items, total, hasMore, nextOffset }`. Best-first. Use short intent phrases like `github issues`, `repo details`, or `create calendar event`.\",\n '- When you already know the namespace, narrow with `tools.search({ namespace: \"github\", query: \"issues\" })`.',\n \"- `tools.executor.coreTools.connections.list({})` returns saved connections with `{ address, integration, owner, name, ... }`. The `address` field includes the leading `tools.` root.\",\n \"- Tool calls return a value union: `{ ok: true, data }` for success or `{ ok: false, error: { code, message, status?, details?, retryable? } }` for expected tool/domain failures. Branch on `result.ok`.\",\n \"- `data` is the upstream payload itself. HTTP-backed tools (OpenAPI) also set `http: { status, headers }` beside `data` — read `result.http?.headers` for pagination (Link) or rate-limit headers.\",\n \"- Use `emit(value)` to append user-visible output and return `undefined`. Plain values become MCP text content. MCP content blocks are forwarded as-is. `ToolFile` values are rendered by MIME.\",\n '- File-returning tools may return `ToolFile` values: `{ _tag: \"ToolFile\", name?, mimeType, encoding: \"base64\", data, byteLength }`. Emit any attachment with `emit(result.data)`.',\n '- To emit MCP-native content directly, pass an MCP content block to `emit(...)`, such as `{ type: \"image\", data, mimeType }`, `{ type: \"audio\", data, mimeType }`, `{ type: \"text\", text }`, `{ type: \"resource\", resource }`, or `{ type: \"resource_link\", uri, name, ... }`.',\n \"- `emit(ToolFile)` is MIME-based: `image/*` becomes MCP image content, `audio/*` becomes MCP audio content, text-like files become decoded text, and other binary files become embedded MCP resources.\",\n \"- `return` is only for ordinary structured data. Returning a `ToolFile`, a `ToolResult`, an MCP content block, or a bare base64 string does not emit content to the MCP client.\",\n \"- Some providers, including Gmail, return attachment bytes without a public URL. To send that attachment to another API from code, decode `ToolFile.data` from base64 and pass the bytes to that API's upload/file input.\",\n \"- If `tools.search()` returns `hasMore: true` and you didn't find what you need, fetch the next page: `tools.search({ query, offset: nextOffset, limit })`.\",\n \"- Always use the full address when calling tools: `tools.<integration>.<owner>.<connection>.<tool>(args)`. The `path` returned by `tools.search()` / `tools.describe.tool()` is already the exact path under `tools` — call `tools[path]` rather than guessing segments.\",\n \"- The `tools` object is a lazy proxy — `Object.keys(tools)` won't work. Use `tools.search()` or `tools.executor.coreTools.connections.list({})` instead.\",\n '- Pass an object to system tools, e.g. `tools.search({ query: \"...\" })`, `tools.executor.coreTools.connections.list({})`, and `tools.describe.tool({ path })`.',\n '- `tools.describe.tool()` returns compact TypeScript shapes. Use `inputTypeScript`, `outputTypeScript`, and `typeScriptDefinitions`. If the path doesn\\'t resolve, the result carries `error: { code: \"tool_not_found\", suggestions }` — use a suggestion instead of retrying the same path.',\n \"- For tools that return large collections (e.g. `getStates`, `getAll`), filter results in code rather than calling per-item tools.\",\n \"- Do not use `fetch` — all API calls go through `tools.*`.\",\n \"- If execution pauses for interaction, resume it with the returned `resumePayload`.\",\n \"- TypeScript type syntax (`: T`, `as T`, generics, interfaces, type aliases) is stripped before execution — feel free to write idiomatic TypeScript using the shapes from `tools.describe.tool()`. Decorators and `enum` are not supported.\",\n ];\n\n if (connectionEntries.length > 0) {\n lines.push(\"\");\n lines.push(\"## Available connection prefixes\");\n lines.push(\"\");\n lines.push(\"These are paths under `tools.`; append the final tool segment.\");\n const sorted = [...connectionEntries]\n .sort((a, b) => a.prefix.localeCompare(b.prefix))\n .slice(0, 50);\n for (const entry of sorted) {\n lines.push(\n entry.description\n ? `- \\`${entry.prefix}\\` — ${entry.description}`\n : `- \\`${entry.prefix}\\``,\n );\n }\n if (connectionEntries.length > sorted.length) {\n lines.push(`- ... ${connectionEntries.length - sorted.length} more`);\n }\n }\n\n return lines.join(\"\\n\");\n};\n","import { Deferred, Effect, Fiber, Predicate, Queue } from \"effect\";\nimport type * as Cause from \"effect/Cause\";\nimport * as Exit from \"effect/Exit\";\n\nimport type {\n Executor,\n InvokeOptions,\n ElicitationResponse,\n ElicitationHandler,\n ElicitationContext,\n} from \"@executor-js/sdk/core\";\nimport { CodeExecutionError } from \"@executor-js/codemode-core\";\nimport type { CodeExecutor, ExecuteResult, SandboxToolInvoker } from \"@executor-js/codemode-core\";\n\nimport {\n defaultToolDiscoveryProvider,\n makeExecutorToolInvoker,\n listExecutorSources,\n describeTool,\n type ToolDiscoveryProvider,\n} from \"./tool-invoker\";\nimport { ExecutionToolError } from \"./errors\";\nimport { buildExecuteDescription } from \"./description\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type ExecutionEngineConfig<E extends Cause.YieldableError = CodeExecutionError> = {\n readonly executor: Executor;\n readonly codeExecutor: CodeExecutor<E>;\n readonly toolDiscoveryProvider?: ToolDiscoveryProvider;\n};\n\nexport type ExecutionResult =\n | { readonly status: \"completed\"; readonly result: ExecuteResult }\n | { readonly status: \"paused\"; readonly execution: PausedExecution };\n\nexport type PausedExecution = {\n readonly id: string;\n readonly elicitationContext: ElicitationContext;\n};\n\n/** Internal representation with Effect runtime state for pause/resume. */\ntype InternalPausedExecution<E> = PausedExecution & {\n readonly response: Deferred.Deferred<typeof ElicitationResponse.Type>;\n readonly fiber: Fiber.Fiber<ExecuteResult, E>;\n readonly pauseQueue: Queue.Queue<InternalPausedExecution<E>>;\n};\n\nexport type ResumeResponse = {\n readonly action: \"accept\" | \"decline\" | \"cancel\";\n readonly content?: Record<string, unknown>;\n};\n\n// ---------------------------------------------------------------------------\n// Result formatting\n// ---------------------------------------------------------------------------\n\nconst MAX_PREVIEW_CHARS = 30_000;\n\nconst truncate = (value: string, max: number): string =>\n value.length > max\n ? `${value.slice(0, max)}\\n... [truncated ${value.length - max} chars]`\n : value;\n\nexport const formatExecuteResult = (\n result: ExecuteResult,\n): {\n text: string;\n structured: Record<string, unknown>;\n isError: boolean;\n} => {\n const resultText =\n result.result != null\n ? typeof result.result === \"string\"\n ? result.result\n : JSON.stringify(result.result, null, 2)\n : null;\n\n const logText = result.logs && result.logs.length > 0 ? result.logs.join(\"\\n\") : null;\n\n if (result.error) {\n const parts = [`Error: ${result.error}`, ...(logText ? [`\\nLogs:\\n${logText}`] : [])];\n return {\n text: truncate(parts.join(\"\\n\"), MAX_PREVIEW_CHARS),\n structured: { status: \"error\", error: result.error, logs: result.logs ?? [] },\n isError: true,\n };\n }\n\n const parts = [\n ...(resultText ? [truncate(resultText, MAX_PREVIEW_CHARS)] : [\"(no result)\"]),\n ...(logText ? [`\\nLogs:\\n${logText}`] : []),\n ];\n return {\n text: parts.join(\"\\n\"),\n structured: { status: \"completed\", result: result.result ?? null, logs: result.logs ?? [] },\n isError: false,\n };\n};\n\nexport const formatPausedExecution = (\n paused: PausedExecution,\n): {\n text: string;\n structured: Record<string, unknown>;\n} => {\n const req = paused.elicitationContext.request;\n const lines: string[] = [`Execution paused: ${req.message}`];\n const isUrlElicitation = Predicate.isTagged(req, \"UrlElicitation\");\n const isFormElicitation = Predicate.isTagged(req, \"FormElicitation\");\n const requestedSchema = isFormElicitation ? req.requestedSchema : undefined;\n const hasRequestedSchema =\n requestedSchema !== undefined && Object.keys(requestedSchema).length > 0;\n const instructions = isUrlElicitation\n ? `The user needs to open this URL in a browser and complete the flow. After the user finishes, call the resume tool with executionId \"${paused.id}\" and action \"accept\".`\n : hasRequestedSchema\n ? `Ask the user for values matching requestedSchema. Then call the resume tool with executionId \"${paused.id}\", action \"accept\", and content matching requestedSchema. If the user declines, call resume with action \"decline\" or \"cancel\".`\n : `This is a model-side confirmation gate; there is no browser form to open. Ask the user whether to approve the paused tool call. If the user approves, call the resume tool with executionId \"${paused.id}\" and action \"accept\". If the user declines, call resume with action \"decline\" or \"cancel\".`;\n\n if (isUrlElicitation) {\n lines.push(`\\nOpen this URL in a browser:\\n${req.url}`);\n lines.push('\\nAfter the browser flow, call the resume tool with action \"accept\".');\n } else if (hasRequestedSchema) {\n lines.push(\n \"\\nAsk the user for a response matching the requested schema, then call the resume tool.\",\n );\n lines.push(`\\nRequested schema:\\n${JSON.stringify(requestedSchema, null, 2)}`);\n } else {\n lines.push(\n '\\nThis is a model-side confirmation gate; no browser form is waiting. Ask the user whether to approve, then call the resume tool with action \"accept\", \"decline\", or \"cancel\".',\n );\n }\n\n lines.push(`\\nexecutionId: ${paused.id}`);\n lines.push(`\\ninstructions: ${instructions}`);\n\n return {\n text: lines.join(\"\\n\"),\n structured: {\n status: \"waiting_for_interaction\",\n executionId: paused.id,\n interaction: {\n kind: isUrlElicitation ? \"url\" : \"form\",\n message: req.message,\n instructions,\n address: String(paused.elicitationContext.address),\n args: paused.elicitationContext.args,\n ...(isUrlElicitation ? { url: req.url } : {}),\n ...(isFormElicitation ? { requestedSchema: req.requestedSchema } : {}),\n },\n },\n };\n};\n\n// ---------------------------------------------------------------------------\n// Full invoker (base + discover + describe)\n// ---------------------------------------------------------------------------\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst readOptionalLimit = (value: unknown, toolName: string): number | ExecutionToolError => {\n if (value === undefined) {\n return 12;\n }\n\n if (typeof value !== \"number\" || !Number.isFinite(value) || value <= 0) {\n return new ExecutionToolError({\n message: `${toolName} limit must be a positive number when provided`,\n });\n }\n\n return Math.floor(value);\n};\n\nconst readOptionalOffset = (value: unknown, toolName: string): number | ExecutionToolError => {\n if (value === undefined) {\n return 0;\n }\n\n if (typeof value !== \"number\" || !Number.isFinite(value) || value < 0) {\n return new ExecutionToolError({\n message: `${toolName} offset must be a non-negative number when provided`,\n });\n }\n\n return Math.floor(value);\n};\n\nconst makeFullInvoker = (\n executor: Executor,\n invokeOptions: InvokeOptions,\n toolDiscoveryProvider: ToolDiscoveryProvider,\n): SandboxToolInvoker => {\n const base = makeExecutorToolInvoker(executor, { invokeOptions });\n return {\n invoke: ({ path, args }) => {\n if (path === \"search\") {\n if (!isRecord(args)) {\n return Effect.fail(\n new ExecutionToolError({\n message:\n \"tools.search expects an object: { query?: string; namespace?: string; limit?: number; offset?: number }\",\n }),\n );\n }\n\n if (args.query !== undefined && typeof args.query !== \"string\") {\n return Effect.fail(\n new ExecutionToolError({\n message: \"tools.search query must be a string when provided\",\n }),\n );\n }\n\n if (args.namespace !== undefined && typeof args.namespace !== \"string\") {\n return Effect.fail(\n new ExecutionToolError({\n message: \"tools.search namespace must be a string when provided\",\n }),\n );\n }\n\n const limit = readOptionalLimit(args.limit, \"tools.search\");\n if (Predicate.isTagged(limit, \"ExecutionToolError\")) {\n return Effect.fail(limit);\n }\n\n const offset = readOptionalOffset(args.offset, \"tools.search\");\n if (Predicate.isTagged(offset, \"ExecutionToolError\")) {\n return Effect.fail(offset);\n }\n\n return toolDiscoveryProvider\n .searchTools({\n executor,\n query: args.query ?? \"\",\n limit,\n namespace: args.namespace,\n offset,\n })\n .pipe(\n Effect.withSpan(\"mcp.tool.dispatch\", {\n attributes: { \"mcp.tool.name\": path, \"executor.tool.builtin\": true },\n }),\n );\n }\n if (path === \"executor.sources.list\") {\n if (args !== undefined && !isRecord(args)) {\n return Effect.fail(\n new ExecutionToolError({\n message:\n \"tools.executor.sources.list expects an object: { query?: string; limit?: number; offset?: number }\",\n }),\n );\n }\n\n if (isRecord(args) && args.query !== undefined && typeof args.query !== \"string\") {\n return Effect.fail(\n new ExecutionToolError({\n message: \"tools.executor.sources.list query must be a string when provided\",\n }),\n );\n }\n\n const limit = readOptionalLimit(\n isRecord(args) ? args.limit : undefined,\n \"tools.executor.sources.list\",\n );\n if (Predicate.isTagged(limit, \"ExecutionToolError\")) {\n return Effect.fail(limit);\n }\n\n const offset = readOptionalOffset(\n isRecord(args) ? args.offset : undefined,\n \"tools.executor.sources.list\",\n );\n if (Predicate.isTagged(offset, \"ExecutionToolError\")) {\n return Effect.fail(offset);\n }\n\n return listExecutorSources(executor, {\n query: isRecord(args) && typeof args.query === \"string\" ? args.query : undefined,\n limit,\n offset,\n }).pipe(\n Effect.withSpan(\"mcp.tool.dispatch\", {\n attributes: { \"mcp.tool.name\": path, \"executor.tool.builtin\": true },\n }),\n );\n }\n if (path === \"describe.tool\") {\n if (!isRecord(args)) {\n return Effect.fail(\n new ExecutionToolError({\n message: \"tools.describe.tool expects an object: { path: string }\",\n }),\n );\n }\n\n if (typeof args.path !== \"string\" || args.path.trim().length === 0) {\n return Effect.fail(new ExecutionToolError({ message: \"describe.tool requires a path\" }));\n }\n\n if (\"includeSchemas\" in args) {\n return Effect.fail(\n new ExecutionToolError({\n message: \"tools.describe.tool no longer accepts includeSchemas\",\n }),\n );\n }\n\n return describeTool(executor, args.path).pipe(\n Effect.withSpan(\"mcp.tool.dispatch\", {\n attributes: {\n \"mcp.tool.name\": path,\n \"executor.tool.builtin\": true,\n \"executor.tool.target_path\": args.path,\n },\n }),\n );\n }\n return base.invoke({ path, args });\n },\n };\n};\n\n// ---------------------------------------------------------------------------\n// Execution Engine\n// ---------------------------------------------------------------------------\n\nexport type ExecutionEngine<E extends Cause.YieldableError = CodeExecutionError> = {\n /**\n * Execute code with elicitation handled inline by the provided handler.\n * Use this when the host supports elicitation (e.g. MCP with elicitation capability).\n *\n * Fails with the code executor's typed error `E` (defaults to\n * `CodeExecutionError`). Runtimes surface their own `Data.TaggedError`\n * subclass, which flows through here unchanged.\n */\n readonly execute: (\n code: string,\n options: { readonly onElicitation: ElicitationHandler },\n ) => Effect.Effect<ExecuteResult, E>;\n\n /**\n * Execute code, intercepting the first elicitation as a pause point.\n * Use this when the host doesn't support inline elicitation.\n * Returns either a completed result or a paused execution that can be resumed.\n */\n readonly executeWithPause: (code: string) => Effect.Effect<ExecutionResult, E>;\n\n /**\n * Resume a paused execution. Returns a completed result, a new pause, or\n * null if the executionId was not found.\n */\n readonly resume: (\n executionId: string,\n response: ResumeResponse,\n ) => Effect.Effect<ExecutionResult | null, E>;\n\n /**\n * Inspect a paused execution without resuming it. Returns null if the id is\n * unknown or has already been resumed.\n */\n readonly getPausedExecution: (executionId: string) => Effect.Effect<PausedExecution | null>;\n\n /**\n * Get the dynamic tool description (workflow + namespaces).\n */\n readonly getDescription: Effect.Effect<string>;\n};\n\nexport const createExecutionEngine = <E extends Cause.YieldableError = CodeExecutionError>(\n config: ExecutionEngineConfig<E>,\n): ExecutionEngine<E> => {\n const { executor, codeExecutor, toolDiscoveryProvider = defaultToolDiscoveryProvider } = config;\n const pausedExecutions = new Map<string, InternalPausedExecution<E>>();\n // Outcomes of executions that already settled (resumed to completion, hit a\n // new pause, or died while paused). MCP clients retry `resume` when a\n // response gets lost in transit; without this cache the retry of an\n // already-delivered resume answers \"no paused execution\" (observed in\n // production seconds after a successful resume). Bounded FIFO — pause\n // volume is tiny (human approvals), so a small window is plenty.\n const settledOutcomes = new Map<string, Exit.Exit<ExecutionResult, E>>();\n const SETTLED_OUTCOME_LIMIT = 64;\n // Resumes whose outcome is still being computed, so a concurrent duplicate\n // awaits the same result instead of missing the (already-consumed) pause.\n const pendingResumes = new Map<string, Deferred.Deferred<ExecutionResult, E>>();\n\n // Exits (not just successes) so a replayed failure re-fails through the\n // typed channel — hosts render engine failures opaquely, and a replay must\n // not bypass that by flattening the cause into result text.\n const recordSettledOutcome = (executionId: string, exit: Exit.Exit<ExecutionResult, E>): void => {\n settledOutcomes.set(executionId, exit);\n while (settledOutcomes.size > SETTLED_OUTCOME_LIMIT) {\n const oldest = settledOutcomes.keys().next().value;\n if (oldest === undefined) break;\n settledOutcomes.delete(oldest);\n }\n };\n\n /**\n * Race a running fiber against the pause queue. Returns when either\n * the fiber completes or an elicitation handler fires (whichever\n * comes first). Re-used by both executeWithPause and resume.\n *\n * `Effect.raceFirst` (not `Effect.race`) — `race` has prefer-success\n * semantics in Effect v4 (\"first successful result\"), which means a\n * fiber failure waits indefinitely for the pause Deferred to succeed.\n * For a fast `codeExecutor.execute` failure (e.g. a syntax error\n * inside the dynamic worker) the pause signal never fires, so the\n * outer Effect hangs until the upstream client gives up. `raceFirst`\n * settles on whichever side completes first, success or failure.\n */\n const awaitCompletionOrPause = (\n fiber: Fiber.Fiber<ExecuteResult, E>,\n pauseQueue: Queue.Queue<InternalPausedExecution<E>>,\n ): Effect.Effect<ExecutionResult, E> =>\n Effect.raceFirst(\n Fiber.join(fiber).pipe(\n Effect.map((result): ExecutionResult => ({ status: \"completed\", result })),\n ),\n Queue.take(pauseQueue).pipe(\n Effect.map((paused): ExecutionResult => ({ status: \"paused\", execution: paused })),\n ),\n );\n\n /**\n * Start an execution in pause/resume mode.\n *\n * The sandbox is forked as a daemon because paused executions can outlive the\n * caller scope that returned the first pause, such as an HTTP request handler.\n */\n const startPausableExecution = Effect.fn(\"mcp.execute\")(function* (code: string) {\n yield* Effect.annotateCurrentSpan({\n \"mcp.execute.mode\": \"pausable\",\n \"mcp.execute.code_length\": code.length,\n });\n\n // Queue preserves pauses that arrive before the previous approval has\n // returned to the caller, which can happen with concurrent tool calls.\n const pauseQueue = yield* Queue.unbounded<InternalPausedExecution<E>>();\n\n // Will be set once the fiber is forked.\n let fiber: Fiber.Fiber<ExecuteResult, E>;\n\n const elicitationHandler: ElicitationHandler = (ctx) =>\n Effect.gen(function* () {\n const responseDeferred = yield* Deferred.make<typeof ElicitationResponse.Type>();\n // Globally unique — engine instances are rebuilt on host restarts\n // (Durable Object cold restores, redeploys), so a counter would\n // re-mint the same ids and let a stale client resume bind to a\n // different execution's pause.\n const id = `exec_${crypto.randomUUID()}`;\n\n const paused: InternalPausedExecution<E> = {\n id,\n elicitationContext: ctx,\n response: responseDeferred,\n fiber: fiber!,\n pauseQueue,\n };\n pausedExecutions.set(id, paused);\n\n yield* Queue.offer(pauseQueue, paused);\n\n // Suspend until resume() completes responseDeferred.\n return yield* Deferred.await(responseDeferred);\n });\n\n const invoker = makeFullInvoker(\n executor,\n { onElicitation: elicitationHandler },\n toolDiscoveryProvider,\n );\n fiber = yield* Effect.forkDetach(\n codeExecutor.execute(code, invoker).pipe(Effect.withSpan(\"executor.code.exec\")),\n );\n\n // When the fiber settles on its own (sandbox timeout, failure) while\n // pauses are still outstanding, drop them: getPausedExecution must not\n // report a pause whose fiber can no longer consume a response, and the\n // map must not grow forever. A resume retry still finds the terminal\n // outcome via the settled-outcome cache.\n const sandboxFiber = fiber;\n yield* Effect.forkDetach(\n Fiber.await(sandboxFiber).pipe(\n Effect.flatMap((exit) =>\n Effect.sync(() => {\n const outcome = Exit.map(\n exit,\n (result): ExecutionResult => ({ status: \"completed\", result }),\n );\n for (const [id, paused] of pausedExecutions) {\n if (paused.fiber !== sandboxFiber) continue;\n pausedExecutions.delete(id);\n recordSettledOutcome(id, outcome);\n }\n }),\n ),\n ),\n );\n\n return (yield* awaitCompletionOrPause(fiber, pauseQueue)) as ExecutionResult;\n });\n\n /**\n * Resume a paused execution. Completes the response Deferred to unblock the\n * fiber, then races completion against the next queued or future pause.\n *\n * Idempotent per executionId: MCP clients retry `resume` when a response is\n * lost in transit, so a duplicate of an already-delivered resume replays the\n * recorded outcome, and a duplicate that arrives while the first is still\n * in flight awaits the same outcome instead of reporting a missing pause.\n */\n const resumeExecution = Effect.fn(\"mcp.execute.resume\")(function* (\n executionId: string,\n response: ResumeResponse,\n ) {\n yield* Effect.annotateCurrentSpan({\n \"mcp.execute.resume.action\": response.action,\n });\n\n const settled = settledOutcomes.get(executionId);\n if (settled) {\n yield* Effect.annotateCurrentSpan({ \"mcp.execute.resume.replayed\": true });\n return (yield* settled) as ExecutionResult;\n }\n\n const pending = pendingResumes.get(executionId);\n if (pending) {\n yield* Effect.annotateCurrentSpan({ \"mcp.execute.resume.joined_inflight\": true });\n return (yield* Deferred.await(pending)) as ExecutionResult;\n }\n\n const paused = pausedExecutions.get(executionId);\n if (!paused) return null;\n pausedExecutions.delete(executionId);\n\n const inflight = yield* Deferred.make<ExecutionResult, E>();\n pendingResumes.set(executionId, inflight);\n\n yield* Deferred.succeed(paused.response, {\n action: response.action as typeof ElicitationResponse.Type.action,\n content: response.content,\n });\n\n return (yield* awaitCompletionOrPause(paused.fiber, paused.pauseQueue).pipe(\n Effect.onExit((exit) =>\n Effect.gen(function* () {\n recordSettledOutcome(executionId, exit);\n pendingResumes.delete(executionId);\n yield* Deferred.done(inflight, exit);\n }),\n ),\n )) as ExecutionResult;\n });\n\n /**\n * Inline-elicitation execute path. Wrapped so every call produces an\n * `mcp.execute` span with the inner `executor.code.exec` as a child.\n */\n const runInlineExecution = Effect.fn(\"mcp.execute\")(function* (\n code: string,\n options: { readonly onElicitation: ElicitationHandler },\n ) {\n yield* Effect.annotateCurrentSpan({\n \"mcp.execute.mode\": \"inline\",\n \"mcp.execute.code_length\": code.length,\n });\n const invoker = makeFullInvoker(\n executor,\n {\n onElicitation: options.onElicitation,\n },\n toolDiscoveryProvider,\n );\n return yield* codeExecutor.execute(code, invoker).pipe(Effect.withSpan(\"executor.code.exec\"));\n });\n\n return {\n execute: runInlineExecution,\n executeWithPause: startPausableExecution,\n resume: resumeExecution,\n getPausedExecution: (executionId) =>\n Effect.sync(() => pausedExecutions.get(executionId) ?? null),\n getDescription: buildExecuteDescription(executor),\n };\n};\n"],"mappings":"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","names":["Effect","Effect","Predicate","parts","Predicate","Effect"]}
|
package/dist/core.js
CHANGED
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@executor-js/execution",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.16",
|
|
4
4
|
"homepage": "https://github.com/RhysSullivan/executor/tree/main/packages/core/execution",
|
|
5
5
|
"bugs": {
|
|
6
6
|
"url": "https://github.com/RhysSullivan/executor/issues"
|
|
@@ -39,12 +39,12 @@
|
|
|
39
39
|
"typecheck:slow": "bunx tsc --noEmit -p tsconfig.json"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@executor-js/codemode-core": "1.5.
|
|
43
|
-
"@executor-js/sdk": "1.5.
|
|
42
|
+
"@executor-js/codemode-core": "1.5.16",
|
|
43
|
+
"@executor-js/sdk": "1.5.16"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@effect/vitest": "4.0.0-beta.59",
|
|
47
|
-
"@executor-js/runtime-quickjs": "1.5.
|
|
47
|
+
"@executor-js/runtime-quickjs": "1.5.16",
|
|
48
48
|
"@types/node": "^24.3.1",
|
|
49
49
|
"bun-types": "^1.2.22",
|
|
50
50
|
"effect": "4.0.0-beta.59",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/tool-invoker.ts","../src/description.ts","../src/engine.ts"],"sourcesContent":["import * as Data from \"effect/Data\";\n\nexport class ExecutionToolError extends Data.TaggedError(\"ExecutionToolError\")<{\n readonly message: string;\n readonly cause?: unknown;\n}> {}\n\n// `CodeExecutionError` lives in `@executor-js/codemode-core` — the `CodeExecutor`\n// interface uses it as the default error channel, so the runtime packages\n// can import the same class directly.\nexport { CodeExecutionError } from \"@executor-js/codemode-core\";\n","import { Effect, Predicate } from \"effect\";\nimport * as Cause from \"effect/Cause\";\nimport type {\n Executor,\n InvokeOptions,\n Integration,\n ToolError,\n Tool,\n ToolSchemaView,\n} from \"@executor-js/sdk/core\";\nimport {\n annotateToolResultOutcome,\n authToolFailure,\n isToolResult,\n ToolResult,\n ToolAddress,\n parseToolAddress,\n} from \"@executor-js/sdk/core\";\nimport type { SandboxToolInvoker } from \"@executor-js/codemode-core\";\nimport { ExecutionToolError } from \"./errors\";\n\nconst OPAQUE_DEFECT_MESSAGE = \"Internal tool error\";\nconst TOOL_DESCRIBE_SUGGESTION_LIMIT = 5;\nconst TOOL_ERROR_TYPESCRIPT =\n \"{ code: string; message: string; status?: number; details?: unknown; retryable?: boolean }\";\n// Present on HTTP-backed tools (OpenAPI): transport facts beside the payload\n// so callers can read pagination/rate-limit headers without the payload\n// being wrapped in an envelope.\nconst TOOL_HTTP_META_TYPESCRIPT = \"{ status: number; headers: { [k: string]: string; } }\";\nconst TOOL_FILE_TYPESCRIPT =\n '{ _tag: \"ToolFile\"; name?: string; mimeType: string; encoding: \"base64\"; data: string; byteLength: number; }';\n\nconst wrapOutputTypeScript = (outputTypeScript?: string): string =>\n `{ ok: true; data: ${outputTypeScript ?? \"unknown\"}; http?: ToolHttpMeta } | { ok: false; error: ToolError }`;\n\nconst withToolResultDefinitions = (\n definitions?: Record<string, string>,\n): Record<string, string> => ({\n ...(definitions ?? {}),\n ToolError: TOOL_ERROR_TYPESCRIPT,\n ToolHttpMeta: TOOL_HTTP_META_TYPESCRIPT,\n ToolFile: TOOL_FILE_TYPESCRIPT,\n});\n\nconst ADDRESS_PREFIX = \"tools.\";\n\n/**\n * Map a sandbox tool path to the executor's `execute` address.\n *\n * v2 dynamic tools are addressed `tools.<integration>.<owner>.<connection>.<tool>`.\n * The sandbox proxy strips the leading `tools.` (the proxy root), so a model\n * writing `tools.github.org.main.getRepo(args)` produces the path\n * `github.org.main.getRepo`. Re-prefix it so it parses as a 5-segment address.\n *\n * Plugin-contributed static tools (core-tools under `executor`, plugin executor\n * namespaces) are addressed by their fqid with no prefix; the executor resolves\n * those from its static map directly, so leave them untouched.\n */\nconst pathToAddress = (path: string): ToolAddress => {\n if (path.startsWith(ADDRESS_PREFIX)) return ToolAddress.make(path);\n if (parseToolAddress(`${ADDRESS_PREFIX}${path}`)) {\n return ToolAddress.make(`${ADDRESS_PREFIX}${path}`);\n }\n return ToolAddress.make(path);\n};\n\n/** Strip the proxy-root `tools.` prefix from a full address so it becomes the\n * sandbox-callable path the model writes after `tools.`. */\nconst addressToPath = (address: string): string =>\n address.startsWith(ADDRESS_PREFIX) ? address.slice(ADDRESS_PREFIX.length) : address;\n\ntype DescribedTool = {\n readonly path: string;\n readonly name: string;\n readonly description?: string;\n readonly inputTypeScript?: string;\n readonly outputTypeScript?: string;\n readonly typeScriptDefinitions?: Record<string, string>;\n /** Set when the path resolves to no tool — mirrors invoke's tool_not_found. */\n readonly error?: {\n readonly code: \"tool_not_found\";\n readonly message: string;\n readonly suggestions?: readonly string[];\n };\n};\n\nconst BUILTIN_TOOL_DESCRIPTIONS: ReadonlyMap<string, DescribedTool> = new Map<\n string,\n DescribedTool\n>([\n [\n \"search\",\n {\n path: \"search\",\n name: \"search\",\n description: \"Search available Executor tools.\",\n inputTypeScript: \"{ query: string; namespace?: string; limit?: number; offset?: number; }\",\n outputTypeScript:\n \"{ items: ToolDiscoveryResult[]; total: number; hasMore: boolean; nextOffset: number | null; }\",\n typeScriptDefinitions: {\n ToolDiscoveryResult:\n \"{ path: string; name: string; description?: string; integration: string; score: number; }\",\n },\n },\n ],\n [\n \"executor.sources.list\",\n {\n path: \"executor.sources.list\",\n name: \"executor.sources.list\",\n description: \"List configured Executor integrations.\",\n inputTypeScript: \"{ query?: string; limit?: number; offset?: number; }\",\n outputTypeScript:\n \"{ items: ExecutorSourceListItem[]; total: number; hasMore: boolean; nextOffset: number | null; }\",\n typeScriptDefinitions: {\n ExecutorSourceListItem:\n \"{ id: string; name: string; description?: string; kind: string; canRemove?: boolean; canRefresh?: boolean; toolCount: number; }\",\n },\n },\n ],\n [\n \"describe.tool\",\n {\n path: \"describe.tool\",\n name: \"describe.tool\",\n description: \"Describe a tool's compact TypeScript input and output shapes.\",\n inputTypeScript: \"{ path: string; }\",\n outputTypeScript: \"DescribedTool\",\n typeScriptDefinitions: {\n DescribedTool:\n '{ path: string; name: string; description?: string; inputTypeScript?: string; outputTypeScript?: string; typeScriptDefinitions?: { [k: string]: string; }; error?: { code: \"tool_not_found\"; message: string; suggestions?: string[]; }; }',\n },\n },\n ],\n]);\n\nconst newCorrelationId = (): string => {\n // 8-hex-char correlation id; enough entropy to disambiguate within a\n // single deployment without leaking host process info.\n return Math.floor(Math.random() * 0x1_0000_0000)\n .toString(16)\n .padStart(8, \"0\");\n};\n\nconst validationIssues = (value: unknown): readonly unknown[] | null => {\n if (typeof value !== \"object\" || value === null) return null;\n const issues = (value as { readonly issues?: unknown }).issues;\n return Array.isArray(issues) ? issues : null;\n};\n\nconst credentialResolutionToolFailure = (input: {\n readonly label: string;\n readonly message: string;\n readonly reauthRequired?: boolean;\n}) =>\n authToolFailure({\n code: input.reauthRequired === true ? \"oauth_reauth_required\" : \"oauth_refresh_failed\",\n message:\n input.reauthRequired === true\n ? `OAuth connection \"${input.label}\" requires reauthorization: ${input.message}`\n : `OAuth connection \"${input.label}\" could not be resolved: ${input.message}`,\n credential: {\n kind: \"oauth\",\n label: input.label,\n },\n });\n\nconst expectedToolFailure = (value: unknown): ToolError | null => {\n if (Predicate.isTagged(value, \"ToolNotFoundError\") && \"address\" in value) {\n const suggestions =\n \"suggestions\" in value && Array.isArray(value.suggestions)\n ? value.suggestions.map((suggestion) => addressToPath(String(suggestion)))\n : undefined;\n const address = addressToPath(String(value.address));\n return {\n code: \"tool_not_found\",\n message: `Tool not found: ${address}`,\n details: { path: address, ...(suggestions ? { suggestions } : {}) },\n };\n }\n if (Predicate.isTagged(value, \"ToolBlockedError\") && \"address\" in value) {\n return {\n code: \"tool_blocked\",\n message: `Tool blocked by policy: ${addressToPath(String(value.address))}`,\n details: value,\n };\n }\n if (Predicate.isTagged(value, \"ToolInvocationError\")) {\n const issues = validationIssues((value as { readonly cause?: unknown }).cause);\n if (issues) {\n return {\n code: \"invalid_tool_arguments\",\n message: \"Tool arguments did not match the input schema.\",\n details: { issues },\n };\n }\n }\n return null;\n};\n\n/**\n * Extract the integration namespace from a tool path. v2 addresses look like\n * `<integration>.<owner>.<connection>.<tool>`; static fqids look like\n * `<source>.<op>`. We take the first segment as a cheap, non-lookup namespace\n * for the span attribute so it's always populated without a catalog read.\n */\nconst extractNamespace = (path: string): string => {\n const normalized = addressToPath(path);\n const idx = normalized.indexOf(\".\");\n return idx === -1 ? normalized : normalized.slice(0, idx);\n};\n\n/**\n * Bridges QuickJS `tools.<integration>.<owner>.<connection>.<tool>(args)` calls\n * into `executor.execute(address, args)`.\n *\n * Wrapped in `Effect.fn(\"mcp.tool.dispatch\")` so every tool call becomes a\n * span in the Effect tracer. Attributes:\n * - `mcp.tool.name` — full tool path (e.g. \"github.org.main.getRepo\")\n * - `mcp.tool.integration` — first segment of the path (namespace)\n *\n * `mcp.tool.kind` (openapi | mcp | graphql | code) is NOT annotated here\n * because it would require an `integrations.list()` lookup on every invocation.\n * Callers that already know the integration kind can annotate at their own span.\n */\nexport const makeExecutorToolInvoker = (\n executor: Executor,\n options: { readonly invokeOptions: InvokeOptions },\n): SandboxToolInvoker => ({\n invoke: Effect.fn(\"mcp.tool.dispatch\")(function* ({ path, args }) {\n yield* Effect.annotateCurrentSpan({\n \"mcp.tool.name\": path,\n \"mcp.tool.integration\": extractNamespace(path),\n });\n\n const address = pathToAddress(path);\n const result = yield* executor.execute(address, args, options.invokeOptions).pipe(\n Effect.catchTag(\"CredentialResolutionError\", (err) =>\n Effect.succeed(\n credentialResolutionToolFailure({\n label: `${err.integration}.${err.owner}.${err.name}`,\n message: err.message,\n reauthRequired: err.reauthRequired,\n }),\n ),\n ),\n Effect.catchCause((cause) => {\n const err = cause.reasons.find(Cause.isFailReason)?.error;\n const expected = expectedToolFailure(err);\n if (expected) {\n return Effect.succeed(ToolResult.fail(expected));\n }\n if (isElicitationDeclinedError(err)) {\n return Effect.fail(\n new ExecutionToolError({\n message: `Tool \"${addressToPath(String(err.address))}\" requires approval but the request was ${err.action === \"cancel\" ? \"cancelled\" : \"declined\"} by the user.`,\n cause: err,\n }),\n );\n }\n // Any other failure here is an infra/plugin defect. Emit an\n // opaque generic with a correlation id so internal context (URLs\n // with tokens, DB connection strings, file paths in stacks)\n // can't leak through Error.message into the sandbox. The full\n // cause is logged with the same correlation id so operators can\n // still trace the failure.\n const correlationId = newCorrelationId();\n return Effect.logError(\"tool dispatch failed\", cause).pipe(\n Effect.annotateLogs({\n \"executor.correlation_id\": correlationId,\n \"mcp.tool.name\": path,\n }),\n Effect.flatMap(() =>\n Effect.fail(\n new ExecutionToolError({\n message: `${OPAQUE_DEFECT_MESSAGE} [${correlationId}]`,\n cause: err ?? cause,\n }),\n ),\n ),\n );\n }),\n );\n\n // Strict: plugins emit ToolResult<T>. Anything else is treated as a\n // raw success value and wrapped — keeps the sandbox-facing contract\n // uniform without forcing every tiny test plugin to import\n // `ToolResult.ok`.\n // Expected failures resolve through the success channel, so without the\n // outcome annotation the dispatch span reads as healthy even when the\n // caller hit an upstream error or auth wall.\n yield* annotateToolResultOutcome(result);\n if (isToolResult(result)) {\n return result;\n }\n return { ok: true, data: result };\n }),\n});\n\nconst isElicitationDeclinedError = (\n value: unknown,\n): value is {\n readonly _tag: \"ElicitationDeclinedError\";\n readonly address: string;\n readonly action: \"cancel\" | \"decline\";\n} =>\n Predicate.isTagged(value, \"ElicitationDeclinedError\") &&\n value !== null &&\n typeof value === \"object\" &&\n \"address\" in value &&\n typeof value.address === \"string\" &&\n \"action\" in value &&\n (value.action === \"cancel\" || value.action === \"decline\");\n\nexport type ToolDiscoveryResult = {\n readonly path: string;\n readonly name: string;\n readonly description?: string;\n readonly integration: string;\n readonly score: number;\n};\n\nexport type ExecutorSourceListItem = {\n readonly id: string;\n readonly name: string;\n readonly description?: string;\n readonly kind: string;\n readonly canRemove?: boolean;\n readonly canRefresh?: boolean;\n readonly toolCount: number;\n};\n\nexport type ToolDiscoveryInput = {\n readonly executor: Executor;\n readonly query: string;\n readonly namespace?: string;\n readonly limit: number;\n readonly offset: number;\n};\n\nexport interface ToolDiscoveryProvider {\n readonly searchTools: (\n input: ToolDiscoveryInput,\n ) => Effect.Effect<PagedResult<ToolDiscoveryResult>, ExecutionToolError>;\n}\n\n/**\n * Page of results from a list-style discovery tool. Shared by\n * `tools.search` and `tools.executor.sources.list` so the model sees one\n * consistent shape:\n *\n * - `items` — the page (slice).\n * - `total` — count after filtering, before pagination. The model\n * can use this to detect truncation.\n * - `hasMore` — convenience flag for `(offset + items.length) < total`.\n * - `nextOffset` — concrete offset for the next page when `hasMore`,\n * `null` otherwise. Pre-computing it removes a class of\n * off-by-one mistakes when the model paginates.\n */\nexport type PagedResult<T> = {\n readonly items: readonly T[];\n readonly total: number;\n readonly hasMore: boolean;\n readonly nextOffset: number | null;\n};\n\nconst paginate = <T>(all: readonly T[], offset: number, limit: number): PagedResult<T> => {\n const total = all.length;\n const start = Math.min(Math.max(offset, 0), total);\n const items = all.slice(start, start + limit);\n const consumed = start + items.length;\n const hasMore = consumed < total;\n return {\n items,\n total,\n hasMore,\n nextOffset: hasMore ? consumed : null,\n };\n};\n\n/** What `searchTools` ranks over — the sandbox-callable path plus the v2\n * identity fields a query can match against. */\ntype SearchableTool = {\n readonly path: string;\n readonly integration: string;\n readonly name: string;\n readonly description?: string;\n};\n\nconst toSearchableTool = (tool: Tool): SearchableTool => ({\n path: addressToPath(String(tool.address)),\n integration: String(tool.integration),\n name: String(tool.name),\n description: tool.description,\n});\n\ntype PreparedField = {\n readonly raw: string;\n readonly tokens: readonly string[];\n};\n\nconst SEARCH_FIELD_WEIGHTS = {\n path: 12,\n integration: 8,\n name: 10,\n description: 5,\n} as const;\n\nconst normalizeSearchText = (value: string): string =>\n value\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .replace(/[_./:-]+/g, \" \")\n .toLowerCase()\n .trim();\n\nconst tokenizeSearchText = (value: string): string[] =>\n normalizeSearchText(value)\n .split(/[^a-z0-9]+/)\n .map((token) => token.trim())\n .filter(Boolean);\n\nconst prepareField = (value?: string): PreparedField => ({\n raw: normalizeSearchText(value ?? \"\"),\n tokens: tokenizeSearchText(value ?? \"\"),\n});\n\nconst scorePreparedField = (\n query: string,\n queryTokens: readonly string[],\n field: PreparedField,\n weight: number,\n): {\n readonly score: number;\n readonly matchedTokens: ReadonlySet<string>;\n readonly exactPhraseMatch: boolean;\n} => {\n if (field.raw.length === 0) {\n return {\n score: 0,\n matchedTokens: new Set<string>(),\n exactPhraseMatch: false,\n };\n }\n\n let score = 0;\n const matchedTokens = new Set<string>();\n const exactPhraseMatch = query.length > 0 && field.raw.includes(query);\n\n if (query.length > 0) {\n if (field.raw === query) {\n score += weight * 14;\n } else if (field.raw.startsWith(query)) {\n score += weight * 9;\n } else if (exactPhraseMatch) {\n score += weight * 6;\n }\n }\n\n for (const token of queryTokens) {\n if (field.tokens.includes(token)) {\n score += weight * 4;\n matchedTokens.add(token);\n continue;\n }\n\n if (\n field.tokens.some((candidate) => candidate.startsWith(token) || token.startsWith(candidate))\n ) {\n score += weight * 2;\n matchedTokens.add(token);\n continue;\n }\n\n if (field.raw.includes(token)) {\n score += weight;\n matchedTokens.add(token);\n }\n }\n\n return {\n score,\n matchedTokens,\n exactPhraseMatch,\n };\n};\n\nconst matchesNamespace = (tool: SearchableTool, namespace?: string): boolean => {\n if (!namespace || normalizeSearchText(namespace).length === 0) {\n return true;\n }\n\n const namespaceTokens = tokenizeSearchText(namespace);\n if (namespaceTokens.length === 0) {\n return true;\n }\n\n const integrationTokens = tokenizeSearchText(tool.integration);\n const pathTokens = tokenizeSearchText(tool.path);\n\n const isPrefixMatch = (tokens: readonly string[]): boolean =>\n namespaceTokens.every((token, index) => tokens[index] === token);\n\n return isPrefixMatch(integrationTokens) || isPrefixMatch(pathTokens);\n};\n\nconst scoreToolMatch = (tool: SearchableTool, query: string): ToolDiscoveryResult | null => {\n const normalizedQuery = normalizeSearchText(query);\n const queryTokens = tokenizeSearchText(query);\n\n if (normalizedQuery.length === 0 || queryTokens.length === 0) {\n return null;\n }\n\n const path = prepareField(tool.path);\n const integration = prepareField(tool.integration);\n const name = prepareField(tool.name);\n const description = prepareField(tool.description);\n\n const fieldScores = [\n scorePreparedField(normalizedQuery, queryTokens, path, SEARCH_FIELD_WEIGHTS.path),\n scorePreparedField(normalizedQuery, queryTokens, integration, SEARCH_FIELD_WEIGHTS.integration),\n scorePreparedField(normalizedQuery, queryTokens, name, SEARCH_FIELD_WEIGHTS.name),\n scorePreparedField(normalizedQuery, queryTokens, description, SEARCH_FIELD_WEIGHTS.description),\n ];\n\n const matchedTokens = new Set<string>();\n let score = 0;\n let exactPhraseMatch = false;\n\n for (const fieldScore of fieldScores) {\n score += fieldScore.score;\n exactPhraseMatch ||= fieldScore.exactPhraseMatch;\n for (const token of fieldScore.matchedTokens) {\n matchedTokens.add(token);\n }\n }\n\n if (matchedTokens.size === 0) {\n return null;\n }\n\n const coverage = matchedTokens.size / queryTokens.length;\n const minimumCoverage = queryTokens.length <= 2 ? 1 : 0.6;\n\n if (coverage < minimumCoverage && !exactPhraseMatch) {\n return null;\n }\n\n if (coverage === 1) {\n score += 25;\n } else {\n score += Math.round(coverage * 10);\n }\n\n if (path.tokens[0] === queryTokens[0] || name.tokens[0] === queryTokens[0]) {\n score += 8;\n }\n\n if (\n normalizeSearchText(tool.path) === normalizedQuery ||\n normalizeSearchText(tool.name) === normalizedQuery\n ) {\n score += 20;\n }\n\n return {\n path: tool.path,\n name: tool.name,\n description: tool.description,\n integration: tool.integration,\n score,\n };\n};\n\n/** What `tools.search()` calls inside the sandbox. */\nexport const searchTools = Effect.fn(\"executor.tools.search\")(function* (\n executor: Executor,\n query: string,\n limit = 12,\n options?: { readonly namespace?: string; readonly offset?: number },\n) {\n const offset = options?.offset ?? 0;\n yield* Effect.annotateCurrentSpan({\n \"executor.search.query_length\": query.length,\n \"executor.search.limit\": limit,\n \"executor.search.offset\": offset,\n ...(options?.namespace ? { \"executor.search.namespace\": options.namespace } : {}),\n });\n\n const empty: PagedResult<ToolDiscoveryResult> = {\n items: [],\n total: 0,\n hasMore: false,\n nextOffset: null,\n };\n\n if (normalizeSearchText(query).length === 0) {\n return empty;\n }\n\n const all = yield* executor.tools.list({ includeAnnotations: false }).pipe(\n Effect.mapError(\n (cause) =>\n new ExecutionToolError({\n message: \"Failed to list tools for search\",\n cause,\n }),\n ),\n );\n const searchable = all.map(toSearchableTool);\n const ranked = searchable\n .filter((tool: SearchableTool) => matchesNamespace(tool, options?.namespace))\n .map((tool: SearchableTool) => scoreToolMatch(tool, query))\n .filter(Predicate.isNotNull)\n .sort((left, right) => right.score - left.score || left.path.localeCompare(right.path));\n\n const page = paginate(ranked, offset, limit);\n\n yield* Effect.annotateCurrentSpan({\n \"executor.search.candidate_count\": all.length,\n \"executor.search.match_count\": ranked.length,\n \"executor.search.result_count\": page.items.length,\n \"executor.search.has_more\": page.hasMore,\n });\n return page;\n});\n\nexport const defaultToolDiscoveryProvider: ToolDiscoveryProvider = {\n searchTools: ({ executor, query, namespace, limit, offset }) =>\n searchTools(executor, query, limit, { namespace, offset }),\n};\n\n/** What `tools.executor.sources.list()` calls inside the sandbox. v2: the\n * \"sources\" are the integration catalog; tool counts come from the\n * per-connection tool list. */\nexport const listExecutorSources = Effect.fn(\"executor.sources.list\")(function* (\n executor: Executor,\n options?: {\n readonly query?: string;\n readonly limit?: number;\n readonly offset?: number;\n },\n) {\n const normalizedQuery = normalizeSearchText(options?.query ?? \"\");\n const limit = options?.limit ?? 50;\n const offset = options?.offset ?? 0;\n const integrations = yield* executor.integrations.list().pipe(\n Effect.mapError(\n (cause) =>\n new ExecutionToolError({\n message: \"Failed to list executor integrations\",\n cause,\n }),\n ),\n );\n\n const filtered =\n normalizedQuery.length === 0\n ? integrations\n : integrations.filter((integration: Integration) => {\n const haystack = normalizeSearchText(\n [String(integration.slug), integration.description, integration.kind].join(\" \"),\n );\n return tokenizeSearchText(normalizedQuery).every((token) => haystack.includes(token));\n });\n\n // Single query for all tools, then count per integration in memory.\n const allTools = yield* executor.tools.list({ includeAnnotations: false }).pipe(\n Effect.mapError(\n (cause) =>\n new ExecutionToolError({\n message: \"Failed to list tools for integration counts\",\n cause,\n }),\n ),\n );\n const toolCountByIntegration = new Map<string, number>();\n for (const tool of allTools) {\n const key = String(tool.integration);\n toolCountByIntegration.set(key, (toolCountByIntegration.get(key) ?? 0) + 1);\n }\n\n const sortedWithCounts = filtered\n .map(\n (integration: Integration) =>\n ({\n id: String(integration.slug),\n name: String(integration.slug),\n // The integration's catalog description — user-editable context the\n // agent can use to pick a source. Omitted when it just repeats the\n // slug or display name (no information beyond identity).\n ...(integration.description &&\n integration.description.toLowerCase() !== String(integration.slug).toLowerCase() &&\n integration.description.toLowerCase() !== integration.name.toLowerCase()\n ? { description: integration.description }\n : {}),\n kind: integration.kind,\n canRemove: integration.canRemove,\n canRefresh: integration.canRefresh,\n toolCount: toolCountByIntegration.get(String(integration.slug)) ?? 0,\n }) satisfies ExecutorSourceListItem,\n )\n .sort((left, right) => left.name.localeCompare(right.name) || left.id.localeCompare(right.id));\n\n const page = paginate(sortedWithCounts, offset, limit);\n\n yield* Effect.annotateCurrentSpan({\n \"executor.sources.candidate_count\": integrations.length,\n \"executor.sources.match_count\": sortedWithCounts.length,\n \"executor.sources.result_count\": page.items.length,\n \"executor.sources.has_more\": page.hasMore,\n });\n return page;\n});\n\n/** What `tools.describe.tool()` calls inside the sandbox. */\nexport const describeTool = Effect.fn(\"executor.tools.describe\")(function* (\n executor: Executor,\n path: string,\n) {\n yield* Effect.annotateCurrentSpan({ \"mcp.tool.name\": path });\n\n const builtin = BUILTIN_TOOL_DESCRIPTIONS.get(path);\n if (builtin) return builtin;\n\n const address = pathToAddress(path);\n\n // Single tools.schema() call — it already fetches the tool row\n // internally. No need to also call tools.list() just for name/description.\n const schema: ToolSchemaView | null = yield* executor.tools.schema(address);\n\n // tools.schema() returns null if the tool doesn't exist. Mirror the\n // invoke path's tool_not_found shape (error + suggestions) instead of a\n // bare stub — a silent `{ path, name }` reads as \"tool exists, schema\n // unavailable\" and sends callers down the wrong debugging path.\n if (schema === null) {\n const lastDot = path.lastIndexOf(\".\");\n const leaf = lastDot === -1 ? path : path.slice(lastDot + 1);\n const scoped = yield* searchTools(executor, leaf, TOOL_DESCRIBE_SUGGESTION_LIMIT, {\n namespace: extractNamespace(path),\n });\n const matches =\n scoped.items.length > 0\n ? scoped.items\n : (yield* searchTools(executor, leaf, TOOL_DESCRIBE_SUGGESTION_LIMIT)).items;\n const suggestions = matches.map((item) => item.path);\n const notFound: DescribedTool = {\n path,\n name: path,\n error: {\n code: \"tool_not_found\",\n message: `Tool not found: ${path}`,\n ...(suggestions.length > 0 ? { suggestions } : {}),\n },\n };\n return notFound;\n }\n\n // The schema's address is the tool address; name/description come from the\n // tool row which tools.schema() already loaded.\n const described: DescribedTool = {\n path,\n name: schema.name ?? path,\n description: schema.description,\n inputTypeScript: schema.inputTypeScript,\n outputTypeScript: wrapOutputTypeScript(schema.outputTypeScript),\n typeScriptDefinitions: withToolResultDefinitions(schema.typeScriptDefinitions),\n };\n return described;\n});\n","import { Effect } from \"effect\";\nimport type { Connection, Integration, Executor } from \"@executor-js/sdk/core\";\n\n/**\n * Builds a tool description dynamically.\n *\n * Structure:\n * 1. Workflow (top — critical, least likely to be truncated)\n * 2. Available connection prefixes (bottom)\n *\n * v2: callable API tools are scoped by saved connections. A tool's sandbox\n * address is `tools.<integration>.<owner>.<connection>.<tool>`, so the useful\n * inventory is the connection prefix rather than only the integration slug.\n */\nexport const buildExecuteDescription = (executor: Executor): Effect.Effect<string> =>\n Effect.gen(function* () {\n const connections: readonly Connection[] = yield* executor.connections.list().pipe(\n // oxlint-disable-next-line executor/no-effect-escape-hatch -- boundary: ExecutionEngine.getDescription currently exposes no error channel; engine typed-error widening is covered separately\n Effect.orDie,\n Effect.withSpan(\"executor.connections.list\"),\n );\n const integrations: readonly Integration[] = yield* executor.integrations.list().pipe(\n // oxlint-disable-next-line executor/no-effect-escape-hatch -- boundary: same getDescription error-channel constraint as connections.list above\n Effect.orDie,\n Effect.withSpan(\"executor.integrations.list\"),\n );\n\n const description = yield* Effect.sync(() =>\n formatDescription(connections.map((connection) => connectionEntry(connection, integrations))),\n ).pipe(\n Effect.withSpan(\"schema.compile.description\", {\n attributes: { \"executor.connection_count\": connections.length },\n }),\n );\n\n yield* Effect.annotateCurrentSpan({\n \"executor.connection_count\": connections.length,\n \"schema.kind\": \"execute\",\n // Connection inventory so a failing session build (which runs this during\n // init) names the callable prefixes it resolved without listing tools.\n \"executor.connection_addresses\": connections\n .map((connection) => connectionPath(connection))\n .slice(0, 50)\n .join(\",\"),\n \"executor.connection_integrations\": [\n ...new Set(connections.map((connection) => String(connection.integration))),\n ].join(\",\"),\n \"executor.connection_owners\": [\n ...new Set(connections.map((connection) => connection.owner)),\n ].join(\",\"),\n });\n\n return description;\n }).pipe(Effect.withSpan(\"schema.describe.execute\"));\n\nconst connectionPath = (connection: Connection): string => {\n const address = String(connection.address);\n return address.startsWith(\"tools.\") ? address.slice(\"tools.\".length) : address;\n};\n\n/** One inventory line: the callable prefix plus the best available context.\n * Connection description wins (the user wrote it about THIS credential);\n * otherwise the integration description, unless it is just the slug again. */\ninterface ConnectionInventoryEntry {\n readonly prefix: string;\n readonly description?: string;\n}\n\nconst inventoryNote = (\n text: string | null | undefined,\n identityEchoes: readonly string[],\n): string | undefined => {\n const firstLine = (text ?? \"\").split(\"\\n\", 1)[0]!.trim();\n if (firstLine.length === 0) return undefined;\n // A description that just restates the slug or display name carries no\n // information beyond identity — drop it from the inventory line.\n if (identityEchoes.some((echo) => firstLine.toLowerCase() === echo.toLowerCase())) {\n return undefined;\n }\n return firstLine.length > 140 ? `${firstLine.slice(0, 139)}…` : firstLine;\n};\n\nconst connectionEntry = (\n connection: Connection,\n integrations: readonly Integration[],\n): ConnectionInventoryEntry => {\n const slug = String(connection.integration);\n const integration = integrations.find((candidate) => String(candidate.slug) === slug);\n const identityEchoes = [slug, ...(integration ? [integration.name] : [])];\n return {\n prefix: connectionPath(connection),\n description:\n inventoryNote(connection.description, identityEchoes) ??\n inventoryNote(integration?.description, identityEchoes),\n };\n};\n\nconst formatDescription = (connectionEntries: readonly ConnectionInventoryEntry[]): string => {\n const lines: string[] = [\n \"Execute TypeScript in a sandboxed runtime with access to configured API tools.\",\n \"\",\n \"## Workflow\",\n \"\",\n '1. `const { items: matches } = await tools.search({ query: \"<intent + key nouns>\", limit: 12 });`',\n '2. `const path = matches[0]?.path; if (!path) return \"No matching tools found.\";`',\n \"3. `const details = await tools.describe.tool({ path });`\",\n \"4. Use `details.inputTypeScript` / `details.outputTypeScript` and `details.typeScriptDefinitions` for compact shapes.\",\n \"5. Use `tools.executor.coreTools.connections.list({})` when you need live saved-connection inventory.\",\n \"6. Call the tool: `const result = await tools.<path>(input);`\",\n \"\",\n \"## Rules\",\n \"\",\n \"- `tools.search()` returns paginated, ranked matches: `{ items, total, hasMore, nextOffset }`. Best-first. Use short intent phrases like `github issues`, `repo details`, or `create calendar event`.\",\n '- When you already know the namespace, narrow with `tools.search({ namespace: \"github\", query: \"issues\" })`.',\n \"- `tools.executor.coreTools.connections.list({})` returns saved connections with `{ address, integration, owner, name, ... }`. The `address` field includes the leading `tools.` root.\",\n \"- Tool calls return a value union: `{ ok: true, data }` for success or `{ ok: false, error: { code, message, status?, details?, retryable? } }` for expected tool/domain failures. Branch on `result.ok`.\",\n \"- `data` is the upstream payload itself. HTTP-backed tools (OpenAPI) also set `http: { status, headers }` beside `data` — read `result.http?.headers` for pagination (Link) or rate-limit headers.\",\n \"- If `tools.search()` returns `hasMore: true` and you didn't find what you need, fetch the next page: `tools.search({ query, offset: nextOffset, limit })`.\",\n \"- Always use the full address when calling tools: `tools.<integration>.<owner>.<connection>.<tool>(args)`. The `path` returned by `tools.search()` / `tools.describe.tool()` is already the exact path under `tools` — call `tools[path]` rather than guessing segments.\",\n \"- The `tools` object is a lazy proxy — `Object.keys(tools)` won't work. Use `tools.search()` or `tools.executor.coreTools.connections.list({})` instead.\",\n '- Pass an object to system tools, e.g. `tools.search({ query: \"...\" })`, `tools.executor.coreTools.connections.list({})`, and `tools.describe.tool({ path })`.',\n '- `tools.describe.tool()` returns compact TypeScript shapes. Use `inputTypeScript`, `outputTypeScript`, and `typeScriptDefinitions`. If the path doesn\\'t resolve, the result carries `error: { code: \"tool_not_found\", suggestions }` — use a suggestion instead of retrying the same path.',\n \"- For tools that return large collections (e.g. `getStates`, `getAll`), filter results in code rather than calling per-item tools.\",\n \"- Do not use `fetch` — all API calls go through `tools.*`.\",\n \"- If execution pauses for interaction, resume it with the returned `resumePayload`.\",\n \"- TypeScript type syntax (`: T`, `as T`, generics, interfaces, type aliases) is stripped before execution — feel free to write idiomatic TypeScript using the shapes from `tools.describe.tool()`. Decorators and `enum` are not supported.\",\n ];\n\n if (connectionEntries.length > 0) {\n lines.push(\"\");\n lines.push(\"## Available connection prefixes\");\n lines.push(\"\");\n lines.push(\"These are paths under `tools.`; append the final tool segment.\");\n const sorted = [...connectionEntries]\n .sort((a, b) => a.prefix.localeCompare(b.prefix))\n .slice(0, 50);\n for (const entry of sorted) {\n lines.push(\n entry.description\n ? `- \\`${entry.prefix}\\` — ${entry.description}`\n : `- \\`${entry.prefix}\\``,\n );\n }\n if (connectionEntries.length > sorted.length) {\n lines.push(`- ... ${connectionEntries.length - sorted.length} more`);\n }\n }\n\n return lines.join(\"\\n\");\n};\n","import { Deferred, Effect, Fiber, Predicate, Queue } from \"effect\";\nimport type * as Cause from \"effect/Cause\";\nimport * as Exit from \"effect/Exit\";\n\nimport type {\n Executor,\n InvokeOptions,\n ElicitationResponse,\n ElicitationHandler,\n ElicitationContext,\n} from \"@executor-js/sdk/core\";\nimport { CodeExecutionError } from \"@executor-js/codemode-core\";\nimport type { CodeExecutor, ExecuteResult, SandboxToolInvoker } from \"@executor-js/codemode-core\";\n\nimport {\n defaultToolDiscoveryProvider,\n makeExecutorToolInvoker,\n listExecutorSources,\n describeTool,\n type ToolDiscoveryProvider,\n} from \"./tool-invoker\";\nimport { ExecutionToolError } from \"./errors\";\nimport { buildExecuteDescription } from \"./description\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type ExecutionEngineConfig<E extends Cause.YieldableError = CodeExecutionError> = {\n readonly executor: Executor;\n readonly codeExecutor: CodeExecutor<E>;\n readonly toolDiscoveryProvider?: ToolDiscoveryProvider;\n};\n\nexport type ExecutionResult =\n | { readonly status: \"completed\"; readonly result: ExecuteResult }\n | { readonly status: \"paused\"; readonly execution: PausedExecution };\n\nexport type PausedExecution = {\n readonly id: string;\n readonly elicitationContext: ElicitationContext;\n};\n\n/** Internal representation with Effect runtime state for pause/resume. */\ntype InternalPausedExecution<E> = PausedExecution & {\n readonly response: Deferred.Deferred<typeof ElicitationResponse.Type>;\n readonly fiber: Fiber.Fiber<ExecuteResult, E>;\n readonly pauseQueue: Queue.Queue<InternalPausedExecution<E>>;\n};\n\nexport type ResumeResponse = {\n readonly action: \"accept\" | \"decline\" | \"cancel\";\n readonly content?: Record<string, unknown>;\n};\n\n// ---------------------------------------------------------------------------\n// Result formatting\n// ---------------------------------------------------------------------------\n\nconst MAX_PREVIEW_CHARS = 30_000;\n\nconst truncate = (value: string, max: number): string =>\n value.length > max\n ? `${value.slice(0, max)}\\n... [truncated ${value.length - max} chars]`\n : value;\n\nexport const formatExecuteResult = (\n result: ExecuteResult,\n): {\n text: string;\n structured: Record<string, unknown>;\n isError: boolean;\n} => {\n const resultText =\n result.result != null\n ? typeof result.result === \"string\"\n ? result.result\n : JSON.stringify(result.result, null, 2)\n : null;\n\n const logText = result.logs && result.logs.length > 0 ? result.logs.join(\"\\n\") : null;\n\n if (result.error) {\n const parts = [`Error: ${result.error}`, ...(logText ? [`\\nLogs:\\n${logText}`] : [])];\n return {\n text: truncate(parts.join(\"\\n\"), MAX_PREVIEW_CHARS),\n structured: { status: \"error\", error: result.error, logs: result.logs ?? [] },\n isError: true,\n };\n }\n\n const parts = [\n ...(resultText ? [truncate(resultText, MAX_PREVIEW_CHARS)] : [\"(no result)\"]),\n ...(logText ? [`\\nLogs:\\n${logText}`] : []),\n ];\n return {\n text: parts.join(\"\\n\"),\n structured: { status: \"completed\", result: result.result ?? null, logs: result.logs ?? [] },\n isError: false,\n };\n};\n\nexport const formatPausedExecution = (\n paused: PausedExecution,\n): {\n text: string;\n structured: Record<string, unknown>;\n} => {\n const req = paused.elicitationContext.request;\n const lines: string[] = [`Execution paused: ${req.message}`];\n const isUrlElicitation = Predicate.isTagged(req, \"UrlElicitation\");\n const isFormElicitation = Predicate.isTagged(req, \"FormElicitation\");\n const requestedSchema = isFormElicitation ? req.requestedSchema : undefined;\n const hasRequestedSchema =\n requestedSchema !== undefined && Object.keys(requestedSchema).length > 0;\n const instructions = isUrlElicitation\n ? `The user needs to open this URL in a browser and complete the flow. After the user finishes, call the resume tool with executionId \"${paused.id}\" and action \"accept\".`\n : hasRequestedSchema\n ? `Ask the user for values matching requestedSchema. Then call the resume tool with executionId \"${paused.id}\", action \"accept\", and content matching requestedSchema. If the user declines, call resume with action \"decline\" or \"cancel\".`\n : `This is a model-side confirmation gate; there is no browser form to open. Ask the user whether to approve the paused tool call. If the user approves, call the resume tool with executionId \"${paused.id}\" and action \"accept\". If the user declines, call resume with action \"decline\" or \"cancel\".`;\n\n if (isUrlElicitation) {\n lines.push(`\\nOpen this URL in a browser:\\n${req.url}`);\n lines.push('\\nAfter the browser flow, call the resume tool with action \"accept\".');\n } else if (hasRequestedSchema) {\n lines.push(\n \"\\nAsk the user for a response matching the requested schema, then call the resume tool.\",\n );\n lines.push(`\\nRequested schema:\\n${JSON.stringify(requestedSchema, null, 2)}`);\n } else {\n lines.push(\n '\\nThis is a model-side confirmation gate; no browser form is waiting. Ask the user whether to approve, then call the resume tool with action \"accept\", \"decline\", or \"cancel\".',\n );\n }\n\n lines.push(`\\nexecutionId: ${paused.id}`);\n lines.push(`\\ninstructions: ${instructions}`);\n\n return {\n text: lines.join(\"\\n\"),\n structured: {\n status: \"waiting_for_interaction\",\n executionId: paused.id,\n interaction: {\n kind: isUrlElicitation ? \"url\" : \"form\",\n message: req.message,\n instructions,\n address: String(paused.elicitationContext.address),\n args: paused.elicitationContext.args,\n ...(isUrlElicitation ? { url: req.url } : {}),\n ...(isFormElicitation ? { requestedSchema: req.requestedSchema } : {}),\n },\n },\n };\n};\n\n// ---------------------------------------------------------------------------\n// Full invoker (base + discover + describe)\n// ---------------------------------------------------------------------------\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst readOptionalLimit = (value: unknown, toolName: string): number | ExecutionToolError => {\n if (value === undefined) {\n return 12;\n }\n\n if (typeof value !== \"number\" || !Number.isFinite(value) || value <= 0) {\n return new ExecutionToolError({\n message: `${toolName} limit must be a positive number when provided`,\n });\n }\n\n return Math.floor(value);\n};\n\nconst readOptionalOffset = (value: unknown, toolName: string): number | ExecutionToolError => {\n if (value === undefined) {\n return 0;\n }\n\n if (typeof value !== \"number\" || !Number.isFinite(value) || value < 0) {\n return new ExecutionToolError({\n message: `${toolName} offset must be a non-negative number when provided`,\n });\n }\n\n return Math.floor(value);\n};\n\nconst makeFullInvoker = (\n executor: Executor,\n invokeOptions: InvokeOptions,\n toolDiscoveryProvider: ToolDiscoveryProvider,\n): SandboxToolInvoker => {\n const base = makeExecutorToolInvoker(executor, { invokeOptions });\n return {\n invoke: ({ path, args }) => {\n if (path === \"search\") {\n if (!isRecord(args)) {\n return Effect.fail(\n new ExecutionToolError({\n message:\n \"tools.search expects an object: { query?: string; namespace?: string; limit?: number; offset?: number }\",\n }),\n );\n }\n\n if (args.query !== undefined && typeof args.query !== \"string\") {\n return Effect.fail(\n new ExecutionToolError({\n message: \"tools.search query must be a string when provided\",\n }),\n );\n }\n\n if (args.namespace !== undefined && typeof args.namespace !== \"string\") {\n return Effect.fail(\n new ExecutionToolError({\n message: \"tools.search namespace must be a string when provided\",\n }),\n );\n }\n\n const limit = readOptionalLimit(args.limit, \"tools.search\");\n if (Predicate.isTagged(limit, \"ExecutionToolError\")) {\n return Effect.fail(limit);\n }\n\n const offset = readOptionalOffset(args.offset, \"tools.search\");\n if (Predicate.isTagged(offset, \"ExecutionToolError\")) {\n return Effect.fail(offset);\n }\n\n return toolDiscoveryProvider\n .searchTools({\n executor,\n query: args.query ?? \"\",\n limit,\n namespace: args.namespace,\n offset,\n })\n .pipe(\n Effect.withSpan(\"mcp.tool.dispatch\", {\n attributes: { \"mcp.tool.name\": path, \"executor.tool.builtin\": true },\n }),\n );\n }\n if (path === \"executor.sources.list\") {\n if (args !== undefined && !isRecord(args)) {\n return Effect.fail(\n new ExecutionToolError({\n message:\n \"tools.executor.sources.list expects an object: { query?: string; limit?: number; offset?: number }\",\n }),\n );\n }\n\n if (isRecord(args) && args.query !== undefined && typeof args.query !== \"string\") {\n return Effect.fail(\n new ExecutionToolError({\n message: \"tools.executor.sources.list query must be a string when provided\",\n }),\n );\n }\n\n const limit = readOptionalLimit(\n isRecord(args) ? args.limit : undefined,\n \"tools.executor.sources.list\",\n );\n if (Predicate.isTagged(limit, \"ExecutionToolError\")) {\n return Effect.fail(limit);\n }\n\n const offset = readOptionalOffset(\n isRecord(args) ? args.offset : undefined,\n \"tools.executor.sources.list\",\n );\n if (Predicate.isTagged(offset, \"ExecutionToolError\")) {\n return Effect.fail(offset);\n }\n\n return listExecutorSources(executor, {\n query: isRecord(args) && typeof args.query === \"string\" ? args.query : undefined,\n limit,\n offset,\n }).pipe(\n Effect.withSpan(\"mcp.tool.dispatch\", {\n attributes: { \"mcp.tool.name\": path, \"executor.tool.builtin\": true },\n }),\n );\n }\n if (path === \"describe.tool\") {\n if (!isRecord(args)) {\n return Effect.fail(\n new ExecutionToolError({\n message: \"tools.describe.tool expects an object: { path: string }\",\n }),\n );\n }\n\n if (typeof args.path !== \"string\" || args.path.trim().length === 0) {\n return Effect.fail(new ExecutionToolError({ message: \"describe.tool requires a path\" }));\n }\n\n if (\"includeSchemas\" in args) {\n return Effect.fail(\n new ExecutionToolError({\n message: \"tools.describe.tool no longer accepts includeSchemas\",\n }),\n );\n }\n\n return describeTool(executor, args.path).pipe(\n Effect.withSpan(\"mcp.tool.dispatch\", {\n attributes: {\n \"mcp.tool.name\": path,\n \"executor.tool.builtin\": true,\n \"executor.tool.target_path\": args.path,\n },\n }),\n );\n }\n return base.invoke({ path, args });\n },\n };\n};\n\n// ---------------------------------------------------------------------------\n// Execution Engine\n// ---------------------------------------------------------------------------\n\nexport type ExecutionEngine<E extends Cause.YieldableError = CodeExecutionError> = {\n /**\n * Execute code with elicitation handled inline by the provided handler.\n * Use this when the host supports elicitation (e.g. MCP with elicitation capability).\n *\n * Fails with the code executor's typed error `E` (defaults to\n * `CodeExecutionError`). Runtimes surface their own `Data.TaggedError`\n * subclass, which flows through here unchanged.\n */\n readonly execute: (\n code: string,\n options: { readonly onElicitation: ElicitationHandler },\n ) => Effect.Effect<ExecuteResult, E>;\n\n /**\n * Execute code, intercepting the first elicitation as a pause point.\n * Use this when the host doesn't support inline elicitation.\n * Returns either a completed result or a paused execution that can be resumed.\n */\n readonly executeWithPause: (code: string) => Effect.Effect<ExecutionResult, E>;\n\n /**\n * Resume a paused execution. Returns a completed result, a new pause, or\n * null if the executionId was not found.\n */\n readonly resume: (\n executionId: string,\n response: ResumeResponse,\n ) => Effect.Effect<ExecutionResult | null, E>;\n\n /**\n * Inspect a paused execution without resuming it. Returns null if the id is\n * unknown or has already been resumed.\n */\n readonly getPausedExecution: (executionId: string) => Effect.Effect<PausedExecution | null>;\n\n /**\n * Get the dynamic tool description (workflow + namespaces).\n */\n readonly getDescription: Effect.Effect<string>;\n};\n\nexport const createExecutionEngine = <E extends Cause.YieldableError = CodeExecutionError>(\n config: ExecutionEngineConfig<E>,\n): ExecutionEngine<E> => {\n const { executor, codeExecutor, toolDiscoveryProvider = defaultToolDiscoveryProvider } = config;\n const pausedExecutions = new Map<string, InternalPausedExecution<E>>();\n // Outcomes of executions that already settled (resumed to completion, hit a\n // new pause, or died while paused). MCP clients retry `resume` when a\n // response gets lost in transit; without this cache the retry of an\n // already-delivered resume answers \"no paused execution\" (observed in\n // production seconds after a successful resume). Bounded FIFO — pause\n // volume is tiny (human approvals), so a small window is plenty.\n const settledOutcomes = new Map<string, Exit.Exit<ExecutionResult, E>>();\n const SETTLED_OUTCOME_LIMIT = 64;\n // Resumes whose outcome is still being computed, so a concurrent duplicate\n // awaits the same result instead of missing the (already-consumed) pause.\n const pendingResumes = new Map<string, Deferred.Deferred<ExecutionResult, E>>();\n\n // Exits (not just successes) so a replayed failure re-fails through the\n // typed channel — hosts render engine failures opaquely, and a replay must\n // not bypass that by flattening the cause into result text.\n const recordSettledOutcome = (executionId: string, exit: Exit.Exit<ExecutionResult, E>): void => {\n settledOutcomes.set(executionId, exit);\n while (settledOutcomes.size > SETTLED_OUTCOME_LIMIT) {\n const oldest = settledOutcomes.keys().next().value;\n if (oldest === undefined) break;\n settledOutcomes.delete(oldest);\n }\n };\n\n /**\n * Race a running fiber against the pause queue. Returns when either\n * the fiber completes or an elicitation handler fires (whichever\n * comes first). Re-used by both executeWithPause and resume.\n *\n * `Effect.raceFirst` (not `Effect.race`) — `race` has prefer-success\n * semantics in Effect v4 (\"first successful result\"), which means a\n * fiber failure waits indefinitely for the pause Deferred to succeed.\n * For a fast `codeExecutor.execute` failure (e.g. a syntax error\n * inside the dynamic worker) the pause signal never fires, so the\n * outer Effect hangs until the upstream client gives up. `raceFirst`\n * settles on whichever side completes first, success or failure.\n */\n const awaitCompletionOrPause = (\n fiber: Fiber.Fiber<ExecuteResult, E>,\n pauseQueue: Queue.Queue<InternalPausedExecution<E>>,\n ): Effect.Effect<ExecutionResult, E> =>\n Effect.raceFirst(\n Fiber.join(fiber).pipe(\n Effect.map((result): ExecutionResult => ({ status: \"completed\", result })),\n ),\n Queue.take(pauseQueue).pipe(\n Effect.map((paused): ExecutionResult => ({ status: \"paused\", execution: paused })),\n ),\n );\n\n /**\n * Start an execution in pause/resume mode.\n *\n * The sandbox is forked as a daemon because paused executions can outlive the\n * caller scope that returned the first pause, such as an HTTP request handler.\n */\n const startPausableExecution = Effect.fn(\"mcp.execute\")(function* (code: string) {\n yield* Effect.annotateCurrentSpan({\n \"mcp.execute.mode\": \"pausable\",\n \"mcp.execute.code_length\": code.length,\n });\n\n // Queue preserves pauses that arrive before the previous approval has\n // returned to the caller, which can happen with concurrent tool calls.\n const pauseQueue = yield* Queue.unbounded<InternalPausedExecution<E>>();\n\n // Will be set once the fiber is forked.\n let fiber: Fiber.Fiber<ExecuteResult, E>;\n\n const elicitationHandler: ElicitationHandler = (ctx) =>\n Effect.gen(function* () {\n const responseDeferred = yield* Deferred.make<typeof ElicitationResponse.Type>();\n // Globally unique — engine instances are rebuilt on host restarts\n // (Durable Object cold restores, redeploys), so a counter would\n // re-mint the same ids and let a stale client resume bind to a\n // different execution's pause.\n const id = `exec_${crypto.randomUUID()}`;\n\n const paused: InternalPausedExecution<E> = {\n id,\n elicitationContext: ctx,\n response: responseDeferred,\n fiber: fiber!,\n pauseQueue,\n };\n pausedExecutions.set(id, paused);\n\n yield* Queue.offer(pauseQueue, paused);\n\n // Suspend until resume() completes responseDeferred.\n return yield* Deferred.await(responseDeferred);\n });\n\n const invoker = makeFullInvoker(\n executor,\n { onElicitation: elicitationHandler },\n toolDiscoveryProvider,\n );\n fiber = yield* Effect.forkDetach(\n codeExecutor.execute(code, invoker).pipe(Effect.withSpan(\"executor.code.exec\")),\n );\n\n // When the fiber settles on its own (sandbox timeout, failure) while\n // pauses are still outstanding, drop them: getPausedExecution must not\n // report a pause whose fiber can no longer consume a response, and the\n // map must not grow forever. A resume retry still finds the terminal\n // outcome via the settled-outcome cache.\n const sandboxFiber = fiber;\n yield* Effect.forkDetach(\n Fiber.await(sandboxFiber).pipe(\n Effect.flatMap((exit) =>\n Effect.sync(() => {\n const outcome = Exit.map(\n exit,\n (result): ExecutionResult => ({ status: \"completed\", result }),\n );\n for (const [id, paused] of pausedExecutions) {\n if (paused.fiber !== sandboxFiber) continue;\n pausedExecutions.delete(id);\n recordSettledOutcome(id, outcome);\n }\n }),\n ),\n ),\n );\n\n return (yield* awaitCompletionOrPause(fiber, pauseQueue)) as ExecutionResult;\n });\n\n /**\n * Resume a paused execution. Completes the response Deferred to unblock the\n * fiber, then races completion against the next queued or future pause.\n *\n * Idempotent per executionId: MCP clients retry `resume` when a response is\n * lost in transit, so a duplicate of an already-delivered resume replays the\n * recorded outcome, and a duplicate that arrives while the first is still\n * in flight awaits the same outcome instead of reporting a missing pause.\n */\n const resumeExecution = Effect.fn(\"mcp.execute.resume\")(function* (\n executionId: string,\n response: ResumeResponse,\n ) {\n yield* Effect.annotateCurrentSpan({\n \"mcp.execute.resume.action\": response.action,\n });\n\n const settled = settledOutcomes.get(executionId);\n if (settled) {\n yield* Effect.annotateCurrentSpan({ \"mcp.execute.resume.replayed\": true });\n return (yield* settled) as ExecutionResult;\n }\n\n const pending = pendingResumes.get(executionId);\n if (pending) {\n yield* Effect.annotateCurrentSpan({ \"mcp.execute.resume.joined_inflight\": true });\n return (yield* Deferred.await(pending)) as ExecutionResult;\n }\n\n const paused = pausedExecutions.get(executionId);\n if (!paused) return null;\n pausedExecutions.delete(executionId);\n\n const inflight = yield* Deferred.make<ExecutionResult, E>();\n pendingResumes.set(executionId, inflight);\n\n yield* Deferred.succeed(paused.response, {\n action: response.action as typeof ElicitationResponse.Type.action,\n content: response.content,\n });\n\n return (yield* awaitCompletionOrPause(paused.fiber, paused.pauseQueue).pipe(\n Effect.onExit((exit) =>\n Effect.gen(function* () {\n recordSettledOutcome(executionId, exit);\n pendingResumes.delete(executionId);\n yield* Deferred.done(inflight, exit);\n }),\n ),\n )) as ExecutionResult;\n });\n\n /**\n * Inline-elicitation execute path. Wrapped so every call produces an\n * `mcp.execute` span with the inner `executor.code.exec` as a child.\n */\n const runInlineExecution = Effect.fn(\"mcp.execute\")(function* (\n code: string,\n options: { readonly onElicitation: ElicitationHandler },\n ) {\n yield* Effect.annotateCurrentSpan({\n \"mcp.execute.mode\": \"inline\",\n \"mcp.execute.code_length\": code.length,\n });\n const invoker = makeFullInvoker(\n executor,\n {\n onElicitation: options.onElicitation,\n },\n toolDiscoveryProvider,\n );\n return yield* codeExecutor.execute(code, invoker).pipe(Effect.withSpan(\"executor.code.exec\"));\n });\n\n return {\n execute: runInlineExecution,\n executeWithPause: startPausableExecution,\n resume: resumeExecution,\n getPausedExecution: (executionId) =>\n Effect.sync(() => pausedExecutions.get(executionId) ?? null),\n getDescription: buildExecuteDescription(executor),\n };\n};\n"],"mappings":";AAAA,YAAY,UAAU;AAUtB,SAAS,0BAA0B;AAR5B,IAAM,qBAAN,cAAsC,iBAAY,oBAAoB,EAG1E;AAAC;;;ACLJ,SAAS,QAAQ,iBAAiB;AAClC,YAAY,WAAW;AASvB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAIP,IAAM,wBAAwB;AAC9B,IAAM,iCAAiC;AACvC,IAAM,wBACJ;AAIF,IAAM,4BAA4B;AAClC,IAAM,uBACJ;AAEF,IAAM,uBAAuB,CAAC,qBAC5B,qBAAqB,oBAAoB,SAAS;AAEpD,IAAM,4BAA4B,CAChC,iBAC4B;AAAA,EAC5B,GAAI,eAAe,CAAC;AAAA,EACpB,WAAW;AAAA,EACX,cAAc;AAAA,EACd,UAAU;AACZ;AAEA,IAAM,iBAAiB;AAcvB,IAAM,gBAAgB,CAAC,SAA8B;AACnD,MAAI,KAAK,WAAW,cAAc,EAAG,QAAO,YAAY,KAAK,IAAI;AACjE,MAAI,iBAAiB,GAAG,cAAc,GAAG,IAAI,EAAE,GAAG;AAChD,WAAO,YAAY,KAAK,GAAG,cAAc,GAAG,IAAI,EAAE;AAAA,EACpD;AACA,SAAO,YAAY,KAAK,IAAI;AAC9B;AAIA,IAAM,gBAAgB,CAAC,YACrB,QAAQ,WAAW,cAAc,IAAI,QAAQ,MAAM,eAAe,MAAM,IAAI;AAiB9E,IAAM,4BAAgE,oBAAI,IAGxE;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,MACb,iBAAiB;AAAA,MACjB,kBACE;AAAA,MACF,uBAAuB;AAAA,QACrB,qBACE;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,MACb,iBAAiB;AAAA,MACjB,kBACE;AAAA,MACF,uBAAuB;AAAA,QACrB,wBACE;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,MACb,iBAAiB;AAAA,MACjB,kBAAkB;AAAA,MAClB,uBAAuB;AAAA,QACrB,eACE;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AACF,CAAC;AAED,IAAM,mBAAmB,MAAc;AAGrC,SAAO,KAAK,MAAM,KAAK,OAAO,IAAI,UAAa,EAC5C,SAAS,EAAE,EACX,SAAS,GAAG,GAAG;AACpB;AAEA,IAAM,mBAAmB,CAAC,UAA8C;AACtE,MAAI,OAAO,UAAU,YAAY,UAAU,KAAM,QAAO;AACxD,QAAM,SAAU,MAAwC;AACxD,SAAO,MAAM,QAAQ,MAAM,IAAI,SAAS;AAC1C;AAEA,IAAM,kCAAkC,CAAC,UAKvC,gBAAgB;AAAA,EACd,MAAM,MAAM,mBAAmB,OAAO,0BAA0B;AAAA,EAChE,SACE,MAAM,mBAAmB,OACrB,qBAAqB,MAAM,KAAK,+BAA+B,MAAM,OAAO,KAC5E,qBAAqB,MAAM,KAAK,4BAA4B,MAAM,OAAO;AAAA,EAC/E,YAAY;AAAA,IACV,MAAM;AAAA,IACN,OAAO,MAAM;AAAA,EACf;AACF,CAAC;AAEH,IAAM,sBAAsB,CAAC,UAAqC;AAChE,MAAI,UAAU,SAAS,OAAO,mBAAmB,KAAK,aAAa,OAAO;AACxE,UAAM,cACJ,iBAAiB,SAAS,MAAM,QAAQ,MAAM,WAAW,IACrD,MAAM,YAAY,IAAI,CAAC,eAAe,cAAc,OAAO,UAAU,CAAC,CAAC,IACvE;AACN,UAAM,UAAU,cAAc,OAAO,MAAM,OAAO,CAAC;AACnD,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS,mBAAmB,OAAO;AAAA,MACnC,SAAS,EAAE,MAAM,SAAS,GAAI,cAAc,EAAE,YAAY,IAAI,CAAC,EAAG;AAAA,IACpE;AAAA,EACF;AACA,MAAI,UAAU,SAAS,OAAO,kBAAkB,KAAK,aAAa,OAAO;AACvE,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS,2BAA2B,cAAc,OAAO,MAAM,OAAO,CAAC,CAAC;AAAA,MACxE,SAAS;AAAA,IACX;AAAA,EACF;AACA,MAAI,UAAU,SAAS,OAAO,qBAAqB,GAAG;AACpD,UAAM,SAAS,iBAAkB,MAAuC,KAAK;AAC7E,QAAI,QAAQ;AACV,aAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS,EAAE,OAAO;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAQA,IAAM,mBAAmB,CAAC,SAAyB;AACjD,QAAM,aAAa,cAAc,IAAI;AACrC,QAAM,MAAM,WAAW,QAAQ,GAAG;AAClC,SAAO,QAAQ,KAAK,aAAa,WAAW,MAAM,GAAG,GAAG;AAC1D;AAeO,IAAM,0BAA0B,CACrC,UACA,aACwB;AAAA,EACxB,QAAQ,OAAO,GAAG,mBAAmB,EAAE,WAAW,EAAE,MAAM,KAAK,GAAG;AAChE,WAAO,OAAO,oBAAoB;AAAA,MAChC,iBAAiB;AAAA,MACjB,wBAAwB,iBAAiB,IAAI;AAAA,IAC/C,CAAC;AAED,UAAM,UAAU,cAAc,IAAI;AAClC,UAAM,SAAS,OAAO,SAAS,QAAQ,SAAS,MAAM,QAAQ,aAAa,EAAE;AAAA,MAC3E,OAAO;AAAA,QAAS;AAAA,QAA6B,CAAC,QAC5C,OAAO;AAAA,UACL,gCAAgC;AAAA,YAC9B,OAAO,GAAG,IAAI,WAAW,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI;AAAA,YAClD,SAAS,IAAI;AAAA,YACb,gBAAgB,IAAI;AAAA,UACtB,CAAC;AAAA,QACH;AAAA,MACF;AAAA,MACA,OAAO,WAAW,CAAC,UAAU;AAC3B,cAAM,MAAM,MAAM,QAAQ,KAAW,kBAAY,GAAG;AACpD,cAAM,WAAW,oBAAoB,GAAG;AACxC,YAAI,UAAU;AACZ,iBAAO,OAAO,QAAQ,WAAW,KAAK,QAAQ,CAAC;AAAA,QACjD;AACA,YAAI,2BAA2B,GAAG,GAAG;AACnC,iBAAO,OAAO;AAAA,YACZ,IAAI,mBAAmB;AAAA,cACrB,SAAS,SAAS,cAAc,OAAO,IAAI,OAAO,CAAC,CAAC,2CAA2C,IAAI,WAAW,WAAW,cAAc,UAAU;AAAA,cACjJ,OAAO;AAAA,YACT,CAAC;AAAA,UACH;AAAA,QACF;AAOA,cAAM,gBAAgB,iBAAiB;AACvC,eAAO,OAAO,SAAS,wBAAwB,KAAK,EAAE;AAAA,UACpD,OAAO,aAAa;AAAA,YAClB,2BAA2B;AAAA,YAC3B,iBAAiB;AAAA,UACnB,CAAC;AAAA,UACD,OAAO;AAAA,YAAQ,MACb,OAAO;AAAA,cACL,IAAI,mBAAmB;AAAA,gBACrB,SAAS,GAAG,qBAAqB,KAAK,aAAa;AAAA,gBACnD,OAAO,OAAO;AAAA,cAChB,CAAC;AAAA,YACH;AAAA,UACF;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AASA,WAAO,0BAA0B,MAAM;AACvC,QAAI,aAAa,MAAM,GAAG;AACxB,aAAO;AAAA,IACT;AACA,WAAO,EAAE,IAAI,MAAM,MAAM,OAAO;AAAA,EAClC,CAAC;AACH;AAEA,IAAM,6BAA6B,CACjC,UAMA,UAAU,SAAS,OAAO,0BAA0B,KACpD,UAAU,QACV,OAAO,UAAU,YACjB,aAAa,SACb,OAAO,MAAM,YAAY,YACzB,YAAY,UACX,MAAM,WAAW,YAAY,MAAM,WAAW;AAsDjD,IAAM,WAAW,CAAI,KAAmB,QAAgB,UAAkC;AACxF,QAAM,QAAQ,IAAI;AAClB,QAAM,QAAQ,KAAK,IAAI,KAAK,IAAI,QAAQ,CAAC,GAAG,KAAK;AACjD,QAAM,QAAQ,IAAI,MAAM,OAAO,QAAQ,KAAK;AAC5C,QAAM,WAAW,QAAQ,MAAM;AAC/B,QAAM,UAAU,WAAW;AAC3B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY,UAAU,WAAW;AAAA,EACnC;AACF;AAWA,IAAM,mBAAmB,CAAC,UAAgC;AAAA,EACxD,MAAM,cAAc,OAAO,KAAK,OAAO,CAAC;AAAA,EACxC,aAAa,OAAO,KAAK,WAAW;AAAA,EACpC,MAAM,OAAO,KAAK,IAAI;AAAA,EACtB,aAAa,KAAK;AACpB;AAOA,IAAM,uBAAuB;AAAA,EAC3B,MAAM;AAAA,EACN,aAAa;AAAA,EACb,MAAM;AAAA,EACN,aAAa;AACf;AAEA,IAAM,sBAAsB,CAAC,UAC3B,MACG,QAAQ,sBAAsB,OAAO,EACrC,QAAQ,aAAa,GAAG,EACxB,YAAY,EACZ,KAAK;AAEV,IAAM,qBAAqB,CAAC,UAC1B,oBAAoB,KAAK,EACtB,MAAM,YAAY,EAClB,IAAI,CAAC,UAAU,MAAM,KAAK,CAAC,EAC3B,OAAO,OAAO;AAEnB,IAAM,eAAe,CAAC,WAAmC;AAAA,EACvD,KAAK,oBAAoB,SAAS,EAAE;AAAA,EACpC,QAAQ,mBAAmB,SAAS,EAAE;AACxC;AAEA,IAAM,qBAAqB,CACzB,OACA,aACA,OACA,WAKG;AACH,MAAI,MAAM,IAAI,WAAW,GAAG;AAC1B,WAAO;AAAA,MACL,OAAO;AAAA,MACP,eAAe,oBAAI,IAAY;AAAA,MAC/B,kBAAkB;AAAA,IACpB;AAAA,EACF;AAEA,MAAI,QAAQ;AACZ,QAAM,gBAAgB,oBAAI,IAAY;AACtC,QAAM,mBAAmB,MAAM,SAAS,KAAK,MAAM,IAAI,SAAS,KAAK;AAErE,MAAI,MAAM,SAAS,GAAG;AACpB,QAAI,MAAM,QAAQ,OAAO;AACvB,eAAS,SAAS;AAAA,IACpB,WAAW,MAAM,IAAI,WAAW,KAAK,GAAG;AACtC,eAAS,SAAS;AAAA,IACpB,WAAW,kBAAkB;AAC3B,eAAS,SAAS;AAAA,IACpB;AAAA,EACF;AAEA,aAAW,SAAS,aAAa;AAC/B,QAAI,MAAM,OAAO,SAAS,KAAK,GAAG;AAChC,eAAS,SAAS;AAClB,oBAAc,IAAI,KAAK;AACvB;AAAA,IACF;AAEA,QACE,MAAM,OAAO,KAAK,CAAC,cAAc,UAAU,WAAW,KAAK,KAAK,MAAM,WAAW,SAAS,CAAC,GAC3F;AACA,eAAS,SAAS;AAClB,oBAAc,IAAI,KAAK;AACvB;AAAA,IACF;AAEA,QAAI,MAAM,IAAI,SAAS,KAAK,GAAG;AAC7B,eAAS;AACT,oBAAc,IAAI,KAAK;AAAA,IACzB;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,IAAM,mBAAmB,CAAC,MAAsB,cAAgC;AAC9E,MAAI,CAAC,aAAa,oBAAoB,SAAS,EAAE,WAAW,GAAG;AAC7D,WAAO;AAAA,EACT;AAEA,QAAM,kBAAkB,mBAAmB,SAAS;AACpD,MAAI,gBAAgB,WAAW,GAAG;AAChC,WAAO;AAAA,EACT;AAEA,QAAM,oBAAoB,mBAAmB,KAAK,WAAW;AAC7D,QAAM,aAAa,mBAAmB,KAAK,IAAI;AAE/C,QAAM,gBAAgB,CAAC,WACrB,gBAAgB,MAAM,CAAC,OAAO,UAAU,OAAO,KAAK,MAAM,KAAK;AAEjE,SAAO,cAAc,iBAAiB,KAAK,cAAc,UAAU;AACrE;AAEA,IAAM,iBAAiB,CAAC,MAAsB,UAA8C;AAC1F,QAAM,kBAAkB,oBAAoB,KAAK;AACjD,QAAM,cAAc,mBAAmB,KAAK;AAE5C,MAAI,gBAAgB,WAAW,KAAK,YAAY,WAAW,GAAG;AAC5D,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,aAAa,KAAK,IAAI;AACnC,QAAM,cAAc,aAAa,KAAK,WAAW;AACjD,QAAM,OAAO,aAAa,KAAK,IAAI;AACnC,QAAM,cAAc,aAAa,KAAK,WAAW;AAEjD,QAAM,cAAc;AAAA,IAClB,mBAAmB,iBAAiB,aAAa,MAAM,qBAAqB,IAAI;AAAA,IAChF,mBAAmB,iBAAiB,aAAa,aAAa,qBAAqB,WAAW;AAAA,IAC9F,mBAAmB,iBAAiB,aAAa,MAAM,qBAAqB,IAAI;AAAA,IAChF,mBAAmB,iBAAiB,aAAa,aAAa,qBAAqB,WAAW;AAAA,EAChG;AAEA,QAAM,gBAAgB,oBAAI,IAAY;AACtC,MAAI,QAAQ;AACZ,MAAI,mBAAmB;AAEvB,aAAW,cAAc,aAAa;AACpC,aAAS,WAAW;AACpB,yBAAqB,WAAW;AAChC,eAAW,SAAS,WAAW,eAAe;AAC5C,oBAAc,IAAI,KAAK;AAAA,IACzB;AAAA,EACF;AAEA,MAAI,cAAc,SAAS,GAAG;AAC5B,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,cAAc,OAAO,YAAY;AAClD,QAAM,kBAAkB,YAAY,UAAU,IAAI,IAAI;AAEtD,MAAI,WAAW,mBAAmB,CAAC,kBAAkB;AACnD,WAAO;AAAA,EACT;AAEA,MAAI,aAAa,GAAG;AAClB,aAAS;AAAA,EACX,OAAO;AACL,aAAS,KAAK,MAAM,WAAW,EAAE;AAAA,EACnC;AAEA,MAAI,KAAK,OAAO,CAAC,MAAM,YAAY,CAAC,KAAK,KAAK,OAAO,CAAC,MAAM,YAAY,CAAC,GAAG;AAC1E,aAAS;AAAA,EACX;AAEA,MACE,oBAAoB,KAAK,IAAI,MAAM,mBACnC,oBAAoB,KAAK,IAAI,MAAM,iBACnC;AACA,aAAS;AAAA,EACX;AAEA,SAAO;AAAA,IACL,MAAM,KAAK;AAAA,IACX,MAAM,KAAK;AAAA,IACX,aAAa,KAAK;AAAA,IAClB,aAAa,KAAK;AAAA,IAClB;AAAA,EACF;AACF;AAGO,IAAM,cAAc,OAAO,GAAG,uBAAuB,EAAE,WAC5D,UACA,OACA,QAAQ,IACR,SACA;AACA,QAAM,SAAS,SAAS,UAAU;AAClC,SAAO,OAAO,oBAAoB;AAAA,IAChC,gCAAgC,MAAM;AAAA,IACtC,yBAAyB;AAAA,IACzB,0BAA0B;AAAA,IAC1B,GAAI,SAAS,YAAY,EAAE,6BAA6B,QAAQ,UAAU,IAAI,CAAC;AAAA,EACjF,CAAC;AAED,QAAM,QAA0C;AAAA,IAC9C,OAAO,CAAC;AAAA,IACR,OAAO;AAAA,IACP,SAAS;AAAA,IACT,YAAY;AAAA,EACd;AAEA,MAAI,oBAAoB,KAAK,EAAE,WAAW,GAAG;AAC3C,WAAO;AAAA,EACT;AAEA,QAAM,MAAM,OAAO,SAAS,MAAM,KAAK,EAAE,oBAAoB,MAAM,CAAC,EAAE;AAAA,IACpE,OAAO;AAAA,MACL,CAAC,UACC,IAAI,mBAAmB;AAAA,QACrB,SAAS;AAAA,QACT;AAAA,MACF,CAAC;AAAA,IACL;AAAA,EACF;AACA,QAAM,aAAa,IAAI,IAAI,gBAAgB;AAC3C,QAAM,SAAS,WACZ,OAAO,CAAC,SAAyB,iBAAiB,MAAM,SAAS,SAAS,CAAC,EAC3E,IAAI,CAAC,SAAyB,eAAe,MAAM,KAAK,CAAC,EACzD,OAAO,UAAU,SAAS,EAC1B,KAAK,CAAC,MAAM,UAAU,MAAM,QAAQ,KAAK,SAAS,KAAK,KAAK,cAAc,MAAM,IAAI,CAAC;AAExF,QAAM,OAAO,SAAS,QAAQ,QAAQ,KAAK;AAE3C,SAAO,OAAO,oBAAoB;AAAA,IAChC,mCAAmC,IAAI;AAAA,IACvC,+BAA+B,OAAO;AAAA,IACtC,gCAAgC,KAAK,MAAM;AAAA,IAC3C,4BAA4B,KAAK;AAAA,EACnC,CAAC;AACD,SAAO;AACT,CAAC;AAEM,IAAM,+BAAsD;AAAA,EACjE,aAAa,CAAC,EAAE,UAAU,OAAO,WAAW,OAAO,OAAO,MACxD,YAAY,UAAU,OAAO,OAAO,EAAE,WAAW,OAAO,CAAC;AAC7D;AAKO,IAAM,sBAAsB,OAAO,GAAG,uBAAuB,EAAE,WACpE,UACA,SAKA;AACA,QAAM,kBAAkB,oBAAoB,SAAS,SAAS,EAAE;AAChE,QAAM,QAAQ,SAAS,SAAS;AAChC,QAAM,SAAS,SAAS,UAAU;AAClC,QAAM,eAAe,OAAO,SAAS,aAAa,KAAK,EAAE;AAAA,IACvD,OAAO;AAAA,MACL,CAAC,UACC,IAAI,mBAAmB;AAAA,QACrB,SAAS;AAAA,QACT;AAAA,MACF,CAAC;AAAA,IACL;AAAA,EACF;AAEA,QAAM,WACJ,gBAAgB,WAAW,IACvB,eACA,aAAa,OAAO,CAAC,gBAA6B;AAChD,UAAM,WAAW;AAAA,MACf,CAAC,OAAO,YAAY,IAAI,GAAG,YAAY,aAAa,YAAY,IAAI,EAAE,KAAK,GAAG;AAAA,IAChF;AACA,WAAO,mBAAmB,eAAe,EAAE,MAAM,CAAC,UAAU,SAAS,SAAS,KAAK,CAAC;AAAA,EACtF,CAAC;AAGP,QAAM,WAAW,OAAO,SAAS,MAAM,KAAK,EAAE,oBAAoB,MAAM,CAAC,EAAE;AAAA,IACzE,OAAO;AAAA,MACL,CAAC,UACC,IAAI,mBAAmB;AAAA,QACrB,SAAS;AAAA,QACT;AAAA,MACF,CAAC;AAAA,IACL;AAAA,EACF;AACA,QAAM,yBAAyB,oBAAI,IAAoB;AACvD,aAAW,QAAQ,UAAU;AAC3B,UAAM,MAAM,OAAO,KAAK,WAAW;AACnC,2BAAuB,IAAI,MAAM,uBAAuB,IAAI,GAAG,KAAK,KAAK,CAAC;AAAA,EAC5E;AAEA,QAAM,mBAAmB,SACtB;AAAA,IACC,CAAC,iBACE;AAAA,MACC,IAAI,OAAO,YAAY,IAAI;AAAA,MAC3B,MAAM,OAAO,YAAY,IAAI;AAAA;AAAA;AAAA;AAAA,MAI7B,GAAI,YAAY,eAChB,YAAY,YAAY,YAAY,MAAM,OAAO,YAAY,IAAI,EAAE,YAAY,KAC/E,YAAY,YAAY,YAAY,MAAM,YAAY,KAAK,YAAY,IACnE,EAAE,aAAa,YAAY,YAAY,IACvC,CAAC;AAAA,MACL,MAAM,YAAY;AAAA,MAClB,WAAW,YAAY;AAAA,MACvB,YAAY,YAAY;AAAA,MACxB,WAAW,uBAAuB,IAAI,OAAO,YAAY,IAAI,CAAC,KAAK;AAAA,IACrE;AAAA,EACJ,EACC,KAAK,CAAC,MAAM,UAAU,KAAK,KAAK,cAAc,MAAM,IAAI,KAAK,KAAK,GAAG,cAAc,MAAM,EAAE,CAAC;AAE/F,QAAM,OAAO,SAAS,kBAAkB,QAAQ,KAAK;AAErD,SAAO,OAAO,oBAAoB;AAAA,IAChC,oCAAoC,aAAa;AAAA,IACjD,gCAAgC,iBAAiB;AAAA,IACjD,iCAAiC,KAAK,MAAM;AAAA,IAC5C,6BAA6B,KAAK;AAAA,EACpC,CAAC;AACD,SAAO;AACT,CAAC;AAGM,IAAM,eAAe,OAAO,GAAG,yBAAyB,EAAE,WAC/D,UACA,MACA;AACA,SAAO,OAAO,oBAAoB,EAAE,iBAAiB,KAAK,CAAC;AAE3D,QAAM,UAAU,0BAA0B,IAAI,IAAI;AAClD,MAAI,QAAS,QAAO;AAEpB,QAAM,UAAU,cAAc,IAAI;AAIlC,QAAM,SAAgC,OAAO,SAAS,MAAM,OAAO,OAAO;AAM1E,MAAI,WAAW,MAAM;AACnB,UAAM,UAAU,KAAK,YAAY,GAAG;AACpC,UAAM,OAAO,YAAY,KAAK,OAAO,KAAK,MAAM,UAAU,CAAC;AAC3D,UAAM,SAAS,OAAO,YAAY,UAAU,MAAM,gCAAgC;AAAA,MAChF,WAAW,iBAAiB,IAAI;AAAA,IAClC,CAAC;AACD,UAAM,UACJ,OAAO,MAAM,SAAS,IAClB,OAAO,SACN,OAAO,YAAY,UAAU,MAAM,8BAA8B,GAAG;AAC3E,UAAM,cAAc,QAAQ,IAAI,CAAC,SAAS,KAAK,IAAI;AACnD,UAAM,WAA0B;AAAA,MAC9B;AAAA,MACA,MAAM;AAAA,MACN,OAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS,mBAAmB,IAAI;AAAA,QAChC,GAAI,YAAY,SAAS,IAAI,EAAE,YAAY,IAAI,CAAC;AAAA,MAClD;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAIA,QAAM,YAA2B;AAAA,IAC/B;AAAA,IACA,MAAM,OAAO,QAAQ;AAAA,IACrB,aAAa,OAAO;AAAA,IACpB,iBAAiB,OAAO;AAAA,IACxB,kBAAkB,qBAAqB,OAAO,gBAAgB;AAAA,IAC9D,uBAAuB,0BAA0B,OAAO,qBAAqB;AAAA,EAC/E;AACA,SAAO;AACT,CAAC;;;ACjwBD,SAAS,UAAAA,eAAc;AAchB,IAAM,0BAA0B,CAAC,aACtCA,QAAO,IAAI,aAAa;AACtB,QAAM,cAAqC,OAAO,SAAS,YAAY,KAAK,EAAE;AAAA;AAAA,IAE5EA,QAAO;AAAA,IACPA,QAAO,SAAS,2BAA2B;AAAA,EAC7C;AACA,QAAM,eAAuC,OAAO,SAAS,aAAa,KAAK,EAAE;AAAA;AAAA,IAE/EA,QAAO;AAAA,IACPA,QAAO,SAAS,4BAA4B;AAAA,EAC9C;AAEA,QAAM,cAAc,OAAOA,QAAO;AAAA,IAAK,MACrC,kBAAkB,YAAY,IAAI,CAAC,eAAe,gBAAgB,YAAY,YAAY,CAAC,CAAC;AAAA,EAC9F,EAAE;AAAA,IACAA,QAAO,SAAS,8BAA8B;AAAA,MAC5C,YAAY,EAAE,6BAA6B,YAAY,OAAO;AAAA,IAChE,CAAC;AAAA,EACH;AAEA,SAAOA,QAAO,oBAAoB;AAAA,IAChC,6BAA6B,YAAY;AAAA,IACzC,eAAe;AAAA;AAAA;AAAA,IAGf,iCAAiC,YAC9B,IAAI,CAAC,eAAe,eAAe,UAAU,CAAC,EAC9C,MAAM,GAAG,EAAE,EACX,KAAK,GAAG;AAAA,IACX,oCAAoC;AAAA,MAClC,GAAG,IAAI,IAAI,YAAY,IAAI,CAAC,eAAe,OAAO,WAAW,WAAW,CAAC,CAAC;AAAA,IAC5E,EAAE,KAAK,GAAG;AAAA,IACV,8BAA8B;AAAA,MAC5B,GAAG,IAAI,IAAI,YAAY,IAAI,CAAC,eAAe,WAAW,KAAK,CAAC;AAAA,IAC9D,EAAE,KAAK,GAAG;AAAA,EACZ,CAAC;AAED,SAAO;AACT,CAAC,EAAE,KAAKA,QAAO,SAAS,yBAAyB,CAAC;AAEpD,IAAM,iBAAiB,CAAC,eAAmC;AACzD,QAAM,UAAU,OAAO,WAAW,OAAO;AACzC,SAAO,QAAQ,WAAW,QAAQ,IAAI,QAAQ,MAAM,SAAS,MAAM,IAAI;AACzE;AAUA,IAAM,gBAAgB,CACpB,MACA,mBACuB;AACvB,QAAM,aAAa,QAAQ,IAAI,MAAM,MAAM,CAAC,EAAE,CAAC,EAAG,KAAK;AACvD,MAAI,UAAU,WAAW,EAAG,QAAO;AAGnC,MAAI,eAAe,KAAK,CAAC,SAAS,UAAU,YAAY,MAAM,KAAK,YAAY,CAAC,GAAG;AACjF,WAAO;AAAA,EACT;AACA,SAAO,UAAU,SAAS,MAAM,GAAG,UAAU,MAAM,GAAG,GAAG,CAAC,WAAM;AAClE;AAEA,IAAM,kBAAkB,CACtB,YACA,iBAC6B;AAC7B,QAAM,OAAO,OAAO,WAAW,WAAW;AAC1C,QAAM,cAAc,aAAa,KAAK,CAAC,cAAc,OAAO,UAAU,IAAI,MAAM,IAAI;AACpF,QAAM,iBAAiB,CAAC,MAAM,GAAI,cAAc,CAAC,YAAY,IAAI,IAAI,CAAC,CAAE;AACxE,SAAO;AAAA,IACL,QAAQ,eAAe,UAAU;AAAA,IACjC,aACE,cAAc,WAAW,aAAa,cAAc,KACpD,cAAc,aAAa,aAAa,cAAc;AAAA,EAC1D;AACF;AAEA,IAAM,oBAAoB,CAAC,sBAAmE;AAC5F,QAAM,QAAkB;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,kBAAkB,SAAS,GAAG;AAChC,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,kCAAkC;AAC7C,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,gEAAgE;AAC3E,UAAM,SAAS,CAAC,GAAG,iBAAiB,EACjC,KAAK,CAAC,GAAG,MAAM,EAAE,OAAO,cAAc,EAAE,MAAM,CAAC,EAC/C,MAAM,GAAG,EAAE;AACd,eAAW,SAAS,QAAQ;AAC1B,YAAM;AAAA,QACJ,MAAM,cACF,OAAO,MAAM,MAAM,aAAQ,MAAM,WAAW,KAC5C,OAAO,MAAM,MAAM;AAAA,MACzB;AAAA,IACF;AACA,QAAI,kBAAkB,SAAS,OAAO,QAAQ;AAC5C,YAAM,KAAK,SAAS,kBAAkB,SAAS,OAAO,MAAM,OAAO;AAAA,IACrE;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;;;ACrJA,SAAS,UAAU,UAAAC,SAAQ,OAAO,aAAAC,YAAW,aAAa;AAE1D,YAAY,UAAU;AAyDtB,IAAM,oBAAoB;AAE1B,IAAM,WAAW,CAAC,OAAe,QAC/B,MAAM,SAAS,MACX,GAAG,MAAM,MAAM,GAAG,GAAG,CAAC;AAAA,iBAAoB,MAAM,SAAS,GAAG,YAC5D;AAEC,IAAM,sBAAsB,CACjC,WAKG;AACH,QAAM,aACJ,OAAO,UAAU,OACb,OAAO,OAAO,WAAW,WACvB,OAAO,SACP,KAAK,UAAU,OAAO,QAAQ,MAAM,CAAC,IACvC;AAEN,QAAM,UAAU,OAAO,QAAQ,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,KAAK,IAAI,IAAI;AAEjF,MAAI,OAAO,OAAO;AAChB,UAAMC,SAAQ,CAAC,UAAU,OAAO,KAAK,IAAI,GAAI,UAAU,CAAC;AAAA;AAAA,EAAY,OAAO,EAAE,IAAI,CAAC,CAAE;AACpF,WAAO;AAAA,MACL,MAAM,SAASA,OAAM,KAAK,IAAI,GAAG,iBAAiB;AAAA,MAClD,YAAY,EAAE,QAAQ,SAAS,OAAO,OAAO,OAAO,MAAM,OAAO,QAAQ,CAAC,EAAE;AAAA,MAC5E,SAAS;AAAA,IACX;AAAA,EACF;AAEA,QAAM,QAAQ;AAAA,IACZ,GAAI,aAAa,CAAC,SAAS,YAAY,iBAAiB,CAAC,IAAI,CAAC,aAAa;AAAA,IAC3E,GAAI,UAAU,CAAC;AAAA;AAAA,EAAY,OAAO,EAAE,IAAI,CAAC;AAAA,EAC3C;AACA,SAAO;AAAA,IACL,MAAM,MAAM,KAAK,IAAI;AAAA,IACrB,YAAY,EAAE,QAAQ,aAAa,QAAQ,OAAO,UAAU,MAAM,MAAM,OAAO,QAAQ,CAAC,EAAE;AAAA,IAC1F,SAAS;AAAA,EACX;AACF;AAEO,IAAM,wBAAwB,CACnC,WAIG;AACH,QAAM,MAAM,OAAO,mBAAmB;AACtC,QAAM,QAAkB,CAAC,qBAAqB,IAAI,OAAO,EAAE;AAC3D,QAAM,mBAAmBC,WAAU,SAAS,KAAK,gBAAgB;AACjE,QAAM,oBAAoBA,WAAU,SAAS,KAAK,iBAAiB;AACnE,QAAM,kBAAkB,oBAAoB,IAAI,kBAAkB;AAClE,QAAM,qBACJ,oBAAoB,UAAa,OAAO,KAAK,eAAe,EAAE,SAAS;AACzE,QAAM,eAAe,mBACjB,uIAAuI,OAAO,EAAE,2BAChJ,qBACE,iGAAiG,OAAO,EAAE,mIAC1G,gMAAgM,OAAO,EAAE;AAE/M,MAAI,kBAAkB;AACpB,UAAM,KAAK;AAAA;AAAA,EAAkC,IAAI,GAAG,EAAE;AACtD,UAAM,KAAK,sEAAsE;AAAA,EACnF,WAAW,oBAAoB;AAC7B,UAAM;AAAA,MACJ;AAAA,IACF;AACA,UAAM,KAAK;AAAA;AAAA,EAAwB,KAAK,UAAU,iBAAiB,MAAM,CAAC,CAAC,EAAE;AAAA,EAC/E,OAAO;AACL,UAAM;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AAEA,QAAM,KAAK;AAAA,eAAkB,OAAO,EAAE,EAAE;AACxC,QAAM,KAAK;AAAA,gBAAmB,YAAY,EAAE;AAE5C,SAAO;AAAA,IACL,MAAM,MAAM,KAAK,IAAI;AAAA,IACrB,YAAY;AAAA,MACV,QAAQ;AAAA,MACR,aAAa,OAAO;AAAA,MACpB,aAAa;AAAA,QACX,MAAM,mBAAmB,QAAQ;AAAA,QACjC,SAAS,IAAI;AAAA,QACb;AAAA,QACA,SAAS,OAAO,OAAO,mBAAmB,OAAO;AAAA,QACjD,MAAM,OAAO,mBAAmB;AAAA,QAChC,GAAI,mBAAmB,EAAE,KAAK,IAAI,IAAI,IAAI,CAAC;AAAA,QAC3C,GAAI,oBAAoB,EAAE,iBAAiB,IAAI,gBAAgB,IAAI,CAAC;AAAA,MACtE;AAAA,IACF;AAAA,EACF;AACF;AAMA,IAAM,WAAW,CAAC,UAChB,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAErE,IAAM,oBAAoB,CAAC,OAAgB,aAAkD;AAC3F,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,KAAK,SAAS,GAAG;AACtE,WAAO,IAAI,mBAAmB;AAAA,MAC5B,SAAS,GAAG,QAAQ;AAAA,IACtB,CAAC;AAAA,EACH;AAEA,SAAO,KAAK,MAAM,KAAK;AACzB;AAEA,IAAM,qBAAqB,CAAC,OAAgB,aAAkD;AAC5F,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,KAAK,QAAQ,GAAG;AACrE,WAAO,IAAI,mBAAmB;AAAA,MAC5B,SAAS,GAAG,QAAQ;AAAA,IACtB,CAAC;AAAA,EACH;AAEA,SAAO,KAAK,MAAM,KAAK;AACzB;AAEA,IAAM,kBAAkB,CACtB,UACA,eACA,0BACuB;AACvB,QAAM,OAAO,wBAAwB,UAAU,EAAE,cAAc,CAAC;AAChE,SAAO;AAAA,IACL,QAAQ,CAAC,EAAE,MAAM,KAAK,MAAM;AAC1B,UAAI,SAAS,UAAU;AACrB,YAAI,CAAC,SAAS,IAAI,GAAG;AACnB,iBAAOC,QAAO;AAAA,YACZ,IAAI,mBAAmB;AAAA,cACrB,SACE;AAAA,YACJ,CAAC;AAAA,UACH;AAAA,QACF;AAEA,YAAI,KAAK,UAAU,UAAa,OAAO,KAAK,UAAU,UAAU;AAC9D,iBAAOA,QAAO;AAAA,YACZ,IAAI,mBAAmB;AAAA,cACrB,SAAS;AAAA,YACX,CAAC;AAAA,UACH;AAAA,QACF;AAEA,YAAI,KAAK,cAAc,UAAa,OAAO,KAAK,cAAc,UAAU;AACtE,iBAAOA,QAAO;AAAA,YACZ,IAAI,mBAAmB;AAAA,cACrB,SAAS;AAAA,YACX,CAAC;AAAA,UACH;AAAA,QACF;AAEA,cAAM,QAAQ,kBAAkB,KAAK,OAAO,cAAc;AAC1D,YAAID,WAAU,SAAS,OAAO,oBAAoB,GAAG;AACnD,iBAAOC,QAAO,KAAK,KAAK;AAAA,QAC1B;AAEA,cAAM,SAAS,mBAAmB,KAAK,QAAQ,cAAc;AAC7D,YAAID,WAAU,SAAS,QAAQ,oBAAoB,GAAG;AACpD,iBAAOC,QAAO,KAAK,MAAM;AAAA,QAC3B;AAEA,eAAO,sBACJ,YAAY;AAAA,UACX;AAAA,UACA,OAAO,KAAK,SAAS;AAAA,UACrB;AAAA,UACA,WAAW,KAAK;AAAA,UAChB;AAAA,QACF,CAAC,EACA;AAAA,UACCA,QAAO,SAAS,qBAAqB;AAAA,YACnC,YAAY,EAAE,iBAAiB,MAAM,yBAAyB,KAAK;AAAA,UACrE,CAAC;AAAA,QACH;AAAA,MACJ;AACA,UAAI,SAAS,yBAAyB;AACpC,YAAI,SAAS,UAAa,CAAC,SAAS,IAAI,GAAG;AACzC,iBAAOA,QAAO;AAAA,YACZ,IAAI,mBAAmB;AAAA,cACrB,SACE;AAAA,YACJ,CAAC;AAAA,UACH;AAAA,QACF;AAEA,YAAI,SAAS,IAAI,KAAK,KAAK,UAAU,UAAa,OAAO,KAAK,UAAU,UAAU;AAChF,iBAAOA,QAAO;AAAA,YACZ,IAAI,mBAAmB;AAAA,cACrB,SAAS;AAAA,YACX,CAAC;AAAA,UACH;AAAA,QACF;AAEA,cAAM,QAAQ;AAAA,UACZ,SAAS,IAAI,IAAI,KAAK,QAAQ;AAAA,UAC9B;AAAA,QACF;AACA,YAAID,WAAU,SAAS,OAAO,oBAAoB,GAAG;AACnD,iBAAOC,QAAO,KAAK,KAAK;AAAA,QAC1B;AAEA,cAAM,SAAS;AAAA,UACb,SAAS,IAAI,IAAI,KAAK,SAAS;AAAA,UAC/B;AAAA,QACF;AACA,YAAID,WAAU,SAAS,QAAQ,oBAAoB,GAAG;AACpD,iBAAOC,QAAO,KAAK,MAAM;AAAA,QAC3B;AAEA,eAAO,oBAAoB,UAAU;AAAA,UACnC,OAAO,SAAS,IAAI,KAAK,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ;AAAA,UACvE;AAAA,UACA;AAAA,QACF,CAAC,EAAE;AAAA,UACDA,QAAO,SAAS,qBAAqB;AAAA,YACnC,YAAY,EAAE,iBAAiB,MAAM,yBAAyB,KAAK;AAAA,UACrE,CAAC;AAAA,QACH;AAAA,MACF;AACA,UAAI,SAAS,iBAAiB;AAC5B,YAAI,CAAC,SAAS,IAAI,GAAG;AACnB,iBAAOA,QAAO;AAAA,YACZ,IAAI,mBAAmB;AAAA,cACrB,SAAS;AAAA,YACX,CAAC;AAAA,UACH;AAAA,QACF;AAEA,YAAI,OAAO,KAAK,SAAS,YAAY,KAAK,KAAK,KAAK,EAAE,WAAW,GAAG;AAClE,iBAAOA,QAAO,KAAK,IAAI,mBAAmB,EAAE,SAAS,gCAAgC,CAAC,CAAC;AAAA,QACzF;AAEA,YAAI,oBAAoB,MAAM;AAC5B,iBAAOA,QAAO;AAAA,YACZ,IAAI,mBAAmB;AAAA,cACrB,SAAS;AAAA,YACX,CAAC;AAAA,UACH;AAAA,QACF;AAEA,eAAO,aAAa,UAAU,KAAK,IAAI,EAAE;AAAA,UACvCA,QAAO,SAAS,qBAAqB;AAAA,YACnC,YAAY;AAAA,cACV,iBAAiB;AAAA,cACjB,yBAAyB;AAAA,cACzB,6BAA6B,KAAK;AAAA,YACpC;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AACA,aAAO,KAAK,OAAO,EAAE,MAAM,KAAK,CAAC;AAAA,IACnC;AAAA,EACF;AACF;AAgDO,IAAM,wBAAwB,CACnC,WACuB;AACvB,QAAM,EAAE,UAAU,cAAc,wBAAwB,6BAA6B,IAAI;AACzF,QAAM,mBAAmB,oBAAI,IAAwC;AAOrE,QAAM,kBAAkB,oBAAI,IAA2C;AACvE,QAAM,wBAAwB;AAG9B,QAAM,iBAAiB,oBAAI,IAAmD;AAK9E,QAAM,uBAAuB,CAAC,aAAqB,SAA8C;AAC/F,oBAAgB,IAAI,aAAa,IAAI;AACrC,WAAO,gBAAgB,OAAO,uBAAuB;AACnD,YAAM,SAAS,gBAAgB,KAAK,EAAE,KAAK,EAAE;AAC7C,UAAI,WAAW,OAAW;AAC1B,sBAAgB,OAAO,MAAM;AAAA,IAC/B;AAAA,EACF;AAeA,QAAM,yBAAyB,CAC7B,OACA,eAEAA,QAAO;AAAA,IACL,MAAM,KAAK,KAAK,EAAE;AAAA,MAChBA,QAAO,IAAI,CAAC,YAA6B,EAAE,QAAQ,aAAa,OAAO,EAAE;AAAA,IAC3E;AAAA,IACA,MAAM,KAAK,UAAU,EAAE;AAAA,MACrBA,QAAO,IAAI,CAAC,YAA6B,EAAE,QAAQ,UAAU,WAAW,OAAO,EAAE;AAAA,IACnF;AAAA,EACF;AAQF,QAAM,yBAAyBA,QAAO,GAAG,aAAa,EAAE,WAAW,MAAc;AAC/E,WAAOA,QAAO,oBAAoB;AAAA,MAChC,oBAAoB;AAAA,MACpB,2BAA2B,KAAK;AAAA,IAClC,CAAC;AAID,UAAM,aAAa,OAAO,MAAM,UAAsC;AAGtE,QAAI;AAEJ,UAAM,qBAAyC,CAAC,QAC9CA,QAAO,IAAI,aAAa;AACtB,YAAM,mBAAmB,OAAO,SAAS,KAAsC;AAK/E,YAAM,KAAK,QAAQ,OAAO,WAAW,CAAC;AAEtC,YAAM,SAAqC;AAAA,QACzC;AAAA,QACA,oBAAoB;AAAA,QACpB,UAAU;AAAA,QACV;AAAA,QACA;AAAA,MACF;AACA,uBAAiB,IAAI,IAAI,MAAM;AAE/B,aAAO,MAAM,MAAM,YAAY,MAAM;AAGrC,aAAO,OAAO,SAAS,MAAM,gBAAgB;AAAA,IAC/C,CAAC;AAEH,UAAM,UAAU;AAAA,MACd;AAAA,MACA,EAAE,eAAe,mBAAmB;AAAA,MACpC;AAAA,IACF;AACA,YAAQ,OAAOA,QAAO;AAAA,MACpB,aAAa,QAAQ,MAAM,OAAO,EAAE,KAAKA,QAAO,SAAS,oBAAoB,CAAC;AAAA,IAChF;AAOA,UAAM,eAAe;AACrB,WAAOA,QAAO;AAAA,MACZ,MAAM,MAAM,YAAY,EAAE;AAAA,QACxBA,QAAO;AAAA,UAAQ,CAAC,SACdA,QAAO,KAAK,MAAM;AAChB,kBAAM,UAAe;AAAA,cACnB;AAAA,cACA,CAAC,YAA6B,EAAE,QAAQ,aAAa,OAAO;AAAA,YAC9D;AACA,uBAAW,CAAC,IAAI,MAAM,KAAK,kBAAkB;AAC3C,kBAAI,OAAO,UAAU,aAAc;AACnC,+BAAiB,OAAO,EAAE;AAC1B,mCAAqB,IAAI,OAAO;AAAA,YAClC;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAEA,WAAQ,OAAO,uBAAuB,OAAO,UAAU;AAAA,EACzD,CAAC;AAWD,QAAM,kBAAkBA,QAAO,GAAG,oBAAoB,EAAE,WACtD,aACA,UACA;AACA,WAAOA,QAAO,oBAAoB;AAAA,MAChC,6BAA6B,SAAS;AAAA,IACxC,CAAC;AAED,UAAM,UAAU,gBAAgB,IAAI,WAAW;AAC/C,QAAI,SAAS;AACX,aAAOA,QAAO,oBAAoB,EAAE,+BAA+B,KAAK,CAAC;AACzE,aAAQ,OAAO;AAAA,IACjB;AAEA,UAAM,UAAU,eAAe,IAAI,WAAW;AAC9C,QAAI,SAAS;AACX,aAAOA,QAAO,oBAAoB,EAAE,sCAAsC,KAAK,CAAC;AAChF,aAAQ,OAAO,SAAS,MAAM,OAAO;AAAA,IACvC;AAEA,UAAM,SAAS,iBAAiB,IAAI,WAAW;AAC/C,QAAI,CAAC,OAAQ,QAAO;AACpB,qBAAiB,OAAO,WAAW;AAEnC,UAAM,WAAW,OAAO,SAAS,KAAyB;AAC1D,mBAAe,IAAI,aAAa,QAAQ;AAExC,WAAO,SAAS,QAAQ,OAAO,UAAU;AAAA,MACvC,QAAQ,SAAS;AAAA,MACjB,SAAS,SAAS;AAAA,IACpB,CAAC;AAED,WAAQ,OAAO,uBAAuB,OAAO,OAAO,OAAO,UAAU,EAAE;AAAA,MACrEA,QAAO;AAAA,QAAO,CAAC,SACbA,QAAO,IAAI,aAAa;AACtB,+BAAqB,aAAa,IAAI;AACtC,yBAAe,OAAO,WAAW;AACjC,iBAAO,SAAS,KAAK,UAAU,IAAI;AAAA,QACrC,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC;AAMD,QAAM,qBAAqBA,QAAO,GAAG,aAAa,EAAE,WAClD,MACA,SACA;AACA,WAAOA,QAAO,oBAAoB;AAAA,MAChC,oBAAoB;AAAA,MACpB,2BAA2B,KAAK;AAAA,IAClC,CAAC;AACD,UAAM,UAAU;AAAA,MACd;AAAA,MACA;AAAA,QACE,eAAe,QAAQ;AAAA,MACzB;AAAA,MACA;AAAA,IACF;AACA,WAAO,OAAO,aAAa,QAAQ,MAAM,OAAO,EAAE,KAAKA,QAAO,SAAS,oBAAoB,CAAC;AAAA,EAC9F,CAAC;AAED,SAAO;AAAA,IACL,SAAS;AAAA,IACT,kBAAkB;AAAA,IAClB,QAAQ;AAAA,IACR,oBAAoB,CAAC,gBACnBA,QAAO,KAAK,MAAM,iBAAiB,IAAI,WAAW,KAAK,IAAI;AAAA,IAC7D,gBAAgB,wBAAwB,QAAQ;AAAA,EAClD;AACF;","names":["Effect","Effect","Predicate","parts","Predicate","Effect"]}
|