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

# Tools

> Understanding tools in Julep

## Overview

Agents can be given access to a number of "tools" -- any programmatic interface that a foundation model can "call" with a set of inputs to achieve a goal. For example, it might use a `web_search(query)` tool to search the Internet for some information.

Unlike agent frameworks, julep is a *backend* that manages agent execution. Clients can interact with agents using our SDKs. julep takes care of executing tasks and running integrations.

## Components

Tools in Julep consist of three main components:

1. **Name**: A unique identifier for the tool.
2. **Type**: The category of the tool. In Julep, there are four types of tools:
   * **User-defined `functions`**: Function signatures provided to the model, similar to OpenAI's function-calling. These require client handling, and the workflow pauses until the client executes the function and returns the results to Julep. [Learn more](#user-defined-function-tool)
   * **`system` tools**: Built-in tools for calling Julep APIs, such as triggering task execution or appending to a metadata field. [Learn more](#system-tool)
   * **`integrations`**: Built-in third-party tools that enhance the capabilities of your agents. [Learn more](#integration-tool)
   * **`api_calls`**: Direct API calls executed during workflow processes as tool calls. [Learn more](#api-call-tool)
3. **Arguments**: The inputs required by the tool.

#### System Tool

Built-in tools that can be used to call the julep APIs themselves, like triggering a task execution, appending to a metadata field, etc. See the [task execution system tool](#task-execution-system-tool) for a complete example.

`System` tools are built into the backend. They get executed automatically when needed. They do not require any action from the client-side. For example,

```yaml YAML theme={"dark"}
name: Example system tool task
description: List agents using system call

tools:
- name: list_agent_docs
  description: List all docs for the given agent
  type: system
  system:
    resource: agent
    subresource: doc
    operation: list

main:
- tool: list_agents
  arguments:
    limit: $ 10
```

<Accordion title="Available system resources and operations">
  <Accordion title="Agent">
    <ul>
      <li><strong>list</strong>: List all agents.</li>
      <li><strong>get</strong>: Get a single agent by id.</li>
      <li><strong>create</strong>: Create a new agent.</li>
      <li><strong>update</strong>: Update an existing agent.</li>
      <li><strong>delete</strong>: Delete an existing agent.</li>
    </ul>
  </Accordion>

  <Accordion title="User">
    <ul>
      <li><strong>list</strong>: List all users.</li>
      <li><strong>get</strong>: Get a single user by id.</li>
      <li><strong>create</strong>: Create a new user.</li>
      <li><strong>update</strong>: Update an existing user.</li>
      <li><strong>delete</strong>: Delete an existing user.</li>
    </ul>
  </Accordion>

  <Accordion title="Session">
    <ul>
      <li><strong>list</strong>: List all sessions.</li>
      <li><strong>get</strong>: Get a single session by id.</li>
      <li><strong>create</strong>: Create a new session.</li>
      <li><strong>update</strong>: Update an existing session.</li>
      <li><strong>delete</strong>: Delete an existing session.</li>
      <li><strong>chat</strong>: Chat with a session.</li>
      <li><strong>history</strong>: Get the chat history with a session.</li>
    </ul>
  </Accordion>

  <Accordion title="Task">
    <ul>
      <li><strong>list</strong>: List all tasks.</li>
      <li><strong>get</strong>: Get a single task by id.</li>
      <li><strong>create</strong>: Create a new task.</li>
      <li><strong>update</strong>: Update an existing task.</li>
      <li><strong>delete</strong>: Delete an existing task.</li>
      <li><strong>execution.create</strong>: Start an execution for a task (see guidance below).</li>
    </ul>
  </Accordion>

  <Accordion title="Doc (subresource for agent and user)">
    <ul>
      <li><strong>list</strong>: List all documents.</li>
      <li><strong>create</strong>: Create a new document.</li>
      <li><strong>delete</strong>: Delete an existing document.</li>
      <li><strong>search</strong>: Search for documents.</li>
    </ul>
  </Accordion>

  <Accordion title="Additional Operations">
    <ul>
      <li><strong>embed</strong>: Embed a resource (specific resources not specified in the provided code).</li>
      <li><strong>change\_status</strong>: Change the status of a resource (specific resources not specified in the provided code).</li>
      <li><strong>chat</strong>: Chat with a resource (specific resources not specified in the provided code).</li>
      <li><strong>history</strong>: Get the chat history with a resource (specific resources not specified in the provided code).</li>
      <li><strong>create\_or\_update</strong>: Create a new resource or update an existing one (specific resources not specified in the provided code).</li>
    </ul>
  </Accordion>
</Accordion>

<a id="task-execution-system-tool" />

##### Task Execution system tool

Use the `execution.create` task tool when you want an agent run to immediately kick off another task execution. A minimal definition looks like this:

```yaml YAML theme={"dark"}
tools:
  - name: create_task_execution
    description: Launch a new execution for the current (or another) task
    type: system
    system:
      resource: task
      subresource: execution
      operation: create

main:
  - tool: create_task_execution
    arguments:
      task_id: $ steps[0].input.sub_task_id
      data:
        input: {}
```

<Info>
  `data.input` must satisfy the task's input schema. Use an empty object only when the schema allows it; otherwise populate the fields the task expects.
</Info>

Operational notes:

* **Re-use existing tasks**: The `task_id` only has to belong to the same developer. You can start executions for tasks attached to different agents you own without extra setup.
* **Inspect prior runs**: To review execution history, call the REST endpoint `GET /tasks/{task_id}/executions` from a workflow via an `api_call` tool or use the SDK (`client.executions.list(task_id=...)`). That gives you the execution IDs needed to fetch outputs later (e.g. via transitions or `execution.get`).

#### Integration Tool

Julep comes with a number of built-in integrations (as described in the section below). `integration` tools are directly executed on the julep backend. Any additional parameters needed by them at runtime can be set in the `agent/session/user` `metadata` fields.

An example of how to create a `integration` tool for an agent using the `wikipedia` integration:

```yaml YAML theme={"dark"}
name: Example integration tool task
description: Search wikipedia for a query

tools:
- name: wikipedia_search
  description: Search wikipedia for a query
  type: integration
  integration:
    provider: wikipedia

main:
- tool: wikipedia_search
  arguments:
    query: "Julep"
```

<Info>
  Checkout the list of integrations that Julep supports [here](/integrations/supported-integrations).
</Info>

#### API Call Tool

Julep can also directly make `api_call` during workflow executions as tool calls. Similar to `integration` tools, additional runtime parameters are loaded from metadata fields.

API call tools support `params_schema` to define the expected parameters for the API call, enabling better validation and documentation:

```yaml YAML theme={"dark"}
name: Example api_call task
tools:
- type: api_call
  name: weather_api
  description: Get weather information for a location
  api_call:
    method: GET  # Required - HTTP method must be specified
    url: https://api.openweathermap.org/data/2.5/weather  # Required - URL must be specified
    params_schema:  # Define expected parameters
      type: object
      properties:
        q:
          type: string
          description: City name or coordinates
        units:
          type: string
          enum: [metric, imperial]
          description: Temperature units
        appid:
          type: string
          description: API key (loaded from metadata)
      required: [q, appid]

main:
- tool: weather_api
  arguments:
    params:
      q: $ _.location  # City from input
      units: "metric"
      appid: $ metadata.weather_api_key  # API key from metadata
```

<Note>
  The `params_schema` follows JSON Schema format and helps:

  * Document expected parameters for the API
  * Enable LLMs to understand what parameters the tool accepts
  * Provide validation for API calls
  * Generate better tool descriptions for the model
</Note>

<AccordionGroup>
  <Accordion title="Available API HTTP Methods">
    <ul>
      <li><strong>GET</strong>: Get a resource.</li>
      <li><strong>POST</strong>: POST a resource.</li>
      <li><strong>PUT</strong>: PUT a resource.</li>
      <li><strong>DELETE</strong>: DELETE a resource.</li>
      <li><strong>PATCH</strong>: PATCH a resource.</li>
      <li><strong>HEAD</strong>: HEAD a resource.</li>
      <li><strong>OPTIONS</strong>: OPTIONS a resource.</li>
      <li><strong>CONNECT</strong>: CONNECT to a resource.</li>
      <li><strong>TRACE</strong>: TRACE a resource.</li>
    </ul>
  </Accordion>

  <Accordion title="Available API Call Parameters">
    <ul>
      <li><strong>method</strong>: (Required) The HTTP method to use.</li>
      <li><strong>url</strong>: (Required) The URL to call.</li>
      <li><strong>params\_schema</strong>: JSON Schema definition for API parameters, enabling validation and better LLM understanding.</li>
      <li><strong>schema</strong>: The schema of the response.</li>
      <li><strong>headers</strong>: The headers to send with the request.</li>
      <li><strong>content</strong>: The content as base64 to send with the request.</li>
      <li><strong>data</strong>: The data to send as form data.</li>
      <li><strong>files</strong>: The data to send as files data.</li>
      <li><strong>json</strong>: The JSON body to send with the request.</li>
      <li><strong>cookies</strong>: The cookies to send with the request.</li>
      <li><strong>params</strong>: The parameters to send with the request.</li>
      <li><strong>follow\_redirects</strong>: Follow redirects.</li>
      <li><strong>timeout</strong>: The timeout for the request.</li>
    </ul>
  </Accordion>
</AccordionGroup>

<Note>
  * Arguments provided during the tool call can override the default `method` and `url` set in the `api_call` configuration.
  * We utlize the python httpx library to make the api calls. Please refer to the [httpx documentation](https://www.python-httpx.org/api/#request-parameters) for more details on the parameters.
</Note>

#### User-defined Function Tool

These are function signatures that you can give the model to choose from, similar to how \[openai]'s function-calling works. An example:

```yaml YAML [expandable] theme={"dark"}
name: Example system tool task
description: List agents using system call

tools:
  - name: send_notification
    description: Send a notification to the user
    type: function
    function:
      parameters:
        type: object
        properties:
          text:
            type: string
            description: Content of the notification

main:
  - tool: send_notification
    arguments:
      content: "hi"
```

<Note>
  Whenever julep encounters a user-defined function, it pauses, giving control back to the client and waits for the client to run the function call and give the results back to julep.
</Note>

##### How User-Defined Functions Work

**User-defined function tools** in Julep work exactly like OpenAI's function calling:

1. **Definition**: You define a function signature with name, description, and parameters schema
2. **Model Decision**: The LLM decides when to call your function based on the conversation context
3. **Execution Pause**: When Julep encounters a user-defined function call, it pauses execution and returns control to your client
4. **Your Implementation**: You implement the actual function logic in your client code
5. **Result Return**: You send the function results back to Julep to continue the workflow

<Warning>
  Unlike `integration`, `system`, or `api_call` tools that execute automatically, function tools require manual handling by your client application.
</Warning>

##### Complete Example: Math Calculator with Function Tools

Here's a comprehensive example showing how to implement and handle user-defined functions:

```python [expandable] theme={"dark"}
import yaml
import time
from julep import Julep

# Replace with your API key
API_KEY = "your-api-key"

client = Julep(api_key=API_KEY, environment="production")

# 1. Define your actual functions
def add_numbers(a, b):
    """Add two numbers together"""
    result = a + b
    print(f"Adding {a} + {b} = {result}")
    return result

def multiply_numbers(x, y):
    """Multiply two numbers"""
    result = x * y
    print(f"Multiplying {x} × {y} = {result}")
    return result

# Function dispatcher
FUNCTION_MAP = {
    "add_numbers": add_numbers,
    "multiply_numbers": multiply_numbers,
}

def execute_function(function_name, arguments):
    """Execute a function by name with arguments"""
    if function_name not in FUNCTION_MAP:
        raise ValueError(f"Unknown function: {function_name}")
    
    func = FUNCTION_MAP[function_name]
    return func(**arguments)

# 2. Create agent
agent = client.agents.create(
    name="Math Calculator",
    model="gpt-4o-mini",
    instructions="You are a calculator."
)

# 3. Define task with inline tools
task_def = yaml.safe_load("""
name: "function-tool-demo"

tools:
  - name: add_numbers
    type: function
    function:
      parameters:
        type: object
        properties:
          a:
            type: number
            description: First number
          b:
            type: number
            description: Second number
        required: ["a", "b"]

main:
  - tool: add_numbers
    arguments:
      a: 15
      b: 27
""")

# 4. Create and execute task
task = client.tasks.create(agent_id=agent.id, **task_def)
execution = client.executions.create(task_id=task.id, input={})

print(f"Execution: {execution.id}")

# 5. Monitor and handle function calls
for i in range(15):
    execution = client.executions.get(execution.id)
    print(f"Iteration {i+1}: Status = {execution.status}")
    
    if execution.status == "awaiting_input":
        # Execute the function based on task definition
        tool_name = task_def["main"][0]["tool"]  # "add_numbers"
        arguments = task_def["main"][0]["arguments"]  # {"a": 15, "b": 27}
        
        result = execute_function(tool_name, arguments)
        print(f"Result: {result}")
        
        # Use change_status to provide tool results
        client.executions.change_status(
            execution_id=execution.id,
            status="running",  # Resume execution
            input={"result": result} 
        )
        print("Sent result back to Julep")
        
    elif execution.status == "succeeded":
        print(f"Output: {execution.output}")
        break
        
    elif execution.status == "failed":
        print(f"Failed: {execution.error}")
        break
    
    time.sleep(3)
```

##### Key Points

1. **Execution Status Monitoring**: You must monitor the execution status and watch for `awaiting_input`
2. **Manual Function Execution**: When status is `awaiting_input`, execute your function locally
3. **Resume with Results**: Use `change_status` to resume execution with the function output
4. **Alternative Tool Creation**: You can also use `client.agents.tools.create()` to create tools before running the task

## How to Use Tools

### Create a Tool for an Agent

A tool can be created for an agent using the `client.agents.tools.create` method.

An example of how to create a `integration` tool for an agent using the `wikipedia` integration:

<CodeGroup>
  ```python Python theme={"dark"}
  # Create an agent
  agent = client.agents.create(name="My Agent")

  # Associate a tool with the agent
  client.agents.tools.create(
          agent_id=AGENT_UUID,
          **{
              "name": "wikipedia_search",
              "type": "integration",
              "integration": {
                "provider": "wikipedia",
              } 
            },
      )
  ```

  ```javascript Node.js theme={"dark"}
  async function createAgent() {
    const agent = await client.agents.create({
      name: "My Agent",
    });

    const tool = await client.agents.tools.create(agent.id, {
      name: "wikipedia_search",
      type: "integration",
      integration: {
        provider: "wikipedia",
      },
    });
    return agent;
  }
  ```
</CodeGroup>

<Tip>
  Check out the API reference [here](api-reference/agents/tools/create) or SDK reference (Python [here](/sdks/python/reference#Tools) or JavaScript [here](/sdks/nodejs/reference#Tools) for more details on different operations you can perform on agents.
</Tip>

### Execute a Tool for a Task

To create a tool for a task, you can use the `client.tasks.create` method and define the tool in that `task` definitions.

<CodeGroup>
  ```yaml YAML theme={"dark"}
  name: Example integration tool task
  description: Search wikipedia for a query

  tools:
  - name: wikipedia_search
    description: Search wikipedia for a query
    type: integration
    integration:
      provider: wikipedia
  main:
  - tool: wikipedia_search
    arguments:
      query: "Julep"
  ```

  ```python Python theme={"dark"}
  # Create a task
  import yaml
  task_yaml = """
  // ... task yaml here ...
  """
  task_def = yaml.safe_load(task_yaml)
  task = client.tasks.create(
      agent_id="agent_id",
      **task_def
  )

  execution = client.executions.create(
    task_id=task.id,
    input={
        "document_text": "This is a sample document"
    }
  )
  ```

  ```javascript Node.js theme={"dark"}
  // Create a task
  const taskYaml = `
  // ... task yaml here ...
  `
  async function createTask(agentId) {
    const task = await client.tasks.create(agentId, yaml.parse(taskYaml));
    return task;
  }
  // Execute a task
  async function executeTask(taskId) {
    const execution = await client.executions.create(taskId, {
      input: {
        document_text: "This is a sample document"
      }
    });
    return execution;
  }
  ```
</CodeGroup>

<Tip>
  Check out the API reference [here](api-reference/agents/tools/create) or SDK reference (Python [here](/sdks/python/reference#Tools) or JavaScript [here](/sdks/nodejs/reference#Tools) for more details on different operations you can perform on agents.
</Tip>

## Relationship to Other Concepts

This section will help you understand how tools relate to other concepts in Julep.

### Task

When a tool is associated with a task, it is meant to be used only for that task. It is not associated with other tasks. An agent associated with that task will have access to that tool, but the same agent associated with another task will not have that access. This ensures that tools are used in a context-specific manner, providing precise functionality tailored to the task's requirements.

### Agent

When a tool is associated with an agent, it is meant to be used across all tasks associated with that agent. This allows for greater flexibility and reuse of tools, as the agent can leverage the same tool in multiple tasks. It also simplifies the management of tools, as they only need to be defined once for the agent and can then be utilized in various tasks.

## Automatic Tool Execution

Julep supports automatic tool execution, allowing agents to seamlessly use tools without manual intervention. This feature is controlled by the `auto_run_tools` parameter.

### How Automatic Tool Execution Works

1. **In Sessions (Chat)**:
   * Set `auto_run_tools=true` when calling `sessions.chat()`
   * When the model decides to use a tool, Julep automatically:
     * Executes the tool with the provided arguments
     * Captures the tool's output
     * Sends the results back to the model
     * Continues the conversation with the tool results
   * All happens in a single API call - no manual intervention needed

2. **In Tasks (Prompt Steps)**:
   * Set `auto_run_tools: true` in the prompt step definition
   * During task execution, tools are automatically invoked when needed
   * Results flow seamlessly into subsequent steps

3. **Default Behavior** (`auto_run_tools=false`):
   * Tool calls are returned in the response
   * Your application must handle tool execution
   * Results must be sent back in a follow-up message

### Example: Session with Automatic Tools

<CodeGroup>
  ```python Python theme={"dark"}
  # Create agent with multiple tools
  agent = client.agents.create(
      name="Research Assistant",
      tools=[
          {
              "name": "web_search",
              "type": "integration",
              "integration": {"provider": "brave"}
          },
          {
              "name": "wikipedia",
              "type": "integration",
              "integration": {"provider": "wikipedia"}
          }
      ]
  )

  # Chat with automatic tool execution
  response = client.sessions.chat(
      session_id=session.id,
      messages=[
          {
              "role": "user",
              "content": "Tell me about the latest developments in quantum computing"
          }
      ],
      auto_run_tools=True  # Enable automatic execution
  )

  # Response includes information gathered from tools
  print(response.choices[0].message.content)
  # "Based on recent search results, here are the latest developments..."
  ```

  ```javascript Node.js theme={"dark"}
  // Create agent with multiple tools
  const agent = await client.agents.create({
      name: "Research Assistant",
      tools: [
          {
              name: "web_search",
              type: "integration",
              integration: {provider: "brave"}
          },
          {
              name: "wikipedia",
              type: "integration",
              integration: {provider: "wikipedia"}
          }
      ]
  });

  // Chat with automatic tool execution
  const response = await client.sessions.chat({
      session_id: session.id,
      messages: [
          {
              role: "user",
              content: "Tell me about the latest developments in quantum computing"
          }
      ],
      auto_run_tools: true  // Enable automatic execution
  });

  // Response includes information gathered from tools
  console.log(response.choices[0].message.content);
  // "Based on recent search results, here are the latest developments..."
  ```
</CodeGroup>

### Example: Task with Automatic Tools

```yaml YAML theme={"dark"}
name: Research and Summarize Task
tools:
  - name: web_search
    type: integration
    integration:
      provider: brave
  
  - name: save_research_summary
    description: Save the research summary as a document
    type: system
    system:
      resource: agent
      subresource: doc
      operation: create

main:
  # Step 1: Search with automatic tool execution
  - prompt:
      - role: user
        content: "Search for recent news about {{topic}} and create a comprehensive summary and save it as a document for agent {{agent.id}}"
    auto_run_tools: true  # Tools execute automatically
  
  # Step 2: The results from tools are already available
  - evaluate:
      summary: $ _.choices[0].message.content
```

### When to Use Automatic Tool Execution

**Use `auto_run_tools=true` when**:

* Building conversational agents that need real-time information
* Creating autonomous workflows in tasks
* You want a seamless, single-call interaction
* Tools are trusted and don't require manual validation

**Use `auto_run_tools=false` when**:

* You need to validate or modify tool inputs before execution
* Tool execution requires user confirmation
* You want to handle tool errors with custom logic
* Building applications with complex tool orchestration

<Warning>
  **Important**: User-defined function tools (`type: function`) are **never** executed automatically, regardless of the `auto_run_tools` setting. They always pause execution and return control to the client for manual handling. This is a key difference from `system`, `integration`, and `api_call` tools.
</Warning>

### Tool Execution Flow

<Steps>
  <Step title="Model Decision">
    The LLM analyzes the user's request and decides if a tool is needed
  </Step>

  <Step title="Tool Call Generation">
    The model generates appropriate tool calls with arguments
  </Step>

  <Step title="Automatic Execution" icon="play">
    With auto\_run\_tools=true: Julep executes the tool automatically
    With auto\_run\_tools=false: Tool calls are returned for manual handling
  </Step>

  <Step title="Result Processing">
    Tool results are fed back to the model or returned to the client
  </Step>

  <Step title="Response Generation">
    The model uses tool results to generate the final response
  </Step>
</Steps>

### Managing Tool History

When using `sessions.chat()`, the `recall_tools` parameter controls whether tool interactions are saved in the conversation history:

* `recall_tools=true` (default): Tool calls and results are preserved
* `recall_tools=false`: Tool interactions are excluded from history

This helps maintain clean conversation logs while still benefiting from tool capabilities.

## Best Practices

<CardGroup cols={3}>
  <Card title="Consistent Naming" icon="tag">
    <ul>
      <li>**1. Naming Conventions**: Use clear and consistent naming conventions for tools to make them easily identifiable and understandable.</li>
    </ul>
  </Card>

  <Card title="Correct Usage" icon="check-double">
    <ul>
      <li>**1. Correct Usage**: Ensure that tools are used correctly and in the appropriate context. This includes providing the necessary arguments and ensuring that the tools are executed as intended.</li>
    </ul>
  </Card>

  <Card title="Type" icon="font">
    <ul>
      <li>**1. Type**: Ensure that the type is correct for the tool you are using. Checkout the Tool Types Definitions <a href="/concepts/tools#tool-types-definitions">here</a> for further details.</li>
    </ul>
  </Card>
</CardGroup>

## Next Steps

* [Checkout the Integration](/integrations/supported-integrations) - Learn how to use executions in an integration
* [Checkout the Tutorial](/tutorials/trip-planning) - Learn how to use tools in a task

## See Examples

* [Adding Tools notebook](https://github.com/julep-ai/julep/blob/main/cookbooks/basics/03-Adding-Tools.ipynb)
* [Browser Use notebook](https://github.com/julep-ai/julep/blob/main/cookbooks/advanced/06-browser-use.ipynb)
