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

> Discover how FreeLLMAPI translates OpenAI tool calls to Google Gemini functionDeclarations and back. Integrate Gemini's capabilities with your existing OpenAI tools seamlessly via a unified API.

- Repository: [Tashfeen/freellmapi](https://github.com/tashfeenahmed/freellmapi)
- Tags: deep-dive
- Published: 2026-08-27

---

**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`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/lib/gemini-wire.ts) and orchestrated by the `geminiRouter` in [`server/src/routes/gemini.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/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`](https://github.com/tashfeenahmed/freellmapi/blob/main/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`](https://github.com/tashfeenahmed/freellmapi/blob/main/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`](https://github.com/tashfeenahmed/freellmapi/blob/main/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:

```json
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:

```json
{
  "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:

```json
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:

```json
{
  "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`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/lib/gemini-wire.ts)** – Contains the core translation helpers including `geminiToolsToChatTools`, `geminiToolChoice`, `geminiResponseFormat`, `geminiPartsFromResult`, `geminiResponseFromResult`, and `geminiFinishReason`.

- **[`server/src/routes/gemini.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/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`](https://github.com/tashfeenahmed/freellmapi/blob/main/docs/api.md)** – Documents API usage patterns including the special Google Search grounding tool configuration.

- **[`docs/architecture.md`](https://github.com/tashfeenahmed/freellmapi/blob/main/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`](https://github.com/tashfeenahmed/freellmapi/blob/main/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`](https://github.com/tashfeenahmed/freellmapi/blob/main/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`](https://github.com/tashfeenahmed/freellmapi/blob/main/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.