Skip to content

feat: configurable skills prompt filter to reduce context bloat - #11223

Open
SupplyantSimon wants to merge 7 commits into
NousResearch:mainfrom
SupplyantSimon:feat/skills-prompt-filter
Open

feat: configurable skills prompt filter to reduce context bloat#11223
SupplyantSimon wants to merge 7 commits into
NousResearch:mainfrom
SupplyantSimon:feat/skills-prompt-filter

Conversation

@SupplyantSimon

Copy link
Copy Markdown

Summary

Adds a skills.system_prompt_skills config option that filters which skills appear in the auto-injected system prompt index.

Changes

  • agent/prompt_builder.py: filters the skills index against the configured curated list; updates cache key so filtered/unfiltered builds do not collide
  • hermes_cli/config.py: adds system_prompt_skills to default config and bumps version to 18

Impact

Cuts ~1,500 tokens per turn when a curated list is configured (e.g., from 81 skills down to 3). Other skills remain discoverable via skills_list() / skill_view() on demand.

Backwards Compatibility

When system_prompt_skills is unset or empty, all skills are included in the prompt (existing behavior).

Zoe Backup added 2 commits April 18, 2026 07:27
- Adds skills.system_prompt_skills config option
- Only listed skills appear in the auto-injected system prompt index
- Cuts ~1500 tokens per turn when curated
- Bumps config version to 18
…lter

# Conflicts:
#	agent/prompt_builder.py
@SupplyantSimon
SupplyantSimon force-pushed the feat/skills-prompt-filter branch from 572198b to 7ada837 Compare April 19, 2026 19:27
Zoe Backup and others added 5 commits April 19, 2026 20:50
- Add send_voice() to WhatsApp adapter for voice bubble delivery
- Fix voice reply dedupe to allow replies on platforms without VC auto-TTS
- Update ffmpeg Opus params for WhatsApp voice note compatibility
Add a circuit breaker mechanism in _invoke_tool() and the sequential
execution path to detect and break infinite tool-call loops.

When the same tool with identical arguments is called 3 consecutive
times, the circuit breaker triggers and returns an error, forcing the
LLM to try a different strategy.

The breaker uses MD5 hashing of (tool_name, json_args) to create a
stable signature, then checks if the last N calls all have the same
signature. After triggering, the counter resets so future calls can
succeed.

- Added _consecutive_tool_calls and _circuit_breaker_threshold to AIAgent.__init__
- Added circuit breaker logic to _invoke_tool() (concurrent path)
- Added circuit breaker logic to _execute_tool_calls_sequential() (sequential path)
- All 22 existing tests pass
When a tool schema declares `type: array` or `type: object` and the model
emits the value as a JSON string (common with complex oneOf discriminated
unions), the MCP server rejects it with -32602 "expected array, received
string".  Extend `_coerce_value` to attempt `json.loads` for these types
and replace the string with the parsed value before dispatch.

Root cause confirmed via live testing: `add_reminders.reminders` uses a
oneOf discriminated union (relative/absolute/location) that triggers model
output drift.  Sending a real array passes validation; sending a string
reproduces the exact error.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint tool/skills Skills system (list, view, manage) area/config Config system, migrations, profiles labels Apr 25, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Related to #12015 (open, skills.system_prompt_mode config) and #10172 (open, context-aware skills prompt optimization). Multiple competing approaches for the same problem — consider consolidating.

@teknium1 teknium1 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.

Thanks for tackling a real prompt-budget issue: current main still renders full descriptions for primary-session skills at agent/prompt_builder.py:1660-1667.

Problems

  • The new filter removes non-curated skill names (agent/prompt_builder.py:783 in this diff). Current main explicitly requires names to remain visible because models do not reliably rediscover omitted skills via skills_list (agent/prompt_builder.py:1622-1630), and the regression test codifies that contract (tests/agent/test_prompt_builder.py:429-455).
  • The branch also includes unrelated auxiliary-client, WhatsApp, MCP, circuit-breaker, and TTS changes. Those should not accompany a skills-index design change.

Suggested changes

  • Preserve all names and reduce token cost through names-only demotion, using the existing compaction direction rather than pruning entries.
  • Split unrelated commits and add tests for configuration, cache partitioning, and name visibility.
  • Please consolidate with the approaches linked in the existing discussion (#12015 and #10172).

Automated hermes-sweeper review.

Comment thread agent/prompt_builder.py
_allowed = set(_sp_skills)
filtered: dict[str, list[tuple[str, str]]] = {}
for cat, items in skills_by_category.items():
kept = [(n, d) for n, d in items if n in _allowed]

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.

This prunes every non-curated skill from the index. Current main intentionally preserves all names because models do not reliably rediscover omitted agent-created skills via skills_list (agent/prompt_builder.py:1622-1630; tests/agent/test_prompt_builder.py:429-455). Please retain names and compact descriptions instead.

@teknium1 teknium1 added sweeper:risk-caching Sweeper risk: may break/degrade prompt caching or cache-key stability (invariant) sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-massive Sweeper blast radius: massive — everyone, every turn (invariant surface) labels Jul 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/config Config system, migrations, profiles comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint P3 Low — cosmetic, nice to have sweeper:blast-massive Sweeper blast radius: massive — everyone, every turn (invariant surface) sweeper:risk-caching Sweeper risk: may break/degrade prompt caching or cache-key stability (invariant) sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades tool/skills Skills system (list, view, manage) type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants