> ## Documentation Index
> Fetch the complete documentation index at: https://anam.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Tools and Function Calling

> Enable your AI personas to interact with external systems, trigger client actions, and search knowledge bases

## Overview

Anam's tool calling system enables AI personas to perform actions beyond conversation. During a session, the LLM can decide when to invoke tools based on user intent, making your personas capable of:

* Triggering client-side actions (opening modals, redirecting pages, updating UI)
* Searching knowledge bases using semantic search (RAG)
* Calling external APIs via webhooks
* Executing custom business logic

Tools make your AI personas agentic, capable of taking actions to help users accomplish their goals.

<Warning>
  **Beta Feature**: Tool calling is currently in beta. You may encounter some
  issues as we continue to improve the feature. Please report any feedback or
  issues to help us make it better.
</Warning>

## How Tool Calling Works

When a user interacts with your persona, the conversation flows through a decision-making process:

<Steps>
  <Step title="User speaks or types">
    The user makes a request: "What's the status of my order 12345?"
  </Step>

  <Step title="LLM analyzes intent">
    The persona's LLM analyzes the request and determines it needs external information to respond accurately.
  </Step>

  <Step title="Tool invocation">
    The LLM selects the appropriate tool and generates a structured function call:

    ```json theme={"system"}
    {
      "name": "check_order_status",
      "arguments": {
        "orderId": "12345"
      }
    }
    ```
  </Step>

  <Step title="Tool execution">
    The system executes the tool based on its type:

    * **Client tools**: The SDK triggers your registered handler. If `awaitResult` is `true`, the return value from `onStart` (or error message if it throws) is sent back to the engine as the tool result.
    * **Knowledge tools**: Semantic search performed on your documents
    * **Webhook tools**: HTTP request sent to your API endpoint
    * **System tools**: Executed instantly inside the engine
  </Step>

  <Step title="Response integration">
    The tool result is returned to the LLM, which incorporates it into a natural language response.

    <Check>
      The user hears a complete, informed answer without knowing the technical orchestration behind the scenes.
    </Check>
  </Step>
</Steps>

## Tool Types

Anam supports four types of tools, each designed for different use cases:

### Client Tools

Client tools trigger events in your client application, enabling the persona to control your user interface.

**Common use cases**:

* Opening product pages or checkout flows
* Displaying modals or notifications
* Navigating to specific sections of your app
* Updating UI state based on conversation

```typescript theme={"system"}
{
  type: 'client',
  name: 'open_checkout',
  description: 'Opens the checkout page when user wants to purchase',
  parameters: {
    type: 'object',
    properties: {
      productId: {
        type: 'string',
        description: 'The ID of the product to checkout'
      }
    },
    required: ['productId']
  },
  awaitResult: true,
  toolTimeoutSeconds: 10
}
```

<Tip>
  Client tools work well for creating voice-driven user experiences
  where the AI can guide users through your application. Set `awaitResult: true` on the tool definition if you want the return value from your handler to be sent back to the LLM. Use `toolTimeoutSeconds` to control how long the engine waits for a result (default: 10s, max: 600s).
</Tip>

### Knowledge Tools (RAG)

Knowledge tools enable semantic search across your uploaded documents using Retrieval-Augmented Generation (RAG).

**Common use cases**:

* Answering questions from product documentation
* Searching company policies or FAQs
* Retrieving information from manuals or guides
* Providing accurate, source-based responses

```typescript theme={"system"}
{
  type: 'server',
  subtype: 'knowledge',
  name: 'search_documentation',
  description: 'Search product documentation when user asks questions',
  documentFolderIds: ['550e8400-e29b-41d4-a716-446655440000', '6ba7b810-9dad-11d1-80b4-00c04fd430c8']
}
```

<Info>
  Folder IDs are UUIDs. You can find them in the Anam Lab UI at `/knowledge` or
  via the API when creating folders.
</Info>

Knowledge tools handle search automatically:

* They understand the user's intent, not just keywords.
* They find the most relevant snippets from your documents.
* They provide this information to the AI to form an accurate answer.

<Note>
  Knowledge tools require you to upload and organize documents in knowledge
  folders before they can be used. Learn more in the [Knowledge Base
  documentation](/personas/knowledge/overview).
</Note>

### Webhook Tools

Webhook tools call external HTTP endpoints, allowing your persona to integrate with any API. This enables your persona to interact with external systems and perform actions.

**Common use cases**:

* Checking order or shipment status
* Creating support tickets
* Updating CRM records
* Fetching real-time data (weather, stock prices, etc.)
* Triggering workflows in external systems

