mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-25 00:51:20 +00:00
feat: wire context engine plugin slot into agent and 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
This commit is contained in:
parent
fe7e6c156c
commit
92382fb00e
4 changed files with 324 additions and 23 deletions
49
run_agent.py
49
run_agent.py
|
|
@ -1268,19 +1268,32 @@ class AIAgent:
|
|||
pass
|
||||
break
|
||||
|
||||
self.context_compressor = ContextCompressor(
|
||||
model=self.model,
|
||||
threshold_percent=compression_threshold,
|
||||
protect_first_n=3,
|
||||
protect_last_n=compression_protect_last,
|
||||
summary_target_ratio=compression_target_ratio,
|
||||
summary_model_override=compression_summary_model,
|
||||
quiet_mode=self.quiet_mode,
|
||||
base_url=self.base_url,
|
||||
api_key=getattr(self, "api_key", ""),
|
||||
config_context_length=_config_context_length,
|
||||
provider=self.provider,
|
||||
)
|
||||
# Check if a plugin registered a custom context engine (e.g. LCM)
|
||||
_plugin_engine = None
|
||||
try:
|
||||
from hermes_cli.plugins import get_plugin_context_engine
|
||||
_plugin_engine = get_plugin_context_engine()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if _plugin_engine is not None:
|
||||
self.context_compressor = _plugin_engine
|
||||
if not self.quiet_mode:
|
||||
logger.info("Using plugin context engine: %s", _plugin_engine.name)
|
||||
else:
|
||||
self.context_compressor = ContextCompressor(
|
||||
model=self.model,
|
||||
threshold_percent=compression_threshold,
|
||||
protect_first_n=3,
|
||||
protect_last_n=compression_protect_last,
|
||||
summary_target_ratio=compression_target_ratio,
|
||||
summary_model_override=compression_summary_model,
|
||||
quiet_mode=self.quiet_mode,
|
||||
base_url=self.base_url,
|
||||
api_key=getattr(self, "api_key", ""),
|
||||
config_context_length=_config_context_length,
|
||||
provider=self.provider,
|
||||
)
|
||||
self.compression_enabled = compression_enabled
|
||||
self._subdirectory_hints = SubdirectoryHintTracker(
|
||||
working_dir=os.getenv("TERMINAL_CWD") or None,
|
||||
|
|
@ -1397,15 +1410,9 @@ class AIAgent:
|
|||
# Turn counter (added after reset_session_state was first written — #2635)
|
||||
self._user_turn_count = 0
|
||||
|
||||
# Context compressor internal counters (if present)
|
||||
# Context engine reset (works for both built-in compressor and plugins)
|
||||
if hasattr(self, "context_compressor") and self.context_compressor:
|
||||
self.context_compressor.last_prompt_tokens = 0
|
||||
self.context_compressor.last_completion_tokens = 0
|
||||
self.context_compressor.compression_count = 0
|
||||
self.context_compressor._context_probed = False
|
||||
self.context_compressor._context_probe_persistable = False
|
||||
# Iterative summary from previous session must not bleed into new one (#2635)
|
||||
self.context_compressor._previous_summary = None
|
||||
self.context_compressor.on_session_reset()
|
||||
|
||||
def switch_model(self, new_model, new_provider, api_key='', base_url='', api_mode=''):
|
||||
"""Switch the model/provider in-place for a live agent.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue