fix(openclaw): claim plugins.slots.memory via registerMemoryCapability#310
Conversation
The OpenClaw integration declared kind: "memory" in its manifest and
wired before_agent_start / agent_end hooks, but never called
api.registerMemoryCapability(...). On OpenClaw 2026.4.9+ that
left plugins.slots.memory = "agentmemory" reporting unavailable
even though the hooks worked end-to-end and the REST API was
healthy.
Per OpenClaw's plugin SDK declarations
(plugin-sdk/src/plugins/types.d.ts), api.registerMemoryCapability
takes a MemoryPluginCapability and is the canonical way to occupy
the memory slot. All capability fields are optional. The
promptBuilder field has signature:
(params: { availableTools: Set<string>; citationsMode? }) => string[]
This commit:
- Calls api.registerMemoryCapability({ promptBuilder }) at register
time when the host exposes it. promptBuilder returns three lines
describing agentmemory as the active memory provider, including
the configured base_url so the agent knows where recall is
coming from.
- Guards on `typeof api.registerMemoryCapability === "function"`
so older OpenClaw builds (pre-capability API) still load via
the existing hook-only path. Net behaviour on older hosts is
unchanged.
- Does NOT register a runtime adapter. OpenClaw's current
MemoryRuntimeBackendConfig type is exactly { backend: "builtin" }
or { backend: "qmd"; qmd?: { command?: string } }; both are
in-process backends and don't fit an external REST service.
The hook-driven recall + capture flow is the working
integration path; runtime registration is documented as a
follow-up gated on an upstream OpenClaw change to add an
"external" backend variant.
README troubleshooting block adds a specific entry for the
"unavailable slot" symptom, pointing at the registerMemoryCapability
fix. The README also documents the runtime-adapter scope decision
so users running deep host integrations aren't surprised.
3 new tests in test/openclaw-plugin.test.ts assert:
1. registerMemoryCapability is called with a promptBuilder when
the host supports it.
2. Plugin still registers hooks and does not throw on older hosts
that don't expose registerMemoryCapability.
3. promptBuilder respects the configured base_url.
871 / 871 tests pass.
Verified against the openclaw npm package surface:
- api.registerMemoryCapability is declared at
plugin-sdk/src/plugins/types.d.ts:2028
- MemoryPluginCapability is declared at
plugin-sdk/src/plugins/memory-state.d.ts
- promptBuilder signature matches MemoryPromptSectionBuilder
- No import from openclaw/extensions/* needed (and that path is
not in the package's exports map anyway)
This is a fresh implementation. The closed PR #302 attempted the
same end goal but imported memoryRuntime from a non-existent
path (openclaw/extensions/memory-core/runtime-api) and would have
failed with ERR_PACKAGE_PATH_NOT_EXPORTED at load time.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Caution Review failedPull request was closed or merged during review No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe OpenClaw plugin now claims the ChangesOpenClaw memory capability registration
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related issues
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@integrations/openclaw/plugin.mjs`:
- Around line 126-132: The promptBuilder currently has the wrong signature
(defined as () => [...]) which violates the expected contract; update the
promptBuilder function to accept a params object parameter (e.g., ({
availableTools }: { availableTools: Set<string> }) or similar) so it matches the
test/type expectations, and if you don't need to use availableTools yet, accept
it and optionally reference or ignore it explicitly to avoid unused-argument
warnings; locate and update the promptBuilder definition in the OpenClaw plugin
(symbol: promptBuilder) to accept and propagate the params argument.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: a277b1a8-b4ce-4d23-bf69-4181b94b16ce
📒 Files selected for processing (3)
integrations/openclaw/README.mdintegrations/openclaw/plugin.mjstest/openclaw-plugin.test.ts
…ptSectionBuilder Reviewer flagged that promptBuilder was declared as () => [...] which doesn't match the MemoryPluginCapability contract verified from [email protected] (plugin-sdk/src/plugins/memory-state.d.ts): type MemoryPromptSectionBuilder = (params: { availableTools: Set<string>; citationsMode?: MemoryCitationsMode; }) => string[]; JavaScript would tolerate the zero-arg form at runtime (extra args are ignored), but the signature was misleading and would fail a TypeScript port. Updated to (_params) => [...] with a comment explaining we accept-but-ignore. Underscore-prefix conveys intentional non-use to lint/readers. Validation: 3/3 openclaw tests still pass (they invoke promptBuilder({ availableTools: new Set() }) — both old and new signatures accept that call).
… website star button (#317) Three landed PRs since v0.9.10: - #311 — Codex plugin support (manifest + marketplace + Codex-shaped hooks subset, sharing the same scripts as the Claude Code plugin via CLAUDE_PLUGIN_ROOT OOTB-compat injection on Codex's hook engine) - #310 — OpenClaw plugins.slots.memory now actually claimed via api.registerMemoryCapability({ promptBuilder }); older builds without the capability API still load via the existing hook-only path - #316 — Star on GitHub button in the website hero CTA row, live stargazer count via api.github.com, 30-minute localStorage cache, graceful degrade on API failure Bumping 0.9.10 -> 0.9.11 across the 8 standard files: - package.json - packages/mcp/package.json - plugin/.claude-plugin/plugin.json - plugin/.codex-plugin/plugin.json - src/version.ts - src/types.ts (ExportData.version literal) - src/functions/export-import.ts (supportedVersions) - test/export-import.test.ts (round-trip expectation) - CHANGELOG.md (new 0.9.11 entry) 877 / 877 tests pass. Build clean.
Problem
The OpenClaw integration declared
"kind": "memory"in its manifest and wiredbefore_agent_start/agent_endhooks, but never calledapi.registerMemoryCapability(...). On OpenClaw2026.4.9+,plugins.slots.memory = "agentmemory"reportedunavailabledespite hooks running end-to-end and the REST API being healthy.Verified API contract
Pulled
[email protected]and read the type declarations directly:All capability fields are optional.
promptBuilderalone is enough to claim the slot.Changes
integrations/openclaw/plugin.mjstypeof api.registerMemoryCapability === "function"so older OpenClaw builds (pre-capability API) still load via the existing hook-only path. Net behaviour on older hosts unchanged.base_urlin the prompt so the agent knows where recall is coming from.integrations/openclaw/README.mdAdds an explicit troubleshooting entry for
plugins.slots.memory = "agentmemory" reports unavailable, points at this fix. Documents the runtime-adapter scope decision so users running deep host integrations aren't surprised.test/openclaw-plugin.test.ts(new, 3 cases)registerMemoryCapabilityis called with apromptBuilderwhen the host supports it.registerMemoryCapability.promptBuilderrespects the configuredbase_url.What this PR does NOT do
Does not register a
runtimeadapter. OpenClaw's currentMemoryRuntimeBackendConfigtype is:Both variants are in-process backends. There's no
"external"option that fits agentmemory's REST shape. The hook-driven recall + capture flow remains the working integration path; full runtime registration is documented as a follow-up gated on an upstream OpenClaw change to add an"external"backend variant.Why a fresh PR, not #302
The closed PR #302 attempted the same end goal but:
memoryRuntimefromopenclaw/extensions/memory-core/runtime-api— a path not in the package'sexportsmap. Would have failed withERR_PACKAGE_PATH_NOT_EXPORTEDat load time.memoryRuntimesymbol that does not exist anywhere in[email protected].This PR uses only
api.registerMemoryCapability(...)directly off the api object the plugin init receives — no openclaw imports needed.Test plan
npm test— 871 / 871 (868 baseline + 3 new tests).npm run build— tsdown clean.2026.4.9+install:plugins.slots.memory = "agentmemory"should now show as available; the prompt-section builder lines should appear in the assembled system prompt.unavailablestill reports after this lands, file follow-up with the exact OpenClaw build's slot-status check (might need additional optional capability fields).Closes the bug premise originally reported in PR #302 (without picking up that PR's broken implementation).
Summary by CodeRabbit
New Features
Documentation
Tests