feat(client): mirror agent events to digital employee
This commit is contained in:
@@ -2,6 +2,7 @@ import { agentService } from "../services/engines/unifiedAgent";
|
||||
import type { UnifiedSessionMessage } from "../services/engines/unifiedAgent";
|
||||
import { pushSseEvent } from "../services/computerServer";
|
||||
import { firstTokenTrace } from "../services/engines/perf/firstTokenTrace";
|
||||
import { recordDigitalEmployeeRuntimeEvent } from "../services/digitalEmployee/stateService";
|
||||
import type { HandlerContext } from "@shared/types/ipc";
|
||||
import log from "electron-log";
|
||||
|
||||
@@ -11,6 +12,34 @@ const registeredHandlers: Array<{
|
||||
handler: (...args: any[]) => void;
|
||||
}> = [];
|
||||
|
||||
function readEventField(data: unknown, keys: string[]): string | undefined {
|
||||
if (!data || typeof data !== "object") return undefined;
|
||||
const record = data as Record<string, unknown>;
|
||||
for (const key of keys) {
|
||||
const value = record[key];
|
||||
if (typeof value === "string" && value.trim()) return value;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function recordForwardedEvent(eventType: string, data: unknown): void {
|
||||
recordDigitalEmployeeRuntimeEvent({
|
||||
kind: eventType,
|
||||
message:
|
||||
readEventField(data, ["message", "description", "title", "subType"]) ||
|
||||
eventType,
|
||||
request_id: readEventField(data, ["requestId", "request_id"]),
|
||||
session_id: readEventField(data, ["sessionId", "session_id", "id"]),
|
||||
project_id: readEventField(data, ["projectId", "project_id"]),
|
||||
status: eventType.includes("error")
|
||||
? "failed"
|
||||
: eventType.includes("idle") || eventType.includes("promptEnd")
|
||||
? "completed"
|
||||
: "running",
|
||||
payload: data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister all event forwarders from agentService.
|
||||
* Call before re-registering or during cleanup.
|
||||
@@ -65,6 +94,7 @@ export function registerEventForwarders(ctx: HandlerContext): void {
|
||||
type: eventType,
|
||||
data,
|
||||
});
|
||||
recordForwardedEvent(eventType, data);
|
||||
};
|
||||
agentService.on(eventType, handler);
|
||||
registeredHandlers.push({ event: eventType, handler });
|
||||
@@ -75,6 +105,12 @@ export function registerEventForwarders(ctx: HandlerContext): void {
|
||||
type: "error",
|
||||
data: { message: error.message },
|
||||
});
|
||||
recordDigitalEmployeeRuntimeEvent({
|
||||
kind: "agent_error",
|
||||
message: error.message,
|
||||
status: "failed",
|
||||
payload: { message: error.message },
|
||||
});
|
||||
};
|
||||
agentService.on("error", errorHandler);
|
||||
registeredHandlers.push({ event: "error", handler: errorHandler });
|
||||
@@ -84,6 +120,11 @@ export function registerEventForwarders(ctx: HandlerContext): void {
|
||||
type: "ready",
|
||||
data: {},
|
||||
});
|
||||
recordDigitalEmployeeRuntimeEvent({
|
||||
kind: "agent_ready",
|
||||
message: "Agent service ready",
|
||||
status: "running",
|
||||
});
|
||||
};
|
||||
agentService.on("ready", readyHandler);
|
||||
registeredHandlers.push({ event: "ready", handler: readyHandler });
|
||||
@@ -93,6 +134,11 @@ export function registerEventForwarders(ctx: HandlerContext): void {
|
||||
type: "destroyed",
|
||||
data: {},
|
||||
});
|
||||
recordDigitalEmployeeRuntimeEvent({
|
||||
kind: "agent_destroyed",
|
||||
message: "Agent service destroyed",
|
||||
status: "completed",
|
||||
});
|
||||
};
|
||||
agentService.on("destroyed", destroyedHandler);
|
||||
registeredHandlers.push({ event: "destroyed", handler: destroyedHandler });
|
||||
@@ -105,6 +151,7 @@ export function registerEventForwarders(ctx: HandlerContext): void {
|
||||
JSON.stringify(data).substring(0, 200),
|
||||
);
|
||||
ctx.getMainWindow()?.webContents.send("computer:progress", data);
|
||||
recordForwardedEvent("computer:progress", data);
|
||||
const d = data as UnifiedSessionMessage;
|
||||
if (d?.sessionId) {
|
||||
// sessionId is now the ACP protocol UUID — same as acpSessionId
|
||||
@@ -139,6 +186,14 @@ export function registerEventForwarders(ctx: HandlerContext): void {
|
||||
timestamp: new Date().toISOString(),
|
||||
};
|
||||
ctx.getMainWindow()?.webContents.send("computer:progress", event);
|
||||
recordDigitalEmployeeRuntimeEvent({
|
||||
kind: "computer_prompt_start",
|
||||
message: "Computer prompt started",
|
||||
request_id: data.requestId,
|
||||
session_id: data.sessionId,
|
||||
status: "running",
|
||||
payload: event,
|
||||
});
|
||||
pushSseEvent(data.sessionId, "prompt_start", event);
|
||||
};
|
||||
agentService.on("computer:promptStart", promptStartHandler);
|
||||
@@ -166,6 +221,13 @@ export function registerEventForwarders(ctx: HandlerContext): void {
|
||||
timestamp: new Date().toISOString(),
|
||||
};
|
||||
ctx.getMainWindow()?.webContents.send("computer:progress", event);
|
||||
recordDigitalEmployeeRuntimeEvent({
|
||||
kind: "computer_prompt_end",
|
||||
message: data.description || data.reason || "Computer prompt ended",
|
||||
session_id: data.sessionId,
|
||||
status: data.reason === "error" ? "failed" : "completed",
|
||||
payload: event,
|
||||
});
|
||||
pushSseEvent(data.sessionId, data.reason || "end_turn", event);
|
||||
};
|
||||
agentService.on("computer:promptEnd", promptEndHandler);
|
||||
|
||||
Reference in New Issue
Block a user