hermes - 💡(How to fix) Fix Feature request: pre_tool_call rewrite action (rewrite tool args from a hook) [1 comments, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
NousResearch/hermes-agent#18988Fetched 2026-05-03 04:53:05
View on GitHub
Comments
1
Participants
1
Timeline
6
Reactions
0
Author
Participants
Timeline (top)
labeled ×3commented ×1mentioned ×1subscribed ×1

Add support for a {"action": "rewrite", "args": {...}} return value to pre_tool_call hook callbacks, allowing plugins to rewrite tool arguments before execution. This would bring parity with Claude Code's PreToolUse permissionDecision: "allow" + updatedInput mechanism, and unblock cleaner integrations for tools like RTK that ship native hook support for other agents.

Root Cause

Hermes is the only major agent platform missing from RTK's hook lineup, specifically because pre_tool_call cannot rewrite. As a workaround I shipped a Hermes plugin (ta3pks/hermes-rtk-hook) that hooks transform_terminal_output and pipes raw output through rtk pipe -f <filter> post-hoc. End-to-end measurements: 98.1% reduction on cargo test (50 tests), 90.2% on git log --oneline (50 commits), 33.4% on find. So the savings target reaches the model — but the original command still runs to completion before the hook fires, so wallclock cost is unchanged. With pre_tool_call rewrite support, the plugin could pivot to args-rewriting and gain wallclock parity with RTK's other integrations, plus lose its own command→filter mapping (RTK would do it natively).

Fix Action

Fix / Workaround

There's no way for a plugin to inspect tool args and rewrite them before execution. This forces output-side workarounds (using transform_terminal_output post-hoc) for use cases that would be cleaner — and slightly more efficient — at the input side.

Hermes is the only major agent platform missing from RTK's hook lineup, specifically because pre_tool_call cannot rewrite. As a workaround I shipped a Hermes plugin (ta3pks/hermes-rtk-hook) that hooks transform_terminal_output and pipes raw output through rtk pipe -f <filter> post-hoc. End-to-end measurements: 98.1% reduction on cargo test (50 tests), 90.2% on git log --oneline (50 commits), 33.4% on find. So the savings target reaches the model — but the original command still runs to completion before the hook fires, so wallclock cost is unchanged. With pre_tool_call rewrite support, the plugin could pivot to args-rewriting and gain wallclock parity with RTK's other integrations, plus lose its own command→filter mapping (RTK would do it natively).

The existing get_pre_tool_call_block_message could be extended (or renamed to get_pre_tool_call_directive) to also surface a rewrite directive back to the dispatcher in model_tools.py. Strictly additive — plugins not returning "action": "rewrite" are unaffected.

Code Example

def my_rewrite_hook(tool_name, args, **_):
    if tool_name == "terminal" and args.get("command", "").startswith("git status"):
        return {"action": "rewrite", "args": {"command": f"rtk {args['command']}"}}
    return None
RAW_BUFFERClick to expand / collapse

Summary

Add support for a {"action": "rewrite", "args": {...}} return value to pre_tool_call hook callbacks, allowing plugins to rewrite tool arguments before execution. This would bring parity with Claude Code's PreToolUse permissionDecision: "allow" + updatedInput mechanism, and unblock cleaner integrations for tools like RTK that ship native hook support for other agents.

Problem

Currently pre_tool_call callbacks support two control-flow actions:

  • Implicit allow (return None)
  • Block (return {"action": "block", "message": "..."} — handled by get_pre_tool_call_block_message at hermes_cli/plugins.py:1172-1208)

There's no way for a plugin to inspect tool args and rewrite them before execution. This forces output-side workarounds (using transform_terminal_output post-hoc) for use cases that would be cleaner — and slightly more efficient — at the input side.

Concrete use case

RTK is a CLI proxy that filters shell command output for token efficiency (60–90% savings on git status, cargo test, pytest, etc.). It ships native hooks for Claude Code, Cursor, Gemini CLI, and Copilot — every platform whose PreToolUse-equivalent supports args rewriting. The integration pattern is uniform: git statusrtk git status so the model sees the filtered output without any plugin-side filtering logic.

Hermes is the only major agent platform missing from RTK's hook lineup, specifically because pre_tool_call cannot rewrite. As a workaround I shipped a Hermes plugin (ta3pks/hermes-rtk-hook) that hooks transform_terminal_output and pipes raw output through rtk pipe -f <filter> post-hoc. End-to-end measurements: 98.1% reduction on cargo test (50 tests), 90.2% on git log --oneline (50 commits), 33.4% on find. So the savings target reaches the model — but the original command still runs to completion before the hook fires, so wallclock cost is unchanged. With pre_tool_call rewrite support, the plugin could pivot to args-rewriting and gain wallclock parity with RTK's other integrations, plus lose its own command→filter mapping (RTK would do it natively).

Proposed shape

def my_rewrite_hook(tool_name, args, **_):
    if tool_name == "terminal" and args.get("command", "").startswith("git status"):
        return {"action": "rewrite", "args": {"command": f"rtk {args['command']}"}}
    return None

The existing get_pre_tool_call_block_message could be extended (or renamed to get_pre_tool_call_directive) to also surface a rewrite directive back to the dispatcher in model_tools.py. Strictly additive — plugins not returning "action": "rewrite" are unaffected.

Related

  • #18148 (@jeremypetz) covers a broader runtime-hook extension system, including transform_user_input / before_llm_call / intercept_tool_call. This request is a narrower, focused ask: add only the rewrite directive to the existing pre_tool_call surface, parallel to how block already works. Either issue can subsume this; I'm filing focused so the use case is concrete.

Notes

  • The pre_gateway_dispatch hook already supports {"action": "rewrite", "text": "..."} (hermes_cli/plugins.py:92-99), so the dispatch shape is precedented.
  • Backwards compatibility: strictly additive.

extent analysis

TL;DR

Add support for a "rewrite" action in the pre_tool_call hook callbacks to allow plugins to modify tool arguments before execution.

Guidance

  • Implement the proposed shape for the pre_tool_call hook callback, returning a dictionary with "action": "rewrite" and the modified arguments.
  • Extend the existing get_pre_tool_call_block_message function to handle the new "rewrite" action and surface the rewritten arguments to the dispatcher.
  • Update the model_tools.py file to handle the rewritten arguments and execute the modified command.
  • Test the implementation with the provided example use case, such as the my_rewrite_hook function, to ensure correct functionality.

Example

def my_rewrite_hook(tool_name, args, **_):
    if tool_name == "terminal" and args.get("command", "").startswith("git status"):
        return {"action": "rewrite", "args": {"command": f"rtk {args['command']}"}}
    return None

Notes

The proposed solution is strictly additive and maintains backwards compatibility, allowing plugins to opt-in to the new functionality without affecting existing behavior.

Recommendation

Apply the proposed workaround by adding support for the "rewrite" action in the pre_tool_call hook callbacks, as it provides a concrete solution to the problem and aligns with the existing pre_gateway_dispatch hook functionality.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - 💡(How to fix) Fix Feature request: pre_tool_call rewrite action (rewrite tool args from a hook) [1 comments, 1 participants]