How FreeLLMAPI Handles Google Gemini Tool Calls: OpenAI-to-Gemini Translation

FreeLLMAPI acts as a protocol bridge that translates OpenAI-compatible tool call requests into Google Gemini's native functionDeclarations format and back, enabling seamless function calling through a unified API surface.

FreeLLMAPI provides an OpenAI-compatible API layer that abstracts provider-specific implementations, allowing developers to use standard tool calling patterns with Google's Gemini models. The system handles FreeLLMAPI Google Gemini tool calls through a bidirectional translation layer defined in server/src/lib/gemini-wire.ts and orchestrated by the geminiRouter in server/src/routes/gemini.ts. This architecture converts function definitions, manages tool choice configurations, and normalizes responses across the two formats without requiring client-side changes.

The Three-Stage Translation Pipeline

The implementation follows a strict pipeline that processes every tool-enabled request through three distinct transformation stages. Each stage uses specific helper functions to ensure protocol compatibility between OpenAI's tools array format and Gemini's functionDeclarations structure.

Stage 1: Converting OpenAI Tool Definitions to Gemini Format

When a client sends a request containing a tools array or toolConfig, FreeLLMAPI immediately translates these OpenAI-style definitions into Gemini's native schema. The geminiToolsToChatTools function (lines 92-102 in server/src/lib/gemini-wire.ts) maps each function definition from the OpenAI format to Gemini's functionDeclarations structure.

Simultaneously, the geminiToolChoice function (lines 13-25) handles the translation of OpenAI's toolConfig—including mode and allowedFunctionNames—into Gemini's functionCallingConfig. This ensures that tool choice constraints like auto, any, or none are properly respected by the Gemini API.

Stage 2: Executing Requests Against the Gemini API

After translation, the adapted request is forwarded to Gemini via the /v1beta/models/{model}:generateContent or streamGenerateContent endpoint. The geminiResponseFormat function (lines 28-43 in server/src/lib/gemini-wire.ts) ensures that when a client requests response_format: {type: "json_object"}, Gemini receives the appropriate JSON schema constraints to enforce structured output.

During execution, Gemini may emit tool calls within its response payload, which FreeLLMAPI captures for the final translation stage.

Stage 3: Transforming Gemini Responses Back to OpenAI Format

FreeLLMAPI receives Gemini's response and reconstructs an OpenAI-compatible payload through two critical functions. The geminiPartsFromResult function (lines 74-86) extracts tool calls, reasoning, and text content from Gemini's native parts format, while geminiResponseFromResult (lines 97-101) packages these components into the final JSON structure returned to the client.

The response includes standard OpenAI fields such as tool_calls containing function names and arguments, content blocks for text and images, and a finish_reason mapped via geminiFinishReason to ensure consistent status codes like stop or tool_calls across providers.

Special Grounding Tool Support

Beyond standard function calling, FreeLLMAPI implements support for Gemini-specific capabilities through the Google Search grounding tool. When a client includes a tool named google_search in the request, the router automatically detects this identifier and translates it into Gemini's proprietary grounding tool rather than a standard function declaration.

This translation allows the model to anchor responses in live web search results while maintaining the standard OpenAI-compatible request and response flow. The implementation details are documented in docs/api.md under the Gemini Google Search grounding section.

Implementation Walkthrough

The following examples demonstrate the complete flow of tool call handling using FreeLLMAPI's Gemini integration.

Sending a Tool-Enabled Request

Clients send standard OpenAI-style requests with tool definitions:

POST /v1beta/models/gemini-1.5-flash:generateContent
Content-Type: application/json
Authorization: Bearer <API_KEY>

{
  "contents": [
    { "role": "user", "parts": [{ "text": "What is the current weather in Paris?" }] }
  ],
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "get_weather",
        "description": "Fetch weather for a city",
        "parameters": {
          "type": "object",
          "properties": {
            "city": { "type": "string", "description": "City name" }
          },
          "required": ["city"]
        }
      }
    }
  ],
  "tool_config": { "function_calling_config": { "mode": "auto" } },
  "response_format": { "type": "json_object" }
}

FreeLLMAPI processes this through geminiToolsToChatTools and returns an OpenAI-compatible response containing the tool call:

