How to Use Provider Passthrough Tools

Last verified 24 Aug 2026

Inference provides a single control plane for managing inference workflows. It includes a Model Catalog where you can view available foundation models, including both DigitalOcean-hosted and third-party commercial models, compare model capabilities and pricing, use routing to match inference requests to the best-fit model, and run inference using serverless or dedicated deployments.

Provider passthrough tools on DigitalOcean Inference let Anthropic and OpenAI models search and load tools on demand, control a desktop, run shell commands, fetch web content, edit files, and call your application-defined functions. These tools forward to the model provider, which runs each tool according to its own schema and agent loop. Provide the Anthropic-schema tools on the Messages API and the OpenAI-schema tools on the Responses API.

Tool search enables searching and loading of tools on demand in agentic workflows, reducing token usage and cost by avoiding loading all tool definitions up front. Use tool search on the Messages API for Anthropic models and the Responses API for OpenAI models.

Tool Search with Anthropic Models

Include a tool search tool by either using regex or BM25 as the type in your tools array:

  • Regex (tool_search_tool_regex_20251119): Allows Claude to construct regex patterns to search for tools using Python re.search() syntax.
  • BM25 (tool_search_tool_bm25_20251119): Allows Claude to use natural language queries to search for tools.

Then, set defer_loading: true on tools that should not load immediately. The model calls the tool search tool when it needs those tools. Both tool search variants search tool names, descriptions, argument names, and argument descriptions. Note the following about tool search:

  • The tool search tool itself must not have "defer_loading": true.
  • Tools without defer_loading load into context immediately while tools with "defer_loading": true load only when Claude discovers them through search.
  • For best performance, keep your 3-5 most frequently used tools non-deferred.

The following example sends a Messages API request with regex tool search enabled.

import os
from pydo.inference import Client

client = Client(token=os.environ.get("MODEL_ACCESS_KEY"))

resp = client.messages.create(
    model="anthropic-claude-opus-4.8",
    max_tokens=2048,
    messages=[
        {"role": "user", "content": "What is the weather in zip code 94107?"},
    ],
    tools=[
        {
            "type": "tool_search_tool_regex_20251119",
            "name": "tool_search_tool_regex",
        },
        {
            "name": "get_weather_by_zip",
            "description": "Return current weather conditions for a US zip code.",
            "input_schema": {
                "type": "object",
                "properties": {
                    "zip_code": {"type": "string"},
                    "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
                },
                "required": ["zip_code"],
            },
            "defer_loading": True,
        },
        {
            "name": "search_files",
            "description": "Search through files in the workspace",
            "input_schema": {
                "type": "object",
                "properties": {
                    "query": {"type": "string"},
                    "file_types": {"type": "array", "items": {"type": "string"}},
                },
                "required": ["query"],
            },
            "defer_loading": True,
        },
    ],
)

print(resp)
import { InferenceClient } from "@digitalocean/dots";

const client = new InferenceClient({
    apiKey: process.env.MODEL_ACCESS_KEY,
});

const resp = await client.messages.create({
    model: "anthropic-claude-opus-4.8",
    max_tokens: 2048,
    messages: [
        { role: "user", content: "What is the weather in zip code 94107?" },
    ],
    tools: [
        {
            type: "tool_search_tool_regex_20251119",
            name: "tool_search_tool_regex",
        },
        {
            name: "get_weather_by_zip",
            description: "Return current weather conditions for a US zip code.",
            input_schema: {
                type: "object",
                properties: {
                    zip_code: { type: "string" },
                    unit: { type: "string", enum: ["celsius", "fahrenheit"] },
                },
                required: ["zip_code"],
            },
            defer_loading: true,
        },
        {
            name: "search_files",
            description: "Search through files in the workspace",
            input_schema: {
                type: "object",
                properties: {
                    query: { type: "string" },
                    file_types: { type: "array", items: { type: "string" } },
                },
                required: ["query"],
            },
            defer_loading: true,
        },
    ],
});

