Skip to content

feat(memory): pluggable system prompt section for memory plugins#40126

Merged
jalehman merged 12 commits intoopenclaw:mainfrom
jarimustonen:feat/memory-prompt-section-plugin-api
Mar 21, 2026
Merged

feat(memory): pluggable system prompt section for memory plugins#40126
jalehman merged 12 commits intoopenclaw:mainfrom
jarimustonen:feat/memory-prompt-section-plugin-api

Conversation

@jarimustonen
Copy link
Copy Markdown
Contributor

@jarimustonen jarimustonen commented Mar 8, 2026

Summary

  • Problem: The system prompt "Memory Recall" section is hardcoded in system-prompt.ts, providing memory-core-specific instructions. When a third-party memory plugin is active (via the exclusive memory slot), these instructions are misleading.
  • Why it matters: Third-party memory plugins need to provide their own system prompt guidance for their tools instead of the hardcoded memory-core instructions.
  • What changed: Added registerMemoryPromptSection(builder) to the plugin API. The active memory plugin registers its own system prompt builder callback. Moved the existing "Memory Recall" logic into memory-core as its registration. buildMemorySection() delegates to the registered callback.
  • What did NOT change (scope boundary): Default behavior is identical — memory-core registers the same prompt content. No changes to memory tools, compaction, or other plugin APIs.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

None

User-visible / Behavior Changes

None for default memory-core users. Memory plugins with kind: "memory" can now register a custom system prompt section via api.registerMemoryPromptSection(builder).

Security Impact (required)

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • New/changed network calls? No
  • Command/tool execution surface changed? No
  • Data access scope changed? No

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: Bun
  • Model/provider: N/A (system prompt wiring)
  • Integration/channel (if any): Telegram (for human test)

Steps

  1. Install a memory plugin that calls api.registerMemoryPromptSection(builder)
  2. Start a session
  3. Observe that the system prompt contains the plugin's memory section instead of the hardcoded one

Expected

  • With memory-core (default): system prompt contains "Memory Recall" section as before
  • With custom memory plugin: system prompt contains the plugin's custom section
  • With no memory plugin: memory section is omitted

Actual (before fix)

  • Hardcoded "Memory Recall" section always present regardless of active memory plugin

Evidence

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

New unit tests in prompt-section.test.ts: delegation, citationsMode passthrough, no-builder returns empty, last-registration-wins. All 43 existing system-prompt.test.ts tests pass.

Human Verification (required)

  • Verified scenarios: Tested on two separate OpenClaw bots (Telegram) with memory-core active — memory instructions present as expected, no regression observed
  • Edge cases checked: None
  • What you did not verify: No memory plugin active (section omitted), custom third-party memory plugin providing its own section

Compatibility / Migration

  • Backward compatible? Yes
  • Config/env changes? No
  • Migration needed? No

Failure Recovery (if this breaks)

  • How to disable/revert this change quickly: Revert the commit; hardcoded prompt returns
  • Files/config to restore: N/A
  • Known bad symptoms reviewers should watch for: Missing "Memory Recall" section in system prompt when memory-core is active

Risks and Mitigations

None. Additive API change. Default behavior is identical — memory-core registers the same prompt content it previously hardcoded.

@openclaw-barnacle openclaw-barnacle bot added extensions: lobster Extension: lobster extensions: memory-core Extension: memory-core agents Agent runtime and tooling extensions: phone-control size: S labels Mar 8, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 8, 2026

Greptile Summary

This PR makes the memory plugin's system prompt section pluggable by introducing a module-level registry (src/memory/prompt-section.ts) that memory plugins can register a builder callback into. The hardcoded "Memory Recall" logic is moved from system-prompt.ts into the memory-core plugin itself, preserving identical runtime behavior while enabling third-party memory plugins to supply their own prompt guidance.

Key changes:

  • New src/memory/prompt-section.ts singleton with registerMemoryPromptSection / buildMemoryPromptSection / _resetMemoryPromptSection (test escape hatch)
  • system-prompt.ts delegates to buildMemoryPromptSection; the isMinimal guard is correctly preserved
  • memory-core plugin calls api.registerMemoryPromptSection(buildPromptSection) on registration — behavior is identical to the previous hardcoded path
  • registerMemoryPromptSection is restricted to kind: "memory" plugins in the registry; however, the enforcement uses throw new Error(...) rather than the pushDiagnostic + return pattern used for every other constraint check in registry.ts, which is inconsistent and could cause an unhandled crash during plugin loading
  • Test mocks in diffs, lobster, and phone-control extension tests are correctly updated with a no-op stub
  • New unit tests cover: no-builder default, delegation, citationsMode passthrough, and last-registration-wins

Confidence Score: 4/5

  • Safe to merge with one minor fix recommended — the kind-enforcement in registry.ts should push a diagnostic instead of throwing.
  • The overall design is clean, the hardcoded logic is faithfully moved without behavioral change, and the new registry is well-tested. The single flagged issue (throw vs pushDiagnostic) is a style/consistency concern rather than a blocking bug, since in practice only memory plugins are expected to call this method. No data loss or regression risk is introduced.
  • src/plugins/registry.ts — the registerMemoryPromptSection guard throws instead of pushing a diagnostic, inconsistent with all other validation in this file.

Last reviewed commit: 01b4d60

Copy link
Copy Markdown

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

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: 01b4d60bac

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Copy link
Copy Markdown

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

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: 35703c4bfc

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@jarimustonen jarimustonen force-pushed the feat/memory-prompt-section-plugin-api branch from 37676db to 1afb607 Compare March 9, 2026 11:20
Copy link
Copy Markdown

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

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: 1afb6075dc

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Copy link
Copy Markdown

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

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: eb28f63a4b

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@jarimustonen jarimustonen force-pushed the feat/memory-prompt-section-plugin-api branch from bd409d1 to e1281f6 Compare March 15, 2026 16:20
Copy link
Copy Markdown

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

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: e1281f6cac

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@jalehman jalehman self-assigned this Mar 17, 2026
Copy link
Copy Markdown
Contributor

@jalehman jalehman left a comment

Choose a reason for hiding this comment

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

Changes Requested

Thank you for this contribution! We've reviewed this PR and have some feedback before it can move forward.

Reset the registered memory prompt section when clearing plugin loader cache

clearPluginLoaderCache() currently clears the plugin registry cache but leaves the active memory prompt section builder in place. That means stale memory-plugin instructions can survive a cache reset and still affect later system prompts. Please make the cache-clear path fully reset the memory prompt section state as well, and extend the tests to cover that reset behavior directly.

Rebase onto main and restore a green CI run

GitHub currently reports merge conflicts against main, and the PR is also failing check plus checks (node, channels, pnpm test:channels). Please rebase or merge main into the branch, resolve the conflict, and update the branch until the required checks are green so we can review the final behavior in a current branch state.


Once these are addressed, we'll re-review. Feel free to ask questions if anything is unclear.

@jarimustonen jarimustonen force-pushed the feat/memory-prompt-section-plugin-api branch from e1281f6 to a77b9b1 Compare March 18, 2026 09:10
Copy link
Copy Markdown

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

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: a77b9b152d

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Copy link
Copy Markdown

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

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: 46528f3e2e

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@jarimustonen jarimustonen force-pushed the feat/memory-prompt-section-plugin-api branch from 46528f3 to c3b2c5f Compare March 18, 2026 14:02
@jarimustonen
Copy link
Copy Markdown
Contributor Author

jarimustonen commented Mar 18, 2026

@jalehman

I now updated clearPluginLoaderCache(). It now resets the memory prompt builder, and the reload path clears it inside the shouldActivate guard. Also switched registerMemoryPromptSection to pushDiagnostic instead of throwing. I added unit tests.

I have a couple of points:

First, I have problems with CI even after rebasing to main: check, node test, and bun test are green but there are still errors. They seem to be unrelated to this PR, but main is fully green. I tried rebasing a couple of times. Can you please check this?

Second, I would like to raise a more general point: How about memory plugin would not support plugin reconfiguration during the runtime? Due to its nature (the internal funtionality assumes continuatity), memory-plugin is in a special position that it would make sense, to require that is does not change when openclaw is running. What do think about this?

@jarimustonen jarimustonen requested a review from jalehman March 18, 2026 15:12
@jalehman jalehman force-pushed the feat/memory-prompt-section-plugin-api branch from c3b2c5f to 80cc0b9 Compare March 20, 2026 13:57
@openclaw-barnacle openclaw-barnacle bot added the scripts Repository scripts label Mar 20, 2026
Copy link
Copy Markdown
Contributor

