@executor-js/codemode-core 0.0.1 → 0.1.0
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/README.md +16 -8
- package/dist/code-recovery.d.ts.map +1 -1
- package/dist/effect-errors.d.ts +17 -0
- package/dist/effect-errors.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +14 -4
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
# @executor/codemode-core
|
|
1
|
+
# @executor-js/codemode-core
|
|
2
2
|
|
|
3
3
|
Core primitives for "code mode" — the pattern where an LLM writes TypeScript/JavaScript that calls into a pre-registered set of tools, executed in a sandbox. This package provides the shared type surface (`Tool`, `SandboxToolInvoker`, `CodeExecutor`), JSON Schema helpers, and error types used by every runtime that implements the contract.
|
|
4
4
|
|
|
5
|
-
Most callers depend on this transitively through `@executor/execution` and a sandbox runtime like `@executor/runtime-quickjs`. Install directly when you're authoring a new runtime.
|
|
5
|
+
Most callers depend on this transitively through `@executor-js/execution` and a sandbox runtime like `@executor-js/runtime-quickjs`. Install directly when you're authoring a new runtime.
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
9
9
|
```sh
|
|
10
|
-
bun add @executor/codemode-core
|
|
10
|
+
bun add @executor-js/codemode-core
|
|
11
11
|
# or
|
|
12
|
-
npm install @executor/codemode-core
|
|
12
|
+
npm install @executor-js/codemode-core
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
## Usage
|
|
@@ -17,19 +17,27 @@ npm install @executor/codemode-core
|
|
|
17
17
|
Implement a runtime that satisfies `CodeExecutor`:
|
|
18
18
|
|
|
19
19
|
```ts
|
|
20
|
-
import type {
|
|
20
|
+
import type {
|
|
21
|
+
CodeExecutor,
|
|
22
|
+
ExecuteResult,
|
|
23
|
+
SandboxToolInvoker,
|
|
24
|
+
} from "@executor-js/codemode-core";
|
|
21
25
|
import { Effect } from "effect";
|
|
22
26
|
|
|
23
27
|
export const makeMyRuntime = (): CodeExecutor => ({
|
|
24
28
|
execute: (code: string, invoker: SandboxToolInvoker) =>
|
|
25
29
|
Effect.gen(function* () {
|
|
26
|
-
// Spin up your sandbox, expose `invoker` as `tools.<path>(...)`, run
|
|
27
|
-
// collect logs, and return an ExecuteResult.
|
|
30
|
+
// Spin up your sandbox, expose `invoker` as `tools.<path>(...)`, run
|
|
31
|
+
// the code, collect logs, and return an ExecuteResult.
|
|
32
|
+
void code;
|
|
33
|
+
void invoker;
|
|
34
|
+
const result: ExecuteResult = { result: undefined, logs: [] };
|
|
35
|
+
return result;
|
|
28
36
|
}),
|
|
29
37
|
});
|
|
30
38
|
```
|
|
31
39
|
|
|
32
|
-
The runtime is passed a `SandboxToolInvoker` that bridges sandbox-side tool calls back to the executor. The sandbox-visible API is whatever you decide — `@executor/runtime-quickjs` exposes a `tools` proxy object; a runtime targeting Cloudflare Workers might use something else.
|
|
40
|
+
The runtime is passed a `SandboxToolInvoker` that bridges sandbox-side tool calls back to the executor. The sandbox-visible API is whatever you decide — `@executor-js/runtime-quickjs` exposes a `tools` proxy object; a runtime targeting Cloudflare Workers might use something else.
|
|
33
41
|
|
|
34
42
|
## Status
|
|
35
43
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code-recovery.d.ts","sourceRoot":"","sources":["../src/code-recovery.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"code-recovery.d.ts","sourceRoot":"","sources":["../src/code-recovery.ts"],"names":[],"mappings":"AAyIA,eAAO,MAAM,oBAAoB,GAAI,MAAM,MAAM,KAAG,MASnD,CAAC"}
|
package/dist/effect-errors.d.ts
CHANGED
|
@@ -7,5 +7,22 @@ export declare class KernelCoreEffectError extends KernelCoreEffectError_base<{
|
|
|
7
7
|
}> {
|
|
8
8
|
}
|
|
9
9
|
export declare const kernelCoreEffectError: (module: string, message: string) => KernelCoreEffectError;
|
|
10
|
+
declare const CodeExecutionError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
11
|
+
readonly _tag: "CodeExecutionError";
|
|
12
|
+
} & Readonly<A>;
|
|
13
|
+
/**
|
|
14
|
+
* Default failure type for any `CodeExecutor.execute` implementation —
|
|
15
|
+
* surfaces sandbox-level defects (isolate crash, module load failure,
|
|
16
|
+
* worker loader error) as a typed error so callers can handle them
|
|
17
|
+
* structurally instead of untyped `unknown`. Runtimes that want a
|
|
18
|
+
* narrower error shape can define their own `Data.TaggedError` subclass
|
|
19
|
+
* and parameterize `CodeExecutor<MyError>`.
|
|
20
|
+
*/
|
|
21
|
+
export declare class CodeExecutionError extends CodeExecutionError_base<{
|
|
22
|
+
readonly runtime: string;
|
|
23
|
+
readonly message: string;
|
|
24
|
+
readonly cause?: unknown;
|
|
25
|
+
}> {
|
|
26
|
+
}
|
|
10
27
|
export {};
|
|
11
28
|
//# sourceMappingURL=effect-errors.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"effect-errors.d.ts","sourceRoot":"","sources":["../src/effect-errors.ts"],"names":[],"mappings":";;;AAEA,qBAAa,qBAAsB,SAAQ,2BAA0C;IACnF,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;CAAG;AAEL,eAAO,MAAM,qBAAqB,GAAI,QAAQ,MAAM,EAAE,SAAS,MAAM,0BACrB,CAAC"}
|
|
1
|
+
{"version":3,"file":"effect-errors.d.ts","sourceRoot":"","sources":["../src/effect-errors.ts"],"names":[],"mappings":";;;AAEA,qBAAa,qBAAsB,SAAQ,2BAA0C;IACnF,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;CAAG;AAEL,eAAO,MAAM,qBAAqB,GAAI,QAAQ,MAAM,EAAE,SAAS,MAAM,0BACrB,CAAC;;;;AAEjD;;;;;;;GAOG;AACH,qBAAa,kBAAmB,SAAQ,wBAAuC;IAC7E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B,CAAC;CAAG"}
|
package/dist/index.js
CHANGED
|
@@ -18,6 +18,8 @@ import * as Data from "effect/Data";
|
|
|
18
18
|
var KernelCoreEffectError = class extends Data.TaggedError("KernelCoreEffectError") {
|
|
19
19
|
};
|
|
20
20
|
var kernelCoreEffectError = (module, message) => new KernelCoreEffectError({ module, message });
|
|
21
|
+
var CodeExecutionError = class extends Data.TaggedError("CodeExecutionError") {
|
|
22
|
+
};
|
|
21
23
|
|
|
22
24
|
// src/validation.ts
|
|
23
25
|
var getSchemaValidator = (schema) => {
|
|
@@ -216,6 +218,7 @@ var recoverExecutionBody = (code) => {
|
|
|
216
218
|
}
|
|
217
219
|
};
|
|
218
220
|
export {
|
|
221
|
+
CodeExecutionError,
|
|
219
222
|
KernelCoreEffectError,
|
|
220
223
|
asToolPath,
|
|
221
224
|
kernelCoreEffectError,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts","../src/validation.ts","../src/effect-errors.ts","../src/json-schema.ts","../src/code-recovery.ts"],"sourcesContent":["import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport type * as Effect from \"effect/Effect\";\n\n/** Branded tool path */\nexport type ToolPath = string & { readonly __toolPath: unique symbol };\n\nexport const asToolPath = (value: string): ToolPath => value as ToolPath;\n\n/** Standard Schema alias */\nexport type StandardSchema<Input = unknown, Output = unknown> = StandardSchemaV1<Input, Output>;\n\n/** A tool that can be invoked */\nexport interface Tool {\n readonly path: ToolPath;\n readonly description?: string;\n readonly inputSchema: StandardSchema;\n readonly outputSchema?: StandardSchema;\n readonly execute: (input: unknown) => unknown | Promise<unknown>;\n}\n\n/** Invoke a tool by path from inside a sandbox */\nexport interface SandboxToolInvoker {\n invoke(input: { path: string; args: unknown }): Effect.Effect<unknown, unknown>;\n}\n\n/** Result of executing code in a sandbox */\nexport type ExecuteResult = {\n result: unknown;\n error?: string;\n logs?: string[];\n};\n\n/** Executes code in a sandboxed runtime with tool access */\nexport interface CodeExecutor {\n execute(code: string, toolInvoker: SandboxToolInvoker): Effect.Effect<ExecuteResult, unknown>;\n}\n\n/** Accept-anything schema for tools with no input validation */\nexport const unknownInputSchema: StandardSchema = {\n \"~standard\": {\n version: 1,\n vendor: \"@executor/codemode-core\",\n validate: (value: unknown) => ({\n value,\n }),\n },\n};\n","import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport * as Effect from \"effect/Effect\";\n\nimport { kernelCoreEffectError } from \"./effect-errors\";\n\nconst getSchemaValidator = (\n schema: unknown,\n):\n | ((\n value: unknown,\n ) => StandardSchemaV1.Result<unknown> | Promise<StandardSchemaV1.Result<unknown>>)\n | null => {\n if (!schema || (typeof schema !== \"object\" && typeof schema !== \"function\")) {\n return null;\n }\n\n const standard = (schema as { \"~standard\"?: unknown })[\"~standard\"];\n if (!standard || typeof standard !== \"object\") {\n return null;\n }\n\n const validate = (standard as { validate?: unknown }).validate;\n return typeof validate === \"function\"\n ? (validate as (\n value: unknown,\n ) => StandardSchemaV1.Result<unknown> | Promise<StandardSchemaV1.Result<unknown>>)\n : null;\n};\n\nconst formatIssuePath = (\n path: ReadonlyArray<PropertyKey | StandardSchemaV1.PathSegment> | undefined,\n): string => {\n if (!path || path.length === 0) {\n return \"$\";\n }\n\n return path\n .map((segment) =>\n typeof segment === \"object\" && segment !== null && \"key\" in segment\n ? String(segment.key)\n : String(segment),\n )\n .join(\".\");\n};\n\nconst formatIssues = (issues: ReadonlyArray<StandardSchemaV1.Issue>): string =>\n issues.map((issue) => `${formatIssuePath(issue.path)}: ${issue.message}`).join(\"; \");\n\n/** Validate a value against a Standard Schema */\nexport const validateInput = (input: {\n schema: unknown;\n value: unknown;\n path: string;\n}): Effect.Effect<unknown, Error> => {\n const validate = getSchemaValidator(input.schema);\n if (!validate) {\n return Effect.fail(\n kernelCoreEffectError(\n \"validation\",\n `Tool ${input.path} has no Standard Schema validator on inputSchema`,\n ),\n );\n }\n\n return Effect.tryPromise({\n try: () => Promise.resolve(validate(input.value)),\n catch: (cause) =>\n kernelCoreEffectError(\"validation\", `Validation error for ${input.path}: ${String(cause)}`),\n }).pipe(\n Effect.flatMap((result) => {\n if (\"issues\" in result && result.issues) {\n return Effect.fail(\n kernelCoreEffectError(\n \"validation\",\n `Input validation failed for ${input.path}: ${formatIssues(result.issues)}`,\n ),\n );\n }\n return Effect.succeed(result.value);\n }),\n );\n};\n","import * as Data from \"effect/Data\";\n\nexport class KernelCoreEffectError extends Data.TaggedError(\"KernelCoreEffectError\")<{\n readonly module: string;\n readonly message: string;\n}> {}\n\nexport const kernelCoreEffectError = (module: string, message: string) =>\n new KernelCoreEffectError({ module, message });\n","import type { ErrorObject } from \"ajv\";\nimport Ajv2020 from \"ajv/dist/2020\";\nimport addFormats from \"ajv-formats\";\n\nimport type { StandardSchema } from \"./types\";\nimport { unknownInputSchema } from \"./types\";\n\nconst ajv = new Ajv2020({\n allErrors: true,\n strict: false,\n validateSchema: false,\n allowUnionTypes: true,\n});\n\naddFormats(ajv);\n\nconst decodePointerSegment = (segment: string): PropertyKey => {\n const decoded = segment.replaceAll(\"~1\", \"/\").replaceAll(\"~0\", \"~\");\n return /^\\d+$/.test(decoded) ? Number(decoded) : decoded;\n};\n\nconst pointerToPath = (pointer: string | undefined): ReadonlyArray<PropertyKey> | undefined => {\n if (!pointer || pointer.length === 0 || pointer === \"/\") {\n return undefined;\n }\n\n return pointer\n .split(\"/\")\n .slice(1)\n .filter((segment) => segment.length > 0)\n .map(decodePointerSegment);\n};\n\nconst toIssueMessage = (error: ErrorObject): string => {\n const keyword = error.keyword.trim();\n const message = (error.message ?? \"Invalid value\").trim();\n return keyword.length > 0 ? `${keyword}: ${message}` : message;\n};\n\nexport const standardSchemaFromJsonSchema = (\n schema: unknown,\n options?: {\n vendor?: string;\n fallback?: StandardSchema;\n },\n): StandardSchema => {\n try {\n const validate = ajv.compile(schema as Record<string, unknown>);\n\n return {\n \"~standard\": {\n version: 1,\n vendor: options?.vendor ?? \"json-schema\",\n validate: (value: unknown) => {\n const valid = validate(value);\n if (valid) {\n return { value };\n }\n\n const issues = (validate.errors ?? []).map((error) => ({\n message: toIssueMessage(error),\n path: pointerToPath(error.instancePath),\n }));\n\n return {\n issues: issues.length > 0 ? issues : [{ message: \"Invalid value\" }],\n };\n },\n },\n };\n } catch {\n return options?.fallback ?? unknownInputSchema;\n }\n};\n","import { parse } from \"@babel/parser\";\n\nconst FENCED_CODE_BLOCK = /```(?:[^\\n`]*)?\\s*\\n([\\s\\S]*?)```/i;\nconst FUNCTION_DECLARATION =\n /^(?:async\\s+)?function(?:\\s+([a-zA-Z_$][a-zA-Z0-9_$]*))?\\s*\\(/;\nconst CALLABLE_ERROR = \"Code must evaluate to a function\";\n\nconst extractCandidateSource = (code: string): string => {\n const trimmed = code.trim();\n if (!trimmed) return \"\";\n\n const fenced = trimmed.match(FENCED_CODE_BLOCK)?.[1];\n return (fenced ?? trimmed).trim();\n};\n\nconst wrapCallableBody = (source: string): string =>\n [\n \"const __fn = (\",\n source,\n \");\",\n `if (typeof __fn !== \"function\") throw new Error(${JSON.stringify(CALLABLE_ERROR)});`,\n \"return await __fn();\",\n ].join(\"\\n\");\n\nconst wrapNamedFunctionBody = (source: string, name: string): string =>\n [source, `return await ${name}();`].join(\"\\n\");\n\nconst wrapAnonymousFunctionBody = (source: string): string => `return await (${source})();`;\n\nconst sliceNode = (\n source: string,\n node: {\n start?: number | null;\n end?: number | null;\n },\n): string => {\n const start = node.start ?? 0;\n const end = node.end ?? source.length;\n return source.slice(start, end);\n};\n\nconst unwrapExpression = (expression: { type: string; expression?: unknown }): unknown => {\n switch (expression.type) {\n case \"ParenthesizedExpression\":\n case \"TSAsExpression\":\n case \"TSSatisfiesExpression\":\n case \"TSTypeAssertion\":\n case \"TSNonNullExpression\":\n case \"TSInstantiationExpression\":\n return expression.expression ? unwrapExpression(expression.expression as { type: string }) : expression;\n default:\n return expression;\n }\n};\n\nconst renderExportDefaultBody = (\n source: string,\n declaration: {\n type: string;\n start?: number | null;\n end?: number | null;\n id?: { name?: string | null } | null;\n expression?: unknown;\n },\n): string => {\n if (declaration.type === \"FunctionDeclaration\") {\n const fnSource = sliceNode(source, declaration);\n const name = declaration.id?.name;\n return name ? wrapNamedFunctionBody(fnSource, name) : wrapAnonymousFunctionBody(fnSource);\n }\n\n const expression = unwrapExpression(declaration as { type: string; expression?: unknown }) as {\n type?: string;\n };\n const expressionSource = sliceNode(source, declaration);\n\n if (expression?.type === \"ArrowFunctionExpression\" || expression?.type === \"FunctionExpression\") {\n return wrapCallableBody(expressionSource);\n }\n\n return `return (${expressionSource});`;\n};\n\nconst renderParsedBody = (source: string): string => {\n const program = parse(source, {\n sourceType: \"module\",\n allowAwaitOutsideFunction: true,\n allowReturnOutsideFunction: true,\n allowImportExportEverywhere: true,\n plugins: [\"typescript\"],\n }).program;\n\n if (program.body.length !== 1) return source;\n\n const [statement] = program.body;\n if (!statement) return source;\n\n switch (statement.type) {\n case \"ExpressionStatement\": {\n const expression = unwrapExpression(statement.expression as { type: string; expression?: unknown }) as {\n type?: string;\n };\n return expression?.type === \"ArrowFunctionExpression\" || expression?.type === \"FunctionExpression\"\n ? wrapCallableBody(source)\n : source;\n }\n case \"FunctionDeclaration\":\n return statement.id?.name ? wrapNamedFunctionBody(source, statement.id.name) : source;\n case \"ExportDefaultDeclaration\":\n return renderExportDefaultBody(source, statement.declaration as never);\n default:\n return source;\n }\n};\n\nconst renderHeuristicBody = (source: string): string => {\n const withoutDefaultExport = source.replace(/^export\\s+default\\s+/, \"\").trim();\n\n if (\n (withoutDefaultExport.startsWith(\"async\") || withoutDefaultExport.startsWith(\"(\")) &&\n withoutDefaultExport.includes(\"=>\")\n ) {\n return wrapCallableBody(withoutDefaultExport);\n }\n\n if (FUNCTION_DECLARATION.test(withoutDefaultExport)) {\n const name = withoutDefaultExport.match(FUNCTION_DECLARATION)?.[1];\n return name\n ? wrapNamedFunctionBody(withoutDefaultExport, name)\n : wrapAnonymousFunctionBody(withoutDefaultExport);\n }\n\n return withoutDefaultExport;\n};\n\nexport const recoverExecutionBody = (code: string): string => {\n const source = extractCandidateSource(code);\n if (!source) return \"\";\n\n try {\n return renderParsedBody(source);\n } catch {\n return renderHeuristicBody(source);\n }\n};\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/validation.ts","../src/effect-errors.ts","../src/json-schema.ts","../src/code-recovery.ts"],"sourcesContent":["import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport type * as Cause from \"effect/Cause\";\nimport type * as Effect from \"effect/Effect\";\n\nimport type { CodeExecutionError } from \"./effect-errors\";\n\n/** Branded tool path */\nexport type ToolPath = string & { readonly __toolPath: unique symbol };\n\nexport const asToolPath = (value: string): ToolPath => value as ToolPath;\n\n/** Standard Schema alias */\nexport type StandardSchema<Input = unknown, Output = unknown> = StandardSchemaV1<Input, Output>;\n\n/** A tool that can be invoked */\nexport interface Tool {\n readonly path: ToolPath;\n readonly description?: string;\n readonly inputSchema: StandardSchema;\n readonly outputSchema?: StandardSchema;\n readonly execute: (input: unknown) => unknown | Promise<unknown>;\n}\n\n/** Invoke a tool by path from inside a sandbox */\nexport interface SandboxToolInvoker {\n invoke(input: { path: string; args: unknown }): Effect.Effect<unknown, unknown, never>;\n}\n\n/** Result of executing code in a sandbox */\nexport type ExecuteResult = {\n result: unknown;\n error?: string;\n logs?: string[];\n};\n\n/**\n * Executes code in a sandboxed runtime with tool access.\n *\n * Error channel is constrained to Effect's `YieldableError` (the base\n * shape `Data.TaggedError(...)` produces) so callers always get a\n * structurally tagged error, never untyped `unknown`. Defaults to\n * `CodeExecutionError`; runtimes can parameterize with their own\n * `Data.TaggedError` subclass — e.g. `CodeExecutor<WorkerLoaderError>`.\n */\nexport interface CodeExecutor<E extends Cause.YieldableError = CodeExecutionError> {\n execute(code: string, toolInvoker: SandboxToolInvoker): Effect.Effect<ExecuteResult, E>;\n}\n\n/** Accept-anything schema for tools with no input validation */\nexport const unknownInputSchema: StandardSchema = {\n \"~standard\": {\n version: 1,\n vendor: \"@executor-js/codemode-core\",\n validate: (value: unknown) => ({\n value,\n }),\n },\n};\n","import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport * as Effect from \"effect/Effect\";\n\nimport { kernelCoreEffectError } from \"./effect-errors\";\n\nconst getSchemaValidator = (\n schema: unknown,\n):\n | ((\n value: unknown,\n ) => StandardSchemaV1.Result<unknown> | Promise<StandardSchemaV1.Result<unknown>>)\n | null => {\n if (!schema || (typeof schema !== \"object\" && typeof schema !== \"function\")) {\n return null;\n }\n\n const standard = (schema as { \"~standard\"?: unknown })[\"~standard\"];\n if (!standard || typeof standard !== \"object\") {\n return null;\n }\n\n const validate = (standard as { validate?: unknown }).validate;\n return typeof validate === \"function\"\n ? (validate as (\n value: unknown,\n ) => StandardSchemaV1.Result<unknown> | Promise<StandardSchemaV1.Result<unknown>>)\n : null;\n};\n\nconst formatIssuePath = (\n path: ReadonlyArray<PropertyKey | StandardSchemaV1.PathSegment> | undefined,\n): string => {\n if (!path || path.length === 0) {\n return \"$\";\n }\n\n return path\n .map((segment) =>\n typeof segment === \"object\" && segment !== null && \"key\" in segment\n ? String(segment.key)\n : String(segment),\n )\n .join(\".\");\n};\n\nconst formatIssues = (issues: ReadonlyArray<StandardSchemaV1.Issue>): string =>\n issues.map((issue) => `${formatIssuePath(issue.path)}: ${issue.message}`).join(\"; \");\n\n/** Validate a value against a Standard Schema */\nexport const validateInput = (input: {\n schema: unknown;\n value: unknown;\n path: string;\n}): Effect.Effect<unknown, Error> => {\n const validate = getSchemaValidator(input.schema);\n if (!validate) {\n return Effect.fail(\n kernelCoreEffectError(\n \"validation\",\n `Tool ${input.path} has no Standard Schema validator on inputSchema`,\n ),\n );\n }\n\n return Effect.tryPromise({\n try: () => Promise.resolve(validate(input.value)),\n catch: (cause) =>\n kernelCoreEffectError(\"validation\", `Validation error for ${input.path}: ${String(cause)}`),\n }).pipe(\n Effect.flatMap((result) => {\n if (\"issues\" in result && result.issues) {\n return Effect.fail(\n kernelCoreEffectError(\n \"validation\",\n `Input validation failed for ${input.path}: ${formatIssues(result.issues)}`,\n ),\n );\n }\n return Effect.succeed(result.value);\n }),\n );\n};\n","import * as Data from \"effect/Data\";\n\nexport class KernelCoreEffectError extends Data.TaggedError(\"KernelCoreEffectError\")<{\n readonly module: string;\n readonly message: string;\n}> {}\n\nexport const kernelCoreEffectError = (module: string, message: string) =>\n new KernelCoreEffectError({ module, message });\n\n/**\n * Default failure type for any `CodeExecutor.execute` implementation —\n * surfaces sandbox-level defects (isolate crash, module load failure,\n * worker loader error) as a typed error so callers can handle them\n * structurally instead of untyped `unknown`. Runtimes that want a\n * narrower error shape can define their own `Data.TaggedError` subclass\n * and parameterize `CodeExecutor<MyError>`.\n */\nexport class CodeExecutionError extends Data.TaggedError(\"CodeExecutionError\")<{\n readonly runtime: string;\n readonly message: string;\n readonly cause?: unknown;\n}> {}\n","import type { ErrorObject } from \"ajv\";\nimport Ajv2020 from \"ajv/dist/2020\";\nimport addFormats from \"ajv-formats\";\n\nimport type { StandardSchema } from \"./types\";\nimport { unknownInputSchema } from \"./types\";\n\nconst ajv = new Ajv2020({\n allErrors: true,\n strict: false,\n validateSchema: false,\n allowUnionTypes: true,\n});\n\naddFormats(ajv);\n\nconst decodePointerSegment = (segment: string): PropertyKey => {\n const decoded = segment.replaceAll(\"~1\", \"/\").replaceAll(\"~0\", \"~\");\n return /^\\d+$/.test(decoded) ? Number(decoded) : decoded;\n};\n\nconst pointerToPath = (pointer: string | undefined): ReadonlyArray<PropertyKey> | undefined => {\n if (!pointer || pointer.length === 0 || pointer === \"/\") {\n return undefined;\n }\n\n return pointer\n .split(\"/\")\n .slice(1)\n .filter((segment) => segment.length > 0)\n .map(decodePointerSegment);\n};\n\nconst toIssueMessage = (error: ErrorObject): string => {\n const keyword = error.keyword.trim();\n const message = (error.message ?? \"Invalid value\").trim();\n return keyword.length > 0 ? `${keyword}: ${message}` : message;\n};\n\nexport const standardSchemaFromJsonSchema = (\n schema: unknown,\n options?: {\n vendor?: string;\n fallback?: StandardSchema;\n },\n): StandardSchema => {\n try {\n const validate = ajv.compile(schema as Record<string, unknown>);\n\n return {\n \"~standard\": {\n version: 1,\n vendor: options?.vendor ?? \"json-schema\",\n validate: (value: unknown) => {\n const valid = validate(value);\n if (valid) {\n return { value };\n }\n\n const issues = (validate.errors ?? []).map((error) => ({\n message: toIssueMessage(error),\n path: pointerToPath(error.instancePath),\n }));\n\n return {\n issues: issues.length > 0 ? issues : [{ message: \"Invalid value\" }],\n };\n },\n },\n };\n } catch {\n return options?.fallback ?? unknownInputSchema;\n }\n};\n","import { parse } from \"@babel/parser\";\n\nconst FENCED_CODE_BLOCK = /```(?:[^\\n`]*)?\\s*\\n([\\s\\S]*?)```/i;\nconst FUNCTION_DECLARATION =\n /^(?:async\\s+)?function(?:\\s+([a-zA-Z_$][a-zA-Z0-9_$]*))?\\s*\\(/;\nconst CALLABLE_ERROR = \"Code must evaluate to a function\";\n\nconst extractCandidateSource = (code: string): string => {\n const trimmed = code.trim();\n if (!trimmed) return \"\";\n\n const fenced = trimmed.match(FENCED_CODE_BLOCK)?.[1];\n return (fenced ?? trimmed).trim();\n};\n\nconst wrapCallableBody = (source: string): string =>\n [\n \"const __fn = (\",\n source,\n \");\",\n `if (typeof __fn !== \"function\") throw new Error(${JSON.stringify(CALLABLE_ERROR)});`,\n \"return await __fn();\",\n ].join(\"\\n\");\n\nconst wrapNamedFunctionBody = (source: string, name: string): string =>\n [source, `return await ${name}();`].join(\"\\n\");\n\nconst wrapAnonymousFunctionBody = (source: string): string => `return await (${source})();`;\n\nconst sliceNode = (\n source: string,\n node: {\n start?: number | null;\n end?: number | null;\n },\n): string => {\n const start = node.start ?? 0;\n const end = node.end ?? source.length;\n return source.slice(start, end);\n};\n\nconst unwrapExpression = (expression: { type: string; expression?: unknown }): unknown => {\n switch (expression.type) {\n case \"ParenthesizedExpression\":\n case \"TSAsExpression\":\n case \"TSSatisfiesExpression\":\n case \"TSTypeAssertion\":\n case \"TSNonNullExpression\":\n case \"TSInstantiationExpression\":\n return expression.expression ? unwrapExpression(expression.expression as { type: string }) : expression;\n default:\n return expression;\n }\n};\n\nconst renderExportDefaultBody = (\n source: string,\n declaration: ExportDefaultDeclarationNode,\n): string => {\n if (declaration.type === \"FunctionDeclaration\") {\n const fnSource = sliceNode(source, declaration);\n const name = declaration.id?.name;\n return name ? wrapNamedFunctionBody(fnSource, name) : wrapAnonymousFunctionBody(fnSource);\n }\n\n const expression = unwrapExpression(declaration) as {\n type?: string;\n };\n const expressionSource = sliceNode(source, declaration);\n\n if (expression?.type === \"ArrowFunctionExpression\" || expression?.type === \"FunctionExpression\") {\n return wrapCallableBody(expressionSource);\n }\n\n return `return (${expressionSource});`;\n};\n\ntype ExportDefaultDeclarationNode = {\n type: string;\n start?: number | null;\n end?: number | null;\n id?: { name?: string | null } | null;\n expression?: unknown;\n};\n\nconst renderParsedBody = (source: string): string => {\n const program = parse(source, {\n sourceType: \"module\",\n allowAwaitOutsideFunction: true,\n allowReturnOutsideFunction: true,\n allowImportExportEverywhere: true,\n plugins: [\"typescript\"],\n }).program;\n\n if (program.body.length !== 1) return source;\n\n const [statement] = program.body;\n if (!statement) return source;\n\n switch (statement.type) {\n case \"ExpressionStatement\": {\n const expression = unwrapExpression(statement.expression as { type: string; expression?: unknown }) as {\n type?: string;\n };\n return expression?.type === \"ArrowFunctionExpression\" || expression?.type === \"FunctionExpression\"\n ? wrapCallableBody(source)\n : source;\n }\n case \"FunctionDeclaration\":\n return statement.id?.name ? wrapNamedFunctionBody(source, statement.id.name) : source;\n case \"ExportDefaultDeclaration\":\n return renderExportDefaultBody(source, statement.declaration);\n default:\n return source;\n }\n};\n\nconst renderHeuristicBody = (source: string): string => {\n const withoutDefaultExport = source.replace(/^export\\s+default\\s+/, \"\").trim();\n\n if (\n (withoutDefaultExport.startsWith(\"async\") || withoutDefaultExport.startsWith(\"(\")) &&\n withoutDefaultExport.includes(\"=>\")\n ) {\n return wrapCallableBody(withoutDefaultExport);\n }\n\n if (FUNCTION_DECLARATION.test(withoutDefaultExport)) {\n const name = withoutDefaultExport.match(FUNCTION_DECLARATION)?.[1];\n return name\n ? wrapNamedFunctionBody(withoutDefaultExport, name)\n : wrapAnonymousFunctionBody(withoutDefaultExport);\n }\n\n return withoutDefaultExport;\n};\n\nexport const recoverExecutionBody = (code: string): string => {\n const source = extractCandidateSource(code);\n if (!source) return \"\";\n\n try {\n return renderParsedBody(source);\n } catch {\n return renderHeuristicBody(source);\n }\n};\n"],"mappings":"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","names":[]}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { StandardSchemaV1 } from "@standard-schema/spec";
|
|
2
|
+
import type * as Cause from "effect/Cause";
|
|
2
3
|
import type * as Effect from "effect/Effect";
|
|
4
|
+
import type { CodeExecutionError } from "./effect-errors";
|
|
3
5
|
/** Branded tool path */
|
|
4
6
|
export type ToolPath = string & {
|
|
5
7
|
readonly __toolPath: unique symbol;
|
|
@@ -20,7 +22,7 @@ export interface SandboxToolInvoker {
|
|
|
20
22
|
invoke(input: {
|
|
21
23
|
path: string;
|
|
22
24
|
args: unknown;
|
|
23
|
-
}): Effect.Effect<unknown, unknown>;
|
|
25
|
+
}): Effect.Effect<unknown, unknown, never>;
|
|
24
26
|
}
|
|
25
27
|
/** Result of executing code in a sandbox */
|
|
26
28
|
export type ExecuteResult = {
|
|
@@ -28,9 +30,17 @@ export type ExecuteResult = {
|
|
|
28
30
|
error?: string;
|
|
29
31
|
logs?: string[];
|
|
30
32
|
};
|
|
31
|
-
/**
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
/**
|
|
34
|
+
* Executes code in a sandboxed runtime with tool access.
|
|
35
|
+
*
|
|
36
|
+
* Error channel is constrained to Effect's `YieldableError` (the base
|
|
37
|
+
* shape `Data.TaggedError(...)` produces) so callers always get a
|
|
38
|
+
* structurally tagged error, never untyped `unknown`. Defaults to
|
|
39
|
+
* `CodeExecutionError`; runtimes can parameterize with their own
|
|
40
|
+
* `Data.TaggedError` subclass — e.g. `CodeExecutor<WorkerLoaderError>`.
|
|
41
|
+
*/
|
|
42
|
+
export interface CodeExecutor<E extends Cause.YieldableError = CodeExecutionError> {
|
|
43
|
+
execute(code: string, toolInvoker: SandboxToolInvoker): Effect.Effect<ExecuteResult, E>;
|
|
34
44
|
}
|
|
35
45
|
/** Accept-anything schema for tools with no input validation */
|
|
36
46
|
export declare const unknownInputSchema: StandardSchema;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,KAAK,KAAK,MAAM,MAAM,eAAe,CAAC;AAE7C,wBAAwB;AACxB,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,UAAU,EAAE,OAAO,MAAM,CAAA;CAAE,CAAC;AAEvE,eAAO,MAAM,UAAU,GAAI,OAAO,MAAM,KAAG,QAA6B,CAAC;AAEzE,4BAA4B;AAC5B,MAAM,MAAM,cAAc,CAAC,KAAK,GAAG,OAAO,EAAE,MAAM,GAAG,OAAO,IAAI,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AAEhG,iCAAiC;AACjC,MAAM,WAAW,IAAI;IACnB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,cAAc,CAAC;IACrC,QAAQ,CAAC,YAAY,CAAC,EAAE,cAAc,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAClE;AAED,kDAAkD;AAClD,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,KAAK,MAAM,MAAM,eAAe,CAAC;AAE7C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAE1D,wBAAwB;AACxB,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,UAAU,EAAE,OAAO,MAAM,CAAA;CAAE,CAAC;AAEvE,eAAO,MAAM,UAAU,GAAI,OAAO,MAAM,KAAG,QAA6B,CAAC;AAEzE,4BAA4B;AAC5B,MAAM,MAAM,cAAc,CAAC,KAAK,GAAG,OAAO,EAAE,MAAM,GAAG,OAAO,IAAI,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AAEhG,iCAAiC;AACjC,MAAM,WAAW,IAAI;IACnB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,cAAc,CAAC;IACrC,QAAQ,CAAC,YAAY,CAAC,EAAE,cAAc,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAClE;AAED,kDAAkD;AAClD,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;CACxF;AAED,4CAA4C;AAC5C,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,WAAW,YAAY,CAAC,CAAC,SAAS,KAAK,CAAC,cAAc,GAAG,kBAAkB;IAC/E,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,kBAAkB,GAAG,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;CACzF;AAED,gEAAgE;AAChE,eAAO,MAAM,kBAAkB,EAAE,cAQhC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@executor-js/codemode-core",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"homepage": "https://github.com/RhysSullivan/executor/tree/main/packages/kernel/core",
|
|
5
5
|
"bugs": {
|
|
6
6
|
"url": "https://github.com/RhysSullivan/executor/issues"
|
|
@@ -38,13 +38,13 @@
|
|
|
38
38
|
"@standard-schema/spec": "^1.0.0",
|
|
39
39
|
"ajv": "^8.17.1",
|
|
40
40
|
"ajv-formats": "^3.0.1",
|
|
41
|
-
"effect": "
|
|
41
|
+
"effect": "4.0.0-beta.59"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@types/node": "^24.3.1",
|
|
45
45
|
"bun-types": "^1.2.22",
|
|
46
46
|
"tsup": "^8.5.0",
|
|
47
47
|
"typescript": "^5.9.3",
|
|
48
|
-
"vitest": "^4.1.
|
|
48
|
+
"vitest": "^4.1.5"
|
|
49
49
|
}
|
|
50
50
|
}
|