johnandersen777.bsky.social/atlibs-agents
agents and atirc modules for atlibs: launch agents from a composition, chat on atirc; pages and the agents service
0
0
import assert from "node:assert/strict";
import { test } from "node:test";
import { did, load, now } from "../../../atlibs/rust/src/harness.mjs";
import { runModule } from "../../../atlibs/javascript/src/run-module/index.js";
const url = new URL("../../target/wasm32-unknown-unknown/release/atirc.wasm", import.meta.url);
const { module, run, handle } = await load(url);
const start = (fields) => ({ did, now, ...fields, state: null, event: { type: "start" } });
// handle(), answering every call with answer(call) and recording { nsid, params, input, proxy }.
async function recorded(entry, input, answer) {
const calls = [];
const ran = await handle(entry, input, { respond: ({ nsid, params, input, proxy }) => (calls.push({ nsid, ...(params && { params }), ...(input && { input }), ...(proxy && { proxy }) }), answer()) });
return { ...ran, calls };
}
const ENTRIES = ["read", "post", "irc_post"];
const PROXY = "did:web:irc.fedfork.com#atirc";
const channel = "#alice_bsky_social";
const message = (seq, text = `line ${seq}`) => ({ seq, channel, did, nick: "alice", text, ts: "2026-11-08T00:00:00Z", source: "xrpc" });
test("module has no imports and exports the ABI", () => {
assert.equal(WebAssembly.Module.imports(module).length, 0);
const names = WebAssembly.Module.exports(module).map((e) => e.name);
for (const name of ["memory", "alloc", ...ENTRIES]) assert.ok(names.includes(name), name);
});
test("read defaults to the handle channel and pages through atirc via the proxy", async () => {
const pages = [
{ messages: Array.from({ length: 200 }, (_, i) => message(i + 1)), cursor: 200 },
{ messages: [message(201), message(202)], cursor: 202 },
];
const ran = await recorded("read", { handle: "Alice.bsky.social", limit: 3 }, () => ({ ok: true, output: pages.shift() }));
assert.deepEqual(ran.calls[0], { nsid: "chat.atirc.list", params: { channel, limit: "200", cursor: "0" }, proxy: PROXY });
assert.equal(ran.calls[1].params.cursor, "200");
assert.deepEqual(ran.result, { channel, messages: [message(200), message(201), message(202)], cursor: 202, more: false });
});
test("read stops after six full pages and says there is more", async () => {
let seq = 0;
const ran = await recorded("read", { channel: "#x", cursor: 7 }, () => ({ ok: true, output: { messages: Array.from({ length: 200 }, () => message(++seq)), cursor: seq } }));
assert.equal(ran.calls.length, 6);
assert.equal(ran.calls[0].params.cursor, "7");
assert.equal(ran.result.more, true);
assert.equal(ran.result.cursor, 1200);
assert.equal(ran.result.messages.length, 50);
});
test("read needs a channel or handle, and a valid channel", () => {
assert.match(run("read", start({})).error, /channel or handle/);
assert.match(run("read", start({ channel: "no-hash" })).error, /channel must be/);
assert.match(run("read", start({ channel: "#a b" })).error, /channel must be/);
});
test("post sends one proxied chat.atirc.post and returns the message", async () => {
const ran = await recorded("post", { channel: "#atirc", text: " hi ", nick: "" }, () => ({ ok: true, output: message(9, "hi") }));
assert.deepEqual(ran.calls, [{ nsid: "chat.atirc.post", input: { text: "hi", channel: "#atirc" }, proxy: PROXY }]);
assert.deepEqual(ran.result, message(9, "hi"));
assert.deepEqual(run("post", start({ text: "x" })).calls[0].input, { text: "x" });
});
test("post rejects empty text and surfaces a failed call", async () => {
assert.match(run("post", start({ text: " " })).error, /text is required/);
assert.match((await recorded("post", { text: "x" }, () => ({ ok: false, error: "Forbidden: channel is bound to another handle" }))).error, /Forbidden/);
});
// The host side of `proxy`: runModule validates it and hands it to call().
test("runModule passes proxy to call and rejects a malformed one", async () => {
const ctx = { wasm: { run: async ({ entry, input }) => run(entry, input) } };
const seen = [];
const ran = await runModule(ctx, { module, calls: ["chat.atirc.post"] }, "post", { did, text: "hi" }, async (nsid, request) => {
seen.push([nsid, request]);
return message(1, "hi");
});
assert.deepEqual(seen.map(([nsid, { params, input, proxy }]) => [nsid, { params, input, proxy }]), [["chat.atirc.post", { params: undefined, input: { text: "hi" }, proxy: PROXY }]]);
assert.equal(ran.result.seq, 1);
const bad = { wasm: { run: async ({ input }) => (input.event.type === "start" ? { calls: [{ id: "x", nsid: "chat.atirc.post", proxy: "https://evil" }] } : { result: input.event, done: true }) } };
const refused = await runModule(bad, { module }, "post", { did }, async () => ({}));
assert.match(refused.result.error, /proxy must be did#service/);
});
const b64url = (o) => Buffer.from(JSON.stringify(o)).toString("base64url");
const token = `${b64url({ alg: "ES256" })}.${b64url({ endpoint: "endpointabc", handle: "alice.bsky.social", nick: "alice-bot" })}.sig`;
test("irc_post plans one iroh atirc/irc/1 exchange from the token's endpoint claim", async () => {
const welcome = ":irc.fedfork.com 001 alice-bot :Welcome\r\n:alice-bot!alice-bot@x JOIN #alice_bsky_social\r\nERROR :Closing link\r\n";
const ran = await recorded("irc_post", { token, text: "hi" }, () => ({ ok: true, output: { output: welcome } }));
assert.deepEqual(ran.calls, [{
nsid: "com.fedfork.exec.iroh.connect",
input: {
ticket: "endpointabc",
alpn: "atirc/irc/1",
send: `PASS ${token}\r\nNICK alice-bot\r\nUSER alice-bot 0 * :alice-bot\r\nJOIN #alice_bsky_social\r\nPRIVMSG #alice_bsky_social :hi\r\nQUIT :done\r\n`,
},
}]);
assert.deepEqual(ran.result, { channel: "#alice_bsky_social", nick: "alice-bot", transport: "iroh", alpn: "atirc/irc/1" });
});
test("irc_post surfaces refusals and rejects bad input before any call", async () => {
const reply = (output) => () => ({ ok: true, output: { output } });
assert.match((await recorded("irc_post", { token, text: "hi" }, reply(":s 433 * alice-bot :Nickname is already in use\r\n"))).error, /refused: .*433/);
assert.match((await recorded("irc_post", { token, text: "hi" }, reply("ERROR :bad token\r\n"))).error, /not registered: ERROR/);
assert.match((await recorded("irc_post", { token, text: "hi", nick: "other" }, reply(":s 001 other :w\r\n"))).error, /did not join/);
assert.match(run("irc_post", start({ text: "hi" })).error, /token/);
assert.match(run("irc_post", start({ token: "nope", text: "hi" })).error, /JWT/);
assert.match(run("irc_post", start({ token, text: "a\nQUIT" })).error, /one line/);
assert.match(run("irc_post", start({ token, text: "hi", nick: "a b" })).error, /one word/);
assert.equal(run("irc_post", start({ token, text: "hi", channel: "#x" })).state.channel, "#x");
});