// Live: node --test modules/asyncai/live.test.mjs (network; not in the offline suite). // Inference against an Anthropic-compatible endpoint: ASYNCAI_ENDPOINT, ASYNCAI_MODEL and ASYNCAI_API_KEY, // else the ANTHROPIC_BASE_URL, ANTHROPIC_MODEL and ANTHROPIC_API_KEY lines of ~/.local/bin/deepseek-claude. // Remote MCP: DeepWiki's public Streamable HTTP server (no auth). The key goes only into the host's // http allowlist; it never reaches the wasm, the result or the output. // co/core: ASYNCAI_COCORE_HANDLE and ASYNCAI_COCORE_PASSWORD (an app password), else the ALICE_ATPROTO_* // lines of ~/.aliceoa_bsky_social_source: the stub model, authorized by a service-auth token the host mints // from that session. An account that never connected co/core answers onboarding_required, which passes // unless ASYNCAI_COCORE_ONBOARDED=1. import assert from "node:assert/strict"; import { readFileSync } from "node:fs"; import { homedir } from "node:os"; import { test } from "node:test"; import { loadComposition, runCompose } from "../../../atlibs/javascript/src/compose/index.js"; import { hostCall } from "../../../atlibs/javascript/src/run-module/host-call.js"; import { runModule } from "../../../atlibs/javascript/src/run-module/index.js"; import { login, modulePolicy, sessionCall } from "../../../atlibs/javascript/src/server/index.js"; import { load } from "../../../atlibs/rust/src/harness.mjs"; import { fetcher, mcpServer, noFetchers, streamableHttp } from "./mcp-stub.mjs"; const { module, run } = await load(new URL("../../target/wasm32-unknown-unknown/release/asyncai.wasm", import.meta.url)); const mod = { module, ...JSON.parse(readFileSync(new URL("module.json", import.meta.url), "utf8")) }; const MCP = "com.fedfork.exec.mcp.message"; const DEEPWIKI = "https://mcp.deepwiki.com/mcp"; const budget = { calls: Infinity, events: Infinity, wallMs: 300_000 }; const wrapper = (() => { try { return readFileSync(`${homedir()}/.local/bin/deepseek-claude`, "utf8"); } catch { return ""; } })(); 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"); const noKey = !(endpoint && key) && "no inference endpoint and key (ASYNCAI_* or ~/.local/bin/deepseek-claude)"; const alice = (() => { try { return readFileSync(`${homedir()}/.aliceoa_bsky_social_source`, "utf8"); } catch { return ""; } })(); const aliceVar = (name) => new RegExp(`^export ${name}=['"]?([^'"\n]+)['"]?$`, "m").exec(alice)?.[1]; const cocoreHandle = process.env.ASYNCAI_COCORE_HANDLE ?? aliceVar("ALICE_ATPROTO_HANDLE"); const cocorePassword = process.env.ASYNCAI_COCORE_PASSWORD ?? aliceVar("ALICE_ATPROTO_PASSWORD"); const ctx = { wasm: { run: async ({ entry, input }) => run(entry, input) }, http: { fetch: (url, init) => fetch(url, init) } }; const http = () => ({ [new URL(endpoint).origin]: { headers: { "x-api-key": key } }, "https://mcp.deepwiki.com": {} }); test("live MCP: DeepWiki initializes and lists its tools over Streamable HTTP (inference stubbed)", async () => { const stub = { wasm: ctx.wasm, http: { fetch: (url, init) => (url.startsWith("https://inference.test/") ? Response.json({ content: [{ type: "text", text: "-" }], stop_reason: "end_turn" }) : fetch(url, init)) } }; const ran = await runModule(stub, mod, "run", { prompt: "-", endpoint: "https://inference.test", mcp: [{ name: "deepwiki", url: DEEPWIKI }] }, async () => {}, { http: { "https://inference.test": {}, "https://mcp.deepwiki.com": {} }, budget }); const [server] = ran.result.servers; assert.equal(server.phase, "ready", server.error); assert.ok(server.tools.includes("read_wiki_structure"), server.tools.join()); assert.ok(ran.result.tools.includes("deepwiki__read_wiki_structure")); }); test("live inference: the model calls an in-process MCP tool and answers with its result", { skip: noKey }, async () => { const word = `atlibs-${Math.random().toString(36).slice(2, 8)}`; const code = mcpServer({ secret_word: () => ({ content: [{ type: "text", text: word }] }) }); const composition = await loadComposition(ctx, { $type: "com.fedfork.exec.composition", name: "live", instances: [{ name: "agent", module: "asyncai" }], handlers: [{ name: "code" }], edges: [{ from: "agent", nsid: MCP, handler: "code", reason: "the secret word tool" }] }, { load: async () => mod }); const ran = await runCompose(ctx, composition, "agent", "run", { prompt: "Call the tool that gives the secret word, then reply with only that word.", endpoint, model, maxTokens: 2000, mcp: [{ name: "code", hook: MCP }], }, { handlers: { code }, http: http(), budget }); assert.equal(ran.error, undefined); assert.equal(ran.result.error, undefined, ran.result.error); assert.equal(ran.result.stop, "end_turn"); assert.ok(ran.result.steps >= 2); assert.match(ran.result.text, new RegExp(word)); assert.ok(!JSON.stringify(ran).includes(key), "the key never reaches the result"); }); test("live inference + live MCP: the model reads DeepWiki through its tools", { skip: noKey }, async () => { const ran = await runModule(ctx, mod, "run", { prompt: "Use deepwiki__read_wiki_structure on the repository modelcontextprotocol/servers and name two of its topics, briefly.", endpoint, model, maxTokens: 2000, maxSteps: 4, mcp: [{ name: "deepwiki", url: DEEPWIKI }], }, async () => {}, { http: http(), budget }); 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((b) => !b.is_error && b.content.length > 50), JSON.stringify(results).slice(0, 500)); assert.ok(["end_turn", "max_steps"].includes(ran.result.stop)); assert.ok(ran.result.text.length > 0 || ran.result.stop === "max_steps"); }); test("live compaction: a small context window forces a summary mid-run, and the run still finishes the task", { skip: noKey }, async () => { const words = [1, 2, 3].map(() => `w${Math.random().toString(36).slice(2, 8)}`); // each page ~6 KB: past 0.6 of a 5000-token window by the second round const filler = Array.from({ length: 120 }, (_, i) => `line ${i}: nothing to see here, keep reading.`).join("\n"); const code = mcpServer({ page: ({ n }) => ({ content: [{ type: "text", text: `${filler}\nThe secret word of page ${n} is ${words[Number(n) - 1] ?? "none"}.` }] }) }); const composition = await loadComposition(ctx, { $type: "com.fedfork.exec.composition", name: "live", instances: [{ name: "agent", module: "asyncai" }], handlers: [{ name: "code" }], edges: [{ from: "agent", nsid: MCP, handler: "code", reason: "the pages tool" }] }, { load: async () => mod }); const compacting = []; const ran = await runCompose(ctx, composition, "agent", "run", { prompt: "Read page 1, then page 2, then page 3 with the page tool (one call at a time, n is the page number). Then reply with only the three secret words, in page order, separated by spaces.", endpoint, model, maxTokens: 2000, maxSteps: 8, contextWindow: 5000, compactAt: 0.6, mcp: [{ name: "code", hook: MCP }], }, { handlers: { code }, http: http(), budget, onEvent: (_, out) => compacting.push(...(out.calls ?? []).filter((c) => c.id?.startsWith("compact.")).map((c) => c.id)) }); assert.equal(ran.error, undefined); assert.equal(ran.result.error, undefined, ran.result.error); assert.equal(ran.result.stop, "end_turn"); assert.ok(ran.result.compactions >= 1, `compactions ${ran.result.compactions}`); assert.equal(compacting.length, ran.result.compactions); assert.match(ran.result.messages[0].content, /^This session continues an earlier conversation that was compacted/); assert.equal(ran.result.text.trim().split(/\s+/).join(" "), words.join(" "), ran.result.text); assert.ok(!JSON.stringify(ran).includes(key), "the key never reaches the result"); console.log(`compactions ${ran.result.compactions}, steps ${ran.result.steps}, usage ${JSON.stringify(ran.result.usage)}`); }); test("live co/core: the stub model over OpenAI chat completions, authorized by the user's session (no key)", { skip: !(cocoreHandle && cocorePassword) && "no co/core test account" }, async () => { const session = await login({ identifier: cocoreHandle, password: cocorePassword }); // held to the module's own session record (records/asyncai.json): the token's rpc scope const policy = await modulePolicy(ctx, "asyncai", mod, new URL(".", import.meta.url).pathname); const call = sessionCall(policy, "asyncai", hostCall({ ctx, xrpc: session.xrpc })); const http = { "https://cocore.dev": { serviceAuth: { aud: "did:web:cocore.dev", lxm: "dev.cocore.inference.dispatch" } } }; const ran = await runModule(ctx, mod, "run", { prompt: "Say hi.", provider: "openai", model: "stub", maxTokens: 32, mcp: [] }, call, { http, budget }); assert.equal(ran.error, undefined, ran.error); const r = ran.result; if (r.error?.includes("onboarding_required") && process.env.ASYNCAI_COCORE_ONBOARDED !== "1") { // not connected to co/core: the documented answer, reached through a minted token (a bad one is BadJwtAudience) assert.match(r.error, /^inference HTTP 401: .*onboarding_required/); console.log(`co/core: ${cocoreHandle} is not onboarded (onboarding_required)`); return; } assert.equal(r.error, undefined, r.error); assert.equal(r.stop, "end_turn"); assert.ok(r.text.length > 0); console.log(`co/core stub: ${JSON.stringify(r.text).slice(0, 80)}, usage ${JSON.stringify(r.usage)}`); }); test("live dynamic MCP: the model connects a server over a host transport's webrtc:// URL mid-run, then uses its tool", { skip: noKey || (await noFetchers(runModule, ctx, mod)) }, async () => { const word = `atlibs-${Math.random().toString(36).slice(2, 8)}`; const vault = fetcher(streamableHttp(mcpServer({ secret_word: () => ({ content: [{ type: "text", text: word }] }) })).handle); const url = "webrtc:///eyJyZWNlaXB0Ijp7InVyaSI6InIxIn19/shell/mcp"; const server = JSON.stringify({ url }); const ran = await runModule(ctx, mod, "run", { prompt: `Use mcp_connect to connect an MCP server named vault with server ${server}. Then call its secret word tool and reply with only that word.`, endpoint, model, maxTokens: 2000, mcp: [], dynamicMcp: ["webrtc:///"], }, async (nsid) => assert.fail(nsid), { http: { ...http(), "webrtc://*": {} }, fetchers: { "webrtc:": vault.fetch }, budget }); assert.equal(ran.error, undefined); assert.equal(ran.result.error, undefined, ran.result.error); assert.ok(ran.result.steps >= 3, `steps ${ran.result.steps}`); assert.match(ran.result.text, new RegExp(word)); assert.deepEqual(ran.result.servers.map((s) => [s.name, s.phase, s.dynamic]), [["vault", "ready", true]]); assert.ok(ran.result.tools.includes("vault__secret_word")); assert.ok(vault.urls.length >= 4 && vault.urls.every((u) => u === url)); assert.ok(!JSON.stringify(ran).includes(key), "the key never reaches the result"); });