Require verification before unlocking AI agent tools
The account tools do not exist in the model's world until a handler says the caller passed.
The claim
The model cannot call a tool that is not active. get_balance and list_recent_transactions are declared with active: false, so at the start of the call they are not in the model’s world: not discouraged, absent. The only thing that turns them on is a toggle_functions action emitted by the verify_pin handler. The handler emits it only when the PIN matches the caller’s record. A prompt that says “verify before discussing the account” is a request; this is a constraint.
How it works
@AgentBase.tool(name="get_balance", description="...", parameters={}, active=False)
def get_balance(self, args, raw_data): ...
@AgentBase.tool(name="verify_pin", ...)
def verify_pin(self, args, raw_data):
if pin_matches(raw_data["caller_id_num"], args["pin"]):
return (FunctionResult("You are verified.")
.toggle_functions([{"function": "get_balance", "active": True},
{"function": "list_recent_transactions", "active": True}])
.toggle_functions([{"function": "verify_pin", "active": False}])
.update_global_data({"verified": True}))
return FunctionResult("That PIN does not match.") # no action: nothing unlocksIn the rendered SWML the account functions carry "active": false. The successful handler’s reply carries the platform action the model never composes:
{"toggle_functions": [{"function": "get_balance", "active": true}, {"function": "list_recent_transactions", "active": true}]}The check is code, so a caller from an unknown number with the right digits still fails, and verify_pin retires itself once it has done its job. Retiring is optional; re-verification mid-call is the same toggle in reverse.
What to change first
Swap the PIN for an OTP: send a code with send-an-otp-by-sms-with-voice-fallback and verify it in the same handler before toggling the tools on.