58 lines
2.0 KiB
TypeScript
58 lines
2.0 KiB
TypeScript
|
|
import * as plugins from '../plugins.js';
|
||
|
|
import type { AuditLog } from '../audit/classes.auditlog.js';
|
||
|
|
|
||
|
|
export class ApprovalQueue {
|
||
|
|
private approvals: plugins.shxInterfaces.data.IApprovalRequest[] = [];
|
||
|
|
|
||
|
|
constructor(private auditLog: AuditLog) {}
|
||
|
|
|
||
|
|
public createApproval(optionsArg: {
|
||
|
|
plan: plugins.shxInterfaces.data.IToolPlan;
|
||
|
|
call: plugins.shxInterfaces.data.IToolCall;
|
||
|
|
agentId: string;
|
||
|
|
title: string;
|
||
|
|
reason: string;
|
||
|
|
requestedScopes: plugins.shxInterfaces.data.TToolScope[];
|
||
|
|
}) {
|
||
|
|
const approval: plugins.shxInterfaces.data.IApprovalRequest = {
|
||
|
|
id: `approval:${Date.now()}:${Math.random().toString(36).slice(2)}`,
|
||
|
|
planId: optionsArg.plan.id,
|
||
|
|
callId: optionsArg.call.id,
|
||
|
|
agentId: optionsArg.agentId,
|
||
|
|
title: optionsArg.title,
|
||
|
|
reason: optionsArg.reason,
|
||
|
|
confidence: optionsArg.plan.confidence,
|
||
|
|
requestedScopes: optionsArg.requestedScopes,
|
||
|
|
status: 'pending',
|
||
|
|
createdAt: new Date().toISOString(),
|
||
|
|
};
|
||
|
|
this.approvals.unshift(approval);
|
||
|
|
return approval;
|
||
|
|
}
|
||
|
|
|
||
|
|
public listApprovals(filterArg: { status?: plugins.shxInterfaces.data.IApprovalRequest['status'] } = {}) {
|
||
|
|
return this.approvals.filter((approvalArg) => !filterArg.status || approvalArg.status === filterArg.status);
|
||
|
|
}
|
||
|
|
|
||
|
|
public submitApproval(approvalIdArg: string, decisionArg: 'approved' | 'rejected') {
|
||
|
|
const approval = this.approvals.find((approvalArg) => approvalArg.id === approvalIdArg);
|
||
|
|
if (!approval) {
|
||
|
|
throw new Error(`Approval not found: ${approvalIdArg}`);
|
||
|
|
}
|
||
|
|
if (approval.status !== 'pending') {
|
||
|
|
throw new Error(`Approval already decided: ${approvalIdArg}`);
|
||
|
|
}
|
||
|
|
approval.status = decisionArg;
|
||
|
|
approval.decidedAt = new Date().toISOString();
|
||
|
|
const receipt = this.auditLog.appendReceipt({
|
||
|
|
kind: 'approval',
|
||
|
|
callerId: approval.agentId,
|
||
|
|
approvalId: approval.id,
|
||
|
|
inputSummary: approval.title,
|
||
|
|
outputSummary: decisionArg,
|
||
|
|
reversible: false,
|
||
|
|
});
|
||
|
|
return { approval, receipt };
|
||
|
|
}
|
||
|
|
}
|