@absolutejs/ai 0.0.10 → 0.0.12

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.
@@ -5,7 +5,7 @@
5
5
  "import type {\n AIChunk,\n AIProviderConfig,\n AIProviderStreamParams,\n AIUsage,\n} from \"../../../types/ai\";\n\nexport const instrumentAIProvider = (\n provider: AIProviderConfig,\n providerName?: string,\n): AIProviderConfig => ({\n stream: (params: AIProviderStreamParams) => {\n if (!params.onUsage && !params.onSpan) {\n return provider.stream(params);\n }\n return tapStream(provider.stream(params), params, providerName);\n },\n});\n\nasync function* tapStream(\n source: AsyncIterable<AIChunk>,\n params: AIProviderStreamParams,\n providerName?: string,\n): AsyncIterable<AIChunk> {\n const startedAt = Date.now();\n let lastUsage: AIUsage | undefined;\n try {\n for await (const chunk of source) {\n if (chunk.type === \"done\" && chunk.usage) {\n lastUsage = chunk.usage;\n }\n yield chunk;\n }\n } finally {\n if (lastUsage && params.onUsage) {\n try {\n params.onUsage({\n ...lastUsage,\n model: params.model,\n provider: providerName,\n });\n } catch {\n // operator-supplied callback errors must not affect stream consumers\n }\n }\n if (params.onSpan) {\n try {\n params.onSpan({\n durationMs: Date.now() - startedAt,\n model: params.model,\n provider: providerName,\n usage: lastUsage,\n });\n } catch {\n // same\n }\n }\n }\n}\n",
