UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

102 lines (101 loc) • 5.38 kB
import { i as getNodeSqliteKysely, s as prepareSqliteQuerySync } from "./kysely-sync-BMSZn9yz.mjs"; import { n as getAdmittedSqliteSchemaFacts } from "./sqlite-schema-facts-1TrpbK4i.mjs"; import { t as SqliteSchemaMismatchError } from "./sqlite-schema-issues-Cd5MmsG2.mjs"; import { a as tableHasColumn, i as tableExists } from "./openclaw-state-db-schema-helpers-DsjDX6BL.mjs"; import "./openclaw-state-db-contract-CQDemVBb.mjs"; import { a as readSqliteUserVersion, n as createNewerSqliteSchemaVersionError } from "./sqlite-user-version-r2LI3NT9.mjs"; import { r as normalizeOpenClawStateSchemaReadError } from "./openclaw-state-db-schema-migration-required-DQkqpkxd.mjs"; import { i as collectSqliteSchemaIssues } from "./sqlite-schema-contract-CKIVRB-P.mjs"; //#region src/state/openclaw-state-db-schema-version.ts const CONTENT_VERSION_KEY = "state.schema.contentVersion"; const contentVersions = /* @__PURE__ */ new WeakMap(); const contentVersionQueries = /* @__PURE__ */ new WeakMap(); /** Content and its marker commit together, even while older readers retain their version floor. */ function readStateSchemaContentVersion(db) { const schema = getAdmittedSqliteSchemaFacts(db); const cached = schema && contentVersions.get(schema); if (cached !== void 0) return cached; const version = readContentVersion(db, schema?.userVersion ?? readSqliteUserVersion(db)); if (schema) contentVersions.set(schema, version); return version; } function readContentVersion(db, published) { if (!tableExists(db, "config_machine_state")) return published; let query = contentVersionQueries.get(db); if (!query) { query = prepareSqliteQuerySync(db, () => getNodeSqliteKysely(db).selectFrom("config_machine_state").select("value_json").where("state_key", "=", CONTENT_VERSION_KEY)); contentVersionQueries.set(db, query); } const row = query().rows[0]; if (!row) return published; let contentVersion; try { contentVersion = JSON.parse(row.value_json); } catch (cause) { throw new SqliteSchemaMismatchError(`Invalid shared state schema content version in ${CONTENT_VERSION_KEY}.`, { cause }); } if (typeof contentVersion !== "number" || !Number.isSafeInteger(contentVersion) || contentVersion < 0) throw new SqliteSchemaMismatchError(`Invalid shared state schema content version in ${CONTENT_VERSION_KEY}.`); return Math.max(published, contentVersion); } /** Cold migration planning checks physical content; admission still uses the recorded version. */ function readStateSchemaMigrationVersion(db) { const version = readStateSchemaContentVersion(db); if (version !== 16) return version; const reviewWorkspace = tableHasColumn(db, "skill_workshop_collection_reviews", "workspace_dir"); const proposalWorkspace = tableHasColumn(db, "skill_workshop_proposals", "workspace_dir"); const releasedClaim = tableHasColumn(db, "skill_workshop_proposals", "claim_released_time"); if (!reviewWorkspace && !proposalWorkspace && !releasedClaim) return version; const missingAttribution = reviewWorkspace && !proposalWorkspace; const issues = collectSqliteSchemaIssues(db, ` CREATE TABLE skill_workshop_collection_reviews ( review_id TEXT NOT NULL PRIMARY KEY, ${reviewWorkspace ? "workspace_dir" : "owner_agent_id"} TEXT NOT NULL, backup_id TEXT NOT NULL, create_time INTEGER NOT NULL, kept_names_json TEXT NOT NULL, written_names_json TEXT NOT NULL, dropped_json TEXT NOT NULL ) STRICT; CREATE TABLE skill_workshop_proposals ( proposal_id TEXT NOT NULL PRIMARY KEY, record_json TEXT NOT NULL, owner_agent_id TEXT, ${proposalWorkspace ? "workspace_dir TEXT NOT NULL," : ""} kind TEXT NOT NULL CHECK (kind IN ('create', 'update')), status TEXT NOT NULL CHECK (status IN ('pending', 'applied', 'rejected', 'quarantined', 'stale')), created_at TEXT NOT NULL, updated_at TEXT NOT NULL, draft_hash TEXT NOT NULL, origin_agent_id TEXT, origin_session_key TEXT, origin_run_id TEXT, origin_message_id TEXT, applied_at TEXT, rejected_at TEXT, quarantined_at TEXT, stale_at TEXT, status_reason TEXT ${releasedClaim ? ", claim_released_time INTEGER" : ""} ) STRICT; `, { allowedMissingTables: ["skill_workshop_collection_reviews"], allowedColumnDefinitions: { "skill_workshop_collection_reviews.workspace_dir": ["workspace_dir TEXT NOT NULL DEFAULT ''"], "skill_workshop_proposals.workspace_dir": ["workspace_dir TEXT NOT NULL DEFAULT ''"] } }); if (!missingAttribution && issues.length === 0) return 15; throw new SqliteSchemaMismatchError("Unrecognized Skill Workshop ownership schema; cannot apply the schema 16 migration."); } function assertSupportedStateSchemaVersion(db, pathname) { try { const userVersion = getAdmittedSqliteSchemaFacts(db)?.userVersion ?? readSqliteUserVersion(db); const contentVersion = userVersion > 19 ? userVersion : readStateSchemaContentVersion(db); if (contentVersion > 19) throw createNewerSqliteSchemaVersionError("OpenClaw state database", pathname, contentVersion, 19); return userVersion; } catch (error) { throw normalizeOpenClawStateSchemaReadError(error, pathname); } } //#endregion export { readStateSchemaMigrationVersion as i, assertSupportedStateSchemaVersion as n, readStateSchemaContentVersion as r, CONTENT_VERSION_KEY as t };