Repository navigation
fix(memory): OpenClaw plugin accepts profile: expert, which hides three of its four contract tools #3237
Description
Component
memory
What happened?
The OpenClaw adapter accepts profile: "expert" in plugins.entries["memory-anolisa"].config and forwards it to the child as MEMORY_PROFILE, but expert is the one profile that hides the tools this plugin is built on.
src/agent-memory/src/config.rs::Profile::tool_visible hides Tier B under expert at both tools/list and tools/call (pinned by tests/profile_test.rs::expert_profile_hides_tier_b), and three of the four tools the plugin registers for the host's memory contract are exactly that list. Measured against main @ a3e641a3:
MEMORY_PROFILE=advanced tools/list -> 37 tools
MEMORY_PROFILE=expert tools/list -> 31 tools
MEMORY_PROFILE=expert:
tools/call memory_search -> -32601 tool 'memory_search' is not exposed under the Expert profile
tools/call memory_observe -> -32601 tool 'memory_observe' is not exposed under the Expert profile
tools/call memory_get_context -> -32601 tool 'memory_get_context' is not exposed under the Expert profile
tools/call mem_read -> ok # what memory_get maps to
So an operator who sets expert — a value the plugin's own configSchema.properties.profile.enum offers and the user guide lists as basic | advanced | expert — does not get "file tools only". The plugin loads, logs plugin registered (... profile=expert ...), registers all four tools plus both hooks, and then:
memory_search/memory_observe/memory_get_contextanswer with the error string inside every tool result;- the auto-recall hook (
before_prompt_build) fails on every prompt, once per recall candidate, and logs a warning each time; - the
corpus=allsupplement catches the same error and returns no hits, so the host's memory corpus silently loses this backend; - only
memory_getstill works.
Nothing at boot says any of this. The adapter exposes exactly one Tier A tool and cannot expose the rest without breaking the contract the host selected it for, so expert is not a profile this adapter can honor at all — it belongs to direct MCP clients that drive Tier A themselves.
What I expected: setting profile: "expert" on the OpenClaw plugin either works or fails at plugin load with a message naming the reason, not a memory slot that loads and then fails per call.
How can we reproduce it?
make -C src/agent-memory buildand install the OpenClaw adapter (install.shoranolisa adapter enable agent-memory openclaw).- Set
plugins.entries["memory-anolisa"].config.profile = "expert"inopenclaw.json. openclaw gateway restart, then callmemory_searchfrom the agent (or watch the gateway log for the auto-recall warnings on the next prompt).- Observe
Search error: tool 'memory_search' is not exposed under the Expert profileand an emptycorpus=allsupplement, whilememory_getstill answers.
The child-side half is reproducible without the host:
MEMORY_PROFILE=expert MEMORY_BASE_DIR=/tmp/m MEMORY_SESSION_DIR=/tmp/s \
agent-memory serve # then tools/list and tools/call memory_search over stdioDiagnostic output
$ git rev-parse --short HEAD
a3e641a3
$ grep -n 'profile' src/agent-memory/adapters/agent-memory/openclaw/src/config.ts
20: profile: "basic" | "advanced" | "expert";
108: if (s === "basic" || s === "advanced" || s === "expert") {
$ grep -n 'MEMORY_PROFILE' src/agent-memory/adapters/agent-memory/openclaw/src/mcp-client.ts
198: MEMORY_PROFILE: this.config.profile,Anything else?
Suggested fix, in the adapter rather than in the server (the server's gate is correct for direct MCP clients):
- reject
profile: "expert"inresolveConfig, which is where this module already fails on config the child would interpret differently than the operator meant (48d10029,a3e641a3). The host catches a throw fromregister()and logs[plugins] memory-anolisa failed during register from <source>: <message>, so the reason reaches the operator. - drop
expertfromconfigSchema.properties.profile.enumso the Control UI stops offering a value whose only effect is a plugin that fails to load, and keep the resolver check for hosts that do not validate config against the schema. - record the restriction next to the profile tables in
docs/user-guide/{en,zh}/token-saving/agent-memory.mdand the component READMEs.
Deliberately out of scope: profile leniency for unrecognized values (a typo still falls back to advanced), and the METHOD_NOT_FOUND troubleshooting row, which describes the direct-MCP path and stays accurate.
Activity
github-actions commentedon Sep 11, 2026
🔀 Issue Router
memory99%问题涉及 Agent Memory 的 OpenClaw 适配器 profile 配置与工具暴露行为。
Evidence: 标题、组件选择及正文中的 src/agent-memory 路径和 memory 工具均明确指向 memory。
This routing was applied by the ANOLISA Issue Router through GitHub Actions.