{
  "choices": [
    {
      "message": {
        "role": "assistant",
        "content": "",
        "tool_calls": [
          {
            "id": "call_0_0",
            "type": "function",
            "function": { "name": "get_weather", "arguments": "{\"city\":\"Paris\"}" }
          }
        ]
      },
      "finish_reason": "stop"
    }
  ],
  "usage": { "prompt_tokens": 27, "completion_tokens": 12, "total_tokens": 39 }
}

Handling Tool Call Responses

After executing the function locally, clients return results using the standard tool role format:

POST /v1beta/models/gemini-1.5-flash:generateContent
{
  "contents": [
    { "role": "assistant", "parts": [] },
    { "role": "tool", "tool_call_id": "call_0_0", "name": "get_weather", "content": "{\"temp\":15,\"unit\":\"C\"}" }
  ]
}

FreeLLMAPI's geminiResponseFromResult processes this input and constructs the final assistant message incorporating the tool output.

Using Google Search Grounding

To enable live search capabilities, specify the reserved tool name:

{
  "tools": [
    { "type": "function", "function": { "name": "google_search", "description": "Search the web", "parameters": {} } }
  ],
  "contents": [{ "role": "user", "parts": [{ "text": "Who won the Nobel Peace Prize in 2023?" }] }]
}

The router detects google_search and activates Gemini's native grounding tool, returning search-augmented responses through the standard translation pipeline.

Core Files and Functions

The following files contain the complete implementation for FreeLLMAPI Google Gemini tool calls:

  • server/src/lib/gemini-wire.ts – Contains the core translation helpers including geminiToolsToChatTools, geminiToolChoice, geminiResponseFormat, geminiPartsFromResult, geminiResponseFromResult, and geminiFinishReason.

  • server/src/routes/gemini.ts – Implements the Express router (geminiRouter) that receives OpenAI-style requests, invokes translation helpers, forwards to Gemini endpoints, and returns normalized responses.

  • docs/api.md – Documents API usage patterns including the special Google Search grounding tool configuration.

  • docs/architecture.md – Provides high-level overview of cross-provider request routing and model-specific feature handling.

Summary

  • Bidirectional translation occurs through specialized helpers in server/src/lib/gemini-wire.ts that map OpenAI tool schemas to Gemini functionDeclarations and back.

  • Request normalization handles tools arrays, tool_choice configurations, and response_format requirements, converting them to Gemini-compatible parameters before API execution.

  • Response standardization extracts function calls from Gemini's native format and reconstructs OpenAI-compatible tool_calls arrays with proper finish_reason mapping.

  • Google Search grounding is supported via a reserved google_search tool name that triggers Gemini's native web search capabilities while maintaining OpenAI API compatibility.

  • Streaming support extends to tool calls through the streamGenerateContent endpoint, with translation applied to chunked responses.

Frequently Asked Questions

What file contains the core translation logic for Gemini tool calls?

The translation logic resides in server/src/lib/gemini-wire.ts, which exports functions like geminiToolsToChatTools (lines 92-102) for converting OpenAI tool definitions to Gemini format and geminiResponseFromResult (lines 97-101) for packaging responses. This file handles all schema transformations between the two API formats.

How does FreeLLMAPI handle the tool_choice parameter from OpenAI requests?

FreeLLMAPI processes tool_choice through the geminiToolChoice function (lines 13-25 in server/src/lib/gemini-wire.ts), which maps OpenAI's function_calling_config modes—such as auto, any, or specific function names—to Gemini's functionCallingConfig structure, ensuring consistent tool selection behavior across providers.

Can I use Gemini's native Google Search grounding through FreeLLMAPI?

Yes, FreeLLMAPI supports Gemini's grounding tool by detecting a tool named google_search in the request and translating it to Gemini's proprietary grounding implementation. This allows models to incorporate live search results while maintaining standard OpenAI-compatible request and response formats.

What finish reasons are supported when using Gemini tool calls?

FreeLLMAPI maps Gemini's native finish reasons to OpenAI-compatible values through the geminiFinishReason helper. Common mappings include converting Gemini's STOP to OpenAI's stop, and function call terminations to tool_calls, ensuring consistent status reporting for conversation flow control.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →