Skip to content

refactor: move runtime state to SQLite#81402

Closed
steipete wants to merge 10 commits into
mainfrom
refactor/sqlite-runtime-clean
Closed

refactor: move runtime state to SQLite#81402
steipete wants to merge 10 commits into
mainfrom
refactor/sqlite-runtime-clean

Conversation

@steipete

@steipete steipete commented May 13, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR reopens the database-first runtime-state refactor after the accidental direct landing in #78595 was reverted from main. It moves active OpenClaw runtime state away from scattered JSON, JSONL, lock files, cache files, and sidecar stores into a typed SQLite layout, while keeping user configuration file-backed.

The main contract is intentionally simple:

  • Global control-plane state lives in ~/.openclaw/state/openclaw.sqlite.
  • Per-agent data-plane state lives in ~/.openclaw/agents/<agentId>/agent/openclaw-agent.sqlite.
  • openclaw.json, plugin manifests, external provider credential files, and user workspaces do not move into SQLite.
  • Legacy JSON, JSONL, lock, and sidecar files are doctor migration inputs only. Runtime startup and hot paths should not dual-read or bridge old file state.
  • Session/transcript identity is relational: { agentId, sessionId } plus explicit conversation/session metadata. Runtime code must not pass transcript file paths or pseudo-locators such as sqlite-transcript://....

What changed

  • Adds the shared global state database opener, schema, generated Kysely types, transaction helpers, WAL maintenance, permissions handling, and state-lock helpers.
  • Adds the per-agent database opener, schema, generated Kysely types, agent database registry rows, and typed session/transcript/VFS/artifact stores.
  • Replaces active session, transcript, cron, task, subagent, plugin-state, pairing, diagnostic, media, backup, commitment, delivery queue, and capture stores with SQLite-backed implementations.
  • Moves legacy file import/cleanup into openclaw doctor --fix style migration surfaces instead of runtime startup compatibility paths.
  • Adds database-first guardrails: generated schema checks, Kysely linting, legacy-store scanners, and docs describing the new storage boundary.
  • Updates bundled plugins and native apps to use the new state boundaries instead of private file paths where they need durable runtime state.
  • Keeps dependency/package-manager/engine/lockfile policy unchanged from main for this cleanup PR.

Architecture

Global database: state/openclaw.sqlite

  • Owns shared gateway/control-plane state.
  • Tracks registered agent databases and global schema metadata.
  • Stores auth profile runtime state, pairing/device/node state, plugin state/blob data, scheduler state, task/flow ledgers, delivery queues, backup/migration records, sandbox registry, restart handoff state, diagnostic rows, media blobs, and shared app/plugin runtime state.
  • Provides the shared state_leases table used by SQLite-backed lock helpers.

Agent database: agents/<agentId>/agent/openclaw-agent.sqlite

  • Owns agent-local data-plane state.
  • Stores sessions, conversation identity, session routing, transcript events, transcript event identities, transcript snapshots, VFS entries, tool/run artifacts, ACP parent stream events, trajectory runtime rows, memory index rows, embedding cache, and generic agent cache entries.
  • Lets large per-agent state move out of the shared gateway write lane while still preserving a global registry in agent_databases.

Proxy capture database: src/proxy-capture/schema.sql

  • Keeps the focused capture-store schema for sessions/events/blobs.
  • The same capture tables are also present in the global schema for managed state paths that need to live under openclaw.sqlite.

Schema files

  • src/state/openclaw-state-schema.sql: global control-plane schema, 62 tables.
  • src/state/openclaw-state-schema.generated.ts: generated SQL module for the global schema.
  • src/state/openclaw-state-db.generated.d.ts: generated Kysely types for the global schema.
  • src/state/openclaw-agent-schema.sql: per-agent data-plane schema, 19 tables.
  • src/state/openclaw-agent-schema.generated.ts: generated SQL module for the per-agent schema.
  • src/state/openclaw-agent-db.generated.d.ts: generated Kysely types for the per-agent schema.
  • src/proxy-capture/schema.sql: standalone proxy capture schema, 3 tables.
  • src/proxy-capture/schema.generated.ts and src/proxy-capture/db.generated.d.ts: generated SQL/types for proxy capture.

Across these schema files there are 84 tables and 110 explicit indexes/unique indexes.

Global database schema

Core metadata and locking:

  • schema_meta: database role, schema version, app version, timestamps.
  • agent_databases: registry of per-agent database paths, schema versions, last-seen timestamps, and size hints.
  • state_leases: scoped durable lease/lock rows with owner, heartbeat, expiry, and payload.

Auth, diagnostics, and approvals:

  • auth_profile_stores, auth_profile_state: runtime auth profile store/state JSON by store key.
  • diagnostic_events, diagnostic_stability_bundles: scoped diagnostic payloads and generated stability bundles.
  • exec_approvals_config: persisted exec approval configuration and derived counts.
  • config_health_entries: last-known-good/promoted config health state.

Pairing, device, node, and native app state:

  • device_pairing_pending, device_pairing_paired: device pairing requests and approved devices.
  • device_bootstrap_tokens: bootstrap tokens plus issued/redeemed profile metadata.
  • node_pairing_pending, node_pairing_paired: node pairing requests and approved nodes.
  • device_identities, device_auth_tokens: device keypairs and role-scoped tokens.
  • android_notification_recent_packages: Android notification recent-package ordering.
  • macos_port_guardian_records: macOS port guardian records.
  • workspace_setup_state: workspace setup lifecycle state.
  • native_hook_relay_bridges: native hook relay bridge metadata and expiry.
  • node_host_config: node-host config state.

Models, media, push, and voice wake:

  • model_capability_cache: provider/model capability and cost cache.
  • agent_model_catalogs: generated model catalogs per agent dir.
  • managed_outgoing_image_records: managed outgoing image attachment metadata.
  • web_push_subscriptions, web_push_vapid_keys: web push subscription and VAPID key state.
  • apns_registrations: APNS registration rows for native nodes.
  • voicewake_triggers, voicewake_routing_config, voicewake_routing_routes: voice wake trigger and routing state.

Plugin and channel state:

  • installed_plugin_index: persisted installed-plugin index and diagnostics.
  • plugin_state_entries: JSON plugin state by plugin, namespace, and key.
  • plugin_blob_entries: binary plugin blobs by plugin, namespace, and key.
  • channel_pairing_requests, channel_pairing_allow_entries: channel pairing codes and allow entries.
  • plugin_binding_approvals: plugin/channel/account binding approvals.
  • current_conversation_bindings: current channel conversation bindings to target agent/session rows.

Gateway, replay, delivery, and runtime queues:

  • gateway_restart_sentinel, gateway_restart_intent, gateway_restart_handoff: restart continuity and supervisor handoff state.
  • acp_replay_sessions, acp_replay_events: ACP replay session/event ledger.
  • delivery_queue_entries: durable delivery queue with retry, failure, session, channel, target, and recovery metadata.
  • command_log_entries: durable command log entries.
  • tui_last_sessions: last active session per TUI scope.

Tasks, flows, subagents, cron, and commitments:

  • task_runs: durable task run state.
  • task_delivery_state: notification state per task.
  • flow_runs: task-flow/controller state.
  • subagent_runs: child-agent lifecycle, archive, announcement, frozen-result, and final-delivery state.
  • cron_jobs: scheduler job definitions plus runtime state.
  • cron_run_logs: scheduler run history.
  • commitments: follow-up commitment records and delivery lifecycle.

Storage, backup, migration, sandbox, and capture:

  • media_blobs: managed media blob storage.
  • skill_uploads: temporary skill upload archives with idempotency/expiry.
  • sandbox_registry_entries: sandbox/container registry state.
  • migration_runs, migration_sources: doctor migration run/source ledger.
  • backup_runs: backup archive manifest records.
  • capture_sessions, capture_events, capture_blobs: managed proxy-capture session/event/blob storage.
  • update_check_state: update notification/auto-install state.

Per-agent database schema

Session and conversation identity:

  • schema_meta: agent database role, schema version, agent id, app version, timestamps.
  • sessions: canonical session metadata, status, channel/account/model metadata, parent/spawn identity, and primary conversation reference.
  • session_routes: maps stable session keys to canonical session ids.
  • conversations: typed channel/account/conversation identity with direct/group/channel kind and thread/native ids.
  • session_conversations: many-to-many session/conversation roles with one primary conversation per session.
  • session_entries: compatibility/display entry JSON keyed by session key, linked to canonical session id.

