openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
102 lines (101 loc) • 5.38 kB
JavaScript
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 };