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

# Tool Calling

> Give your AI agents the ability to take actions during and after conversations

## What Are Tools?

Tools are capabilities you can attach to a persona. When the agent determines it needs to perform an action — like transferring a call, looking up information, or sending a follow-up message — it invokes the appropriate tool.

Kejue provides a set of built-in tools and lets you create custom HTTP tools that call your own APIs.

## Tool Scoping: In-Call vs Post-Call

Each tool attached to a persona is assigned to a specific scope that determines when it can be used:

| Scope             | When It Runs                                | Use Case                                            |
| ----------------- | ------------------------------------------- | --------------------------------------------------- |
| `voice:in-call`   | During the live call, in real-time          | Transfer calls, play DTMF tones, look up live data  |
| `voice:post-call` | After the call ends, as a background action | Send follow-up messages, update CRM, create tickets |
| `whatsapp`        | During a WhatsApp conversation              | Send media, templates, or trigger actions           |

<Warning>
  A tool cannot be enabled for both `voice:in-call` and `voice:post-call` at the same time. Choose the scope that matches how you want the tool to be used.
</Warning>

This separation is important because in-call tools run synchronously during the conversation (the agent waits for the result), while post-call tools run asynchronously after the call ends.

## Built-in Tools

### Voice Tools

These tools interact directly with the call and are only available during live voice calls (`voice:in-call`).

| Tool              | Description                                                              |
| ----------------- | ------------------------------------------------------------------------ |
| `hang_up`         | End the call immediately                                                 |
| `warm_transfer`   | Transfer the call with context — the AI stays on the line during handoff |
| `cold_transfer`   | Transfer the call directly without staying on the line                   |
| `leave_voicemail` | Leave a voicemail message                                                |
| `play_dtmf`       | Play touch-tone digits (for navigating IVR systems)                      |

### Platform Built-in Tools

These tools interact with the Kejue platform and are available across all scopes.

| Tool                  | Description                                                                  |
| --------------------- | ---------------------------------------------------------------------------- |
| `get_contact_info`    | Retrieve information about the current contact                               |
| `update_contact_info` | Update the contact's details                                                 |
| `add_contact_note`    | Add a note to the contact's record                                           |
| `set_contact_status`  | Update the contact's stage or outcome                                        |
| `schedule_callback`   | Schedule a follow-up call at a specific time                                 |
| `cancel_callback`     | Cancel a previously scheduled callback                                       |
| `request_removal`     | Mark the contact as Do Not Contact                                           |
| `get_current_time`    | Get the current time in a specific timezone                                  |
| `get_datetime`        | Get the caller's current date and time                                       |
| `agent_transfer`      | Transfer the live call to a different persona via call stages (in-call only) |
| `create_call`         | Create a new outbound call to a contact on behalf of a persona               |

#### `agent_transfer`

Hands the live call off to a different persona mid-conversation. Configure one or more transfer targets — the AI picks among them based on each target's `when_to_use` description.

| Field                       | Type   | Description                                                                               |
| --------------------------- | ------ | ----------------------------------------------------------------------------------------- |
| `targets`                   | array  | **Required.** List of transfer targets.                                                   |
| `targets[].key`             | string | **Required.** Unique slug the AI uses to pick this target (e.g. `billing`).               |
| `targets[].persona_id`      | string | **Required.** ID of the persona to transfer to.                                           |
| `targets[].voice_config_id` | string | Optional. Voice config to use on the new stage; defaults to the target persona's default. |
| `targets[].when_to_use`     | string | **Required.** Natural-language hint describing when to choose this target.                |

```json theme={null}
{
  "tool_name": "agent_transfer",
  "channels": ["voice:in-call"],
  "config": {
    "targets": [
      {
        "key": "billing",
        "persona_id": "prs_01H...",
        "when_to_use": "Caller has questions about invoices, refunds, or payments."
      },
      {
        "key": "tech_support",
        "persona_id": "prs_02K...",
        "voice_config_id": "vc_03L...",
        "when_to_use": "Caller is reporting a technical issue with the product."
      }
    ]
  }
}
```

#### `create_call`

Lets the agent dial a contact (now or scheduled) on behalf of a persona. The new call runs as a separate session — it does not interrupt the current conversation.

