@sema-agent/core
Version:
Stateless, task-oriented AI agent core
46 lines (45 loc) • 1.95 kB
JavaScript
import {} from "./ask-origin.js";
export const EXECUTION_OUTCOME_RECORD_WORDS = Object.freeze(["recorded", "already_recorded", "not_resolved", "absent"]);
export const EXECUTION_RECORD_LEAVES_ROW_UNRECORDED = {
recorded: false,
already_recorded: false,
not_resolved: true,
absent: true,
};
export class ExecutionOutcomeConflictError extends Error {
code = "checkpoint.execution_outcome_conflict";
recorded;
attempted;
constructor(recorded, attempted) {
super("the checkpoint already carries an execution outcome that differs from the one being recorded — the record is immutable, so this is an engine defect (one decided action settled twice), not a retry");
this.name = "ExecutionOutcomeConflictError";
this.recorded = structuredClone(recorded);
this.attempted = structuredClone(attempted);
}
}
export function checkpointExecutionRecorded(cp) {
return cp.executionOutcome !== undefined;
}
export function sameExecutionRecord(a, b) {
return canonicalJson(a) === canonicalJson(b);
}
function canonicalJson(v) {
if (v === null || typeof v !== "object")
return JSON.stringify(v) ?? "undefined";
if (Array.isArray(v))
return `[${v.map(canonicalJson).join(",")}]`;
const keys = Object.keys(v).filter((k) => v[k] !== undefined).sort();
return `{${keys.map((k) => `${JSON.stringify(k)}:${canonicalJson(v[k])}`).join(",")}}`;
}
export function executionRecordDisposition(cp, scope, gate) {
if (cp === undefined || cp.scope !== scope)
return "absent";
if (cp.executionOutcome !== undefined)
return sameExecutionRecord(cp.executionOutcome, gate) ? "already_recorded" : "conflict";
if (cp.status !== "resolved")
return "not_resolved";
return "commit";
}
export function executionVerdict(cp) {
return cp.executionOutcome !== undefined ? { kind: "executed", gate: cp.executionOutcome } : { kind: "unknown" };
}