吸收数字员工技能调用审计

This commit is contained in:
baiyanyun
2026-06-10 09:24:02 +08:00
parent 91540dec0c
commit cc36d8dcaf
15 changed files with 894 additions and 73 deletions

View File

@@ -2,7 +2,12 @@ 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 {
recordDigitalEmployeeRuntimeEvent,
recordDigitalEmployeeSkillCallAudit,
} from "../services/digitalEmployee/stateService";
import { evaluateDigitalEmployeeSkillCall } from "../services/digitalEmployee/skillExecutionPolicy";
import { mcpProxyManager } from "../services/packages/mcp";
import type { HandlerContext } from "@shared/types/ipc";
import log from "electron-log";
@@ -25,6 +30,42 @@ function readEventField(data: unknown, keys: string[]): string | undefined {
function recordForwardedEvent(eventType: string, data: unknown): void {
const normalized = normalizeForwardedEvent(eventType, data);
recordDigitalEmployeeRuntimeEvent(normalized);
recordSkillCallAuditForForwardedEvent(eventType, data, normalized);
}
function recordSkillCallAuditForForwardedEvent(
eventType: string,
data: unknown,
normalized: Parameters<typeof recordDigitalEmployeeRuntimeEvent>[0],
): void {
const subtype = readEventField(data, ["subType", "sessionUpdate", "type", "messageType"]);
if (eventType !== "computer:progress" || (subtype !== "tool_call" && subtype !== "tool_call_update")) {
return;
}
try {
const toolName = readEventField(data, ["toolTitle", "title", "name", "kind"]);
const policy = evaluateDigitalEmployeeSkillCall({
source: "qimingclaw-acp",
toolName,
callId: readEventField(data, ["toolCallId", "id"]) || `${subtype}:${Date.now()}`,
sessionId: readEventField(data, ["sessionId", "session_id", "id"]),
mcpConfig: mcpProxyManager.getConfig(),
});
recordDigitalEmployeeSkillCallAudit({
callId: readEventField(data, ["toolCallId", "id"]) || `${subtype}:${Date.now()}`,
source: policy.source,
serverId: policy.server_id,
toolName: policy.tool_name || toolName,
skillId: policy.skill_id,
decision: policy.decision,
reasonCodes: policy.reason_codes,
policySnapshot: policy.policy_snapshot,
sessionId: normalized.session_id,
status: readEventField(data, ["status"]) || normalized.status,
});
} catch (error) {
log.warn("[EventForwarders] Failed to record skill call audit:", error);
}
}
function normalizeForwardedEvent(