~ knotless Search/
↑↓ move↵ open⇧↵ all results

johnandersen777.bsky.social/atlibs-asyncai

0
0
main
169 lines · 10.9 KB Raw History
// 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");
});