console.log(resp);
curl -X POST https://inference.do-ai.run/v1/messages \
  -H "Authorization: Bearer $MODEL_ACCESS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic-claude-opus-4.8",
    "max_tokens": 2048,
    "messages": [
      {
        "role": "user",
        "content": "What is the weather in zip code 94107?"
      }
    ],
    "tools": [
      {
        "type": "tool_search_tool_regex_20251119",
        "name": "tool_search_tool_regex"
      },
      {
        "name": "get_weather_by_zip",
        "description": "Return current weather conditions for a US zip code.",
        "input_schema": {
          "type": "object",
          "properties": {
            "zip_code": {"type": "string"},
            "unit": {
              "type": "string",
              "enum": ["celsius", "fahrenheit"]
            }
          },
          "required": ["zip_code"]
        },
        "defer_loading": true
      },
      {
        "name": "search_files",
        "description": "Search through files in the workspace",
        "input_schema": {
          "type": "object",
          "properties": {
            "query": {"type": "string"},
            "file_types": {
              "type": "array",
              "items": {"type": "string"}
            }
          },
          "required": ["query"]
        },
        "defer_loading": true
      }
    ]
  }'

The response includes additional block types before any client tool call:

  • server_tool_use: Indicates that Claude is calling the tool search tool.
  • tool_search_tool_result: Contains search results with a nested tool_search_tool_search_result object.
  • tool_use: Claude calling a discovered tool.
  • tool_references: Points to discovered tools.

The response looks similar to the following:

Show the example response
{
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "I'll search for tools to help with the weather information."
    },
    {
      "type": "server_tool_use",
      "id": "srvtoolu_01ABC123",
      "name": "tool_search_tool_regex",
      "input": {
        "query": "weather"
      }
    },
    {
      "type": "tool_search_tool_result",
      "tool_use_id": "srvtoolu_01ABC123",
      "content": {
        "type": "tool_search_tool_search_result",
        "tool_references": [{ "type": "tool_reference", "tool_name": "get_weather_by_zip" }]
      }
    },
    {
      "type": "text",
      "text": "I found a weather tool. Let me get the weather for zip code 94107."
    },
    {
      "type": "tool_use",
      "id": "toolu_01XYZ789",
      "name": "get_weather_by_zip",
      "input": { "zip_code": "94107", "unit": "fahrenheit" }
    }
  ],
  "stop_reason": "tool_use"
}

Tool search tool usage is tracked in the usage object in the response:

Show the example response
{
  "usage": {
    "input_tokens": 1024,
    "output_tokens": 256,
    "server_tool_use": {
      "tool_search_requests": 2
    }
  }
}

For more information on how to use tool search with MCP integration and best practices, see the Anthropic tool search documentation.

Tool Search with OpenAI Models

Only GPT-5.4 and later models support tool search. To enable tool search, add a tool object with "type": "tool_search" to the tools array. Then, mark tools to defer with "defer_loading": true. The following example sends a Responses API request with hosted tool search enabled.

import os
from pydo.inference import Client

client = Client(token=os.environ.get("MODEL_ACCESS_KEY"))

resp = client.responses.create(
    model="openai-gpt-5.5",
    input="Compare the current weather in zip code 94107 and 10001.",
    tools=[
        {
            "type": "namespace",
            "name": "weather",
            "description": "Weather lookup tools for US zip codes.",
            "tools": [
                {
                    "type": "function",
                    "name": "get_weather_by_zip",
                    "description": "Return current weather conditions for a US zip code.",
                    "defer_loading": True,
                    "parameters": {
                        "type": "object",
                        "properties": {
                            "zip_code": {"type": "string"},
                        },
                        "required": ["zip_code"],
                        "additionalProperties": False,
                    },
                }
            ],
        },
        {"type": "tool_search"},
    ],
    parallel_tool_calls=False,
)

print(resp)
import { InferenceClient } from "@digitalocean/dots";

const client = new InferenceClient({
    apiKey: process.env.MODEL_ACCESS_KEY,
});

