UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

227 lines (226 loc) • 10.1 kB
import { a as extractErrorCode, i as collectNestedErrorCandidates } from "./error-coercion-W9BtigRm.mjs"; import "./src-BirUqOZp.mjs"; import { t as expectDefined } from "./expect-lbe3Hgrh.mjs"; import { c as isRecord } from "./record-coerce-TIsquoVR.mjs"; import { a as isStateDatabaseReadAdmissionInvalidatedError } from "./openclaw-state-db-async-lifecycle-DwFy2ZTk.mjs"; import { r as createLazyRuntimeModule } from "./lazy-runtime-CJrzFzqU.mjs"; import { t as executeExistingOpenClawStateRead } from "./openclaw-state-db-readonly-ywwvuxdQ.mjs"; import { r as captureOpenClawStateWorkerContext } from "./openclaw-state-worker-context-BvvgY6-t.mjs"; import { d as reserveSqliteWorkerInputPreparation, n as createSqliteWorkerWriteAdmission } from "./sqlite-worker-store-C0QRqven.mjs"; import { o as runOpenClawStateWorkerOperation } from "./openclaw-state-worker-store-BxZXTKna.mjs"; import { o as withCronReceiptAuthorityMutation } from "./receipt-authority-owner-CGp53wXR.mjs"; import { t as createKeyedFifoLeaseRegistry } from "./keyed-fifo-lease-Czc3xgVJ.mjs"; import "./operator-approval-store.transitions-CkEcDLIV.mjs"; import { o as decodeOperatorApprovalHistoryCursor } from "./operator-approval-store.rows-CK66kG3A.mjs"; import { serialize } from "node:v8"; import { AsyncLocalStorage } from "node:async_hooks"; //#region src/gateway/operator-approval-store.ts /** Storage admission failure is not evidence that a pending row is corrupt. */ function isOperatorApprovalStoreRefusal(error) { return collectNestedErrorCandidates(error).some((cause) => isStateDatabaseReadAdmissionInvalidatedError(cause) || [ "closed", "overloaded", "unavailable" ].includes(extractErrorCode(cause) ?? "")); } function isOperatorApprovalStoreOutcomeUnknown(error) { return collectNestedErrorCandidates(error).some((cause) => extractErrorCode(cause) === "outcome-unknown"); } const loadNativeStore = createLazyRuntimeModule(() => import("./operator-approval-store.native-Dk8c652x.mjs")); const leases = createKeyedFifoLeaseRegistry(Symbol.for("openclaw.operatorApprovalStoreLeases")); async function runApprovalStoreOperation(context, input, operation, options, assertCurrent, retainAuthority) { context.admission.assertCurrent(); const preparation = reserveSqliteWorkerInputPreparation(serialize(input).byteLength); const lease = expectDefined(leases.reserve([context.admission.identity.key, `path:${context.admission.identity.canonicalPath}`]), "Operator approval storage lease"); try { await lease.wait(); preparation.assertCurrent(); context.admission.assertCurrent(); assertCurrent?.(); const run = (retainedContext = context) => runOpenClawStateWorkerOperation(retainedContext, (scope) => operation(scope, preparation), options); return await (retainAuthority ? retainAuthority(run) : run()); } finally { preparation.release(); lease.release(); } } function execute(type, { databaseOptions, assertCurrent, guard, ...input }, onCommitted) { const context = captureOpenClawStateWorkerContext({ ...databaseOptions, path: databaseOptions?.database?.path ?? databaseOptions?.path }); const captured = structuredClone(input); const assertCallerCurrent = AsyncLocalStorage.bind(() => { guard?.assertCurrent(); assertCurrent?.(); }); let mutation; const assertOperationCurrent = () => { context.admission.assertCurrent(); mutation?.assertCurrent(); assertCallerCurrent(); }; const native = guard?.family === "native-compatibility"; let admission; const createAdmission = (operation) => { const authority = expectDefined(mutation, "Operator approval receipt authority"); const retained = createSqliteWorkerWriteAdmission(assertOperationCurrent, [context.admission.databasePath], authority.attachment)(operation); admission = retained.admission; authority.observe(admission, operation); return retained; }; const publishCommitted = (facts) => { if (onCommitted && isRecord(facts) && facts.type === "operatorApprovals.resolve" && typeof facts.resolutionKey === "string") onCommitted(facts.resolutionKey); }; return runApprovalStoreOperation(context, captured, async (scope, preparation) => { if (native) { const store = await loadNativeStore(); preparation.assertCurrent(); assertOperationCurrent(); preparation.release(); const authority = expectDefined(mutation, "Operator approval receipt authority"); let receipt; try { return store.executeNativeOperatorApproval(type, captured, context, assertOperationCurrent, authority.attachment, (committed) => { receipt = committed; if (committed.receiptAuthority) authority.publish(committed.receiptAuthority); }); } finally { publishCommitted(receipt); } } try { return await preparation.handoff(() => scope.execute({ type, input: captured })); } finally { publishCommitted(admission?.committed?.facts); } }, { assertCurrent: native ? void 0 : assertOperationCurrent, ...native ? {} : { createAdmission } }, assertOperationCurrent, (run) => withCronReceiptAuthorityMutation(context, (authority) => { mutation = authority; return run(authority.context); }, { settlement: type === "operatorApprovals.consume" && assertCurrent !== void 0 })); } function insertOperatorApproval(params) { return execute("operatorApprovals.insert", params); } function getOperatorApprovalDetailed(params) { return execute("operatorApprovals.get", params); } function listPendingOperatorApprovals(params = {}) { return execute("operatorApprovals.pending", params); } function resolveOperatorApproval(params) { const { onCommitted, ...input } = params; return execute("operatorApprovals.resolve", input, onCommitted); } function forceDenyOperatorApproval(params) { return execute("operatorApprovals.deny", params); } function expireDueOperatorApprovals(params) { return execute("operatorApprovals.expire", params); } function consumeOperatorApprovalAllowOnce(params) { return execute("operatorApprovals.consume", params); } async function readApprovalStore(command, { databaseOptions, assertCurrent, guard }, project) { const context = captureOpenClawStateWorkerContext({ ...databaseOptions, path: databaseOptions?.database?.path ?? databaseOptions?.path }); const captured = structuredClone(command); const assertOperationCurrent = () => { context.admission.assertCurrent(); guard?.assertCurrent(); assertCurrent?.(); }; return runApprovalStoreOperation(context, captured, async (_scope, preparation) => { preparation.assertCurrent(); assertOperationCurrent(); preparation.release(); const result = await executeExistingOpenClawStateRead({ env: context.environment, path: context.admission.databasePath }, captured); assertOperationCurrent(); const value = result?.ok && result.type === command.type ? project(result) : void 0; if (value !== void 0) return value; throw new Error("Operator approval database became unavailable"); }, void 0, assertOperationCurrent); } async function listTerminalOperatorApprovals(params = {}) { const { databaseOptions, assertCurrent, guard, ...input } = params; if (input.cursor !== void 0) decodeOperatorApprovalHistoryCursor(input.cursor); return readApprovalStore({ type: "operatorApprovals.history", input }, { databaseOptions, assertCurrent, guard }, (result) => result.type === "operatorApprovals.history" ? result.history : void 0); } function listCronStandingGrants(params = {}) { const { databaseOptions, assertCurrent, guard, ...input } = params; return readApprovalStore({ type: "operatorApprovals.listCronGrants", input }, { databaseOptions, assertCurrent, guard }, (result) => result.type === "operatorApprovals.listCronGrants" ? result.grants : void 0); } function revokeCronStandingGrant(params) { return execute("operatorApprovals.revokeCronGrant", params); } function validateCronStandingGrant(params) { const { databaseOptions, assertCurrent, guard, ...input } = params; return readApprovalStore({ type: "operatorApprovals.validateCronGrant", input }, { databaseOptions, assertCurrent, guard }, (result) => result.type === "operatorApprovals.validateCronGrant" ? result.result : void 0); } /** The approval FIFO precedes acquisition of the caller's exact cron authority interval. */ function consumeCronStandingGrant(context, input, assertCurrent, withAuthority) { const captured = structuredClone(input); let authority; const assertUseCurrent = () => { context.admission.assertCurrent(); authority?.assertCurrent(); assertCurrent(); }; return runApprovalStoreOperation(context, captured, (scope, preparation) => preparation.handoff(() => scope.execute({ type: "operatorApprovals.consumeCronGrant", input: captured })), { assertCurrent: assertUseCurrent, createAdmission(retained) { const mutation = expectDefined(authority, "Cron standing-grant receipt authority"); const admission = createSqliteWorkerWriteAdmission(assertUseCurrent, [context.admission.databasePath], mutation.attachment)(retained); mutation.observe(admission.admission, retained); return admission; } }, assertUseCurrent, (run) => withAuthority(async (mutation) => { authority = mutation; const result = await run(mutation.context); assertUseCurrent(); return result; })); } function readPlacementStandingGrant(input, options) { return readApprovalStore({ type: "operatorApprovals.placementGrant", input }, options, (result) => result.type === "operatorApprovals.placementGrant" ? result.rows : void 0); } //#endregion export { getOperatorApprovalDetailed as a, isOperatorApprovalStoreRefusal as c, listTerminalOperatorApprovals as d, readPlacementStandingGrant as f, validateCronStandingGrant as h, forceDenyOperatorApproval as i, listCronStandingGrants as l, revokeCronStandingGrant as m, consumeOperatorApprovalAllowOnce as n, insertOperatorApproval as o, resolveOperatorApproval as p, expireDueOperatorApprovals as r, isOperatorApprovalStoreOutcomeUnknown as s, consumeCronStandingGrant as t, listPendingOperatorApprovals as u };