// node --test modules/asyncai/code-mode.test.mjs: asyncai with atlibs-code-mode (../atlibs-code-mode, npm ci there) // as its in-process MCP server (a composition handler) and over Streamable HTTP; with stubbed inference, then live // (the endpoint and key as live.test.mjs reads them). import assert from "node:assert/strict"; import { existsSync, mkdtempSync, readFileSync } from "node:fs"; import { homedir, tmpdir } from "node:os"; import { join } from "node:path"; import { test } from "node:test"; import { loadComposition, runCompose } from "../../../atlibs/javascript/src/compose/index.js"; import { localModule } from "../../../atlibs/javascript/src/run-module/index.js"; import { createNodeContext, fileFetch } from "../../../atlibs/javascript/src/server/index.js"; const CODE_MODE = new URL("../../../atlibs-code-mode/js/index.js", import.meta.url); const absent = !existsSync(CODE_MODE) && "no ../atlibs-code-mode"; const MCP = "com.fedfork.exec.mcp.message"; const budget = { calls: Infinity, events: Infinity, wallMs: 300_000 }; const PROGRAM = 'export function main(run: Run): void { print("hi"); run.finish(Json.number(17 * 23)); }'; const wrapper = existsSync(`${homedir()}/.local/bin/deepseek-claude`) ? readFileSync(`${homedir()}/.local/bin/deepseek-claude`, "utf8") : ""; const exported = (name) => new RegExp(`^export ${name}="?([^"\\n]+)"?$`, "m").exec(wrapper)?.[1]; const endpoint = process.env.ASYNCAI_ENDPOINT ?? exported("ANTHROPIC_BASE_URL"); const model = process.env.ASYNCAI_MODEL ?? exported("ANTHROPIC_MODEL"); const key = process.env.ASYNCAI_API_KEY ?? exported("ANTHROPIC_API_KEY"); async function setup(fetchStub) { const { codeMode, streamableHttp } = await import(CODE_MODE); const ctx = createNodeContext({ id: "asyncai-code-mode", stateDir: mkdtempSync(join(tmpdir(), "asyncai-")), ...(fetchStub && { fetch: fetchStub }) }); const code = codeMode({ ctx }); const root = new URL("../../", import.meta.url); const mod = await localModule(new URL("target/wasm32-unknown-unknown/release/asyncai.wasm", root), new URL("modules/asyncai/module.json", root), fileFetch); const composition = await loadComposition(ctx, { $type: "com.fedfork.exec.composition", name: "code", instances: [{ name: "agent", module: "asyncai" }], handlers: [{ name: "code" }], edges: [{ from: "agent", nsid: MCP, handler: "code", reason: "code mode" }] }, { load: async () => mod }); return { ctx, code, composition, http: streamableHttp(code.message) }; } test("stubbed inference: code mode answers in-process and over Streamable HTTP", { skip: absent }, async () => { const turns = [ { content: [{ type: "tool_use", id: "a", name: "code__run_assemblyscript", input: { code: PROGRAM } }, { type: "tool_use", id: "b", name: "web__run_assemblyscript", input: { code: PROGRAM } }], stop_reason: "tool_use" }, { content: [{ type: "text", text: "391" }], stop_reason: "end_turn" }, ]; const { ctx, code, composition, http: serve } = await setup(async (url, init) => (url.startsWith("https://inference.test/") ? Response.json(turns.shift()) : url.startsWith("https://code.test/") ? serve(new Request(url, init)) : fetch(url, init))); const ran = await runCompose(ctx, composition, "agent", "run", { prompt: "17 * 23?", endpoint: "https://inference.test", mcp: [{ name: "code" }, { name: "web", url: "https://code.test/mcp" }] }, { handlers: { code: code.handler }, http: { "https://inference.test": {}, "https://code.test": {} }, budget }); ctx.close?.(); assert.equal(ran.result.error, undefined, ran.result.error); assert.deepEqual(ran.result.servers.map((s) => [s.name, s.phase, s.tools]), [["code", "ready", ["run_assemblyscript"]], ["web", "ready", ["run_assemblyscript"]]]); const results = ran.result.messages.at(-2).content; for (const r of results) assert.deepEqual([r.is_error, JSON.parse(r.content)], [undefined, { stdout: "hi\n", result: 391 }]); assert.equal(ran.result.text, "391"); }); test("live inference: the model writes and runs a program through code mode", { skip: absent || (!(endpoint && key) && "no inference key") }, async () => { const { ctx, code, composition } = await setup(); const ran = await runCompose(ctx, composition, "agent", "run", { prompt: "Compute 1234 * 5678 by running a program with the code tool (finish with the number), then reply with only the number.", endpoint, model, maxTokens: 4000, maxSteps: 6, }, { handlers: { code: code.handler }, http: { [new URL(endpoint).origin]: { headers: { "x-api-key": key } } }, budget }); ctx.close?.(); assert.equal(ran.result.error, undefined, ran.result.error); const results = ran.result.messages.flatMap((m) => (Array.isArray(m.content) ? m.content : [])).filter((b) => b.type === "tool_result"); assert.ok(results.some((r) => !r.is_error && r.content.includes("7006652")), JSON.stringify(results).slice(0, 800)); assert.match(ran.result.text.replaceAll(",", ""), /7006652/); });