const resp = await client.responses.create({
    model: "openai-gpt-5.5",
    input: "Compare the current weather in zip code 94107 and 10001.",
    tools: [
        {
            type: "namespace",
            name: "weather",
            description: "Weather lookup tools for US zip codes.",
            tools: [
                {
                    type: "function",
                    name: "get_weather_by_zip",
                    description: "Return current weather conditions for a US zip code.",
                    defer_loading: true,
                    parameters: {
                        type: "object",
                        properties: {
                            zip_code: { type: "string" },
                        },
                        required: ["zip_code"],
                        additionalProperties: false,
                    },
                },
            ],
        },
        { type: "tool_search" },
    ],
    parallel_tool_calls: false,
});

console.log(resp);
curl -X POST https://inference.do-ai.run/v1/responses \
  -H "Authorization: Bearer $MODEL_ACCESS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai-gpt-5.5",
    "input": "Compare the current weather in zip code 94107 and 10001.",
    "tools": [
      {
        "type": "namespace",
        "name": "weather",
        "description": "Weather lookup tools for US zip codes.",
        "tools": [
          {
            "type": "function",
            "name": "get_weather_by_zip",
            "description": "Return current weather conditions for a US zip code.",
            "defer_loading": true,
            "parameters": {
              "type": "object",
              "properties": {
                "zip_code": { "type": "string" }
              },
              "required": ["zip_code"],
              "additionalProperties": false
            }
          }
        ]
      },
      {
        "type": "tool_search"
      }
    ],
    "parallel_tool_calls": false
  }'

For MCP servers, set defer_loading: true on the MCP server tool definition (or on individual tools within the server). For maximum token savings, group deferred functions into namespaces or MCP servers with clear, high-level descriptions so that the model can effectively search and load only the relevant functions. For other best practices, see the OpenAI tool search documentation.

If the model needs a deferred tool, the response includes two additional output items before the eventual function call: tool_search_call which records the hosted search step, and tool_search_output, which contains the loaded subset that becomes callable. The response looks similar to the following:

Show the example response
[
  {
    "type": "tool_search_call",
    "execution": "server",
    "call_id": null,
    "status": "completed",
    "arguments": {
      "paths": ["weather"]
    }
  },
  {
    "type": "tool_search_output",
    "execution": "server",
    "call_id": null,
    "status": "completed",
    "tools": [
  ....
  },
  {
    "type": "function_call",
    "name": "get_weather_by_zip",
    "namespace": "weather",
    "call_id": "call_abc123",
    "arguments": "{\"zip_code\":\"94107\"}"
  }
]

Computer Use

With the computer use tool, you can interact with computer environments for autonomous desktop interaction such as screenshots, mouse and keyboard control, and desktop automation. You can use the computer use tool in combination with other tools such as bash and text editor for more comprehensive automation workflows.

Computer Use with Anthropic Models

Add the computer use tool to the model using the Messages API. The tool requires the anthropic-beta: computer-use-2025-11-24 header. Set display_width_px and display_height_px to match the resolution of the environment the model controls. The following example sends a Messages API request with the computer use tool enabled:

import os
from pydo.inference import Client

client = Client(token=os.environ.get("MODEL_ACCESS_KEY"))

resp = client.messages.create(
    model="anthropic-claude-opus-4.8",
    max_tokens=1024,
    tools=[
        {
            "type": "computer_20251124",
            "name": "computer",
            "display_width_px": 1024,
            "display_height_px": 768,
            "display_number": 1,
        }
    ],
    messages=[
        {"role": "user", "content": "Save a picture of a cat to my desktop."}
    ],
    headers={"anthropic-beta": "computer-use-2025-11-24"},
)

print(resp)
curl -X POST https://inference.do-ai.run/v1/messages \
  -H "Authorization: Bearer $MODEL_ACCESS_KEY" \
  -H "Content-Type: application/json" \
  -H "anthropic-beta: computer-use-2025-11-24" \
  -d '{
    "model": "anthropic-claude-opus-4.8",
    "max_tokens": 1024,
    "tools": [
      {
        "type": "computer_20251124",
        "name": "computer",
        "display_width_px": 1024,
        "display_height_px": 768,
        "display_number": 1
      }
    ],
    "messages": [
      {
        "role": "user",
        "content": "Save a picture of a cat to my desktop."
      }
    ]
  }'