Transcripts and trajectory:

  • transcript_events: append-only transcript event stream keyed by (session_id, seq).
  • transcript_event_identities: event id, parent/idempotency identity, tail indexes, and event type metadata.
  • transcript_snapshots: explicit transcript snapshot records with reason/count/metadata.
  • trajectory_runtime_events: runtime trajectory rows linked to session/run identity.
  • acp_parent_stream_events: ACP parent stream event ledger by run id and sequence.

Agent-local workspace, artifacts, memory, and cache:

  • vfs_entries: virtual filesystem namespace/path records with optional blob content and metadata.
  • tool_artifacts: tool output artifacts by run id and artifact id.
  • run_artifacts: run artifacts by run id and path.
  • memory_index_meta: memory index provider/model/config metadata.
  • memory_index_sources: indexed memory/session sources.
  • memory_index_chunks: indexed text chunks with embedding blobs and source/session references.
  • memory_embedding_cache: provider/model/provider-key/hash embedding cache.
  • cache_entries: generic agent-local cache rows with JSON/blob payloads and optional expiry.

Runtime contract changes reviewers should focus on

  • Runtime code should pass { agentId, sessionId } or { agentId, sessionKey }, not transcript file paths.
  • sessions.session_scope, sessions.primary_conversation_id, conversations, and session_conversations are the typed routing source of truth. session_key remains a routing/display key, not a parsing surface for hidden provider identity.
  • Active transcript read/write paths should use transcript_events and transcript_event_identities; JSONL transcript helpers should be limited to doctor import/export/debug materialization.
  • Legacy sessions.json, .jsonl, .jsonl.lock, pruning/truncation files, auth profile files, model catalog files, and old sidecar stores should appear only in doctor migration, backup/import, or explicit legacy tests.
  • SQLite schema changes must be reflected in generated SQL modules and Kysely database types.
  • Kysely is the expected typed query boundary. Raw SQLite use should stay in low-level openers, transaction helpers, generated-schema plumbing, or deliberately tiny runtime wrappers.

Important non-goals

  • This does not move openclaw.json into SQLite.
  • This does not move plugin manifests or user workspaces into SQLite.
  • This does not introduce runtime dual-read compatibility for old file state.
  • This does not add shipped database migrations for the new layout; schema version remains 1 because this layout has not shipped yet.
  • This does not change dependency/package-manager/engine policy from main.

Real behavior proof

  • Behavior addressed: database-first SQLite runtime refactor is back in a clean review PR after the accidental direct landing was reverted from main.
  • Real environment tested: local macOS checkout on Node/pnpm, using a fresh temporary OPENCLAW_HOME so runtime state is isolated from the maintainer profile.
  • Exact steps or command run after this patch: OPENCLAW_HOME=$(mktemp -d) pnpm openclaw doctor
  • Evidence after fix: terminal output from the real OpenClaw CLI run after this patch:
$ OPENCLAW_HOME=<temp-openclaw-home> pnpm openclaw doctor
$ node scripts/run-node.mjs doctor
[openclaw] Building TypeScript (dist is stale: missing_build_stamp - build stamp missing).
runtime-postbuild: plugin SDK root alias completed in 1ms
runtime-postbuild: bundled plugin metadata completed in 137ms
runtime-postbuild: official channel catalog completed in 5ms
runtime-postbuild: bundled plugin runtime overlay completed in 221ms
runtime-postbuild: static extension assets completed in 21ms
runtime-postbuild: stable root runtime imports completed in 136ms
runtime-postbuild: stable root runtime aliases completed in 25ms
runtime-postbuild: legacy root runtime compat aliases completed in 5ms
runtime-postbuild: legacy CLI exit compat chunks completed in 0ms
OpenClaw doctor
State integrity:
- Active state dir: $OPENCLAW_HOME/.openclaw
Gateway connection:
- Gateway target: ws://127.0.0.1:18789
- Source: local loopback
- Config: <temp-openclaw-home>/.openclaw/openclaw.json
Doctor complete.
  • Observed result after fix: the CLI built and completed the doctor path against the isolated temp state directory; no dependency install or package-manager mutation was needed.
  • What was not tested: no broad Docker/live gateway run in this cleanup PR pass.

Verification

  • pnpm check:database-first-legacy-stores
  • pnpm db:kysely:check
  • pnpm lint:kysely
  • git diff --check && node scripts/check-no-conflict-markers.mjs
  • Custom package-manifest proof: dependency/package-manager/engine fields unchanged across 13 changed package manifests.

Review notes

  • The diff is intentionally large because it is the reapply of the reverted database-first branch plus one cleanup commit.
  • Commit 1 reapplies the SQLite runtime-state refactor.
  • Commit 2 removes a duplicate Docker test script.
  • Main revert commit: 694ca50 (Revert "refactor: move runtime state to SQLite").
  • Supersedes the merged/reverted PR Refactor runtime state into SQLite #78595 with a clean reviewable PR.

@steipete
steipete requested review from a team as code owners May 13, 2026 12:36
@github-actions github-actions Bot added the dependencies-changed PR changes dependency-related files label May 13, 2026
@github-actions

github-actions Bot commented May 13, 2026

Copy link
Copy Markdown
Contributor

Dependency Changes Detected

This PR changes dependency-related files. Maintainers should confirm these changes are intentional.

Changed files:

  • extensions/acpx/npm-shrinkwrap.json
  • extensions/amazon-bedrock-mantle/npm-shrinkwrap.json
  • extensions/anthropic-vertex/npm-shrinkwrap.json
  • extensions/clickclack/package.json
  • extensions/diffs/npm-shrinkwrap.json
  • extensions/discord/package.json
  • extensions/feishu/npm-shrinkwrap.json
  • extensions/feishu/package.json
  • extensions/imessage/package.json
  • extensions/matrix/npm-shrinkwrap.json
  • extensions/matrix/package.json
  • extensions/msteams/npm-shrinkwrap.json
  • extensions/msteams/package.json
  • extensions/nostr/package.json
  • extensions/qqbot/package.json
  • extensions/slack/npm-shrinkwrap.json
  • extensions/telegram/package.json
  • extensions/tlon/npm-shrinkwrap.json
  • extensions/whatsapp/package.json
  • extensions/zalouser/npm-shrinkwrap.json
  • npm-shrinkwrap.json
  • package.json
  • packages/memory-host-sdk/package.json
  • packages/plugin-sdk/package.json
  • pnpm-lock.yaml

Maintainer follow-up:

  • Review whether the dependency changes are intentional.
  • Inspect resolved package deltas when lockfile, shrinkwrap, or workspace dependency policy changes are present.
  • Treat package-lock.json and npm-shrinkwrap.json diffs as security-review surfaces.
  • Run pnpm deps:changes:report -- --base-ref origin/main --markdown /tmp/dependency-changes.md --json /tmp/dependency-changes.json locally for detailed release-style evidence.

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation channel: discord Channel integration: discord channel: googlechat Channel integration: googlechat channel: imessage Channel integration: imessage channel: line Channel integration: line channel: matrix Channel integration: matrix channel: mattermost Channel integration: mattermost channel: msteams Channel integration: msteams channel: nextcloud-talk Channel integration: nextcloud-talk channel: nostr Channel integration: nostr channel: signal Channel integration: signal channel: slack Channel integration: slack channel: telegram Channel integration: telegram channel: tlon Channel integration: tlon channel: voice-call Channel integration: voice-call channel: whatsapp-web Channel integration: whatsapp-web channel: zalo Channel integration: zalo channel: zalouser Channel integration: zalouser app: android App: android app: ios App: ios app: macos App: macos app: web-ui App: web-ui gateway Gateway runtime extensions: diagnostics-otel Extension: diagnostics-otel extensions: llm-task Extension: llm-task extensions: memory-core Extension: memory-core labels May 13, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0694638fe9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/e2e/lib/plugins/assertions.mjs Outdated
const config = fs.existsSync(configPath) ? readJson(configPath) : {};
const allowLegacyCompat = process.env.OPENCLAW_PACKAGE_ACCEPTANCE_LEGACY_COMPAT === "1";
if (!allowLegacyCompat && !index.installRecords) {
const index = readInstalledPluginIndex();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Import the SQLite index helpers before use

In this package-acceptance assertions script, the new SQLite-backed reads call readInstalledPluginIndex, writeInstalledPluginIndex, and readInstalledPluginRecords, but this file never imports or defines those helpers (unlike the sibling probes that import ../installed-plugin-index.mjs). Any command path that reaches install-record checks now throws ReferenceError before validating plugin install/uninstall behavior.

Useful? React with 👍 / 👎.

const storePath = path.join(sessionsDir, "sessions.json");
const store = readJson(storePath);
const entry = Object.values(store).find((candidate) => candidate?.sessionId === sessionId);
const entry = readAgentSessionEntryBySessionId(sessionId);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Define the SQLite session assertion helpers

This Codex npm live assertion now calls readAgentSessionEntryBySessionId (and later countAgentTranscriptEvents / readPluginStateJson), but none of those helpers are imported or defined in this script or its existing codex-install-utils.mjs import. The assert-agent-turn phase therefore fails with ReferenceError after the agent turn succeeds, so the live Codex npm plugin lane can no longer complete.

Useful? React with 👍 / 👎.

const authRaw = fs.readFileSync(authPath, "utf8");
if (!authRaw.includes("OPENAI_API_KEY")) {
const authAgentDir = path.join(stateDir(), "agents", "main", "agent");
const authStore = readAuthProfileStorePayload(authAgentDir);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Add the auth-profile SQLite reader before calling it

The Codex on-demand assertion was switched to read the auth profile from SQLite, but readAuthProfileStorePayload is not defined or imported in this file. When this assertion script runs, it reaches this line after install/model checks and aborts with ReferenceError instead of validating the persisted auth profile.

Useful? React with 👍 / 👎.

const index = fs.existsSync(indexPath) ? readJson(indexPath) : {};
const cfg = fs.existsSync(configPath()) ? readJson(configPath()) : {};
return index.installRecords || index.records || cfg.plugins?.installs || {};
return withSqliteDatabase(stateDatabasePath(), (db) => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Restore SQLite transcript helper definitions

The live plugin tool assertion now depends on withSqliteDatabase and stateDatabasePath here (and readMainAgentTranscript later), but this script does not import or define any of them. As a result, both install-record lookup and transcript validation paths fail immediately with ReferenceError, breaking the live plugin tool E2E lane.

Useful? React with 👍 / 👎.

assertOpenAiRequestLogUsed,
} from "../agent-turn-output.mjs";
import { applyMockOpenAiModelConfig } from "../fixtures/mock-openai-config.mjs";
import { DatabaseSync } from "node:sqlite";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep the agent-turn assertion imports

This import block dropped assertAgentReplyContainsMarker and assertOpenAiRequestLogUsed, but assertAgentTurn still calls both helpers later in the same file. The npm onboard channel-agent scenario will therefore fail with ReferenceError during its agent-turn verification instead of checking the reply marker and mock OpenAI request log.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 11715d136b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

struct CronSchedulerStatus: Decodable {
let enabled: Bool
let storePath: String
let storeKey: String

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Decode the existing cron.status storePath field

When the gateway is current, cron.status still returns storePath from src/cron/service/ops.ts:249-251 / CronStatusSummary, not storeKey. This required storeKey field makes cronStatus() fail decoding; CronJobsStore.refreshJobs catches that with try?, so the macOS Cron UI silently loses scheduler enabled/next-wake status whenever it talks to the existing gateway. Either keep decoding storePath here or add a compatibility decoder while the wire response is unchanged.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 93dfb037aa

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

public struct OpenClawChatSessionsListResponse: Codable, Sendable {
public let ts: Double?
public let path: String?
public let databasePath: String?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Decode sessions.list path into databasePath

When MacGatewayChatTransport.listSessions decodes the live gateway response, the gateway still sends path for sessions.list (SessionsListResultBase and listSessionsFromStoreAsync both use path), but this renamed Codable model has no CodingKeys fallback from path to databasePath. As a result decoded.databasePath is always nil for current gateways before WebChatSwiftUI forwards it, unlike the nearby macOS session/health decoders that preserve the old wire key.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8e0c82f463

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/install-cli.sh
fi
MIN_NODE_VERSION="22.19.0"
APK_NODE_BIN_DIR="/usr/bin"
SHARP_IGNORE_GLOBAL_LIBVIPS="${SHARP_IGNORE_GLOBAL_LIBVIPS:-1}"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Export the sharp libvips override for npm installs

When SHARP_IGNORE_GLOBAL_LIBVIPS is not already present in the environment, this assignment creates only a shell-local variable, and the later env ... npm install invocations do not inherit it. On hosts with a system libvips that sharp would otherwise try to use, the installer still behaves as if the default override were absent; export this value or pass it in the env command that launches npm.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9ae4443956

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

}
const authRaw = fs.readFileSync(authPath, "utf8");
if (!authRaw.includes("OPENAI_API_KEY")) {
const authStore = readAuthProfileStorePayload(stateDir, agentDir);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Read the file-backed auth profile store in onboarding E2E

In the npm onboard Docker lane (scripts/e2e/npm-onboard-channel-agent-docker.sh:160), this runs right after onboarding, but the current auth-profile writer is still file-backed: updateAuthProfileStoreWithLock creates auth-profiles.json and saveAuthProfileStore writes that path (src/agents/auth-profiles/store.ts:752-763, src/agents/auth-profiles/store.ts:1086-1102). Since nothing writes an auth_profile_stores row for this path, this SQLite lookup returns undefined and the subsequent legacy-file rejection fails even when onboarding persisted the expected env ref.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d08909f06d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@@ -0,0 +1,26 @@
export {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Publish the new provider AI SDK subpaths

This adds a src/plugin-sdk/provider-ai.ts facade, but neither package.json exports nor scripts/lib/plugin-sdk-entrypoints.json include provider-ai (and the sibling new provider-ai-oauth/sqlite-runtime surfaces are omitted the same way). In a published package, an external or bundled plugin importing openclaw/plugin-sdk/provider-ai will hit ERR_PACKAGE_PATH_NOT_EXPORTED even though the facade exists in source, so the SDK entrypoint list/package exports need to be updated with the new subpaths.

Useful? React with 👍 / 👎.

@RomneyDa

RomneyDa commented Jun 15, 2026

Copy link
Copy Markdown
Member

Updated this PR for the YAML-only QA scenario format in commit 2d01479053.

Change made:

  • Converted the six PR-touched SQLite/memory QA scenarios from qa/scenarios/**/*.md fenced blocks to qa/scenarios/**/*.yaml with top-level title, scenario, and flow keys.
  • Preserved the PR intent around SQLite-backed runtime state, memory heartbeat, dreaming sweep, ranking, active-memory preprompt recall, config setup, and stale child-link expectations.
  • Parsed the converted YAML files and ran git diff --check -- qa/scenarios before pushing.

I was not able to make a normal merge commit from current origin/main in this worktree because Git reported no local merge base and refused the merge as unrelated histories. This commit removes the scenario-format request from my side, but the PR may still need its broader branch rebase/merge resolved separately.

@steipete

steipete commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

Closing this broad branch in favor of the incremental database-first work now on main.

The branch is 333 files (+9,503/-4,514) and currently 7,775 commits behind main. Its core direction still makes sense, but the implementation has been overtaken by smaller owner-scoped landings, including SQLite subagent, cron, auth-profile, plugin-binding, memory/proxy, and doctor-migration work (#88260, #88285, #89102, #88945, #91629, #94646). Current main now has the shared state DB/Kysely seams and focused migration contracts this branch was trying to introduce wholesale.

The supported path is to keep landing any remaining storage gaps as narrow owner-boundary changes with explicit doctor migration and focused upgrade proof. A concrete missing shared seam that cannot be delivered incrementally would be reason to revisit; rebasing this 333-file snapshot is not.

Preserving the branch for history, but closing the PR as superseded by the incremental architecture on main.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling app: android App: android app: ios App: ios app: macos App: macos app: web-ui App: web-ui channel: discord Channel integration: discord channel: matrix Channel integration: matrix channel: telegram Channel integration: telegram channel: whatsapp-web Channel integration: whatsapp-web docker Docker and sandbox tooling docs Improvements or additions to documentation extensions: qa-lab extensions: tts-local-cli gateway Gateway runtime maintainer Maintainer-authored PR mantis: telegram-visible-proof Mantis should capture Telegram visible proof. merge-risk: 🚨 auth-provider 🚨 May break OAuth, tokens, provider routing, model choice, or credentials. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. P1 High-priority user-facing bug, regression, or broken workflow. plugin: azure-speech Azure Speech plugin plugin: file-transfer plugin: migrate-claude plugin: migrate-hermes rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. scripts Repository scripts security Security documentation size: XL status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants