Custom Tools
Allow your AI assistant to execute functions during calls, like looking up customer information or booking appointments.
Custom tools allow your AI assistant to execute functions during calls, like looking up customer information, booking appointments, or checking inventory.
How Tools Work
- You define tools in your assistant's
llm_config.tools[] - During a call, the LLM decides when to use a tool
- HMS Sovereign sends a webhook request with the tool call details
- Your endpoint returns the result
- The LLM uses the result to continue the conversation
Defining a Tool
Add tools when creating or updating your assistant:
curl -X PATCH https://api.hmsovereign.com/api/v1/assistants/ASSISTANT_ID \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"llm_config": {
"provider": "openai",
"model": "gpt-4o-mini",
"tools": [
{
"name": "lookup_customer",
"description": "Look up customer information by phone number or name. Use this when the caller asks about their account or you need to verify their identity.",
"parameters": {
"type": "object",
"properties": {
"phone": {
"type": "string",
"description": "Customer phone number in E.164 format"
},
"name": {
"type": "string",
"description": "Customer name to search for"
}
}
}
},
{
"name": "book_appointment",
"description": "Book an appointment for the customer. Ask for their preferred date and time first.",
"parameters": {
"type": "object",
"properties": {
"date": {
"type": "string",
"description": "Appointment date in YYYY-MM-DD format"
},
"time": {
"type": "string",
"description": "Appointment time in HH:MM format"
},
"service": {
"type": "string",
"description": "Type of service requested"
}
},
"required": ["date", "time"]
}
}
]
}
}'Tool Definition Schema
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Unique tool name (used by LLM) |
description | string | Yes | What the tool does (helps LLM decide when to use it) |
url | string | No | Per-tool webhook URL (overrides assistant's webhook_url) |
async | boolean | No | Fire-and-forget mode (default: false) |
async_response | string | No | Response for async tools |
parameters | object | No | JSON Schema for tool inputs |
Writing Good Descriptions
The description is crucial - it tells the LLM when and how to use the tool.
Good descriptions:
{
"name": "check_inventory",
"description": "Check product availability and stock levels. Use when customer asks if a product is in stock or available. Returns quantity available and location."
}{
"name": "create_support_ticket",
"description": "Create a support ticket for issues that cannot be resolved during the call. Use only when you cannot help the customer directly. Requires a description of the issue."
}Bad descriptions:
{
"name": "lookup",
"description": "Looks up data"
}Handling Tool Calls
When a tool is called, your webhook receives:
{
"message": {
"type": "tool-calls",
"tool_call_list": [
{
"id": "tool_abc123",
"type": "function",
"function": {
"name": "lookup_customer",
"arguments": {
"phone": "+31612345678"
}
}
}
]
}
}Return the result:
{
"results": [
{
"tool_call_id": "tool_abc123",
"result": {
"found": true,
"name": "Jan de Vries",
"email": "jan@example.com",
"account_type": "premium",
"member_since": "2020-03-15"
}
}
]
}Per-Tool URLs
Route different tools to different endpoints:
{
"tools": [
{
"name": "lookup_customer",
"description": "...",
"url": "https://crm.example.com/api/lookup"
},
{
"name": "book_appointment",
"description": "...",
"url": "https://calendar.example.com/api/book"
}
]
}Async Tools
For tools that don't need to return a result (logging, notifications):
{
"name": "log_interest",
"description": "Log that the customer expressed interest in a product for follow-up",
"async": true,
"async_response": "Interest noted for follow-up.",
"parameters": {
"type": "object",
"properties": {
"product": { "type": "string" },
"notes": { "type": "string" }
}
}
}The LLM immediately receives "Interest noted for follow-up." while your webhook processes in the background.
Built-in Tools
End Call
Allow the assistant to end the call:
{
"type": "end_call"
}Transfer Call
Allow the assistant to transfer to specific destinations:
{
"type": "transfer_call",
"destinations": [
{
"type": "number",
"number": "+31612345678",
"description": "Sales team - for pricing questions and quotes",
"message": "I'm transferring you to our sales team."
},
{
"type": "number",
"number": "+31687654321",
"description": "Technical support - for product issues",
"message": "I'm transferring you to technical support."
}
]
}Complete Example
Assistant configuration with multiple tools:
{
"name": "Customer Service Assistant",
"webhook_url": "https://api.example.com/webhooks/hms-sovereign",
"webhook_secret": "secret123",
"webhook_events": ["tool-calls", "end-of-call-report"],
"llm_config": {
"provider": "openai",
"model": "gpt-4o-mini",
"messages": [
{
"role": "system",
"content": "You are a customer service agent. Use the available tools to help customers."
}
],
"tools": [
{
"name": "lookup_customer",
"description": "Look up customer by phone number",
"parameters": {
"type": "object",
"properties": {
"phone": { "type": "string" }
},
"required": ["phone"]
}
},
{
"name": "check_order_status",
"description": "Check the status of a customer order",
"parameters": {
"type": "object",
"properties": {
"order_id": { "type": "string" }
},
"required": ["order_id"]
}
},
{ "type": "end_call" },
{
"type": "transfer_call",
"destinations": [
{
"type": "number",
"number": "+31612345678",
"description": "Human support for complex issues"
}
]
}
]
}
}See Tool Calls Webhook for webhook details.