Computer use runs as an agent loop. The model does not control the environment directly. Instead, it returns a tool_use block with an action such as screenshot, left_click, or type, and your application runs that action in a sandboxed environment (such as a virtual machine or container). Your application then returns the result, often a new screenshot, in a tool_result block and continues the conversation. The model evaluates the result and either requests another action or returns a final response when the task is complete.

Because the model can control a real environment, run computer use only in an isolated, low-privilege sandbox, keep sensitive data and credentials out of reach, and require human confirmation for consequential actions. For the full set of actions, response handling, and security guidance, see the Anthropic computer use tool documentation.

Computer Use with OpenAI Models

Provide the computer use tool to the model using the Responses API. Add a tool object with "type": "computer" to the tools array and then describe the task in plain language. The following example sends a Responses API request with the computer use tool enabled:

import os
from pydo.inference import Client

client = Client(token=os.environ.get("MODEL_ACCESS_KEY"))

resp = client.responses.create(
    model="openai-gpt-5.5",
    input="Check whether the Filters panel is open. If it is not open, click Show filters. Then type penguin in the search box. Use the computer tool for UI interaction.",
    tools=[
        {"type": "computer"}
    ],
)

print(resp)
import { InferenceClient } from "@digitalocean/dots";

const client = new InferenceClient({
    apiKey: process.env.MODEL_ACCESS_KEY,
});

const resp = await client.responses.create({
    model: "openai-gpt-5.5",
    input: "Check whether the Filters panel is open. If it is not open, click Show filters. Then type penguin in the search box. Use the computer tool for UI interaction.",
    tools: [
        { type: "computer" },
    ],
});

console.log(resp);
curl -X POST https://inference.do-ai.run/v1/responses \
  -H "Authorization: Bearer $MODEL_ACCESS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai-gpt-5.5",
    "input": "Check whether the Filters panel is open. If it is not open, click Show filters. Then type penguin in the search box. Use the computer tool for UI interaction.",
    "tools": [
      {
        "type": "computer"
      }
    ]
  }'

Computer use runs as a built-in loop that your harness drives. Inspect the returned computer_call and run every action in its actions[] array, in order. The first turn often requests a screenshot before the model commits to UI actions. Then, capture the updated screen and send it back as a computer_call_output item that references the call_id. Repeat until the model stops returning computer_call items and returns a final response.

Because the model can control a real environment, run computer use only in an isolated, low-privilege sandbox (such as a dedicated browser or container), keep an allowlist of permitted domains and actions, and require human confirmation for purchases, authenticated flows, and other consequential actions. For the full action set, screenshot handling, and security guidance, see the OpenAI computer use tool documentation.

Bash and Local Shell

Use the local shell tool to execute shell commands in a persistent session, allowing system operations, script execution, access to environment variables, and command-line automation. Use the bash tool with the Messages API for Anthropic models and the local shell tool with the Responses API for OpenAI models:

Bash Tool with Anthropic Models

Provide the bash tool to the model using the Messages API. Use the bash_20250124 tool type with the name bash. The following example sends a Messages API request with the bash tool enabled:

import os
from pydo.inference import Client

client = Client(token=os.environ.get("MODEL_ACCESS_KEY"))

resp = client.messages.create(
    model="anthropic-claude-opus-4.8",
    max_tokens=1024,
    tools=[
        {"type": "bash_20250124", "name": "bash"}
    ],
    messages=[
        {"role": "user", "content": "List all Python files in the current directory."}
    ],
)

print(resp)
import { InferenceClient } from "@digitalocean/dots";

const client = new InferenceClient({
    apiKey: process.env.MODEL_ACCESS_KEY,
});

const resp = await client.messages.create({
    model: "anthropic-claude-opus-4.8",
    max_tokens: 1024,
    tools: [
        { type: "bash_20250124", name: "bash" },
    ],
    messages: [
        { role: "user", content: "List all Python files in the current directory." },
    ],
});

console.log(resp);
curl -X POST https://inference.do-ai.run/v1/messages \
  -H "Authorization: Bearer $MODEL_ACCESS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic-claude-opus-4.8",
    "max_tokens": 1024,
    "tools": [
      {
        "type": "bash_20250124",
        "name": "bash"
      }
    ],
    "messages": [
      {
        "role": "user",
        "content": "List all Python files in the current directory."
      }
    ]
  }'

