吸收数字员工技能调用审计
This commit is contained in:
@@ -655,6 +655,10 @@ export async function handleQimingclawDigitalApi<T>(
|
||||
const rows = filterDailyReportRows(dailyReportRows(await readQimingclawSnapshot()), url.searchParams);
|
||||
return { ...paginateBusinessRows(rows, url.searchParams), source: BUSINESS_VIEW_SOURCE } as T;
|
||||
}
|
||||
if (method === 'GET' && pathname === '/api/digital-employee/skill-call-audits') {
|
||||
const rows = filterSkillCallAuditRows(skillCallAuditRows(await readQimingclawSnapshot()), url.searchParams);
|
||||
return { ...paginateBusinessRows(rows, url.searchParams), source: BUSINESS_VIEW_SOURCE } as T;
|
||||
}
|
||||
const businessPlanDetailMatch = pathname.match(/^\/api\/digital-employee\/plans\/([^/]+)$/);
|
||||
if (method === 'GET' && businessPlanDetailMatch) {
|
||||
const planId = decodeURIComponent(businessPlanDetailMatch[1] || '');
|
||||
@@ -2324,6 +2328,46 @@ function businessApprovalRows(snapshot: QimingclawSnapshot | null): BusinessView
|
||||
});
|
||||
}
|
||||
|
||||
function skillCallAuditRows(snapshot: QimingclawSnapshot | null): BusinessViewRow[] {
|
||||
return runtimeEvents(snapshot)
|
||||
.filter((event) => ['skill_call_allowed', 'skill_call_rejected', 'skill_call_observed'].includes(event.kind))
|
||||
.map((event) => {
|
||||
const payload = asRecord(event.payload) ?? {};
|
||||
return {
|
||||
audit_id: event.id,
|
||||
event_id: event.id,
|
||||
remote_id: event.remoteId ?? null,
|
||||
decision: stringValue(payload.decision) || event.kind.replace('skill_call_', ''),
|
||||
source: stringValue(payload.source) || null,
|
||||
server_id: stringValue(payload.server_id) || null,
|
||||
tool_name: stringValue(payload.tool_name) || null,
|
||||
skill_id: stringValue(payload.skill_id) || null,
|
||||
call_id: stringValue(payload.call_id) || null,
|
||||
session_id: stringValue(payload.session_id) || null,
|
||||
task_id: (event.taskId ?? stringValue(payload.task_id)) || null,
|
||||
run_id: (event.runId ?? stringValue(payload.run_id)) || null,
|
||||
reason_codes: Array.isArray(payload.reason_codes) ? payload.reason_codes : [],
|
||||
message: event.message,
|
||||
occurred_at: event.occurredAt,
|
||||
sync_status: event.syncStatus ?? null,
|
||||
payload,
|
||||
};
|
||||
})
|
||||
.sort((left, right) => stringValue(right.occurred_at).localeCompare(stringValue(left.occurred_at)));
|
||||
}
|
||||
|
||||
function filterSkillCallAuditRows(rows: BusinessViewRow[], searchParams: URLSearchParams): BusinessViewRow[] {
|
||||
const skillId = stringValue(searchParams.get('skill_id'));
|
||||
const serverId = stringValue(searchParams.get('server_id'));
|
||||
const toolName = stringValue(searchParams.get('tool_name'));
|
||||
const decision = stringValue(searchParams.get('decision'));
|
||||
return rows
|
||||
.filter((row) => !skillId || stringValue(row.skill_id) === skillId)
|
||||
.filter((row) => !serverId || stringValue(row.server_id) === serverId)
|
||||
.filter((row) => !toolName || stringValue(row.tool_name) === toolName)
|
||||
.filter((row) => !decision || stringValue(row.decision) === decision);
|
||||
}
|
||||
|
||||
function dailyReportRows(snapshot: QimingclawSnapshot | null): BusinessViewRow[] {
|
||||
return buildArtifacts(snapshot)
|
||||
.filter(isDailyReportArtifact)
|
||||
|
||||
Reference in New Issue
Block a user