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

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

@@ -83,6 +83,9 @@ import { ACP_ABORT_TIMEOUT, ACP_PROMPT_TIMEOUT } from "@shared/constants";
import { APP_DATA_DIR_NAME } from "../../constants";
import { perfEmitter } from "../perf/perfEmitter";
import { firstTokenTrace } from "../perf/firstTokenTrace";
import { mcpProxyManager } from "../../packages/mcp";
import { evaluateDigitalEmployeeSkillCall } from "../../digitalEmployee/skillExecutionPolicy";
import { recordDigitalEmployeeSkillCallAudit } from "../../digitalEmployee/stateService";
/** Safe JSON.stringify that handles circular references */
function safeStringify(obj: unknown): string {
@@ -2418,6 +2421,38 @@ User question: ${request.prompt}`;
return { outcome: { outcome: "cancelled" } };
}
const skillPolicy = evaluateDigitalEmployeeSkillCall({
source: "qimingclaw-acp-permission",
toolName: params.toolCall.title || params.toolCall.kind || null,
callId: params.toolCall.toolCallId,
sessionId: acpSessionId,
mcpConfig: mcpProxyManager.getConfig(),
});
recordDigitalEmployeeSkillCallAudit({
callId: params.toolCall.toolCallId,
source: skillPolicy.source,
serverId: skillPolicy.server_id,
toolName: skillPolicy.tool_name || params.toolCall.title || params.toolCall.kind || null,
skillId: skillPolicy.skill_id,
decision: skillPolicy.decision,
reasonCodes: skillPolicy.reason_codes,
policySnapshot: skillPolicy.policy_snapshot,
sessionId: acpSessionId,
status: "permission_request",
message: skillPolicy.decision === "rejected"
? `技能权限请求已拒绝:${params.toolCall.title || params.toolCall.kind || "unknown"}`
: `技能权限请求已审计:${params.toolCall.title || params.toolCall.kind || "unknown"}`,
});
if (skillPolicy.decision === "rejected") {
log.warn(`${this.logTag} 🚫 Skill policy rejected permission request`, {
toolCallId: params.toolCall.toolCallId,
toolTitle: params.toolCall.title,
reasonCodes: skillPolicy.reason_codes,
skillId: skillPolicy.skill_id,
});
return { outcome: { outcome: "cancelled" } };
}
const strictEnabled = this.isStrictSandboxActiveForQimingCode();
const strictCheck = evaluateStrictWritePermission(params, {
strictEnabled,