Tool Calling (Function Calling)

Enable AI models to invoke predefined functions and interact with external systems.

Overview

Tool calling (also known as function calling) allows AI models to invoke predefined functions during conversations. This enables the model to interact with external systems, retrieve real-time data, and perform actions beyond text generation.

Super Agent Stack provides full OpenAI-compatible tool calling support, working seamlessly with the OpenAI SDK and direct HTTP requests.

Quick Start

tool-calling-example.ts
import OpenAI from 'openai';

const client = new OpenAI({
  baseURL: 'https://www.superagentstack.com/api/v1',
  apiKey: process.env.OPENROUTER_KEY,
  defaultHeaders: {
    'superAgentKey': process.env.SUPER_AGENT_KEY
  }
});

// Define a tool
const tools = [{
  type: 'function',
  function: {
    name: 'get_weather',
    description: 'Get the current weather for a location',
    parameters: {
      type: 'object',
      properties: {
        location: {
          type: 'string',
          description: 'City name, e.g. San Francisco'
        },
        unit: {
          type: 'string',
          enum: ['celsius', 'fahrenheit']
        }
      },
      required: ['location']
    }
  }
}];

// Make request with tools
const response = await client.chat.completions.create({
  model: 'google/gemini-2.0-flash-exp:free',
  messages: [{ role: 'user', content: "What's the weather in Tokyo?" }],
  tools: tools
});

// Check if model called a tool
if (response.choices[0].message.tool_calls) {
  const toolCall = response.choices[0].message.tool_calls[0];
  console.log(`Tool: ${toolCall.function.name}`);
  console.log(`Args: ${toolCall.function.arguments}`);
}

Tool Definition

Tools are defined using JSON Schema format. Each tool must have:

  • type: Always "function"
  • function.name: Function name (1-64 chars, alphanumeric + underscore/hyphen)
  • function.description: What the function does (optional but recommended)
  • function.parameters: JSON Schema object describing the parameters

Example Tool Definition

json
{
  "type": "function",
  "function": {
    "name": "get_weather",
    "description": "Get the current weather for a location",
    "parameters": {
      "type": "object",
      "properties": {
        "location": {
          "type": "string",
          "description": "City name, e.g. San Francisco"
        },
        "unit": {
          "type": "string",
          "enum": ["celsius", "fahrenheit"],
          "description": "Temperature unit"
        }
      },
      "required": ["location"]
    }
  }
}

Tool Choice Parameter

Control how the model uses tools with the tool_choice parameter:

ValueBehavior
"auto"Model decides whether to use tools (default)
"none"Model will not use any tools
"required"Model must use at least one tool
Specific functionForce model to use a specific tool
typescript
// Let model decide (default)
const response = await client.chat.completions.create({
  model: 'google/gemini-2.0-flash-exp:free',
  messages: [...],
  tools: tools,
  tool_choice: 'auto'
});

// Force specific tool
const response = await client.chat.completions.create({
  model: 'google/gemini-2.0-flash-exp:free',
  messages: [...],
  tools: tools,
  tool_choice: {
    type: 'function',
    function: { name: 'get_weather' }
  }
});

Complete Workflow

Here's a complete example showing the full tool calling workflow:

complete-example.ts
import OpenAI from 'openai';

const client = new OpenAI({
  baseURL: 'https://www.superagentstack.com/api/v1',
  apiKey: process.env.OPENROUTER_KEY,
  defaultHeaders: { 'superAgentKey': process.env.SUPER_AGENT_KEY }
});

// Define tools
const tools = [{
  type: 'function',
  function: {
    name: 'get_weather',
    description: 'Get current weather',
    parameters: {
      type: 'object',
      properties: {
        location: { type: 'string' }
      },
      required: ['location']
    }
  }
}];

// Step 1: Initial request
const response = await client.chat.completions.create({
  model: 'google/gemini-2.0-flash-exp:free',
  messages: [{ role: 'user', content: "What's the weather in Tokyo?" }],
  tools: tools
});

// Step 2: Check for tool calls
const toolCall = response.choices[0].message.tool_calls?.[0];

if (toolCall) {
  // Step 3: Execute function
  const functionArgs = JSON.parse(toolCall.function.arguments);
  const result = await getWeather(functionArgs.location);
  
  // Step 4: Send result back to model
  const finalResponse = await client.chat.completions.create({
    model: 'google/gemini-2.0-flash-exp:free',
    messages: [
      { role: 'user', content: "What's the weather in Tokyo?" },
      response.choices[0].message,
      {
        role: 'tool',
        content: JSON.stringify(result),
        tool_call_id: toolCall.id
      }
    ],
    tools: tools
  });
  
  console.log(finalResponse.choices[0].message.content);
}

// Your function implementation
async function getWeather(location: string) {
  // Call weather API
  return {
    location,
    temperature: 22,
    condition: 'sunny'
  };
}

Best Practices

1. Clear Tool Descriptions

Provide detailed descriptions to help the model understand when to use each tool:

typescript
// ❌ Bad
{
  name: 'get_data',
  description: 'Gets data'
}

// ✅ Good
{
  name: 'get_weather',
  description: 'Get the current weather conditions including temperature, humidity, and forecast for a specific city'
}

2. Use Enums for Limited Options

typescript
{
  unit: {
    type: 'string',
    enum: ['celsius', 'fahrenheit'],
    description: 'Temperature unit'
  }
}

3. Mark Required Parameters

typescript
{
  parameters: {
    type: 'object',
    properties: {
      location: { type: 'string' },
      unit: { type: 'string' }
    },
    required: ['location']  // unit is optional
  }
}

4. Handle Errors Gracefully

typescript
try {
  const result = await executeFunction(args);
  return result;
} catch (error) {
  // Return error to model
  return { error: error.message };
}

Error Handling

Common Errors

Invalid Tool Definition

json
{
  "error": "Invalid tool definition",
  "details": [
    "Tool name must only contain letters, numbers, underscores, and hyphens"
  ]
}

Solution: Fix tool name to match pattern ^[a-zA-Z0-9_-]+$

tool_choice Without Tools

json
{
  "error": "Invalid tool_choice",
  "details": "tool_choice requires tools to be defined"
}

Solution: Include tools parameter when using tool_choice

Non-existent Tool Reference

json
{
  "error": "Invalid tool_choice",
  "details": "tool_choice references non-existent tool: 'get_weather'"
}

Solution: Ensure tool name in tool_choice matches a defined tool

Works with Memory & RAG

Tool calling works seamlessly with session management and RAG features. Just add sessionId header and enable useRAG to combine tools with memory and file search!

Next Steps