Skip to content

feat: pluggable context engine slot with config-driven selection#6126

Closed
teknium1 wants to merge 4 commits into
mainfrom
hermes/hermes-83d3c1db
Closed

feat: pluggable context engine slot with config-driven selection#6126
teknium1 wants to merge 4 commits into
mainfrom
hermes/hermes-83d3c1db

Conversation

@teknium1

@teknium1 teknium1 commented Apr 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Salvages PR #5700 by @stephenschoettler (context engine plugin slot for LCM) and adds robust infrastructure on top.

What this PR does: Adds a pluggable context engine system — an ABC that defines the interface, makes the built-in ContextCompressor the default implementation, and allows plugins to replace it. Config-driven selection via context.engine in config.yaml, with a plugins/context_engine/ discovery directory mirroring how memory providers work.

From PR #5700 (cherry-picked, credit: @stephenschoettler)

  • agent/context_engine.py — ContextEngine ABC
  • agent/context_compressor.py — Inherits from ContextEngine, adds on_session_reset(), name property
  • hermes_cli/plugins.pyregister_context_engine() on PluginContext, single-engine rule
  • run_agent.py — Plugin engine check, tool injection, session lifecycle, tool dispatch
  • tests/agent/test_context_engine.py — 19 tests for ABC contract, plugin slot

Follow-up fixes (this PR adds)

  • Enhanced ABC contract: threshold_percent, protect_first_n, protect_last_n as class attributes; complete update_model() default with threshold recalculation
  • ContextCompressor.update_model(): Handles model/provider/base_url/api_key/context_length updates
  • run_agent.py hardened: All direct compressor internal access replaced with ABC interface (update_model() for switch_model, fallback restore, context probing); _context_probed guarded with getattr/hasattr for plugin compatibility
  • plugins/context_engine/__init__.py: Discovery module mirroring plugins/memory/discover_context_engines(), load_context_engine()
  • Config-driven selection: context.engine in DEFAULT_CONFIG (default: "compressor"). Selection checks config → plugins/context_engine/ → general plugin system → built-in
  • on_session_end() wired: Called at real session boundaries in shutdown_memory_provider()

Test results

  • 55 context engine + compressor tests: all pass
  • 3671 hermes_cli + gateway tests: all pass (8 pre-existing failures unrelated)
  • E2E verified: plugin discovery, loading, ABC contract, config selection

Subsumes

Closes #5701. Credit to @stephenschoettler for the original design and implementation.

stephenschoettler and others added 4 commits April 8, 2026 04:05
…om it

Introduces agent/context_engine.py — an abstract base class that defines
the pluggable context engine interface. ContextCompressor now inherits
from ContextEngine as the default implementation.

No behavior change. All 34 existing compressor tests pass.

This is the foundation for a context engine plugin slot, enabling
third-party engines like LCM (Lossless Context Management) to replace
the built-in compressor via the plugin system.
- PluginContext.register_context_engine() lets plugins replace the
  built-in ContextCompressor with a custom ContextEngine implementation
- PluginManager stores the registered engine; only one allowed
- run_agent.py checks for a plugin engine at init before falling back
  to the default ContextCompressor
- reset_session_state() now calls engine.on_session_reset() instead of
  poking internal attributes directly
- ContextCompressor.on_session_reset() handles its own internals
  (_context_probed, _previous_summary, etc.)
- 19 new tests covering ABC contract, defaults, plugin slot registration,
  rejection of duplicates/non-engines, and compressor reset behavior
- All 34 existing compressor tests pass unchanged
- Inject engine tool schemas into agent tool surface after compressor init
- Call on_session_start() with session_id, hermes_home, platform, model
- Dispatch engine tool calls (lcm_grep, etc.) before regular tool handler
- 55/55 tests pass
…very, ABC completeness

Follow-up fixes for the context engine plugin slot (PR #5700):

- Enhance ContextEngine ABC: add threshold_percent, protect_first_n,
  protect_last_n as class attributes; complete update_model() default
  with threshold recalculation; clarify on_session_end() lifecycle docs
- Add ContextCompressor.update_model() override for model/provider/
  base_url/api_key updates
- Replace all direct compressor internal access in run_agent.py with
  ABC interface: switch_model(), fallback restore, context probing
  all use update_model() now; _context_probed guarded with getattr/
  hasattr for plugin engine compatibility
- Create plugins/context_engine/ directory with discovery module
  (mirrors plugins/memory/ pattern) — discover_context_engines(),
  load_context_engine()
- Add context.engine config key to DEFAULT_CONFIG (default: compressor)
- Config-driven engine selection in run_agent.__init__: checks config,
  then plugins/context_engine/<name>/, then general plugin system,
  falls back to built-in ContextCompressor
- Wire on_session_end() in shutdown_memory_provider() at real session
  boundaries (CLI exit, /reset, gateway expiry)
@teknium1

Copy link
Copy Markdown
Contributor Author

Merged via PR #7464 which includes your salvage work plus the unified hermes plugins UI and auto-activation fix. @stephenschoettler's original commits are preserved with authorship in git log.

@teknium1 teknium1 closed this Apr 11, 2026
dusterbloom added a commit to dusterbloom/hermes-agent that referenced this pull request May 14, 2026
Three-layer memory hierarchy (L1 Hot / L2 Warm DAM / L3 Cold HRR) as a
self-contained plugin under plugins/context_engine/lcm/.

Implements the ContextEngine ABC from PR NousResearch#6126 -- zero changes to run_agent.py.
Activated by setting context.engine: lcm in config.yaml.

Features:
  - ImmutableStore: append-only archive of all messages
  - SummaryDAG: reversible compaction with expansion
  - Dense Associative Memory (L2): Modern Hopfield network
  - HRR persistent knowledge store (L3): cross-session facts
  - LLM escalation: structured summary generation
  - 7 agent-facing tools: expand, pin, forget, search, budget, toc, focus
  - Session persistence and rebuild

Tests: 199 tests (171 internal + 28 ABC contract), all passing.
Config: lcm section in DEFAULT_CONFIG, context.engine selection.

Based on original PR NousResearch#4033, restructured as a plugin per the ContextEngine
ABC design in PR NousResearch#6126 by @teknium1 / @stephenschoettler.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Proposal: Pluggable context engines — enabling LCM as a plugin (like OpenClaw's lossless-claw)

2 participants