Menu
popagent
publicLatest change 248b7c0673ea9d544f9e4738ee4d3e8ec2925924 - Add native BifrOSt Navigator browser provider with per-browser status LEDs by AkurAI Build
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, listBifrOStTools, pingBifrOSt } 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: request.method === "ping"
? {}
: request.method === "tools/list"
? { tools: [{ name: "browser_current_page" }, { name: "browser_navigate" }] }
: { 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"}' }] });
await expect(pingBifrOSt(AbortSignal.timeout(5_000), socketPath)).resolves.toBeUndefined();
await expect(pingBifrOSt(AbortSignal.timeout(5_000), join(directory, "missing.sock"))).rejects.toThrow();
expect(await listBifrOStTools(AbortSignal.timeout(5_000), socketPath)).toEqual(["browser_current_page", "browser_navigate"]);
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 });
}
});
});