# How DS2API Handles Gemini API Compatibility with Function Declarations

> DS2API ensures Gemini API compatibility with function declarations by normalizing them into OpenAI tools. Learn how this process preserves schema integrity for seamless integration.

- Repository: [CJACK./ds2api](https://github.com/CJackHwang/ds2api)
- Tags: internals
- Published: 2026-04-26

---

**DS2API translates Gemini's native `functionDeclarations` into OpenAI-compatible function tools through a three-step normalization process that preserves schema integrity while enabling seamless integration with DeepSeek WebUI.**

DS2API bridges Google Gemini's tool-calling capabilities and OpenAI's function schema by treating `functionDeclarations` as a specialized tool definition. This translation layer allows developers to send native Gemini API requests containing function declarations while the underlying system communicates with DeepSeek using OpenAI-style tool definitions. The conversion logic resides in the `CJackHwang/ds2api` repository's Gemini HTTP adapter, ensuring that Gemini-specific syntax never reaches the downstream processing pipeline.

## How DS2API Normalizes Incoming Gemini Requests

When a Gemini-formatted request arrives at DS2API's HTTP adapter, the system first invokes `normalizeGeminiRequest` to prepare the payload for internal processing. This function extracts the raw `tools` field from the incoming JSON and routes it through `convertGeminiTools` to handle schema transformation.

You can see this orchestration at line 31 in [`internal/httpapi/gemini/convert_request.go`](https://github.com/CJackHwang/ds2api/blob/main/internal/httpapi/gemini/convert_request.go), where the normalization engine delegates tool-specific conversion before the request proceeds to prompt building.

## Converting functionDeclarations to OpenAI-Compatible Tools

The core translation logic lives in `convertGeminiTools` within [`internal/httpapi/gemini/convert_tools.go`](https://github.com/CJackHwang/ds2api/blob/main/internal/httpapi/gemini/convert_tools.go) (lines 5-71). This function iterates through the Gemini tools array and inspects each object for the presence of a `functionDeclarations` field.

### Processing functionDeclarations Arrays

When `convertGeminiTools` encounters a `functionDeclarations` array, it extracts each declaration and maps it to an OpenAI function tool structure. The transformation preserves the `name`, optional `description`, and raw `parameters` object verbatim, wrapping them in a tool object with `"type": "function"`.

This occurs specifically in lines 18-40 of [`convert_tools.go`](https://github.com/CJackHwang/ds2api/blob/main/convert_tools.go), where the function constructs the standardized tool definition that `promptcompat.BuildOpenAIPromptForAdapter` expects later in the pipeline.

### Fallback Compatibility Modes

If no `functionDeclarations` are present, `convertGeminiTools` employs two fallback strategies to maximize compatibility:

- **Direct passthrough**: If the input already contains an OpenAI-style `"function"` object, it passes through unchanged.
- **Loose fallback**: Flat objects containing `name`, `description`, and `parameters` keys are automatically wrapped as function-type tools.

These fallbacks ensure that partial or alternative tool schemas still route correctly through the DeepSeek-bound pipeline.

## Code Example: Gemini to OpenAI Tool Transformation

Consider a client sending a Gemini-native request with a JavaScript execution function:

```json
{
  "model": "gemini-1.5-pro",
  "messages": [{ "role": "user", "content": "Run JavaScript:" }],
  "tools": [
    {
      "functionDeclarations": [
        {
          "name": "eval_javascript",
          "description": "Executes a short JS snippet",
          "parameters": {
            "type": "object",
            "properties": {
              "code": { "type": "string" }
            }
          }
        }
      ]
    }
  ]
}

```

After processing through `convertGeminiTools`, the internal representation becomes:

```json
{
  "model": "gemini-1.5-pro",
  "messages": [{ "role": "user", "content": "Run JavaScript:" }],
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "eval_javascript",
        "description": "Executes a short JS snippet",
        "parameters": {
          "type": "object",
          "properties": {
            "code": { "type": "string" }
          }
        }
      }
    }
  ]
}

```

This transformation occurs automatically before the request reaches [`internal/promptcompat/prompt_build.go`](https://github.com/CJackHwang/ds2api/blob/main/internal/promptcompat/prompt_build.go), which generates the final OpenAI-style payload for DeepSeek consumption.

## Key Source Files in the Conversion Pipeline

Several components cooperate to maintain **DS2API Gemini API compatibility with function declarations**:

- **[`internal/httpapi/gemini/convert_tools.go`](https://github.com/CJackHwang/ds2api/blob/main/internal/httpapi/gemini/convert_tools.go)**: Implements `convertGeminiTools`, the primary translator that handles Gemini-specific `functionDeclarations` and fallback modes (lines 5-71).

- **[`internal/httpapi/gemini/convert_request.go`](https://github.com/CJackHwang/ds2api/blob/main/internal/httpapi/gemini/convert_request.go)**: Orchestrates the conversion by calling `convertGeminiTools` during the normalization phase (line 31).

- **[`internal/promptcompat/prompt_build.go`](https://github.com/CJackHwang/ds2api/blob/main/internal/promptcompat/prompt_build.go)**: Consumes the normalized tools to construct OpenAI-format prompts for the DeepSeek backend.

- **[`docs/prompt-compatibility.md`](https://github.com/CJackHwang/ds2api/blob/main/docs/prompt-compatibility.md)**: Documents the architectural decision to map Gemini function declarations to OpenAI function tools and notes the reuse of the OpenAI prompt builder for Gemini adapters (lines 65-100).

## Summary

- DS2API treats Gemini `functionDeclarations` as a specialized tool category requiring translation to OpenAI's function schema.
- The `convertGeminiTools` function in [`convert_tools.go`](https://github.com/CJackHwang/ds2api/blob/main/convert_tools.go) (lines 5-71) performs the core transformation, preserving function names, descriptions, and parameter schemas.
- [`convert_request.go`](https://github.com/CJackHwang/ds2api/blob/main/convert_request.go) triggers this conversion at line 31 during request normalization.
- Fallback modes handle existing OpenAI-style tools and loose object structures without explicit type declarations.
- The converted tools integrate seamlessly with `promptcompat.BuildOpenAIPromptForAdapter`, enabling DeepSeek WebUI compatibility.

## Frequently Asked Questions

### Where does the actual conversion from Gemini to OpenAI format happen?

The transformation occurs in [`internal/httpapi/gemini/convert_tools.go`](https://github.com/CJackHwang/ds2api/blob/main/internal/httpapi/gemini/convert_tools.go) within the `convertGeminiTools` function (lines 5-71), which is invoked by `normalizeGeminiRequest` in [`convert_request.go`](https://github.com/CJackHwang/ds2api/blob/main/convert_request.go) at line 31.

### Is the parameter schema modified during conversion to OpenAI format?

No. DS2API copies the `parameters` object verbatim from the Gemini declaration to the OpenAI function definition, preserving the original JSON Schema structure without transformation or validation.

### Can I mix Gemini function declarations with OpenAI-style tools in the same request?

Yes. The fallback logic in `convertGeminiTools` detects existing OpenAI-format `"function"` objects and passes them through unchanged, allowing heterogeneous tool definitions to coexist in the same request payload.

### What happens if functionDeclarations are missing from the Gemini request?

When `functionDeclarations` arrays are absent, `convertGeminiTools` falls back to two compatibility modes: it passes through existing OpenAI-style `"function"` objects directly, or wraps flat objects containing `name`, `description`, and `parameters` as function tools, ensuring non-Gemini tool formats still route correctly.