Stateless APIRemember 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.
Basic Tool Definition
Define tools using the OpenAI function calling format: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))
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));
Tool Choice Options
Control when and how tools are called using thetool_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 |
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,
},
)
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,
}),
});
Handling Tool Calls
When a model calls a tool, the response contains function call information in the output: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
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
}
}
}
Multi-Turn Tool Calling
Stateless DesignSince 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.
# 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"])
// 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);
}
Parallel Tool Calls
Enable parallel tool execution withparallel_tool_calls:
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,
},
)
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,
}),
});
Best Practices
- Clear tool descriptions: Provide detailed descriptions for better tool selection
- Validate tool results: Always validate and sanitize tool execution results
- Handle errors gracefully: Implement error handling for tool execution failures
- Use parallel calls: Enable
parallel_tool_callswhen multiple independent tools can run simultaneously - Tool result format: Return tool results as JSON strings for consistency
Was this page helpful?