UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

195 lines (194 loc) • 10.1 kB
import { a as resolveGlobalSingleton } from "./global-singleton-0m-JziJW.mjs"; import { c as getPluginCache, m as getProcessPluginCache, n as PluginCacheFactInvalidatedError, u as getPluginCacheRetirementSignal, y as preparePluginCacheFact } from "./plugin-cache-CfBhQFSN.mjs"; import { c as isRecord } from "./record-coerce-TIsquoVR.mjs"; import { n as isArtifactPreservingStateRead } from "./artifact-preserving-state-reads-BQnQLAJR.mjs"; import { c as resolveOpenClawStateSqlitePath } from "./openclaw-state-db.paths-CmKkMYdo.mjs"; import { a as isStateDatabaseReadAdmissionInvalidatedError } from "./openclaw-state-db-async-lifecycle-DwFy2ZTk.mjs"; import { n as getActiveOpenClawStateDatabaseReadSnapshot } from "./openclaw-state-db-readonly-ywwvuxdQ.mjs"; import { r as captureOpenClawStateWorkerContext } from "./openclaw-state-worker-context-BvvgY6-t.mjs"; import { n as readConfigMachineState } from "./config-machine-state-BAsvqrtu.mjs"; import { r as resolveActivePluginInstallRoots, t as hasActivePluginInstallRoots } from "./install-root-context-BJfgtQE2.mjs"; import { n as registerPluginMetadataProcessMemoLifecycleClear } from "./plugin-metadata-lifecycle-COmFOHdR.mjs"; import { n as readPluginMetadataStateRowSync, r as readPluginMetadataStateRowsSync } from "./installed-plugin-index-row-CvqFVPqV.mjs"; //#region src/plugins/plugin-metadata-state-worker.ts async function readPluginMetadataState(selection, options, artifactPreservingReadOnly, decode) { const preserveArtifacts = artifactPreservingReadOnly || isArtifactPreservingStateRead(); try { const context = captureOpenClawStateWorkerContext(options); try { if (preserveArtifacts && getActiveOpenClawStateDatabaseReadSnapshot(options)) { context.admission.assertCurrent(); return decode("stateKeys" in selection ? readPluginMetadataStateRowsSync(selection.stateKeys, options, true) : readPluginMetadataStateRowSync(selection.selector, options, true)); } const { runOpenClawStateWorkerOperation } = await import("./openclaw-state-worker-store-x5r3Lkjl.mjs"); context.admission.assertCurrent(); const result = await runOpenClawStateWorkerOperation(context, async (scope) => { return decode(await scope.execute({ type: "plugins.metadata.read", input: { ...selection, artifactPreservingReadOnly: preserveArtifacts } })); }, { existingOnly: true }); return result === void 0 ? decode(void 0) : result; } finally { context.admission.assertCurrent(); } } catch (error) { if (isStateDatabaseReadAdmissionInvalidatedError(error)) throw new PluginCacheFactInvalidatedError("Plugin metadata read admission changed during preparation; retry the operation.", { cause: error }); throw error; } } /** Read raw metadata from retained snapshot bytes or the shared inspection actor. */ function readPluginMetadataStateRow(selector, options, artifactPreservingReadOnly = false) { return readPluginMetadataState({ selector }, options, artifactPreservingReadOnly, (row) => { if (row === void 0) return; if (!isRecord(row) || typeof row.value_json !== "string") throw new Error("Shared-state worker returned an invalid plugin metadata row"); return { value_json: row.value_json }; }); } /** Policy and inventory preparation share one worker request and SQLite snapshot. */ function readPluginMetadataStateRows(stateKeys, options, artifactPreservingReadOnly = false) { return readPluginMetadataState({ stateKeys }, options, artifactPreservingReadOnly, (rows) => { if (rows === void 0) return []; if (!Array.isArray(rows)) throw new Error("Shared-state worker returned invalid plugin metadata rows"); return rows.map((row) => { if (!isRecord(row) || typeof row.state_key !== "string" || typeof row.value_json !== "string") throw new Error("Shared-state worker returned an invalid plugin metadata row"); return { state_key: row.state_key, value_json: row.value_json }; }); }); } //#endregion //#region src/plugins/bundled-discovery-state.ts function parseBundledDiscoveryMode(value) { return value === "compat" || value === "allowlist" ? value : void 0; } function readBundledDiscoveryFact(read) { try { return read(); } catch (error) { if (isStateDatabaseReadAdmissionInvalidatedError(error)) throw new PluginCacheFactInvalidatedError("Plugin discovery read admission changed during preparation; retry the operation.", { cause: error }); throw error; } } function resolveBundledDiscoveryOptions(options) { return options.path || options.database || !hasActivePluginInstallRoots() ? options : { ...options, env: { ...options.env ?? process.env, OPENCLAW_STATE_DIR: resolveActivePluginInstallRoots(options.env).stateDir } }; } function readBundledDiscoveryMode(options = {}, behavior = {}) { const resolvedOptions = resolveBundledDiscoveryOptions(options); return parseBundledDiscoveryMode(readBundledDiscoveryFact(() => readConfigMachineState("plugins.bundledDiscovery", resolvedOptions, behavior))); } const discoveryState = resolveGlobalSingleton(Symbol.for("openclaw.bundledDiscoveryMode"), () => ({ generation: {}, snapshotModes: /* @__PURE__ */ new WeakMap() })); registerPluginMetadataProcessMemoLifecycleClear(() => { clearBundledDiscoveryModeMemo(); }); function resolveBundledDiscoveryMemoKey(env) { const scopedEnv = hasActivePluginInstallRoots() ? { ...env, OPENCLAW_STATE_DIR: resolveActivePluginInstallRoots(env).stateDir } : env; return resolveOpenClawStateSqlitePath(scopedEnv); } /** * Callers loading a registry with an explicit env pass it so the mode comes * from that env's state root; omitting it reads the process root. Pinned * install roots win over both, matching readBundledDiscoveryMode. */ function readBundledDiscoveryModeMemoized(env = process.env, behavior = {}, readPreparedValue) { const options = env === process.env ? {} : { env }; const snapshot = behavior.artifactPreservingReadOnly || isArtifactPreservingStateRead() ? readBundledDiscoveryFact(() => getActiveOpenClawStateDatabaseReadSnapshot(resolveBundledDiscoveryOptions(options))) : void 0; if (snapshot || behavior.artifactPreservingReadOnly) { const prepared = snapshot && discoveryState.snapshotModes.get(snapshot); if (prepared) return prepared.value; const value = readBundledDiscoveryMode(options, behavior); if (snapshot) discoveryState.snapshotModes.set(snapshot, { value }); return value; } const key = resolveBundledDiscoveryMemoKey(env); if (discoveryState.memoized?.key !== key) { const owner = getPluginCache(); const prepared = owner.preparedBundledDiscoveryModes.get(key); if (prepared && "value" in prepared && prepared.value.generation === discoveryState.generation) { getPluginCacheRetirementSignal(owner).throwIfAborted(); discoveryState.memoized = { key, value: prepared.value.value }; } else discoveryState.memoized = { key, value: readPreparedValue ? parseBundledDiscoveryMode(readBundledDiscoveryFact(() => readPreparedValue(key))) : readBundledDiscoveryMode(env === process.env ? {} : { env }) }; } return discoveryState.memoized.value; } /** Prepare the same machine-owned fact for synchronous metadata derivation. */ async function prepareBundledDiscoveryMode(env = process.env, readPreparedRow) { const owner = getPluginCache(); const options = resolveBundledDiscoveryOptions({ env }); const snapshot = isArtifactPreservingStateRead() ? readBundledDiscoveryFact(() => getActiveOpenClawStateDatabaseReadSnapshot(options)) : void 0; if (snapshot) { const metadata = owner.metadata; const generation = discoveryState.generation; const signal = getPluginCacheRetirementSignal(owner); const assertCurrent = () => { signal.throwIfAborted(); if (owner.metadata !== metadata || discoveryState.generation !== generation || readBundledDiscoveryFact(() => getActiveOpenClawStateDatabaseReadSnapshot(options)) !== snapshot) throw new PluginCacheFactInvalidatedError("Plugin discovery snapshot changed during preparation; retry the operation."); }; assertCurrent(); return assertCurrent; } const cache = owner.preparedBundledDiscoveryModes; const key = resolveBundledDiscoveryMemoKey(env); const generation = discoveryState.generation; const current = cache.get(key); if (current && "value" in current && current.value.generation !== generation) cache.delete(key); const prepared = await preparePluginCacheFact(owner, cache, key, async () => { let value; if (discoveryState.memoized?.key === key) value = discoveryState.memoized.value; else { const row = readPreparedRow ? await readPreparedRow(key) : await readPluginMetadataStateRow("bundled-discovery", resolveBundledDiscoveryOptions({ env })); value = parseBundledDiscoveryMode(row ? JSON.parse(row.value_json) : void 0); } if (discoveryState.generation !== generation) throw new PluginCacheFactInvalidatedError("Plugin discovery state changed during preparation; retry the operation."); return { value, generation }; }); const activate = () => { prepared.assertCurrent(); if (discoveryState.generation !== generation) throw new PluginCacheFactInvalidatedError("Plugin discovery state changed during preparation; retry the operation."); discoveryState.memoized = { key, value: prepared.value.value }; }; activate(); return activate; } /** * Clears the memo after a machine-state write so same-process readers observe * the new mode. Without this, doctor's migration could cache the pre-migration * absent mode and rebuild plugin indexes against stale strict-gate decisions. */ function clearBundledDiscoveryModeMemo() { discoveryState.memoized = void 0; discoveryState.snapshotModes = /* @__PURE__ */ new WeakMap(); discoveryState.generation = {}; for (const cache of /* @__PURE__ */ new Set([getPluginCache(), getProcessPluginCache()])) cache.preparedBundledDiscoveryModes.clear(); } //#endregion export { readPluginMetadataStateRow as a, readBundledDiscoveryModeMemoized as i, prepareBundledDiscoveryMode as n, readPluginMetadataStateRows as o, readBundledDiscoveryMode as r, clearBundledDiscoveryModeMemo as t };