@earendil-works/pi-codemode 0.99.1 → 1.0.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 +4 -0
- package/dist/declarations.d.ts +5 -0
- package/dist/declarations.d.ts.map +1 -1
- package/dist/declarations.js +6 -2
- package/dist/declarations.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/runtime/host.d.ts.map +1 -1
- package/dist/runtime/host.js.map +1 -1
- package/dist/runtime/prelude-source.d.ts.map +1 -1
- package/dist/runtime/prelude-source.js +67 -8
- package/dist/runtime/prelude-source.js.map +1 -1
- package/dist/runtime/worker.js +1 -1
- package/dist/runtime/worker.js.map +1 -1
- package/dist/types.d.ts +3 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -92,6 +92,10 @@ const sandbox = new CodemodeSandbox({
|
|
|
92
92
|
});
|
|
93
93
|
```
|
|
94
94
|
|
|
95
|
+
`workerUrl` accepts a URL or string. For a Bun compiled executable, include the worker as an
|
|
96
|
+
additional build entrypoint and pass its relative source path as a string, for example
|
|
97
|
+
`"./src/codemode-worker.ts"`; Bun resolves that form from its embedded module graph.
|
|
98
|
+
|
|
95
99
|
## Declarations for the model
|
|
96
100
|
|
|
97
101
|
Tools and globals can carry `description`, `inputSchema`, and `outputSchema` (JSON Schema). `renderDeclarations()` turns them into TypeScript declarations for a model-facing tool description:
|
package/dist/declarations.d.ts
CHANGED
|
@@ -40,6 +40,11 @@ export declare function renderToolSample(tool: Pick<CodemodeTool, "name" | "desc
|
|
|
40
40
|
* `undefined` when the schema is not a `CallToolResult`.
|
|
41
41
|
*/
|
|
42
42
|
export declare function mcpStructuredContentSchema(schema: CodemodeJsonSchema | undefined): CodemodeJsonSchema | undefined;
|
|
43
|
+
/**
|
|
44
|
+
* The type a tool call resolves to: `CallToolResult<T>` for MCP output schemas (needs
|
|
45
|
+
* {@link MCP_TYPESCRIPT_PREAMBLE}), the schema's type otherwise, and `unknown` without a schema.
|
|
46
|
+
*/
|
|
47
|
+
export declare function renderToolOutputType(schema: CodemodeJsonSchema | undefined): string;
|
|
43
48
|
/**
|
|
44
49
|
* Convert a JSON Schema to a TypeScript type expression: objects on one line (`{ a: string; b?: number; }`) with properties sorted by name,
|
|
45
50
|
* or one property per line with `//` comments when a property has a description; `Array<T>` for
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"declarations.d.ts","sourceRoot":"","sources":["../src/declarations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEvD,OAAO,EAAE,oBAAoB,EAAE,CAAC;AAEhC,OAAO,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAInE,+EAA+E;AAC/E,eAAO,MAAM,8BAA8B,QAAS,CAAC;AAIrD;;;GAGG;AACH,eAAO,MAAM,uBAAuB,ymDA2EjC,CAAC;AAEJ,MAAM,WAAW,yBAAyB;IACzC,KAAK,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;IAChC,OAAO,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;CAClC;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,yBAAyB,GAAG,MAAM,CAyB7E;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAClC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,aAAa,GAAG,cAAc,CAAC,EACjE,OAAO,GAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAA;CAAO,GACtC,MAAM,CAMR;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC/B,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,aAAa,GAAG,aAAa,GAAG,cAAc,CAAC,EACjF,OAAO,GAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAA;CAAO,GACtC,MAAM,CAGR;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,kBAAkB,GAAG,SAAS,GAAG,kBAAkB,GAAG,SAAS,CASjH;
|
|
1
|
+
{"version":3,"file":"declarations.d.ts","sourceRoot":"","sources":["../src/declarations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEvD,OAAO,EAAE,oBAAoB,EAAE,CAAC;AAEhC,OAAO,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAInE,+EAA+E;AAC/E,eAAO,MAAM,8BAA8B,QAAS,CAAC;AAIrD;;;GAGG;AACH,eAAO,MAAM,uBAAuB,ymDA2EjC,CAAC;AAEJ,MAAM,WAAW,yBAAyB;IACzC,KAAK,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;IAChC,OAAO,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;CAClC;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,yBAAyB,GAAG,MAAM,CAyB7E;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAClC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,aAAa,GAAG,cAAc,CAAC,EACjE,OAAO,GAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAA;CAAO,GACtC,MAAM,CAMR;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC/B,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,aAAa,GAAG,aAAa,GAAG,cAAc,CAAC,EACjF,OAAO,GAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAA;CAAO,GACtC,MAAM,CAGR;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,kBAAkB,GAAG,SAAS,GAAG,kBAAkB,GAAG,SAAS,CASjH;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,kBAAkB,GAAG,SAAS,GAAG,MAAM,CAOnF;AAiCD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,kBAAkB,EAAE,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,MAAM,CAGpG"}
|
package/dist/declarations.js
CHANGED
|
@@ -126,7 +126,7 @@ export function renderToolSignature(tool, options = {}) {
|
|
|
126
126
|
const input = tool.inputSchema === undefined
|
|
127
127
|
? "unknown"
|
|
128
128
|
: schemaToType(tool.inputSchema, { maxChars: options.inputMaxChars ?? DEFAULT_INPUT_SCHEMA_MAX_CHARS });
|
|
129
|
-
return `${toCodemodeIdentifier(tool.name)}(args: ${input}): Promise<${
|
|
129
|
+
return `${toCodemodeIdentifier(tool.name)}(args: ${input}): Promise<${renderToolOutputType(tool.outputSchema)}>;`;
|
|
130
130
|
}
|
|
131
131
|
/**
|
|
132
132
|
* A tool's sample: the description followed by the tool's declaration. Used for tool
|
|
@@ -152,7 +152,11 @@ export function mcpStructuredContentSchema(schema) {
|
|
|
152
152
|
return undefined;
|
|
153
153
|
return isObject(structuredContent) || typeof structuredContent === "boolean" ? structuredContent : true;
|
|
154
154
|
}
|
|
155
|
-
|
|
155
|
+
/**
|
|
156
|
+
* The type a tool call resolves to: `CallToolResult<T>` for MCP output schemas (needs
|
|
157
|
+
* {@link MCP_TYPESCRIPT_PREAMBLE}), the schema's type otherwise, and `unknown` without a schema.
|
|
158
|
+
*/
|
|
159
|
+
export function renderToolOutputType(schema) {
|
|
156
160
|
const structured = mcpStructuredContentSchema(schema);
|
|
157
161
|
if (structured !== undefined) {
|
|
158
162
|
const type = schemaToType(structured);
|
package/dist/declarations.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"declarations.js","sourceRoot":"","sources":["../src/declarations.ts"],"names":[],"mappings":"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","sourcesContent":["import { toCodemodeIdentifier } from \"./identifier.ts\";\n\nexport { toCodemodeIdentifier };\n\nimport type { CodemodeJsonSchema, CodemodeTool } from \"./types.ts\";\n\nconst IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\nconst INDENT = \" \";\n/** Largest rendered input type, in characters, before it becomes `unknown`. */\nexport const DEFAULT_INPUT_SCHEMA_MAX_CHARS = 16_000;\n/** Local `$ref` expansions per rendered schema, so shared definitions cannot blow up the output. */\nconst MAX_REF_EXPANSIONS = 32;\n\n/**\n * TypeScript types for MCP results, from the MCP `CallToolResult` schema, so `CallToolResult<T>`\n * declarations can refer to them.\n */\nexport const MCP_TYPESCRIPT_PREAMBLE = `type Role = \"user\" | \"assistant\";\ntype MetaObject = Record<string, unknown>;\ntype Annotations = {\n audience?: Role[];\n priority?: number;\n lastModified?: string;\n};\ntype Icon = {\n src: string;\n mimeType?: string;\n sizes?: string[];\n theme?: \"light\" | \"dark\";\n};\ntype TextResourceContents = {\n uri: string;\n mimeType?: string;\n _meta?: MetaObject;\n text: string;\n};\ntype BlobResourceContents = {\n uri: string;\n mimeType?: string;\n _meta?: MetaObject;\n blob: string;\n};\ntype TextContent = {\n type: \"text\";\n text: string;\n annotations?: Annotations;\n _meta?: MetaObject;\n};\ntype ImageContent = {\n type: \"image\";\n data: string;\n mimeType: string;\n annotations?: Annotations;\n _meta?: MetaObject;\n};\ntype AudioContent = {\n type: \"audio\";\n data: string;\n mimeType: string;\n annotations?: Annotations;\n _meta?: MetaObject;\n};\ntype ResourceLink = {\n icons?: Icon[];\n name: string;\n title?: string;\n uri: string;\n description?: string;\n mimeType?: string;\n annotations?: Annotations;\n size?: number;\n _meta?: MetaObject;\n type: \"resource_link\";\n};\ntype EmbeddedResource = {\n type: \"resource\";\n resource: TextResourceContents | BlobResourceContents;\n annotations?: Annotations;\n _meta?: MetaObject;\n};\ntype ContentBlock =\n | TextContent\n | ImageContent\n | AudioContent\n | ResourceLink\n | EmbeddedResource;\ntype CallToolResult<TStructured = { [key: string]: unknown }> = {\n _meta?: MetaObject;\n content: ContentBlock[];\n isError?: boolean;\n structuredContent?: TStructured;\n [key: string]: unknown;\n};`;\n\nexport interface RenderDeclarationsOptions {\n\ttools?: readonly CodemodeTool[];\n\tglobals?: readonly CodemodeTool[];\n}\n\n/**\n * Render TypeScript declarations for the script-visible API. Tools become members of\n * `declare const tools`, globals become `declare function` statements, and `ns.member` globals\n * members of `declare const ns`. Descriptions become doc comments; schemas become types.\n */\nexport function renderDeclarations(options: RenderDeclarationsOptions): string {\n\tconst sections: string[] = [];\n\tconst tools = options.tools ?? [];\n\tif (tools.length > 0) {\n\t\tconst members = tools.map(\n\t\t\t(tool) => `${docComment(tool.description, INDENT)}${INDENT}${renderToolSignature(tool)}`,\n\t\t);\n\t\tsections.push(`declare const tools: {\\n${members.join(\"\\n\")}\\n};`);\n\t}\n\tconst namespaces = new Map<string, string[]>();\n\tfor (const global of options.globals ?? []) {\n\t\tconst dot = global.name.indexOf(\".\");\n\t\tif (dot === -1) {\n\t\t\tsections.push(renderGlobal(`declare function ${global.name}`, global, \"\"));\n\t\t\tcontinue;\n\t\t}\n\t\tconst namespace = global.name.slice(0, dot);\n\t\tconst members = namespaces.get(namespace) ?? [];\n\t\tif (members.length === 0) namespaces.set(namespace, members);\n\t\tmembers.push(renderGlobal(global.name.slice(dot + 1), global, INDENT));\n\t}\n\tfor (const [namespace, members] of namespaces) {\n\t\tsections.push(`declare const ${namespace}: {\\n${members.join(\"\\n\")}\\n};`);\n\t}\n\treturn sections.join(\"\\n\\n\");\n}\n\n/**\n * One tool as a member of the `tools` object: `name(args: T): Promise<R>;` with the\n * name as the identifier scripts use. Input types longer than `inputMaxChars` render as `unknown`.\n * Tools whose output schema is an MCP `CallToolResult` render as `Promise<CallToolResult<T>>`,\n * which needs {@link MCP_TYPESCRIPT_PREAMBLE}.\n */\nexport function renderToolSignature(\n\ttool: Pick<CodemodeTool, \"name\" | \"inputSchema\" | \"outputSchema\">,\n\toptions: { inputMaxChars?: number } = {},\n): string {\n\tconst input =\n\t\ttool.inputSchema === undefined\n\t\t\t? \"unknown\"\n\t\t\t: schemaToType(tool.inputSchema, { maxChars: options.inputMaxChars ?? DEFAULT_INPUT_SCHEMA_MAX_CHARS });\n\treturn `${toCodemodeIdentifier(tool.name)}(args: ${input}): Promise<${outputType(tool.outputSchema)}>;`;\n}\n\n/**\n * A tool's sample: the description followed by the tool's declaration. Used for tool\n * listings and `ALL_TOOLS` entries.\n */\nexport function renderToolSample(\n\ttool: Pick<CodemodeTool, \"name\" | \"description\" | \"inputSchema\" | \"outputSchema\">,\n\toptions: { inputMaxChars?: number } = {},\n): string {\n\tconst declaration = `declare const tools: { ${renderToolSignature(tool, options)} };`;\n\treturn `${tool.description?.trim() ?? \"\"}\\n\\ncodemode tool declaration:\\n\\`\\`\\`ts\\n${declaration}\\n\\`\\`\\``;\n}\n\n/**\n * The `structuredContent` schema of an MCP `CallToolResult` output schema (detected by a\n * `content` array of objects, boolean `isError`, and object `_meta`), `true` when it declares none, or\n * `undefined` when the schema is not a `CallToolResult`.\n */\nexport function mcpStructuredContentSchema(schema: CodemodeJsonSchema | undefined): CodemodeJsonSchema | undefined {\n\tif (!isObject(schema) || !isObject(schema.properties)) return undefined;\n\tconst { content, isError, _meta, structuredContent } = schema.properties;\n\tif (!isObject(content) || content.type !== \"array\" || !isObject(content.items) || content.items.type !== \"object\") {\n\t\treturn undefined;\n\t}\n\tif (!isObject(isError) || isError.type !== \"boolean\" || !isObject(_meta) || _meta.type !== \"object\")\n\t\treturn undefined;\n\treturn isObject(structuredContent) || typeof structuredContent === \"boolean\" ? structuredContent : true;\n}\n\nfunction outputType(schema: CodemodeJsonSchema | undefined): string {\n\tconst structured = mcpStructuredContentSchema(schema);\n\tif (structured !== undefined) {\n\t\tconst type = schemaToType(structured);\n\t\treturn type === \"unknown\" ? \"CallToolResult\" : `CallToolResult<${type}>`;\n\t}\n\treturn schema === undefined ? \"unknown\" : schemaToType(schema);\n}\n\nfunction renderGlobal(head: string, global: CodemodeTool, indent: string): string {\n\tif (global.signature !== undefined) {\n\t\treturn `${docComment(global.description, indent)}${indent}${head}${global.signature};`;\n\t}\n\tconst input = global.inputSchema === undefined ? \"unknown\" : schemaToType(global.inputSchema);\n\tconst output = global.outputSchema === undefined ? \"unknown\" : schemaToType(global.outputSchema);\n\treturn `${docComment(global.description, indent)}${indent}${head}(args: ${input}): Promise<${output}>;`;\n}\n\nfunction docComment(description: string | undefined, indent: string): string {\n\tconst text = description?.trim();\n\tif (!text) return \"\";\n\tconst lines = text.replaceAll(\"*/\", \"*\\\\/\").split(/\\r?\\n/);\n\tif (lines.length === 1) return `${indent}/** ${lines[0]} */\\n`;\n\treturn `${indent}/**\\n${lines.map((line) => `${indent} *${line ? ` ${line}` : \"\"}`).join(\"\\n\")}\\n${indent} */\\n`;\n}\n\nfunction propertyKey(name: string): string {\n\treturn IDENTIFIER.test(name) ? name : JSON.stringify(name);\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction union(types: string[]): string {\n\tconst unique = [...new Set(types)];\n\tif (unique.includes(\"unknown\")) return \"unknown\";\n\treturn unique.length === 0 ? \"never\" : unique.join(\" | \");\n}\n\n/**\n * Convert a JSON Schema to a TypeScript type expression: objects on one line (`{ a: string; b?: number; }`) with properties sorted by name,\n * or one property per line with `//` comments when a property has a description; `Array<T>` for\n * arrays. Local references (`#/$defs/...`, `#/definitions/...`) resolve against `schema`;\n * recursive and remote references render as `unknown`. A result longer than `maxChars` renders as\n * `unknown`.\n */\nexport function schemaToType(schema: CodemodeJsonSchema, options: { maxChars?: number } = {}): string {\n\tconst type = toType(schema, { root: schema, resolving: new Set(), expansions: 0 });\n\treturn options.maxChars !== undefined && type.length > options.maxChars ? \"unknown\" : type;\n}\n\ninterface SchemaContext {\n\troot: CodemodeJsonSchema;\n\t/** References being expanded on the current path, to stop at recursive types. */\n\tresolving: Set<string>;\n\texpansions: number;\n}\n\nfunction resolveRef(ref: string, root: CodemodeJsonSchema): CodemodeJsonSchema | undefined {\n\tif (ref !== \"#\" && !ref.startsWith(\"#/\")) return undefined;\n\tlet current: unknown = root;\n\tfor (const segment of ref.slice(2).split(\"/\").filter(Boolean)) {\n\t\tconst key = decodeURIComponent(segment).replaceAll(\"~1\", \"/\").replaceAll(\"~0\", \"~\");\n\t\tif (!isObject(current) || !(key in current)) return undefined;\n\t\tcurrent = current[key];\n\t}\n\treturn typeof current === \"boolean\" || isObject(current) ? current : undefined;\n}\n\nfunction toType(schema: CodemodeJsonSchema, context: SchemaContext): string {\n\tif (schema === true) return \"unknown\";\n\tif (schema === false) return \"never\";\n\tif (!isObject(schema)) return \"unknown\";\n\tif (typeof schema.$ref === \"string\") {\n\t\tconst ref = schema.$ref;\n\t\tif (context.resolving.has(ref) || context.expansions >= MAX_REF_EXPANSIONS) return \"unknown\";\n\t\tconst target = resolveRef(ref, context.root);\n\t\tif (target === undefined) return \"unknown\";\n\t\tcontext.expansions++;\n\t\tcontext.resolving.add(ref);\n\t\ttry {\n\t\t\treturn toType(target, context);\n\t\t} finally {\n\t\t\tcontext.resolving.delete(ref);\n\t\t}\n\t}\n\n\tif (\"const\" in schema) return JSON.stringify(schema.const) ?? \"unknown\";\n\tif (Array.isArray(schema.enum)) return union(schema.enum.map((value) => JSON.stringify(value) ?? \"unknown\"));\n\n\tconst variants = Array.isArray(schema.anyOf) ? schema.anyOf : Array.isArray(schema.oneOf) ? schema.oneOf : undefined;\n\tif (variants) return union(variants.map((variant) => toType(variant as CodemodeJsonSchema, context)));\n\tif (Array.isArray(schema.allOf)) {\n\t\tconst parts = schema.allOf\n\t\t\t.map((part) => toType(part as CodemodeJsonSchema, context))\n\t\t\t.filter((part) => part !== \"unknown\");\n\t\treturn parts.length === 0\n\t\t\t? \"unknown\"\n\t\t\t: parts.map((part) => (part.includes(\" | \") ? `(${part})` : part)).join(\" & \");\n\t}\n\n\tconst type = schema.type;\n\tif (Array.isArray(type)) return union(type.map((entry) => toType({ ...schema, type: entry }, context)));\n\tswitch (type) {\n\t\tcase \"string\":\n\t\t\treturn \"string\";\n\t\tcase \"number\":\n\t\tcase \"integer\":\n\t\t\treturn \"number\";\n\t\tcase \"boolean\":\n\t\t\treturn \"boolean\";\n\t\tcase \"null\":\n\t\t\treturn \"null\";\n\t\tcase \"array\":\n\t\t\treturn arrayType(schema, context);\n\t\tcase \"object\":\n\t\t\treturn objectType(schema, context);\n\t\tcase undefined:\n\t\t\tif (\"properties\" in schema || \"additionalProperties\" in schema || \"required\" in schema) {\n\t\t\t\treturn objectType(schema, context);\n\t\t\t}\n\t\t\tif (\"items\" in schema || \"prefixItems\" in schema) return arrayType(schema, context);\n\t\t\treturn \"unknown\";\n\t\tdefault:\n\t\t\treturn \"unknown\";\n\t}\n}\n\nfunction arrayType(schema: Record<string, unknown>, context: SchemaContext): string {\n\tif (schema.items !== undefined && !Array.isArray(schema.items)) {\n\t\treturn `Array<${toType(schema.items as CodemodeJsonSchema, context)}>`;\n\t}\n\tconst tuple = Array.isArray(schema.prefixItems)\n\t\t? schema.prefixItems\n\t\t: Array.isArray(schema.items)\n\t\t\t? schema.items\n\t\t\t: [];\n\tif (tuple.length > 0) return `[${tuple.map((item) => toType(item as CodemodeJsonSchema, context)).join(\", \")}]`;\n\treturn \"unknown[]\";\n}\n\nfunction descriptionOf(property: unknown): string {\n\treturn isObject(property) && typeof property.description === \"string\" ? property.description.trim() : \"\";\n}\n\nfunction objectType(schema: Record<string, unknown>, context: SchemaContext): string {\n\tconst properties = isObject(schema.properties) ? schema.properties : {};\n\tconst required = new Set(Array.isArray(schema.required) ? schema.required : []);\n\tconst names = Object.keys(properties).sort();\n\tconst members = names.map((name) => {\n\t\tconst optional = required.has(name) ? \"\" : \"?\";\n\t\treturn `${propertyKey(name)}${optional}: ${toType(properties[name] as CodemodeJsonSchema, context)};`;\n\t});\n\tconst additional = schema.additionalProperties;\n\tif (additional !== undefined && additional !== false) {\n\t\tconst type = additional === true ? \"unknown\" : toType(additional as CodemodeJsonSchema, context);\n\t\tmembers.push(`[key: string]: ${type};`);\n\t} else if (additional === undefined && names.length === 0) {\n\t\tmembers.push(\"[key: string]: unknown;\");\n\t}\n\tif (members.length === 0) return \"{}\";\n\tif (!names.some((name) => descriptionOf(properties[name]))) return `{ ${members.join(\" \")} }`;\n\n\tconst lines = [\"{\"];\n\tnames.forEach((name, index) => {\n\t\tfor (const line of descriptionOf(properties[name]).split(/\\r?\\n/)) {\n\t\t\tif (line.trim()) lines.push(`${INDENT}// ${line.trim()}`);\n\t\t}\n\t\tlines.push(`${INDENT}${members[index].replaceAll(\"\\n\", `\\n${INDENT}`)}`);\n\t});\n\tfor (const member of members.slice(names.length)) lines.push(`${INDENT}${member}`);\n\tlines.push(\"}\");\n\treturn lines.join(\"\\n\");\n}\n"]}
|
|
1
|
+
{"version":3,"file":"declarations.js","sourceRoot":"","sources":["../src/declarations.ts"],"names":[],"mappings":"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","sourcesContent":["import { toCodemodeIdentifier } from \"./identifier.ts\";\n\nexport { toCodemodeIdentifier };\n\nimport type { CodemodeJsonSchema, CodemodeTool } from \"./types.ts\";\n\nconst IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\nconst INDENT = \" \";\n/** Largest rendered input type, in characters, before it becomes `unknown`. */\nexport const DEFAULT_INPUT_SCHEMA_MAX_CHARS = 16_000;\n/** Local `$ref` expansions per rendered schema, so shared definitions cannot blow up the output. */\nconst MAX_REF_EXPANSIONS = 32;\n\n/**\n * TypeScript types for MCP results, from the MCP `CallToolResult` schema, so `CallToolResult<T>`\n * declarations can refer to them.\n */\nexport const MCP_TYPESCRIPT_PREAMBLE = `type Role = \"user\" | \"assistant\";\ntype MetaObject = Record<string, unknown>;\ntype Annotations = {\n audience?: Role[];\n priority?: number;\n lastModified?: string;\n};\ntype Icon = {\n src: string;\n mimeType?: string;\n sizes?: string[];\n theme?: \"light\" | \"dark\";\n};\ntype TextResourceContents = {\n uri: string;\n mimeType?: string;\n _meta?: MetaObject;\n text: string;\n};\ntype BlobResourceContents = {\n uri: string;\n mimeType?: string;\n _meta?: MetaObject;\n blob: string;\n};\ntype TextContent = {\n type: \"text\";\n text: string;\n annotations?: Annotations;\n _meta?: MetaObject;\n};\ntype ImageContent = {\n type: \"image\";\n data: string;\n mimeType: string;\n annotations?: Annotations;\n _meta?: MetaObject;\n};\ntype AudioContent = {\n type: \"audio\";\n data: string;\n mimeType: string;\n annotations?: Annotations;\n _meta?: MetaObject;\n};\ntype ResourceLink = {\n icons?: Icon[];\n name: string;\n title?: string;\n uri: string;\n description?: string;\n mimeType?: string;\n annotations?: Annotations;\n size?: number;\n _meta?: MetaObject;\n type: \"resource_link\";\n};\ntype EmbeddedResource = {\n type: \"resource\";\n resource: TextResourceContents | BlobResourceContents;\n annotations?: Annotations;\n _meta?: MetaObject;\n};\ntype ContentBlock =\n | TextContent\n | ImageContent\n | AudioContent\n | ResourceLink\n | EmbeddedResource;\ntype CallToolResult<TStructured = { [key: string]: unknown }> = {\n _meta?: MetaObject;\n content: ContentBlock[];\n isError?: boolean;\n structuredContent?: TStructured;\n [key: string]: unknown;\n};`;\n\nexport interface RenderDeclarationsOptions {\n\ttools?: readonly CodemodeTool[];\n\tglobals?: readonly CodemodeTool[];\n}\n\n/**\n * Render TypeScript declarations for the script-visible API. Tools become members of\n * `declare const tools`, globals become `declare function` statements, and `ns.member` globals\n * members of `declare const ns`. Descriptions become doc comments; schemas become types.\n */\nexport function renderDeclarations(options: RenderDeclarationsOptions): string {\n\tconst sections: string[] = [];\n\tconst tools = options.tools ?? [];\n\tif (tools.length > 0) {\n\t\tconst members = tools.map(\n\t\t\t(tool) => `${docComment(tool.description, INDENT)}${INDENT}${renderToolSignature(tool)}`,\n\t\t);\n\t\tsections.push(`declare const tools: {\\n${members.join(\"\\n\")}\\n};`);\n\t}\n\tconst namespaces = new Map<string, string[]>();\n\tfor (const global of options.globals ?? []) {\n\t\tconst dot = global.name.indexOf(\".\");\n\t\tif (dot === -1) {\n\t\t\tsections.push(renderGlobal(`declare function ${global.name}`, global, \"\"));\n\t\t\tcontinue;\n\t\t}\n\t\tconst namespace = global.name.slice(0, dot);\n\t\tconst members = namespaces.get(namespace) ?? [];\n\t\tif (members.length === 0) namespaces.set(namespace, members);\n\t\tmembers.push(renderGlobal(global.name.slice(dot + 1), global, INDENT));\n\t}\n\tfor (const [namespace, members] of namespaces) {\n\t\tsections.push(`declare const ${namespace}: {\\n${members.join(\"\\n\")}\\n};`);\n\t}\n\treturn sections.join(\"\\n\\n\");\n}\n\n/**\n * One tool as a member of the `tools` object: `name(args: T): Promise<R>;` with the\n * name as the identifier scripts use. Input types longer than `inputMaxChars` render as `unknown`.\n * Tools whose output schema is an MCP `CallToolResult` render as `Promise<CallToolResult<T>>`,\n * which needs {@link MCP_TYPESCRIPT_PREAMBLE}.\n */\nexport function renderToolSignature(\n\ttool: Pick<CodemodeTool, \"name\" | \"inputSchema\" | \"outputSchema\">,\n\toptions: { inputMaxChars?: number } = {},\n): string {\n\tconst input =\n\t\ttool.inputSchema === undefined\n\t\t\t? \"unknown\"\n\t\t\t: schemaToType(tool.inputSchema, { maxChars: options.inputMaxChars ?? DEFAULT_INPUT_SCHEMA_MAX_CHARS });\n\treturn `${toCodemodeIdentifier(tool.name)}(args: ${input}): Promise<${renderToolOutputType(tool.outputSchema)}>;`;\n}\n\n/**\n * A tool's sample: the description followed by the tool's declaration. Used for tool\n * listings and `ALL_TOOLS` entries.\n */\nexport function renderToolSample(\n\ttool: Pick<CodemodeTool, \"name\" | \"description\" | \"inputSchema\" | \"outputSchema\">,\n\toptions: { inputMaxChars?: number } = {},\n): string {\n\tconst declaration = `declare const tools: { ${renderToolSignature(tool, options)} };`;\n\treturn `${tool.description?.trim() ?? \"\"}\\n\\ncodemode tool declaration:\\n\\`\\`\\`ts\\n${declaration}\\n\\`\\`\\``;\n}\n\n/**\n * The `structuredContent` schema of an MCP `CallToolResult` output schema (detected by a\n * `content` array of objects, boolean `isError`, and object `_meta`), `true` when it declares none, or\n * `undefined` when the schema is not a `CallToolResult`.\n */\nexport function mcpStructuredContentSchema(schema: CodemodeJsonSchema | undefined): CodemodeJsonSchema | undefined {\n\tif (!isObject(schema) || !isObject(schema.properties)) return undefined;\n\tconst { content, isError, _meta, structuredContent } = schema.properties;\n\tif (!isObject(content) || content.type !== \"array\" || !isObject(content.items) || content.items.type !== \"object\") {\n\t\treturn undefined;\n\t}\n\tif (!isObject(isError) || isError.type !== \"boolean\" || !isObject(_meta) || _meta.type !== \"object\")\n\t\treturn undefined;\n\treturn isObject(structuredContent) || typeof structuredContent === \"boolean\" ? structuredContent : true;\n}\n\n/**\n * The type a tool call resolves to: `CallToolResult<T>` for MCP output schemas (needs\n * {@link MCP_TYPESCRIPT_PREAMBLE}), the schema's type otherwise, and `unknown` without a schema.\n */\nexport function renderToolOutputType(schema: CodemodeJsonSchema | undefined): string {\n\tconst structured = mcpStructuredContentSchema(schema);\n\tif (structured !== undefined) {\n\t\tconst type = schemaToType(structured);\n\t\treturn type === \"unknown\" ? \"CallToolResult\" : `CallToolResult<${type}>`;\n\t}\n\treturn schema === undefined ? \"unknown\" : schemaToType(schema);\n}\n\nfunction renderGlobal(head: string, global: CodemodeTool, indent: string): string {\n\tif (global.signature !== undefined) {\n\t\treturn `${docComment(global.description, indent)}${indent}${head}${global.signature};`;\n\t}\n\tconst input = global.inputSchema === undefined ? \"unknown\" : schemaToType(global.inputSchema);\n\tconst output = global.outputSchema === undefined ? \"unknown\" : schemaToType(global.outputSchema);\n\treturn `${docComment(global.description, indent)}${indent}${head}(args: ${input}): Promise<${output}>;`;\n}\n\nfunction docComment(description: string | undefined, indent: string): string {\n\tconst text = description?.trim();\n\tif (!text) return \"\";\n\tconst lines = text.replaceAll(\"*/\", \"*\\\\/\").split(/\\r?\\n/);\n\tif (lines.length === 1) return `${indent}/** ${lines[0]} */\\n`;\n\treturn `${indent}/**\\n${lines.map((line) => `${indent} *${line ? ` ${line}` : \"\"}`).join(\"\\n\")}\\n${indent} */\\n`;\n}\n\nfunction propertyKey(name: string): string {\n\treturn IDENTIFIER.test(name) ? name : JSON.stringify(name);\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction union(types: string[]): string {\n\tconst unique = [...new Set(types)];\n\tif (unique.includes(\"unknown\")) return \"unknown\";\n\treturn unique.length === 0 ? \"never\" : unique.join(\" | \");\n}\n\n/**\n * Convert a JSON Schema to a TypeScript type expression: objects on one line (`{ a: string; b?: number; }`) with properties sorted by name,\n * or one property per line with `//` comments when a property has a description; `Array<T>` for\n * arrays. Local references (`#/$defs/...`, `#/definitions/...`) resolve against `schema`;\n * recursive and remote references render as `unknown`. A result longer than `maxChars` renders as\n * `unknown`.\n */\nexport function schemaToType(schema: CodemodeJsonSchema, options: { maxChars?: number } = {}): string {\n\tconst type = toType(schema, { root: schema, resolving: new Set(), expansions: 0 });\n\treturn options.maxChars !== undefined && type.length > options.maxChars ? \"unknown\" : type;\n}\n\ninterface SchemaContext {\n\troot: CodemodeJsonSchema;\n\t/** References being expanded on the current path, to stop at recursive types. */\n\tresolving: Set<string>;\n\texpansions: number;\n}\n\nfunction resolveRef(ref: string, root: CodemodeJsonSchema): CodemodeJsonSchema | undefined {\n\tif (ref !== \"#\" && !ref.startsWith(\"#/\")) return undefined;\n\tlet current: unknown = root;\n\tfor (const segment of ref.slice(2).split(\"/\").filter(Boolean)) {\n\t\tconst key = decodeURIComponent(segment).replaceAll(\"~1\", \"/\").replaceAll(\"~0\", \"~\");\n\t\tif (!isObject(current) || !(key in current)) return undefined;\n\t\tcurrent = current[key];\n\t}\n\treturn typeof current === \"boolean\" || isObject(current) ? current : undefined;\n}\n\nfunction toType(schema: CodemodeJsonSchema, context: SchemaContext): string {\n\tif (schema === true) return \"unknown\";\n\tif (schema === false) return \"never\";\n\tif (!isObject(schema)) return \"unknown\";\n\tif (typeof schema.$ref === \"string\") {\n\t\tconst ref = schema.$ref;\n\t\tif (context.resolving.has(ref) || context.expansions >= MAX_REF_EXPANSIONS) return \"unknown\";\n\t\tconst target = resolveRef(ref, context.root);\n\t\tif (target === undefined) return \"unknown\";\n\t\tcontext.expansions++;\n\t\tcontext.resolving.add(ref);\n\t\ttry {\n\t\t\treturn toType(target, context);\n\t\t} finally {\n\t\t\tcontext.resolving.delete(ref);\n\t\t}\n\t}\n\n\tif (\"const\" in schema) return JSON.stringify(schema.const) ?? \"unknown\";\n\tif (Array.isArray(schema.enum)) return union(schema.enum.map((value) => JSON.stringify(value) ?? \"unknown\"));\n\n\tconst variants = Array.isArray(schema.anyOf) ? schema.anyOf : Array.isArray(schema.oneOf) ? schema.oneOf : undefined;\n\tif (variants) return union(variants.map((variant) => toType(variant as CodemodeJsonSchema, context)));\n\tif (Array.isArray(schema.allOf)) {\n\t\tconst parts = schema.allOf\n\t\t\t.map((part) => toType(part as CodemodeJsonSchema, context))\n\t\t\t.filter((part) => part !== \"unknown\");\n\t\treturn parts.length === 0\n\t\t\t? \"unknown\"\n\t\t\t: parts.map((part) => (part.includes(\" | \") ? `(${part})` : part)).join(\" & \");\n\t}\n\n\tconst type = schema.type;\n\tif (Array.isArray(type)) return union(type.map((entry) => toType({ ...schema, type: entry }, context)));\n\tswitch (type) {\n\t\tcase \"string\":\n\t\t\treturn \"string\";\n\t\tcase \"number\":\n\t\tcase \"integer\":\n\t\t\treturn \"number\";\n\t\tcase \"boolean\":\n\t\t\treturn \"boolean\";\n\t\tcase \"null\":\n\t\t\treturn \"null\";\n\t\tcase \"array\":\n\t\t\treturn arrayType(schema, context);\n\t\tcase \"object\":\n\t\t\treturn objectType(schema, context);\n\t\tcase undefined:\n\t\t\tif (\"properties\" in schema || \"additionalProperties\" in schema || \"required\" in schema) {\n\t\t\t\treturn objectType(schema, context);\n\t\t\t}\n\t\t\tif (\"items\" in schema || \"prefixItems\" in schema) return arrayType(schema, context);\n\t\t\treturn \"unknown\";\n\t\tdefault:\n\t\t\treturn \"unknown\";\n\t}\n}\n\nfunction arrayType(schema: Record<string, unknown>, context: SchemaContext): string {\n\tif (schema.items !== undefined && !Array.isArray(schema.items)) {\n\t\treturn `Array<${toType(schema.items as CodemodeJsonSchema, context)}>`;\n\t}\n\tconst tuple = Array.isArray(schema.prefixItems)\n\t\t? schema.prefixItems\n\t\t: Array.isArray(schema.items)\n\t\t\t? schema.items\n\t\t\t: [];\n\tif (tuple.length > 0) return `[${tuple.map((item) => toType(item as CodemodeJsonSchema, context)).join(\", \")}]`;\n\treturn \"unknown[]\";\n}\n\nfunction descriptionOf(property: unknown): string {\n\treturn isObject(property) && typeof property.description === \"string\" ? property.description.trim() : \"\";\n}\n\nfunction objectType(schema: Record<string, unknown>, context: SchemaContext): string {\n\tconst properties = isObject(schema.properties) ? schema.properties : {};\n\tconst required = new Set(Array.isArray(schema.required) ? schema.required : []);\n\tconst names = Object.keys(properties).sort();\n\tconst members = names.map((name) => {\n\t\tconst optional = required.has(name) ? \"\" : \"?\";\n\t\treturn `${propertyKey(name)}${optional}: ${toType(properties[name] as CodemodeJsonSchema, context)};`;\n\t});\n\tconst additional = schema.additionalProperties;\n\tif (additional !== undefined && additional !== false) {\n\t\tconst type = additional === true ? \"unknown\" : toType(additional as CodemodeJsonSchema, context);\n\t\tmembers.push(`[key: string]: ${type};`);\n\t} else if (additional === undefined && names.length === 0) {\n\t\tmembers.push(\"[key: string]: unknown;\");\n\t}\n\tif (members.length === 0) return \"{}\";\n\tif (!names.some((name) => descriptionOf(properties[name]))) return `{ ${members.join(\" \")} }`;\n\n\tconst lines = [\"{\"];\n\tnames.forEach((name, index) => {\n\t\tfor (const line of descriptionOf(properties[name]).split(/\\r?\\n/)) {\n\t\t\tif (line.trim()) lines.push(`${INDENT}// ${line.trim()}`);\n\t\t}\n\t\tlines.push(`${INDENT}${members[index].replaceAll(\"\\n\", `\\n${INDENT}`)}`);\n\t});\n\tfor (const member of members.slice(names.length)) lines.push(`${INDENT}${member}`);\n\tlines.push(\"}\");\n\treturn lines.join(\"\\n\");\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { DEFAULT_INPUT_SCHEMA_MAX_CHARS, MCP_TYPESCRIPT_PREAMBLE, mcpStructuredContentSchema, type RenderDeclarationsOptions, renderDeclarations, renderToolSample, renderToolSignature, schemaToType, } from "./declarations.ts";
|
|
1
|
+
export { DEFAULT_INPUT_SCHEMA_MAX_CHARS, MCP_TYPESCRIPT_PREAMBLE, mcpStructuredContentSchema, type RenderDeclarationsOptions, renderDeclarations, renderToolOutputType, renderToolSample, renderToolSignature, schemaToType, } from "./declarations.ts";
|
|
2
2
|
export { toCodemodeIdentifier } from "./identifier.ts";
|
|
3
3
|
export { CodemodeSandbox } from "./runtime/host.ts";
|
|
4
4
|
export { MAX_STORE_TOTAL_CHARS, MAX_STORE_VALUE_CHARS } from "./runtime/prelude-source.ts";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,8BAA8B,EAC9B,uBAAuB,EACvB,0BAA0B,EAC1B,KAAK,yBAAyB,EAC9B,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,YAAY,GACZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAC3F,OAAO,EACN,uBAAuB,EACvB,uBAAuB,EACvB,mBAAmB,EACnB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,mBAAmB,GACnB,MAAM,aAAa,CAAC;AACrB,YAAY,EACX,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,iBAAiB,EACjB,sBAAsB,EACtB,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,sBAAsB,EACtB,mBAAmB,EACnB,YAAY,EACZ,mBAAmB,GACnB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,KAAK,kBAAkB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,8BAA8B,EAC9B,uBAAuB,EACvB,0BAA0B,EAC1B,KAAK,yBAAyB,EAC9B,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,mBAAmB,EACnB,YAAY,GACZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAC3F,OAAO,EACN,uBAAuB,EACvB,uBAAuB,EACvB,mBAAmB,EACnB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,mBAAmB,GACnB,MAAM,aAAa,CAAC;AACrB,YAAY,EACX,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,iBAAiB,EACjB,sBAAsB,EACtB,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,sBAAsB,EACtB,mBAAmB,EACnB,YAAY,EACZ,mBAAmB,GACnB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,KAAK,kBAAkB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { DEFAULT_INPUT_SCHEMA_MAX_CHARS, MCP_TYPESCRIPT_PREAMBLE, mcpStructuredContentSchema, renderDeclarations, renderToolSample, renderToolSignature, schemaToType, } from "./declarations.js";
|
|
1
|
+
export { DEFAULT_INPUT_SCHEMA_MAX_CHARS, MCP_TYPESCRIPT_PREAMBLE, mcpStructuredContentSchema, renderDeclarations, renderToolOutputType, renderToolSample, renderToolSignature, schemaToType, } from "./declarations.js";
|
|
2
2
|
export { toCodemodeIdentifier } from "./identifier.js";
|
|
3
3
|
export { CodemodeSandbox } from "./runtime/host.js";
|
|
4
4
|
export { MAX_STORE_TOTAL_CHARS, MAX_STORE_VALUE_CHARS } from "./runtime/prelude-source.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,8BAA8B,EAC9B,uBAAuB,EACvB,0BAA0B,EAE1B,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,YAAY,GACZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAC3F,OAAO,EACN,uBAAuB,EACvB,uBAAuB,EACvB,mBAAmB,EAGnB,mBAAmB,GACnB,MAAM,aAAa,CAAC;AAerB,OAAO,EAA2B,eAAe,EAAE,MAAM,WAAW,CAAC","sourcesContent":["export {\n\tDEFAULT_INPUT_SCHEMA_MAX_CHARS,\n\tMCP_TYPESCRIPT_PREAMBLE,\n\tmcpStructuredContentSchema,\n\ttype RenderDeclarationsOptions,\n\trenderDeclarations,\n\trenderToolSample,\n\trenderToolSignature,\n\tschemaToType,\n} from \"./declarations.ts\";\nexport { toCodemodeIdentifier } from \"./identifier.ts\";\nexport { CodemodeSandbox } from \"./runtime/host.ts\";\nexport { MAX_STORE_TOTAL_CHARS, MAX_STORE_VALUE_CHARS } from \"./runtime/prelude-source.ts\";\nexport {\n\tCODEMODE_OPTIONS_PREFIX,\n\tCODEMODE_SOURCE_GRAMMAR,\n\tCodemodeSourceError,\n\ttype CodemodeSourceOptions,\n\ttype ParsedCodemodeSource,\n\tparseCodemodeSource,\n} from \"./source.ts\";\nexport type {\n\tCodemodeCall,\n\tCodemodeCallStatus,\n\tCodemodeError,\n\tCodemodeErrorKind,\n\tCodemodeExecuteOptions,\n\tCodemodeJsonSchema,\n\tCodemodeOutputItem,\n\tCodemodeResult,\n\tCodemodeSandboxOptions,\n\tCodemodeStoreWrites,\n\tCodemodeTool,\n\tCodemodeToolContext,\n} from \"./types.ts\";\nexport { type CodemodeWasmModule, loadQuickJSWasm } from \"./wasm.ts\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,8BAA8B,EAC9B,uBAAuB,EACvB,0BAA0B,EAE1B,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,mBAAmB,EACnB,YAAY,GACZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAC3F,OAAO,EACN,uBAAuB,EACvB,uBAAuB,EACvB,mBAAmB,EAGnB,mBAAmB,GACnB,MAAM,aAAa,CAAC;AAerB,OAAO,EAA2B,eAAe,EAAE,MAAM,WAAW,CAAC","sourcesContent":["export {\n\tDEFAULT_INPUT_SCHEMA_MAX_CHARS,\n\tMCP_TYPESCRIPT_PREAMBLE,\n\tmcpStructuredContentSchema,\n\ttype RenderDeclarationsOptions,\n\trenderDeclarations,\n\trenderToolOutputType,\n\trenderToolSample,\n\trenderToolSignature,\n\tschemaToType,\n} from \"./declarations.ts\";\nexport { toCodemodeIdentifier } from \"./identifier.ts\";\nexport { CodemodeSandbox } from \"./runtime/host.ts\";\nexport { MAX_STORE_TOTAL_CHARS, MAX_STORE_VALUE_CHARS } from \"./runtime/prelude-source.ts\";\nexport {\n\tCODEMODE_OPTIONS_PREFIX,\n\tCODEMODE_SOURCE_GRAMMAR,\n\tCodemodeSourceError,\n\ttype CodemodeSourceOptions,\n\ttype ParsedCodemodeSource,\n\tparseCodemodeSource,\n} from \"./source.ts\";\nexport type {\n\tCodemodeCall,\n\tCodemodeCallStatus,\n\tCodemodeError,\n\tCodemodeErrorKind,\n\tCodemodeExecuteOptions,\n\tCodemodeJsonSchema,\n\tCodemodeOutputItem,\n\tCodemodeResult,\n\tCodemodeSandboxOptions,\n\tCodemodeStoreWrites,\n\tCodemodeTool,\n\tCodemodeToolContext,\n} from \"./types.ts\";\nexport { type CodemodeWasmModule, loadQuickJSWasm } from \"./wasm.ts\";\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../src/runtime/host.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAIX,sBAAsB,EAEtB,cAAc,EACd,sBAAsB,EAEtB,YAAY,EACZ,MAAM,aAAa,CAAC;AAuQrB;;;;;;;;GAQG;AACH,qBAAa,eAAe;IAC3B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAmC;IAC/D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAmC;IACjE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAqB;IACtD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA+D;IACpF,OAAO,CAAC,QAAQ,CAAC,SAAS,
|
|
1
|
+
{"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../src/runtime/host.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAIX,sBAAsB,EAEtB,cAAc,EACd,sBAAsB,EAEtB,YAAY,EACZ,MAAM,aAAa,CAAC;AAuQrB;;;;;;;;GAQG;AACH,qBAAa,eAAe;IAC3B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAmC;IAC/D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAmC;IACjE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAqB;IACtD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA+D;IACpF,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;IACzC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwB;IAChD,OAAO,CAAC,MAAM,CAAS;IAEvB,YAAY,OAAO,GAAE,sBAA2B,EAmB/C;IAED,iEAAiE;IACjE,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAGrC;IAED,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEpC;IAED,IAAI,KAAK,IAAI,YAAY,EAAE,CAE1B;IAED,IAAI,OAAO,IAAI,YAAY,EAAE,CAE5B;IAED;;;;OAIG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,sBAA2B,GAAG,OAAO,CAAC,cAAc,CAAC,CAenF;IAED,8FAA8F;IACxF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAG3B;CACD"}
|
package/dist/runtime/host.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host.js","sourceRoot":"","sources":["../../src/runtime/host.ts"],"names":[],"mappings":"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","sourcesContent":["import { Worker } from \"node:worker_threads\";\nimport { toCodemodeIdentifier } from \"../identifier.ts\";\nimport type {\n\tCodemodeCall,\n\tCodemodeCallStatus,\n\tCodemodeError,\n\tCodemodeExecuteOptions,\n\tCodemodeOutputItem,\n\tCodemodeResult,\n\tCodemodeSandboxOptions,\n\tCodemodeStoreWrites,\n\tCodemodeTool,\n} from \"../types.ts\";\nimport { type CodemodeWasmModule, loadQuickJSWasm } from \"../wasm.ts\";\nimport {\n\ttype HostToWorkerMessage,\n\tisWorkerToHostMessage,\n\ttype WorkerData,\n\ttype WorkerToHostMessage,\n} from \"./protocol.ts\";\n\nconst DEFAULT_TIMEOUT_MS = 300_000;\nconst IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\nconst RESERVED_GLOBALS: ReadonlySet<string> = new Set([\n\t\"tools\",\n\t\"ALL_TOOLS\",\n\t\"console\",\n\t\"text\",\n\t\"image\",\n\t\"exit\",\n\t\"globalThis\",\n\t\"store\",\n\t\"load\",\n]);\n\nfunction errorMessage(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nfunction serializeStore(store: Readonly<Record<string, unknown>> | undefined): Record<string, string> {\n\tconst serialized: Record<string, string> = {};\n\tfor (const [key, value] of Object.entries(store ?? {})) {\n\t\tconst json = JSON.stringify(value);\n\t\tif (json !== undefined) serialized[key] = json;\n\t}\n\treturn serialized;\n}\n\nfunction parseStoreWrites(json: string): CodemodeStoreWrites {\n\tconst writes: CodemodeStoreWrites = { set: {}, delete: [] };\n\tfor (const [key, value] of JSON.parse(json) as [string, string?][]) {\n\t\tif (value === undefined) writes.delete.push(key);\n\t\telse writes.set[key] = JSON.parse(value);\n\t}\n\treturn writes;\n}\n\nfunction defaultWorkerUrl(): URL {\n\t// `.ts` when running from source (tests, tsx), `.js` from the published dist.\n\treturn new URL(import.meta.url.endsWith(\".ts\") ? \"./worker.ts\" : \"./worker.js\", import.meta.url);\n}\n\ninterface PendingCall {\n\trecord: CodemodeCall | undefined;\n\tstartedAt: number;\n\tcontroller: AbortController;\n}\n\ninterface ExecutionOptions {\n\tcode: string;\n\ttools: ReadonlyMap<string, CodemodeTool>;\n\tglobals: ReadonlyMap<string, CodemodeTool>;\n\ttimeoutMs: number;\n\tsignal: AbortSignal | undefined;\n\tmemoryLimitBytes: number | undefined;\n\tstore: Record<string, string>;\n\twasm: Promise<CodemodeWasmModule>;\n\tworkerUrl: URL;\n}\n\n/**\n * One script run in its own worker and QuickJS VM. A fresh worker per run keeps\n * termination simple: a runaway script, including one that only spins the\n * microtask queue, is killed with `terminate()` and cannot poison a later run.\n */\nclass Execution {\n\treadonly promise: Promise<CodemodeResult>;\n\tprivate resolveResult!: (result: CodemodeResult) => void;\n\tprivate worker: Worker | undefined;\n\tprivate readonly interrupt = new SharedArrayBuffer(4);\n\tprivate readonly tools: ReadonlyMap<string, CodemodeTool>;\n\tprivate readonly globals: ReadonlyMap<string, CodemodeTool>;\n\tprivate readonly signal: AbortSignal | undefined;\n\tprivate readonly timer: NodeJS.Timeout | undefined;\n\tprivate readonly output: CodemodeOutputItem[] = [];\n\tprivate readonly calls: CodemodeCall[] = [];\n\tprivate readonly pending = new Map<number, PendingCall>();\n\tprivate finished = false;\n\n\tconstructor(options: ExecutionOptions) {\n\t\tthis.promise = new Promise<CodemodeResult>((resolve) => {\n\t\t\tthis.resolveResult = resolve;\n\t\t});\n\t\tthis.tools = options.tools;\n\t\tthis.globals = options.globals;\n\t\tthis.signal = options.signal;\n\n\t\tif (Number.isFinite(options.timeoutMs)) {\n\t\t\tthis.timer = setTimeout(() => {\n\t\t\t\tthis.finish({ kind: \"timeout\", message: `Execution timed out after ${options.timeoutMs} ms` });\n\t\t\t}, options.timeoutMs);\n\t\t}\n\n\t\tif (options.signal) {\n\t\t\tif (options.signal.aborted) {\n\t\t\t\tthis.onAbort();\n\t\t\t} else {\n\t\t\t\toptions.signal.addEventListener(\"abort\", this.onAbort, { once: true });\n\t\t\t}\n\t\t}\n\n\t\toptions.wasm.then(\n\t\t\t(wasm) => this.start(options, wasm),\n\t\t\t(error: unknown) => {\n\t\t\t\tthis.finish({ kind: \"sandbox\", message: `Failed to load QuickJS: ${errorMessage(error)}` });\n\t\t\t},\n\t\t);\n\t}\n\n\tabort(message: string): Promise<CodemodeResult> {\n\t\tthis.finish({ kind: \"aborted\", message });\n\t\treturn this.promise;\n\t}\n\n\tprivate start(options: ExecutionOptions, wasm: CodemodeWasmModule): void {\n\t\tif (this.finished) return;\n\t\tconst workerData: WorkerData = {\n\t\t\tcode: options.code,\n\t\t\ttools: [...options.tools.values()].map((tool) => ({\n\t\t\t\tname: tool.name,\n\t\t\t\tjsName: toCodemodeIdentifier(tool.name),\n\t\t\t\tdescription: tool.description ?? \"\",\n\t\t\t})),\n\t\t\tglobals: [...options.globals.values()].map((global) => ({\n\t\t\t\tname: global.name,\n\t\t\t\tspread: global.spread === true,\n\t\t\t})),\n\t\t\twasm,\n\t\t\tmemoryLimitBytes: options.memoryLimitBytes,\n\t\t\tstore: options.store,\n\t\t\tinterrupt: this.interrupt,\n\t\t};\n\t\tlet worker: Worker;\n\t\ttry {\n\t\t\tworker = new Worker(options.workerUrl, { workerData });\n\t\t} catch (error) {\n\t\t\tthis.finish({ kind: \"sandbox\", message: `Failed to start worker: ${errorMessage(error)}` });\n\t\t\treturn;\n\t\t}\n\t\tthis.worker = worker;\n\t\tworker.on(\"message\", (message: unknown) => this.handleMessage(message));\n\t\tworker.on(\"error\", (error: unknown) => {\n\t\t\tthis.finish({\n\t\t\t\tkind: \"sandbox\",\n\t\t\t\tname: error instanceof Error ? error.name : undefined,\n\t\t\t\tmessage: errorMessage(error),\n\t\t\t});\n\t\t});\n\t\tworker.on(\"exit\", (code) => {\n\t\t\tthis.finish({ kind: \"sandbox\", message: `Worker exited with code ${code} before the script settled` });\n\t\t});\n\t}\n\n\tprivate readonly onAbort = (): void => {\n\t\tconst reason: unknown = this.signal?.reason;\n\t\tthis.finish({ kind: \"aborted\", message: reason instanceof Error ? reason.message : \"Execution aborted\" });\n\t};\n\n\tprivate post(message: HostToWorkerMessage): void {\n\t\tthis.worker?.postMessage(message);\n\t}\n\n\tprivate handleMessage(message: unknown): void {\n\t\tif (this.finished || !isWorkerToHostMessage(message)) return;\n\t\tswitch (message.type) {\n\t\t\tcase \"output\":\n\t\t\t\tthis.output.push(message.item);\n\t\t\t\tbreak;\n\t\t\tcase \"call\":\n\t\t\t\tvoid this.handleCall(message);\n\t\t\t\tbreak;\n\t\t\tcase \"done\":\n\t\t\t\tthis.handleDone(message);\n\t\t\t\tbreak;\n\t\t\tcase \"crash\":\n\t\t\t\tthis.finish({ kind: \"sandbox\", message: message.message });\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tprivate handleDone(message: Extract<WorkerToHostMessage, { type: \"done\" }>): void {\n\t\tif (!message.ok) {\n\t\t\tconst parsed = JSON.parse(message.error) as Omit<CodemodeError, \"kind\">;\n\t\t\tthis.finish({ kind: \"script\", ...parsed });\n\t\t\treturn;\n\t\t}\n\t\tthis.finish(undefined, message.value === undefined ? undefined : JSON.parse(message.value), message.writes);\n\t}\n\n\tprivate async handleCall(message: Extract<WorkerToHostMessage, { type: \"call\" }>): Promise<void> {\n\t\tconst { id, name } = message;\n\t\tconst isTool = message.target === \"tool\";\n\t\tconst record: CodemodeCall | undefined = isTool ? { name, status: \"cancelled\", durationMs: 0 } : undefined;\n\t\tif (record) this.calls.push(record);\n\t\tconst pending: PendingCall = { record, startedAt: performance.now(), controller: new AbortController() };\n\t\tthis.pending.set(id, pending);\n\n\t\tlet status: CodemodeCallStatus;\n\t\tlet reply: HostToWorkerMessage;\n\t\ttry {\n\t\t\tconst tool = (isTool ? this.tools : this.globals).get(name);\n\t\t\tif (!tool) throw new Error(`Unknown ${isTool ? \"tool\" : \"global\"} \"${name}\"`);\n\t\t\tconst args: unknown = message.args === undefined ? undefined : JSON.parse(message.args);\n\t\t\tconst value = await tool.execute(args, { signal: pending.controller.signal });\n\t\t\treply = { type: \"result\", id, ok: true, payload: value === undefined ? undefined : JSON.stringify(value) };\n\t\t\tstatus = \"ok\";\n\t\t} catch (error) {\n\t\t\treply = { type: \"result\", id, ok: false, payload: errorMessage(error) };\n\t\t\tstatus = \"error\";\n\t\t}\n\n\t\t// Already cancelled by finish(): the record keeps \"cancelled\" and the\n\t\t// worker is gone or going.\n\t\tif (!this.pending.delete(id)) return;\n\t\tif (record) {\n\t\t\trecord.status = status;\n\t\t\trecord.durationMs = performance.now() - pending.startedAt;\n\t\t}\n\t\tthis.post(reply);\n\t}\n\n\tprivate finish(error: CodemodeError | undefined, value?: unknown, writes?: string): void {\n\t\tif (this.finished) return;\n\t\tthis.finished = true;\n\t\tclearTimeout(this.timer);\n\t\tthis.signal?.removeEventListener(\"abort\", this.onAbort);\n\n\t\tconst now = performance.now();\n\t\tfor (const pending of this.pending.values()) {\n\t\t\tif (pending.record) pending.record.durationMs = now - pending.startedAt;\n\t\t\tpending.controller.abort();\n\t\t}\n\t\tthis.pending.clear();\n\n\t\tconst result: CodemodeResult = error\n\t\t\t? { ok: false, error, output: this.output, calls: this.calls }\n\t\t\t: {\n\t\t\t\t\tok: true,\n\t\t\t\t\tvalue,\n\t\t\t\t\toutput: this.output,\n\t\t\t\t\tcalls: this.calls,\n\t\t\t\t\tstoreWrites: writes === undefined ? { set: {}, delete: [] } : parseStoreWrites(writes),\n\t\t\t\t};\n\t\tif (!this.worker) {\n\t\t\tthis.resolveResult(result);\n\t\t\treturn;\n\t\t}\n\t\tAtomics.store(new Int32Array(this.interrupt), 0, 1);\n\t\tthis.worker\n\t\t\t.terminate()\n\t\t\t.catch(() => undefined)\n\t\t\t.then(() => this.resolveResult(result));\n\t}\n}\n\n/**\n * Runs JavaScript in a QuickJS VM (a separate wasm instance) inside a worker\n * thread. The script sees `tools.<name>(args)` for every registered tool, `ALL_TOOLS`,\n * the output helpers `text`, `image`, `exit`, and `console.*`, `store`/`load`, and the\n * configured globals; nothing else (no timers, `fetch`, `process`, `require`, modules).\n *\n * Each `execute()` gets its own worker and VM; the sandbox only holds the tool\n * table and defaults. `close()` aborts in-flight executions.\n */\nexport class CodemodeSandbox {\n\tprivate readonly toolsByName = new Map<string, CodemodeTool>();\n\tprivate readonly globalsByName = new Map<string, CodemodeTool>();\n\tprivate readonly timeoutMs: number;\n\tprivate readonly memoryLimitBytes: number | undefined;\n\tprivate readonly wasm: CodemodeWasmModule | Promise<CodemodeWasmModule> | undefined;\n\tprivate readonly workerUrl: URL;\n\tprivate readonly running = new Set<Execution>();\n\tprivate closed = false;\n\n\tconstructor(options: CodemodeSandboxOptions = {}) {\n\t\tthis.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n\t\tthis.memoryLimitBytes = options.memoryLimitBytes;\n\t\tthis.wasm = options.wasm;\n\t\tthis.workerUrl = options.workerUrl ?? defaultWorkerUrl();\n\t\tfor (const tool of options.tools ?? []) this.registerTool(tool);\n\t\tconst namespaces = new Set<string>();\n\t\tfor (const global of options.globals ?? []) {\n\t\t\tconst parts = global.name.split(\".\");\n\t\t\tif (parts.length > 2 || !parts.every((part) => IDENTIFIER.test(part)) || RESERVED_GLOBALS.has(parts[0])) {\n\t\t\t\tthrow new Error(`Invalid global name \"${global.name}\"`);\n\t\t\t}\n\t\t\tif (this.globalsByName.has(global.name)) throw new Error(`Global \"${global.name}\" is already registered`);\n\t\t\tif (parts.length === 2) namespaces.add(parts[0]);\n\t\t\tthis.globalsByName.set(global.name, global);\n\t\t}\n\t\tfor (const name of namespaces) {\n\t\t\tif (this.globalsByName.has(name)) throw new Error(`Global \"${name}\" conflicts with the namespace \"${name}\"`);\n\t\t}\n\t}\n\n\t/** Throws if a tool with the same name is already registered. */\n\tregisterTool(tool: CodemodeTool): void {\n\t\tif (this.toolsByName.has(tool.name)) throw new Error(`Tool \"${tool.name}\" is already registered`);\n\t\tthis.toolsByName.set(tool.name, tool);\n\t}\n\n\tunregisterTool(name: string): boolean {\n\t\treturn this.toolsByName.delete(name);\n\t}\n\n\tget tools(): CodemodeTool[] {\n\t\treturn [...this.toolsByName.values()];\n\t}\n\n\tget globals(): CodemodeTool[] {\n\t\treturn [...this.globalsByName.values()];\n\t}\n\n\t/**\n\t * `code` is an async function body: `return` and top-level `await` work.\n\t * Never rejects for script failures; those come back as `{ ok: false }`.\n\t * The script can use `store(key, value)` and `load(key)` on `options.store`.\n\t */\n\texecute(code: string, options: CodemodeExecuteOptions = {}): Promise<CodemodeResult> {\n\t\tif (this.closed) return Promise.reject(new Error(\"Sandbox is closed\"));\n\t\tconst execution = new Execution({\n\t\t\tcode,\n\t\t\ttools: new Map(this.toolsByName),\n\t\t\tglobals: this.globalsByName,\n\t\t\ttimeoutMs: options.timeoutMs ?? this.timeoutMs,\n\t\t\tsignal: options.signal,\n\t\t\tmemoryLimitBytes: this.memoryLimitBytes,\n\t\t\tstore: serializeStore(options.store),\n\t\t\twasm: this.wasm === undefined ? loadQuickJSWasm() : Promise.resolve(this.wasm),\n\t\t\tworkerUrl: this.workerUrl,\n\t\t});\n\t\tthis.running.add(execution);\n\t\treturn execution.promise.finally(() => this.running.delete(execution));\n\t}\n\n\t/** Aborts in-flight executions (they resolve with `kind: \"aborted\"`) and rejects new ones. */\n\tasync close(): Promise<void> {\n\t\tthis.closed = true;\n\t\tawait Promise.all([...this.running].map((execution) => execution.abort(\"Sandbox closed\")));\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"host.js","sourceRoot":"","sources":["../../src/runtime/host.ts"],"names":[],"mappings":"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","sourcesContent":["import { Worker } from \"node:worker_threads\";\nimport { toCodemodeIdentifier } from \"../identifier.ts\";\nimport type {\n\tCodemodeCall,\n\tCodemodeCallStatus,\n\tCodemodeError,\n\tCodemodeExecuteOptions,\n\tCodemodeOutputItem,\n\tCodemodeResult,\n\tCodemodeSandboxOptions,\n\tCodemodeStoreWrites,\n\tCodemodeTool,\n} from \"../types.ts\";\nimport { type CodemodeWasmModule, loadQuickJSWasm } from \"../wasm.ts\";\nimport {\n\ttype HostToWorkerMessage,\n\tisWorkerToHostMessage,\n\ttype WorkerData,\n\ttype WorkerToHostMessage,\n} from \"./protocol.ts\";\n\nconst DEFAULT_TIMEOUT_MS = 300_000;\nconst IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\nconst RESERVED_GLOBALS: ReadonlySet<string> = new Set([\n\t\"tools\",\n\t\"ALL_TOOLS\",\n\t\"console\",\n\t\"text\",\n\t\"image\",\n\t\"exit\",\n\t\"globalThis\",\n\t\"store\",\n\t\"load\",\n]);\n\nfunction errorMessage(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nfunction serializeStore(store: Readonly<Record<string, unknown>> | undefined): Record<string, string> {\n\tconst serialized: Record<string, string> = {};\n\tfor (const [key, value] of Object.entries(store ?? {})) {\n\t\tconst json = JSON.stringify(value);\n\t\tif (json !== undefined) serialized[key] = json;\n\t}\n\treturn serialized;\n}\n\nfunction parseStoreWrites(json: string): CodemodeStoreWrites {\n\tconst writes: CodemodeStoreWrites = { set: {}, delete: [] };\n\tfor (const [key, value] of JSON.parse(json) as [string, string?][]) {\n\t\tif (value === undefined) writes.delete.push(key);\n\t\telse writes.set[key] = JSON.parse(value);\n\t}\n\treturn writes;\n}\n\nfunction defaultWorkerUrl(): URL {\n\t// `.ts` when running from source (tests, tsx), `.js` from the published dist.\n\treturn new URL(import.meta.url.endsWith(\".ts\") ? \"./worker.ts\" : \"./worker.js\", import.meta.url);\n}\n\ninterface PendingCall {\n\trecord: CodemodeCall | undefined;\n\tstartedAt: number;\n\tcontroller: AbortController;\n}\n\ninterface ExecutionOptions {\n\tcode: string;\n\ttools: ReadonlyMap<string, CodemodeTool>;\n\tglobals: ReadonlyMap<string, CodemodeTool>;\n\ttimeoutMs: number;\n\tsignal: AbortSignal | undefined;\n\tmemoryLimitBytes: number | undefined;\n\tstore: Record<string, string>;\n\twasm: Promise<CodemodeWasmModule>;\n\tworkerUrl: string | URL;\n}\n\n/**\n * One script run in its own worker and QuickJS VM. A fresh worker per run keeps\n * termination simple: a runaway script, including one that only spins the\n * microtask queue, is killed with `terminate()` and cannot poison a later run.\n */\nclass Execution {\n\treadonly promise: Promise<CodemodeResult>;\n\tprivate resolveResult!: (result: CodemodeResult) => void;\n\tprivate worker: Worker | undefined;\n\tprivate readonly interrupt = new SharedArrayBuffer(4);\n\tprivate readonly tools: ReadonlyMap<string, CodemodeTool>;\n\tprivate readonly globals: ReadonlyMap<string, CodemodeTool>;\n\tprivate readonly signal: AbortSignal | undefined;\n\tprivate readonly timer: NodeJS.Timeout | undefined;\n\tprivate readonly output: CodemodeOutputItem[] = [];\n\tprivate readonly calls: CodemodeCall[] = [];\n\tprivate readonly pending = new Map<number, PendingCall>();\n\tprivate finished = false;\n\n\tconstructor(options: ExecutionOptions) {\n\t\tthis.promise = new Promise<CodemodeResult>((resolve) => {\n\t\t\tthis.resolveResult = resolve;\n\t\t});\n\t\tthis.tools = options.tools;\n\t\tthis.globals = options.globals;\n\t\tthis.signal = options.signal;\n\n\t\tif (Number.isFinite(options.timeoutMs)) {\n\t\t\tthis.timer = setTimeout(() => {\n\t\t\t\tthis.finish({ kind: \"timeout\", message: `Execution timed out after ${options.timeoutMs} ms` });\n\t\t\t}, options.timeoutMs);\n\t\t}\n\n\t\tif (options.signal) {\n\t\t\tif (options.signal.aborted) {\n\t\t\t\tthis.onAbort();\n\t\t\t} else {\n\t\t\t\toptions.signal.addEventListener(\"abort\", this.onAbort, { once: true });\n\t\t\t}\n\t\t}\n\n\t\toptions.wasm.then(\n\t\t\t(wasm) => this.start(options, wasm),\n\t\t\t(error: unknown) => {\n\t\t\t\tthis.finish({ kind: \"sandbox\", message: `Failed to load QuickJS: ${errorMessage(error)}` });\n\t\t\t},\n\t\t);\n\t}\n\n\tabort(message: string): Promise<CodemodeResult> {\n\t\tthis.finish({ kind: \"aborted\", message });\n\t\treturn this.promise;\n\t}\n\n\tprivate start(options: ExecutionOptions, wasm: CodemodeWasmModule): void {\n\t\tif (this.finished) return;\n\t\tconst workerData: WorkerData = {\n\t\t\tcode: options.code,\n\t\t\ttools: [...options.tools.values()].map((tool) => ({\n\t\t\t\tname: tool.name,\n\t\t\t\tjsName: toCodemodeIdentifier(tool.name),\n\t\t\t\tdescription: tool.description ?? \"\",\n\t\t\t})),\n\t\t\tglobals: [...options.globals.values()].map((global) => ({\n\t\t\t\tname: global.name,\n\t\t\t\tspread: global.spread === true,\n\t\t\t})),\n\t\t\twasm,\n\t\t\tmemoryLimitBytes: options.memoryLimitBytes,\n\t\t\tstore: options.store,\n\t\t\tinterrupt: this.interrupt,\n\t\t};\n\t\tlet worker: Worker;\n\t\ttry {\n\t\t\tworker = new Worker(options.workerUrl, { workerData });\n\t\t} catch (error) {\n\t\t\tthis.finish({ kind: \"sandbox\", message: `Failed to start worker: ${errorMessage(error)}` });\n\t\t\treturn;\n\t\t}\n\t\tthis.worker = worker;\n\t\tworker.on(\"message\", (message: unknown) => this.handleMessage(message));\n\t\tworker.on(\"error\", (error: unknown) => {\n\t\t\tthis.finish({\n\t\t\t\tkind: \"sandbox\",\n\t\t\t\tname: error instanceof Error ? error.name : undefined,\n\t\t\t\tmessage: errorMessage(error),\n\t\t\t});\n\t\t});\n\t\tworker.on(\"exit\", (code) => {\n\t\t\tthis.finish({ kind: \"sandbox\", message: `Worker exited with code ${code} before the script settled` });\n\t\t});\n\t}\n\n\tprivate readonly onAbort = (): void => {\n\t\tconst reason: unknown = this.signal?.reason;\n\t\tthis.finish({ kind: \"aborted\", message: reason instanceof Error ? reason.message : \"Execution aborted\" });\n\t};\n\n\tprivate post(message: HostToWorkerMessage): void {\n\t\tthis.worker?.postMessage(message);\n\t}\n\n\tprivate handleMessage(message: unknown): void {\n\t\tif (this.finished || !isWorkerToHostMessage(message)) return;\n\t\tswitch (message.type) {\n\t\t\tcase \"output\":\n\t\t\t\tthis.output.push(message.item);\n\t\t\t\tbreak;\n\t\t\tcase \"call\":\n\t\t\t\tvoid this.handleCall(message);\n\t\t\t\tbreak;\n\t\t\tcase \"done\":\n\t\t\t\tthis.handleDone(message);\n\t\t\t\tbreak;\n\t\t\tcase \"crash\":\n\t\t\t\tthis.finish({ kind: \"sandbox\", message: message.message });\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tprivate handleDone(message: Extract<WorkerToHostMessage, { type: \"done\" }>): void {\n\t\tif (!message.ok) {\n\t\t\tconst parsed = JSON.parse(message.error) as Omit<CodemodeError, \"kind\">;\n\t\t\tthis.finish({ kind: \"script\", ...parsed });\n\t\t\treturn;\n\t\t}\n\t\tthis.finish(undefined, message.value === undefined ? undefined : JSON.parse(message.value), message.writes);\n\t}\n\n\tprivate async handleCall(message: Extract<WorkerToHostMessage, { type: \"call\" }>): Promise<void> {\n\t\tconst { id, name } = message;\n\t\tconst isTool = message.target === \"tool\";\n\t\tconst record: CodemodeCall | undefined = isTool ? { name, status: \"cancelled\", durationMs: 0 } : undefined;\n\t\tif (record) this.calls.push(record);\n\t\tconst pending: PendingCall = { record, startedAt: performance.now(), controller: new AbortController() };\n\t\tthis.pending.set(id, pending);\n\n\t\tlet status: CodemodeCallStatus;\n\t\tlet reply: HostToWorkerMessage;\n\t\ttry {\n\t\t\tconst tool = (isTool ? this.tools : this.globals).get(name);\n\t\t\tif (!tool) throw new Error(`Unknown ${isTool ? \"tool\" : \"global\"} \"${name}\"`);\n\t\t\tconst args: unknown = message.args === undefined ? undefined : JSON.parse(message.args);\n\t\t\tconst value = await tool.execute(args, { signal: pending.controller.signal });\n\t\t\treply = { type: \"result\", id, ok: true, payload: value === undefined ? undefined : JSON.stringify(value) };\n\t\t\tstatus = \"ok\";\n\t\t} catch (error) {\n\t\t\treply = { type: \"result\", id, ok: false, payload: errorMessage(error) };\n\t\t\tstatus = \"error\";\n\t\t}\n\n\t\t// Already cancelled by finish(): the record keeps \"cancelled\" and the\n\t\t// worker is gone or going.\n\t\tif (!this.pending.delete(id)) return;\n\t\tif (record) {\n\t\t\trecord.status = status;\n\t\t\trecord.durationMs = performance.now() - pending.startedAt;\n\t\t}\n\t\tthis.post(reply);\n\t}\n\n\tprivate finish(error: CodemodeError | undefined, value?: unknown, writes?: string): void {\n\t\tif (this.finished) return;\n\t\tthis.finished = true;\n\t\tclearTimeout(this.timer);\n\t\tthis.signal?.removeEventListener(\"abort\", this.onAbort);\n\n\t\tconst now = performance.now();\n\t\tfor (const pending of this.pending.values()) {\n\t\t\tif (pending.record) pending.record.durationMs = now - pending.startedAt;\n\t\t\tpending.controller.abort();\n\t\t}\n\t\tthis.pending.clear();\n\n\t\tconst result: CodemodeResult = error\n\t\t\t? { ok: false, error, output: this.output, calls: this.calls }\n\t\t\t: {\n\t\t\t\t\tok: true,\n\t\t\t\t\tvalue,\n\t\t\t\t\toutput: this.output,\n\t\t\t\t\tcalls: this.calls,\n\t\t\t\t\tstoreWrites: writes === undefined ? { set: {}, delete: [] } : parseStoreWrites(writes),\n\t\t\t\t};\n\t\tif (!this.worker) {\n\t\t\tthis.resolveResult(result);\n\t\t\treturn;\n\t\t}\n\t\tAtomics.store(new Int32Array(this.interrupt), 0, 1);\n\t\tthis.worker\n\t\t\t.terminate()\n\t\t\t.catch(() => undefined)\n\t\t\t.then(() => this.resolveResult(result));\n\t}\n}\n\n/**\n * Runs JavaScript in a QuickJS VM (a separate wasm instance) inside a worker\n * thread. The script sees `tools.<name>(args)` for every registered tool, `ALL_TOOLS`,\n * the output helpers `text`, `image`, `exit`, and `console.*`, `store`/`load`, and the\n * configured globals; nothing else (no timers, `fetch`, `process`, `require`, modules).\n *\n * Each `execute()` gets its own worker and VM; the sandbox only holds the tool\n * table and defaults. `close()` aborts in-flight executions.\n */\nexport class CodemodeSandbox {\n\tprivate readonly toolsByName = new Map<string, CodemodeTool>();\n\tprivate readonly globalsByName = new Map<string, CodemodeTool>();\n\tprivate readonly timeoutMs: number;\n\tprivate readonly memoryLimitBytes: number | undefined;\n\tprivate readonly wasm: CodemodeWasmModule | Promise<CodemodeWasmModule> | undefined;\n\tprivate readonly workerUrl: string | URL;\n\tprivate readonly running = new Set<Execution>();\n\tprivate closed = false;\n\n\tconstructor(options: CodemodeSandboxOptions = {}) {\n\t\tthis.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n\t\tthis.memoryLimitBytes = options.memoryLimitBytes;\n\t\tthis.wasm = options.wasm;\n\t\tthis.workerUrl = options.workerUrl ?? defaultWorkerUrl();\n\t\tfor (const tool of options.tools ?? []) this.registerTool(tool);\n\t\tconst namespaces = new Set<string>();\n\t\tfor (const global of options.globals ?? []) {\n\t\t\tconst parts = global.name.split(\".\");\n\t\t\tif (parts.length > 2 || !parts.every((part) => IDENTIFIER.test(part)) || RESERVED_GLOBALS.has(parts[0])) {\n\t\t\t\tthrow new Error(`Invalid global name \"${global.name}\"`);\n\t\t\t}\n\t\t\tif (this.globalsByName.has(global.name)) throw new Error(`Global \"${global.name}\" is already registered`);\n\t\t\tif (parts.length === 2) namespaces.add(parts[0]);\n\t\t\tthis.globalsByName.set(global.name, global);\n\t\t}\n\t\tfor (const name of namespaces) {\n\t\t\tif (this.globalsByName.has(name)) throw new Error(`Global \"${name}\" conflicts with the namespace \"${name}\"`);\n\t\t}\n\t}\n\n\t/** Throws if a tool with the same name is already registered. */\n\tregisterTool(tool: CodemodeTool): void {\n\t\tif (this.toolsByName.has(tool.name)) throw new Error(`Tool \"${tool.name}\" is already registered`);\n\t\tthis.toolsByName.set(tool.name, tool);\n\t}\n\n\tunregisterTool(name: string): boolean {\n\t\treturn this.toolsByName.delete(name);\n\t}\n\n\tget tools(): CodemodeTool[] {\n\t\treturn [...this.toolsByName.values()];\n\t}\n\n\tget globals(): CodemodeTool[] {\n\t\treturn [...this.globalsByName.values()];\n\t}\n\n\t/**\n\t * `code` is an async function body: `return` and top-level `await` work.\n\t * Never rejects for script failures; those come back as `{ ok: false }`.\n\t * The script can use `store(key, value)` and `load(key)` on `options.store`.\n\t */\n\texecute(code: string, options: CodemodeExecuteOptions = {}): Promise<CodemodeResult> {\n\t\tif (this.closed) return Promise.reject(new Error(\"Sandbox is closed\"));\n\t\tconst execution = new Execution({\n\t\t\tcode,\n\t\t\ttools: new Map(this.toolsByName),\n\t\t\tglobals: this.globalsByName,\n\t\t\ttimeoutMs: options.timeoutMs ?? this.timeoutMs,\n\t\t\tsignal: options.signal,\n\t\t\tmemoryLimitBytes: this.memoryLimitBytes,\n\t\t\tstore: serializeStore(options.store),\n\t\t\twasm: this.wasm === undefined ? loadQuickJSWasm() : Promise.resolve(this.wasm),\n\t\t\tworkerUrl: this.workerUrl,\n\t\t});\n\t\tthis.running.add(execution);\n\t\treturn execution.promise.finally(() => this.running.delete(execution));\n\t}\n\n\t/** Aborts in-flight executions (they resolve with `kind: \"aborted\"`) and rejects new ones. */\n\tasync close(): Promise<void> {\n\t\tthis.closed = true;\n\t\tawait Promise.all([...this.running].map((execution) => execution.abort(\"Sandbox closed\")));\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prelude-source.d.ts","sourceRoot":"","sources":["../../src/runtime/prelude-source.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,qBAAqB,QAAa,CAAC;AAChD,eAAO,MAAM,qBAAqB,QAAc,CAAC;AAKjD,eAAO,MAAM,cAAc,EAAE,
|
|
1
|
+
{"version":3,"file":"prelude-source.d.ts","sourceRoot":"","sources":["../../src/runtime/prelude-source.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,qBAAqB,QAAa,CAAC;AAChD,eAAO,MAAM,qBAAqB,QAAc,CAAC;AAKjD,eAAO,MAAM,cAAc,EAAE,MA6V1B,CAAC"}
|
|
@@ -110,6 +110,34 @@ export const PRELUDE_SOURCE = `(function (bridge, toolsJson, globalsJson, storeJ
|
|
|
110
110
|
Object.freeze(tools);
|
|
111
111
|
Object.freeze(allTools);
|
|
112
112
|
|
|
113
|
+
// Reading a member that does not exist throws an error that names the close matches, instead of
|
|
114
|
+
// a later "not a function". \`in\` checks still work.
|
|
115
|
+
const comparable = (name) => name.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
116
|
+
function guard(target, label, names, hint) {
|
|
117
|
+
return new Proxy(target, {
|
|
118
|
+
get(object, property, receiver) {
|
|
119
|
+
if (typeof property !== "string" || property in object || property in Object.prototype || property === "then" || property === "toJSON") {
|
|
120
|
+
return Reflect.get(object, property, receiver);
|
|
121
|
+
}
|
|
122
|
+
const wanted = comparable(property);
|
|
123
|
+
const exact = names.filter((name) => comparable(name) === wanted);
|
|
124
|
+
const close = exact.length > 0 ? exact : names.filter((name) => wanted && (comparable(name).includes(wanted) || wanted.includes(comparable(name))));
|
|
125
|
+
let message = label + "." + property + " does not exist.";
|
|
126
|
+
if (close.length > 0) message += " Did you mean " + close.slice(0, 5).map((name) => label + "." + name).join(", ") + "?";
|
|
127
|
+
else if (names.length <= 20) message += " Available: " + names.join(", ") + ".";
|
|
128
|
+
if (hint) message += " " + hint;
|
|
129
|
+
message += ' Check for a member with "' + property + '" in ' + label + ".";
|
|
130
|
+
throw new TypeErrorCtor(message);
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
const toolsProxy = guard(
|
|
135
|
+
tools,
|
|
136
|
+
"tools",
|
|
137
|
+
allTools.map((tool) => tool.name),
|
|
138
|
+
"ALL_TOOLS lists every tool; searchTools(query) finds tools by topic.",
|
|
139
|
+
);
|
|
140
|
+
|
|
113
141
|
const namespaces = new Map();
|
|
114
142
|
for (const { name, spread } of parse(globalsJson)) {
|
|
115
143
|
const fn = caller("global", name, spread);
|
|
@@ -123,7 +151,9 @@ export const PRELUDE_SOURCE = `(function (bridge, toolsJson, globalsJson, storeJ
|
|
|
123
151
|
namespaces.get(namespace)[name.slice(dot + 1)] = fn;
|
|
124
152
|
}
|
|
125
153
|
for (const [namespace, members] of namespaces) {
|
|
126
|
-
Object.
|
|
154
|
+
Object.freeze(members);
|
|
155
|
+
const value = guard(members, namespace, Object.keys(members));
|
|
156
|
+
Object.defineProperty(globalThis, namespace, { value, enumerable: true });
|
|
127
157
|
}
|
|
128
158
|
|
|
129
159
|
// key -> JSON text. Sizes count key and JSON characters.
|
|
@@ -132,6 +162,9 @@ export const PRELUDE_SOURCE = `(function (bridge, toolsJson, globalsJson, storeJ
|
|
|
132
162
|
let storedChars = 0;
|
|
133
163
|
for (const [key, json] of stored) storedChars += key.length + json.length;
|
|
134
164
|
|
|
165
|
+
const STORE_HINT =
|
|
166
|
+
"store() is for small state such as IDs or summaries. Show images with image(), keep large data in variables, or write it to a file with a tool.";
|
|
167
|
+
|
|
135
168
|
function checkKey(name, key) {
|
|
136
169
|
if (typeof key !== "string") throw new TypeError(name + "() key must be a string");
|
|
137
170
|
}
|
|
@@ -155,11 +188,17 @@ export const PRELUDE_SOURCE = `(function (bridge, toolsJson, globalsJson, storeJ
|
|
|
155
188
|
throw new TypeError("store(" + stringify(key) + ") value is not JSON-serializable");
|
|
156
189
|
}
|
|
157
190
|
if (json.length > ${MAX_STORE_VALUE_CHARS}) {
|
|
158
|
-
throw new RangeError(
|
|
191
|
+
throw new RangeError(
|
|
192
|
+
"store(" + stringify(key) + ") value has " + json.length + " characters of JSON, more than the limit of ${MAX_STORE_VALUE_CHARS}. " +
|
|
193
|
+
STORE_HINT,
|
|
194
|
+
);
|
|
159
195
|
}
|
|
160
196
|
const next = storedChars - previous + key.length + json.length;
|
|
161
197
|
if (next > ${MAX_STORE_TOTAL_CHARS}) {
|
|
162
|
-
throw new RangeError(
|
|
198
|
+
throw new RangeError(
|
|
199
|
+
"store is full: stored values would exceed ${MAX_STORE_TOTAL_CHARS} characters of JSON. Delete keys with store(key, undefined). " +
|
|
200
|
+
STORE_HINT,
|
|
201
|
+
);
|
|
163
202
|
}
|
|
164
203
|
stored.set(key, json);
|
|
165
204
|
storedChars = next;
|
|
@@ -215,10 +254,18 @@ export const PRELUDE_SOURCE = `(function (bridge, toolsJson, globalsJson, storeJ
|
|
|
215
254
|
}
|
|
216
255
|
if (typeof value.data !== "string" || value.data === "") throw new TypeErrorCtor("image expected MCP image data");
|
|
217
256
|
if (value.data.toLowerCase().startsWith("data:")) return value.data;
|
|
218
|
-
|
|
219
|
-
return "data:" + mimeType + ";base64," + value.data;
|
|
257
|
+
return "data:;base64," + value.data;
|
|
220
258
|
}
|
|
221
259
|
|
|
260
|
+
// Base64 of the signatures of the formats providers accept inline (PNG, JPEG except
|
|
261
|
+
// JPEG-LS, GIF, "RIFF....WEBP"). Signatures start at byte 0, so their encodings are prefixes.
|
|
262
|
+
const IMAGE_SIGNATURES = [
|
|
263
|
+
["image/png", /^iVBORw0KGg/],
|
|
264
|
+
["image/jpeg", /^[/]9j[/](?!9)/],
|
|
265
|
+
["image/gif", /^R0lGOD[dl]h/],
|
|
266
|
+
["image/webp", /^UklG.{8}RUJQ/],
|
|
267
|
+
];
|
|
268
|
+
|
|
222
269
|
function image(value) {
|
|
223
270
|
const url = imageUrl(value);
|
|
224
271
|
if (url === "") throw new TypeErrorCtor(${JSON.stringify(IMAGE_HELPER_EXPECTS)});
|
|
@@ -232,7 +279,19 @@ export const PRELUDE_SOURCE = `(function (bridge, toolsJson, globalsJson, storeJ
|
|
|
232
279
|
if (scheme !== "data" || comma === -1 || header.slice(1).every((part) => part.toLowerCase() !== "base64")) {
|
|
233
280
|
throw new TypeErrorCtor("invalid image output. Pass a base64 data URI instead");
|
|
234
281
|
}
|
|
235
|
-
|
|
282
|
+
// Providers reject the whole request on a bad image, and a persisted image block would be
|
|
283
|
+
// resent on every later turn. Line breaks from wrapped base64 are dropped. The declared type
|
|
284
|
+
// is ignored in favor of the detected one, as providers also reject mismatches.
|
|
285
|
+
const data = url.slice(comma + 1).replace(/\\s+/g, "");
|
|
286
|
+
if (data.length % 4 !== 0 || !/^[A-Za-z0-9+/]+={0,2}$/.test(data)) {
|
|
287
|
+
throw new TypeErrorCtor("invalid image output. The image data is not valid base64 (truncated or corrupted?)");
|
|
288
|
+
}
|
|
289
|
+
const head = data.slice(0, 16);
|
|
290
|
+
const signature = IMAGE_SIGNATURES.find(([, pattern]) => pattern.test(head));
|
|
291
|
+
if (!signature) {
|
|
292
|
+
throw new TypeErrorCtor("invalid image output. The image data is not a PNG, JPEG, GIF, or WebP image");
|
|
293
|
+
}
|
|
294
|
+
if (!finished) bridge("output", "image", data, signature[0]);
|
|
236
295
|
}
|
|
237
296
|
|
|
238
297
|
function exit() {
|
|
@@ -255,7 +314,7 @@ export const PRELUDE_SOURCE = `(function (bridge, toolsJson, globalsJson, storeJ
|
|
|
255
314
|
}
|
|
256
315
|
Object.freeze(console);
|
|
257
316
|
|
|
258
|
-
Object.defineProperty(globalThis, "tools", { value:
|
|
317
|
+
Object.defineProperty(globalThis, "tools", { value: toolsProxy, enumerable: true });
|
|
259
318
|
Object.defineProperty(globalThis, "ALL_TOOLS", { value: allTools, enumerable: true });
|
|
260
319
|
Object.defineProperty(globalThis, "console", { value: console, enumerable: true });
|
|
261
320
|
Object.defineProperty(globalThis, "text", { value: text, enumerable: true });
|
|
@@ -283,7 +342,7 @@ export const PRELUDE_SOURCE = `(function (bridge, toolsJson, globalsJson, storeJ
|
|
|
283
342
|
run(fn) {
|
|
284
343
|
let promise;
|
|
285
344
|
try {
|
|
286
|
-
promise = fn(
|
|
345
|
+
promise = fn(toolsProxy, console);
|
|
287
346
|
} catch (error) {
|
|
288
347
|
done(false, describeError(error));
|
|
289
348
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prelude-source.js","sourceRoot":"","sources":["../../src/runtime/prelude-source.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,GAAG,IAAI,CAAC;AAChD,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,GAAG,IAAI,CAAC;AAEjD,MAAM,oBAAoB,GACzB,gGAAgG,CAAC;AAElG,MAAM,CAAC,MAAM,cAAc,GAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sBA8HhB,qBAAqB;uEAC4B,qBAAqB;;;eAG7E,qBAAqB;qEACiC,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BA4C7D,IAAI,CAAC,SAAS,CAAC,oBAAoB,CAAC;;;sEAGK,IAAI,CAAC,SAAS,CAAC,oBAAoB,CAAC;;;gEAG1C,IAAI,CAAC,SAAS,CAAC,oBAAoB,CAAC;;;;;;;;;;;;4CAYxD,IAAI,CAAC,SAAS,CAAC,oBAAoB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiG7E,CAAC","sourcesContent":["/**\n * JavaScript evaluated inside the QuickJS VM before the script runs.\n *\n * The VM is its own wasm instance, so nothing here guards a realm boundary.\n * The prelude keeps the host bridge in a closure so the script cannot call it\n * directly, and builds `tools`, `ALL_TOOLS`, the output helpers (`text`, `image`,\n * `exit`, `console`), and globals on top of it. Tool arguments and results cross\n * as JSON strings and are parsed on this side.\n *\n * Output helpers: `text(value)` appends a text item (non-strings are\n * JSON-stringified), `image(urlOrItem)` appends an image from a base64 `data:` URL, an\n * `{ image_url }` object, or an MCP `ImageContent` block, and `exit()` ends the script\n * successfully. `console.*` appends text items like `text()`.\n *\n * `store(key, value)` and `load(key)` are synchronous: they work on a snapshot of\n * JSON text passed in as `storeJson`, and the keys the script wrote are reported\n * with a successful \"done\".\n *\n * Evaluates to a function `(bridge, toolsJson, globalsJson, storeJson) => { settle, run, stalled }`.\n * `toolsJson` lists `{ name, jsName, description }`: `tools[jsName]` and `tools[name]` call the\n * tool, and `ALL_TOOLS` lists `{ name: jsName, description }`.\n * `stalled()` reports a script that has not finished while no host call is pending: with no timers\n * or I/O in the VM, nothing can ever resume it.\n * `globalsJson` lists `{ name, spread }`; `a.b` names are grouped into a frozen `a` object.\n * `bridge(kind, a, b, c)` with kind \"call\" or \"global\" (id, name, argsJson),\n * \"output\" (\"text\", text) or (\"image\", data, mimeType), or \"done\" (ok, valueJsonOrErrorJson, writesJson).\n */\nexport const MAX_STORE_VALUE_CHARS = 256 * 1024;\nexport const MAX_STORE_TOTAL_CHARS = 1024 * 1024;\n\nconst IMAGE_HELPER_EXPECTS =\n\t\"image expects a non-empty image URL string, an object with image_url, or a raw MCP image block\";\n\nexport const PRELUDE_SOURCE: string = `(function (bridge, toolsJson, globalsJson, storeJson) {\n\t\"use strict\";\n\tconst stringify = JSON.stringify;\n\tconst parse = JSON.parse;\n\tconst promiseThen = Promise.prototype.then;\n\tconst ErrorCtor = Error;\n\tconst TypeErrorCtor = TypeError;\n\tconst pending = new Map();\n\tlet nextId = 1;\n\tlet finished = false;\n\t// Thrown by exit() to unwind the script after it already reported success.\n\tconst EXIT = Object.freeze({});\n\n\tfunction done(ok, payload, writes) {\n\t\tif (finished) return;\n\t\tfinished = true;\n\t\tbridge(\"done\", ok, payload, writes);\n\t}\n\n\tfunction serialize(value) {\n\t\treturn value === undefined ? undefined : stringify(value);\n\t}\n\n\t// QuickJS stacks list frames only. Prefix \"Name: message\" like V8 so the\n\t// text reads the same as a Node error, and drop this prelude's frames.\n\tfunction errorText(error) {\n\t\tconst head = error.message ? error.name + \": \" + error.message : String(error.name);\n\t\tconst frames =\n\t\t\ttypeof error.stack === \"string\"\n\t\t\t\t? error.stack.split(\"\\\\n\").filter((line) => line.trim() && !line.includes(\"codemode-prelude.js\"))\n\t\t\t\t: [];\n\t\treturn [head, ...frames].join(\"\\\\n\");\n\t}\n\n\tfunction format(value) {\n\t\tif (typeof value === \"string\") return value;\n\t\tif (value instanceof ErrorCtor) return errorText(value);\n\t\ttry {\n\t\t\tconst json = stringify(value);\n\t\t\treturn json === undefined ? String(value) : json;\n\t\t} catch {\n\t\t\treturn String(value);\n\t\t}\n\t}\n\n\tfunction describeError(error) {\n\t\tif (error instanceof ErrorCtor) {\n\t\t\treturn stringify({ name: error.name, message: error.message, stack: errorText(error) });\n\t\t}\n\t\treturn stringify({ message: format(error) });\n\t}\n\n\tfunction caller(kind, name, spread) {\n\t\treturn (...args) =>\n\t\t\tnew Promise((resolve, reject) => {\n\t\t\t\tlet json;\n\t\t\t\ttry {\n\t\t\t\t\tjson = serialize(spread ? args : args[0]);\n\t\t\t\t} catch (error) {\n\t\t\t\t\treject(error);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst id = nextId++;\n\t\t\t\tpending.set(id, { resolve, reject });\n\t\t\t\tbridge(kind, id, name, json);\n\t\t\t});\n\t}\n\n\tconst tools = Object.create(null);\n\tconst allTools = [];\n\tfor (const { name, jsName, description } of parse(toolsJson)) {\n\t\tconst fn = caller(\"call\", name);\n\t\t// The first tool wins when two names normalize to the same identifier.\n\t\tif (!(jsName in tools)) {\n\t\t\ttools[jsName] = fn;\n\t\t\tallTools.push(Object.freeze({ name: jsName, description }));\n\t\t}\n\t\tif (!(name in tools)) tools[name] = fn;\n\t}\n\tObject.freeze(tools);\n\tObject.freeze(allTools);\n\n\tconst namespaces = new Map();\n\tfor (const { name, spread } of parse(globalsJson)) {\n\t\tconst fn = caller(\"global\", name, spread);\n\t\tconst dot = name.indexOf(\".\");\n\t\tif (dot === -1) {\n\t\t\tObject.defineProperty(globalThis, name, { value: fn, enumerable: true });\n\t\t\tcontinue;\n\t\t}\n\t\tconst namespace = name.slice(0, dot);\n\t\tif (!namespaces.has(namespace)) namespaces.set(namespace, Object.create(null));\n\t\tnamespaces.get(namespace)[name.slice(dot + 1)] = fn;\n\t}\n\tfor (const [namespace, members] of namespaces) {\n\t\tObject.defineProperty(globalThis, namespace, { value: Object.freeze(members), enumerable: true });\n\t}\n\n\t// key -> JSON text. Sizes count key and JSON characters.\n\tconst stored = new Map(Object.entries(parse(storeJson)));\n\tconst writes = new Map();\n\tlet storedChars = 0;\n\tfor (const [key, json] of stored) storedChars += key.length + json.length;\n\n\tfunction checkKey(name, key) {\n\t\tif (typeof key !== \"string\") throw new TypeError(name + \"() key must be a string\");\n\t}\n\n\tfunction store(key, value) {\n\t\tcheckKey(\"store\", key);\n\t\tconst previous = stored.has(key) ? key.length + stored.get(key).length : 0;\n\t\tif (value === undefined) {\n\t\t\tstored.delete(key);\n\t\t\tstoredChars -= previous;\n\t\t\twrites.set(key, undefined);\n\t\t\treturn;\n\t\t}\n\t\tlet json;\n\t\ttry {\n\t\t\tjson = stringify(value);\n\t\t} catch (error) {\n\t\t\tthrow new TypeError(\"store(\" + stringify(key) + \") value is not JSON-serializable: \" + format(error));\n\t\t}\n\t\tif (json === undefined) {\n\t\t\tthrow new TypeError(\"store(\" + stringify(key) + \") value is not JSON-serializable\");\n\t\t}\n\t\tif (json.length > ${MAX_STORE_VALUE_CHARS}) {\n\t\t\tthrow new RangeError(\"store(\" + stringify(key) + \") value exceeds ${MAX_STORE_VALUE_CHARS} characters of JSON\");\n\t\t}\n\t\tconst next = storedChars - previous + key.length + json.length;\n\t\tif (next > ${MAX_STORE_TOTAL_CHARS}) {\n\t\t\tthrow new RangeError(\"store is full: stored values would exceed ${MAX_STORE_TOTAL_CHARS} characters of JSON\");\n\t\t}\n\t\tstored.set(key, json);\n\t\tstoredChars = next;\n\t\twrites.set(key, json);\n\t}\n\n\tfunction load(key) {\n\t\tcheckKey(\"load\", key);\n\t\tconst json = stored.get(key);\n\t\treturn json === undefined ? undefined : parse(json);\n\t}\n\n\tfunction serializeWrites() {\n\t\tconst entries = [];\n\t\tfor (const [key, json] of writes) entries.push(json === undefined ? [key] : [key, json]);\n\t\treturn stringify(entries);\n\t}\n\n\tObject.defineProperty(globalThis, \"store\", { value: store, enumerable: true });\n\tObject.defineProperty(globalThis, \"load\", { value: load, enumerable: true });\n\n\t// Primitives become their string form, everything else JSON.\n\tfunction outputText(value) {\n\t\tif (value === undefined || value === null || typeof value !== \"object\" && typeof value !== \"function\") {\n\t\t\treturn String(value);\n\t\t}\n\t\tconst json = stringify(value);\n\t\treturn json === undefined ? String(value) : json;\n\t}\n\n\tfunction text(value) {\n\t\tlet rendered;\n\t\ttry {\n\t\t\trendered = outputText(value);\n\t\t} catch (error) {\n\t\t\tthrow new TypeErrorCtor(error instanceof ErrorCtor ? error.message : String(error));\n\t\t}\n\t\tif (!finished) bridge(\"output\", \"text\", rendered);\n\t}\n\n\tfunction imageUrl(value) {\n\t\tif (typeof value === \"string\") return value;\n\t\tif (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n\t\t\tthrow new TypeErrorCtor(${JSON.stringify(IMAGE_HELPER_EXPECTS)});\n\t\t}\n\t\tif (value.image_url !== undefined) {\n\t\t\tif (typeof value.image_url !== \"string\") throw new TypeErrorCtor(${JSON.stringify(IMAGE_HELPER_EXPECTS)});\n\t\t\treturn value.image_url;\n\t\t}\n\t\tif (typeof value.type !== \"string\") throw new TypeErrorCtor(${JSON.stringify(IMAGE_HELPER_EXPECTS)});\n\t\tif (value.type !== \"image\") {\n\t\t\tthrow new TypeErrorCtor('image only accepts MCP image blocks, got \"' + value.type + '\"');\n\t\t}\n\t\tif (typeof value.data !== \"string\" || value.data === \"\") throw new TypeErrorCtor(\"image expected MCP image data\");\n\t\tif (value.data.toLowerCase().startsWith(\"data:\")) return value.data;\n\t\tconst mimeType = typeof value.mimeType === \"string\" && value.mimeType ? value.mimeType : \"application/octet-stream\";\n\t\treturn \"data:\" + mimeType + \";base64,\" + value.data;\n\t}\n\n\tfunction image(value) {\n\t\tconst url = imageUrl(value);\n\t\tif (url === \"\") throw new TypeErrorCtor(${JSON.stringify(IMAGE_HELPER_EXPECTS)});\n\t\tconst colon = url.indexOf(\":\");\n\t\tconst scheme = colon === -1 ? \"\" : url.slice(0, colon).toLowerCase();\n\t\tif (scheme === \"http\" || scheme === \"https\") {\n\t\t\tthrow new TypeErrorCtor(\"remote image URLs are not supported in tool outputs. Pass a base64 data URI instead\");\n\t\t}\n\t\tconst comma = url.indexOf(\",\");\n\t\tconst header = comma === -1 ? [] : url.slice(colon + 1, comma).split(\";\");\n\t\tif (scheme !== \"data\" || comma === -1 || header.slice(1).every((part) => part.toLowerCase() !== \"base64\")) {\n\t\t\tthrow new TypeErrorCtor(\"invalid image output. Pass a base64 data URI instead\");\n\t\t}\n\t\tif (!finished) bridge(\"output\", \"image\", url.slice(comma + 1), header[0] || \"application/octet-stream\");\n\t}\n\n\tfunction exit() {\n\t\tlet writesJson;\n\t\ttry {\n\t\t\twritesJson = serializeWrites();\n\t\t} catch (error) {\n\t\t\tdone(false, describeError(error));\n\t\t\tthrow EXIT;\n\t\t}\n\t\tdone(true, undefined, writesJson);\n\t\tthrow EXIT;\n\t}\n\n\tconst console = {};\n\tfor (const level of [\"log\", \"info\", \"warn\", \"error\", \"debug\"]) {\n\t\tconsole[level] = (...args) => {\n\t\t\tif (!finished) bridge(\"output\", \"text\", args.map(format).join(\" \"));\n\t\t};\n\t}\n\tObject.freeze(console);\n\n\tObject.defineProperty(globalThis, \"tools\", { value: tools, enumerable: true });\n\tObject.defineProperty(globalThis, \"ALL_TOOLS\", { value: allTools, enumerable: true });\n\tObject.defineProperty(globalThis, \"console\", { value: console, enumerable: true });\n\tObject.defineProperty(globalThis, \"text\", { value: text, enumerable: true });\n\tObject.defineProperty(globalThis, \"image\", { value: image, enumerable: true });\n\tObject.defineProperty(globalThis, \"exit\", { value: exit, enumerable: true });\n\n\treturn {\n\t\tsettle(id, ok, payload) {\n\t\t\tconst entry = pending.get(id);\n\t\t\tif (!entry) return;\n\t\t\tpending.delete(id);\n\t\t\tif (!ok) {\n\t\t\t\tentry.reject(new ErrorCtor(payload));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tlet value;\n\t\t\ttry {\n\t\t\t\tvalue = payload === undefined ? undefined : parse(payload);\n\t\t\t} catch (error) {\n\t\t\t\tentry.reject(error);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tentry.resolve(value);\n\t\t},\n\t\trun(fn) {\n\t\t\tlet promise;\n\t\t\ttry {\n\t\t\t\tpromise = fn(tools, console);\n\t\t\t} catch (error) {\n\t\t\t\tdone(false, describeError(error));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tpromiseThen.call(\n\t\t\t\tpromise,\n\t\t\t\t(value) => {\n\t\t\t\t\tlet json;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tjson = serialize(value);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tdone(false, describeError(error));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tdone(true, json, serializeWrites());\n\t\t\t\t},\n\t\t\t\t(error) => {\n\t\t\t\t\tdone(false, describeError(error));\n\t\t\t\t},\n\t\t\t);\n\t\t},\n\t\tstalled() {\n\t\t\tif (finished || pending.size > 0) return false;\n\t\t\tdone(\n\t\t\t\tfalse,\n\t\t\t\tstringify({\n\t\t\t\t\tname: \"Error\",\n\t\t\t\t\tmessage:\n\t\t\t\t\t\t\"The script is waiting on a promise that can never settle: no tool call is pending, and timers do not exist here.\",\n\t\t\t\t}),\n\t\t\t);\n\t\t\treturn true;\n\t\t},\n\t};\n})`;\n"]}
|
|
1
|
+
{"version":3,"file":"prelude-source.js","sourceRoot":"","sources":["../../src/runtime/prelude-source.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,GAAG,IAAI,CAAC;AAChD,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,GAAG,IAAI,CAAC;AAEjD,MAAM,oBAAoB,GACzB,gGAAgG,CAAC;AAElG,MAAM,CAAC,MAAM,cAAc,GAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sBA+JhB,qBAAqB;;8GAEmE,qBAAqB;;;;;eAKpH,qBAAqB;;iDAEa,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BA8CzC,IAAI,CAAC,SAAS,CAAC,oBAAoB,CAAC;;;sEAGK,IAAI,CAAC,SAAS,CAAC,oBAAoB,CAAC;;;gEAG1C,IAAI,CAAC,SAAS,CAAC,oBAAoB,CAAC;;;;;;;;;;;;;;;;;;;;4CAoBxD,IAAI,CAAC,SAAS,CAAC,oBAAoB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6G7E,CAAC","sourcesContent":["/**\n * JavaScript evaluated inside the QuickJS VM before the script runs.\n *\n * The VM is its own wasm instance, so nothing here guards a realm boundary.\n * The prelude keeps the host bridge in a closure so the script cannot call it\n * directly, and builds `tools`, `ALL_TOOLS`, the output helpers (`text`, `image`,\n * `exit`, `console`), and globals on top of it. Tool arguments and results cross\n * as JSON strings and are parsed on this side.\n *\n * Output helpers: `text(value)` appends a text item (non-strings are\n * JSON-stringified), `image(urlOrItem)` appends an image from a base64 `data:` URL, an\n * `{ image_url }` object, or an MCP `ImageContent` block, and `exit()` ends the script\n * successfully. `console.*` appends text items like `text()`.\n *\n * `store(key, value)` and `load(key)` are synchronous: they work on a snapshot of\n * JSON text passed in as `storeJson`, and the keys the script wrote are reported\n * with a successful \"done\".\n *\n * Evaluates to a function `(bridge, toolsJson, globalsJson, storeJson) => { settle, run, stalled }`.\n * `toolsJson` lists `{ name, jsName, description }`: `tools[jsName]` and `tools[name]` call the\n * tool, and `ALL_TOOLS` lists `{ name: jsName, description }`.\n * `stalled()` reports a script that has not finished while no host call is pending: with no timers\n * or I/O in the VM, nothing can ever resume it.\n * `globalsJson` lists `{ name, spread }`; `a.b` names are grouped into a frozen `a` object.\n * `bridge(kind, a, b, c)` with kind \"call\" or \"global\" (id, name, argsJson),\n * \"output\" (\"text\", text) or (\"image\", data, mimeType), or \"done\" (ok, valueJsonOrErrorJson, writesJson).\n */\nexport const MAX_STORE_VALUE_CHARS = 256 * 1024;\nexport const MAX_STORE_TOTAL_CHARS = 1024 * 1024;\n\nconst IMAGE_HELPER_EXPECTS =\n\t\"image expects a non-empty image URL string, an object with image_url, or a raw MCP image block\";\n\nexport const PRELUDE_SOURCE: string = `(function (bridge, toolsJson, globalsJson, storeJson) {\n\t\"use strict\";\n\tconst stringify = JSON.stringify;\n\tconst parse = JSON.parse;\n\tconst promiseThen = Promise.prototype.then;\n\tconst ErrorCtor = Error;\n\tconst TypeErrorCtor = TypeError;\n\tconst pending = new Map();\n\tlet nextId = 1;\n\tlet finished = false;\n\t// Thrown by exit() to unwind the script after it already reported success.\n\tconst EXIT = Object.freeze({});\n\n\tfunction done(ok, payload, writes) {\n\t\tif (finished) return;\n\t\tfinished = true;\n\t\tbridge(\"done\", ok, payload, writes);\n\t}\n\n\tfunction serialize(value) {\n\t\treturn value === undefined ? undefined : stringify(value);\n\t}\n\n\t// QuickJS stacks list frames only. Prefix \"Name: message\" like V8 so the\n\t// text reads the same as a Node error, and drop this prelude's frames.\n\tfunction errorText(error) {\n\t\tconst head = error.message ? error.name + \": \" + error.message : String(error.name);\n\t\tconst frames =\n\t\t\ttypeof error.stack === \"string\"\n\t\t\t\t? error.stack.split(\"\\\\n\").filter((line) => line.trim() && !line.includes(\"codemode-prelude.js\"))\n\t\t\t\t: [];\n\t\treturn [head, ...frames].join(\"\\\\n\");\n\t}\n\n\tfunction format(value) {\n\t\tif (typeof value === \"string\") return value;\n\t\tif (value instanceof ErrorCtor) return errorText(value);\n\t\ttry {\n\t\t\tconst json = stringify(value);\n\t\t\treturn json === undefined ? String(value) : json;\n\t\t} catch {\n\t\t\treturn String(value);\n\t\t}\n\t}\n\n\tfunction describeError(error) {\n\t\tif (error instanceof ErrorCtor) {\n\t\t\treturn stringify({ name: error.name, message: error.message, stack: errorText(error) });\n\t\t}\n\t\treturn stringify({ message: format(error) });\n\t}\n\n\tfunction caller(kind, name, spread) {\n\t\treturn (...args) =>\n\t\t\tnew Promise((resolve, reject) => {\n\t\t\t\tlet json;\n\t\t\t\ttry {\n\t\t\t\t\tjson = serialize(spread ? args : args[0]);\n\t\t\t\t} catch (error) {\n\t\t\t\t\treject(error);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst id = nextId++;\n\t\t\t\tpending.set(id, { resolve, reject });\n\t\t\t\tbridge(kind, id, name, json);\n\t\t\t});\n\t}\n\n\tconst tools = Object.create(null);\n\tconst allTools = [];\n\tfor (const { name, jsName, description } of parse(toolsJson)) {\n\t\tconst fn = caller(\"call\", name);\n\t\t// The first tool wins when two names normalize to the same identifier.\n\t\tif (!(jsName in tools)) {\n\t\t\ttools[jsName] = fn;\n\t\t\tallTools.push(Object.freeze({ name: jsName, description }));\n\t\t}\n\t\tif (!(name in tools)) tools[name] = fn;\n\t}\n\tObject.freeze(tools);\n\tObject.freeze(allTools);\n\n\t// Reading a member that does not exist throws an error that names the close matches, instead of\n\t// a later \"not a function\". \\`in\\` checks still work.\n\tconst comparable = (name) => name.toLowerCase().replace(/[^a-z0-9]/g, \"\");\n\tfunction guard(target, label, names, hint) {\n\t\treturn new Proxy(target, {\n\t\t\tget(object, property, receiver) {\n\t\t\t\tif (typeof property !== \"string\" || property in object || property in Object.prototype || property === \"then\" || property === \"toJSON\") {\n\t\t\t\t\treturn Reflect.get(object, property, receiver);\n\t\t\t\t}\n\t\t\t\tconst wanted = comparable(property);\n\t\t\t\tconst exact = names.filter((name) => comparable(name) === wanted);\n\t\t\t\tconst close = exact.length > 0 ? exact : names.filter((name) => wanted && (comparable(name).includes(wanted) || wanted.includes(comparable(name))));\n\t\t\t\tlet message = label + \".\" + property + \" does not exist.\";\n\t\t\t\tif (close.length > 0) message += \" Did you mean \" + close.slice(0, 5).map((name) => label + \".\" + name).join(\", \") + \"?\";\n\t\t\t\telse if (names.length <= 20) message += \" Available: \" + names.join(\", \") + \".\";\n\t\t\t\tif (hint) message += \" \" + hint;\n\t\t\t\tmessage += ' Check for a member with \"' + property + '\" in ' + label + \".\";\n\t\t\t\tthrow new TypeErrorCtor(message);\n\t\t\t},\n\t\t});\n\t}\n\tconst toolsProxy = guard(\n\t\ttools,\n\t\t\"tools\",\n\t\tallTools.map((tool) => tool.name),\n\t\t\"ALL_TOOLS lists every tool; searchTools(query) finds tools by topic.\",\n\t);\n\n\tconst namespaces = new Map();\n\tfor (const { name, spread } of parse(globalsJson)) {\n\t\tconst fn = caller(\"global\", name, spread);\n\t\tconst dot = name.indexOf(\".\");\n\t\tif (dot === -1) {\n\t\t\tObject.defineProperty(globalThis, name, { value: fn, enumerable: true });\n\t\t\tcontinue;\n\t\t}\n\t\tconst namespace = name.slice(0, dot);\n\t\tif (!namespaces.has(namespace)) namespaces.set(namespace, Object.create(null));\n\t\tnamespaces.get(namespace)[name.slice(dot + 1)] = fn;\n\t}\n\tfor (const [namespace, members] of namespaces) {\n\t\tObject.freeze(members);\n\t\tconst value = guard(members, namespace, Object.keys(members));\n\t\tObject.defineProperty(globalThis, namespace, { value, enumerable: true });\n\t}\n\n\t// key -> JSON text. Sizes count key and JSON characters.\n\tconst stored = new Map(Object.entries(parse(storeJson)));\n\tconst writes = new Map();\n\tlet storedChars = 0;\n\tfor (const [key, json] of stored) storedChars += key.length + json.length;\n\n\tconst STORE_HINT =\n\t\t\"store() is for small state such as IDs or summaries. Show images with image(), keep large data in variables, or write it to a file with a tool.\";\n\n\tfunction checkKey(name, key) {\n\t\tif (typeof key !== \"string\") throw new TypeError(name + \"() key must be a string\");\n\t}\n\n\tfunction store(key, value) {\n\t\tcheckKey(\"store\", key);\n\t\tconst previous = stored.has(key) ? key.length + stored.get(key).length : 0;\n\t\tif (value === undefined) {\n\t\t\tstored.delete(key);\n\t\t\tstoredChars -= previous;\n\t\t\twrites.set(key, undefined);\n\t\t\treturn;\n\t\t}\n\t\tlet json;\n\t\ttry {\n\t\t\tjson = stringify(value);\n\t\t} catch (error) {\n\t\t\tthrow new TypeError(\"store(\" + stringify(key) + \") value is not JSON-serializable: \" + format(error));\n\t\t}\n\t\tif (json === undefined) {\n\t\t\tthrow new TypeError(\"store(\" + stringify(key) + \") value is not JSON-serializable\");\n\t\t}\n\t\tif (json.length > ${MAX_STORE_VALUE_CHARS}) {\n\t\t\tthrow new RangeError(\n\t\t\t\t\"store(\" + stringify(key) + \") value has \" + json.length + \" characters of JSON, more than the limit of ${MAX_STORE_VALUE_CHARS}. \" +\n\t\t\t\t\tSTORE_HINT,\n\t\t\t);\n\t\t}\n\t\tconst next = storedChars - previous + key.length + json.length;\n\t\tif (next > ${MAX_STORE_TOTAL_CHARS}) {\n\t\t\tthrow new RangeError(\n\t\t\t\t\"store is full: stored values would exceed ${MAX_STORE_TOTAL_CHARS} characters of JSON. Delete keys with store(key, undefined). \" +\n\t\t\t\t\tSTORE_HINT,\n\t\t\t);\n\t\t}\n\t\tstored.set(key, json);\n\t\tstoredChars = next;\n\t\twrites.set(key, json);\n\t}\n\n\tfunction load(key) {\n\t\tcheckKey(\"load\", key);\n\t\tconst json = stored.get(key);\n\t\treturn json === undefined ? undefined : parse(json);\n\t}\n\n\tfunction serializeWrites() {\n\t\tconst entries = [];\n\t\tfor (const [key, json] of writes) entries.push(json === undefined ? [key] : [key, json]);\n\t\treturn stringify(entries);\n\t}\n\n\tObject.defineProperty(globalThis, \"store\", { value: store, enumerable: true });\n\tObject.defineProperty(globalThis, \"load\", { value: load, enumerable: true });\n\n\t// Primitives become their string form, everything else JSON.\n\tfunction outputText(value) {\n\t\tif (value === undefined || value === null || typeof value !== \"object\" && typeof value !== \"function\") {\n\t\t\treturn String(value);\n\t\t}\n\t\tconst json = stringify(value);\n\t\treturn json === undefined ? String(value) : json;\n\t}\n\n\tfunction text(value) {\n\t\tlet rendered;\n\t\ttry {\n\t\t\trendered = outputText(value);\n\t\t} catch (error) {\n\t\t\tthrow new TypeErrorCtor(error instanceof ErrorCtor ? error.message : String(error));\n\t\t}\n\t\tif (!finished) bridge(\"output\", \"text\", rendered);\n\t}\n\n\tfunction imageUrl(value) {\n\t\tif (typeof value === \"string\") return value;\n\t\tif (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n\t\t\tthrow new TypeErrorCtor(${JSON.stringify(IMAGE_HELPER_EXPECTS)});\n\t\t}\n\t\tif (value.image_url !== undefined) {\n\t\t\tif (typeof value.image_url !== \"string\") throw new TypeErrorCtor(${JSON.stringify(IMAGE_HELPER_EXPECTS)});\n\t\t\treturn value.image_url;\n\t\t}\n\t\tif (typeof value.type !== \"string\") throw new TypeErrorCtor(${JSON.stringify(IMAGE_HELPER_EXPECTS)});\n\t\tif (value.type !== \"image\") {\n\t\t\tthrow new TypeErrorCtor('image only accepts MCP image blocks, got \"' + value.type + '\"');\n\t\t}\n\t\tif (typeof value.data !== \"string\" || value.data === \"\") throw new TypeErrorCtor(\"image expected MCP image data\");\n\t\tif (value.data.toLowerCase().startsWith(\"data:\")) return value.data;\n\t\treturn \"data:;base64,\" + value.data;\n\t}\n\n\t// Base64 of the signatures of the formats providers accept inline (PNG, JPEG except\n\t// JPEG-LS, GIF, \"RIFF....WEBP\"). Signatures start at byte 0, so their encodings are prefixes.\n\tconst IMAGE_SIGNATURES = [\n\t\t[\"image/png\", /^iVBORw0KGg/],\n\t\t[\"image/jpeg\", /^[/]9j[/](?!9)/],\n\t\t[\"image/gif\", /^R0lGOD[dl]h/],\n\t\t[\"image/webp\", /^UklG.{8}RUJQ/],\n\t];\n\n\tfunction image(value) {\n\t\tconst url = imageUrl(value);\n\t\tif (url === \"\") throw new TypeErrorCtor(${JSON.stringify(IMAGE_HELPER_EXPECTS)});\n\t\tconst colon = url.indexOf(\":\");\n\t\tconst scheme = colon === -1 ? \"\" : url.slice(0, colon).toLowerCase();\n\t\tif (scheme === \"http\" || scheme === \"https\") {\n\t\t\tthrow new TypeErrorCtor(\"remote image URLs are not supported in tool outputs. Pass a base64 data URI instead\");\n\t\t}\n\t\tconst comma = url.indexOf(\",\");\n\t\tconst header = comma === -1 ? [] : url.slice(colon + 1, comma).split(\";\");\n\t\tif (scheme !== \"data\" || comma === -1 || header.slice(1).every((part) => part.toLowerCase() !== \"base64\")) {\n\t\t\tthrow new TypeErrorCtor(\"invalid image output. Pass a base64 data URI instead\");\n\t\t}\n\t\t// Providers reject the whole request on a bad image, and a persisted image block would be\n\t\t// resent on every later turn. Line breaks from wrapped base64 are dropped. The declared type\n\t\t// is ignored in favor of the detected one, as providers also reject mismatches.\n\t\tconst data = url.slice(comma + 1).replace(/\\\\s+/g, \"\");\n\t\tif (data.length % 4 !== 0 || !/^[A-Za-z0-9+/]+={0,2}$/.test(data)) {\n\t\t\tthrow new TypeErrorCtor(\"invalid image output. The image data is not valid base64 (truncated or corrupted?)\");\n\t\t}\n\t\tconst head = data.slice(0, 16);\n\t\tconst signature = IMAGE_SIGNATURES.find(([, pattern]) => pattern.test(head));\n\t\tif (!signature) {\n\t\t\tthrow new TypeErrorCtor(\"invalid image output. The image data is not a PNG, JPEG, GIF, or WebP image\");\n\t\t}\n\t\tif (!finished) bridge(\"output\", \"image\", data, signature[0]);\n\t}\n\n\tfunction exit() {\n\t\tlet writesJson;\n\t\ttry {\n\t\t\twritesJson = serializeWrites();\n\t\t} catch (error) {\n\t\t\tdone(false, describeError(error));\n\t\t\tthrow EXIT;\n\t\t}\n\t\tdone(true, undefined, writesJson);\n\t\tthrow EXIT;\n\t}\n\n\tconst console = {};\n\tfor (const level of [\"log\", \"info\", \"warn\", \"error\", \"debug\"]) {\n\t\tconsole[level] = (...args) => {\n\t\t\tif (!finished) bridge(\"output\", \"text\", args.map(format).join(\" \"));\n\t\t};\n\t}\n\tObject.freeze(console);\n\n\tObject.defineProperty(globalThis, \"tools\", { value: toolsProxy, enumerable: true });\n\tObject.defineProperty(globalThis, \"ALL_TOOLS\", { value: allTools, enumerable: true });\n\tObject.defineProperty(globalThis, \"console\", { value: console, enumerable: true });\n\tObject.defineProperty(globalThis, \"text\", { value: text, enumerable: true });\n\tObject.defineProperty(globalThis, \"image\", { value: image, enumerable: true });\n\tObject.defineProperty(globalThis, \"exit\", { value: exit, enumerable: true });\n\n\treturn {\n\t\tsettle(id, ok, payload) {\n\t\t\tconst entry = pending.get(id);\n\t\t\tif (!entry) return;\n\t\t\tpending.delete(id);\n\t\t\tif (!ok) {\n\t\t\t\tentry.reject(new ErrorCtor(payload));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tlet value;\n\t\t\ttry {\n\t\t\t\tvalue = payload === undefined ? undefined : parse(payload);\n\t\t\t} catch (error) {\n\t\t\t\tentry.reject(error);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tentry.resolve(value);\n\t\t},\n\t\trun(fn) {\n\t\t\tlet promise;\n\t\t\ttry {\n\t\t\t\tpromise = fn(toolsProxy, console);\n\t\t\t} catch (error) {\n\t\t\t\tdone(false, describeError(error));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tpromiseThen.call(\n\t\t\t\tpromise,\n\t\t\t\t(value) => {\n\t\t\t\t\tlet json;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tjson = serialize(value);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tdone(false, describeError(error));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tdone(true, json, serializeWrites());\n\t\t\t\t},\n\t\t\t\t(error) => {\n\t\t\t\t\tdone(false, describeError(error));\n\t\t\t\t},\n\t\t\t);\n\t\t},\n\t\tstalled() {\n\t\t\tif (finished || pending.size > 0) return false;\n\t\t\tdone(\n\t\t\t\tfalse,\n\t\t\t\tstringify({\n\t\t\t\t\tname: \"Error\",\n\t\t\t\t\tmessage:\n\t\t\t\t\t\t\"The script is waiting on a promise that can never settle: no tool call is pending, and timers do not exist here.\",\n\t\t\t\t}),\n\t\t\t);\n\t\t\treturn true;\n\t\t},\n\t};\n})`;\n"]}
|
package/dist/runtime/worker.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* Importing this module starts the worker. Hosts that bundle their code (for
|
|
9
9
|
* example a Bun compiled executable) add a file that imports
|
|
10
10
|
* `@earendil-works/pi-codemode/worker` as a separate entrypoint and pass its URL
|
|
11
|
-
* as `workerUrl`.
|
|
11
|
+
* or embedded-module string specifier as `workerUrl`.
|
|
12
12
|
*/
|
|
13
13
|
import { parentPort, workerData } from "node:worker_threads";
|
|
14
14
|
import { JSException, MAX_STACK_SIZE, QuickJS } from "quickjs-wasi";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker.js","sourceRoot":"","sources":["../../src/runtime/worker.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Worker thread entry. One worker runs one script inside a fresh QuickJS VM\n * (a separate wasm instance), relays tool calls and output to the host, and\n * reports the result. The host terminates the worker when the script settles,\n * times out, or is aborted; the worker exists so that a spinning script never\n * blocks the host thread.\n *\n * Importing this module starts the worker. Hosts that bundle their code (for\n * example a Bun compiled executable) add a file that imports\n * `@earendil-works/pi-codemode/worker` as a separate entrypoint and pass its URL\n * as `workerUrl`.\n */\nimport { parentPort, workerData } from \"node:worker_threads\";\nimport { JSException, type JSValueHandle, MAX_STACK_SIZE, QuickJS } from \"quickjs-wasi\";\nimport { PRELUDE_SOURCE } from \"./prelude-source.ts\";\nimport { isHostToWorkerMessage, type WorkerData, type WorkerToHostMessage } from \"./protocol.ts\";\n\nfunction post(message: WorkerToHostMessage): void {\n\tparentPort?.postMessage(message);\n}\n\nfunction crash(error: unknown): void {\n\tpost({ type: \"crash\", message: error instanceof Error ? `${error.name}: ${error.message}` : String(error) });\n}\n\n/**\n * QuickJS writes engine diagnostics to fd 1 and 2, which the default shim\n * forwards to the host's stdout and stderr. That output belongs to the host\n * application (for example a TUI), so it is discarded. Reporting every byte as\n * written keeps libc from retrying.\n */\nfunction discardOutput(memory: { readonly buffer: ArrayBufferLike }) {\n\treturn {\n\t\tfd_write(_fd: number, iovsPtr: number, iovsLen: number, nwrittenPtr: number): number {\n\t\t\tconst view = new DataView(memory.buffer);\n\t\t\tlet written = 0;\n\t\t\tfor (let i = 0; i < iovsLen; i++) {\n\t\t\t\twritten += view.getUint32(iovsPtr + i * 8 + 4, true);\n\t\t\t}\n\t\t\tview.setUint32(nwrittenPtr, written, true);\n\t\t\treturn 0;\n\t\t},\n\t};\n}\n\nfunction describeException(error: JSException): string {\n\tconst head = error.message ? `${error.name}: ${error.message}` : error.name;\n\tconst stack = error.stack?.trimEnd();\n\treturn JSON.stringify({ name: error.name, message: error.message, stack: stack ? `${head}\\n${stack}` : head });\n}\n\nasync function main(data: WorkerData): Promise<void> {\n\tconst interrupt = new Int32Array(data.interrupt);\n\tconst vm = await QuickJS.create({\n\t\twasm: data.wasm,\n\t\tmemoryLimit: data.memoryLimitBytes,\n\t\t// Without a guard, deep recursion overflows the wasm stack and traps instead of throwing a\n\t\t// catchable RangeError.\n\t\tmaxStackSize: MAX_STACK_SIZE,\n\t\tinterruptHandler: () => Atomics.load(interrupt, 0) !== 0,\n\t\twasi: discardOutput,\n\t});\n\n\t// Called from the prelude with primitives only.\n\tconst bridge = vm.newFunction(\"bridge\", (kind, a, b, c) => {\n\t\tswitch (kind.toString()) {\n\t\t\tcase \"call\":\n\t\t\tcase \"global\":\n\t\t\t\tpost({\n\t\t\t\t\ttype: \"call\",\n\t\t\t\t\tid: a.toNumber(),\n\t\t\t\t\ttarget: kind.toString() === \"call\" ? \"tool\" : \"global\",\n\t\t\t\t\tname: b.toString(),\n\t\t\t\t\targs: c === undefined || c.isUndefined ? undefined : c.toString(),\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tcase \"output\":\n\t\t\t\tpost({\n\t\t\t\t\ttype: \"output\",\n\t\t\t\t\titem:\n\t\t\t\t\t\ta.toString() === \"image\"\n\t\t\t\t\t\t\t? { type: \"image\", data: b.toString(), mimeType: c.toString() }\n\t\t\t\t\t\t\t: { type: \"text\", text: b.toString() },\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tcase \"done\":\n\t\t\t\tif (a.toBoolean()) {\n\t\t\t\t\tpost({\n\t\t\t\t\t\ttype: \"done\",\n\t\t\t\t\t\tok: true,\n\t\t\t\t\t\tvalue: b === undefined || b.isUndefined ? undefined : b.toString(),\n\t\t\t\t\t\twrites: c.toString(),\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tpost({ type: \"done\", ok: false, error: b.toString() });\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t\treturn vm.undefined;\n\t});\n\n\t// The VM lives until the host terminates the worker, so these handles are never disposed.\n\tconst api = vm.withScope((scope) =>\n\t\tscope.escape(\n\t\t\tvm.callFunction(\n\t\t\t\tvm.evalCode(PRELUDE_SOURCE, \"codemode-prelude.js\"),\n\t\t\t\tvm.undefined,\n\t\t\t\tbridge,\n\t\t\t\tvm.newString(JSON.stringify(data.tools)),\n\t\t\t\tvm.newString(JSON.stringify(data.globals)),\n\t\t\t\tvm.newString(JSON.stringify(data.store)),\n\t\t\t),\n\t\t),\n\t);\n\tconst settle = api.getProp(\"settle\");\n\tconst run = api.getProp(\"run\");\n\tconst stalled = api.getProp(\"stalled\");\n\t/** Run queued jobs, then fail a script that waits on nothing that can ever resume it. */\n\tconst drain = () => {\n\t\tvm.executePendingJobs();\n\t\tvm.callFunction(stalled, api).dispose();\n\t};\n\n\tparentPort?.on(\"message\", (message: unknown) => {\n\t\tif (!isHostToWorkerMessage(message)) return;\n\t\ttry {\n\t\t\tvm.withScope(() => {\n\t\t\t\tvm.callFunction(\n\t\t\t\t\tsettle,\n\t\t\t\t\tapi,\n\t\t\t\t\tvm.newNumber(message.id),\n\t\t\t\t\tmessage.ok ? vm.true : vm.false,\n\t\t\t\t\tmessage.payload === undefined ? vm.undefined : vm.newString(message.payload),\n\t\t\t\t);\n\t\t\t});\n\t\t\tdrain();\n\t\t} catch (error) {\n\t\t\tcrash(error);\n\t\t}\n\t});\n\n\t// The prefix shares the first line with the script so reported line numbers\n\t// match the script as written.\n\tlet fn: JSValueHandle;\n\ttry {\n\t\tfn = vm.evalCode(`(async (tools, console) => {${data.code}\\n})`, \"codemode.js\");\n\t} catch (error) {\n\t\tif (!(error instanceof JSException)) throw error;\n\t\tpost({ type: \"done\", ok: false, error: describeException(error) });\n\t\treturn;\n\t}\n\tvm.callFunction(run, api, fn).dispose();\n\tfn.dispose();\n\tdrain();\n}\n\nif (parentPort) {\n\tmain(workerData as WorkerData).catch(crash);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"worker.js","sourceRoot":"","sources":["../../src/runtime/worker.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Worker thread entry. One worker runs one script inside a fresh QuickJS VM\n * (a separate wasm instance), relays tool calls and output to the host, and\n * reports the result. The host terminates the worker when the script settles,\n * times out, or is aborted; the worker exists so that a spinning script never\n * blocks the host thread.\n *\n * Importing this module starts the worker. Hosts that bundle their code (for\n * example a Bun compiled executable) add a file that imports\n * `@earendil-works/pi-codemode/worker` as a separate entrypoint and pass its URL\n * or embedded-module string specifier as `workerUrl`.\n */\nimport { parentPort, workerData } from \"node:worker_threads\";\nimport { JSException, type JSValueHandle, MAX_STACK_SIZE, QuickJS } from \"quickjs-wasi\";\nimport { PRELUDE_SOURCE } from \"./prelude-source.ts\";\nimport { isHostToWorkerMessage, type WorkerData, type WorkerToHostMessage } from \"./protocol.ts\";\n\nfunction post(message: WorkerToHostMessage): void {\n\tparentPort?.postMessage(message);\n}\n\nfunction crash(error: unknown): void {\n\tpost({ type: \"crash\", message: error instanceof Error ? `${error.name}: ${error.message}` : String(error) });\n}\n\n/**\n * QuickJS writes engine diagnostics to fd 1 and 2, which the default shim\n * forwards to the host's stdout and stderr. That output belongs to the host\n * application (for example a TUI), so it is discarded. Reporting every byte as\n * written keeps libc from retrying.\n */\nfunction discardOutput(memory: { readonly buffer: ArrayBufferLike }) {\n\treturn {\n\t\tfd_write(_fd: number, iovsPtr: number, iovsLen: number, nwrittenPtr: number): number {\n\t\t\tconst view = new DataView(memory.buffer);\n\t\t\tlet written = 0;\n\t\t\tfor (let i = 0; i < iovsLen; i++) {\n\t\t\t\twritten += view.getUint32(iovsPtr + i * 8 + 4, true);\n\t\t\t}\n\t\t\tview.setUint32(nwrittenPtr, written, true);\n\t\t\treturn 0;\n\t\t},\n\t};\n}\n\nfunction describeException(error: JSException): string {\n\tconst head = error.message ? `${error.name}: ${error.message}` : error.name;\n\tconst stack = error.stack?.trimEnd();\n\treturn JSON.stringify({ name: error.name, message: error.message, stack: stack ? `${head}\\n${stack}` : head });\n}\n\nasync function main(data: WorkerData): Promise<void> {\n\tconst interrupt = new Int32Array(data.interrupt);\n\tconst vm = await QuickJS.create({\n\t\twasm: data.wasm,\n\t\tmemoryLimit: data.memoryLimitBytes,\n\t\t// Without a guard, deep recursion overflows the wasm stack and traps instead of throwing a\n\t\t// catchable RangeError.\n\t\tmaxStackSize: MAX_STACK_SIZE,\n\t\tinterruptHandler: () => Atomics.load(interrupt, 0) !== 0,\n\t\twasi: discardOutput,\n\t});\n\n\t// Called from the prelude with primitives only.\n\tconst bridge = vm.newFunction(\"bridge\", (kind, a, b, c) => {\n\t\tswitch (kind.toString()) {\n\t\t\tcase \"call\":\n\t\t\tcase \"global\":\n\t\t\t\tpost({\n\t\t\t\t\ttype: \"call\",\n\t\t\t\t\tid: a.toNumber(),\n\t\t\t\t\ttarget: kind.toString() === \"call\" ? \"tool\" : \"global\",\n\t\t\t\t\tname: b.toString(),\n\t\t\t\t\targs: c === undefined || c.isUndefined ? undefined : c.toString(),\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tcase \"output\":\n\t\t\t\tpost({\n\t\t\t\t\ttype: \"output\",\n\t\t\t\t\titem:\n\t\t\t\t\t\ta.toString() === \"image\"\n\t\t\t\t\t\t\t? { type: \"image\", data: b.toString(), mimeType: c.toString() }\n\t\t\t\t\t\t\t: { type: \"text\", text: b.toString() },\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tcase \"done\":\n\t\t\t\tif (a.toBoolean()) {\n\t\t\t\t\tpost({\n\t\t\t\t\t\ttype: \"done\",\n\t\t\t\t\t\tok: true,\n\t\t\t\t\t\tvalue: b === undefined || b.isUndefined ? undefined : b.toString(),\n\t\t\t\t\t\twrites: c.toString(),\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tpost({ type: \"done\", ok: false, error: b.toString() });\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t\treturn vm.undefined;\n\t});\n\n\t// The VM lives until the host terminates the worker, so these handles are never disposed.\n\tconst api = vm.withScope((scope) =>\n\t\tscope.escape(\n\t\t\tvm.callFunction(\n\t\t\t\tvm.evalCode(PRELUDE_SOURCE, \"codemode-prelude.js\"),\n\t\t\t\tvm.undefined,\n\t\t\t\tbridge,\n\t\t\t\tvm.newString(JSON.stringify(data.tools)),\n\t\t\t\tvm.newString(JSON.stringify(data.globals)),\n\t\t\t\tvm.newString(JSON.stringify(data.store)),\n\t\t\t),\n\t\t),\n\t);\n\tconst settle = api.getProp(\"settle\");\n\tconst run = api.getProp(\"run\");\n\tconst stalled = api.getProp(\"stalled\");\n\t/** Run queued jobs, then fail a script that waits on nothing that can ever resume it. */\n\tconst drain = () => {\n\t\tvm.executePendingJobs();\n\t\tvm.callFunction(stalled, api).dispose();\n\t};\n\n\tparentPort?.on(\"message\", (message: unknown) => {\n\t\tif (!isHostToWorkerMessage(message)) return;\n\t\ttry {\n\t\t\tvm.withScope(() => {\n\t\t\t\tvm.callFunction(\n\t\t\t\t\tsettle,\n\t\t\t\t\tapi,\n\t\t\t\t\tvm.newNumber(message.id),\n\t\t\t\t\tmessage.ok ? vm.true : vm.false,\n\t\t\t\t\tmessage.payload === undefined ? vm.undefined : vm.newString(message.payload),\n\t\t\t\t);\n\t\t\t});\n\t\t\tdrain();\n\t\t} catch (error) {\n\t\t\tcrash(error);\n\t\t}\n\t});\n\n\t// The prefix shares the first line with the script so reported line numbers\n\t// match the script as written.\n\tlet fn: JSValueHandle;\n\ttry {\n\t\tfn = vm.evalCode(`(async (tools, console) => {${data.code}\\n})`, \"codemode.js\");\n\t} catch (error) {\n\t\tif (!(error instanceof JSException)) throw error;\n\t\tpost({ type: \"done\", ok: false, error: describeException(error) });\n\t\treturn;\n\t}\n\tvm.callFunction(run, api, fn).dispose();\n\tfn.dispose();\n\tdrain();\n}\n\nif (parentPort) {\n\tmain(workerData as WorkerData).catch(crash);\n}\n"]}
|
package/dist/types.d.ts
CHANGED
|
@@ -119,9 +119,10 @@ export interface CodemodeSandboxOptions {
|
|
|
119
119
|
/**
|
|
120
120
|
* Worker entry that imports `@earendil-works/pi-codemode/worker`. Default: this package's own
|
|
121
121
|
* worker file. Pass it when this package is bundled, since the default is resolved relative to
|
|
122
|
-
* the module that creates the sandbox.
|
|
122
|
+
* the module that creates the sandbox. Bun compiled executables require the relative string
|
|
123
|
+
* specifier of an embedded build entrypoint; other hosts usually use a URL.
|
|
123
124
|
*/
|
|
124
|
-
workerUrl?: URL;
|
|
125
|
+
workerUrl?: string | URL;
|
|
125
126
|
}
|
|
126
127
|
export interface CodemodeExecuteOptions {
|
|
127
128
|
signal?: AbortSignal;
|
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,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAEpD,MAAM,WAAW,mBAAmB;IACnC;;;OAGG;IACH,MAAM,EAAE,WAAW,CAAC;CACpB;AAED,qGAAqG;AACrG,MAAM,MAAM,kBAAkB,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC;AAEtE,MAAM,WAAW,YAAY;IAC5B;;;;;OAKG;IACH,IAAI,EAAE,MAAM,CAAC;IACb,iGAAiG;IACjG,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6FAA6F;IAC7F,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,0FAA0F;IAC1F,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAClC,gGAAgG;IAChG,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;CACjF;AAED;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpH,MAAM,MAAM,kBAAkB,GAAG,IAAI,GAAG,OAAO,GAAG,WAAW,CAAC;AAE9D,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,kBAAkB,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,iBAAiB;AAC5B,4FAA4F;AAC1F,QAAQ;AACV,+DAA+D;GAC7D,SAAS;AACX,sFAAsF;GACpF,SAAS;AACX,+GAA+G;GAC7G,SAAS,CAAC;AAEb,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,iBAAiB,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wFAAwF;AACxF,MAAM,WAAW,mBAAmB;IACnC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,kCAAkC;IAClC,MAAM,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,iHAAiH;AACjH,MAAM,MAAM,cAAc,GACvB;IACA,EAAE,EAAE,IAAI,CAAC;IACT,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,WAAW,EAAE,mBAAmB,CAAC;CAChC,GACD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAAC,KAAK,EAAE,YAAY,EAAE,CAAA;CAAE,CAAC;AAE5F,MAAM,WAAW,sBAAsB;IACtC,KAAK,CAAC,EAAE,YAAY,EAAE,CAAC;IACvB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,IAAI,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACxD
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAEpD,MAAM,WAAW,mBAAmB;IACnC;;;OAGG;IACH,MAAM,EAAE,WAAW,CAAC;CACpB;AAED,qGAAqG;AACrG,MAAM,MAAM,kBAAkB,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC;AAEtE,MAAM,WAAW,YAAY;IAC5B;;;;;OAKG;IACH,IAAI,EAAE,MAAM,CAAC;IACb,iGAAiG;IACjG,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6FAA6F;IAC7F,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,0FAA0F;IAC1F,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAClC,gGAAgG;IAChG,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;CACjF;AAED;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpH,MAAM,MAAM,kBAAkB,GAAG,IAAI,GAAG,OAAO,GAAG,WAAW,CAAC;AAE9D,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,kBAAkB,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,iBAAiB;AAC5B,4FAA4F;AAC1F,QAAQ;AACV,+DAA+D;GAC7D,SAAS;AACX,sFAAsF;GACpF,SAAS;AACX,+GAA+G;GAC7G,SAAS,CAAC;AAEb,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,iBAAiB,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wFAAwF;AACxF,MAAM,WAAW,mBAAmB;IACnC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,kCAAkC;IAClC,MAAM,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,iHAAiH;AACjH,MAAM,MAAM,cAAc,GACvB;IACA,EAAE,EAAE,IAAI,CAAC;IACT,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,WAAW,EAAE,mBAAmB,CAAC;CAChC,GACD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAAC,KAAK,EAAE,YAAY,EAAE,CAAA;CAAE,CAAC;AAE5F,MAAM,WAAW,sBAAsB;IACtC,KAAK,CAAC,EAAE,YAAY,EAAE,CAAC;IACvB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,IAAI,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACxD;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;CACzB;AAED,MAAM,WAAW,sBAAsB;IACtC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAC1C"}
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { CodemodeWasmModule } from \"./wasm.ts\";\n\nexport interface CodemodeToolContext {\n\t/**\n\t * Aborted when the script finishes (including unawaited calls), the\n\t * execution times out, the caller aborts, or the sandbox is closed.\n\t */\n\tsignal: AbortSignal;\n}\n\n/** A JSON Schema document. Only used to render declarations; values are not validated against it. */\nexport type CodemodeJsonSchema = { [key: string]: unknown } | boolean;\n\nexport interface CodemodeTool {\n\t/**\n\t * The script calls tools as `tools.<id>(args)`, where `<id>` is the name with characters that\n\t * are not valid in identifiers replaced by `_` (see `toCodemodeIdentifier`), and also as\n\t * `tools[\"<name>\"](args)`. Globals are called as `<name>(args)` and must be identifiers, or\n\t * `<namespace>.<member>`, which groups them into a frozen namespace object.\n\t */\n\tname: string;\n\t/** Shown as a doc comment in {@link renderDeclarations}, and listed in `ALL_TOOLS` for tools. */\n\tdescription?: string;\n\t/** Schema of the single argument. Rendered as the parameter type; `unknown` when omitted. */\n\tinputSchema?: CodemodeJsonSchema;\n\t/** Schema of the resolved value. Rendered as the promise type; `unknown` when omitted. */\n\toutputSchema?: CodemodeJsonSchema;\n\t/** Globals only: `execute` receives all call arguments as an array instead of the first one. */\n\tspread?: boolean;\n\t/**\n\t * Globals only: TypeScript parameter list and return type for {@link renderDeclarations}, for\n\t * example `(type: string, id?: string): Promise<Model[]>`. Replaces the rendering from the schemas.\n\t */\n\tsignature?: string;\n\t/**\n\t * `args` is whatever the script passed, after a JSON round trip. The return\n\t * value must be JSON-serializable; a thrown error surfaces in the script as\n\t * an `Error` with the same message.\n\t */\n\texecute(args: unknown, context: CodemodeToolContext): Promise<unknown> | unknown;\n}\n\n/**\n * One item of the script's output, in the order the script produced it: `text()` and `console.*`\n * produce text items, `image()` image items. `data` is base64.\n */\nexport type CodemodeOutputItem = { type: \"text\"; text: string } | { type: \"image\"; data: string; mimeType: string };\n\nexport type CodemodeCallStatus = \"ok\" | \"error\" | \"cancelled\";\n\nexport interface CodemodeCall {\n\tname: string;\n\tstatus: CodemodeCallStatus;\n\tdurationMs: number;\n}\n\nexport type CodemodeErrorKind =\n\t/** The script threw or failed to parse. `name` and `stack` come from the script's error. */\n\t| \"script\"\n\t/** The overall deadline expired. The worker was terminated. */\n\t| \"timeout\"\n\t/** The caller's signal fired or the sandbox was closed. The worker was terminated. */\n\t| \"aborted\"\n\t/** The worker or VM failed outside the script's control (for example a wasm trap or a missing worker file). */\n\t| \"sandbox\";\n\nexport interface CodemodeError {\n\tkind: CodemodeErrorKind;\n\tname?: string;\n\tmessage: string;\n\tstack?: string;\n}\n\n/** Keys the script changed with `store()`. Only successful executions report writes. */\nexport interface CodemodeStoreWrites {\n\tset: Record<string, unknown>;\n\t/** Keys stored as `undefined`. */\n\tdelete: string[];\n}\n\n/** `output` is kept for failed executions too, up to the failure. `exit()` completes with `value: undefined`. */\nexport type CodemodeResult =\n\t| {\n\t\t\tok: true;\n\t\t\tvalue: unknown;\n\t\t\toutput: CodemodeOutputItem[];\n\t\t\tcalls: CodemodeCall[];\n\t\t\tstoreWrites: CodemodeStoreWrites;\n\t }\n\t| { ok: false; error: CodemodeError; output: CodemodeOutputItem[]; calls: CodemodeCall[] };\n\nexport interface CodemodeSandboxOptions {\n\ttools?: CodemodeTool[];\n\t/**\n\t * Functions exposed as top-level identifiers instead of on `tools`, for host helpers such as\n\t * attaching an image to the result. They behave like tools (JSON round trip, promise result)\n\t * but are not recorded in `result.calls`. Names must be identifiers and may not shadow the\n\t * built-in globals (`tools`, `ALL_TOOLS`, `console`, `text`, `image`, `exit`, `store`, `load`).\n\t */\n\tglobals?: CodemodeTool[];\n\t/**\n\t * Overall deadline per execution, including time spent in tools. `Infinity` disables the\n\t * deadline; the execution then only ends when the script settles or is aborted.\n\t * Default: 300000.\n\t */\n\ttimeoutMs?: number;\n\t/**\n\t * Maximum memory the QuickJS VM may allocate. Allocations beyond it fail inside the script as\n\t * `InternalError: out of memory`. Default: no limit beyond wasm32's 4 GiB address space.\n\t */\n\tmemoryLimitBytes?: number;\n\t/**\n\t * Compiled `quickjs-wasi/quickjs.wasm`, usually from {@link loadQuickJSWasm}. Default:\n\t * `loadQuickJSWasm()`, the file in the installed `quickjs-wasi` package. Pass it when that file\n\t * is not on disk, for example in a Bun compiled executable.\n\t */\n\twasm?: CodemodeWasmModule | Promise<CodemodeWasmModule>;\n\t/**\n\t * Worker entry that imports `@earendil-works/pi-codemode/worker`. Default: this package's own\n\t * worker file. Pass it when this package is bundled, since the default is resolved relative to\n\t * the module that creates the sandbox.\n\t */\n\tworkerUrl?: URL;\n}\n\nexport interface CodemodeExecuteOptions {\n\tsignal?: AbortSignal;\n\t/** Overrides the sandbox default for this execution. */\n\ttimeoutMs?: number;\n\t/**\n\t * Values the script reads with `load(key)`. Must be JSON-serializable. The script's own\n\t * `store()` calls come back as `result.storeWrites`; persisting them is up to the caller.\n\t */\n\tstore?: Readonly<Record<string, unknown>>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { CodemodeWasmModule } from \"./wasm.ts\";\n\nexport interface CodemodeToolContext {\n\t/**\n\t * Aborted when the script finishes (including unawaited calls), the\n\t * execution times out, the caller aborts, or the sandbox is closed.\n\t */\n\tsignal: AbortSignal;\n}\n\n/** A JSON Schema document. Only used to render declarations; values are not validated against it. */\nexport type CodemodeJsonSchema = { [key: string]: unknown } | boolean;\n\nexport interface CodemodeTool {\n\t/**\n\t * The script calls tools as `tools.<id>(args)`, where `<id>` is the name with characters that\n\t * are not valid in identifiers replaced by `_` (see `toCodemodeIdentifier`), and also as\n\t * `tools[\"<name>\"](args)`. Globals are called as `<name>(args)` and must be identifiers, or\n\t * `<namespace>.<member>`, which groups them into a frozen namespace object.\n\t */\n\tname: string;\n\t/** Shown as a doc comment in {@link renderDeclarations}, and listed in `ALL_TOOLS` for tools. */\n\tdescription?: string;\n\t/** Schema of the single argument. Rendered as the parameter type; `unknown` when omitted. */\n\tinputSchema?: CodemodeJsonSchema;\n\t/** Schema of the resolved value. Rendered as the promise type; `unknown` when omitted. */\n\toutputSchema?: CodemodeJsonSchema;\n\t/** Globals only: `execute` receives all call arguments as an array instead of the first one. */\n\tspread?: boolean;\n\t/**\n\t * Globals only: TypeScript parameter list and return type for {@link renderDeclarations}, for\n\t * example `(type: string, id?: string): Promise<Model[]>`. Replaces the rendering from the schemas.\n\t */\n\tsignature?: string;\n\t/**\n\t * `args` is whatever the script passed, after a JSON round trip. The return\n\t * value must be JSON-serializable; a thrown error surfaces in the script as\n\t * an `Error` with the same message.\n\t */\n\texecute(args: unknown, context: CodemodeToolContext): Promise<unknown> | unknown;\n}\n\n/**\n * One item of the script's output, in the order the script produced it: `text()` and `console.*`\n * produce text items, `image()` image items. `data` is base64.\n */\nexport type CodemodeOutputItem = { type: \"text\"; text: string } | { type: \"image\"; data: string; mimeType: string };\n\nexport type CodemodeCallStatus = \"ok\" | \"error\" | \"cancelled\";\n\nexport interface CodemodeCall {\n\tname: string;\n\tstatus: CodemodeCallStatus;\n\tdurationMs: number;\n}\n\nexport type CodemodeErrorKind =\n\t/** The script threw or failed to parse. `name` and `stack` come from the script's error. */\n\t| \"script\"\n\t/** The overall deadline expired. The worker was terminated. */\n\t| \"timeout\"\n\t/** The caller's signal fired or the sandbox was closed. The worker was terminated. */\n\t| \"aborted\"\n\t/** The worker or VM failed outside the script's control (for example a wasm trap or a missing worker file). */\n\t| \"sandbox\";\n\nexport interface CodemodeError {\n\tkind: CodemodeErrorKind;\n\tname?: string;\n\tmessage: string;\n\tstack?: string;\n}\n\n/** Keys the script changed with `store()`. Only successful executions report writes. */\nexport interface CodemodeStoreWrites {\n\tset: Record<string, unknown>;\n\t/** Keys stored as `undefined`. */\n\tdelete: string[];\n}\n\n/** `output` is kept for failed executions too, up to the failure. `exit()` completes with `value: undefined`. */\nexport type CodemodeResult =\n\t| {\n\t\t\tok: true;\n\t\t\tvalue: unknown;\n\t\t\toutput: CodemodeOutputItem[];\n\t\t\tcalls: CodemodeCall[];\n\t\t\tstoreWrites: CodemodeStoreWrites;\n\t }\n\t| { ok: false; error: CodemodeError; output: CodemodeOutputItem[]; calls: CodemodeCall[] };\n\nexport interface CodemodeSandboxOptions {\n\ttools?: CodemodeTool[];\n\t/**\n\t * Functions exposed as top-level identifiers instead of on `tools`, for host helpers such as\n\t * attaching an image to the result. They behave like tools (JSON round trip, promise result)\n\t * but are not recorded in `result.calls`. Names must be identifiers and may not shadow the\n\t * built-in globals (`tools`, `ALL_TOOLS`, `console`, `text`, `image`, `exit`, `store`, `load`).\n\t */\n\tglobals?: CodemodeTool[];\n\t/**\n\t * Overall deadline per execution, including time spent in tools. `Infinity` disables the\n\t * deadline; the execution then only ends when the script settles or is aborted.\n\t * Default: 300000.\n\t */\n\ttimeoutMs?: number;\n\t/**\n\t * Maximum memory the QuickJS VM may allocate. Allocations beyond it fail inside the script as\n\t * `InternalError: out of memory`. Default: no limit beyond wasm32's 4 GiB address space.\n\t */\n\tmemoryLimitBytes?: number;\n\t/**\n\t * Compiled `quickjs-wasi/quickjs.wasm`, usually from {@link loadQuickJSWasm}. Default:\n\t * `loadQuickJSWasm()`, the file in the installed `quickjs-wasi` package. Pass it when that file\n\t * is not on disk, for example in a Bun compiled executable.\n\t */\n\twasm?: CodemodeWasmModule | Promise<CodemodeWasmModule>;\n\t/**\n\t * Worker entry that imports `@earendil-works/pi-codemode/worker`. Default: this package's own\n\t * worker file. Pass it when this package is bundled, since the default is resolved relative to\n\t * the module that creates the sandbox. Bun compiled executables require the relative string\n\t * specifier of an embedded build entrypoint; other hosts usually use a URL.\n\t */\n\tworkerUrl?: string | URL;\n}\n\nexport interface CodemodeExecuteOptions {\n\tsignal?: AbortSignal;\n\t/** Overrides the sandbox default for this execution. */\n\ttimeoutMs?: number;\n\t/**\n\t * Values the script reads with `load(key)`. Must be JSON-serializable. The script's own\n\t * `store()` calls come back as `result.storeWrites`; persisting them is up to the caller.\n\t */\n\tstore?: Readonly<Record<string, unknown>>;\n}\n"]}
|
package/package.json
CHANGED