The bash tool runs as an agent loop against a persistent session that your application maintains. The model returns a tool_use block with a command to run (for example, ls -la *.py), your application runs that command in a bash shell and returns the combined stdout and stderr in a tool_result block, and the conversation continues. Session state, such as the working directory and environment variables, persists between commands, so the model can chain steps like installing a package, writing a script, and running it. To reset the session, the model can send {"restart": true} instead of a command.

The bash tool provides direct system access, so run it only in an isolated environment (such as a container or virtual machine), restrict commands with an allowlist, set resource limits, run with minimal permissions, and log every command. For the full parameter set, response handling, and security guidance, see the Anthropic bash tool documentation.

Local Shell Tool with OpenAI Models

Provide the shell tool to the model using the Responses API. Add a tool object with "type": "shell" to the tools array and set environment to local to run commands in your own runtime. The following example sends a Responses API request with the shell tool enabled for local execution:

import os
from pydo.inference import Client

client = Client(token=os.environ.get("MODEL_ACCESS_KEY"))

resp = client.responses.create(
    model="openai-gpt-5.5",
    instructions="The local bash shell environment is on Linux.",
    input="List all Python files in the current directory.",
    tools=[
        {
            "type": "shell",
            "environment": {
                "type": "local",
            },
        }
    ],
)

print(resp)
import { InferenceClient } from "@digitalocean/dots";

const client = new InferenceClient({
    apiKey: process.env.MODEL_ACCESS_KEY,
});

const resp = await client.responses.create({
    model: "openai-gpt-5.5",
    instructions: "The local bash shell environment is on Linux.",
    input: "List all Python files in the current directory.",
    tools: [
        {
            type: "shell",
            environment: {
                type: "local",
            },
        },
    ],
});

console.log(resp);
curl -X POST https://inference.do-ai.run/v1/responses \
  -H "Authorization: Bearer $MODEL_ACCESS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai-gpt-5.5",
    "instructions": "The local bash shell environment is on Linux.",
    "input": "List all Python files in the current directory.",
    "tools": [
      {
        "type": "shell",
        "environment": {
          "type": "local"
        }
      }
    ]
  }'

For the full parameter set and response handling, see the OpenAI shell tool documentation.

Web Fetch with Anthropic Models

Using an Anthropic-schema web fetch tool, the model can retrieve the full content of specific web pages and PDF documents to augment its context with live web content. The model fetches and reads the URL within a single request instead of running a multi-step agent loop.

Provide the web fetch tool to the model using the Messages API. Use the web_fetch_20250910 tool type with the name web_fetch. Optionally set max_uses to cap the number of fetches per request and allowed_domains or blocked_domains to restrict which sites the model can fetch. The following example sends a Messages API request with the web fetch tool enabled:

import os
from pydo.inference import Client

client = Client(token=os.environ.get("MODEL_ACCESS_KEY"))

resp = client.messages.create(
    model="anthropic-claude-opus-4.8",
    max_tokens=1024,
    messages=[
        {
            "role": "user",
            "content": "Please analyze the content at https://docs.digitalocean.com/products/inference/",
        }
    ],
    tools=[
        {
            "type": "web_fetch_20250910",
            "name": "web_fetch",
            "max_uses": 5,
        }
    ],
)

print(resp)
import { InferenceClient } from "@digitalocean/dots";

const client = new InferenceClient({
    apiKey: process.env.MODEL_ACCESS_KEY,
});

const resp = await client.messages.create({
    model: "anthropic-claude-opus-4.8",
    max_tokens: 1024,
    messages: [
        {
            role: "user",
            content: "Please analyze the content at https://docs.digitalocean.com/products/inference/",
        },
    ],
    tools: [
        {
            type: "web_fetch_20250910",
            name: "web_fetch",
            max_uses: 5,
        },
    ],
});

