← Back to PRs

#11732: feat(plugins): add injectMessages to before_agent_start hook

by antra-tess open 2026-02-08 07:30 View on GitHub →
agents stale
## Summary - Add `injectMessages` field to `PluginHookBeforeAgentStartResult`, allowing plugins to inject messages of any role into the conversation history before the agent prompt - Messages are prepended to the existing history via `agent.replaceMessages()` - Multiple plugins' messages are concatenated in priority order ## Motivation The existing `before_agent_start` hook offers `prependContext` (prepends text to the user message) and `systemPrompt` (replaces the system prompt). Neither allows plugins to inject **assistant-role** messages — which is needed for plugins that provide the agent's own memories, personality context, or prior conversation summaries. This is a prerequisite for the `openclaw-memory-hierarchical` npm plugin, which injects first-person autobiographical memories as assistant messages so the model reads them as its own recollections rather than user-provided context. ## Changes | File | Change | |---|---| | `src/plugins/types.ts` | Add `injectMessages` to `PluginHookBeforeAgentStartResult` | | `src/plugins/hooks.ts` | Merge `injectMessages` arrays from multiple handlers | | `src/agents/pi-embedded-runner/run/attempt.ts` | Handle `injectMessages` by prepending to conversation history | ## Plugin usage ```typescript api.on("before_agent_start", async (_event, ctx) => { return { injectMessages: [ { role: "assistant", content: [{ type: "text", text: "I remember our previous discussion about..." }], }, ], }; }); ``` ## Test plan - [x] Full test suite passes (969 files, 6604 tests, 0 failures) - [x] Lint passes (0 errors) - [x] Backwards compatible — existing plugins using `prependContext`/`systemPrompt` are unaffected - [ ] Manual: verify injected messages appear in conversation history before the prompt 🤖 AI-assisted (Claude). Fully tested, code understood. <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR extends the `before_agent_start` plugin hook to support injecting arbitrary conversation messages via a new `injectMessages` field. Hook results are merged across plugins in priority order, and `runEmbeddedAttempt` prepends injected messages to the current session history before building the final prompt. Main integration points: - `src/plugins/types.ts` adds `injectMessages` to the hook result type. - `src/plugins/hooks.ts` merges `injectMessages` arrays across handlers. - `src/agents/pi-embedded-runner/run/attempt.ts` applies injected messages by calling `agent.replaceMessages()` before prompt execution. <h3>Confidence Score: 3/5</h3> - This PR is mostly safe to merge, but has a correctness bug where injected history can be overwritten later in the prompt pipeline. - The hook/type changes are straightforward, but `runEmbeddedAttempt` currently updates the agent’s internal message list without keeping `activeSession.messages` in sync. Subsequent code paths read from and may re-apply `activeSession.messages`, which can drop the injected messages entirely, undermining the feature. - src/agents/pi-embedded-runner/run/attempt.ts <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs