Skip to content

Improve external context engine plugin support#13370

Closed
Tosko4 wants to merge 7 commits into
NousResearch:mainfrom
Tosko4:fix/external-context-engine-host-support
Closed

Improve external context engine plugin support#13370
Tosko4 wants to merge 7 commits into
NousResearch:mainfrom
Tosko4:fix/external-context-engine-host-support

Conversation

@Tosko4

@Tosko4 Tosko4 commented Apr 21, 2026

Copy link
Copy Markdown
Contributor

Supersedes closed PR #8416. The original PR became unreopenable after the source fork disappeared; this recreates the same branch on the restored fork.

Summary

  • improves Hermes as a host for external context-engine plugins
  • does not vendor any plugin code into Hermes core
  • keeps the built-in compressor as the default unless context.engine explicitly selects something else

What changed

  • load plugin-registered context engines only when context.engine explicitly asks for one
  • make the fallback path actually discover installed plugins before checking the active plugin engine
  • pass live model/context information into the selected engine during init
  • restart context-engine lifecycle cleanly across /new, /resume, and /branch
  • keep /compress <focus> backward-compatible with engines that do not accept a focus_topic argument
  • surface an installed plugin-registered context engine in hermes plugins so it can be selected from the provider UI

Non-goals

  • no bundled hermes-lcm
  • no vendored engine code under plugins/context_engine/
  • no change to the default behavior for users who stay on the built-in compressor

Validation

Passed:

  • python -m pytest tests/run_agent/test_context_engine_plugin_init.py tests/run_agent/test_session_reset_fix.py tests/cli/test_cli_new_session.py tests/hermes_cli/test_plugins_cmd.py tests/agent/test_context_engine.py -q
    • result: 93 passed

That slice includes explicit coverage for:

  • default compressor stays active when no external engine is selected
  • missing external engine falls back cleanly to the built-in compressor
  • external plugin engine init/discovery paths
  • session reset / resume / branch lifecycle handling

@Tosko4 Tosko4 force-pushed the fix/external-context-engine-host-support branch from 54f983f to 061a15b Compare April 21, 2026 08:05
@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have comp/agent Core agent loop, run_agent.py, prompt builder comp/plugins Plugin system and bundled plugins labels Apr 22, 2026

@stephenschoettler stephenschoettler left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Validated locally. This addresses the host-side context-engine lifecycle layer behind the #68 repro by making session boundaries explicit for external engines instead of reusing stale session state across /new, /resume, /branch, and rollover paths. I also ran the targeted plugin/session tests from the PR body locally; they passed.

@Tosko4 Tosko4 force-pushed the fix/external-context-engine-host-support branch from 061a15b to c57cd99 Compare April 26, 2026 13:27
@Tosko4

Tosko4 commented Apr 26, 2026

Copy link
Copy Markdown
Contributor Author

@xlionjuan

teknium1 pushed a commit that referenced this pull request Apr 27, 2026
When _compress_context rotates session_id (compression split), fire
on_session_start(new_sid, boundary_reason="compression",
old_session_id=<old>) on the active context engine. Plugin engines
(e.g. hermes-lcm) use this to preserve DAG lineage across the rollover
instead of re-initializing fresh per-session state.

Built-in ContextCompressor.on_session_start accepts **kwargs and ignores
them — no behavior change for default users.

Closes hermes-lcm#68 symptom: after Hermes compressed and minted a new
physical session, LCM was treating the split as a fresh /new and losing
continuity (compression_count: 1, store_messages: 0, dag_nodes: 0).

Credit: @Tosko4 (PR #13370) — minimized scope to the boundary_reason
signal only; the broader session-lifecycle refactor will be taken in
separate PRs if justified by concrete plugin need.
@teknium1

Copy link
Copy Markdown
Contributor

Closing in favor of #16306, which is merged to main as commit e85b752 with your authorship preserved.

We salvaged the core hermes-lcm#68 fix — the boundary_reason="compression" signal to the context engine on compression-split — as a focused 16-line change. Your commit fix: mark compression context-engine rollovers on this branch was the right fix; we just dropped the wider session-lifecycle refactor to keep the PR surface minimal.

The rest of #13370 (new _transition_context_engine_session helper, off-thread memory flush on /new, HERMES_SESSION_ID contextvar, conversation_session_id on ProcessSession, inspect.signature introspection for focus_topic, plugin discovery re-ordering in cli.py / gateway/run.py / plugins_cmd.py) is independently reasonable but each piece needs its own justification and PR — happy to take them as separate focused changes if you want to split them out.

Thanks for the fix and for driving the hermes-lcm#68 repro.

@teknium1 teknium1 closed this Apr 27, 2026
ulasbilgen pushed a commit to ulasbilgen/hermes-adhd-agent that referenced this pull request May 1, 2026
When _compress_context rotates session_id (compression split), fire
on_session_start(new_sid, boundary_reason="compression",
old_session_id=<old>) on the active context engine. Plugin engines
(e.g. hermes-lcm) use this to preserve DAG lineage across the rollover
instead of re-initializing fresh per-session state.

Built-in ContextCompressor.on_session_start accepts **kwargs and ignores
them — no behavior change for default users.

Closes hermes-lcm#68 symptom: after Hermes compressed and minted a new
physical session, LCM was treating the split as a fresh /new and losing
continuity (compression_count: 1, store_messages: 0, dag_nodes: 0).

Credit: @Tosko4 (PR NousResearch#13370) — minimized scope to the boundary_reason
signal only; the broader session-lifecycle refactor will be taken in
separate PRs if justified by concrete plugin need.
donald131 pushed a commit to donald131/hermes-agent that referenced this pull request May 2, 2026
When _compress_context rotates session_id (compression split), fire
on_session_start(new_sid, boundary_reason="compression",
old_session_id=<old>) on the active context engine. Plugin engines
(e.g. hermes-lcm) use this to preserve DAG lineage across the rollover
instead of re-initializing fresh per-session state.

Built-in ContextCompressor.on_session_start accepts **kwargs and ignores
them — no behavior change for default users.

Closes hermes-lcm#68 symptom: after Hermes compressed and minted a new
physical session, LCM was treating the split as a fresh /new and losing
continuity (compression_count: 1, store_messages: 0, dag_nodes: 0).

Credit: @Tosko4 (PR NousResearch#13370) — minimized scope to the boundary_reason
signal only; the broader session-lifecycle refactor will be taken in
separate PRs if justified by concrete plugin need.
02356abc pushed a commit to 02356abc/hermes-agent that referenced this pull request May 14, 2026
When _compress_context rotates session_id (compression split), fire
on_session_start(new_sid, boundary_reason="compression",
old_session_id=<old>) on the active context engine. Plugin engines
(e.g. hermes-lcm) use this to preserve DAG lineage across the rollover
instead of re-initializing fresh per-session state.

Built-in ContextCompressor.on_session_start accepts **kwargs and ignores
them — no behavior change for default users.

Closes hermes-lcm#68 symptom: after Hermes compressed and minted a new
physical session, LCM was treating the split as a fresh /new and losing
continuity (compression_count: 1, store_messages: 0, dag_nodes: 0).

Credit: @Tosko4 (PR NousResearch#13370) — minimized scope to the boundary_reason
signal only; the broader session-lifecycle refactor will be taken in
separate PRs if justified by concrete plugin need.
dannyJ848 pushed a commit to dannyJ848/hermes-agent that referenced this pull request May 17, 2026
When _compress_context rotates session_id (compression split), fire
on_session_start(new_sid, boundary_reason="compression",
old_session_id=<old>) on the active context engine. Plugin engines
(e.g. hermes-lcm) use this to preserve DAG lineage across the rollover
instead of re-initializing fresh per-session state.

Built-in ContextCompressor.on_session_start accepts **kwargs and ignores
them — no behavior change for default users.

Closes hermes-lcm#68 symptom: after Hermes compressed and minted a new
physical session, LCM was treating the split as a fresh /new and losing
continuity (compression_count: 1, store_messages: 0, dag_nodes: 0).

Credit: @Tosko4 (PR NousResearch#13370) — minimized scope to the boundary_reason
signal only; the broader session-lifecycle refactor will be taken in
separate PRs if justified by concrete plugin need.
gweeteve pushed a commit to gweeteve/hermes-agent that referenced this pull request Jun 2, 2026
When _compress_context rotates session_id (compression split), fire
on_session_start(new_sid, boundary_reason="compression",
old_session_id=<old>) on the active context engine. Plugin engines
(e.g. hermes-lcm) use this to preserve DAG lineage across the rollover
instead of re-initializing fresh per-session state.

Built-in ContextCompressor.on_session_start accepts **kwargs and ignores
them — no behavior change for default users.

Closes hermes-lcm#68 symptom: after Hermes compressed and minted a new
physical session, LCM was treating the split as a fresh /new and losing
continuity (compression_count: 1, store_messages: 0, dag_nodes: 0).

Credit: @Tosko4 (PR NousResearch#13370) — minimized scope to the boundary_reason
signal only; the broader session-lifecycle refactor will be taken in
separate PRs if justified by concrete plugin need.
Egavasyug pushed a commit to Egavasyug/hermes-agent that referenced this pull request Jun 10, 2026
When _compress_context rotates session_id (compression split), fire
on_session_start(new_sid, boundary_reason="compression",
old_session_id=<old>) on the active context engine. Plugin engines
(e.g. hermes-lcm) use this to preserve DAG lineage across the rollover
instead of re-initializing fresh per-session state.

Built-in ContextCompressor.on_session_start accepts **kwargs and ignores
them — no behavior change for default users.

Closes hermes-lcm#68 symptom: after Hermes compressed and minted a new
physical session, LCM was treating the split as a fresh /new and losing
continuity (compression_count: 1, store_messages: 0, dag_nodes: 0).

Credit: @Tosko4 (PR NousResearch#13370) — minimized scope to the boundary_reason
signal only; the broader session-lifecycle refactor will be taken in
separate PRs if justified by concrete plugin need.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent loop, run_agent.py, prompt builder comp/plugins Plugin system and bundled plugins P3 Low — cosmetic, nice to have type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants