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

# Tool Calling

> Integrate function calling with the Responses API.

The Responses API supports comprehensive tool calling capabilities, allowing models to call functions, execute tools in parallel, and handle complex multi-step workflows.

<Note>
  **Stateless API**

  Remember that this API is stateless. When handling multi-turn tool calls, you must include the complete conversation history (including previous tool calls and results) in each request.
</Note>

### Basic Tool Definition

Define tools using the OpenAI function calling format:

<CodeGroup>
  ```python Python theme={null}
  import requests
  import json

  weather_tool = {
      "type": "function",
      "name": "get_weather",
      "description": "Get the current weather in a location",
      "parameters": {
          "type": "object",
          "properties": {
              "location": {
                  "type": "string",
                  "description": "The city and state, e.g. San Francisco, CA"
              },
              "unit": {
                  "type": "string",
                  "enum": ["celsius", "fahrenheit"]
              }
          },
          "required": ["location"]
      }
  }

  response = requests.post(
      "https://api.anannas.ai/api/v1/responses",
      headers={
          "Authorization": "Bearer <ANANNAS_API_KEY>",
          "Content-Type": "application/json",
      },
      json={
          "model": "openai/gpt-5-mini",
          "input": [
              {
                  "type": "message",
                  "role": "user",
                  "content": [
                      {
                          "type": "input_text",
                          "text": "What is the weather in San Francisco?"
                      }
                  ]
              }
          ],
          "tools": [weather_tool],
          "tool_choice": "auto",
          "max_output_tokens": 9000,
      },
  )

  result = response.json()
  print(json.dumps(result, indent=2))
  ```

  ```typescript TypeScript theme={null}
  const weatherTool = {
    type: 'function' as const,
    name: 'get_weather',
    description: 'Get the current weather in a location',
    parameters: {
      type: 'object',
      properties: {
        location: {
          type: 'string',
          description: 'The city and state, e.g. San Francisco, CA',
        },
        unit: {
          type: 'string',
          enum: ['celsius', 'fahrenheit'],
        },
      },
      required: ['location'],
    },
  };

  const response = await fetch('https://api.anannas.ai/api/v1/responses', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer <ANANNAS_API_KEY>',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      model: 'openai/gpt-5-mini',
      input: [
        {
          type: 'message',
          role: 'user',
          content: [
            {
              type: 'input_text',
              text: 'What is the weather in San Francisco?',
            },
          ],
        },
      ],
      tools: [weatherTool],
      tool_choice: 'auto',
      max_output_tokens: 9000,
    }),
  });

  const result = await response.json();
  console.log(JSON.stringify(result, null, 2));
  ```
</CodeGroup>

### Tool Choice Options

Control when and how tools are called using the `tool_choice` parameter:

| Tool Choice                                 | Description                                   |
| ------------------------------------------- | --------------------------------------------- |
| `"auto"`                                    | Model decides whether to call tools (default) |
| `"none"`                                    | Model will not call any tools                 |
| `{"type": "function", "name": "tool_name"}` | Force specific tool call                      |

**Force Specific Tool:**

<CodeGroup>
  ```python Python theme={null}
  response = requests.post(
      "https://api.anannas.ai/api/v1/responses",
      headers={
          "Authorization": "Bearer <ANANNAS_API_KEY>",
          "Content-Type": "application/json",
      },
      json={
          "model": "openai/gpt-5-mini",
          "input": [
              {
                  "type": "message",
                  "role": "user",
                  "content": [
                      {
                          "type": "input_text",
                          "text": "Get the weather for New York"
                      }
                  ]
              }
          ],
          "tools": [weather_tool],
          "tool_choice": {
              "type": "function",
              "name": "get_weather"
          },
          "max_output_tokens": 9000,
      },
  )
  ```

  ```typescript TypeScript theme={null}
  const response = await fetch('https://api.anannas.ai/api/v1/responses', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer <ANANNAS_API_KEY>',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      model: 'openai/gpt-5-mini',
      input: [
        {
          type: 'message',
          role: 'user',
          content: [
            {
              type: 'input_text',
              text: 'Get the weather for New York',
            },
          ],
        },
      ],
      tools: [weatherTool],
      tool_choice: {
        type: 'function',
        name: 'get_weather',
      },
      max_output_tokens: 9000,
    }),
  });
  ```
</CodeGroup>

### Handling Tool Calls

When a model calls a tool, the response contains function call information in the output:

<CodeGroup>
  ```python Python theme={null}
  response = requests.post(
      "https://api.anannas.ai/api/v1/responses",
      headers={
          "Authorization": "Bearer <ANANNAS_API_KEY>",
          "Content-Type": "application/json",
      },
      json={
          "model": "openai/gpt-5-mini",
          "input": [
              {
                  "type": "message",
                  "role": "user",
                  "content": [
                      {
                          "type": "input_text",
                          "text": "What is the weather in Paris?"
                      }
                  ]
              }
          ],
          "tools": [weather_tool],
          "tool_choice": "auto",
          "max_output_tokens": 9000,
      },
  )

  result = response.json()

  # Extract function calls from output
  for output_item in result["output"]:
      for content_part in output_item.get("content", []):
          if content_part.get("type") == "function_call":
              func_call = content_part["function_call"]
              print(f"Function: {func_call['name']}")
              print(f"Arguments: {func_call['arguments']}")
              
              # Execute the function
              args = json.loads(func_call["arguments"])
              # ... execute your function with args ...
              
              # Then make another request with the tool result
  ```

  ```typescript TypeScript theme={null}
  const response = await fetch('https://api.anannas.ai/api/v1/responses', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer <ANANNAS_API_KEY>',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      model: 'openai/gpt-5-mini',
      input: [
        {
          type: 'message',
          role: 'user',
          content: [
            {
              type: 'input_text',
              text: 'What is the weather in Paris?',
            },
          ],
        },
      ],
      tools: [weatherTool],
      tool_choice: 'auto',
      max_output_tokens: 9000,
    }),
  });

  const result = await response.json();

  // Extract function calls from output
  for (const outputItem of result.output) {
    for (const contentPart of outputItem.content || []) {
      if (contentPart.type === 'function_call') {
        const funcCall = contentPart.function_call;
        console.log(`Function: ${funcCall.name}`);
        console.log(`Arguments: ${funcCall.arguments}`);
        
        // Execute the function
        const args = JSON.parse(funcCall.arguments);
        // ... execute your function with args ...
        
        // Then make another request with the tool result
      }
    }
  }
  ```
</CodeGroup>

### Multi-Turn Tool Calling

<Warning>
  **Stateless Design**

  Since the Anannas API is stateless, you must include the complete conversation history in each request, including all previous tool calls and their results. The Anannas API does not remember previous tool interactions.
</Warning>

For multi-turn conversations with tool calls, include the tool results in subsequent requests:

<CodeGroup>
  ```python Python theme={null}
  # First request - model calls tool
  first_response = requests.post(
      "https://api.anannas.ai/api/v1/responses",
      headers={
          "Authorization": "Bearer <ANANNAS_API_KEY>",
          "Content-Type": "application/json",
      },
      json={
          "model": "openai/gpt-5-mini",
          "input": [
              {
                  "type": "message",
                  "role": "user",
                  "content": [
                      {
                          "type": "input_text",
                          "text": "What's the weather in Boston? Then recommend what to wear."
                      }
                  ]
              }
          ],
          "tools": [weather_tool],
          "max_output_tokens": 9000,
      },
  )

  first_result = first_response.json()

  # Extract function call
  function_call = None
  for output_item in first_result["output"]:
      for content_part in output_item.get("content", []):
          if content_part.get("type") == "function_call":
              function_call = content_part["function_call"]
              break

  if function_call:
      # Execute the function
      args = json.loads(function_call["arguments"])
      # Simulate weather API call
      weather_result = {"temperature": 45, "condition": "rainy", "humidity": 85}
      
      # Second request - include tool result
      second_response = requests.post(
          "https://api.anannas.ai/api/v1/responses",
          headers={
              "Authorization": "Bearer <ANANNAS_API_KEY>",
              "Content-Type": "application/json",
          },
          json={
              "model": "openai/gpt-5-mini",
              "input": [
                  {
                      "type": "message",
                      "role": "user",
                      "content": [
                          {
                              "type": "input_text",
                              "text": "What's the weather in Boston? Then recommend what to wear."
                          }
                      ]
                  },
                  {
                      "type": "message",
                      "role": "assistant",
                      "status": "completed",
                      "content": first_result["output"][0]["content"]
                  },
                  {
                      "type": "message",
                      "role": "tool",
                      "content": [
                          {
                              "type": "tool_result",
                              "tool_call_id": function_call["id"],
                              "content": json.dumps(weather_result)
                          }
                      ]
                  }
              ],
              "tools": [weather_tool],
              "max_output_tokens": 9000,
          },
      )
      
      second_result = second_response.json()
      print(second_result["output"][0]["content"][0]["text"])
  ```

  ```typescript TypeScript theme={null}
  // First request - model calls tool
  const firstResponse = await fetch('https://api.anannas.ai/api/v1/responses', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer <ANANNAS_API_KEY>',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      model: 'openai/gpt-5-mini',
      input: [
        {
          type: 'message',
          role: 'user',
          content: [
            {
              type: 'input_text',
              text: "What's the weather in Boston? Then recommend what to wear.",
            },
          ],
        },
      ],
      tools: [weatherTool],
      max_output_tokens: 9000,
    }),
  });

  const firstResult = await firstResponse.json();

  // Extract function call
  let functionCall = null;
  for (const outputItem of firstResult.output) {
    for (const contentPart of outputItem.content || []) {
      if (contentPart.type === 'function_call') {
        functionCall = contentPart.function_call;
        break;
      }
    }
  }

  if (functionCall) {
    // Execute the function
    const args = JSON.parse(functionCall.arguments);
    // Simulate weather API call
    const weatherResult = { temperature: 45, condition: 'rainy', humidity: 85 };
    
    // Second request - include tool result
    const secondResponse = await fetch('https://api.anannas.ai/api/v1/responses', {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer <ANANNAS_API_KEY>',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        model: 'openai/gpt-5-mini',
        input: [
          {
            type: 'message',
            role: 'user',
            content: [
              {
                type: 'input_text',
                text: "What's the weather in Boston? Then recommend what to wear.",
              },
            ],
          },
          {
            type: 'message',
            role: 'assistant',
            status: 'completed',
            content: firstResult.output[0].content,
          },
          {
            type: 'message',
            role: 'tool',
            content: [
              {
                type: 'tool_result',
                tool_call_id: functionCall.id,
                content: JSON.stringify(weatherResult),
              },
            ],
          },
        ],
        tools: [weatherTool],
        max_output_tokens: 9000,
      }),
    });
    
    const secondResult = await secondResponse.json();
    console.log(secondResult.output[0].content[0].text);
  }
  ```
</CodeGroup>

### Parallel Tool Calls

Enable parallel tool execution with `parallel_tool_calls`:

<CodeGroup>
  ```python Python theme={null}
  response = requests.post(
      "https://api.anannas.ai/api/v1/responses",
      headers={
          "Authorization": "Bearer <ANANNAS_API_KEY>",
          "Content-Type": "application/json",
      },
      json={
          "model": "openai/gpt-5-mini",
          "input": [
              {
                  "type": "message",
                  "role": "user",
                  "content": [
                      {
                          "type": "input_text",
                          "text": "Get the weather for both New York and London"
                      }
                  ]
              }
          ],
          "tools": [weather_tool],
          "parallel_tool_calls": True,
          "max_output_tokens": 9000,
      },
  )
  ```

  ```typescript TypeScript theme={null}
  const response = await fetch('https://api.anannas.ai/api/v1/responses', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer <ANANNAS_API_KEY>',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      model: 'openai/gpt-5-mini',
      input: [
        {
          type: 'message',
          role: 'user',
          content: [
            {
              type: 'input_text',
              text: 'Get the weather for both New York and London',
            },
          ],
        },
      ],
      tools: [weatherTool],
      parallel_tool_calls: true,
      max_output_tokens: 9000,
    }),
  });
  ```
</CodeGroup>

### Best Practices

1. **Clear tool descriptions**: Provide detailed descriptions for better tool selection
2. **Validate tool results**: Always validate and sanitize tool execution results
3. **Handle errors gracefully**: Implement error handling for tool execution failures
4. **Use parallel calls**: Enable `parallel_tool_calls` when multiple independent tools can run simultaneously
5. **Tool result format**: Return tool results as JSON strings for consistency

<div
  style={{ 
marginTop: '2rem',
display: 'flex',
alignItems: 'center',
gap: '0.75rem',
fontSize: '14px',
color: '#6b7280'
}}
>
  <span>Was this page helpful?</span>

  <button
    id="feedback-yes-btn"
    onClick={() => {
  console.log('Positive feedback');
  document.getElementById('feedback-yes-btn').style.background = 'rgba(156, 163, 175, 0.1)';
  document.getElementById('feedback-yes-btn').style.backdropFilter = 'blur(10px)';
  document.getElementById('feedback-yes-btn').style.border = '1px solid rgba(156, 163, 175, 0.2)';
  document.getElementById('feedback-no-btn').style.background = 'transparent';
  document.getElementById('feedback-no-btn').style.backdropFilter = 'none';
  document.getElementById('feedback-no-btn').style.border = 'none';
}}
    style={{
  background: 'transparent',
  border: 'none',
  cursor: 'pointer',
  padding: '6px 12px',
  fontSize: '14px',
  borderRadius: '8px',
  transition: 'all 0.2s ease',
  display: 'flex',
  alignItems: 'center',
  gap: '6px',
  color: '#6b7280'
}}
  >
    <span style={{ fontSize: '16px' }}>👍</span>
    Yes
  </button>

  <button
    id="feedback-no-btn"
    onClick={() => {
  console.log('Negative feedback');
  document.getElementById('feedback-no-btn').style.background = 'rgba(156, 163, 175, 0.1)';
  document.getElementById('feedback-no-btn').style.backdropFilter = 'blur(10px)';
  document.getElementById('feedback-no-btn').style.border = '1px solid rgba(156, 163, 175, 0.2)';
  document.getElementById('feedback-yes-btn').style.background = 'transparent';
  document.getElementById('feedback-yes-btn').style.backdropFilter = 'none';
  document.getElementById('feedback-yes-btn').style.border = 'none';
}}
    style={{
  background: 'transparent',
  border: 'none',
  cursor: 'pointer',
  padding: '6px 12px',
  fontSize: '14px',
  borderRadius: '8px',
  transition: 'all 0.2s ease',
  display: 'flex',
  alignItems: 'center',
  gap: '6px',
  color: '#6b7280'
}}
  >
    <span style={{ fontSize: '16px' }}>👎</span>
    No
  </button>
</div>
