feat: pluggable context engine slot with config-driven selection#6126
Closed
teknium1 wants to merge 4 commits into
Closed
feat: pluggable context engine slot with config-driven selection#6126teknium1 wants to merge 4 commits into
teknium1 wants to merge 4 commits into
Conversation
…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)
Contributor
Author
|
Merged via PR #7464 which includes your salvage work plus the unified |
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.enginein config.yaml, with aplugins/context_engine/discovery directory mirroring how memory providers work.From PR #5700 (cherry-picked, credit: @stephenschoettler)
agent/context_engine.py— ContextEngine ABCagent/context_compressor.py— Inherits from ContextEngine, addson_session_reset(),namepropertyhermes_cli/plugins.py—register_context_engine()on PluginContext, single-engine rulerun_agent.py— Plugin engine check, tool injection, session lifecycle, tool dispatchtests/agent/test_context_engine.py— 19 tests for ABC contract, plugin slotFollow-up fixes (this PR adds)
threshold_percent,protect_first_n,protect_last_nas class attributes; completeupdate_model()default with threshold recalculationupdate_model()for switch_model, fallback restore, context probing);_context_probedguarded withgetattr/hasattrfor plugin compatibilityplugins/context_engine/__init__.py: Discovery module mirroringplugins/memory/—discover_context_engines(),load_context_engine()context.engineinDEFAULT_CONFIG(default:"compressor"). Selection checks config → plugins/context_engine/ → general plugin system → built-inon_session_end()wired: Called at real session boundaries inshutdown_memory_provider()Test results
Subsumes
Closes #5701. Credit to @stephenschoettler for the original design and implementation.