hermes - ✅(Solved) Fix Built-in memory and external provider both inject into system prompt when external provider has content [2 pull requests, 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
NousResearch/hermes-agent#28796Fetched 2026-05-20 04:01:55
View on GitHub
Comments
0
Participants
1
Timeline
8
Reactions
0
Author
Participants
Timeline (top)
labeled ×5cross-referenced ×2referenced ×1

Fix Action

Fixed

PR fix notes

PR #16: fix(memory): suppress built-in memory block when external provider is active (#28796)

Description (problem / solution / changelog)

🟢 Merge order: 5 / 12 — small, conditional skip, low risk

Closes #28796 (P3)

Problem

Both built-in MEMORY.md and the external provider's system_prompt_block() were injected into every system prompt, causing duplicate context.

Fix

Auto-suppress the built-in memory block when _memory_manager is active. USER.md (identity) is still included regardless.

Risk assessment

FactorRating
Lines changed6/-1
New code1 boolean check
Side effectsUsers with external providers will see less context (correct behavior)
Revert complexityEasy

Files changed

  • agent/system_prompt.py (+6/-1)

Changed files

  • agent/system_prompt.py (modified, +6/-1)

PR #29020: feat(memory): add memory.suppress_builtin_when_external opt-in

Description (problem / solution / changelog)

Summary

Opt-in config knob to stop double-injecting MEMORY.md/USER.md into the system prompt when an external memory provider (OpenViking, Honcho, etc.) is configured and already supplies its own context block.

Before this change, agent/system_prompt.py unconditionally appended both the built-in memory/user blocks and MemoryManager.build_system_prompt(). Users who migrated their notes into an external provider saw the same information twice on every turn and the only workaround was manually flipping memory_enabled: false (which also disables the memory tool).

Behavior

memory:
  provider: openviking
  suppress_builtin_when_external: true   # new, default false
  • Flag false / absent → historical additive behavior, byte-stable for existing deployments.
  • Flag true + external provider returns non-empty block → built-in memory/user blocks are skipped, external block is injected.
  • Flag true + external provider returns empty (no content yet, transient error, exception) → built-in blocks are still injected. We never silently strip the user's notes.

External-provider exceptions are caught and treated as "empty block", same as the prior behavior.

Files

  • agent/system_prompt.py — build the external block first, gate the built-in injection on (_suppress && _ext_mem_block).
  • agent/agent_init.py — read memory.suppress_builtin_when_external from config, default False, expose as agent._memory_suppress_builtin_when_external.
  • tests/agent/test_system_prompt_memory_suppression.py — 5 cases (default keeps both, suppress drops built-in, empty external keeps built-in, no manager configured, external raises).
  • website/docs/user-guide/features/memory.md — document the new knob and the "we don't silently strip" safety.

Test Plan

  • python -m pytest tests/agent/test_system_prompt_memory_suppression.py -q -o 'addopts=' → 5 passed
  • python -m pytest tests/agent/test_memory_provider.py tests/run_agent/test_memory_provider_init.py tests/agent/test_system_prompt_restore.py tests/agent/test_system_prompt_memory_suppression.py -q -o 'addopts=' → 78 passed in 98s

Closes #28796

Changed files

  • agent/agent_init.py (modified, +4/-0)
  • agent/system_prompt.py (modified, +21/-9)
  • tests/agent/test_system_prompt_memory_suppression.py (added, +124/-0)
  • website/docs/user-guide/features/memory.md (modified, +11/-1)
RAW_BUFFERClick to expand / collapse

Observation

When an external memory provider (e.g. OpenViking) is configured as memory.provider and has accumulated content, both of these are injected into the system prompt on every turn:

  1. Built-in memory section — from ~/.hermes/memories/MEMORY.md and USER.md (controlled by memory_enabled / user_profile_enabled)
  2. External provider context — from the provider's system_prompt_block() (e.g. OV's <memory-context> block)

They are assembled independently in agent/system_prompt.py:239-257 with no awareness of each other.

Scenario that surfaced this

Deployed OpenViking as memory.provider. Previous built-in memories accumulated over time were still in MEMORY.md/USER.md. After OV was activated, both sets appeared in every system prompt — the agent saw the same information twice. The only way to stop it was manually setting memory_enabled: false.

Question

Is this double-injection by design (built-in and external are always additive), or should the built-in sections automatically suppress when an external provider already covers the same content? The config knobs exist, but users who switch to an external provider mid-lifecycle won't know they need to disable built-in manually.

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

hermes - ✅(Solved) Fix Built-in memory and external provider both inject into system prompt when external provider has content [2 pull requests, 1 participants]