Skip to content

fix: expose context engine tools with saved toolsets - #31194

Closed
stephenschoettler wants to merge 1 commit into
NousResearch:mainfrom
stephenschoettler:fix/context-engine-toolset
Closed

fix: expose context engine tools with saved toolsets#31194
stephenschoettler wants to merge 1 commit into
NousResearch:mainfrom
stephenschoettler:fix/context-engine-toolset

Conversation

@stephenschoettler

@stephenschoettler stephenschoettler commented May 23, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Fixes context-engine tool exposure when a platform has a saved toolset list from hermes tools.

Context engines such as hermes-lcm expose runtime tools through get_tool_schemas(), but AIAgent only injects those schemas when the context_engine toolset is enabled. Saved platform lists like web, terminal, etc. did not include that toolset, so active LCM sessions could run with context.engine: lcm while the model never saw the lcm_* tools.

This adds a first-class context_engine toolset and auto-enables it when a non-default context engine is configured, while preserving the explicit empty-selection behavior.

Related Issue

Related: stephenschoettler/hermes-lcm#200

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

  • toolsets.py
    • Adds a static context_engine toolset entry for runtime-provided context-engine tools.
  • hermes_cli/tools_config.py
    • Adds context_engine to the configurable toolset list.
    • Auto-enables context_engine for non-default context.engine values, unless the platform selection is explicitly empty.
  • tests/hermes_cli/test_tools_config.py
    • Adds regressions for context-engine toolset visibility with explicit platform toolsets, default compressor behavior, and explicit empty selection.
  • tests/run_agent/test_plugin_context_engine_init.py
    • Adds an end-to-end regression proving a plugin context engine's tool schema reaches AIAgent.valid_tool_names after platform tool resolution.

How to Test

  1. Run focused validation:

    scripts/run_tests.sh tests/hermes_cli/test_tools_config.py tests/run_agent/test_plugin_context_engine_init.py tests/test_model_tools.py tests/test_get_tool_definitions_cache_isolation.py -- -q --tb=short

    Result:

    114 tests passed, 0 failed
    
  2. Run static checks:

    uvx ruff check .
    python scripts/check-windows-footguns.py --all

    Result:

    All checks passed!
    ✓ No Windows footguns found (502 file(s) scanned).
    
  3. Broader local validation:

    scripts/run_tests.sh -- -q --tb=short

    Result:

    25,165 tests passed, 4 failed
    

    The failures were in unrelated model-picker tests that hit this machine's live local Ollama /models endpoint and returned installed local models instead of the test fixture models:

    • tests/hermes_cli/test_list_picker_providers.py::test_current_custom_endpoint_passthrough_marks_current_row
    • tests/hermes_cli/test_model_switch_custom_providers.py::test_list_authenticated_providers_groups_same_endpoint
    • tests/hermes_cli/test_model_switch_custom_providers.py::test_list_authenticated_providers_distinct_endpoints_stay_separate
    • tests/hermes_cli/test_model_switch_custom_providers.py::test_list_authenticated_providers_total_models_reflects_grouped_count
  4. Manual exercise of changed path:

    Covered by the new AIAgent regression: `_get_platform_tools()` resolves `context_engine` for an active non-default engine, and the engine's `stub_recover` schema appears in `AIAgent.valid_tool_names` and `agent.tools`.
    

Validation Status

  • Focused regression tests: passing locally.
  • Static checks: passing locally (ruff, Windows footguns).
  • Broader local suite: run locally, blocked only by 4 unrelated local Ollama/model-picker fixture failures as noted above.
  • GitHub PR checks: green on head 6bd2b5b437a3ae11f8ea42f93195000faf7151b1.
    • Passing: dependency bounds, supply-chain scan, attribution, common ancestor, e2e, ruff/ty, Windows footguns, Nix, Docker builds, and test (1) through test (6).
    • Skipped: expected publish/duration jobs (merge, move-latest, save-durations).
  • Merge state: CLEAN when rechecked after the green rerun.
  • Full-suite checklist is intentionally unchecked because local full validation did not finish green for unrelated local provider/fixture failures.

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: Linux 7.0.5-arch1-1 x86_64, Python 3.14.5

Documentation and Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) or N/A
  • I've updated cli-config.yaml.example if I added/changed config keys or N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows or N/A
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide or N/A
  • I've updated tool descriptions/schemas if I changed tool behavior or N/A

For New Skills

N/A.

Screenshots / Logs

Before: active non-default context engines could expose schemas via get_tool_schemas(), but saved platform toolset lists omitted `context_engine`, so `AIAgent` suppressed those schemas.

After: `_get_platform_tools()` includes `context_engine` for non-default context engines, and the regression confirms the runtime schema reaches `AIAgent.valid_tool_names`.

@stephenschoettler

Copy link
Copy Markdown
Contributor Author

@ethernet8023 Bump on this one: PR checks are green, mergeState is CLEAN, and I refreshed the body against the live diff/current checks.

This is the narrow host-side fix for hermes-lcm tool visibility: active context-engine tools stay exposed after saved platform toolset selections. It unblocks the canonical path for stephenschoettler/hermes-lcm#200 without adding plugin-side registry duplication.

@teknium1

Copy link
Copy Markdown
Contributor

Merged via PR #33719 (commit 8595281f3). Your commit 6bd2b5b43 was cherry-picked onto current main with authorship preserved (conflict-free auto-merge, 455 commits behind when picked). All 112 of your targeted regression tests pass against current main.

The context_engine toolset is now first-class and auto-enables whenever context.engine is set to anything other than the default compressor, so an active LCM session's lcm_* tools will reach the model even when a user has saved an explicit platform toolset list via hermes tools. Thanks for the precise diagnosis + clean fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cli CLI entry point, hermes_cli/, setup wizard comp/plugins Plugin system and bundled plugins comp/tools Tool registry, model_tools, toolsets P3 Low — cosmetic, nice to have type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants