Summary
ToolCallHookAction (in crates/rig-core/src/agent/prompt_request/hooks.rs) currently has three variants:
Continue
Skip { reason: String }
Terminate { reason: String }
There is no Replace { args: serde_json::Value } variant, which means a PromptHook implementation cannot intercept and rewrite a tool call's arguments mid-flight. Hooks can only let the call proceed unchanged, skip it, or terminate the loop.
This is a real limitation for any middleware that needs to mutate (not just gate) tool arguments before execution — for example, guardrail / policy / DLP libraries that want to redact PII, normalize parameters, or substitute scoped credentials before the tool runs.
Use case
We're building Agent Shield (an open guardrails specification + reference implementation) and have a rig adapter at agent_shield_rig. Our Stage 3 (tool_execution_validation) policies can produce mutated arguments — e.g. phone_number: "555-867-5309" → phone_number: "[REDACTED]". The hook needs to hand those mutated args back to rig so the tool sees the safe version.
Because there's no Replace { args } variant, our PromptHook impl (ShieldHook) currently fails closed (returns Skip { reason }) on any Stage-3 mutation, and customers needing full Stage-3 coverage have to fall back to a tool-wrapping pattern (GuardedRigTool) that wraps each tool before constructing the agent. That works, but it loses the elegance of the hook-based composition story.
Proposed change
Add a fourth variant to ToolCallHookAction:
pub enum ToolCallHookAction {
Continue,
Skip { reason: String },
Terminate { reason: String },
Replace { args: serde_json::Value }, // ← new
}
When the agent loop processes a Replace { args } action, it would substitute the provided args for the original tool-call arguments and continue with the call.
Why this matters beyond AgentShield
This pattern (mutating-not-just-gating middleware) is common in agent ecosystems:
- Semantic Kernel's
IAutoFunctionInvocationFilter (.NET) lets filters rewrite arguments via context.Arguments.
- Vercel AI SDK's
onStepFinish callback lets steps rewrite tool inputs.
- LangChain's tool callbacks can rewrite tool args before execution.
rig having only Continue/Skip/Terminate puts it slightly behind those ecosystems on the middleware-composition story. Adding Replace { args } would close the gap.
Backward compatibility
Adding an enum variant is a breaking change for anyone exhaustively matching on ToolCallHookAction, so this likely belongs in a minor version bump. The existing variants stay; existing hooks continue to compile and behave identically.
Happy to contribute
If the rig maintainers are open to this, we'd be happy to send a PR.
Summary
ToolCallHookAction(incrates/rig-core/src/agent/prompt_request/hooks.rs) currently has three variants:ContinueSkip { reason: String }Terminate { reason: String }There is no
Replace { args: serde_json::Value }variant, which means aPromptHookimplementation cannot intercept and rewrite a tool call's arguments mid-flight. Hooks can only let the call proceed unchanged, skip it, or terminate the loop.This is a real limitation for any middleware that needs to mutate (not just gate) tool arguments before execution — for example, guardrail / policy / DLP libraries that want to redact PII, normalize parameters, or substitute scoped credentials before the tool runs.
Use case
We're building Agent Shield (an open guardrails specification + reference implementation) and have a
rigadapter atagent_shield_rig. Our Stage 3 (tool_execution_validation) policies can produce mutated arguments — e.g.phone_number: "555-867-5309"→phone_number: "[REDACTED]". The hook needs to hand those mutated args back torigso the tool sees the safe version.Because there's no
Replace { args }variant, ourPromptHookimpl (ShieldHook) currently fails closed (returnsSkip { reason }) on any Stage-3 mutation, and customers needing full Stage-3 coverage have to fall back to a tool-wrapping pattern (GuardedRigTool) that wraps each tool before constructing the agent. That works, but it loses the elegance of the hook-based composition story.Proposed change
Add a fourth variant to
ToolCallHookAction:When the agent loop processes a
Replace { args }action, it would substitute the providedargsfor the original tool-call arguments and continue with the call.Why this matters beyond AgentShield
This pattern (mutating-not-just-gating middleware) is common in agent ecosystems:
IAutoFunctionInvocationFilter(.NET) lets filters rewrite arguments viacontext.Arguments.onStepFinishcallback lets steps rewrite tool inputs.righaving only Continue/Skip/Terminate puts it slightly behind those ecosystems on the middleware-composition story. AddingReplace { args }would close the gap.Backward compatibility
Adding an enum variant is a breaking change for anyone exhaustively matching on
ToolCallHookAction, so this likely belongs in a minor version bump. The existing variants stay; existing hooks continue to compile and behave identically.Happy to contribute
If the rig maintainers are open to this, we'd be happy to send a PR.