Skip to content

Commit 9f3748c

Browse files
committed
channels: make plugin state persistence best effort by default
Build the alternative default-on version of the bundled plugin state migration. The four migrated caches now keep their existing in-memory fast paths as the source of truth and automatically try the SDK-backed keyed store once their plugin runtime is available. If opening SQLite or a store operation fails, the plugin logs once for that path, disables further persistent access for the process, and keeps the previous process-local behavior. This removes the experimentalPersistentState plugin config gate and the cfg threading that only existed for that opt-in. Slack/MS Teams continue to backfill memory after restart lookups; Discord keeps consume/delete semantics; Matrix keeps versioned approval reaction targets. Tests cover both available persistent stores and unavailable SQLite fallback. Validation: targeted plugin cache tests, relevant call-site tests, oxfmt check, and pnpm check:changed.
1 parent f0b8ac6 commit 9f3748c

28 files changed

Lines changed: 361 additions & 413 deletions

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ Docs: https://docs.openclaw.ai
2727
- Providers/NVIDIA: add the NVIDIA provider with API-key onboarding, setup docs, static catalog metadata, and literal model-ref picker support so NVIDIA hosted models can be selected with their provider prefix intact. (#71204) Thanks @eleqtrizit.
2828
- Models: suppress explicitly configured openai-codex/gpt-5.4-mini inline entries so a stale models config written by `openclaw doctor --fix` cannot bypass the manifest capability block and cause repeated assistant-turn failures when the runtime switches to that model on ChatGPT-backed Codex accounts. Conditional suppressions (e.g. qwen Coding Plan endpoint guards) remain bypassable by explicit user configuration. (#74451) Thanks @0xCyda, @hclsys, and @Marvae.
2929
- Added SQLite-backed plugin state store (`api.runtime.state.openKeyedStore`) for restart-safe keyed registries with TTL, eviction, and automatic plugin isolation. Thanks @amknight.
30-
- Channels/plugins: add opt-in SDK-backed persistent state for Slack thread participation, Discord component/modal registries, Microsoft Teams sent-message markers, and Matrix approval reaction targets while keeping process-local caches as the default and warming hot in-memory paths after restart lookups. Thanks @amknight.
30+
- Channels/plugins: add best-effort SDK-backed persistent state behind in-memory caches for Slack thread participation, Discord component/modal registries, Microsoft Teams sent-message markers, and Matrix approval reaction targets, with fallback to process-local behavior when SQLite is unavailable. Thanks @amknight.
3131
- Plugin SDK: mark remaining legacy alias exports and diffs tool/config aliases with deprecation metadata, and add a guard so future legacy alias comments require `@deprecated` tags. Thanks @vincentkoc.
3232
- CLI/QR/dependencies: internalize small terminal progress and QR wrapper helpers while keeping the real QR encoder dependency direct, reducing the default runtime dependency graph without changing QR output behavior. Thanks @vincentkoc.
3333
- Dependencies: refresh workspace runtime, plugin, and tooling packages, including ACP, Pi, AWS SDK, TypeBox, pnpm, oxlint, oxfmt, jsdom, pdfjs, ciao, and tokenjuice, while keeping patched ACP behavior and lint gates current. Thanks @mariozechner.

docs/channels/discord.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ Supported blocks:
348348

349349
By default, components are single use. Set `components.reusable=true` to allow buttons, selects, and forms to be used multiple times until they expire.
350350

351-
Set `plugins.entries.discord.config.experimentalPersistentState: true` to opt in to the experimental SDK-backed persistent component/modal registry, so valid buttons, selects, and forms can survive a Gateway restart until their normal TTL expires. The default remains the previous process-local registry.
351+
Discord component and modal registries use best-effort SDK-backed persistent state behind the in-memory registry, so valid buttons, selects, and forms can survive a Gateway restart until their normal TTL expires. If the persistent store is unavailable or fails, Discord logs the failure and keeps the previous process-local registry behavior.
352352

353353
To restrict who can click a button, set `allowedUsers` on that button (Discord user IDs, tags, or `*`). When configured, unmatched users receive an ephemeral denial.
354354

docs/channels/matrix.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -699,7 +699,7 @@ Both kinds share Matrix reaction shortcuts and message updates. Approvers see re
699699

700700
Fallback slash commands: `/approve <id> allow-once`, `/approve <id> allow-always`, `/approve <id> deny`.
701701

702-
Set `plugins.entries.matrix.config.experimentalPersistentState: true` to opt in to the experimental SDK-backed persistent reaction-target cache. With the opt-in, reactions on still-pending approval prompts can resolve after a Gateway restart; by default OpenClaw keeps the previous process-local cache.
702+
Matrix approval reaction targets use best-effort SDK-backed persistent state behind the in-memory cache. Reactions on still-pending approval prompts can resolve after a Gateway restart; if the persistent store is unavailable or fails, OpenClaw logs the failure and keeps the previous process-local cache behavior.
703703

704704
Only resolved approvers can approve or deny. Channel delivery for exec approvals includes the command text — only enable `channel` or `both` in trusted rooms.
705705

docs/channels/msteams.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,7 @@ Key settings (see `/gateway/configuration` for shared channel patterns):
710710
- `channels.msteams.managedIdentityClientId`: client ID for user-assigned managed identity.
711711
- `channels.msteams.sharePointSiteId`: SharePoint site ID for file uploads in group chats/channels (see [Sending files in group chats](#sending-files-in-group-chats)).
712712

713-
Set `plugins.entries.msteams.config.experimentalPersistentState: true` to opt in to the experimental SDK-backed persistent sent-message cache. With the opt-in, replies to recent bot-sent Teams messages can still be classified as `reply_to_bot` after a Gateway restart; by default OpenClaw keeps the previous process-local cache.
713+
Microsoft Teams sent-message markers use best-effort SDK-backed persistent state behind the in-memory cache. Replies to recent bot-sent Teams messages can still be classified as `reply_to_bot` after a Gateway restart; if the persistent store is unavailable or fails, OpenClaw logs the failure and keeps the previous process-local cache behavior.
714714

715715
## Routing & Sessions
716716

docs/channels/slack.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,7 @@ Current Slack message actions include `send`, `upload-file`, `download-file`, `r
594594
- `channels.slack.thread.historyScope` default is `thread`; `thread.inheritParent` default is `false`.
595595
- `channels.slack.thread.initialHistoryLimit` controls how many existing thread messages are fetched when a new thread session starts (default `20`; set `0` to disable).
596596
- `channels.slack.thread.requireExplicitMention` (default `false`): when `true`, suppress implicit thread mentions so the bot only responds to explicit `@bot` mentions inside threads, even when the bot already participated in the thread. Without this, replies in a bot-participated thread bypass `requireMention` gating.
597-
- Experimental restart-safe thread participation: set `plugins.entries.slack.config.experimentalPersistentState: true` to opt in to the SDK-backed persistent cache for bot-participated thread markers. The default remains the previous process-local cache.
597+
- Restart-safe thread participation: Slack uses best-effort SDK-backed persistent state behind the in-memory cache for bot-participated thread markers, so thread auto-reply context can survive a Gateway restart. If the persistent store is unavailable or fails, Slack logs the failure and keeps the previous process-local cache behavior.
598598

599599
Reply threading controls:
600600

docs/plugins/sdk-runtime.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ Provider and channel execution paths must use the active runtime config snapshot
414414

415415
Keyed stores survive restarts and are isolated by the runtime-bound plugin id. Limits: `maxEntries` per namespace, 1,000 live rows per plugin, JSON values under 64KB, and optional TTL expiry.
416416

417-
Early bundled-plugin migrations are deliberately opt-in. Set `plugins.entries.<pluginId>.config.experimentalPersistentState: true` to let Slack thread participation, Discord component/modal registries, Microsoft Teams sent-message markers, or Matrix approval reaction targets use this SDK-backed store; otherwise those plugins keep their previous process-local caches.
417+
Early bundled-plugin migrations use the store as best-effort durability behind existing in-memory caches. Slack thread participation, Discord component/modal registries, Microsoft Teams sent-message markers, and Matrix approval reaction targets try this SDK-backed store automatically after their plugin runtime is available; if SQLite is unavailable or an operation fails, they log and keep the previous process-local behavior.
418418

419419
<Warning>
420420
Bundled plugins only in this release.

extensions/discord/openclaw.plugin.json

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,6 @@
1010
"configSchema": {
1111
"type": "object",
1212
"additionalProperties": false,
13-
"properties": {
14-
"experimentalPersistentState": {
15-
"type": "boolean",
16-
"description": "Opt in to the experimental SDK-backed persistent state store for Discord runtime caches."
17-
}
18-
}
13+
"properties": {}
1914
}
2015
}

0 commit comments

Comments
 (0)