1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
// 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");
});