diff --git a/docs/refactor/database-first.md b/docs/refactor/database-first.md index ef8fd39585de..d0e472a1b021 100644 --- a/docs/refactor/database-first.md +++ b/docs/refactor/database-first.md @@ -1469,10 +1469,10 @@ create` validates the written archive by default; `--no-verify` is the bridge; they are not a second canonical transcript store. - QMD's own `index.sqlite`, YAML collection config, and model downloads remain external-tool artifacts under `~/.openclaw/agents//qmd`; they are not - mirrored into `plugin_blob_entries`. OpenClaw-owned QMD coordination is - database-first: shared `state_leases` serialize embeds globally and per-agent - `state_leases` serialize collection/update/embed writers. Runtime creates no - QMD lock sidecars. + mirrored into `plugin_blob_entries`. Current host-owned lease consumers use + shared `state_leases`; the per-agent `state_leases` table remains in the + canonical schema but has no runtime tenants. Runtime creates no QMD lock + sidecars. - The optional `memory-lancedb` plugin no longer creates `~/.openclaw/memory/lancedb` as an implicit OpenClaw-managed store. It is an external LanceDB backend and stays disabled until the operator configures an @@ -2044,8 +2044,7 @@ payload. `gateway_locks` and no longer exposes a file-lock directory seam. - Generic plugin SDK dedupe persistence no longer uses file locks or JSON files; it writes shared SQLite plugin-state rows. Done. - - QMD coordination uses a shared SQLite lease for embeds and a per-agent - SQLite lease for every collection/update/embed writer. Runtime no longer + - QMD writers no longer take OpenClaw state leases. Runtime no longer creates `qmd/embed.lock.lock` or `agents//qmd-write.lock.lock`; Doctor removes only definitely stale retired sidecars. Done. diff --git a/src/agents/command/attempt-execution.cli.test.ts b/src/agents/command/attempt-execution.cli.test.ts index 750f62c6aa4e..6649a5253eea 100644 --- a/src/agents/command/attempt-execution.cli.test.ts +++ b/src/agents/command/attempt-execution.cli.test.ts @@ -730,7 +730,6 @@ describe("CLI attempt execution", () => { DELETE FROM auth_profile_store; DELETE FROM auth_profile_state; DELETE FROM cache_entries; - DELETE FROM state_leases; `); }, database, diff --git a/src/state/openclaw-state-lease.test.ts b/src/state/openclaw-state-lease.test.ts index f26c93186c2c..d4ae31a9b79a 100644 --- a/src/state/openclaw-state-lease.test.ts +++ b/src/state/openclaw-state-lease.test.ts @@ -4,7 +4,6 @@ import { pathToFileURL } from "node:url"; import { afterEach, describe, expect, it } from "vitest"; import { executeSqliteQuerySync, getNodeSqliteKysely } from "../infra/kysely-sync.js"; import { withOpenClawTestState } from "../test-utils/openclaw-test-state.js"; -import { closeOpenClawAgentDatabasesForTest } from "./openclaw-agent-db.js"; import type { DB as OpenClawStateKyselyDatabase } from "./openclaw-state-db.generated.js"; import { closeOpenClawStateDatabaseForTest, @@ -15,7 +14,6 @@ import { withOpenClawStateLease } from "./openclaw-state-lease.js"; type LeaseDatabase = Pick; afterEach(() => { - closeOpenClawAgentDatabasesForTest(); closeOpenClawStateDatabaseForTest(); }); diff --git a/src/state/openclaw-state-lease.ts b/src/state/openclaw-state-lease.ts index 57966b7a7b27..07a88f3899be 100644 --- a/src/state/openclaw-state-lease.ts +++ b/src/state/openclaw-state-lease.ts @@ -10,11 +10,6 @@ import { import { isSqliteLockError } from "../infra/sqlite-transaction.js"; import { loggingState } from "../logging/state.js"; import { MAX_TIMER_TIMEOUT_MS } from "../shared/number-coercion.js"; -import type { DB as OpenClawAgentKyselyDatabase } from "./openclaw-agent-db.generated.js"; -import { - openOpenClawAgentDatabase, - runOpenClawAgentWriteTransaction, -} from "./openclaw-agent-db.js"; import type { DB as OpenClawStateKyselyDatabase } from "./openclaw-state-db.generated.js"; import { openOpenClawStateDatabase, @@ -23,12 +18,12 @@ import { } from "./openclaw-state-db.js"; type LeaseDatabase = Pick; -type AgentLeaseDatabase = Pick; type LeaseKysely = ReturnType>; -type OpenClawStateLeaseDatabase = - | { scope: "shared"; options?: OpenClawStateDatabaseOptions } - | { scope: "agent"; agentId: string; path?: string }; +type OpenClawStateLeaseDatabase = { + scope: "shared"; + options?: OpenClawStateDatabaseOptions; +}; type OpenClawStateLeaseOptions = { scope: string; @@ -157,11 +152,8 @@ function validateOptions(options: OpenClawStateLeaseOptions) { if (typeof database !== "object" || database === null || Array.isArray(database)) { throw invalidInput("state lease database must be an object"); } - if (database.scope !== "shared" && database.scope !== "agent") { - throw invalidInput("state lease database scope must be shared or agent"); - } - if (database.scope === "agent") { - validateNonEmptyString(database.agentId, "state lease agent database agentId"); + if (database.scope !== "shared") { + throw invalidInput("state lease database scope must be shared"); } const leaseLabel = options.leaseLabel === undefined @@ -217,41 +209,21 @@ function withLeaseWriteTransaction( operation: (db: DatabaseSync, kysely: LeaseKysely) => T, busyTimeoutMs = LEASE_DB_BUSY_TIMEOUT_MS, ): T { - if (database.scope === "shared") { - const stateDatabase = openOpenClawStateDatabase(database.options); - const run = () => - runOpenClawStateWriteTransaction( - ({ db }) => operation(db, getNodeSqliteKysely(db)), - database.options, - { operationLabel, busyTimeoutMs }, - ); - return withBusyTimeout(stateDatabase.db, busyTimeoutMs, run); - } - const agentOptions = { - agentId: database.agentId, - ...(database.path ? { path: database.path } : {}), - }; - const agentDatabase = openOpenClawAgentDatabase(agentOptions); + const stateDatabase = openOpenClawStateDatabase(database.options); const run = () => - runOpenClawAgentWriteTransaction( - ({ db }) => operation(db, getNodeSqliteKysely(db)), - agentOptions, + runOpenClawStateWriteTransaction( + ({ db }) => operation(db, getNodeSqliteKysely(db)), + database.options, { operationLabel, busyTimeoutMs }, ); - return withBusyTimeout(agentDatabase.db, busyTimeoutMs, run); + return withBusyTimeout(stateDatabase.db, busyTimeoutMs, run); } function withLeaseRead( database: OpenClawStateLeaseDatabase, operation: (db: DatabaseSync, kysely: LeaseKysely) => T, ): T { - const sqlite = - database.scope === "shared" - ? openOpenClawStateDatabase(database.options).db - : openOpenClawAgentDatabase({ - agentId: database.agentId, - ...(database.path ? { path: database.path } : {}), - }).db; + const sqlite = openOpenClawStateDatabase(database.options).db; return operation(sqlite, getNodeSqliteKysely(sqlite)); }