Skip to content

fix: strip <relevant-memories> injected by memory plugin from user messages in WebUI#59697

Closed
jwchmodx wants to merge 2 commits into
openclaw:mainfrom
jwchmodx:fix/webui-strip-relevant-memories-from-user-messages
Closed

fix: strip <relevant-memories> injected by memory plugin from user messages in WebUI#59697
jwchmodx wants to merge 2 commits into
openclaw:mainfrom
jwchmodx:fix/webui-strip-relevant-memories-from-user-messages

Conversation

@jwchmodx

@jwchmodx jwchmodx commented Apr 2, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Memory plugin's before_agent_start hook prepends <relevant-memories>...</relevant-memories> to user prompts before they are stored in session history
  • stripEnvelopeFromMessages() (server) and processMessageText (WebUI) only stripped these tags from assistant messages, never from user messages
  • This caused internal memory context to appear in the user message bubble in WebUI

Root cause

stripRelevantMemoriesTags was only reachable via stripAssistantInternalScaffolding, which is only called for role === "assistant". User messages went through stripInboundMetadata + stripEnvelope, neither of which handles <relevant-memories> XML tags.

Fix

  • Export stripRelevantMemoriesTags from assistant-visible-text.ts
  • chat-sanitize.ts (stripEnvelopeFromMessage): apply stripRelevantMemoriesTags to user-role message content — fixes the chat.history RPC path
  • message-extract.ts (processMessageText): apply stripRelevantMemoriesTags for user-role messages — fixes the WebUI rendering path
  • Add regression tests in chat-sanitize.test.ts and message-extract.test.ts for both string content and array content shapes

Test plan

  • npx vitest run src/gateway/chat-sanitize.test.ts — 11 tests pass
  • npx vitest run ui/src/ui/chat/message-extract.test.ts — 6 tests pass
  • Start OpenClaw with memory-lancedb extension enabled, send a message, verify user bubble shows only the actual message text

Fixes #59568

🤖 Generated with Claude Code

@greptile-apps

greptile-apps Bot commented Apr 2, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR correctly fixes a bug where the <relevant-memories> block injected by the memory plugin into user messages was leaking through into the WebUI user message bubble. The fix exports stripRelevantMemoriesTags and applies it to user-role messages in both the chat.history RPC path (chat-sanitize.ts) and the WebUI rendering path (message-extract.ts), with regression tests for both string and array content shapes.

  • assistant-visible-text.ts: stripRelevantMemoriesTags exported (minimal change)
  • chat-sanitize.ts: Memory tag stripping added to all three user-message content shapes (string, array of text blocks, bare text field)
  • message-extract.ts: Memory tag stripping added to the WebUI processMessageText user path
  • chat-sanitize.test.ts / message-extract.test.ts: Regression tests covering string content and array content
  • Minor behavioural note: .trimStart() is now applied unconditionally to every user message across both files, not only to messages where a memory block was actually removed. This could silently trim intentional leading whitespace from user messages that never contained a <relevant-memories> block.

Confidence Score: 4/5

  • Safe to merge; the fix is targeted and well-tested, with only a minor unconditional trimStart() side-effect on user messages.
  • The logic change is correct and the root cause is accurately described. Two dedicated regression tests cover both content shapes in each code path. The only concern is that .trimStart() is applied to all user messages regardless of whether a memory block was present, which is a pre-existing pattern from stripAssistantInternalScaffolding but is now also applied on the user side — unlikely to cause real-world problems but worth awareness.
  • src/gateway/chat-sanitize.ts and ui/src/ui/chat/message-extract.ts — both now apply trimStart() unconditionally to all user messages.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/gateway/chat-sanitize.ts
Line: 53

Comment:
**`trimStart()` applied unconditionally to all user messages**

`.trimStart()` is now unconditionally applied to every user message, not just those from which memory tags were actually removed. If a user message begins with intentional leading whitespace (e.g. a code snippet pasted directly, or a message from a channel adapter that prefixes content with spaces), that whitespace will be silently stripped even when no `<relevant-memories>` block was present.

A safer approach would be to conditionally trim only when the strip actually modified the text:

```suggestion
      ? (() => { const s = stripRelevantMemoriesTags(stripMessageIdHints(stripEnvelope(inboundStripped))); return s !== inboundStripped ? s.trimStart() : s; })()
```

Alternatively, `trimStart()` could be applied only inside `stripRelevantMemoriesTags` when it actually removes a block (which would require a small change to that function's return logic). The same concern applies to lines 86 and 101 in this file, and to `message-extract.ts` line 15.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "fix: strip relevant-memories from user m..." | Re-trigger Greptile

Comment thread src/gateway/chat-sanitize.ts Outdated

@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: bc9f21c885

ℹ️ 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 thread src/gateway/chat-sanitize.ts Outdated
jwchmodx and others added 2 commits April 28, 2026 18:40
…tory

Memory plugin prepends <relevant-memories>...</relevant-memories> blocks
to user prompts via the before_agent_start hook. These blocks were only
stripped from assistant messages (via stripAssistantInternalScaffolding)
but never from user-role messages, causing them to appear in the WebUI
user message bubble and in chat.history responses.

Changes:
- Export stripRelevantMemoriesTags from assistant-visible-text.ts
- chat-sanitize.ts: apply stripRelevantMemoriesTags when stripping user
  messages in stripEnvelopeFromMessage (covers chat.history server path)
- message-extract.ts: apply stripRelevantMemoriesTags for user-role
  messages in processMessageText (covers WebUI rendering path)
- Add regression tests in both chat-sanitize.test.ts and
  message-extract.test.ts

Fixes openclaw#59568

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
@vincentkoc
vincentkoc force-pushed the fix/webui-strip-relevant-memories-from-user-messages branch from bc9f21c to a1939e4 Compare April 28, 2026 18:40
@vincentkoc

Copy link
Copy Markdown
Member

ProjectClownfish pushed a narrow repair to this branch so the original contributor path can stay canonical.

Source PR: #59697
Validation: pnpm -s vitest run src/gateway/chat-sanitize.test.ts ui/src/ui/chat/message-extract.test.ts; pnpm check:changed
Contributor credit is preserved in the branch history and PR context.

@clawsweeper

clawsweeper Bot commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

Thanks for the context here. I swept through the related work, and this is now duplicate or superseded.

Keep this PR open: the reported user-visible memory metadata leak is still present on current main and in the latest release, but the branch is not merge-ready because it is dirty against current main, lacks real behavior proof, and still has a user-text preservation bug.

Canonical path: Close this stale PR. The latest review rated it F, the branch still lacks merge-ready proof, and there has been no human follow-up after the durable review.

So I’m closing this here because the remaining work is already tracked in the canonical issue.

Review details

Best possible solution:

Close this stale PR. The latest review rated it F, the branch still lacks merge-ready proof, and there has been no human follow-up after the durable review.

Do we have a high-confidence way to reproduce the issue?

Yes from source inspection: memory-lancedb emits the <relevant-memories> prefix, the agent loop prepends hook context before the user prompt, and current Gateway/WebUI user display paths do not strip that XML. I did not run a live WebUI scenario because this review is read-only.

Is this the best way to solve the issue?

No: the direction is right, but this branch is not the best merge shape until it is refreshed onto current main, preserves user indentation after stripped prefixes, and includes real behavior proof.

Security review:

Security review cleared: The diff changes display sanitization code, tests, and a changelog entry; I found no concrete security or supply-chain regression in the patch.

AGENTS.md: found and applied where relevant.

What I checked:

  • stale F-rated PR: PR was opened 2026-04-02T13:50:30Z, is older than 30 days, and the latest review rated it F.
  • proof blocker: real behavior proof is missing and proof tier is F, so this branch is not merge-ready without contributor follow-up.
  • no human follow-up: live comments and timeline hydrated by apply contain no non-automation activity after the ClawSweeper review.

Likely related people:

  • vincentkoc: Pushed the latest repair commit on this PR branch and left the maintainer-side validation/context comment preserving the contributor path. (role: recent branch repair contributor; confidence: high; commits: a1939e4a05dc; files: src/shared/text/assistant-visible-text.ts, src/gateway/chat-sanitize.test.ts, ui/src/ui/chat/message-normalizer.ts)
  • Peter Steinberger: History search shows nearby work unifying and sharing assistant-visible text sanitizer profiles that now own memory/scaffolding stripping behavior. (role: sanitizer refactor contributor; confidence: medium; commits: 712479eea1a1, c63a4f0f13fc; files: src/shared/text/assistant-visible-text.ts)
  • Vignesh Natarajan: History search ties this person to both the memory-lancedb recall formatter and the earlier Web UI relevant-memories scaffolding strip work. (role: memory and initial scaffolding-strip contributor; confidence: medium; commits: 61725fb37e33, e90429794a37; files: extensions/memory-lancedb/index.ts, src/shared/text/assistant-visible-text.ts, ui/src/ui/chat/message-extract.test.ts)
  • Mars: Prior UI history work stripped injected inbound metadata from user messages in history, which is the sibling display invariant this PR extends to memory XML. (role: adjacent user metadata display contributor; confidence: medium; commits: a4e7e952e143; files: ui/src/ui/chat/message-extract.ts, ui/src/ui/chat/message-normalizer.ts)
  • Agustin Rivera: Current-main blame in this checkout attributes the active Gateway/UI display paths to the snapshot root commit; confidence is lower because the checkout history is partially synthetic around current main. (role: current-main snapshot contributor; confidence: low; commits: a4e02cd1dd48; files: src/auto-reply/reply/display-text-sanitize.ts, ui/src/ui/chat/message-extract.ts, ui/src/ui/chat/message-normalizer.ts)

Codex review notes: model gpt-5.5, reasoning high; reviewed against 52bc2a12bc8c.

@vincentkoc vincentkoc added clawsweeper Tracked by ClawSweeper automation and removed clownfish:merge-ready labels Apr 28, 2026
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. labels May 19, 2026
@openclaw-barnacle openclaw-barnacle Bot added the triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. label May 19, 2026
@clawsweeper clawsweeper Bot added the merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. label May 19, 2026
@clawsweeper

clawsweeper Bot commented May 20, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper PR egg

🎁 Pass real behavior proof to wake the egg and unlock a hatchable treat.

Where did the egg go?
  • The egg game starts only after the PR passes the real-behavior proof check.
  • Before that, no creature or rarity is rolled. The treat waits for real proof.
  • This is still just collectible flavor: proof affects review readiness, not creature quality.

@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Jun 10, 2026
@clawsweeper

clawsweeper Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper applied the proposed close for this PR.

@clawsweeper clawsweeper Bot closed this Jun 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app: web-ui App: web-ui clawsweeper Tracked by ClawSweeper automation gateway Gateway runtime merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. P2 Normal backlog priority with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: M stale Marked as stale due to inactivity status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] WebUI: internal metadata displayed in user message input area

2 participants