```typescript theme={"system"}
{
  type: 'server',
  subtype: 'webhook',
  name: 'check_order_status',
  description: 'Check the status of a customer order',
  url: 'https://api.example.com/orders',
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.API_SECRET}`,
    'X-Organization-ID': 'org-uuid'
  },
  parameters: {
    type: 'object',
    properties: {
      orderId: {
        type: 'string',
        description: 'The order ID to check'
      }
    },
    required: ['orderId']
  },
  awaitResponse: true
}
```

<Tip>
  Set `awaitResponse: false` for fire-and-forget webhooks like logging or
  notifications where you don't need the response data.
</Tip>

### System Tools

System tools are built-in tools that execute directly inside the Anam engine for instant session control. Unlike other tool types, they require no external endpoints or client-side handlers — just specify the `type` and `name`.

**Available system tools**:

* `change_language` — Dynamically switch the speech recognition language mid-session
* `skip_turn` — Skip the persona's response and wait silently for the user to continue

System tools are pre-provisioned for all organizations. Fetch the tool IDs via the API and attach them using `toolIds`:

```bash theme={"system"}
curl -X GET 'https://api.anam.ai/v1/tools' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'
```

<Tip>
  See the [System Tools guide](/personas/tools/system-tools) for detailed usage, supported languages, and configuration examples.
</Tip>

## Protecting Tool Turns from Interruptions

By default, the user can interrupt the persona at any point, including while a tool is executing or while the persona is reading the tool result back. For tools that drive a multi-step action — for example, navigating to a new page, submitting a form, or playing back a confirmation — an interruption part way through can leave the conversation out of sync with what your application just did.

Set `disableInterruptions` to `true` on a tool definition to suppress interruptions for the duration of that tool's turn:

```typescript theme={"system"}
{
  type: 'server',
  subtype: 'webhook',
  name: 'submit_order',
  description: 'Submit the customer order once they have confirmed the items',
  url: 'https://api.example.com/orders',
  method: 'POST',
  awaitResponse: true,
  disableInterruptions: true,
}
```

The flag applies to all tool types: `client`, `server` (knowledge and webhook), and `system`. It defaults to `false`, which preserves the existing interrupt-anytime behavior.

<Note>
  `disableInterruptions` only takes effect when there is a turn to protect. Set `awaitResult: true` on client tools and `awaitResponse: true` on webhook tools — fire-and-forget tools return control to the LLM immediately, so the flag has nothing to guard.
</Note>

When creating tools via the API, pass `disableInterruptions` alongside the other tool fields:

```http theme={"system"}
POST /v1/tools
Content-Type: application/json
Authorization: Bearer YOUR_API_KEY

{
  "type": "server",
  "subtype": "webhook",
  "name": "submit_order",
  "description": "Submit the customer order once they have confirmed the items",
  "disableInterruptions": true,
  "config": {
    "url": "https://api.example.com/orders",
    "method": "POST",
    "awaitResponse": true
  }
}
```

## Attaching Tools to Personas

Tools can be attached to personas in two ways:

### Stateful Personas (Database-Stored)

For stateful personas, tools must be created first and then attached by their ID.

<Steps>
  <Step title="Create tools">
    Create tools via the UI at `/tools` or via the API. Each tool gets a persistent ID.

    ```http theme={"system"}
    POST /v1/tools
    Content-Type: application/json
    Authorization: Bearer YOUR_API_KEY

    {
      "type": "server",
      "subtype": "knowledge",
      "name": "search_docs",
      "description": "Search product documentation",
      "config": {
        "documentFolderIds": ["550e8400-e29b-41d4-a716-446655440000"]
      }
    }
    ```

    Response includes the tool ID:

    ```json theme={"system"}
    {
      "id": "tool-uuid-123",
      "name": "search_docs",
      ...
    }
    ```
  </Step>

  <Step title="Attach tools to persona">
    In the UI at `/build/{personaId}`, add tools from your organization's tool library, OR via API when creating/updating a persona:

    ```http theme={"system"}
    PUT /v1/personas/{personaId}
    Content-Type: application/json
    Authorization: Bearer YOUR_API_KEY

    {
      "toolIds": ["tool-uuid-123", "tool-uuid-456"]
    }
    ```
  </Step>

  <Step title="Use persona in session">
    When you create a session with this persona, all attached tools are automatically loaded:

    ```http theme={"system"}
    POST /v1/auth/session-token
    Content-Type: application/json

    {
      "personaConfig": {
        "personaId": "persona-uuid"
      }
    }
    ```

    <Check>
      The persona's tools are available during the session without needing to specify them again.
    </Check>
  </Step>
</Steps>

### Ephemeral Personas (Session-Only)

For ephemeral personas defined at session creation time, attach tools by their IDs in the `toolIds` array:

```http theme={"system"}
POST /v1/auth/session-token
Content-Type: application/json
Authorization: Bearer YOUR_API_KEY

{
  "personaConfig": {
    "name": "Support Agent",
    "avatarId": "avatar-uuid",
    "voiceId": "voice-uuid",
    "llmId": "llm-uuid",
    "systemPrompt": "You are a helpful support agent...",
    "toolIds": ["tool-uuid-123", "tool-uuid-456"]
  }
}
```

<Info>
  Tools must be created first via the API or UI before they can be attached to ephemeral personas. The `toolIds` array references existing tool IDs.
</Info>

## Handling Tool Events

For client tools, use `registerToolCallHandler` to define per-tool handlers, this will automatically emit `completed` or `failed` events when the handler completes.

```typescript theme={"system"}
import { AnamClient } from '@anam-ai/js-sdk';

