Skip to content

hooks/hermes: add transform_tool_result output filter for high-token tools#2261

Open
cfournel wants to merge 2 commits into
rtk-ai:developfrom
cfournel:feat/hermes-transform-tool-result-v2
Open

hooks/hermes: add transform_tool_result output filter for high-token tools#2261
cfournel wants to merge 2 commits into
rtk-ai:developfrom
cfournel:feat/hermes-transform-tool-result-v2

Conversation

@cfournel

@cfournel cfournel commented Jun 4, 2026

Copy link
Copy Markdown

Summary

Adds a Hermes plugin (hooks/hermes/rtk-rewrite/) that registers two hooks:

Hook 1 — pre_tool_call: automatic command rewriting

Rewrites bare terminal commands (find, grep, cat, ls, …) to their rtk equivalents before execution, using rtk rewrite as the single source of truth. Workers benefit automatically without needing to prefix commands manually — identical to the Claude Code PreToolUse hook but applied inside Hermes so all backends (local, Docker, SSH, Modal) benefit.

Worker command Executed as
find /home -name '*.py' rtk find /home -name '*.py'
grep -rn foo /src rtk grep -rn foo /src
cat large_file.yaml rtk read large_file.yaml
ls -la /some/dir rtk ls -la /some/dir
python3 script.py unchanged

Hook 2 — transform_tool_result: output filtering

Filters high-token tool outputs before they enter the conversation context:

Tool(s) Filter Limit
terminal JSON-unwrap, deduplicate, strip blanks 100 lines
browser_navigate Strip Layout* accessibility noise, deduplicate, truncate 120 lines
read_file, execute_code Deduplicate, strip blank lines 100 lines
write_file, patch Replace unified diff with 1-line summary
search_files Truncate results 50 results
kanban_show, kanban_list Keep last 10 events 10 events

The write_file/patch filter is the main fix for context overflow on patch-heavy tasks — a 50-line diff becomes [patch] src/foo.cs (2 hunks, +5/-3 lines).

All filters fail open — if parsing fails or RTK is absent, the original output is passed through unchanged.

Motivation

Observed in Hermes kanban worker logs over 24h (pigwars board):

Bare command Count Notable cost
find 60 2× timeout [exit 124] at 10–15s
ls 19 unfiltered directory trees
grep 13 full match dumps
cat 5 large Unity YAML files

Context overflow crashes (context length exceeded at ~41k tokens) were traced to unfiltered write_file/patch diffs and large browser_navigate snapshots accumulating across turns.

Files changed

  • hooks/hermes/rtk-rewrite/__init__.py — plugin implementation (pre_tool_call + transform_tool_result)
  • hooks/hermes/rtk-rewrite/plugin.yaml — hook declarations
  • hooks/hermes/README.md — full documentation for both hooks
  • hooks/hermes/tests/test_transform_tool_result.py — 44 tests covering all filters

Test plan

  • 44 unit tests for all transform_tool_result filters (all pass)
  • Existing 18 pre_tool_call tests (all pass)
  • Worker runs bare find /home -name '*.py' → executes as rtk find, output filtered
  • Worker runs python3 script.py → passes through unchanged
  • rtk absent from PATH → all commands execute normally, one warning logged
  • write_file with 50-line diff → result replaced with 1-line [patch] summary
  • browser_navigate with Layout* noise → snapshot stripped and truncated
  • kanban_show with 80 events → truncated to last 10

🤖 Generated with Claude Code

@cfournel

cfournel commented Jun 4, 2026

Copy link
Copy Markdown
Author

This allows also to compact tools output in Hermes kanban so all cards are optimized too .

@cfournel cfournel force-pushed the feat/hermes-transform-tool-result-v2 branch 2 times, most recently from 8ba9760 to 2bf3707 Compare June 7, 2026 21:50
@CLAassistant

CLAassistant commented Jun 9, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@cfournel cfournel force-pushed the feat/hermes-transform-tool-result-v2 branch from b230a6d to 92f9b15 Compare June 9, 2026 08:22
cfournel and others added 2 commits June 22, 2026 18:51
… tools

Filters 7 tools before their output enters the conversation context:

- terminal: JSON unwrap + dedup + truncate 100L
- browser_navigate: strip Layout* noise, dedup, truncate 120L (~21% reduction)
- read_file / execute_code: dedup + truncate 100L
- write_file / patch: replace full unified diff with 1-line summary
  (e.g. "[patch] file.cs (2 hunks, +13/-8 lines)") — main fix for
  patch-heavy tasks where 5+ diffs × 25L each saturate the context
- search_files: truncate to 50 results
- kanban_show / kanban_list: keep last 10 events only

All filters fail open. plugin.yaml updated to declare the hook.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Tests (44 cases across 7 test classes):
- TransformDispatchTest: unknown tool → None, None/empty result → None
- FilterTextTest: dedup, blank-strip, 100-line truncation, no-change → None
- FilterTerminalTest: JSON unwrap, exit_code/error preservation, non-JSON fallback
- FilterBrowserTest: Layout* stripping, dedup, 120-line truncation, stealth field removal
- FilterDiffTest: compact summary format, hunk singular/plural, shorter-than-original guard
- FilterSearchFilesTest: 50-result limit, exact boundary, blank-line exclusion
- FilterKanbanTest: 10-event limit, section preservation, kanban_show + kanban_list dispatch

README: documents both hooks (pre_tool_call + transform_tool_result) with
filter table, diff-summary example, browser noise context, fail-open
behavior, and limitations section.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@cfournel cfournel force-pushed the feat/hermes-transform-tool-result-v2 branch from 3817c7a to f5b5802 Compare June 22, 2026 16:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants