Forced tool use in text
Text that tries to force a tool invocation, or strip the consent step out of one, is aforced_tool_use detection like any other.
Validating the calls themselves
Declare the tools the model may call, and the guard judges every call the model produced against them, before anything runs.blocked cannot forward a request whose call was just rejected.
Supplying
tools turns on the allowlist check. Leaving them out leaves it off, because an absent list means you did not say what the model may call, not that it may call nothing.function. Anthropic puts it at the top level and names the schema input_schema. The SDK normalises them, so pass your provider request’s tools array straight through.
Findings
Each rejected call carries findings. Thecode is one of:
A finding raised against the raw argument text carries
start and end. That is the only kind you can redact.
Where the gate applies
- Non-streamed completions:
decorategates the response in place, reading declarations from the request body. A rejected call returns a blocked body instead of the response. - Streams: chunks are already in your hands by the time the call completes, so the decorator cannot withhold it. Assemble the calls yourself and pass them to
validateToolCalls, which is the same check.
Redacting arguments
WithonMatch: "sanitise", a finding raised against the raw argument text is redacted in place rather than dropped.
The semantic pass over arguments
The semantic pass runs over arguments as well as text. A call the signature pass clears is judged by the classifier, and its answer comes back on the tool verdict asmodelCheck. An argument it flags rejects the call with argument_injection: the model’s own output is steering the action layer.
modelCheck is absent when the signature pass already rejected the call, because the second stage never ran.