const client = new AnamClient(sessionToken);

const cancelCheckoutHandler = client.registerToolCallHandler('open_checkout', {
  onStart: async (payload) => {
    window.location.href = `/checkout/${payload.arguments.productId}`;
    return `Opened checkout for product ${payload.arguments.productId}`;
  },
  onComplete: async(payload) => {
    console.log(`tool call completed ${payload.toolName}`)
  },
  onFail: async(payload) => {
    console.log(`tool call failed ${payload.toolName}`)
  }
});

// you can also register partial handlers
const cancelRegisterHandler = client.registerToolCallHandler('show_notification', {
  onStart: async (payload) => {
    showNotification(payload.arguments.message);
    return 'Notification shown';
  },
});
```

You can also listen for tool call lifecycle events for logging or analytics:

```typescript theme={"system"}
import { AnamEvent } from '@anam-ai/js-sdk';

client.addListener(AnamEvent.TOOL_CALL_STARTED, (event) => {
  console.log('Tool started:', event.toolName, event.arguments);
});

client.addListener(AnamEvent.TOOL_CALL_COMPLETED, (event) => {
  console.log('Tool completed:', event.toolName, `${event.executionTime}ms`);
});
```

<Warning>
  Register handlers and event listeners before calling `streamToVideoElement()` to ensure you don't miss any events.
</Warning>

## Tool Design Best Practices

### Write Clear Descriptions

The tool description helps the LLM understand **when** to use the tool. Be specific and include context.

<CodeGroup>
  ```typescript Good theme={"system"}
  {
    name: 'check_order_status',
    description: 'Check the status of a customer order when they ask about delivery, tracking, or order updates. Use the order ID from the conversation.'
  }
  ```

  ```typescript Bad theme={"system"}
  {
    name: 'check_order_status',
    description: 'Checks orders'
  }
  ```
</CodeGroup>

### Use Semantic Function Names

Follow snake\_case naming conventions and make names descriptive:

* `search_product_documentation`
* `create_support_ticket`
* `open_checkout_page`
* ~~`search`~~
* ~~`doThing`~~
* ~~`tool1`~~

### Define Clear Parameters

Use JSON Schema to define parameters with detailed descriptions:

```typescript theme={"system"}
parameters: {
  type: 'object',
  properties: {
    orderId: {
      type: 'string',
      description: 'The order ID mentioned by the user, typically in format ORD-12345'
    },
    includeTracking: {
      type: 'boolean',
      description: 'Whether to include detailed tracking information'
    }
  },
  required: ['orderId']
}
```

<Warning>
  The LLM extracts parameter values from the conversation. If a required
  parameter isn't available, the LLM may ask the user for clarification or skip
  the tool call.
</Warning>

### Organize Knowledge by Domain

Create separate knowledge folders for different topics and assign them to specific tools for better relevance:

```typescript theme={"system"}
// Instead of one tool searching everything...
{
  name: 'search_all_docs',
  documentFolderIds: [
    '550e8400-e29b-41d4-a716-446655440000', // product docs
    '6ba7b810-9dad-11d1-80b4-00c04fd430c8', // faqs
    '7c9e6679-7425-40de-944b-e07fc1f90ae7'  // policies
  ]
}

// ...use focused tools.
{
  name: 'search_product_docs',
  description: 'Search product documentation for technical questions',
  documentFolderIds: ['550e8400-e29b-41d4-a716-446655440000']
},
{
  name: 'search_faqs',
  description: 'Search frequently asked questions for common inquiries',
  documentFolderIds: ['6ba7b810-9dad-11d1-80b4-00c04fd430c8']
}
```

## Limitations

**Tool naming**:

* Length: 1-64 characters
* Pattern: `^[a-zA-Z0-9_.-]+$`
* No spaces or special characters

**Tool descriptions**:

* Length: 1-1024 characters

**Knowledge tools**:

* Require at least one folder ID
* Folders must contain at least one READY document for useful results
* Document uploads subject to size and storage limits
* Supported formats: PDF, TXT, MD, DOCX, CSV, JSON, LOG

**Webhook tools**:

* 5-second timeout (Ideally much faster)
* Supported methods: GET, POST, PUT, PATCH, DELETE
* Response size limit: 1MB (ideally lower)

## Next Steps

<CardGroup cols={2}>
  <Card title="Cookbook: Client-Side Tools" icon="book-open" href="https://anam.ai/cookbook/client-side-tools">
    Build a multi-page app where the avatar navigates users with voice commands
  </Card>

  <Card title="Getting Started with Tools" icon="rocket" href="/personas/tools/tool-calling-example">
    Create your first tool in 15 minutes
  </Card>

  <Card title="Knowledge Base Setup" icon="database" href="/personas/knowledge/overview">
    Upload documents and configure RAG search
  </Card>

  <Card title="Webhook Tools" icon="webhook" href="/personas/tools/webhook-tools">
    Integrate external APIs with webhook tools
  </Card>

  <Card title="System Tools" icon="gear" href="/personas/tools/system-tools">
    Built-in tools for language switching and turn management
  </Card>
</CardGroup>
