feat(client): project managed services to digital employee

This commit is contained in:
baiyanyun
2026-06-08 11:40:03 +08:00
parent 8dc9ce73b9
commit 710bf72353
9 changed files with 406 additions and 146 deletions

View File

@@ -14,6 +14,7 @@ import {
readDigitalEmployeeState,
readDigitalEmployeeUiState,
saveDigitalEmployeeUiState,
type DigitalEmployeeManagedService,
type DigitalEmployeeGovernanceCommandRecord,
type DigitalEmployeeServiceStatus,
type DigitalEmployeeSnapshot,
@@ -84,19 +85,22 @@ export function registerDigitalEmployeeHandlers(ctx: HandlerContext): void {
function buildSnapshot(ctx: HandlerContext): DigitalEmployeeSnapshot {
const sessions = agentService.listAllSessionsDetailed();
return {
generatedAt: new Date().toISOString(),
services: {
agent: {
running: agentService.isReady,
engineType: agentService.getEngineType(),
},
mcp: normalizeServiceStatus(mcpProxyManager.getStatus()),
computerServer: normalizeServiceStatus(getComputerServerStatus()),
lanproxy: normalizeServiceStatus(ctx.lanproxy.status()),
fileServer: normalizeServiceStatus(ctx.fileServer.status()),
guiServer: normalizeServiceStatus(getGuiStatus()),
const generatedAt = new Date().toISOString();
const services = {
agent: {
running: agentService.isReady,
engineType: agentService.getEngineType(),
},
mcp: normalizeServiceStatus(mcpProxyManager.getStatus()),
computerServer: normalizeServiceStatus(getComputerServerStatus()),
lanproxy: normalizeServiceStatus(ctx.lanproxy.status()),
fileServer: normalizeServiceStatus(ctx.fileServer.status()),
guiServer: normalizeServiceStatus(getGuiStatus()),
} satisfies Record<string, DigitalEmployeeServiceStatus | null>;
return {
generatedAt,
services,
managedServices: buildManagedServices(services, generatedAt),
sessions: {
total: sessions.length,
active: sessions.filter((session) =>
@@ -107,6 +111,93 @@ function buildSnapshot(ctx: HandlerContext): DigitalEmployeeSnapshot {
};
}
function buildManagedServices(
services: Record<string, DigitalEmployeeServiceStatus | null>,
generatedAt: string,
): DigitalEmployeeManagedService[] {
return MANAGED_SERVICE_DEFINITIONS.map((definition) => {
const status = services[definition.serviceId] ?? { running: false };
const error = status.error ?? null;
const running = status.running === true;
const state = error ? "degraded" : running ? "running" : "stopped";
return {
serviceId: definition.serviceId,
name: definition.name,
kind: definition.kind,
status: state,
statusLabel: state === "running" ? "运行中" : state === "degraded" ? "异常" : "未运行",
running,
error,
requiresHumanAction: Boolean(error || (!running && definition.required)),
dependentTasks: definition.dependentTasks,
restartCount: 0,
lastSeenAt: generatedAt,
instance: {
pid: status.pid,
port: status.port,
engineType: status.engineType,
serverCount: status.serverCount,
serverNames: status.serverNames,
},
lease: {
state: state === "running" ? "active" : state,
updatedAt: generatedAt,
},
};
});
}
const MANAGED_SERVICE_DEFINITIONS: Array<{
serviceId: string;
name: string;
kind: DigitalEmployeeManagedService["kind"];
required: boolean;
dependentTasks: string[];
}> = [
{
serviceId: "agent",
name: "Agent",
kind: "agent",
required: true,
dependentTasks: ["ACP 会话执行", "Plan Agent", "Task Agent"],
},
{
serviceId: "mcp",
name: "MCP Proxy",
kind: "mcp",
required: true,
dependentTasks: ["Skill Catalog", "MCP 工具调用"],
},
{
serviceId: "computerServer",
name: "Computer Server",
kind: "desktop",
required: true,
dependentTasks: ["/computer/chat", "远程任务接入"],
},
{
serviceId: "fileServer",
name: "File Server",
kind: "file",
required: false,
dependentTasks: ["Artifact 上传", "文件交付"],
},
{
serviceId: "lanproxy",
name: "Lanproxy",
kind: "network",
required: false,
dependentTasks: ["远程访问", "管理端回连"],
},
{
serviceId: "guiServer",
name: "GUI Agent Server",
kind: "gui",
required: false,
dependentTasks: ["GUI 自动化", "桌面操作"],
},
];
function normalizeServiceStatus(
value: object | null | undefined,
): DigitalEmployeeServiceStatus {

View File

@@ -26,9 +26,35 @@ export interface DigitalEmployeeSessionSummary {
}>;
}
export interface DigitalEmployeeManagedService {
serviceId: string;
name: string;
kind: "agent" | "mcp" | "desktop" | "network" | "file" | "gui" | "unknown";
status: "running" | "stopped" | "degraded";
statusLabel: string;
running: boolean;
error?: string | null;
requiresHumanAction: boolean;
dependentTasks: string[];
restartCount: number;
lastSeenAt: string;
instance: {
pid?: number;
port?: number;
engineType?: string | null;
serverCount?: number;
serverNames?: string[];
};
lease: {
state: "active" | "stopped" | "degraded";
updatedAt: string;
};
}
export interface DigitalEmployeeSnapshot {
generatedAt: string;
services: Record<string, DigitalEmployeeServiceStatus | null>;
managedServices?: DigitalEmployeeManagedService[];
sessions: DigitalEmployeeSessionSummary;
}