console.log(resp);
curl -X POST https://inference.do-ai.run/v1/messages \
  -H "Authorization: Bearer $MODEL_ACCESS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic-claude-opus-4.8",
    "max_tokens": 1024,
    "messages": [
      {
        "role": "user",
        "content": "Please analyze the content at https://docs.digitalocean.com/products/inference/"
      }
    ],
    "tools": [
      {
        "type": "web_fetch_20250910",
        "name": "web_fetch",
        "max_uses": 5
      }
    ]
  }'

The response includes additional block types before the model’s final answer:

  • server_tool_use: Indicates that the model is fetching a URL.
  • web_fetch_tool_result: Contains the fetched page as a web_fetch_result object with a document block.

The response looks similar to the following:

Show the example response
{
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "I'll fetch the content from the page to analyze it."
    },
    {
      "type": "server_tool_use",
      "id": "srvtoolu_01234567890abcdef",
      "name": "web_fetch",
      "input": {
        "url": "https://docs.digitalocean.com/products/inference/"
      }
    },
    {
      "type": "web_fetch_tool_result",
      "tool_use_id": "srvtoolu_01234567890abcdef",
      "content": {
        "type": "web_fetch_result",
        "url": "https://docs.digitalocean.com/products/inference/",
        "content": {
          "type": "document",
          "source": {
            "type": "text",
            "media_type": "text/plain",
            "data": "DigitalOcean Inference provides serverless and dedicated access to foundation models..."
          },
          "title": "Inference | DigitalOcean Documentation"
        },
        "retrieved_at": "2025-08-25T10:30:00Z"
      }
    },
    {
      "type": "text",
      "text": "Based on the documentation, DigitalOcean Inference is a managed AI platform that provides access to foundation models through serverless and dedicated endpoints..."
    }
  ],
  ....
  }
}

For PDF documents, the document block uses base64-encoded data in source.data instead of plain text. Web fetch usage is tracked in usage.server_tool_use.web_fetch_requests.

The model decides when to fetch based on the prompt and the URLs available in the conversation. For security, the model can only fetch URLs that already appear in the conversation, such as a URL in a user message or one returned by a previous web search or web fetch result. The model then analyzes the fetched content and returns its answer, with optional citations when you set "citations": {"enabled": true} on the tool.

Because the model processes external web content, enable web fetch only in trusted environments or when handling non-sensitive data, and use max_uses, allowed_domains, and max_content_tokens to limit exposure and token usage. For the full parameter set, response handling, and security guidance, see the Anthropic web fetch tool documentation.

Code Editing

Both Anthropic and OpenAI models can edit files in your codebase. Anthropic models use the text editor tool with the Messages API, and OpenAI models use the apply patch tool with the Responses API:

Code Editing with Anthropic Models

Using an Anthropic-schema text editor tool, you can directly view and modify text files, and interact with them to debug, refactor, and write tests to improve your code or other text documents.

Provide the text editor tool (named str_replace_based_edit_tool) to the model using the Messages API. Use the text_editor_20250728 tool type, and optionally set max_characters to control truncation when the model views large files. The following example sends a Messages API request with the text editor tool enabled:

import os
from pydo.inference import Client

client = Client(token=os.environ.get("MODEL_ACCESS_KEY"))

resp = client.messages.create(
    model="anthropic-claude-opus-4.8",
    max_tokens=1024,
    messages=[
        {
            "role": "user",
            "content": "There's a syntax error in my primes.py file. Can you help me fix it?",
        }
    ],
    tools=[
        {
            "type": "text_editor_20250728",
            "name": "str_replace_based_edit_tool",
            "max_characters": 10000,
        }
    ],
)

print(resp)
import { InferenceClient } from "@digitalocean/dots";

const client = new InferenceClient({
    apiKey: process.env.MODEL_ACCESS_KEY,
});

const resp = await client.messages.create({
    model: "anthropic-claude-opus-4.8",
    max_tokens: 1024,
    messages: [
        {
            role: "user",
            content: "There's a syntax error in my primes.py file. Can you help me fix it?",
        },
    ],
    tools: [
        {
            type: "text_editor_20250728",
            name: "str_replace_based_edit_tool",
            max_characters: 10000,
        },
    ],
});

console.log(resp);
curl -X POST https://inference.do-ai.run/v1/messages \
  -H "Authorization: Bearer $MODEL_ACCESS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic-claude-opus-4.8",
    "max_tokens": 1024,
    "messages": [
      {
        "role": "user",
        "content": "There'\''s a syntax error in my primes.py file. Can you help me fix it?"
      }
    ],
    "tools": [
      {
        "type": "text_editor_20250728",
        "name": "str_replace_based_edit_tool",
        "max_characters": 10000
      }
    ]
  }'

The model first responds with a tool_use block containing a view command to examine the file. Your application reads the file, returns its contents in a tool_result block, and continues the conversation. The model then issues commands such as str_replace, insert, or create to make edits. For the full set of commands and the request and response flow, see the Anthropic text editor tool documentation.

Code Editing with OpenAI Models

Using the apply patch tool, you can create, update (refactor, fix bugs, test files), and delete files in your codebase using structured diffs. The model emits patch operations that your application applies and then reports back on, enabling iterative, multi-step code editing workflows.

Provide the apply patch tool to the model using the Responses API. Add a tool object with "type": "apply_patch" to the tools array and give the model context about the relevant files in your input (or provide tools for exploring the file system). The following example sends a Responses API request with the apply patch tool enabled:

import os
from pydo.inference import Client

client = Client(token=os.environ.get("MODEL_ACCESS_KEY"))

resp = client.responses.create(
    model="openai-gpt-5.5",
    input="The file lib/fib.py defines a function fib(n). Rename the fib() function to fibonacci() and update any references.",
    tools=[
        {"type": "apply_patch"}
    ],
)

print(resp)
import { InferenceClient } from "@digitalocean/dots";

const client = new InferenceClient({
    apiKey: process.env.MODEL_ACCESS_KEY,
});

const resp = await client.responses.create({
    model: "openai-gpt-5.5",
    input: "The file lib/fib.py defines a function fib(n). Rename the fib() function to fibonacci() and update any references.",
    tools: [
        { type: "apply_patch" },
    ],
});

console.log(resp);
curl -X POST https://inference.do-ai.run/v1/responses \
  -H "Authorization: Bearer $MODEL_ACCESS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai-gpt-5.5",
    "input": "The file lib/fib.py defines a function fib(n). Rename the fib() function to fibonacci() and update any references.",
    "tools": [
      {
        "type": "apply_patch"
      }
    ]
  }'

The apply patch tool runs as an agent loop that your application maintains. The model returns one or more apply_patch_call output items, each describing a single file operation (create_file, update_file, or delete_file) with a diff and path. Your application applies each patch in its working directory, then sends the result back as an apply_patch_call_output item that references the call_id, with a status of completed or failed and an optional output string. Pass the results back using previous_response_id (or by including the items in input) and keep the apply patch tool enabled so the model can continue editing or explain its changes. If a patch fails, set status to failed and include a helpful output message so the model can recover.

The apply patch tool modifies files in your codebase, so apply patches only in an isolated working directory or version-controlled repository, review the diffs before applying them, and keep a human in the loop for consequential changes. For the full operation set and response handling, see the OpenAI apply patch tool documentation.

Function Calling

Using function calling, models can interface with external systems and access data outside their training data. Unlike DigitalOcean-hosted server-side tools, function calling is client-side: you define your own functions, the model decides when to call them and returns the arguments, and your application runs the function and returns the result. Define functions with the Messages API for Anthropic models and the Responses API for OpenAI models.

Function Calling with Anthropic Models

Define each function in the tools array with a name, description, and input_schema to describe its parameters. The following example sends a Messages API request with a single get_weather function defined:

import os
from pydo.inference import Client

client = Client(token=os.environ.get("MODEL_ACCESS_KEY"))

resp = client.messages.create(
    model="anthropic-claude-opus-4.8",
    max_tokens=1024,
    tools=[
        {
            "name": "get_weather",
            "description": "Get the current weather for a location.",
            "input_schema": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "The city and state, for example San Francisco, CA",
                    }
                },
                "required": ["location"],
            },
        }
    ],
    messages=[
        {"role": "user", "content": "What is the weather in San Francisco?"}
    ],
)

print(resp)
import { InferenceClient } from "@digitalocean/dots";

const client = new InferenceClient({
    apiKey: process.env.MODEL_ACCESS_KEY,
});

const resp = await client.messages.create({
    model: "anthropic-claude-opus-4.8",
    max_tokens: 1024,
    tools: [
        {
            name: "get_weather",
            description: "Get the current weather for a location.",
            input_schema: {
                type: "object",
                properties: {
                    location: {
                        type: "string",
                        description: "The city and state, for example San Francisco, CA",
                    },
                },
                required: ["location"],
            },
        },
    ],
    messages: [
        { role: "user", content: "What is the weather in San Francisco?" },
    ],
});

console.log(resp);
curl -X POST https://inference.do-ai.run/v1/messages \
  -H "Authorization: Bearer $MODEL_ACCESS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic-claude-opus-4.8",
    "max_tokens": 1024,
    "tools": [
      {
        "name": "get_weather",
        "description": "Get the current weather for a location.",
        "input_schema": {
          "type": "object",
          "properties": {
            "location": {
              "type": "string",
              "description": "The city and state, for example San Francisco, CA"
            }
          },
          "required": ["location"]
        }
      }
    ],
    "messages": [
      {
        "role": "user",
        "content": "What is the weather in San Francisco?"
      }
    ]
  }'

When the model decides to call a function, it returns a tool_use block with the function name and an input object containing the arguments. Your application runs the function, then continues the conversation by sending a tool_result block that references the tool_use_id and contains the function output. The model uses that result to produce its final response. For the full request and response flow, see the Anthropic tool use documentation.

Function Calling with OpenAI Models

Define each function in the tools array with "type": "function", name, description, and parameters JSON schema. The following example sends a Responses API request with a single get_horoscope function defined:

import os
from pydo.inference import Client

client = Client(token=os.environ.get("MODEL_ACCESS_KEY"))

resp = client.responses.create(
    model="openai-gpt-5.5",
    input="What is my horoscope? I am an Aquarius.",
    tools=[
        {
            "type": "function",
            "name": "get_horoscope",
            "description": "Get today's horoscope for an astrological sign.",
            "parameters": {
                "type": "object",
                "properties": {
                    "sign": {
                        "type": "string",
                        "description": "An astrological sign like Taurus or Aquarius",
                    }
                },
                "required": ["sign"],
            },
        }
    ],
)

print(resp)
import { InferenceClient } from "@digitalocean/dots";

const client = new InferenceClient({
    apiKey: process.env.MODEL_ACCESS_KEY,
});

const resp = await client.responses.create({
    model: "openai-gpt-5.5",
    input: "What is my horoscope? I am an Aquarius.",
    tools: [
        {
            type: "function",
            name: "get_horoscope",
            description: "Get today's horoscope for an astrological sign.",
            parameters: {
                type: "object",
                properties: {
                    sign: {
                        type: "string",
                        description: "An astrological sign like Taurus or Aquarius",
                    },
                },
                required: ["sign"],
            },
        },
    ],
});

console.log(resp);
curl -X POST https://inference.do-ai.run/v1/responses \
  -H "Authorization: Bearer $MODEL_ACCESS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai-gpt-5.5",
    "input": "What is my horoscope? I am an Aquarius.",
    "tools": [
      {
        "type": "function",
        "name": "get_horoscope",
        "description": "Get today'\''s horoscope for an astrological sign.",
        "parameters": {
          "type": "object",
          "properties": {
            "sign": {
              "type": "string",
              "description": "An astrological sign like Taurus or Aquarius"
            }
          },
          "required": ["sign"]
        }
      }
    ]
  }'

When the model decides to call a function, it returns a function_call output item with the function name, a call_id, and an arguments JSON string. Your application runs the function, then sends the result back as a function_call_output item that references the call_id (using previous_response_id or by including the items in input). The model uses that result to produce its final response. For the full request and response flow, see the OpenAI function calling documentation.

We can't find any results for your search.

Try using different keywords or simplifying your search terms.