Conversation
Addresses teknium1 review feedback on PR NousResearch#60781: 1. Gateway cache invalidation: added ('compression', 'model_thresholds') to _CACHE_BUSTING_CONFIG_KEYS so a live config edit to the map invalidates the cached compressor (previously kept stale thresholds). 2. Integrated resolver with small-context floor: per-model overrides are resolved FIRST, then the existing 75% floor for <512K models is applied on top. The floor is no longer replaced — it stacks. An override below 75% on a small-context model still gets floored to 75% (raise-only); an override above 75% wins. 3. Clean rebase on upstream main — no unrelated deletions or anti-thrashing changes. Only the per-model threshold feature is added. Changes: - resolve_model_threshold() module-level helper (longest substring match) - ContextCompressor.__init__ accepts model_thresholds dict - _base_threshold_percent stores the per-model resolved value - _config_threshold_percent stores the raw config value (fallback base) - update_model() re-resolves on /model switch, falls back to config value - ContextEngine base class update_model() applies overrides for plugin engines - agent_init.py reads compression.model_thresholds from config, passes to ctor - gateway/run.py cache busting key added - cli-config.yaml.example documents the feature - 17 tests covering resolve helper, compressor init (large/small context, override above/below floor), update_model (re-resolve, fallback), base class Co-authored-by: Copilot <copilot@github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Adds support for configuring per-model compression thresholds so Hermes can trigger context compaction at different usage points depending on the active model (resolved by longest substring match), while preserving existing compression behavior when no overrides are configured.
Changes:
- Introduces
compression.model_thresholdsresolution logic and integrates it into compressor model-switch handling. - Extends the
ContextEnginebaseupdate_model()to apply per-model threshold overrides for plugin engines. - Updates gateway cache-busting, example config documentation, and adds a dedicated test suite for override behavior.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
agent/context_compressor.py |
Adds resolve_model_threshold() and wires per-model overrides into compressor init + update_model(). |
agent/context_engine.py |
Applies per-model overrides in base ContextEngine.update_model() for engines that don’t override it. |
agent/agent_init.py |
Reads compression.model_thresholds from config and passes/propagates it to compressors/engines. |
gateway/run.py |
Busts gateway agent cache when compression.model_thresholds changes. |
cli-config.yaml.example |
Documents the new compression.model_thresholds configuration. |
tests/run_agent/test_per_model_compression_threshold.py |
Adds tests covering resolution rules, floor interactions, and model-switch re-resolution. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+935
to
+937
| _new_base = resolve_model_threshold( | ||
| model, self.model_thresholds, _config_pct, | ||
| ) |
Comment on lines
+728
to
+734
| best_key = "" | ||
| for key in model_thresholds: | ||
| if key in model and len(key) > len(best_key): | ||
| best_key = key | ||
| if best_key: | ||
| return float(model_thresholds[best_key]) | ||
| return default |
Comment on lines
1821
to
+1825
| api_mode=agent.api_mode, | ||
| ) | ||
| # Propagate per-model threshold overrides to plugin engines. | ||
| if compression_model_thresholds: | ||
| agent.context_compressor.model_thresholds = compression_model_thresholds |
Comment on lines
+416
to
+420
| # Per-model threshold overrides: keys are substring-matched against the model | ||
| # name (longest match wins). Useful when some models need different compaction | ||
| # points — e.g. a 1M-context model can compress later (0.30) while a 128K | ||
| # model needs to compress earlier (0.60). The small-context floor (75% for | ||
| # <512K models) still applies on top of per-model overrides. |
Comment on lines
+1570
to
+1577
| _raw_model_thresholds = _compression_cfg.get("model_thresholds", {}) | ||
| if isinstance(_raw_model_thresholds, dict): | ||
| compression_model_thresholds = { | ||
| str(k): float(v) for k, v in _raw_model_thresholds.items() | ||
| if isinstance(v, (int, float)) and not isinstance(v, bool) | ||
| } | ||
| else: | ||
| compression_model_thresholds = {} |
Collaborator
|
Thanks for preserving the small-context floor and adding gateway cache invalidation. The configurable built-in compressor premise is still present on current main. Problems
Suggested changes
Automated hermes-sweeper review. |
9 tasks
teknium1
added a commit
that referenced
this pull request
Jul 22, 2026
Follow-up to the salvaged contributor commit, closing the three gaps flagged in the sweeper review: 1. Init ordering: assign compression.model_thresholds to a selected plugin context engine BEFORE the initial update_model() call in agent_init.py, so the initial model's override applies from init (previously it only took effect after the first /model switch). Base-class ContextEngine.update_model() now snapshots the pre-override percent once so repeated switches fall back to the engine's configured threshold, not a previous model's override. 2. DEFAULT_CONFIG: add compression.model_thresholds (empty map) to hermes_cli/config.py — additive key, no _config_version bump. 3. Docs: document the key in website/docs/developer-guide/context-compression-and-caching.md (yaml example, parameter table, dedicated section) and update the plugin-boundary note in context-engine-plugin.md to state the explicit context-engine contract for model_thresholds. Adds tests/run_agent/test_per_model_threshold_init_ordering.py: plugin-engine AIAgent init regression (override applies at init, empty map unchanged), DEFAULT_CONFIG key presence, floor interaction on the model-switch path (override below the small-context floor is raised to the floor; above the floor wins), and base-class config snapshot across repeated switches. Also maps @bennybuoy in contributors/emails/.
This was referenced Jul 22, 2026
Collaborator
randlee
pushed a commit
to randlee/hermes-agent
that referenced
this pull request
Aug 11, 2026
…h#63020) Follow-up to the salvaged contributor commit, closing the three gaps flagged in the sweeper review: 1. Init ordering: assign compression.model_thresholds to a selected plugin context engine BEFORE the initial update_model() call in agent_init.py, so the initial model's override applies from init (previously it only took effect after the first /model switch). Base-class ContextEngine.update_model() now snapshots the pre-override percent once so repeated switches fall back to the engine's configured threshold, not a previous model's override. 2. DEFAULT_CONFIG: add compression.model_thresholds (empty map) to hermes_cli/config.py — additive key, no _config_version bump. 3. Docs: document the key in website/docs/developer-guide/context-compression-and-caching.md (yaml example, parameter table, dedicated section) and update the plugin-boundary note in context-engine-plugin.md to state the explicit context-engine contract for model_thresholds. Adds tests/run_agent/test_per_model_threshold_init_ordering.py: plugin-engine AIAgent init regression (override applies at init, empty map unchanged), DEFAULT_CONFIG key presence, floor interaction on the model-switch path (override below the small-context floor is raised to the floor; above the floor wins), and base-class config snapshot across repeated switches. Also maps @bennybuoy in contributors/emails/.
prmartinow
pushed a commit
to prmartinow/hermes-agent
that referenced
this pull request
Aug 26, 2026
…h#63020) Follow-up to the salvaged contributor commit, closing the three gaps flagged in the sweeper review: 1. Init ordering: assign compression.model_thresholds to a selected plugin context engine BEFORE the initial update_model() call in agent_init.py, so the initial model's override applies from init (previously it only took effect after the first /model switch). Base-class ContextEngine.update_model() now snapshots the pre-override percent once so repeated switches fall back to the engine's configured threshold, not a previous model's override. 2. DEFAULT_CONFIG: add compression.model_thresholds (empty map) to hermes_cli/config.py — additive key, no _config_version bump. 3. Docs: document the key in website/docs/developer-guide/context-compression-and-caching.md (yaml example, parameter table, dedicated section) and update the plugin-boundary note in context-engine-plugin.md to state the explicit context-engine contract for model_thresholds. Adds tests/run_agent/test_per_model_threshold_init_ordering.py: plugin-engine AIAgent init regression (override applies at init, empty map unchanged), DEFAULT_CONFIG key presence, floor interaction on the model-switch path (override below the small-context floor is raised to the floor; above the floor wins), and base-class config snapshot across repeated switches. Also maps @bennybuoy in contributors/emails/.
melon-xf
added a commit
to melon-xf/hermes-agent
that referenced
this pull request
Sep 3, 2026
…h#63020) Follow-up to the salvaged contributor commit, closing the three gaps flagged in the sweeper review: 1. Init ordering: assign compression.model_thresholds to a selected plugin context engine BEFORE the initial update_model() call in agent_init.py, so the initial model's override applies from init (previously it only took effect after the first /model switch). Base-class ContextEngine.update_model() now snapshots the pre-override percent once so repeated switches fall back to the engine's configured threshold, not a previous model's override. 2. DEFAULT_CONFIG: add compression.model_thresholds (empty map) to hermes_cli/config.py — additive key, no _config_version bump. 3. Docs: document the key in website/docs/developer-guide/context-compression-and-caching.md (yaml example, parameter table, dedicated section) and update the plugin-boundary note in context-engine-plugin.md to state the explicit context-engine contract for model_thresholds. Adds tests/run_agent/test_per_model_threshold_init_ordering.py: plugin-engine AIAgent init regression (override applies at init, empty map unchanged), DEFAULT_CONFIG key presence, floor interaction on the model-switch path (override below the small-context floor is raised to the floor; above the floor wins), and base-class config snapshot across repeated switches. Also maps @bennybuoy in contributors/emails/.
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.
Per-model compression threshold overrides (v2, rebased)
Replaces #60781 (closed). Cleanly rebased on current main — no unrelated deletions or anti-thrashing changes. Addresses both points from @teknium1's review:
Review feedback addressed
1. Gateway cache invalidation — added
('compression', 'model_thresholds')to_CACHE_BUSTING_CONFIG_KEYSingateway/run.py. A live config edit to the map now invalidates the cached compressor instead of silently keeping stale thresholds.2. Integrated resolver with small-context floor — per-model overrides are resolved FIRST, then the existing 75% floor for <512K models is applied ON TOP. The floor is no longer replaced; it stacks:
What it does
compression.model_thresholdsin config.yaml maps model name substrings to threshold fractions. Longest match wins (soglm-5.2-1Mbeatsglm-5.2). Re-resolved on/modelswitch.Files changed (6 files, +323/-11)
agent/context_compressor.py—resolve_model_threshold()helper,model_thresholdsparam, integration with_effective_threshold_percent()agent/context_engine.py— base classupdate_model()applies overrides for plugin enginesagent/agent_init.py— readscompression.model_thresholdsfrom config, passes to compressorgateway/run.py— cache busting key addedcli-config.yaml.example— documents the featuretests/run_agent/test_per_model_compression_threshold.py— 17 tests, all passingTest results
Tests cover: resolve helper (no overrides, empty model, exact/substring/longest match, no match, lower override), compressor init (large context with/without override, small context with override above/below floor, empty/None thresholds), update_model (re-resolve on switch, fall back to global), and ContextEngine base class.