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

# Tools

> Understanding Tools and how tool calls work

# Tools

**Tools** are callable functions that agents can invoke. Each tool belongs to an adapter and defines parameters using JSON Schema.

## Tool Types

Bedrock supports two types of tools:

| Type         | Description                            | Use Case                                    |
| ------------ | -------------------------------------- | ------------------------------------------- |
| **Internal** | Runs in-process via a handler function | Built-in functionality, database operations |
| **External** | Calls an HTTP webhook URL              | Custom APIs, third-party integrations       |

## How Tool Calls Work

When an agent decides to use a tool:

1. **LLM generates** a tool call with arguments
2. **Bedrock validates** arguments against the tool's JSON Schema
3. **Tool executes**:
   * Internal: Calls the handler function directly
   * External: POSTs to the webhook URL
4. **Result returns** to the agent as text

## Internal Tools

Internal tools run Python functions in the Bedrock backend. They're used for built-in adapters like Contacts, SMS, Email, Projects, and others.

Example internal tool definition:

```json theme={null}
{
  "name": "create_contact",
  "description": "Create a new contact in your contact book",
  "handler": "defaults.contacts.handlers.create_contact",
  "parameters": {
    "type": "object",
    "properties": {
      "name": { "type": "string", "description": "Contact's full name" },
      "phones": {
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "phone": { "type": "string", "description": "Phone in E.164 format" },
            "label": { "type": "string" },
            "is_primary": { "type": "boolean" }
          },
          "required": ["phone"]
        }
      },
      "emails": {
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "email": { "type": "string" },
            "label": { "type": "string" },
            "is_primary": { "type": "boolean" }
          },
          "required": ["email"]
        }
      }
    },
    "required": ["name"]
  }
}
```

A contact can hold multiple email addresses and one primary plus zero or
more backup phone numbers. Each address tracks its own verification
status (`verified` / `pending`); messages from pending addresses are
stored but withheld from the agent's context until an owner or operator
approves the contact in the portal.

The `handler` is a dotted path to a Python function: `module.path.function_name`

### Handler Function Signature

Internal handlers receive:

```python theme={null}
def create_contact(args: dict, agent: Agent, tool: Tool) -> str:
    """
    Args:
        args: The arguments from the LLM (validated against parameters schema)
        agent: The Agent instance calling the tool
        tool: The Tool instance being called

    Returns:
        String result shown to the agent
    """
    from defaults.contacts.testing import make_contact

    contact = make_contact(
        agent=agent,
        name=args["name"],
        phone=(args.get("phones") or [{}])[0].get("phone", ""),
    )
    return f"Created contact: {contact.name} (ID: {contact.id})"
```

## External Tools (Webhooks)

External tools make HTTP POST requests to your API when called by an agent. This is how you integrate custom functionality.

When an agent calls an external tool, Bedrock POSTs to your `url` with:

* **Headers**: `X-Agent-Secret` (the agent's template tool call secret) and `X-Agent-Identity` (agent UUID)
* **Body**: The tool definition, agent/template context, and the LLM-generated arguments

Your endpoint returns JSON, which becomes the tool result the agent sees.

<Card title="Custom Adapters Guide" icon="webhook" href="/concepts/custom-adapters">
  For a full walkthrough of creating adapters, registering tools, handling
  webhook requests, verifying secrets, and best practices — see the **Custom
  Adapters** guide.
</Card>

## Tool Parameters (JSON Schema)

Tool parameters use JSON Schema. Common patterns:

### Required String Parameter

```json theme={null}
{
  "type": "object",
  "properties": {
    "message": {
      "type": "string",
      "description": "The message to send"
    }
  },
  "required": ["message"]
}
```

### Optional Parameters with Defaults

```json theme={null}
{
  "type": "object",
  "properties": {
    "limit": {
      "type": "integer",
      "description": "Max results (default 50)",
      "default": 50
    }
  }
}
```

### Enum Values

```json theme={null}
{
  "type": "object",
  "properties": {
    "status": {
      "type": "string",
      "enum": ["pending", "in_progress", "completed"],
      "description": "Task status"
    }
  }
}
```

### Nested Objects

```json theme={null}
{
  "type": "object",
  "properties": {
    "address": {
      "type": "object",
      "properties": {
        "street": { "type": "string" },
        "city": { "type": "string" },
        "zip": { "type": "string" }
      },
      "required": ["street", "city"]
    }
  }
}
```

## Automatic Reasoning

Bedrock automatically adds a `reasoning` parameter to all tools:

```json theme={null}
{
  "reasoning": {
    "type": "string",
    "description": "The reasoning for the tool call."
  }
}
```

This helps with tracing and debugging - you can see why the agent decided to call each tool.

## Detail URL (Dynamic Descriptions)

Tools can have a `detail_url` that's fetched at runtime to augment the description with dynamic content:

```json theme={null}
{
  "name": "check_schedule",
  "description": "Check availability on the calendar",
  "detail_url": "https://api.yourcompany.com/calendar/tool-detail",
  "url": "https://api.yourcompany.com/calendar/check"
}
```

The detail URL should return:

```json theme={null}
{
  "detail": "Available slots this week: Monday 2pm, Wednesday 10am, Friday 3pm"
}
```

This detail is appended to the tool description, giving the agent real-time context.

## Listing Tools

View all tools for an adapter:

```bash theme={null}
curl -X GET "https://api.bedrock.orinlabs.org/api/toolbox/tools/?adapter=ADAPTER_ID" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

## Best Practices

<CardGroup cols={2}>
  <Card title="Clear Descriptions" icon="file-lines">
    Write detailed descriptions - they're included in the LLM prompt.
  </Card>

  <Card title="Verify Secrets" icon="lock">
    Always verify `X-Agent-Secret` in webhook handlers.
  </Card>

  <Card title="Return Useful Data" icon="reply">
    Return structured, actionable information the agent can use.
  </Card>

  <Card title="Handle Errors Gracefully" icon="triangle-exclamation">
    Return error messages the agent can understand and act on.
  </Card>
</CardGroup>
