@executor-js/execution 0.0.1-beta.0 → 0.0.1-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-7ZEYKKLC.js → chunk-AURUYWWF.js} +12 -3
- package/dist/chunk-AURUYWWF.js.map +1 -0
- package/dist/core.js +1 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/index.js +34 -12
- package/dist/index.js.map +1 -1
- package/dist/promise.d.ts +2 -3
- package/dist/promise.d.ts.map +1 -1
- package/package.json +4 -2
- package/dist/chunk-7ZEYKKLC.js.map +0 -1
|
@@ -247,7 +247,10 @@ var formatDescription = (namespaces, sources) => {
|
|
|
247
247
|
|
|
248
248
|
// src/engine.ts
|
|
249
249
|
import { Deferred, Effect as Effect3, Fiber, Ref } from "effect";
|
|
250
|
-
|
|
250
|
+
var loadDefaultCodeExecutor = async () => {
|
|
251
|
+
const mod = await import("@executor-js/runtime-quickjs");
|
|
252
|
+
return mod.makeQuickJsExecutor();
|
|
253
|
+
};
|
|
251
254
|
var MAX_PREVIEW_CHARS = 3e4;
|
|
252
255
|
var truncate = (value, max) => value.length > max ? `${value.slice(0, max)}
|
|
253
256
|
... [truncated ${value.length - max} chars]` : value;
|
|
@@ -409,7 +412,11 @@ var makeFullInvoker = (executor, invokeOptions) => {
|
|
|
409
412
|
var runEffect = (effect) => Effect3.runPromise(effect);
|
|
410
413
|
var createExecutionEngine = (config) => {
|
|
411
414
|
const { executor } = config;
|
|
412
|
-
|
|
415
|
+
let codeExecutorPromise = config.codeExecutor ? Promise.resolve(config.codeExecutor) : null;
|
|
416
|
+
const getCodeExecutor = () => {
|
|
417
|
+
if (!codeExecutorPromise) codeExecutorPromise = loadDefaultCodeExecutor();
|
|
418
|
+
return codeExecutorPromise;
|
|
419
|
+
};
|
|
413
420
|
const pausedExecutions = /* @__PURE__ */ new Map();
|
|
414
421
|
let nextId = 0;
|
|
415
422
|
const awaitCompletionOrPause = (fiber, pauseSignal) => Effect3.race(
|
|
@@ -440,6 +447,7 @@ var createExecutionEngine = (config) => {
|
|
|
440
447
|
return yield* Deferred.await(responseDeferred);
|
|
441
448
|
});
|
|
442
449
|
const invoker = makeFullInvoker(executor, { onElicitation: elicitationHandler });
|
|
450
|
+
const codeExecutor = yield* Effect3.promise(() => getCodeExecutor());
|
|
443
451
|
fiber = yield* Effect3.forkDaemon(codeExecutor.execute(code, invoker));
|
|
444
452
|
const initialSignal = yield* Ref.get(pauseSignalRef);
|
|
445
453
|
return yield* awaitCompletionOrPause(fiber, initialSignal);
|
|
@@ -461,6 +469,7 @@ var createExecutionEngine = (config) => {
|
|
|
461
469
|
const invoker = makeFullInvoker(executor, {
|
|
462
470
|
onElicitation: options.onElicitation
|
|
463
471
|
});
|
|
472
|
+
const codeExecutor = await getCodeExecutor();
|
|
464
473
|
return runEffect(codeExecutor.execute(code, invoker));
|
|
465
474
|
},
|
|
466
475
|
executeWithPause: (code) => runEffect(startPausableExecution(code)),
|
|
@@ -480,4 +489,4 @@ export {
|
|
|
480
489
|
formatPausedExecution,
|
|
481
490
|
createExecutionEngine
|
|
482
491
|
};
|
|
483
|
-
//# sourceMappingURL=chunk-
|
|
492
|
+
//# sourceMappingURL=chunk-AURUYWWF.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","import { Effect } from \"effect\";\nimport type {\n Executor,\n ToolId,\n Tool,\n ToolSchema,\n InvokeOptions,\n Source,\n} from \"@executor/sdk\";\nimport type { SandboxToolInvoker } from \"@executor/codemode-core\";\nimport { ExecutionToolError } from \"./errors\";\n\n/**\n * Bridges QuickJS `tools.someSource.someOp(args)` calls into\n * `executor.tools.invoke(toolId, args)`.\n */\nexport const makeExecutorToolInvoker = (\n executor: Executor,\n options: { readonly invokeOptions: InvokeOptions },\n): SandboxToolInvoker => ({\n invoke: ({ path, args }) =>\n Effect.gen(function* () {\n const result = yield* executor.tools.invoke(path as ToolId, args, options.invokeOptions).pipe(\n Effect.catchTag(\"ElicitationDeclinedError\", (err) =>\n Effect.fail(\n new ExecutionToolError({\n message: `Tool \"${err.toolId}\" requires approval but the request was ${err.action === \"cancel\" ? \"cancelled\" : \"declined\"} by the user.`,\n cause: err,\n }),\n ),\n ),\n );\n const r = result as { readonly error?: unknown; readonly data?: unknown } | unknown;\n if (\n r !== null &&\n typeof r === \"object\" &&\n \"error\" in r &&\n (r as { error?: unknown }).error !== null &&\n (r as { error?: unknown }).error !== undefined\n ) {\n return yield* Effect.fail((r as { error: unknown }).error);\n }\n if (r !== null && typeof r === \"object\" && \"data\" in r) {\n return (r as { data: unknown }).data;\n }\n return r;\n }),\n});\n\nexport type ToolDiscoveryResult = {\n readonly path: string;\n readonly name: string;\n readonly description?: string;\n readonly sourceId: string;\n readonly score: number;\n};\n\nexport type ExecutorSourceListItem = {\n readonly id: string;\n readonly name: string;\n readonly kind: string;\n readonly runtime?: boolean;\n readonly canRemove?: boolean;\n readonly canRefresh?: boolean;\n readonly toolCount: number;\n};\n\ntype SearchableTool = Pick<Tool, \"id\" | \"sourceId\" | \"name\" | \"description\">;\n\ntype PreparedField = {\n readonly raw: string;\n readonly tokens: readonly string[];\n};\n\nconst SEARCH_FIELD_WEIGHTS = {\n path: 12,\n sourceId: 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 sourceTokens = tokenizeSearchText(tool.sourceId);\n const pathTokens = tokenizeSearchText(tool.id);\n\n const isPrefixMatch = (tokens: readonly string[]): boolean =>\n namespaceTokens.every((token, index) => tokens[index] === token);\n\n return isPrefixMatch(sourceTokens) || 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.id);\n const sourceId = prepareField(tool.sourceId);\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, sourceId, SEARCH_FIELD_WEIGHTS.sourceId),\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.id) === normalizedQuery ||\n normalizeSearchText(tool.name) === normalizedQuery\n ) {\n score += 20;\n }\n\n return {\n path: tool.id,\n name: tool.name,\n description: tool.description,\n sourceId: tool.sourceId,\n score,\n };\n};\n\n/** What `tools.search()` calls inside the sandbox. */\nexport const searchTools = (\n executor: Executor,\n query: string,\n limit = 12,\n options?: { readonly namespace?: string },\n): Effect.Effect<ReadonlyArray<ToolDiscoveryResult>> =>\n Effect.gen(function* () {\n if (normalizeSearchText(query).length === 0) {\n return [];\n }\n\n const all = yield* executor.tools.list().pipe(Effect.orDie);\n return all\n .filter((tool: Tool) => matchesNamespace(tool, options?.namespace))\n .map((tool: Tool) => scoreToolMatch(tool, query))\n .filter((tool): tool is ToolDiscoveryResult => tool !== null)\n .sort((left, right) => right.score - left.score || left.path.localeCompare(right.path))\n .slice(0, limit);\n });\n\n/** What `tools.executor.sources.list()` calls inside the sandbox. */\nexport const listExecutorSources = (\n executor: Executor,\n options?: { readonly query?: string; readonly limit?: number },\n): Effect.Effect<ReadonlyArray<ExecutorSourceListItem>> =>\n Effect.gen(function* () {\n const normalizedQuery = normalizeSearchText(options?.query ?? \"\");\n const limit = options?.limit ?? 200;\n const sources = yield* executor.sources.list().pipe(Effect.orDie);\n\n const filtered =\n normalizedQuery.length === 0\n ? sources\n : sources.filter((source: Source) => {\n const haystack = normalizeSearchText([source.id, source.name, source.kind].join(\" \"));\n return tokenizeSearchText(normalizedQuery).every((token) => haystack.includes(token));\n });\n\n // Single query for all tools, then count per source in memory.\n const allTools = yield* executor.tools.list().pipe(Effect.orDie);\n const toolCountBySource = new Map<string, number>();\n for (const tool of allTools) {\n toolCountBySource.set(tool.sourceId, (toolCountBySource.get(tool.sourceId) ?? 0) + 1);\n }\n\n const withCounts = filtered.map(\n (source: Source) =>\n ({\n id: source.id,\n name: source.name,\n kind: source.kind,\n runtime: source.runtime,\n canRemove: source.canRemove,\n canRefresh: source.canRefresh,\n toolCount: toolCountBySource.get(source.id) ?? 0,\n }) satisfies ExecutorSourceListItem,\n );\n\n return withCounts\n .sort((left, right) => left.name.localeCompare(right.name) || left.id.localeCompare(right.id))\n .slice(0, limit);\n });\n\n/** What `tools.describe.tool()` calls inside the sandbox. */\nexport const describeTool = (\n executor: Executor,\n path: string,\n): Effect.Effect<\n {\n path: string;\n name: string;\n description?: string;\n inputTypeScript?: string;\n outputTypeScript?: string;\n typeScriptDefinitions?: Record<string, string>;\n },\n unknown\n> =>\n Effect.gen(function* () {\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: ToolSchema | null = yield* executor.tools.schema(path);\n\n // tools.schema() returns null if the tool doesn't exist. Fall back to\n // a minimal stub so callers can still render something.\n if (schema === null) {\n return { path, name: path };\n }\n\n // The schema's id is the tool path; name/description come from the\n // tool row which tools.schema() already loaded.\n return {\n path,\n name: schema.name ?? path,\n description: schema.description,\n inputTypeScript: schema.inputTypeScript,\n outputTypeScript: schema.outputTypeScript,\n typeScriptDefinitions: schema.typeScriptDefinitions,\n };\n });\n","import { Effect } from \"effect\";\nimport type { Executor, Tool, Source } from \"@executor/sdk\";\n\n/**\n * Builds a tool description dynamically.\n *\n * Structure:\n * 1. Workflow (top — critical, least likely to be truncated)\n * 2. Available namespaces (bottom)\n */\nexport const buildExecuteDescription = (executor: Executor): Effect.Effect<string> =>\n Effect.gen(function* () {\n const sources: readonly Source[] = yield* executor.sources.list().pipe(Effect.orDie);\n const tools: readonly Tool[] = yield* executor.tools.list().pipe(Effect.orDie);\n\n const namespaces = new Set<string>();\n for (const tool of tools) namespaces.add(tool.sourceId);\n\n return formatDescription([...namespaces], sources);\n });\n\nconst formatDescription = (namespaces: readonly string[], sources: readonly Source[]): 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 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.sources.list()` when you need configured source inventory.\",\n \"6. Call the tool: `const result = await tools.<path>(input);`\",\n \"\",\n \"## Rules\",\n \"\",\n \"- `tools.search()` returns ranked matches, 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 \"- Use `tools.executor.sources.list()` to inspect configured sources and their tool counts. Returns `[{ id, toolCount, ... }]`.\",\n \"- Always use the namespace prefix when calling tools: `tools.<namespace>.<tool>(args)`. Example: `tools.home_assistant_rest_api.states.getState(...)` — not `tools.states.getState(...)`.\",\n \"- The `tools` object is a lazy proxy — `Object.keys(tools)` won't work. Use `tools.search()` or `tools.executor.sources.list()` instead.\",\n '- Pass an object to system tools, e.g. `tools.search({ query: \"...\" })`, `tools.executor.sources.list()`, and `tools.describe.tool({ path })`.',\n \"- `tools.describe.tool()` returns compact TypeScript shapes. Use `inputTypeScript`, `outputTypeScript`, and `typeScriptDefinitions`.\",\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 ];\n\n if (namespaces.length > 0) {\n lines.push(\"\");\n lines.push(\"## Available namespaces\");\n lines.push(\"\");\n const sorted = [...namespaces].sort();\n for (const ns of sorted) {\n const source = sources.find((s) => s.id === ns);\n const label = source?.name ?? ns;\n lines.push(`- \\`${ns}\\`${label !== ns ? ` — ${label}` : \"\"}`);\n }\n }\n\n return lines.join(\"\\n\");\n};\n","import { Deferred, Effect, Fiber, Ref } from \"effect\";\n\nimport type {\n Executor,\n InvokeOptions,\n ElicitationResponse,\n ElicitationHandler,\n ElicitationContext,\n} from \"@executor/sdk\";\nimport type { CodeExecutor, ExecuteResult, SandboxToolInvoker } from \"@executor/codemode-core\";\n\n/**\n * Lazily resolve a default `CodeExecutor` only when the caller did not\n * supply one. Kept dynamic so consumers that bring their own runtime\n * never pay the cost of loading QuickJS + its WASM asset (~13 MB).\n */\nconst loadDefaultCodeExecutor = async (): Promise<CodeExecutor> => {\n const mod = await import(\"@executor/runtime-quickjs\");\n return mod.makeQuickJsExecutor();\n};\n\nimport {\n makeExecutorToolInvoker,\n searchTools,\n listExecutorSources,\n describeTool,\n} from \"./tool-invoker\";\nimport { ExecutionToolError } from \"./errors\";\nimport { buildExecuteDescription } from \"./description\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type ExecutionEngineConfig = {\n readonly executor: Executor;\n readonly codeExecutor?: CodeExecutor;\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 = PausedExecution & {\n readonly response: Deferred.Deferred<typeof ElicitationResponse.Type>;\n readonly fiber: Fiber.Fiber<ExecuteResult, unknown>;\n readonly pauseSignalRef: Ref.Ref<Deferred.Deferred<InternalPausedExecution>>;\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\n if (req._tag === \"UrlElicitation\") {\n lines.push(`\\nOpen this URL in a browser:\\n${req.url}`);\n lines.push(\"\\nAfter the browser flow, resume with the executionId below:\");\n } else {\n lines.push(\"\\nResume with the executionId below and a response matching the requested schema:\");\n const schema = req.requestedSchema;\n if (schema && Object.keys(schema).length > 0) {\n lines.push(`\\nRequested schema:\\n${JSON.stringify(schema, null, 2)}`);\n }\n }\n\n lines.push(`\\nexecutionId: ${paused.id}`);\n\n return {\n text: lines.join(\"\\n\"),\n structured: {\n status: \"waiting_for_interaction\",\n executionId: paused.id,\n interaction: {\n kind: req._tag === \"UrlElicitation\" ? \"url\" : \"form\",\n message: req.message,\n ...(req._tag === \"UrlElicitation\" ? { url: req.url } : {}),\n ...(req._tag === \"FormElicitation\" ? { 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 makeFullInvoker = (executor: Executor, invokeOptions: InvokeOptions): 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 }\",\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 (limit instanceof ExecutionToolError) {\n return Effect.fail(limit);\n }\n\n return searchTools(executor, args.query ?? \"\", limit, {\n namespace: args.namespace,\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 }\",\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 (limit instanceof ExecutionToolError) {\n return Effect.fail(limit);\n }\n\n return listExecutorSources(executor, {\n query: isRecord(args) && typeof args.query === \"string\" ? args.query : undefined,\n limit,\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);\n }\n return base.invoke({ path, args });\n },\n };\n};\n\n// ---------------------------------------------------------------------------\n// Execution Engine\n// ---------------------------------------------------------------------------\n\nexport type ExecutionEngine = {\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 readonly execute: (\n code: string,\n options: { readonly onElicitation: ElicitationHandler },\n ) => Promise<ExecuteResult>;\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) => Promise<ExecutionResult>;\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 ) => Promise<ExecutionResult | null>;\n\n /**\n * Get the dynamic tool description (workflow + namespaces).\n */\n readonly getDescription: () => Promise<string>;\n};\n\nconst runEffect = <A>(effect: Effect.Effect<A, unknown>): Promise<A> =>\n Effect.runPromise(effect as Effect.Effect<A, never>);\n\nexport const createExecutionEngine = (config: ExecutionEngineConfig): ExecutionEngine => {\n const { executor } = config;\n // Defer construction of the default QuickJS runtime so its WASM loader\n // is not evaluated for callers who supply their own `codeExecutor`.\n let codeExecutorPromise: Promise<CodeExecutor> | null = config.codeExecutor\n ? Promise.resolve(config.codeExecutor)\n : null;\n const getCodeExecutor = (): Promise<CodeExecutor> => {\n if (!codeExecutorPromise) codeExecutorPromise = loadDefaultCodeExecutor();\n return codeExecutorPromise;\n };\n const pausedExecutions = new Map<string, InternalPausedExecution>();\n let nextId = 0;\n\n /**\n * Race a running fiber against a pause signal. 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 const awaitCompletionOrPause = (\n fiber: Fiber.Fiber<ExecuteResult, unknown>,\n pauseSignal: Deferred.Deferred<InternalPausedExecution>,\n ): Effect.Effect<ExecutionResult> =>\n Effect.race(\n Fiber.join(fiber).pipe(\n Effect.orDie,\n Effect.map((result): ExecutionResult => ({ status: \"completed\", result })),\n ),\n Deferred.await(pauseSignal).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 = (code: string): Effect.Effect<ExecutionResult> =>\n Effect.gen(function* () {\n // Ref holds the current pause signal. The elicitation handler reads\n // it each time it fires, so resume() can swap in a fresh Deferred\n // before unblocking the fiber.\n const pauseSignalRef = yield* Ref.make(yield* Deferred.make<InternalPausedExecution>());\n\n // Will be set once the fiber is forked.\n let fiber: Fiber.Fiber<ExecuteResult, unknown>;\n\n const elicitationHandler: ElicitationHandler = (ctx) =>\n Effect.gen(function* () {\n const responseDeferred = yield* Deferred.make<typeof ElicitationResponse.Type>();\n const id = `exec_${++nextId}`;\n\n const paused: InternalPausedExecution = {\n id,\n elicitationContext: ctx,\n response: responseDeferred,\n fiber: fiber!,\n pauseSignalRef,\n };\n pausedExecutions.set(id, paused);\n\n const currentSignal = yield* Ref.get(pauseSignalRef);\n yield* Deferred.succeed(currentSignal, paused);\n\n // Suspend until resume() completes responseDeferred.\n return yield* Deferred.await(responseDeferred);\n });\n\n const invoker = makeFullInvoker(executor, { onElicitation: elicitationHandler });\n const codeExecutor = yield* Effect.promise(() => getCodeExecutor());\n fiber = yield* Effect.forkDaemon(codeExecutor.execute(code, invoker));\n\n const initialSignal = yield* Ref.get(pauseSignalRef);\n return yield* awaitCompletionOrPause(fiber, initialSignal);\n });\n\n /**\n * Resume a paused execution. Swaps in a fresh pause signal, completes\n * the response Deferred to unblock the fiber, then races completion\n * against the next pause.\n */\n const resumeExecution = (\n executionId: string,\n response: ResumeResponse,\n ): Effect.Effect<ExecutionResult | null> =>\n Effect.gen(function* () {\n const paused = pausedExecutions.get(executionId);\n if (!paused) return null;\n pausedExecutions.delete(executionId);\n\n // Swap in a fresh pause signal BEFORE unblocking the fiber, so the\n // next elicitation handler call signals this new Deferred.\n const nextSignal = yield* Deferred.make<InternalPausedExecution>();\n yield* Ref.set(paused.pauseSignalRef, nextSignal);\n\n yield* Deferred.succeed(paused.response, {\n action: response.action,\n content: response.content,\n });\n\n return yield* awaitCompletionOrPause(paused.fiber, nextSignal);\n });\n\n return {\n execute: async (code, options) => {\n const invoker = makeFullInvoker(executor, {\n onElicitation: options.onElicitation,\n });\n const codeExecutor = await getCodeExecutor();\n return runEffect(codeExecutor.execute(code, invoker));\n },\n\n executeWithPause: (code) => runEffect(startPausableExecution(code)),\n\n resume: (executionId, response) => runEffect(resumeExecution(executionId, response)),\n\n getDescription: () => runEffect(buildExecuteDescription(executor)),\n };\n};\n"],"mappings":"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","names":["Effect","Effect","parts","Effect"]}
|
package/dist/core.js
CHANGED
package/dist/engine.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,QAAQ,EAGR,kBAAkB,EAClB,kBAAkB,EACnB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAsB,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,QAAQ,EAGR,kBAAkB,EAClB,kBAAkB,EACnB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAsB,MAAM,yBAAyB,CAAC;AAyB/F,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,eAAe,GACvB;IAAE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAA;CAAE,GAChE;IAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAA;CAAE,CAAC;AAEvE,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,kBAAkB,EAAE,kBAAkB,CAAC;CACjD,CAAC;AASF,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IACjD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC5C,CAAC;AAaF,eAAO,MAAM,mBAAmB,GAC9B,QAAQ,aAAa,KACpB;IACD,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,OAAO,EAAE,OAAO,CAAC;CA6BlB,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAChC,QAAQ,eAAe,KACtB;IACD,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CA+BrC,CAAC;AA6HF,MAAM,MAAM,eAAe,GAAG;IAC5B;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,CAChB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;QAAE,QAAQ,CAAC,aAAa,EAAE,kBAAkB,CAAA;KAAE,KACpD,OAAO,CAAC,aAAa,CAAC,CAAC;IAE5B;;;;OAIG;IACH,QAAQ,CAAC,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;IAEtE;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,CACf,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,cAAc,KACrB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;IAErC;;OAEG;IACH,QAAQ,CAAC,cAAc,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;CAChD,CAAC;AAKF,eAAO,MAAM,qBAAqB,GAAI,QAAQ,qBAAqB,KAAG,eAwHrE,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -2,18 +2,44 @@ import {
|
|
|
2
2
|
ExecutionToolError,
|
|
3
3
|
buildExecuteDescription,
|
|
4
4
|
createExecutionEngine,
|
|
5
|
-
describeTool,
|
|
6
5
|
formatExecuteResult,
|
|
7
|
-
formatPausedExecution
|
|
8
|
-
|
|
9
|
-
makeExecutorToolInvoker,
|
|
10
|
-
searchTools
|
|
11
|
-
} from "./chunk-7ZEYKKLC.js";
|
|
6
|
+
formatPausedExecution
|
|
7
|
+
} from "./chunk-AURUYWWF.js";
|
|
12
8
|
|
|
13
9
|
// src/promise.ts
|
|
14
10
|
import { Effect } from "effect";
|
|
11
|
+
var wrapPromiseExecutor = (pe) => ({
|
|
12
|
+
scope: pe.scope,
|
|
13
|
+
tools: {
|
|
14
|
+
invoke: (id, args, options) => Effect.tryPromise({
|
|
15
|
+
try: () => pe.tools.invoke(id, args, options),
|
|
16
|
+
catch: (cause) => cause
|
|
17
|
+
}),
|
|
18
|
+
list: (filter) => Effect.tryPromise({
|
|
19
|
+
try: () => pe.tools.list(filter),
|
|
20
|
+
catch: (cause) => cause
|
|
21
|
+
}).pipe(Effect.orDie),
|
|
22
|
+
schema: (id) => Effect.tryPromise({
|
|
23
|
+
try: () => pe.tools.schema(id),
|
|
24
|
+
catch: (cause) => cause
|
|
25
|
+
}),
|
|
26
|
+
definitions: () => Effect.tryPromise({
|
|
27
|
+
try: () => pe.tools.definitions(),
|
|
28
|
+
catch: (cause) => cause
|
|
29
|
+
}).pipe(Effect.orDie)
|
|
30
|
+
},
|
|
31
|
+
sources: {
|
|
32
|
+
list: () => Effect.tryPromise({
|
|
33
|
+
try: () => pe.sources.list(),
|
|
34
|
+
catch: (cause) => cause
|
|
35
|
+
}).pipe(Effect.orDie)
|
|
36
|
+
}
|
|
37
|
+
});
|
|
15
38
|
var createExecutionEngine2 = (config) => {
|
|
16
|
-
const engine = createExecutionEngine(
|
|
39
|
+
const engine = createExecutionEngine({
|
|
40
|
+
executor: wrapPromiseExecutor(config.executor),
|
|
41
|
+
codeExecutor: config.codeExecutor
|
|
42
|
+
});
|
|
17
43
|
return {
|
|
18
44
|
execute: (code, options) => engine.execute(code, {
|
|
19
45
|
onElicitation: (ctx) => Effect.tryPromise(() => options.onElicitation(ctx)).pipe(
|
|
@@ -29,11 +55,7 @@ export {
|
|
|
29
55
|
ExecutionToolError,
|
|
30
56
|
buildExecuteDescription,
|
|
31
57
|
createExecutionEngine2 as createExecutionEngine,
|
|
32
|
-
describeTool,
|
|
33
58
|
formatExecuteResult,
|
|
34
|
-
formatPausedExecution
|
|
35
|
-
listExecutorSources,
|
|
36
|
-
makeExecutorToolInvoker,
|
|
37
|
-
searchTools
|
|
59
|
+
formatPausedExecution
|
|
38
60
|
};
|
|
39
61
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/promise.ts"],"sourcesContent":["// ---------------------------------------------------------------------------\n// @executor/execution/promise — Promise-native surface for the execution\n// engine.
|
|
1
|
+
{"version":3,"sources":["../src/promise.ts"],"sourcesContent":["// ---------------------------------------------------------------------------\n// @executor/execution/promise — Promise-native surface for the execution\n// engine. Accepts a Promise-style Executor (from @executor/sdk) and an\n// async `onElicitation` handler — no Effect imports required by callers.\n//\n// Under the hood the engine is Effect-based, so we wrap the incoming\n// Promise executor into the minimal Effect shape the engine consumes,\n// and bridge the elicitation handler via `Effect.tryPromise`.\n// ---------------------------------------------------------------------------\n\nimport { Effect } from \"effect\";\n\nimport type {\n ElicitationContext,\n ElicitationResponse,\n Executor as PromiseExecutor,\n} from \"@executor/sdk\";\nimport type { CodeExecutor, ExecuteResult } from \"@executor/codemode-core\";\n\nimport {\n createExecutionEngine as createEffectExecutionEngine,\n type ExecutionResult,\n type PausedExecution,\n type ResumeResponse,\n} from \"./engine\";\n\nexport type ElicitationHandler = (\n ctx: ElicitationContext,\n) => Promise<ElicitationResponse>;\n\nexport type ExecutionEngineConfig = {\n readonly executor: PromiseExecutor;\n readonly codeExecutor?: CodeExecutor;\n};\n\nexport type ExecutionEngine = {\n readonly execute: (\n code: string,\n options: { readonly onElicitation: ElicitationHandler },\n ) => Promise<ExecuteResult>;\n readonly executeWithPause: (code: string) => Promise<ExecutionResult>;\n readonly resume: (\n executionId: string,\n response: ResumeResponse,\n ) => Promise<ExecutionResult | null>;\n readonly getDescription: () => Promise<string>;\n};\n\n/**\n * Wrap a Promise-style executor into the Effect shape the engine consumes.\n * Only the four method families the engine actually touches need wrapping:\n * `tools.{invoke,list,schema}` and `sources.list`.\n */\nconst wrapPromiseExecutor = (pe: PromiseExecutor): any => ({\n scope: (pe as any).scope,\n tools: {\n invoke: (id: unknown, args: unknown, options: unknown) =>\n Effect.tryPromise({\n try: () => (pe.tools as any).invoke(id, args, options),\n catch: (cause) => cause,\n }),\n list: (filter?: unknown) =>\n Effect.tryPromise({\n try: () => (pe.tools as any).list(filter),\n catch: (cause) => cause,\n }).pipe(Effect.orDie),\n schema: (id: unknown) =>\n Effect.tryPromise({\n try: () => (pe.tools as any).schema(id),\n catch: (cause) => cause,\n }),\n definitions: () =>\n Effect.tryPromise({\n try: () => (pe.tools as any).definitions(),\n catch: (cause) => cause,\n }).pipe(Effect.orDie),\n },\n sources: {\n list: () =>\n Effect.tryPromise({\n try: () => (pe.sources as any).list(),\n catch: (cause) => cause,\n }).pipe(Effect.orDie),\n },\n});\n\nexport const createExecutionEngine = (\n config: ExecutionEngineConfig,\n): ExecutionEngine => {\n const engine = createEffectExecutionEngine({\n executor: wrapPromiseExecutor(config.executor),\n codeExecutor: config.codeExecutor,\n });\n return {\n execute: (code, options) =>\n engine.execute(code, {\n onElicitation: (ctx) =>\n Effect.tryPromise(() => options.onElicitation(ctx)).pipe(\n Effect.orDie,\n ),\n }),\n executeWithPause: (code) => engine.executeWithPause(code),\n resume: (executionId, response) => engine.resume(executionId, response),\n getDescription: () => engine.getDescription(),\n };\n};\n\n// ---------------------------------------------------------------------------\n// Re-exports — plain types/helpers that don't carry Effect signatures.\n// ---------------------------------------------------------------------------\n\nexport {\n formatExecuteResult,\n formatPausedExecution,\n} from \"./engine\";\n\nexport type { ExecutionResult, PausedExecution, ResumeResponse };\n\nexport { buildExecuteDescription } from \"./description\";\nexport { ExecutionToolError } from \"./errors\";\n"],"mappings":";;;;;;;;;AAUA,SAAS,cAAc;AA2CvB,IAAM,sBAAsB,CAAC,QAA8B;AAAA,EACzD,OAAQ,GAAW;AAAA,EACnB,OAAO;AAAA,IACL,QAAQ,CAAC,IAAa,MAAe,YACnC,OAAO,WAAW;AAAA,MAChB,KAAK,MAAO,GAAG,MAAc,OAAO,IAAI,MAAM,OAAO;AAAA,MACrD,OAAO,CAAC,UAAU;AAAA,IACpB,CAAC;AAAA,IACH,MAAM,CAAC,WACL,OAAO,WAAW;AAAA,MAChB,KAAK,MAAO,GAAG,MAAc,KAAK,MAAM;AAAA,MACxC,OAAO,CAAC,UAAU;AAAA,IACpB,CAAC,EAAE,KAAK,OAAO,KAAK;AAAA,IACtB,QAAQ,CAAC,OACP,OAAO,WAAW;AAAA,MAChB,KAAK,MAAO,GAAG,MAAc,OAAO,EAAE;AAAA,MACtC,OAAO,CAAC,UAAU;AAAA,IACpB,CAAC;AAAA,IACH,aAAa,MACX,OAAO,WAAW;AAAA,MAChB,KAAK,MAAO,GAAG,MAAc,YAAY;AAAA,MACzC,OAAO,CAAC,UAAU;AAAA,IACpB,CAAC,EAAE,KAAK,OAAO,KAAK;AAAA,EACxB;AAAA,EACA,SAAS;AAAA,IACP,MAAM,MACJ,OAAO,WAAW;AAAA,MAChB,KAAK,MAAO,GAAG,QAAgB,KAAK;AAAA,MACpC,OAAO,CAAC,UAAU;AAAA,IACpB,CAAC,EAAE,KAAK,OAAO,KAAK;AAAA,EACxB;AACF;AAEO,IAAMA,yBAAwB,CACnC,WACoB;AACpB,QAAM,SAAS,sBAA4B;AAAA,IACzC,UAAU,oBAAoB,OAAO,QAAQ;AAAA,IAC7C,cAAc,OAAO;AAAA,EACvB,CAAC;AACD,SAAO;AAAA,IACL,SAAS,CAAC,MAAM,YACd,OAAO,QAAQ,MAAM;AAAA,MACnB,eAAe,CAAC,QACd,OAAO,WAAW,MAAM,QAAQ,cAAc,GAAG,CAAC,EAAE;AAAA,QAClD,OAAO;AAAA,MACT;AAAA,IACJ,CAAC;AAAA,IACH,kBAAkB,CAAC,SAAS,OAAO,iBAAiB,IAAI;AAAA,IACxD,QAAQ,CAAC,aAAa,aAAa,OAAO,OAAO,aAAa,QAAQ;AAAA,IACtE,gBAAgB,MAAM,OAAO,eAAe;AAAA,EAC9C;AACF;","names":["createExecutionEngine"]}
|
package/dist/promise.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { ElicitationContext, ElicitationResponse, Executor } from "@executor-js/sdk
|
|
1
|
+
import type { ElicitationContext, ElicitationResponse, Executor as PromiseExecutor } from "@executor-js/sdk";
|
|
2
2
|
import type { CodeExecutor, ExecuteResult } from "@executor-js/codemode-core";
|
|
3
3
|
import { type ExecutionResult, type PausedExecution, type ResumeResponse } from "./engine";
|
|
4
4
|
export type ElicitationHandler = (ctx: ElicitationContext) => Promise<ElicitationResponse>;
|
|
5
5
|
export type ExecutionEngineConfig = {
|
|
6
|
-
readonly executor:
|
|
6
|
+
readonly executor: PromiseExecutor;
|
|
7
7
|
readonly codeExecutor?: CodeExecutor;
|
|
8
8
|
};
|
|
9
9
|
export type ExecutionEngine = {
|
|
@@ -19,5 +19,4 @@ export { formatExecuteResult, formatPausedExecution, } from "./engine";
|
|
|
19
19
|
export type { ExecutionResult, PausedExecution, ResumeResponse };
|
|
20
20
|
export { buildExecuteDescription } from "./description";
|
|
21
21
|
export { ExecutionToolError } from "./errors";
|
|
22
|
-
export { makeExecutorToolInvoker, searchTools, listExecutorSources, describeTool, } from "./tool-invoker";
|
|
23
22
|
//# sourceMappingURL=promise.d.ts.map
|
package/dist/promise.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"promise.d.ts","sourceRoot":"","sources":["../src/promise.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"promise.d.ts","sourceRoot":"","sources":["../src/promise.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,kBAAkB,EAClB,mBAAmB,EACnB,QAAQ,IAAI,eAAe,EAC5B,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAE3E,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,cAAc,EACpB,MAAM,UAAU,CAAC;AAElB,MAAM,MAAM,kBAAkB,GAAG,CAC/B,GAAG,EAAE,kBAAkB,KACpB,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAElC,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;IACnC,QAAQ,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,OAAO,EAAE,CAChB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;QAAE,QAAQ,CAAC,aAAa,EAAE,kBAAkB,CAAA;KAAE,KACpD,OAAO,CAAC,aAAa,CAAC,CAAC;IAC5B,QAAQ,CAAC,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;IACtE,QAAQ,CAAC,MAAM,EAAE,CACf,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,cAAc,KACrB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;IACrC,QAAQ,CAAC,cAAc,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;CAChD,CAAC;AAwCF,eAAO,MAAM,qBAAqB,GAChC,QAAQ,qBAAqB,KAC5B,eAiBF,CAAC;AAMF,OAAO,EACL,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,UAAU,CAAC;AAElB,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,cAAc,EAAE,CAAC;AAEjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@executor-js/execution",
|
|
3
|
-
"version": "0.0.1-beta.
|
|
3
|
+
"version": "0.0.1-beta.2",
|
|
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"
|
|
@@ -40,10 +40,12 @@
|
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@executor-js/codemode-core": "0.0.1-beta.0",
|
|
43
|
-
"@executor-js/runtime-quickjs": "0.0.1-beta.0",
|
|
44
43
|
"@executor-js/sdk": "0.0.1",
|
|
45
44
|
"effect": "^3.21.0"
|
|
46
45
|
},
|
|
46
|
+
"optionalDependencies": {
|
|
47
|
+
"@executor-js/runtime-quickjs": "0.0.1-beta.0"
|
|
48
|
+
},
|
|
47
49
|
"devDependencies": {
|
|
48
50
|
"@effect/vitest": "^0.29.0",
|
|
49
51
|
"@types/node": "^24.3.1",
|
|
@@ -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","import { Effect } from \"effect\";\nimport type {\n Executor,\n ToolId,\n Tool,\n ToolSchema,\n InvokeOptions,\n Source,\n} from \"@executor/sdk\";\nimport type { SandboxToolInvoker } from \"@executor/codemode-core\";\nimport { ExecutionToolError } from \"./errors\";\n\n/**\n * Bridges QuickJS `tools.someSource.someOp(args)` calls into\n * `executor.tools.invoke(toolId, args)`.\n */\nexport const makeExecutorToolInvoker = (\n executor: Executor,\n options: { readonly invokeOptions: InvokeOptions },\n): SandboxToolInvoker => ({\n invoke: ({ path, args }) =>\n Effect.gen(function* () {\n const result = yield* executor.tools.invoke(path as ToolId, args, options.invokeOptions).pipe(\n Effect.catchTag(\"ElicitationDeclinedError\", (err) =>\n Effect.fail(\n new ExecutionToolError({\n message: `Tool \"${err.toolId}\" requires approval but the request was ${err.action === \"cancel\" ? \"cancelled\" : \"declined\"} by the user.`,\n cause: err,\n }),\n ),\n ),\n );\n const r = result as { readonly error?: unknown; readonly data?: unknown } | unknown;\n if (\n r !== null &&\n typeof r === \"object\" &&\n \"error\" in r &&\n (r as { error?: unknown }).error !== null &&\n (r as { error?: unknown }).error !== undefined\n ) {\n return yield* Effect.fail((r as { error: unknown }).error);\n }\n if (r !== null && typeof r === \"object\" && \"data\" in r) {\n return (r as { data: unknown }).data;\n }\n return r;\n }),\n});\n\nexport type ToolDiscoveryResult = {\n readonly path: string;\n readonly name: string;\n readonly description?: string;\n readonly sourceId: string;\n readonly score: number;\n};\n\nexport type ExecutorSourceListItem = {\n readonly id: string;\n readonly name: string;\n readonly kind: string;\n readonly runtime?: boolean;\n readonly canRemove?: boolean;\n readonly canRefresh?: boolean;\n readonly toolCount: number;\n};\n\ntype SearchableTool = Pick<Tool, \"id\" | \"sourceId\" | \"name\" | \"description\">;\n\ntype PreparedField = {\n readonly raw: string;\n readonly tokens: readonly string[];\n};\n\nconst SEARCH_FIELD_WEIGHTS = {\n path: 12,\n sourceId: 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 sourceTokens = tokenizeSearchText(tool.sourceId);\n const pathTokens = tokenizeSearchText(tool.id);\n\n const isPrefixMatch = (tokens: readonly string[]): boolean =>\n namespaceTokens.every((token, index) => tokens[index] === token);\n\n return isPrefixMatch(sourceTokens) || 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.id);\n const sourceId = prepareField(tool.sourceId);\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, sourceId, SEARCH_FIELD_WEIGHTS.sourceId),\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.id) === normalizedQuery ||\n normalizeSearchText(tool.name) === normalizedQuery\n ) {\n score += 20;\n }\n\n return {\n path: tool.id,\n name: tool.name,\n description: tool.description,\n sourceId: tool.sourceId,\n score,\n };\n};\n\n/** What `tools.search()` calls inside the sandbox. */\nexport const searchTools = (\n executor: Executor,\n query: string,\n limit = 12,\n options?: { readonly namespace?: string },\n): Effect.Effect<ReadonlyArray<ToolDiscoveryResult>> =>\n Effect.gen(function* () {\n if (normalizeSearchText(query).length === 0) {\n return [];\n }\n\n const all = yield* executor.tools.list().pipe(Effect.orDie);\n return all\n .filter((tool: Tool) => matchesNamespace(tool, options?.namespace))\n .map((tool: Tool) => scoreToolMatch(tool, query))\n .filter((tool): tool is ToolDiscoveryResult => tool !== null)\n .sort((left, right) => right.score - left.score || left.path.localeCompare(right.path))\n .slice(0, limit);\n });\n\n/** What `tools.executor.sources.list()` calls inside the sandbox. */\nexport const listExecutorSources = (\n executor: Executor,\n options?: { readonly query?: string; readonly limit?: number },\n): Effect.Effect<ReadonlyArray<ExecutorSourceListItem>> =>\n Effect.gen(function* () {\n const normalizedQuery = normalizeSearchText(options?.query ?? \"\");\n const limit = options?.limit ?? 200;\n const sources = yield* executor.sources.list().pipe(Effect.orDie);\n\n const filtered =\n normalizedQuery.length === 0\n ? sources\n : sources.filter((source: Source) => {\n const haystack = normalizeSearchText([source.id, source.name, source.kind].join(\" \"));\n return tokenizeSearchText(normalizedQuery).every((token) => haystack.includes(token));\n });\n\n // Single query for all tools, then count per source in memory.\n const allTools = yield* executor.tools.list().pipe(Effect.orDie);\n const toolCountBySource = new Map<string, number>();\n for (const tool of allTools) {\n toolCountBySource.set(tool.sourceId, (toolCountBySource.get(tool.sourceId) ?? 0) + 1);\n }\n\n const withCounts = filtered.map(\n (source: Source) =>\n ({\n id: source.id,\n name: source.name,\n kind: source.kind,\n runtime: source.runtime,\n canRemove: source.canRemove,\n canRefresh: source.canRefresh,\n toolCount: toolCountBySource.get(source.id) ?? 0,\n }) satisfies ExecutorSourceListItem,\n );\n\n return withCounts\n .sort((left, right) => left.name.localeCompare(right.name) || left.id.localeCompare(right.id))\n .slice(0, limit);\n });\n\n/** What `tools.describe.tool()` calls inside the sandbox. */\nexport const describeTool = (\n executor: Executor,\n path: string,\n): Effect.Effect<\n {\n path: string;\n name: string;\n description?: string;\n inputTypeScript?: string;\n outputTypeScript?: string;\n typeScriptDefinitions?: Record<string, string>;\n },\n unknown\n> =>\n Effect.gen(function* () {\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: ToolSchema | null = yield* executor.tools.schema(path);\n\n // tools.schema() returns null if the tool doesn't exist. Fall back to\n // a minimal stub so callers can still render something.\n if (schema === null) {\n return { path, name: path };\n }\n\n // The schema's id is the tool path; name/description come from the\n // tool row which tools.schema() already loaded.\n return {\n path,\n name: schema.name ?? path,\n description: schema.description,\n inputTypeScript: schema.inputTypeScript,\n outputTypeScript: schema.outputTypeScript,\n typeScriptDefinitions: schema.typeScriptDefinitions,\n };\n });\n","import { Effect } from \"effect\";\nimport type { Executor, Tool, Source } from \"@executor/sdk\";\n\n/**\n * Builds a tool description dynamically.\n *\n * Structure:\n * 1. Workflow (top — critical, least likely to be truncated)\n * 2. Available namespaces (bottom)\n */\nexport const buildExecuteDescription = (executor: Executor): Effect.Effect<string> =>\n Effect.gen(function* () {\n const sources: readonly Source[] = yield* executor.sources.list().pipe(Effect.orDie);\n const tools: readonly Tool[] = yield* executor.tools.list().pipe(Effect.orDie);\n\n const namespaces = new Set<string>();\n for (const tool of tools) namespaces.add(tool.sourceId);\n\n return formatDescription([...namespaces], sources);\n });\n\nconst formatDescription = (namespaces: readonly string[], sources: readonly Source[]): 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 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.sources.list()` when you need configured source inventory.\",\n \"6. Call the tool: `const result = await tools.<path>(input);`\",\n \"\",\n \"## Rules\",\n \"\",\n \"- `tools.search()` returns ranked matches, 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 \"- Use `tools.executor.sources.list()` to inspect configured sources and their tool counts. Returns `[{ id, toolCount, ... }]`.\",\n \"- Always use the namespace prefix when calling tools: `tools.<namespace>.<tool>(args)`. Example: `tools.home_assistant_rest_api.states.getState(...)` — not `tools.states.getState(...)`.\",\n \"- The `tools` object is a lazy proxy — `Object.keys(tools)` won't work. Use `tools.search()` or `tools.executor.sources.list()` instead.\",\n '- Pass an object to system tools, e.g. `tools.search({ query: \"...\" })`, `tools.executor.sources.list()`, and `tools.describe.tool({ path })`.',\n \"- `tools.describe.tool()` returns compact TypeScript shapes. Use `inputTypeScript`, `outputTypeScript`, and `typeScriptDefinitions`.\",\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 ];\n\n if (namespaces.length > 0) {\n lines.push(\"\");\n lines.push(\"## Available namespaces\");\n lines.push(\"\");\n const sorted = [...namespaces].sort();\n for (const ns of sorted) {\n const source = sources.find((s) => s.id === ns);\n const label = source?.name ?? ns;\n lines.push(`- \\`${ns}\\`${label !== ns ? ` — ${label}` : \"\"}`);\n }\n }\n\n return lines.join(\"\\n\");\n};\n","import { Deferred, Effect, Fiber, Ref } from \"effect\";\n\nimport type {\n Executor,\n InvokeOptions,\n ElicitationResponse,\n ElicitationHandler,\n ElicitationContext,\n} from \"@executor/sdk\";\nimport type { CodeExecutor, ExecuteResult, SandboxToolInvoker } from \"@executor/codemode-core\";\nimport { makeQuickJsExecutor } from \"@executor/runtime-quickjs\";\n\nimport {\n makeExecutorToolInvoker,\n searchTools,\n listExecutorSources,\n describeTool,\n} from \"./tool-invoker\";\nimport { ExecutionToolError } from \"./errors\";\nimport { buildExecuteDescription } from \"./description\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type ExecutionEngineConfig = {\n readonly executor: Executor;\n readonly codeExecutor?: CodeExecutor;\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 = PausedExecution & {\n readonly response: Deferred.Deferred<typeof ElicitationResponse.Type>;\n readonly fiber: Fiber.Fiber<ExecuteResult, unknown>;\n readonly pauseSignalRef: Ref.Ref<Deferred.Deferred<InternalPausedExecution>>;\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\n if (req._tag === \"UrlElicitation\") {\n lines.push(`\\nOpen this URL in a browser:\\n${req.url}`);\n lines.push(\"\\nAfter the browser flow, resume with the executionId below:\");\n } else {\n lines.push(\"\\nResume with the executionId below and a response matching the requested schema:\");\n const schema = req.requestedSchema;\n if (schema && Object.keys(schema).length > 0) {\n lines.push(`\\nRequested schema:\\n${JSON.stringify(schema, null, 2)}`);\n }\n }\n\n lines.push(`\\nexecutionId: ${paused.id}`);\n\n return {\n text: lines.join(\"\\n\"),\n structured: {\n status: \"waiting_for_interaction\",\n executionId: paused.id,\n interaction: {\n kind: req._tag === \"UrlElicitation\" ? \"url\" : \"form\",\n message: req.message,\n ...(req._tag === \"UrlElicitation\" ? { url: req.url } : {}),\n ...(req._tag === \"FormElicitation\" ? { 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 makeFullInvoker = (executor: Executor, invokeOptions: InvokeOptions): 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 }\",\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 (limit instanceof ExecutionToolError) {\n return Effect.fail(limit);\n }\n\n return searchTools(executor, args.query ?? \"\", limit, {\n namespace: args.namespace,\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 }\",\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 (limit instanceof ExecutionToolError) {\n return Effect.fail(limit);\n }\n\n return listExecutorSources(executor, {\n query: isRecord(args) && typeof args.query === \"string\" ? args.query : undefined,\n limit,\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);\n }\n return base.invoke({ path, args });\n },\n };\n};\n\n// ---------------------------------------------------------------------------\n// Execution Engine\n// ---------------------------------------------------------------------------\n\nexport type ExecutionEngine = {\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 readonly execute: (\n code: string,\n options: { readonly onElicitation: ElicitationHandler },\n ) => Promise<ExecuteResult>;\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) => Promise<ExecutionResult>;\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 ) => Promise<ExecutionResult | null>;\n\n /**\n * Get the dynamic tool description (workflow + namespaces).\n */\n readonly getDescription: () => Promise<string>;\n};\n\nconst runEffect = <A>(effect: Effect.Effect<A, unknown>): Promise<A> =>\n Effect.runPromise(effect as Effect.Effect<A, never>);\n\nexport const createExecutionEngine = (config: ExecutionEngineConfig): ExecutionEngine => {\n const { executor } = config;\n const codeExecutor = config.codeExecutor ?? makeQuickJsExecutor();\n const pausedExecutions = new Map<string, InternalPausedExecution>();\n let nextId = 0;\n\n /**\n * Race a running fiber against a pause signal. 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 const awaitCompletionOrPause = (\n fiber: Fiber.Fiber<ExecuteResult, unknown>,\n pauseSignal: Deferred.Deferred<InternalPausedExecution>,\n ): Effect.Effect<ExecutionResult> =>\n Effect.race(\n Fiber.join(fiber).pipe(\n Effect.orDie,\n Effect.map((result): ExecutionResult => ({ status: \"completed\", result })),\n ),\n Deferred.await(pauseSignal).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 = (code: string): Effect.Effect<ExecutionResult> =>\n Effect.gen(function* () {\n // Ref holds the current pause signal. The elicitation handler reads\n // it each time it fires, so resume() can swap in a fresh Deferred\n // before unblocking the fiber.\n const pauseSignalRef = yield* Ref.make(yield* Deferred.make<InternalPausedExecution>());\n\n // Will be set once the fiber is forked.\n let fiber: Fiber.Fiber<ExecuteResult, unknown>;\n\n const elicitationHandler: ElicitationHandler = (ctx) =>\n Effect.gen(function* () {\n const responseDeferred = yield* Deferred.make<typeof ElicitationResponse.Type>();\n const id = `exec_${++nextId}`;\n\n const paused: InternalPausedExecution = {\n id,\n elicitationContext: ctx,\n response: responseDeferred,\n fiber: fiber!,\n pauseSignalRef,\n };\n pausedExecutions.set(id, paused);\n\n const currentSignal = yield* Ref.get(pauseSignalRef);\n yield* Deferred.succeed(currentSignal, paused);\n\n // Suspend until resume() completes responseDeferred.\n return yield* Deferred.await(responseDeferred);\n });\n\n const invoker = makeFullInvoker(executor, { onElicitation: elicitationHandler });\n fiber = yield* Effect.forkDaemon(codeExecutor.execute(code, invoker));\n\n const initialSignal = yield* Ref.get(pauseSignalRef);\n return yield* awaitCompletionOrPause(fiber, initialSignal);\n });\n\n /**\n * Resume a paused execution. Swaps in a fresh pause signal, completes\n * the response Deferred to unblock the fiber, then races completion\n * against the next pause.\n */\n const resumeExecution = (\n executionId: string,\n response: ResumeResponse,\n ): Effect.Effect<ExecutionResult | null> =>\n Effect.gen(function* () {\n const paused = pausedExecutions.get(executionId);\n if (!paused) return null;\n pausedExecutions.delete(executionId);\n\n // Swap in a fresh pause signal BEFORE unblocking the fiber, so the\n // next elicitation handler call signals this new Deferred.\n const nextSignal = yield* Deferred.make<InternalPausedExecution>();\n yield* Ref.set(paused.pauseSignalRef, nextSignal);\n\n yield* Deferred.succeed(paused.response, {\n action: response.action,\n content: response.content,\n });\n\n return yield* awaitCompletionOrPause(paused.fiber, nextSignal);\n });\n\n return {\n execute: async (code, options) => {\n const invoker = makeFullInvoker(executor, {\n onElicitation: options.onElicitation,\n });\n return runEffect(codeExecutor.execute(code, invoker));\n },\n\n executeWithPause: (code) => runEffect(startPausableExecution(code)),\n\n resume: (executionId, response) => runEffect(resumeExecution(executionId, response)),\n\n getDescription: () => runEffect(buildExecuteDescription(executor)),\n };\n};\n"],"mappings":"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","names":["Effect","Effect","parts","Effect"]}
|