Skip to content

fix(agent): preserve memory-provider context during compression (salvage #64342) - #67938

Merged
teknium1 merged 10 commits into
mainfrom
hermes/hermes-e7906cce
Jul 20, 2026
Merged

fix(agent): preserve memory-provider context during compression (salvage #64342)#67938
teknium1 merged 10 commits into
mainfrom
hermes/hermes-e7906cce

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Summary

Memory-provider context returned by on_pre_compress() now survives compression: it is sanitized, bounded, and injected into the compression summary prompt instead of being silently discarded. Salvages PR #64342 by @GottZ (with a foundational commit by @Tranquil-Flow) onto current main with authorship preserved.

Root cause: compress_context() invoked agent._memory_manager.on_pre_compress(messages) but dropped its return value, despite the MemoryProvider/MemoryManager contract stating the returned text should be included in the compression summary prompt.

Changes

  • agent/conversation_compression.py: capture + sanitize the on_pre_compress() return and forward it to the engine; new _supported_compression_kwargs() inspects the engine signature so legacy plugin engines get only kwargs they accept (replaces the broad TypeError retry that could double-invoke a stateful compressor); lock lease refresher + release hardened across all failure paths (idempotent release, refresher-start/stop failures can't strand the lock); semantic no-op detection (equal-copy results skip boundary rewrite, in-place mutations restored).
  • agent/context_compressor.py: _generate_summary()/compress() accept memory_context; injected into both initial and iterative summary prompts inside a JSON-string-escaped <memory-provider-context> frame (decode-as-data instruction, markers cannot escape the frame); survives aux→main summary retry.
  • agent/context_engine.py: sanitize_memory_context() (strict redaction + 6K head/tail bound) and documented optional force/memory_context params on the ABC.
  • agent/redact.py: opt-in redact_url_credentials=True strict mode — masks credential-named query params (incl. hyphen/percent-encoded aliases, ; separators, fragments, relative and network-path refs) and URL userinfo. Default stays off so OAuth callback/magic-link URLs survive normal tool flows.
  • Tests: 2 new behavior-contract files (507 lines) + lock/refresher failure-mode coverage + stub signature updates.

Validation

Check Result
Targeted suites (6 files, incl. 2 new) via scripts/run_tests.sh 238/238 green
Compression sibling suites (threshold floor, summary prefix, gateway /compress) 31/31 green
E2E (real imports, temp HERMES_HOME): manager→engine handoff sanitized, secrets blocked at egress, legacy-engine single-invoke, equal-copy no-op all pass
Pre-push stale-base gate 0 commits behind origin/main

Salvaged from #64342; duplicate cluster #11236, #21118, #22576, #29598 to be closed with credit (earliest: @jairodriguez, Apr 16).

Infographic

PR infographic

teknium1 and others added 10 commits July 20, 2026 01:12
The MemoryProvider.on_pre_compress() hook returns text that providers
want preserved in the compression summary, but run_agent.py discarded
the return value. Additionally, compress() and _generate_summary() had
no mechanism to accept this context.

- Capture on_pre_compress() return value in run_agent.py
- Add memory_context parameter to compress() and _generate_summary()
- Inject memory provider insights into summarization prompts

Fixes all MemoryProvider plugins that return context from
on_pre_compress() (currently silently broken for every plugin).
@teknium1
teknium1 force-pushed the hermes/hermes-e7906cce branch from d5873d4 to 5271ccb Compare July 20, 2026 08:29
@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint tool/memory Memory tool and memory providers needs-decision Awaiting maintainer decision before any implementation sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state labels Jul 20, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Related to open #64342 and #29598. This is a maintainer salvage with the same memory-context goal plus additional compression-lock and compatibility work, so it is not marked duplicate.

Skywind5487 added a commit to Skywind5487/hermes-agent that referenced this pull request Aug 17, 2026
Port the explicit plugin no-op session-boundary guard onto current upstream lifecycle seams and add a regression for the residual case not covered by semantic equality: cleanup-changed active context reported as noop must be adopted without rotating the session.

Prior art: NousResearch#58495. Equal-copy no-progress handling remains upstream-owned by NousResearch#67938.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint needs-decision Awaiting maintainer decision before any implementation P3 Low — cosmetic, nice to have sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state tool/memory Memory tool and memory providers type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants