/** * @file Tests server/lib/omp-usage.js and the omp branch of the transcript * routes — Oh My Pi sessions from omp's session journals: a session created * as `tool = 'omp'` with its title, cwd, model and per-model tokens (its * subagents' included), a subagent row per subagent journal, a journal read on * from where it stopped, `session_exit` settling it to completed, a session * the user deleted staying deleted, a non-omp row with the same id never * touched, and the journal mapped to the Claude transcript shape. The omp dir * and the DB are temp dirs; the journals are synthetic, in the shape omp * 18.12 writes. * @author Nguyễn Ngọc Trí Vĩ */ const os = require("node:os"); const fs = require("node:fs"); const path = require("node:path"); const ROOT = fs.mkdtempSync(path.join(os.tmpdir(), "agenthub-omp-usage-")); process.env.DASHBOARD_DB_PATH = path.join(ROOT, "dashboard.db"); process.env.CLAUDE_HOME = path.join(ROOT, "claude"); process.env.AGENTHUB_OMP_DIR = path.join(ROOT, "omp"); const { describe, it, before, after } = require("node:test"); const assert = require("node:assert/strict"); const { db } = require("../db"); const omp = require("../lib/omp-usage"); const { createApp, startServer } = require("../index"); const ID = "01a15366-27e2-734a-9247-04d5c65c1636"; const STAMP = "2026-10-19T09-02-46-242Z"; const CWD = path.join(fs.realpathSync(ROOT), "work"); fs.mkdirSync(CWD, { recursive: true }); const DIR = path.join(process.env.AGENTHUB_OMP_DIR, "agent", "sessions", "-work"); const MAIN = path.join(DIR, `${STAMP}_${ID}.jsonl`); const SUB = path.join(DIR, `${STAMP}_${ID}`, "Pinger.jsonl"); let server; let BASE; after(() => { server?.close(); fs.rmSync(ROOT, { recursive: true, force: true }); }); const line = (o) => JSON.stringify(o) + "\n"; const title = (t) => line({ type: "title", v: 1, title: t, updatedAt: "2026-10-19T09:02:46.242Z", pad: " ".repeat(40) }); const header = (id = ID) => line({ type: "session", version: 3, id, timestamp: "2026-10-19T09:02:46.242Z", cwd: CWD }); const user = (text, attribution = "user") => line({ type: "message", id: "u1", timestamp: "2026-10-19T09:02:46.400Z", message: { role: "user", content: [{ type: "text", text }], attribution }, }); const assistant = (content, usage, model = "claude-sonnet-4-5") => line({ type: "message", id: "a1", timestamp: "2026-10-19T09:02:47.000Z", message: { role: "assistant", content, provider: "anthropic", model, usage }, }); const usage = (input, output, cacheRead = 0, cacheWrite = 0) => ({ input, output, cacheRead, cacheWrite, totalTokens: input + output + cacheRead + cacheWrite, }); const exit = line({ type: "custom", customType: "session_exit", data: { reason: "dispose" } }); const sessionRow = () => db.prepare("SELECT * FROM sessions WHERE id = ?").get(ID); const tokens = () => db .prepare( "SELECT model, input_tokens, output_tokens, cache_read_tokens, cache_write_tokens FROM token_usage WHERE session_id = ? ORDER BY model" ) .all(ID); before(async () => { fs.mkdirSync(path.dirname(SUB), { recursive: true }); fs.writeFileSync( MAIN, title("") + header() + line({ type: "model_change", model: "anthropic/claude-sonnet-4-5" }) + user("Fix the login bug\nin auth.ts") + assistant( [ { type: "thinking", thinking: "Look first" }, { type: "toolCall", id: "t1", name: "task", arguments: { tasks: [{ task: "ping" }] } }, ], usage(100, 20, 1000, 50) ) + line({ type: "message", timestamp: "2026-10-19T09:02:48.000Z", message: { role: "toolResult", toolCallId: "t1", toolName: "task", content: [{ type: "text", text: "Spawned agent `Pinger`." }], }, }) ); fs.writeFileSync( SUB, header("01a15366-0000-7000-8000-000000000001") + user("Complete assignment: ping", "agent") + assistant([{ type: "text", text: "pong" }], usage(10, 5), "claude-haiku-4-5") ); server = await startServer(createApp(), 0); BASE = `http://127.0.0.1:${server.address().port}`; }); describe("omp usage ingest", () => { it("creates the session with its prompt, cwd, model and every journal's tokens", async () => { const r = await omp.ingestOmpUsage(); assert.equal(r.files, 2); const s = sessionRow(); assert.equal(s.tool, "omp"); assert.equal(s.name, "Fix the login bug"); assert.equal(s.cwd, CWD); assert.equal(s.model, "claude-sonnet-4-5"); assert.equal(s.status, "active"); // written just now, no session_exit assert.deepEqual(tokens(), [ { model: "claude-haiku-4-5", input_tokens: 10, output_tokens: 5, cache_read_tokens: 0, cache_write_tokens: 0, }, { model: "claude-sonnet-4-5", input_tokens: 100, output_tokens: 20, cache_read_tokens: 1000, cache_write_tokens: 50, }, ]); const agents = db.prepare("SELECT * FROM agents WHERE session_id = ?").all(ID); assert.equal(agents.length, 1); assert.equal(agents[0].id, `omp-${ID}-Pinger`); assert.equal(agents[0].name, "Pinger"); assert.equal(agents[0].type, "subagent"); assert.equal(agents[0].task, "Complete assignment: ping"); }); it("leaves an unchanged journal unread", async () => { const r = await omp.ingestOmpUsage(); assert.equal(r.files, 0); }); it("reads only what was appended, takes the title, and settles on session_exit", async () => { fs.appendFileSync(MAIN, assistant([{ type: "text", text: "Done" }], usage(5, 7)) + exit); // The title slot is rewritten in place, same width. const text = fs.readFileSync(MAIN, "utf8").split("\n"); const slot = { type: "title", v: 1, title: "Login fix", updatedAt: "x", pad: "" }; slot.pad = " ".repeat(Math.max(0, text[0].length - JSON.stringify(slot).length)); text[0] = JSON.stringify(slot); fs.writeFileSync(MAIN, text.join("\n")); const r = await omp.ingestOmpUsage(); assert.equal(r.files, 1); const s = sessionRow(); assert.equal(s.name, "Login fix"); assert.equal(s.status, "completed"); assert.ok(s.ended_at); const sonnet = tokens().find((t) => t.model === "claude-sonnet-4-5"); assert.equal(sonnet.input_tokens, 105); assert.equal(sonnet.output_tokens, 27); const agent = db.prepare("SELECT status FROM agents WHERE id = ?").get(`omp-${ID}-Pinger`); assert.equal(agent.status, "completed"); }); it("maps the journal to the transcript shape, and lists the subagent's", async () => { const list = await (await fetch(`${BASE}/api/sessions/${ID}/transcripts`)).json(); assert.deepEqual( list.transcripts.map((t) => [t.id, t.type, t.db_agent_id]), [ ["main", "main", null], ["Pinger", "subagent", `omp-${ID}-Pinger`], ] ); const body = await (await fetch(`${BASE}/api/sessions/${ID}/transcript`)).json(); assert.deepEqual( body.messages.map((m) => [m.type, m.sender, m.content.map((c) => c.type).join("+")]), [ ["user", "user", "text"], ["assistant", "assistant", "thinking+tool_use"], ["user", "tool", "tool_result"], ["assistant", "assistant", "text"], ] ); assert.deepEqual(body.messages[1].content[1], { type: "tool_use", name: "task", id: "t1", input: { tasks: [{ task: "ping" }] }, }); const sub = await ( await fetch(`${BASE}/api/sessions/${ID}/transcript?agent_id=Pinger`) ).json(); assert.deepEqual( sub.messages.map((m) => [m.sender, m.content[0].text]), [ ["orchestrator", "Complete assignment: ping"], ["assistant", "pong"], ] ); }); it("keeps a deleted session deleted until omp writes again", async () => { db.prepare("DELETE FROM sessions WHERE id = ?").run(ID); await omp.ingestOmpUsage(); assert.equal(sessionRow(), undefined); fs.appendFileSync(MAIN, user("one more")); await omp.ingestOmpUsage(); assert.equal(sessionRow()?.tool, "omp"); }); it("never touches another tool's session with the same id", async () => { const other = "01a15366-27e2-734a-9247-04d5c65c9999"; db.prepare("INSERT INTO sessions (id, name, status, tool) VALUES (?, 'mine', 'completed', 'codex')").run( other ); fs.writeFileSync(path.join(DIR, `${STAMP}_${other}.jsonl`), title("") + header(other) + user("x")); await omp.ingestOmpUsage(); const s = db.prepare("SELECT * FROM sessions WHERE id = ?").get(other); assert.equal(s.tool, "codex"); assert.equal(s.name, "mine"); }); });