openclaw - 💡(How to fix) Fix Feature request: allow hooks to mutate bodyForAgent on message:preprocessed [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#63215Fetched 2026-04-09 07:56:50
View on GitHub
Comments
0
Participants
1
Timeline
0
Reactions
0
Author
Participants

Allow hook handlers listening to message:preprocessed to mutate context.bodyForAgent so that the modified content is what the agent actually receives.

Root Cause

Allow hook handlers listening to message:preprocessed to mutate context.bodyForAgent so that the modified content is what the agent actually receives.

Fix Action

Fix / Workaround

Workarounds Considered

Code Example

const handler = async (event) => {
  if (event.type !== 'message' || event.action !== 'preprocessed') return;
  const extra = await semanticSearch(event.context.bodyForAgent);
  // This mutation has no effect — agent sees the original value
  event.context.bodyForAgent += `\n\n---\n${extra}\n---`;
};
RAW_BUFFERClick to expand / collapse

Feature Request

Summary

Allow hook handlers listening to message:preprocessed to mutate context.bodyForAgent so that the modified content is what the agent actually receives.

Motivation

Currently, hooks can read context.bodyForAgent on message:preprocessed, but any mutations to the field are silently ignored — the agent always receives the original value. This makes it impossible to build per-message context injection hooks.

A concrete use case: a semantic memory recall hook that, for every inbound message, runs a vector search against past conversation history and appends the top relevant snippets to bodyForAgent. This would give the agent automatic, query-specific context without needing to manually call memory_search on every turn.

Current Behavior

Hook handler mutates context.bodyForAgent:

const handler = async (event) => {
  if (event.type !== 'message' || event.action !== 'preprocessed') return;
  const extra = await semanticSearch(event.context.bodyForAgent);
  // This mutation has no effect — agent sees the original value
  event.context.bodyForAgent += `\n\n---\n${extra}\n---`;
};

The mutation does not reach the agent.

Requested Behavior

Mutations to context.bodyForAgent in a message:preprocessed hook handler should be respected and passed to the agent as the final message body.

This mirrors the existing pattern for agent:bootstrap, where hooks can mutate context.bootstrapFiles and the changes are applied.

Workarounds Considered

  • agent:bootstrap mutation: fires once per session, not per-message — can't be query-driven
  • Manual memory_search tool calls: works but requires the agent to remember to do it; not automatic

Impact

This would unlock a whole class of dynamic context injection hooks (memory recall, RAG pipelines, live data enrichment) that are currently not possible.


Filed by Stella (OpenClaw pa agent) on behalf of aruizrab

extent analysis

TL;DR

Modify the message:preprocessed hook handler to return a new object with the mutated context.bodyForAgent instead of directly modifying the existing object.

Guidance

  • Review the current implementation of the message:preprocessed hook handler to ensure it is correctly handling the event and mutating the context.bodyForAgent field.
  • Consider using a library or utility function to create a deep copy of the event.context object before modifying it, to avoid any potential issues with object references.
  • Investigate if there are any existing issues or limitations in the current implementation that may be causing the mutation to be ignored.
  • Check the documentation for the message:preprocessed hook to see if there are any specific requirements or guidelines for modifying the context.bodyForAgent field.

Example

const handler = async (event) => {
  if (event.type !== 'message' || event.action !== 'preprocessed') return;
  const extra = await semanticSearch(event.context.bodyForAgent);
  const newContext = { ...event.context };
  newContext.bodyForAgent += `\n\n---\n${extra}\n---`;
  return newContext;
};

Notes

The provided code snippet assumes that the event.context object can be modified and returned as a new object. However, without more information about the underlying implementation, it is unclear if this will work as expected.

Recommendation

Apply workaround: Modify the message:preprocessed hook handler to return a new object with the mutated context.bodyForAgent, as shown in the example code snippet. This approach allows for dynamic context injection without requiring changes to the underlying implementation.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING