[claude] Agent commentary during job execution (#1) (#94)

This commit was merged in pull request #94.
This commit is contained in:
2026-03-23 20:41:57 +00:00
parent 82a170da87
commit 2ad3403061
4 changed files with 133 additions and 1 deletions

View File

@@ -257,6 +257,15 @@ function translateEvent(ev: BusEvent): object | null {
isFinal: ev.isFinal,
};
// ── Agent commentary (#1) ─────────────────────────────────────────────────
case "agent_commentary":
return {
type: "agent_commentary",
agentId: ev.agentId,
jobId: ev.jobId,
text: ev.text,
};
default:
return null;
}
@@ -389,5 +398,50 @@ export function attachWebSocketServer(server: Server): void {
});
});
// ── Global commentary listener (set up once per server, not per socket) ────
// Watches job lifecycle events and fires Haiku commentary to all clients.
eventBus.on("bus", (ev: BusEvent) => {
let agentId: string | null = null;
let phase: string | null = null;
let jobId: string | null = null;
if (ev.type === "job:state") {
jobId = ev.jobId;
if (ev.state === "evaluating") {
// Beta evaluating + Alpha routing
void (async () => {
const [betaText, alphaText] = await Promise.all([
agentService.generateCommentary("beta", "evaluating"),
agentService.generateCommentary("alpha", "routing"),
]);
if (betaText) broadcastToAll(wss, { type: "agent_commentary", agentId: "beta", jobId, text: betaText });
if (alphaText) broadcastToAll(wss, { type: "agent_commentary", agentId: "alpha", jobId, text: alphaText });
})();
return;
}
if (ev.state === "executing") {
agentId = "gamma"; phase = "starting";
} else if (ev.state === "complete") {
agentId = "alpha"; phase = "complete";
} else if (ev.state === "rejected") {
agentId = "alpha"; phase = "rejected";
}
} else if (ev.type === "job:paid") {
jobId = ev.jobId;
agentId = "delta";
phase = ev.invoiceType === "eval" ? "eval_paid" : "work_paid";
}
if (agentId && phase && jobId) {
const capturedAgentId = agentId;
const capturedPhase = phase;
const capturedJobId = jobId;
void (async () => {
const text = await agentService.generateCommentary(capturedAgentId, capturedPhase);
if (text) broadcastToAll(wss, { type: "agent_commentary", agentId: capturedAgentId, jobId: capturedJobId, text });
})();
}
});
logger.info("WebSocket server attached at /api/ws");
}