UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

135 lines (134 loc) • 6.55 kB
import { c as isRecord } from "./record-coerce-TIsquoVR.mjs"; import { a as isStateDatabaseReadAdmissionInvalidatedError } from "./openclaw-state-db-async-lifecycle-DwFy2ZTk.mjs"; import { c as SqliteWorkerError } from "./sqlite-worker-contract-C51cJHzg.mjs"; import { r as createSqliteWorkerOperationAdmission } from "./sqlite-worker-operation-admission-C5lBzzTk.mjs"; import { o as captureAgentDatabasePreparationDeletionForIdentity } from "./agent-database-admission-CRwW7FsI.mjs"; import { i as sessionChanges } from "./session-row-changes-Dj2yVWo-.mjs"; import { r as captureOpenClawStateWorkerContext } from "./openclaw-state-worker-context-BvvgY6-t.mjs"; import { o as runOpenClawStateWorkerOperation } from "./openclaw-state-worker-store-BxZXTKna.mjs"; import { t as ErrorCodes } from "./gateway-error-details-gTekQWj2.mjs"; import { d as errorShape } from "./error-codes-D0WRV4Bq.mjs"; import { i as captureActiveCronJobAgentDeletion } from "./active-jobs-DcrjhGDv.mjs"; import { o as withCronReceiptAuthorityMutation } from "./receipt-authority-owner-CGp53wXR.mjs"; import { n as digestClawValue } from "./digest-CI8Suvd7.mjs"; import { n as prepareAgentSessionStoreDeletionSafety, t as assertAgentSessionStoreDeletionTargetsCurrent } from "./agent-delete-session-store-safety.targets-BDM1rHre.mjs"; import { t as resolveClawMonitorCleanupBinding } from "./monitor-cleanup-binding-D9AiNk2E.mjs"; import { n as clawRemovalJournalResultSchema, t as clawRemovalJournalRequestSchema } from "./removal-journal-contract-OUPyO7hb.mjs"; import { isDeepStrictEqual } from "node:util"; import { randomUUID } from "node:crypto"; //#region src/claws/removal-journal.ts /** Only the serving Cron owner publishes a journal mutation; native settlement precedes its reply. */ async function mutateClawRemovalJournal(input, assertRequestCurrent) { const context = captureOpenClawStateWorkerContext(); const assertSourceCurrent = () => { context.admission.assertCurrent(); if (!isDeepStrictEqual(context.admission.identity, input.request.sourceIdentity)) throw new Error("Claw journal mutation no longer owns its original physical database."); }; assertSourceCurrent(); const command = { ...structuredClone(input), nonce: randomUUID(), sessionStoreSafety: input.request.phase === "begin" ? prepareAgentSessionStoreDeletionSafety(input.config, input.request.agentId, context.environment) : null }; const cancel = captureActiveCronJobAgentDeletion(input.request.agentId, context.admission.identity.key); const invalidatePreparation = captureAgentDatabasePreparationDeletionForIdentity(input.request.agentId, { databasePath: context.admission.databasePath, identityKey: context.admission.identity.key }); return withCronReceiptAuthorityMutation(context, async (mutation) => { const assertCurrent = () => { assertSourceCurrent(); mutation.assertCurrent(); assertRequestCurrent(); if (command.sessionStoreSafety) assertAgentSessionStoreDeletionTargetsCurrent(command.sessionStoreSafety.targets); }; let native; let settlement; let failure; try { await runOpenClawStateWorkerOperation(mutation.context, async (scope) => { if ((await scope.execute({ type: "clawProvenance.removalJournal", input: command })).nonce !== command.nonce) throw new Error("Claw journal mutation returned a different operation nonce"); }, { assertCurrent, createAdmission(retained) { settlement = retained.settled; let phase = "transaction"; const admission = createSqliteWorkerOperationAdmission((request, grant) => { assertCurrent(); if (!isRecord(request.facts) || request.facts.nonce !== command.nonce || request.stage !== phase) throw new Error("Claw journal mutation lost its transaction owner"); if (!grant()) throw new Error("Claw journal mutation admission expired"); phase = phase === "transaction" ? "commit" : "settling"; }, mutation.attachment); native = admission; mutation.observe(admission, retained); return { admission, nativeLocations: [context.admission.databasePath] }; } }); } catch (error) { failure = error; } const settled = await settlement; const facts = native?.committed?.facts; if (isRecord(facts) && facts.nonce === command.nonce) { const result = clawRemovalJournalResultSchema.parse({ ok: true, journal: facts.journal }); if (input.request.phase === "begin") { invalidatePreparation(); cancel(); } try { (context.assertPublicationCurrent ?? context.admission.assertCurrent)(); sessionChanges.emit({ all: true, scope: "stores" }); } catch (error) { if (!isStateDatabaseReadAdmissionInvalidatedError(error)) throw error; } return result; } if (native?.committed || settled?.kind === "unknown" || native?.settlement?.kind === "unknown") throw new SqliteWorkerError("Claw journal mutation has an unknown durable outcome; inspect claws status before retrying.", "outcome-unknown"); return { ok: false, error: failure instanceof Error ? failure.message : "Claw journal mutation did not commit." }; }); } //#endregion //#region src/gateway/server-methods/claws-removal-journal.ts const clawsRemovalJournalHandlers = { "claws.removalJournal": async (options) => { const { params, context, respond } = options; const parsed = clawRemovalJournalRequestSchema.safeParse(params); if (!parsed.success) { respond(false, void 0, errorShape(ErrorCodes.INVALID_REQUEST, "Invalid Claw removal journal parameters.")); return; } const request = parsed.data; const config = context.getRuntimeConfig(); const assertCurrent = () => { options.signal?.throwIfAborted(); options.sessionMutationCommitGuard?.(); if (options.hasCurrentClientAuthority?.() === false || !isDeepStrictEqual(request.binding, resolveClawMonitorCleanupBinding(context.cronStorePath)) || context.getRuntimeConfig() !== config || digestClawValue(config) !== request.configDigest || !context.isConfigReloadSettled()) throw new Error("Claw removal no longer owns the serving Gateway's configuration or request authority."); }; let dispatched = false; try { assertCurrent(); dispatched = true; respond(true, await mutateClawRemovalJournal({ request, config }, assertCurrent)); } catch (error) { respond(false, void 0, errorShape(ErrorCodes.UNAVAILABLE, error instanceof Error ? error.message : String(error), { details: { outcomeUnknown: dispatched } })); } } }; //#endregion export { clawsRemovalJournalHandlers };