@sema-agent/core
Version:
Stateless, task-oriented AI agent core
28 lines (27 loc) • 1.68 kB
JavaScript
export const PAUSE_REGISTRY = {
human: { pending: "tool_approval", resume: "policy_ask", facet: "A", taskStatus: "suspended", terminal: false },
irreversible_ask: { pending: "tool_approval", resume: "policy_ask", facet: "A", taskStatus: "suspended", terminal: false },
resource_limit: { pending: "resource_limit", resume: "resource_limit", facet: "B", taskStatus: "suspended", terminal: false },
needs_review: { pending: "review", resume: "dry_run_review", facet: "B", taskStatus: "needs_review", terminal: false },
plan_review: { pending: "plan_review", resume: "plan_review", facet: "B", taskStatus: "needs_review", terminal: false },
task_done: { pending: "task_done", resume: "task_done", facet: "-", taskStatus: "suspended", terminal: true },
};
export function isGateKind(v) {
return typeof v === "string" && Object.prototype.hasOwnProperty.call(PAUSE_REGISTRY, v);
}
export function resumeGateMatches(gateKind, outcomeGate) {
return outcomeGate === "wake" || PAUSE_REGISTRY[gateKind].resume === outcomeGate;
}
export function pauseOf(gate, pendingAction) {
if (!isGateKind(gate.kind))
throw new Error(`checkpoint gate kind "${String(gate.kind)}" is not a registered pause`);
const expected = PAUSE_REGISTRY[gate.kind].pending;
if (pendingAction.kind !== expected) {
throw new Error(`a "${gate.kind}" checkpoint carries a "${String(pendingAction.kind)}" pending action — the pause registry pairs it with "${expected}"`);
}
return { gate, pendingAction };
}
export function checkpointFrom(fields) {
const { gate, pendingAction, ...row } = fields;
return { ...row, ...pauseOf(gate, pendingAction) };
}