@jalehman jalehman left a comment

Choose a reason for hiding this comment

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

Rebased onto main and pushed merge-prep updates to the PR branch.

What changed:

  • restored memory prompt builder state across activate:false snapshot loads
  • rolled back newly-registered memory prompt state when plugin register() fails
  • exported the new openclaw/plugin-sdk/memory-core subpath so plugin-sdk boundary checks pass

Local verification on the rebased branch:

  • pnpm test -- src/plugins/loader.test.ts src/memory/prompt-section.test.ts extensions/memory-core/index.test.ts
  • pnpm check
  • pnpm build

I am intentionally not adding a try/catch wrapper around buildMemoryPromptSection(): for this surface, a broken memory-plugin prompt builder should still fail loudly during prompt assembly rather than silently degrade behavior.

Copy link
Copy Markdown

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

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: 80cc0b9c07

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +47 to +50
return buildMemoryPromptSection({
availableTools: params.availableTools,
citationsMode: params.citationsMode,
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve default Memory Recall section for prompt-only callers

This change makes buildAgentSystemPrompt() depend on a prior registerMemoryPromptSection() side effect, but there are still in-repo callers that synthesize memory_search/memory_get tool sets without loading plugins first (for example src/agents/prompt-composition-scenarios.ts:39-99). In those flows the default memory-core instructions now disappear unless some earlier code happened to populate the global builder, so prompt-composition fixtures become ambient-state-dependent instead of matching the default memory-core slot behavior.

Useful? React with 👍 / 👎.

@jalehman jalehman force-pushed the feat/memory-prompt-section-plugin-api branch from 80cc0b9 to 9fde296 Compare March 21, 2026 15:26
jalehman added a commit to jarimustonen/openclaw that referenced this pull request Mar 21, 2026
Regeneration-Prompt: |
  Refresh prepare for PR openclaw#40126 after origin/main advanced again during push. The refreshed base exposed a build failure unrelated to the memory prompt feature: src/memory/embeddings-openai.ts declared DEFAULT_OPENAI_EMBEDDING_MODEL twice after a recent mainline fix landed. Remove only the duplicate export so the rebased prep branch keeps the shared embedding default alias that memory sync expects while restoring a green build.
@jalehman jalehman force-pushed the feat/memory-prompt-section-plugin-api branch from ac6ac5e to 9cf4316 Compare March 21, 2026 16:38
Copy link
Copy Markdown

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

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: 9cf4316fd9

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +47 to +49
return buildMemoryPromptSection({
availableTools: params.availableTools,
citationsMode: params.citationsMode,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Clone availableTools before delegating to memory plugins

buildMemoryPromptSection() receives the live availableTools Set here, and buildAgentSystemPrompt() reuses that same Set later for sections like buildMessagingSection(). For third-party memory plugins, a perfectly plausible implementation is to mutate the set while narrowing it to memory-related tools (for example, deleting non-memory entries); that would silently remove unrelated prompt guidance such as the message section from the same request. Passing a cloned/read-only set into the memory callback would keep prompt assembly deterministic even when plugin code manipulates its inputs.

Useful? React with 👍 / 👎.

@jalehman jalehman force-pushed the feat/memory-prompt-section-plugin-api branch 2 times, most recently from 1be06c2 to e953198 Compare March 21, 2026 18:07
jarimustonen and others added 12 commits March 21, 2026 11:07
Add registerMemoryPromptSection to the plugin API so the active memory
plugin provides its own system prompt builder callback. The built-in
memory-core plugin registers the existing Memory Recall section via
this new API.

When no memory plugin is active (or a plugin does not register a
builder), the memory section is simply omitted from the system prompt.
This lets third-party memory plugins inject their own guidance at the
same position in the prompt.
Throw if a non-memory plugin attempts to register a memory prompt
section builder, enforcing the exclusive slot constraint at the API
level.
@jalehman jalehman force-pushed the feat/memory-prompt-section-plugin-api branch from e953198 to 5228d19 Compare March 21, 2026 18:12
@openclaw-barnacle openclaw-barnacle bot added the cli CLI command changes label Mar 21, 2026
Copy link
Copy Markdown

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

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: 5228d1937f

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@@ -1,11 +1,38 @@
import { definePluginEntry } from "openclaw/plugin-sdk/core";
import type { MemoryPromptSectionBuilder } from "openclaw/plugin-sdk/memory-core";
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Route memory-core SDK types through a local barrel

extensions/memory-core/index.ts now imports openclaw/plugin-sdk/memory-core from inside the extensions/memory-core package itself. The repo explicitly forbids this pattern in AGENTS.md ("inside an extension package, do not import that same extension via openclaw/plugin-sdk/<extension> from production files") because it pulls the package back through the SDK alias/export path instead of the local source graph. That makes future lazy-load/build refactors prone to duplicate-module or ineffective-dynamic-import regressions for this extension surface, which is why other extensions use local api.ts/runtime-api.ts barrels instead.

Useful? React with 👍 / 👎.

@jalehman jalehman merged commit fd2b3ed into openclaw:main Mar 21, 2026
39 checks passed
mrosmarin added a commit to mrosmarin/openclaw that referenced this pull request Mar 21, 2026
* main: (516 commits)
  fix: use content hash for memory flush dedup instead of compactionCount (openclaw#30115) (openclaw#34222)
  fix(tts): add matrix to VOICE_BUBBLE_CHANNELS (openclaw#37080)
  feat(memory): pluggable system prompt section for memory plugins (openclaw#40126)
  fix: detect nvm services from installed command (openclaw#51146)
  fix: handle Linux nvm CA env before startup (openclaw#51146) (thanks @GodsBoy)
  refactor: route Telegram runtime through plugin sdk (openclaw#51772)
  refactor: route iMessage runtime through plugin sdk (openclaw#51770)
  refactor: route Slack runtime through plugin sdk (openclaw#51766)
  refactor(doctor): extract provider and shared config helpers (openclaw#51753)
  Fix Discord `/codex_resume` picker expiration (openclaw#51260)
  fix(ci): remove duplicate embedding default export
  fix(ci): restore embedding defaults and plugin boundaries
  fix: compaction safeguard summary budget (openclaw#27727)
  web UI: fix context notice using accumulated inputTokens instead of prompt snapshot (openclaw#51721)
  fix(status): skip cold-start status probes
  refactor(doctor): extract telegram provider warnings (openclaw#51704)
  fix(telegram): default fresh setups to mention-gated groups
  docs(changelog): note telegram doctor first-run guidance
  fix(doctor): add telegram first-run guidance
  fix(doctor): suppress telegram fresh-install group warning
  ...
JohnJAS pushed a commit to JohnJAS/openclaw that referenced this pull request Mar 22, 2026
…nclaw#40126)

Merged via squash.

Prepared head SHA: 5228d19
Co-authored-by: jarimustonen <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman
pholpaphankorn pushed a commit to pholpaphankorn/openclaw that referenced this pull request Mar 22, 2026
…nclaw#40126)

Merged via squash.

Prepared head SHA: 5228d19
Co-authored-by: jarimustonen <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman
MaheshBhushan pushed a commit to MaheshBhushan/openclaw that referenced this pull request Mar 22, 2026
…nclaw#40126)

Merged via squash.

Prepared head SHA: 5228d19
Co-authored-by: jarimustonen <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman
frankekn pushed a commit to artwalker/openclaw that referenced this pull request Mar 23, 2026
…nclaw#40126)

Merged via squash.

Prepared head SHA: 5228d19
Co-authored-by: jarimustonen <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman
furaul pushed a commit to furaul/openclaw that referenced this pull request Mar 24, 2026
…nclaw#40126)

Merged via squash.

Prepared head SHA: 5228d19
Co-authored-by: jarimustonen <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman
Interstellar-code pushed a commit to Interstellar-code/operator1 that referenced this pull request Mar 24, 2026
…nclaw#40126)

Cherry-picked from fd2b3ed.
Conflict resolution: Took upstream's buildMemoryPromptSection delegate
pattern in system-prompt.ts. Kept our enhanced operator1 memory prompt
in memory-core buildPromptSection with per-tool guidance. Kept our
googlechat export and matrix/mattermost entrypoints in append-only files.
Took upstream for plugin infrastructure (loader.ts, registry.ts, types.ts).

(cherry picked from commit fd2b3ed)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling cli CLI command changes extensions: lobster Extension: lobster extensions: memory-core Extension: memory-core scripts Repository scripts size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants