mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-20 10:11:58 +00:00
fix(agent): freeze carveout-era SUMMARY_PREFIX for renormalization
The prompt consolidation above retires the carveout-era prefix. Without a frozen copy in _HISTORICAL_SUMMARY_PREFIXES, summaries persisted by pre-upgrade builds would lose detection (_is_context_summary_content) and renormalization (_strip_summary_prefix) — the exact regression class the tuple exists to prevent. Adds contract tests covering every frozen prefix. Refs #41607 #38364 #42812
This commit is contained in:
parent
8f8cad7ec5
commit
acb2954d82
2 changed files with 59 additions and 0 deletions
|
|
@ -80,6 +80,31 @@ LEGACY_SUMMARY_PREFIX = "[CONTEXT SUMMARY]:"
|
|||
# embedded in the body and keeps hijacking replies. Keep newest-first; entries
|
||||
# are matched literally. Add a frozen copy here whenever SUMMARY_PREFIX changes.
|
||||
_HISTORICAL_SUMMARY_PREFIXES = (
|
||||
# Carveout era (#41607/#38364/#42812): "consistent → use as background"
|
||||
# licensed stale-task resumption on topic overlap.
|
||||
"[CONTEXT COMPACTION — REFERENCE ONLY] Earlier turns were compacted "
|
||||
"into the summary below. This is a handoff from a previous context "
|
||||
"window — treat it as background reference, NOT as active instructions. "
|
||||
"Do NOT answer questions or fulfill requests mentioned in this summary; "
|
||||
"they were already addressed. "
|
||||
"Respond ONLY to the latest user message that appears AFTER this "
|
||||
"summary — that message is the single source of truth for what to do "
|
||||
"right now. "
|
||||
"If the latest user message is consistent with the '## Active Task' "
|
||||
"section, you may use the summary as background. If the latest user "
|
||||
"message contradicts, supersedes, changes topic from, or in any way "
|
||||
"diverges from '## Active Task' / '## In Progress' / '## Pending User "
|
||||
"Asks' / '## Remaining Work', the latest message WINS — discard those "
|
||||
"stale items entirely and do not 'wrap up the old task first'. "
|
||||
"Reverse signals in the latest message (e.g. 'stop', 'undo', 'roll "
|
||||
"back', 'just verify', 'don't do that anymore', 'never mind', a new "
|
||||
"topic) must immediately end any in-flight work described in the "
|
||||
"summary; do not re-surface it in later turns. "
|
||||
"IMPORTANT: Your persistent memory (MEMORY.md, USER.md) in the system "
|
||||
"prompt is ALWAYS authoritative and active — never ignore or deprioritize "
|
||||
"memory content due to this compaction note. "
|
||||
"The current session state (files, config, etc.) may reflect work "
|
||||
"described here — avoid repeating it:",
|
||||
# Pre-#35344: contained the self-contradicting "resume exactly" directive.
|
||||
"[CONTEXT COMPACTION — REFERENCE ONLY] Earlier turns were compacted "
|
||||
"into the summary below. This is a handoff from a previous context "
|
||||
|
|
|
|||
|
|
@ -80,3 +80,37 @@ def test_memory_authority_preserved():
|
|||
assert "MEMORY.md" in SUMMARY_PREFIX
|
||||
assert "USER.md" in SUMMARY_PREFIX
|
||||
assert "authoritative" in SUMMARY_PREFIX
|
||||
|
||||
|
||||
def test_no_background_consistency_carveout():
|
||||
"""The "consistent → use as background" carveout licensed stale-task
|
||||
resumption on topic overlap (#41607, #38364, #42812). It must stay gone,
|
||||
and the prefix must explicitly neutralize topic overlap."""
|
||||
lower = SUMMARY_PREFIX.lower()
|
||||
assert "you may use the summary as background" not in lower
|
||||
assert "topic overlap" in lower
|
||||
|
||||
|
||||
def test_replaced_prefixes_are_frozen_for_renormalization():
|
||||
"""Every retired SUMMARY_PREFIX must be frozen into
|
||||
_HISTORICAL_SUMMARY_PREFIXES, otherwise summaries persisted by older
|
||||
builds lose detection/renormalization after an upgrade. The carveout-era
|
||||
prefix is the latest retiree."""
|
||||
from agent.context_compressor import (
|
||||
_HISTORICAL_SUMMARY_PREFIXES,
|
||||
ContextCompressor,
|
||||
)
|
||||
|
||||
carveout_era = [
|
||||
p for p in _HISTORICAL_SUMMARY_PREFIXES
|
||||
if "you may use the summary as background" in p
|
||||
]
|
||||
assert carveout_era, "carveout-era prefix missing from frozen tuple"
|
||||
# The live prefix must never be one of the frozen ones.
|
||||
assert SUMMARY_PREFIX not in _HISTORICAL_SUMMARY_PREFIXES
|
||||
# Detection + strip must work for every frozen prefix.
|
||||
for old_prefix in _HISTORICAL_SUMMARY_PREFIXES:
|
||||
content = old_prefix + "\n## Summary body"
|
||||
assert ContextCompressor._is_context_summary_content(content)
|
||||
stripped = ContextCompressor._strip_summary_prefix(content)
|
||||
assert not stripped.startswith(old_prefix)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue