Voice Tools

Voice Approvals (HITL)

Get verbal confirmation from callers before executing high-stakes actions like payments, bookings, or data changes.

Voice Approvals (HITL)

The Voice Approvals tool implements Human-in-the-Loop (HITL) for voice calls. Before executing high-stakes actions — payments, bookings, permanent changes — the agent asks for verbal confirmation and handles three intents: approve, reject, and clarify.

How It Works

Agent: "I'd like to place your order for $45.00. Should I go ahead?"
Caller: "Yes, go ahead."
-> Agent calls record_approval_decision with decision="approved"
-> Agent executes the action

-- OR --

Caller: "Wait, how much was shipping?"
-> Agent answers the clarification question naturally
-> Agent re-asks for confirmation
Caller: "Okay yes, that works."
-> Agent calls record_approval_decision with decision="approved"

Approval Modes

ModeBehavior
blockingAgent cannot proceed until explicit approval or rejection
confirm_toolsAgent asks confirmation before ANY tool that modifies external state
auditLogs approval requests but doesn't block execution

Configuration

{
  "voiceApprovalEnabled": true,
  "voiceApprovalMode": "blocking",
  "voiceApprovalMaxClarifications": 3,
  "voiceApprovalTimeoutMinutes": 5,
  "voiceApprovalPrompt": ""
}
SettingTypeDefaultDescription
voiceApprovalEnabledbooleanfalseEnable voice HITL approvals
voiceApprovalModestringblockingMode: blocking, confirm_tools, audit
voiceApprovalMaxClarificationsinteger3Max clarification questions before forcing yes/no
voiceApprovalTimeoutMinutesinteger5Approval timeout in minutes
voiceApprovalPromptstringCustom approval protocol prompt (overrides defaults)

LLM Tools

request_voice_approval

Request verbal confirmation from the caller before a high-stakes action.

Parameters:
  action_description: string (what the agent wants to do)
  impact_summary: string (brief summary of the impact)

Returns: Instructions for the LLM to speak the confirmation question

record_approval_decision

Record the caller's approval or rejection.

Parameters:
  decision: string ("approved" or "rejected")
  reason: string (optional reason)

Returns: Confirmation of the recorded decision

Three-Intent Handling

The LLM acts as a natural-language state machine:

  1. APPROVE — "Yes", "Go ahead", "Sure", "Do it" -> calls record_approval_decision with decision='approved'
  2. REJECT — "No", "Cancel", "Never mind" -> calls record_approval_decision with decision='rejected'
  3. CLARIFY — "Wait, how much?", "What's included?" -> Agent answers naturally, then re-asks. No tool call for clarifications.

Confirm Tools Mode

In confirm_tools mode, the agent automatically asks for confirmation before calling ANY tool that modifies external state:

  • Creating records
  • Sending messages
  • Processing payments
  • Booking appointments
  • Updating databases
  • Triggering webhooks

Read-only tools (lookups, searches, fetching information) are exempt.

Example — Create Agent with Voice Approvals

curl -X POST https://api.thinnest.ai/v1/agents \
  -H "Authorization: Bearer $THINNESTAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Order Agent with Approvals",
    "model": "gpt-4o",
    "instructions": "You help customers place orders. Before processing any payment or order, you MUST get verbal confirmation from the caller.",
    "voiceEnabled": true,
    "transcriber": { "provider": "deepgram", "model": "nova-2-conversationalai" },
    "voice": { "provider": "deepgram", "voiceId": "aura-2-thalia-en" },
    "voiceApprovalEnabled": true,
    "voiceApprovalMode": "blocking",
    "voiceApprovalMaxClarifications": 3,
    "voiceApprovalTimeoutMinutes": 5
  }'

System Prompt Example

Before performing any action that involves money, permanent changes, scheduling,
or sensitive operations, you MUST get verbal confirmation from the caller.

1. Call request_voice_approval with a description and impact summary
2. Speak the confirmation question naturally
3. Handle the response:
   - APPROVE -> call record_approval_decision with decision='approved'
   - REJECT -> call record_approval_decision with decision='rejected'
   - CLARIFY -> answer naturally, then re-ask
4. Maximum 3 clarifications. If exceeded, summarize and ask for a final yes/no.

On this page