Menu
popagent
publicLatest change 8828a8233b015e0c6e7896c3e9ba8b060bd3ce5c - Add BifrOSt Navigator agent tool by Ólafur Búi Ólafsson
import { createServer } from "node:net";
import { mkdir, mkdtemp, rm } from "node:fs/promises";
import { join } from "node:path";
import { describe, expect, test } from "bun:test";
import { callBifrOSt, createBifrOStTool } from "./bifrost";
const context = (agentId: string) => ({ agent: { agentId }, abortSignal: AbortSignal.timeout(5_000) }) as never;
describe("bifrostNavigator", () => {
test("uses the local Unix bridge and preserves role access", async () => {
await mkdir(".tmp", { recursive: true });
const directory = await mkdtemp(join(process.cwd(), ".tmp", "bifrost-agent-"));
const socketPath = join(directory, "browser.sock");
const server = createServer((socket) => socket.once("data", (data) => {
const request = JSON.parse(data.toString());
socket.end(`${JSON.stringify({
jsonrpc: "2.0",
id: request.id,
result: { content: [{ type: "text", text: JSON.stringify({ title: "BifrOSt Home" }) }] },
})}\n`);
}));
const listening = Promise.withResolvers<void>();
server.listen(socketPath, listening.resolve);
await listening.promise;
try {
expect(await callBifrOSt("browser_current_page", {}, AbortSignal.timeout(5_000), socketPath))
.toEqual({ content: [{ type: "text", text: '{"title":"BifrOSt Home"}' }] });
const tool = createBifrOStTool({
get: async (id: string) => ({ id, browserAccess: id === "researcher" ? "read-only" : "interactive" }),
} as never, async (operation: Parameters<typeof callBifrOSt>[0], args: Record<string, unknown>) => ({ content: [{ type: "text", text: JSON.stringify({ operation, args }) }] }));
await expect(tool.execute?.(
{ operation: "browser_navigate", arguments: { url: "https://example.com" } },
context("researcher"),
)).rejects.toThrow("read-only");
expect(await tool.execute?.(
{ operation: "browser_current_page", arguments: {} },
context("researcher"),
)).toEqual({ content: [{ type: "text", text: '{"operation":"browser_current_page","args":{}}' }] });
} finally {
const closed = Promise.withResolvers<void>();
server.close((error) => error ? closed.reject(error) : closed.resolve());
await closed.promise;
await rm(directory, { recursive: true, force: true });
}
});
});