6
6
  "import type {\n AIProviderConfig,\n AIProviderContentBlock,\n AIProviderMessage,\n AIProviderStreamParams,\n AIProviderToolDefinition,\n AIUsage,\n} from \"../../../types/ai\";\nimport { instrumentAIProvider } from \"./instrumentation\";\n\n// Opportunistic HTTP/2 multiplexing for outbound HTTPS (Bun 1.3.14+).\n// The `protocol` option lands in @types/bun 1.3.14; widen locally for now.\n// Hard-skip on non-HTTPS — Bun's h2 client throws HTTP2Unsupported on h2c.\ntype H2Init = RequestInit & { protocol?: \"http2\" };\nconst h2IfHttps = (url: string): H2Init =>\n url.startsWith(\"https://\") ? { protocol: \"http2\" } : {};\n\ntype OpenAIResponsesConfig = {\n apiKey: string;\n baseUrl?: string;\n imageModels?: Set<string> | string[];\n};\n\ntype PendingFunctionCall = {\n callId: string;\n name: string;\n arguments: string;\n};\n\ntype StreamState = {\n buffer: string;\n currentEvent: string;\n pendingCalls: Map<string, PendingFunctionCall>;\n usage: AIUsage | undefined;\n};\n\nconst DEFAULT_BASE_URL = \"https://api.openai.com\";\nconst EVENT_PREFIX_LENGTH = 7;\nconst DATA_PREFIX_LENGTH = 6;\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null;\n\nconst isRecordArray = (\n value: unknown,\n): value is Array<Record<string, unknown>> =>\n Array.isArray(value) && value.length > 0 && isRecord(value[0]);\n\n/* ─── Message conversion ─── */\n\nconst mapBlockToResponsesFormat = (block: AIProviderContentBlock) => {\n if (block.type === \"text\") {\n return { text: block.content, type: \"input_text\" };\n }\n\n if (block.type === \"image\") {\n return {\n image_url: {\n url: `data:${block.source.media_type};base64,${block.source.data}`,\n },\n type: \"input_image\",\n };\n }\n\n if (block.type === \"document\") {\n return {\n file: {\n file_data: `data:${block.source.media_type};base64,${block.source.data}`,\n filename: block.name ?? \"document.pdf\",\n },\n type: \"input_file\",\n };\n }\n\n return null;\n};\n\nconst mapContentToResponsesFormat = (\n content: string | AIProviderContentBlock[],\n) => {\n if (typeof content === \"string\") {\n return content;\n }\n\n const parts = content\n .map(mapBlockToResponsesFormat)\n .filter((mapped) => mapped !== null);\n\n return parts.length > 0 ? parts : \"\";\n};\n\nconst hasToolBlocks = (content: AIProviderContentBlock[]) =>\n content.some(\n (block) => block.type === \"tool_use\" || block.type === \"tool_result\",\n );\n\nconst convertToolBlock = (block: AIProviderContentBlock) => {\n if (block.type === \"tool_use\") {\n return {\n arguments:\n typeof block.input === \"string\"\n ? block.input\n : JSON.stringify(block.input),\n call_id: block.id,\n name: block.name,\n type: \"function_call\",\n };\n }\n\n if (block.type === \"tool_result\") {\n return {\n call_id: block.tool_use_id,\n output: typeof block.content === \"string\" ? block.content : \"\",\n type: \"function_call_output\",\n };\n }\n\n return null;\n};\n\nconst convertToolBlocks = (content: AIProviderContentBlock[]) =>\n content.map(convertToolBlock).filter((converted) => converted !== null);\n\nconst convertMessage = (msg: AIProviderMessage) => {\n if (\n typeof msg.content !== \"string\" &&\n Array.isArray(msg.content) &&\n hasToolBlocks(msg.content)\n ) {\n return convertToolBlocks(msg.content);\n }\n\n const content = mapContentToResponsesFormat(msg.content);\n\n return [\n {\n content,\n role: msg.role === \"system\" ? \"developer\" : msg.role,\n type: \"message\",\n },\n ];\n};\n\nconst buildInput = (messages: AIProviderMessage[]) => {\n const input: Array<Record<string, unknown>> = [];\n\n for (const msg of messages) {\n input.push(...convertMessage(msg));\n }\n\n return input;\n};\n\nconst mapToolDefinition = (tool: AIProviderToolDefinition) => ({\n description: tool.description,\n name: tool.name,\n parameters: tool.input_schema,\n type: \"function\",\n});\n\nconst buildTools = (\n tools: AIProviderToolDefinition[] | undefined,\n isImageModel: boolean,\n) => {\n const mapped = tools ? tools.map(mapToolDefinition) : [];\n const result: Array<Record<string, unknown>> = [...mapped];\n\n if (isImageModel) {\n result.push({ type: \"image_generation\" });\n }\n\n return result.length > 0 ? result : undefined;\n};\n\nconst buildRequestBody = (\n params: AIProviderStreamParams,\n isImageModel: boolean,\n) => {\n const body: Record<string, unknown> = {\n input: buildInput(params.messages),\n model: params.model,\n stream: true,\n };\n\n if (params.systemPrompt) {\n body.instructions = params.systemPrompt;\n }\n\n const tools = buildTools(params.tools, isImageModel);\n\n if (tools) {\n body.tools = tools;\n if (params.toolChoice === \"auto\" || params.toolChoice === \"none\" || params.toolChoice === \"required\") {\n body.tool_choice = params.toolChoice;\n } else if (params.toolChoice && typeof params.toolChoice === \"object\") {\n body.tool_choice = {\n name: params.toolChoice.name,\n type: \"function\",\n };\n }\n if (typeof params.parallelToolCalls === \"boolean\") {\n body.parallel_tool_calls = params.parallelToolCalls;\n }\n }\n\n if (typeof params.temperature === \"number\") body.temperature = params.temperature;\n if (typeof params.topP === \"number\") body.top_p = params.topP;\n if (typeof params.maxTokens === \"number\") body.max_output_tokens = params.maxTokens;\n if (params.stopSequences && params.stopSequences.length > 0) body.stop = params.stopSequences;\n if (typeof params.seed === \"number\") body.seed = params.seed;\n if (typeof params.frequencyPenalty === \"number\") body.frequency_penalty = params.frequencyPenalty;\n if (typeof params.presencePenalty === \"number\") body.presence_penalty = params.presencePenalty;\n\n if (params.responseFormat) {\n if (params.responseFormat.type === \"text\" || params.responseFormat.type === \"json_object\") {\n body.text = { format: { type: params.responseFormat.type } };\n } else if (params.responseFormat.type === \"json_schema\") {\n body.text = {\n format: {\n name: params.responseFormat.name,\n schema: params.responseFormat.schema,\n strict: params.responseFormat.strict ?? true,\n type: \"json_schema\",\n },\n };\n }\n }\n\n // Enable reasoning summary for models that support thinking/reasoning\n if (params.thinking) {\n body.reasoning = {\n effort: \"high\",\n summary: \"auto\",\n };\n }\n\n return body;\n};\n\n/* ─── SSE parsing ─── */\n\nconst parseJSON = (data: string) => {\n try {\n return JSON.parse(data);\n } catch {\n return null;\n }\n};\n\nconst parseToolInput = (rawArguments: string) => {\n try {\n return JSON.parse(rawArguments);\n } catch {\n return rawArguments;\n }\n};\n\nconst extractUsage = (response: Record<string, unknown>) => {\n if (!isRecord(response.usage)) {\n return undefined;\n }\n\n const { usage } = response;\n\n return {\n inputTokens:\n typeof usage.input_tokens === \"number\" ? usage.input_tokens : 0,\n outputTokens:\n typeof usage.output_tokens === \"number\" ? usage.output_tokens : 0,\n };\n};\n\nconst extractMimeFormat = (mimeType: unknown) => {\n if (typeof mimeType !== \"string\") {\n return \"png\";\n }\n\n if (mimeType.includes(\"jpeg\")) return \"jpeg\";\n if (mimeType.includes(\"webp\")) return \"webp\";\n\n return \"png\";\n};\n\nconst processTextDelta = function* (parsed: Record<string, unknown>) {\n if (typeof parsed.delta === \"string\") {\n yield { content: parsed.delta, type: \"text\" as const };\n }\n};\n\nconst processPartialImage = function* (parsed: Record<string, unknown>) {\n const itemId =\n typeof parsed.item_id === \"string\" ? parsed.item_id : undefined;\n const b64 =\n typeof parsed.partial_image_b64 === \"string\"\n ? parsed.partial_image_b64\n : undefined;\n\n if (b64) {\n yield {\n data: b64,\n format: \"png\",\n imageId: itemId,\n isPartial: true,\n type: \"image\" as const,\n };\n }\n};\n\nconst processFunctionCallArgumentsDelta = (\n parsed: Record<string, unknown>,\n pendingCalls: Map<string, PendingFunctionCall>,\n) => {\n const itemId = typeof parsed.item_id === \"string\" ? parsed.item_id : \"\";\n const callId = typeof parsed.call_id === \"string\" ? parsed.call_id : \"\";\n const delta =\n typeof parsed.arguments_delta === \"string\" ? parsed.arguments_delta : \"\";\n\n const existing = pendingCalls.get(itemId);\n\n if (existing) {\n existing.arguments += delta;\n } else {\n pendingCalls.set(itemId, {\n arguments: delta,\n callId,\n name: \"\",\n });\n }\n};\n\nconst processFunctionCallArgumentsDone = function* (\n parsed: Record<string, unknown>,\n pendingCalls: Map<string, PendingFunctionCall>,\n) {\n const itemId = typeof parsed.item_id === \"string\" ? parsed.item_id : \"\";\n const callId = typeof parsed.call_id === \"string\" ? parsed.call_id : \"\";\n const fullArgs = typeof parsed.arguments === \"string\" ? parsed.arguments : \"\";\n\n const pending = pendingCalls.get(itemId);\n const name = pending?.name ?? \"\";\n const args = fullArgs || pending?.arguments || \"\";\n\n pendingCalls.delete(itemId);\n\n yield {\n id: callId || pending?.callId || itemId,\n input: parseToolInput(args),\n name,\n type: \"tool_use\" as const,\n };\n};\n\nconst processOutputItemAdded = (\n parsed: Record<string, unknown>,\n pendingCalls: Map<string, PendingFunctionCall>,\n) => {\n if (!isRecord(parsed.item)) {\n return;\n }\n\n const { item } = parsed;\n const itemId = typeof item.id === \"string\" ? item.id : \"\";\n const itemType = typeof item.type === \"string\" ? item.type : \"\";\n\n if (itemType !== \"function_call\") {\n return;\n }\n\n const callId = typeof item.call_id === \"string\" ? item.call_id : \"\";\n const name = typeof item.name === \"string\" ? item.name : \"\";\n\n pendingCalls.set(itemId, {\n arguments: \"\",\n callId,\n name,\n });\n};\n\nconst isCompletedImageGeneration = (item: Record<string, unknown>) =>\n item.type === \"image_generation_call\" &&\n item.status === \"completed\" &&\n typeof item.result === \"string\" &&\n item.result !== \"\";\n\nconst buildImageChunk = (item: Record<string, unknown>) => ({\n data: typeof item.result === \"string\" ? item.result : \"\",\n format: extractMimeFormat(item.output_format),\n imageId: typeof item.id === \"string\" ? item.id : undefined,\n isPartial: false,\n revisedPrompt:\n typeof item.revised_prompt === \"string\" ? item.revised_prompt : undefined,\n type: \"image\" as const,\n});\n\nconst extractImageFromOutput = function* (\n output: Array<Record<string, unknown>>,\n) {\n const completedImages = output.filter(isCompletedImageGeneration);\n\n for (const item of completedImages) {\n yield buildImageChunk(item);\n }\n};\n\nconst processCompleted = function* (parsed: Record<string, unknown>) {\n if (!isRecord(parsed.response)) {\n yield { type: \"done\" as const, usage: undefined };\n\n return;\n }\n\n const { response } = parsed;\n const usage = extractUsage(response);\n\n if (isRecordArray(response.output)) {\n yield* extractImageFromOutput(response.output);\n }\n\n yield { type: \"done\" as const, usage };\n};\n\nconst processSSEEvent = function* (\n eventType: string,\n parsed: Record<string, unknown>,\n pendingCalls: Map<string, PendingFunctionCall>,\n) {\n switch (eventType) {\n case \"response.reasoning_summary_text.delta\": {\n const delta = typeof parsed.delta === \"string\" ? parsed.delta : \"\";\n if (!delta) break;\n\n yield {\n content: delta,\n type: \"thinking\" as const,\n };\n\n break;\n }\n\n case \"response.output_text.delta\":\n yield* processTextDelta(parsed);\n break;\n\n case \"response.image_generation_call.partial_image\":\n yield* processPartialImage(parsed);\n break;\n\n case \"response.output_item.added\":\n processOutputItemAdded(parsed, pendingCalls);\n break;\n\n case \"response.function_call_arguments.delta\":\n processFunctionCallArgumentsDelta(parsed, pendingCalls);\n break;\n\n case \"response.function_call_arguments.done\":\n yield* processFunctionCallArgumentsDone(parsed, pendingCalls);\n break;\n\n case \"response.completed\":\n yield* processCompleted(parsed);\n break;\n\n case \"response.failed\":\n case \"response.incomplete\": {\n const respObj = isRecord(parsed.response) ? parsed.response : parsed;\n const errMsg =\n isRecord(respObj.error) && typeof respObj.error.message === \"string\"\n ? respObj.error.message\n : `OpenAI Responses API: ${eventType}`;\n throw new Error(errMsg);\n }\n }\n};\n\nconst flushSSEBuffer = function* (state: StreamState) {\n if (!state.currentEvent || !state.buffer) {\n return;\n }\n\n const parsed = parseJSON(state.buffer);\n\n if (parsed) {\n yield* processSSEEvent(state.currentEvent, parsed, state.pendingCalls);\n }\n\n state.currentEvent = \"\";\n state.buffer = \"\";\n};\n\nconst parseSSELine = (trimmed: string, state: StreamState) => {\n if (trimmed.startsWith(\"event: \")) {\n state.currentEvent = trimmed.slice(EVENT_PREFIX_LENGTH);\n } else if (trimmed.startsWith(\"data: \")) {\n state.buffer = trimmed.slice(DATA_PREFIX_LENGTH);\n }\n};\n\nconst processSSELine = function* (line: string, state: StreamState) {\n const trimmed = line.trim();\n\n if (trimmed) {\n parseSSELine(trimmed, state);\n\n return;\n }\n\n yield* flushSSEBuffer(state);\n};\n\nconst processSSELines = function* (lines: string[], state: StreamState) {\n for (const line of lines) {\n yield* processSSELine(line, state);\n }\n};\n\nconst drainReader = async function* (\n reader: ReadableStreamDefaultReader<Uint8Array>,\n decoder: TextDecoder,\n state: StreamState,\n signal?: AbortSignal,\n) {\n let textBuffer = \"\";\n\n for (\n let result = await reader.read();\n !result.done && !signal?.aborted;\n // eslint-disable-next-line no-await-in-loop\n result = await reader.read()\n ) {\n textBuffer += decoder.decode(result.value, { stream: true });\n const lines = textBuffer.split(\"\\n\");\n textBuffer = lines.pop() ?? \"\";\n\n yield* processSSELines(lines, state);\n }\n\n if (textBuffer.trim()) {\n yield* processSSELines([textBuffer, \"\"], state);\n }\n};\n\nconst parseSSEStream = async function* (\n body: ReadableStream<Uint8Array>,\n signal?: AbortSignal,\n) {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n const state: StreamState = {\n buffer: \"\",\n currentEvent: \"\",\n pendingCalls: new Map(),\n usage: undefined,\n };\n\n try {\n yield* drainReader(reader, decoder, state, signal);\n } finally {\n reader.releaseLock();\n }\n};\n\nconst fetchResponsesStream = async function* (\n baseUrl: string,\n apiKey: string,\n body: Record<string, unknown>,\n signal?: AbortSignal,\n) {\n const target = `${baseUrl}/v1/responses`;\n const response = await fetch(target, {\n ...h2IfHttps(target),\n body: JSON.stringify(body),\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n method: \"POST\",\n signal,\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(\n `OpenAI Responses API error ${response.status}: ${errorText}`,\n );\n }\n\n if (!response.body) {\n throw new Error(\"OpenAI Responses API returned no response body\");\n }\n\n yield* parseSSEStream(response.body, signal);\n};\n\nconst resolveImageModels = (\n imageModels: Set<string> | string[] | undefined,\n) => {\n if (!imageModels) {\n return new Set<string>();\n }\n\n if (imageModels instanceof Set) {\n return imageModels;\n }\n\n return new Set(imageModels);\n};\n\nexport const openaiResponses = (config: OpenAIResponsesConfig) => {\n const baseUrl = config.baseUrl ?? DEFAULT_BASE_URL;\n const imageModels = resolveImageModels(config.imageModels);\n\n return instrumentAIProvider(\n {\n stream: (params: AIProviderStreamParams) => {\n const isImageModel = imageModels.has(params.model);\n const body = buildRequestBody(params, isImageModel);\n\n return fetchResponsesStream(\n baseUrl,\n config.apiKey,\n body,\n params.signal,\n );\n },\n } satisfies AIProviderConfig,\n \"openai-responses\",\n );\n};\n"