| Field                     | Type    | Description                                                                                         |
| ------------------------- | ------- | --------------------------------------------------------------------------------------------------- |
| `default_persona_id`      | string  | Persona to use when the AI does not specify one.                                                    |
| `default_voice_config_id` | string  | Optional. Specific voice config (agent) to use; falls back to the persona's default when omitted.   |
| `default_context`         | string  | Default context shared with the receiving persona if the AI does not supply one.                    |
| `allow_persona_override`  | boolean | If `true`, the AI may pick a different persona via the `persona_id` parameter. Defaults to `false`. |

```json theme={null}
{
  "tool_name": "create_call",
  "channels": ["voice:in-call", "voice:post-call"],
  "config": {
    "default_persona_id": "prs_01H...",
    "default_context": "Follow-up call about the contact's inquiry.",
    "allow_persona_override": false
  }
}
```

### Integration Tools

These tools connect with external messaging platforms.

| Tool            | Description                                    |
| --------------- | ---------------------------------------------- |
| `send_media`    | Send an image, video, or document via WhatsApp |
| `send_template` | Send a pre-approved WhatsApp template message  |
| `send_text`     | Send a text message via WhatsApp               |

## Custom HTTP Tools

Custom HTTP tools let you connect your agent to any external API. When the agent invokes a custom tool, Kejue makes an HTTP request to your endpoint with the parameters the agent provides.

### Creating a Custom Tool

| Setting            | Description                                                 |
| ------------------ | ----------------------------------------------------------- |
| **Name**           | A unique name the agent uses to invoke the tool             |
| **Description**    | Explains to the agent what the tool does and when to use it |
| **URL**            | The HTTP endpoint to call                                   |
| **Method**         | HTTP method (GET, POST, PUT, PATCH, DELETE)                 |
| **Authentication** | Auth type — none, basic, bearer, or API key                 |
| **Headers**        | Custom headers to include in the request                    |
| **Timeout**        | Request timeout (1-60 seconds)                              |

### Parameters

Each parameter you define has a **source** that controls who provides the value:

* **AI Generated** (`source: "ai"`) — the AI fills in the value based on the conversation. You provide a description and type so the AI knows what to supply. These are visible to the AI.
* **System Injected** (`source: "system"`) — the value is injected automatically from the execution context (e.g. call ID, contact ID). These are hidden from the AI.

You also have **static parameters** — fixed values with a constant string, useful for API keys or account identifiers. These are hidden from the AI.

All parameters can be routed to different parts of the HTTP request: the request body, query string, URL path, or headers.

### System-Injected Parameters

When you set a parameter's source to `system`, you choose which system variable to inject. This lets you pass execution context to your external APIs without exposing it to the AI.

#### Available System Variables

| Variable          | Description                                      |
| ----------------- | ------------------------------------------------ |
| `call_id`         | Current call job ID                              |
| `workspace_id`    | Workspace ID                                     |
| `contact_id`      | Contact being spoken to                          |
| `conversation_id` | Current conversation ID                          |
| `persona_id`      | Persona/agent in use                             |
| `channel`         | Channel type (`voice`, `whatsapp`, `sms`, `web`) |
| `campaign_id`     | Campaign ID (if part of a campaign)              |

#### Example

A CRM integration tool that creates a ticket with the call and contact context:

```json theme={null}
{
  "name": "create_ticket",
  "description": "Create a support ticket when the customer reports an issue",
  "http_config": {
    "url": "https://api.example.com/tickets",
    "method": "POST"
  },
  "dynamic_parameters": [
    {
      "name": "subject",
      "description": "Brief summary of the issue",
      "param_type": "string",
      "required": true,
      "source": "ai"
    },
    {
      "name": "call_id",
      "source": "system",
      "system_variable": "call_id",
      "location": "body"
    },
    {
      "name": "customer_id",
      "source": "system",
      "system_variable": "contact_id",
      "location": "body"
    }
  ]
}
```

The AI only sees `subject` as a parameter. The `call_id` and `customer_id` are injected silently by the system.

<Info>
  If a system variable is not available in the current context (e.g., `campaign_id` for a non-campaign call), it is omitted from the request.
</Info>

## Attaching Tools to a Persona

After creating a tool (or choosing a built-in one), you attach it to a persona with a specific channel scope. The attachment specifies:

* Which tool to attach
* Which channels it's active on (e.g. `voice:in-call`, `voice:post-call`, `whatsapp`)
* Any tool-specific configuration (like transfer phone numbers)

<Info>
  Use post-call tools for actions that don't need to happen during the live conversation. This keeps calls fast and responsive while still letting your agent take follow-up actions automatically.
</Info>