7
7
  ],
8
- "mappings": "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",
9
- "debugId": "8E50D1B913079D8F64756E2164756E21",
8
+ "mappings": "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",
9
+ "debugId": "61BC980A04AF7BA864756E2164756E21",
10
10
  "names": []
11
11
  }
@@ -0,0 +1,309 @@
1
+ // @bun
2
+ var __require = import.meta.require;
3
+
4
+ // src/ai/tools/codeExecution.ts
5
+ var defaultDescription = (expose) => {
6
+ const lines = [
7
+ "Execute JavaScript code in a sandboxed environment.",
8
+ "",
9
+ "Input: `{ code: string }` \u2014 the JS source to evaluate. The script's last",
10
+ "expression is the return value (vm.Script semantics).",
11
+ "",
12
+ "Output: JSON with `{ result, log, error?, cpuMs, heapBytes }`.",
13
+ "",
14
+ "Built-in: `log(...args)` captures stdout-like output into the result.log",
15
+ "array."
16
+ ];
17
+ const exposed = expose ? Object.keys(expose) : [];
18
+ if (exposed.length > 0) {
19
+ lines.push("");
20
+ lines.push("Host functions available in the sandbox:");
21
+ for (const name of exposed) {
22
+ lines.push(` - ${name}(...)`);
23
+ }
24
+ }
25
+ return lines.join(`
26
+ `);
27
+ };
28
+ var codeExecutionTool = (options = {}) => {
29
+ const memoryLimit = options.memoryLimit ?? 64;
30
+ const timeout = options.timeout ?? 1000;
31
+ const backend = options.backend ?? "auto";
32
+ const expose = options.expose ?? {};
33
+ const poolSize = options.poolSize ?? 8;
34
+ const recycleAfter = options.recycleAfter ?? 50;
35
+ const description = options.description ?? defaultDescription(expose);
36
+ let cachedPool = null;
37
+ let cachedPoolPromise = null;
38
+ const loadPool = async () => {
39
+ if (cachedPool !== null)
40
+ return cachedPool;
41
+ if (cachedPoolPromise !== null)
42
+ return cachedPoolPromise;
43
+ cachedPoolPromise = (async () => {
44
+ const jsc = await import("@absolutejs/isolated-jsc");
45
+ const pool = jsc.createIsolatePool({
46
+ isolate: { backend, memoryLimit },
47
+ maxSize: poolSize,
48
+ recycleAfter
49
+ });
50
+ cachedPool = { pool, jsc };
51
+ return cachedPool;
52
+ })();
53
+ return cachedPoolPromise;
54
+ };
55
+ const runCode = async (code) => {
56
+ const log = [];
57
+ let cpuMs = 0;
58
+ let heapBytes = 0;
59
+ try {
60
+ const { pool, jsc } = await loadPool();
61
+ return await pool.run("default", async (isolate) => {
62
+ const context = await isolate.createContext();
63
+ try {
64
+ await context.setGlobal("log", new jsc.Reference((...args) => {
65
+ log.push(args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" "));
66
+ }));
67
+ for (const [name, fn] of Object.entries(expose)) {
68
+ await context.setGlobal(name, new jsc.Reference(fn));
69
+ }
70
+ const script = await isolate.compileScript(code);
71
+ const { result, metrics } = await script.runWithMetrics(context, { timeout });
72
+ cpuMs = metrics.cpuMs;
73
+ heapBytes = metrics.heapBytes;
74
+ return { ok: true, result, log, cpuMs, heapBytes };
75
+ } finally {
76
+ await context.dispose().catch(() => {});
77
+ }
78
+ });
79
+ } catch (error) {
80
+ const name = error instanceof Error ? error.name : "Error";
81
+ const message = error instanceof Error ? error.message : String(error);
82
+ return {
83
+ ok: false,
84
+ log,
85
+ error: { name, message },
86
+ cpuMs,
87
+ heapBytes
88
+ };
89
+ }
90
+ };
91
+ return {
92
+ description,
93
+ input: {
94
+ type: "object",
95
+ properties: {
96
+ code: {
97
+ type: "string",
98
+ description: "JavaScript source to evaluate. The script's last expression is the return value. Use `log(...)` for stdout-like output."
99
+ }
100
+ },
101
+ required: ["code"]
102
+ },
103
+ handler: async (input) => {
104
+ const code = input && typeof input === "object" && "code" in input ? input.code : undefined;
105
+ if (typeof code !== "string") {
106
+ return JSON.stringify({
107
+ ok: false,
108
+ error: { name: "InvalidInput", message: "expected `{ code: string }`" },
109
+ log: [],
110
+ cpuMs: 0,
111
+ heapBytes: 0
112
+ });
113
+ }
114
+ const run = await runCode(code);
115
+ return JSON.stringify(run);
116
+ }
117
+ };
118
+ };
119
+ // src/ai/tools/codeMode.ts
120
+ var buildDescription = (tools, types) => {
121
+ const lines = [
122
+ "Execute JavaScript that calls one or more host tools, returning a",
123
+ "single value. Prefer this over calling individual tools when you'd",
124
+ "otherwise need multiple sequential tool calls \u2014 one Code Mode call",
125
+ "replaces N tool calls plus the intermediate context.",
126
+ "",
127
+ "Input: `{ code: string }`. The code is a function BODY (not a full",
128
+ "function). It can use `await`, `const`/`let`, control flow, etc.",
129
+ "Whatever you `return` becomes the tool output.",
130
+ "",
131
+ "Built-in: `log(...args)` captures messages for debugging. Logs are",
132
+ "returned alongside the result; they don't enter the model context.",
133
+ "",
134
+ "Available host functions (calling these from your code is what runs",
135
+ "the real work; everything else is plain JS):",
136
+ ""
137
+ ];
138
+ for (const [name, tool] of Object.entries(tools)) {
139
+ lines.push(`// ${tool.description}`);
140
+ lines.push(`declare const ${name}: ${tool.tsSignature};`);
141
+ lines.push("");
142
+ }
143
+ if (types !== undefined && types.trim().length > 0) {
144
+ lines.push("// Shared types referenced by the signatures above:");
145
+ lines.push(types.trim());
146
+ lines.push("");
147
+ }
148
+ lines.push("Example:");
149
+ lines.push("```js");
150
+ lines.push("// Get the cheapest matching product and its full record.");
151
+ const firstTool = Object.keys(tools)[0];
152
+ if (firstTool !== undefined) {
153
+ lines.push(`const items = await ${firstTool}('search query');`);
154
+ lines.push("const cheapest = items.sort((a, b) => a.price - b.price)[0];");
155
+ lines.push("return cheapest;");
156
+ } else {
157
+ lines.push("return 42;");
158
+ }
159
+ lines.push("```");
160
+ lines.push("");
161
+ lines.push("Output: JSON with `{ result, log, toolCalls, cpuMs, heapBytes }`.");
162
+ return lines.join(`
163
+ `);
164
+ };
165
+ var codeModeTool = (options) => {
166
+ const memoryLimit = options.memoryLimit ?? 64;
167
+ const timeout = options.timeout ?? 5000;
168
+ const backend = options.backend ?? "auto";
169
+ const poolSize = options.poolSize ?? 8;
170
+ const recycleAfter = options.recycleAfter ?? 50;
171
+ const tools = options.tools;
172
+ const description = options.description ?? buildDescription(tools, options.types);
173
+ let cachedPool = null;
174
+ let cachedPoolPromise = null;
175
+ const loadPool = async () => {
176
+ if (cachedPool !== null)
177
+ return cachedPool;
178
+ if (cachedPoolPromise !== null)
179
+ return cachedPoolPromise;
180
+ cachedPoolPromise = (async () => {
181
+ const jsc = await import("@absolutejs/isolated-jsc");
182
+ const pool = jsc.createIsolatePool({
183
+ isolate: { backend, memoryLimit },
184
+ maxSize: poolSize,
185
+ recycleAfter
186
+ });
187
+ cachedPool = { pool, jsc };
188
+ return cachedPool;
189
+ })();
190
+ return cachedPoolPromise;
191
+ };
192
+ const runCode = async (code) => {
193
+ const log = [];
194
+ const toolCalls = [];
195
+ let cpuMs = 0;
196
+ let heapBytes = 0;
197
+ try {
198
+ const { pool, jsc } = await loadPool();
199
+ return await pool.run("default", async (isolate) => {
200
+ const context = await isolate.createContext();
201
+ try {
202
+ await context.setGlobal("log", new jsc.Reference((...args) => {
203
+ log.push(args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" "));
204
+ }));
205
+ for (const [name, tool] of Object.entries(tools)) {
206
+ await context.setGlobal(name, new jsc.Reference((...args) => {
207
+ const startedAt = performance.now();
208
+ const recordSuccess = () => {
209
+ toolCalls.push({
210
+ args,
211
+ durationMs: performance.now() - startedAt,
212
+ name,
213
+ ok: true
214
+ });
215
+ };
216
+ const recordError = (err) => {
217
+ toolCalls.push({
218
+ args,
219
+ durationMs: performance.now() - startedAt,
220
+ error: err instanceof Error ? err.message : String(err),
221
+ name,
222
+ ok: false
223
+ });
224
+ };
225
+ let outcome;
226
+ try {
227
+ outcome = tool.handler(...args);
228
+ } catch (err) {
229
+ recordError(err);
230
+ throw err;
231
+ }
232
+ if (outcome !== null && typeof outcome === "object" && "then" in outcome && typeof outcome.then === "function") {
233
+ return outcome.then((v) => {
234
+ recordSuccess();
235
+ return v;
236
+ }, (err) => {
237
+ recordError(err);
238
+ throw err;
239
+ });
240
+ }
241
+ recordSuccess();
242
+ return outcome;
243
+ }));
244
+ }
245
+ const wrapped = `(async () => { ${code}
246
+ })()`;
247
+ const script = await isolate.compileScript(wrapped);
248
+ const { result, metrics } = await script.runWithMetrics(context, {
249
+ timeout
250
+ });
251
+ cpuMs = metrics.cpuMs;
252
+ heapBytes = metrics.heapBytes;
253
+ return { cpuMs, heapBytes, log, ok: true, result, toolCalls };
254
+ } finally {
255
+ await context.dispose().catch(() => {});
256
+ }
257
+ });
258
+ } catch (error) {
259
+ const name = error instanceof Error ? error.name : "Error";
260
+ const message = error instanceof Error ? error.message : String(error);
261
+ return {
262
+ cpuMs,
263
+ error: { message, name },
264
+ heapBytes,
265
+ log,
266
+ ok: false,
267
+ toolCalls
268
+ };
269
+ }
270
+ };
271
+ return {
272
+ description,
273
+ handler: async (input) => {
274
+ const code = input !== null && typeof input === "object" && "code" in input ? input.code : undefined;
275
+ if (typeof code !== "string") {
276
+ return JSON.stringify({
277
+ cpuMs: 0,
278
+ error: {
279
+ message: "expected `{ code: string }`",
280
+ name: "InvalidInput"
281
+ },
282
+ heapBytes: 0,
283
+ log: [],
284
+ ok: false,
285
+ toolCalls: []
286
+ });
287
+ }
288
+ const run = await runCode(code);
289
+ return JSON.stringify(run);
290
+ },
291
+ input: {
292
+ properties: {
293
+ code: {
294
+ description: "JavaScript function-body source. Use `await` to call host tools; `return` the final value. Multiple tool calls in one " + "block are encouraged \u2014 that's the whole point of Code Mode.",
295
+ type: "string"
296
+ }
297
+ },
298
+ required: ["code"],
299
+ type: "object"
300
+ }
301
+ };
302
+ };
303
+ export {
304
+ codeModeTool,
305
+ codeExecutionTool
306
+ };
307
+
308
+ //# debugId=05A8D1541DB1A68E64756E2164756E21
309
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,11 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/ai/tools/codeExecution.ts", "../src/ai/tools/codeMode.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * `codeExecutionTool` — an `AIToolDefinition` that runs model-generated\n * JavaScript inside an `@absolutejs/isolated-jsc` sandbox.\n *\n * Drop into any `tools: {...}` map:\n *\n * ```ts\n * import { codeExecutionTool } from '@absolutejs/ai/tools';\n *\n * const tools = {\n * run_code: codeExecutionTool({\n * memoryLimit: 64,\n * timeout: 1000,\n * expose: {\n * lookup_user: async (id) => db.users.findById(id as string),\n * round: (n) => Math.round(n as number),\n * },\n * }),\n * };\n * ```\n *\n * The model emits `{ code: '<JS source>' }` as the tool input; the host\n * runs the code in a fresh context inside a pooled isolate and returns\n * a JSON-stringified result containing:\n *\n * - `result` — the script's return value (JSON-clonable).\n * - `log` — array of strings captured via the host-injected `log(...)`.\n * - `error` — error message + name if the script threw or timed out.\n * - `cpuMs`, `heapBytes` — per-call telemetry (Phase 3 docs / monitoring).\n *\n * Defaults to the FFI backend on macOS + Linux (with libJSC installed),\n * Worker fallback elsewhere. Per-isolate pool is created once per\n * `codeExecutionTool()` call; pool key is `'default'` (one isolate for\n * all calls). For per-tenant isolation, create one tool instance per\n * tenant.\n *\n * Constraint: when using the FFI backend, **exposed host fns must be\n * synchronous**. Async host fns (returning a Promise that doesn't settle\n * synchronously — `fetch`, `setTimeout`-resolved Promises, real I/O)\n * require `backend: 'worker'` per isolated-jsc 0.3 documented limit.\n * Set `backend: 'worker'` in the tool options if any of your `expose`d\n * fns are async-settling.\n */\n\nimport type { AIToolDefinition } from \"../../../types/ai\";\n\n/** Options for {@link codeExecutionTool}. */\nexport type CodeExecutionToolOptions = {\n /**\n * Per-isolate heap memory cap (MB). Default 64. Note that the\n * sandbox's cold-start baseline differs by backend (FFI ~300 KB vs\n * Worker ~46 MB), so the practical floor for Worker is ~64 MB.\n */\n memoryLimit?: number;\n /** Wall-clock timeout per `run_code` call (ms). Default 1000. */\n timeout?: number;\n /**\n * isolated-jsc backend. Default `\"auto\"` (FFI when reachable, Worker\n * otherwise). Set to `\"worker\"` if your `expose`d fns are async-settling\n * — the FFI backend only supports sync host fns (see Reference docs).\n */\n backend?: \"auto\" | \"ffi\" | \"worker\";\n /**\n * Host functions the model can call from inside the sandbox. Names\n * become globals; the model invokes them with `await name(...)`.\n * The function's description (`.toString()` first line, if a doc\n * comment) is included in the tool's description so the model knows\n * what's available.\n */\n expose?: Record<string, (...args: unknown[]) => unknown>;\n /**\n * Override the tool's description string. Default is auto-generated\n * from the exposed function list.\n */\n description?: string;\n /**\n * Pool size cap — max concurrent isolates across all parallel tool\n * calls. Default 8.\n */\n poolSize?: number;\n /**\n * Recycle the isolate after N successful runs to bound per-context\n * heap creep. Default 50.\n */\n recycleAfter?: number;\n};\n\ntype Run = {\n ok: boolean;\n result?: unknown;\n log: string[];\n error?: { name: string; message: string };\n cpuMs: number;\n heapBytes: number;\n};\n\nconst defaultDescription = (\n expose: Record<string, (...args: unknown[]) => unknown> | undefined,\n): string => {\n const lines = [\n \"Execute JavaScript code in a sandboxed environment.\",\n \"\",\n \"Input: `{ code: string }` — the JS source to evaluate. The script's last\",\n \"expression is the return value (vm.Script semantics).\",\n \"\",\n \"Output: JSON with `{ result, log, error?, cpuMs, heapBytes }`.\",\n \"\",\n \"Built-in: `log(...args)` captures stdout-like output into the result.log\",\n \"array.\",\n ];\n const exposed = expose ? Object.keys(expose) : [];\n if (exposed.length > 0) {\n lines.push(\"\");\n lines.push(\"Host functions available in the sandbox:\");\n for (const name of exposed) {\n lines.push(` - ${name}(...)`);\n }\n }\n return lines.join(\"\\n\");\n};\n\nexport const codeExecutionTool = (\n options: CodeExecutionToolOptions = {},\n): AIToolDefinition => {\n const memoryLimit = options.memoryLimit ?? 64;\n const timeout = options.timeout ?? 1000;\n const backend = options.backend ?? \"auto\";\n const expose = options.expose ?? {};\n const poolSize = options.poolSize ?? 8;\n const recycleAfter = options.recycleAfter ?? 50;\n const description = options.description ?? defaultDescription(expose);\n\n // Lazy import isolated-jsc so this module loads without it (consumers\n // who never call the tool don't pay the dep). The first call resolves\n // and caches the pool; later calls reuse it.\n type IsolatedJsc = typeof import(\"@absolutejs/isolated-jsc\");\n let cachedPool:\n | { pool: ReturnType<IsolatedJsc[\"createIsolatePool\"]>; jsc: IsolatedJsc }\n | null = null;\n let cachedPoolPromise: Promise<{\n pool: ReturnType<IsolatedJsc[\"createIsolatePool\"]>;\n jsc: IsolatedJsc;\n }> | null = null;\n\n const loadPool = async () => {\n if (cachedPool !== null) return cachedPool;\n if (cachedPoolPromise !== null) return cachedPoolPromise;\n cachedPoolPromise = (async () => {\n const jsc = (await import(\"@absolutejs/isolated-jsc\")) as IsolatedJsc;\n const pool = jsc.createIsolatePool({\n isolate: { backend, memoryLimit },\n maxSize: poolSize,\n recycleAfter,\n });\n cachedPool = { pool, jsc };\n return cachedPool;\n })();\n return cachedPoolPromise;\n };\n\n const runCode = async (code: string): Promise<Run> => {\n const log: string[] = [];\n let cpuMs = 0;\n let heapBytes = 0;\n try {\n const { pool, jsc } = await loadPool();\n return await pool.run(\"default\", async (isolate) => {\n const context = await isolate.createContext();\n try {\n // Built-in log capture. Sync host fn → works on FFI + Worker.\n await context.setGlobal(\n \"log\",\n new jsc.Reference((...args: unknown[]) => {\n log.push(\n args\n .map((a) =>\n typeof a === \"string\" ? a : JSON.stringify(a),\n )\n .join(\" \"),\n );\n }),\n );\n // Exposed host fns. Names become globals; user code calls them\n // directly (FFI sync path) or with `await` (Worker path).\n for (const [name, fn] of Object.entries(expose)) {\n await context.setGlobal(name, new jsc.Reference(fn));\n }\n // Wrap the user code so the last expression is what's returned\n // (matching the conventional script-result semantics).\n const script = await isolate.compileScript(code);\n const { result, metrics } = await script.runWithMetrics(\n context,\n { timeout },\n );\n cpuMs = metrics.cpuMs;\n heapBytes = metrics.heapBytes;\n return { ok: true, result, log, cpuMs, heapBytes };\n } finally {\n await context.dispose().catch(() => {\n /* dead context — fine */\n });\n }\n });\n } catch (error) {\n const name =\n error instanceof Error ? error.name : \"Error\";\n const message =\n error instanceof Error ? error.message : String(error);\n return {\n ok: false,\n log,\n error: { name, message },\n cpuMs,\n heapBytes,\n };\n }\n };\n\n return {\n description,\n input: {\n type: \"object\",\n properties: {\n code: {\n type: \"string\",\n description:\n \"JavaScript source to evaluate. The script's last expression \" +\n \"is the return value. Use `log(...)` for stdout-like output.\",\n },\n },\n required: [\"code\"],\n },\n handler: async (input: unknown) => {\n const code =\n input && typeof input === \"object\" && \"code\" in input\n ? (input as { code: unknown }).code\n : undefined;\n if (typeof code !== \"string\") {\n return JSON.stringify({\n ok: false,\n error: { name: \"InvalidInput\", message: \"expected `{ code: string }`\" },\n log: [],\n cpuMs: 0,\n heapBytes: 0,\n });\n }\n const run = await runCode(code);\n return JSON.stringify(run);\n },\n };\n};\n",
6
+ "/**\n * `codeModeTool` — Code Mode for AI agents.\n *\n * Instead of exposing N tools to the model and having it call them one\n * at a time (N round-trips per turn, N tool-call tokens, the model has\n * to track intermediate state in context), Code Mode exposes ONE tool:\n * `run_code`. The model sees the typed TypeScript signatures of all\n * underlying tools and emits a single function that chains them.\n *\n * Pattern was popularized by Cloudflare's Dynamic Workers (April 2026\n * blog post: \"100× faster than containers\"). Anthropic's programmatic\n * tool calling is the same idea — execution pauses on a sub-tool call,\n * the API yields a tool_use, you return a result, execution resumes.\n * Both vendors report ~80% token reduction on multi-tool turns.\n *\n * ```ts\n * import { codeModeTool } from '@absolutejs/ai/tools';\n *\n * const tools = {\n * run_code: codeModeTool({\n * timeout: 5000,\n * tools: {\n * search_products: {\n * description: 'Full-text search the product catalogue.',\n * tsSignature: '(query: string) => Promise<Product[]>',\n * handler: async (q) => db.products.search(q as string),\n * },\n * get_product: {\n * description: 'Fetch one product by id.',\n * tsSignature: '(id: string) => Promise<Product | null>',\n * handler: async (id) => db.products.findById(id as string),\n * },\n * },\n * types: `\n * type Product = { id: string; name: string; price: number };\n * `,\n * }),\n * };\n * ```\n *\n * The model emits a single function:\n *\n * ```js\n * const items = await search_products('hat');\n * const cheapest = items.sort((a, b) => a.price - b.price)[0];\n * const detail = await get_product(cheapest.id);\n * return { name: detail.name, price: detail.price };\n * ```\n *\n * One sandbox eval. Two host-fn calls. One returned value. The model's\n * context only ever sees the final return — intermediate tool results\n * don't enter the conversation window, so multi-step workflows are\n * dramatically cheaper.\n *\n * Each underlying tool's `handler` runs on the HOST side (not in the\n * sandbox). Async host fns work on both FFI (via the 0.4 pump) and\n * Worker backends since isolated-jsc 0.4+. Errors thrown by host\n * handlers propagate into the sandbox as JS Errors the model can\n * catch and recover from.\n */\n\nimport type { AIToolDefinition } from \"../../../types/ai\";\n\n/**\n * One callable surfaced to the sandbox. The `tsSignature` shows up in\n * the model-visible description; `handler` runs on the host when the\n * sandbox calls it.\n */\nexport type CodeModeHostTool = {\n /** One-line human description of what this tool does. */\n description: string;\n /** TypeScript signature shown to the model. Example:\n * `'(query: string, options?: { limit?: number }) => Promise<Item[]>'`.\n * The model writes JS against this signature; we don't enforce it at\n * runtime — type-check is the model's responsibility. */\n tsSignature: string;\n /** Host implementation. Receives positional args as the model passed\n * them. Return value is structure-cloned back into the sandbox. */\n handler: (...args: unknown[]) => unknown;\n};\n\n/** Options for {@link codeModeTool}. */\nexport type CodeModeToolOptions = {\n /** Map of host-tool name → {@link CodeModeHostTool}. */\n tools: Record<string, CodeModeHostTool>;\n /**\n * Optional shared TypeScript declarations stitched into the prompt\n * (type aliases, interfaces, etc.) so signatures can reference them.\n * Use raw TS source; no parsing happens host-side.\n */\n types?: string;\n /**\n * Per-isolate heap memory cap (MB). Default 64. As with the regular\n * code-execution tool, FFI's cold heap is much smaller than Worker's,\n * but per-call retention scales similarly.\n */\n memoryLimit?: number;\n /** Wall-clock timeout per `run_code` call (ms). Default 5000. */\n timeout?: number;\n /**\n * isolated-jsc backend. Defaults to `'auto'`. Since isolated-jsc 0.4\n * both backends support async host fns, so the choice is purely\n * about cold spawn (FFI wins ~6×) vs Web APIs availability (Worker\n * has `URL` / `TextEncoder` / `WebSocket`; FFI does not).\n */\n backend?: \"auto\" | \"ffi\" | \"worker\";\n /**\n * Override the auto-generated description. By default we emit the\n * model-facing prompt: a short instruction header + the host fn\n * signatures + any shared `types`.\n */\n description?: string;\n /** Pool size cap. Default 8. */\n poolSize?: number;\n /** Recycle the isolate after N successful runs. Default 50. */\n recycleAfter?: number;\n};\n\ntype RunResult = {\n ok: boolean;\n result?: unknown;\n log: string[];\n toolCalls: Array<{\n name: string;\n args: unknown[];\n durationMs: number;\n ok: boolean;\n error?: string;\n }>;\n error?: { name: string; message: string };\n cpuMs: number;\n heapBytes: number;\n};\n\nconst buildDescription = (\n tools: Record<string, CodeModeHostTool>,\n types: string | undefined,\n): string => {\n const lines: string[] = [\n \"Execute JavaScript that calls one or more host tools, returning a\",\n \"single value. Prefer this over calling individual tools when you'd\",\n \"otherwise need multiple sequential tool calls — one Code Mode call\",\n \"replaces N tool calls plus the intermediate context.\",\n \"\",\n \"Input: `{ code: string }`. The code is a function BODY (not a full\",\n \"function). It can use `await`, `const`/`let`, control flow, etc.\",\n \"Whatever you `return` becomes the tool output.\",\n \"\",\n \"Built-in: `log(...args)` captures messages for debugging. Logs are\",\n \"returned alongside the result; they don't enter the model context.\",\n \"\",\n \"Available host functions (calling these from your code is what runs\",\n \"the real work; everything else is plain JS):\",\n \"\",\n ];\n for (const [name, tool] of Object.entries(tools)) {\n lines.push(`// ${tool.description}`);\n lines.push(`declare const ${name}: ${tool.tsSignature};`);\n lines.push(\"\");\n }\n if (types !== undefined && types.trim().length > 0) {\n lines.push(\"// Shared types referenced by the signatures above:\");\n lines.push(types.trim());\n lines.push(\"\");\n }\n lines.push(\"Example:\");\n lines.push(\"```js\");\n lines.push(\"// Get the cheapest matching product and its full record.\");\n const firstTool = Object.keys(tools)[0];\n if (firstTool !== undefined) {\n lines.push(`const items = await ${firstTool}('search query');`);\n lines.push(\n \"const cheapest = items.sort((a, b) => a.price - b.price)[0];\",\n );\n lines.push(\"return cheapest;\");\n } else {\n lines.push(\"return 42;\");\n }\n lines.push(\"```\");\n lines.push(\"\");\n lines.push(\"Output: JSON with `{ result, log, toolCalls, cpuMs, heapBytes }`.\");\n return lines.join(\"\\n\");\n};\n\nexport const codeModeTool = (\n options: CodeModeToolOptions,\n): AIToolDefinition => {\n const memoryLimit = options.memoryLimit ?? 64;\n const timeout = options.timeout ?? 5000;\n const backend = options.backend ?? \"auto\";\n const poolSize = options.poolSize ?? 8;\n const recycleAfter = options.recycleAfter ?? 50;\n const tools = options.tools;\n const description =\n options.description ?? buildDescription(tools, options.types);\n\n type IsolatedJsc = typeof import(\"@absolutejs/isolated-jsc\");\n let cachedPool:\n | { pool: ReturnType<IsolatedJsc[\"createIsolatePool\"]>; jsc: IsolatedJsc }\n | null = null;\n let cachedPoolPromise: Promise<{\n pool: ReturnType<IsolatedJsc[\"createIsolatePool\"]>;\n jsc: IsolatedJsc;\n }> | null = null;\n\n const loadPool = async () => {\n if (cachedPool !== null) return cachedPool;\n if (cachedPoolPromise !== null) return cachedPoolPromise;\n cachedPoolPromise = (async () => {\n const jsc = (await import(\"@absolutejs/isolated-jsc\")) as IsolatedJsc;\n const pool = jsc.createIsolatePool({\n isolate: { backend, memoryLimit },\n maxSize: poolSize,\n recycleAfter,\n });\n cachedPool = { pool, jsc };\n return cachedPool;\n })();\n return cachedPoolPromise;\n };\n\n const runCode = async (code: string): Promise<RunResult> => {\n const log: string[] = [];\n const toolCalls: RunResult[\"toolCalls\"] = [];\n let cpuMs = 0;\n let heapBytes = 0;\n try {\n const { pool, jsc } = await loadPool();\n return await pool.run(\"default\", async (isolate) => {\n const context = await isolate.createContext();\n try {\n // Built-in log capture.\n await context.setGlobal(\n \"log\",\n new jsc.Reference((...args: unknown[]) => {\n log.push(\n args\n .map((a) =>\n typeof a === \"string\" ? a : JSON.stringify(a),\n )\n .join(\" \"),\n );\n }),\n );\n\n // Bind each host tool as a global Reference. Wrap so we\n // capture per-call telemetry (durationMs, error). Async\n // host fns work on both FFI (0.4+) and Worker backends.\n for (const [name, tool] of Object.entries(tools)) {\n await context.setGlobal(\n name,\n new jsc.Reference(((...args: unknown[]) => {\n const startedAt = performance.now();\n const recordSuccess = () => {\n toolCalls.push({\n args,\n durationMs: performance.now() - startedAt,\n name,\n ok: true,\n });\n };\n const recordError = (err: unknown) => {\n toolCalls.push({\n args,\n durationMs: performance.now() - startedAt,\n error: err instanceof Error ? err.message : String(err),\n name,\n ok: false,\n });\n };\n let outcome: unknown;\n try {\n outcome = tool.handler(...args);\n } catch (err) {\n recordError(err);\n throw err;\n }\n if (\n outcome !== null &&\n typeof outcome === \"object\" &&\n \"then\" in outcome &&\n typeof (outcome as { then: unknown }).then === \"function\"\n ) {\n return (outcome as Promise<unknown>).then(\n (v) => {\n recordSuccess();\n return v;\n },\n (err) => {\n recordError(err);\n throw err;\n },\n );\n }\n recordSuccess();\n return outcome;\n }) as (...args: unknown[]) => unknown),\n );\n }\n\n // Wrap the model's code as an async function body. Whatever\n // it `return`s becomes the tool output.\n const wrapped = `(async () => { ${code}\\n})()`;\n const script = await isolate.compileScript(wrapped);\n const { result, metrics } = await script.runWithMetrics(context, {\n timeout,\n });\n cpuMs = metrics.cpuMs;\n heapBytes = metrics.heapBytes;\n return { cpuMs, heapBytes, log, ok: true, result, toolCalls };\n } finally {\n await context.dispose().catch(() => {\n /* ok */\n });\n }\n });\n } catch (error) {\n const name = error instanceof Error ? error.name : \"Error\";\n const message =\n error instanceof Error ? error.message : String(error);\n return {\n cpuMs,\n error: { message, name },\n heapBytes,\n log,\n ok: false,\n toolCalls,\n };\n }\n };\n\n return {\n description,\n handler: async (input: unknown) => {\n const code =\n input !== null &&\n typeof input === \"object\" &&\n \"code\" in input\n ? (input as { code: unknown }).code\n : undefined;\n if (typeof code !== \"string\") {\n return JSON.stringify({\n cpuMs: 0,\n error: {\n message: \"expected `{ code: string }`\",\n name: \"InvalidInput\",\n },\n heapBytes: 0,\n log: [],\n ok: false,\n toolCalls: [],\n });\n }\n const run = await runCode(code);\n return JSON.stringify(run);\n },\n input: {\n properties: {\n code: {\n description:\n \"JavaScript function-body source. Use `await` to call host \" +\n \"tools; `return` the final value. Multiple tool calls in one \" +\n \"block are encouraged — that's the whole point of Code Mode.\",\n type: \"string\",\n },\n },\n required: [\"code\"],\n type: \"object\",\n },\n };\n};\n"
7
+ ],
8
+ "mappings": "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",
9
+ "debugId": "05A8D1541DB1A68E64756E2164756E21",
10
+ "names": []
11
+ }
@@ -0,0 +1,85 @@
1
+ /**
2
+ * `codeExecutionTool` — an `AIToolDefinition` that runs model-generated
3
+ * JavaScript inside an `@absolutejs/isolated-jsc` sandbox.
4
+ *
5
+ * Drop into any `tools: {...}` map:
6
+ *
7
+ * ```ts
8
+ * import { codeExecutionTool } from '@absolutejs/ai/tools';
9
+ *
10
+ * const tools = {
11
+ * run_code: codeExecutionTool({
12
+ * memoryLimit: 64,
13
+ * timeout: 1000,
14
+ * expose: {
15
+ * lookup_user: async (id) => db.users.findById(id as string),
16
+ * round: (n) => Math.round(n as number),
17
+ * },
18
+ * }),
19
+ * };
20
+ * ```
21
+ *
22
+ * The model emits `{ code: '<JS source>' }` as the tool input; the host
23
+ * runs the code in a fresh context inside a pooled isolate and returns
24
+ * a JSON-stringified result containing:
25
+ *
26
+ * - `result` — the script's return value (JSON-clonable).
27
+ * - `log` — array of strings captured via the host-injected `log(...)`.
28
+ * - `error` — error message + name if the script threw or timed out.
29
+ * - `cpuMs`, `heapBytes` — per-call telemetry (Phase 3 docs / monitoring).
30
+ *
31
+ * Defaults to the FFI backend on macOS + Linux (with libJSC installed),
32
+ * Worker fallback elsewhere. Per-isolate pool is created once per
33
+ * `codeExecutionTool()` call; pool key is `'default'` (one isolate for
34
+ * all calls). For per-tenant isolation, create one tool instance per
35
+ * tenant.
36
+ *
37
+ * Constraint: when using the FFI backend, **exposed host fns must be
38
+ * synchronous**. Async host fns (returning a Promise that doesn't settle
39
+ * synchronously — `fetch`, `setTimeout`-resolved Promises, real I/O)
40
+ * require `backend: 'worker'` per isolated-jsc 0.3 documented limit.
41
+ * Set `backend: 'worker'` in the tool options if any of your `expose`d
42
+ * fns are async-settling.
43
+ */
44
+ import type { AIToolDefinition } from "../../../types/ai";
45
+ /** Options for {@link codeExecutionTool}. */
46
+ export type CodeExecutionToolOptions = {
47
+ /**
48
+ * Per-isolate heap memory cap (MB). Default 64. Note that the
49
+ * sandbox's cold-start baseline differs by backend (FFI ~300 KB vs
50
+ * Worker ~46 MB), so the practical floor for Worker is ~64 MB.
51
+ */
52
+ memoryLimit?: number;
53
+ /** Wall-clock timeout per `run_code` call (ms). Default 1000. */
54
+ timeout?: number;
55
+ /**
56
+ * isolated-jsc backend. Default `"auto"` (FFI when reachable, Worker
57
+ * otherwise). Set to `"worker"` if your `expose`d fns are async-settling
58
+ * — the FFI backend only supports sync host fns (see Reference docs).
59
+ */
60
+ backend?: "auto" | "ffi" | "worker";
61
+ /**
62
+ * Host functions the model can call from inside the sandbox. Names
63
+ * become globals; the model invokes them with `await name(...)`.
64
+ * The function's description (`.toString()` first line, if a doc
65
+ * comment) is included in the tool's description so the model knows
66
+ * what's available.
67
+ */
68
+ expose?: Record<string, (...args: unknown[]) => unknown>;
69
+ /**
70
+ * Override the tool's description string. Default is auto-generated
71
+ * from the exposed function list.
72
+ */
73
+ description?: string;
74
+ /**
75
+ * Pool size cap — max concurrent isolates across all parallel tool
76
+ * calls. Default 8.
77
+ */
78
+ poolSize?: number;
79
+ /**
80
+ * Recycle the isolate after N successful runs to bound per-context
81
+ * heap creep. Default 50.
82
+ */
83
+ recycleAfter?: number;
84
+ };
85
+ export declare const codeExecutionTool: (options?: CodeExecutionToolOptions) => AIToolDefinition;