# How the OmniRoute Translator Converts Between OpenAI, Anthropic, and Gemini API Formats

> OmniRoute's translator normalizes API requests and responses between OpenAI, Anthropic, and Gemini formats. Discover how this bidirectional layer streamlines LM integration.

- Repository: [Diego Rodrigues de Sa e Souza/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- Tags: deep-dive
- Published: 2026-07-30

---

**The OmniRoute translator functions as a bidirectional normalization layer that converts API requests and responses between OpenAI-compatible, Anthropic (Claude), and Google Gemini formats using registry-based dispatch and provider-specific adapters.**

The `diegosouzapw/OmniRoute` repository implements this translation layer within the `open-sse/translator` package to isolate provider-specific API differences from the core routing logic. By normalizing payloads to a canonical OpenAI-style schema before routing and converting responses back to the same format, the system enables seamless interaction with heterogeneous large language model providers through a single unified endpoint.

## Core Architecture and Entry Points

The translation system exposes two primary functions in [`open-sse/translator/index.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/translator/index.ts): `translateRequest` for outbound conversion and `translateResponse` for inbound normalization [lines 49-52](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/translator/index.ts#L49-L52). These functions consult [`open-sse/translator/registry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/translator/registry.ts) to dispatch payloads to the appropriate source-to-target adapter pair.

### Request Normalization Pipeline

Before provider-specific conversion, every request undergoes normalization in [`open-sse/translator/index.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/translator/index.ts):

- **Thinking budget enforcement**: The `applyThinkingBudget` filter from [`open-sse/services/thinkingBudget.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/services/thinkingBudget.ts) enforces token limits for reasoning models.
- **Role mapping**: `normalizeRoles` in [`open-sse/services/roleNormalizer.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/services/roleNormalizer.ts) converts non-standard roles such as `developer` to provider-compatible equivalents like `system`.
- **Tool-call sanitization**: [`open-sse/translator/helpers/toolCallHelper.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/translator/helpers/toolCallHelper.ts) normalizes tool-call IDs, strips orphaned results, and inserts missing tool-result placeholders to maintain conversation integrity.

## Provider-Specific Translation Workflows

### OpenAI to Gemini Request Conversion

The [`open-sse/translator/request/openai-to-gemini.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/translator/request/openai-to-gemini.ts) module handles conversion to Google's Gemini format. It restructures the OpenAI `messages` array into Gemini's `content` blocks and elevates system messages to the `system_instruction` field. Helper utilities in [`open-sse/translator/helpers/geminiHelper.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/translator/helpers/geminiHelper.ts) manage image data encoding and multimodal content mapping.

```typescript
import { translateRequest } from '@/open-sse/translator';

const openAIPayload = {
  model: 'gpt-4o-mini',
  messages: [
    { role: 'system', content: 'You are a helpful assistant.' },
    { role: 'user', content: 'Explain neural networks.' }
  ],
  temperature: 0.7
};

const geminiPayload = translateRequest(
  'openai',
  'gemini',
  'gemini-pro',
  openAIPayload,
  false
);

```

The resulting payload conforms to Gemini's schema, with the system instruction properly separated from the content array.

### OpenAI to Anthropic (Claude) Request Conversion

When targeting Anthropic models, [`open-sse/translator/request/openai-to-claude.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/translator/request/openai-to-claude.ts) utilizes [`open-sse/translator/helpers/claudeHelper.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/translator/helpers/claudeHelper.ts) to merge system-role messages into Claude's top-level `system` parameter. It reformats tool calls according to Claude's `tool` schema and sets the required `tool_choice` field while ensuring the `assistant` role is correctly mapped for conversation continuity.

```typescript
import { translateRequest } from '@/open-sse/translator';

const request = {
  model: 'claude-3-5-sonnet-20240620',
  messages: [{ role: 'user', content: 'Weather in Paris?' }],
  tool_calls: [{
    id: 'tc_1',
    type: 'function',
    function: { name: 'weather', arguments: '{}' }
  }]
};

const claudePayload = translateRequest(
  'openai',
  'anthropic',
  'claude-3-5-sonnet-20240620',
  request,
  false
);

```

### Gemini to OpenAI Response Conversion

For reverse translation, [`open-sse/translator/response/gemini-to-openai.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/translator/response/gemini-to-openai.ts) extracts Gemini's `content` blocks and reconstructs them as OpenAI-compatible message objects. This includes restoring tool-call results, standardizing finish reasons, and handling provider-specific cache-control headers through the `providerHonorsOpenAIFormatCacheControl` flag.

## Streaming and Advanced Features

The translator supports Server-Sent Events (SSE) through dedicated stream handlers such as [`openai-to-gemini-sse.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/openai-to-gemini-sse.ts), which processes incremental content from providers and reformats it into OpenAI-compatible SSE chunks in real-time. For models requiring cached reasoning content—such as DeepSeek V4 or Xiaomi MiMo—the system implements replay-cache mechanisms that preserve reasoning chains across the translation boundary.

## Key Source Files

| File | Purpose | Source |
|------|---------|--------|
| [`open-sse/translator/index.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/translator/index.ts) | Entry points `translateRequest` and `translateResponse`, normalization pipeline | [View](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/translator/index.ts) |
| [`open-sse/translator/registry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/translator/registry.ts) | Translator pair registration and dispatch logic | [View](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/translator/registry.ts) |
| [`open-sse/translator/request/openai-to-gemini.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/translator/request/openai-to-gemini.ts) | OpenAI → Gemini request transformation | [View](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/translator/request/openai-to-gemini.ts) |
| [`open-sse/translator/request/openai-to-claude.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/translator/request/openai-to-claude.ts) | OpenAI → Anthropic request adaptation | [View](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/translator/request/openai-to-claude.ts) |
| [`open-sse/translator/response/gemini-to-openai.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/translator/response/gemini-to-openai.ts) | Gemini → OpenAI response normalization | [View](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/translator/response/gemini-to-openai.ts) |
| [`open-sse/translator/helpers/toolCallHelper.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/translator/helpers/toolCallHelper.ts) | Tool-call ID normalization and placeholder insertion | [View](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/translator/helpers/toolCallHelper.ts) |
| [`open-sse/services/roleNormalizer.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/services/roleNormalizer.ts) | Role name mapping across providers | [View](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/services/roleNormalizer.ts) |
| [`open-sse/services/thinkingBudget.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/services/thinkingBudget.ts) | Token budget enforcement pre-translation | [View](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/services/thinkingBudget.ts) |

## Summary

- The **OmniRoute translator** acts as a bidirectional conversion layer, enabling the `diegosouzapw/OmniRoute` system to route requests between OpenAI, Anthropic, and Gemini formats using `translateRequest` and `translateResponse` in [`open-sse/translator/index.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/translator/index.ts).
- **Normalization** occurs before translation via [`thinkingBudget.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/thinkingBudget.ts), [`roleNormalizer.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/roleNormalizer.ts), and [`toolCallHelper.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/toolCallHelper.ts), handling token limits, role mappings, and tool-call sanitization.
- **Provider-specific adapters** in `open-sse/translator/request/` convert OpenAI-formatted payloads to Gemini and Claude schemas, while response handlers in `open-sse/translator/response/` convert back to OpenAI format.
- **Streaming support** is implemented through SSE-specific translators that maintain real-time compatibility across provider protocols.
- The architecture respects provider-specific features such as `providerHonorsOpenAIFormatCacheControl` and reasoning content replay for supported models.

## Frequently Asked Questions

### What is the primary function of the translator in OmniRoute?

The translator functions as a bidirectional API normalization layer that converts requests and responses between OpenAI-compatible formats and provider-specific implementations like Anthropic's Claude or Google Gemini. According to the `diegosouzapw/OmniRoute` source code, this allows the system to expose a unified OpenAI-style endpoint while routing to diverse backend models.

### How does OmniRoute convert tool calls between different provider formats?

OmniRoute normalizes tool calls through [`open-sse/translator/helpers/toolCallHelper.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/translator/helpers/toolCallHelper.ts), which standardizes tool-call IDs and injects missing result placeholders. Provider-specific translators—such as [`openai-to-claude.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/openai-to-claude.ts) for Anthropic and [`openai-to-gemini.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/openai-to-gemini.ts) for Gemini—then restructure these calls into the target API's expected schema, whether that involves Claude's `tool` blocks or Gemini's function calling format.

### Does OmniRoute support streaming responses when translating between formats?

Yes, the translator implements dedicated SSE handlers that process streaming responses in real-time. For example, [`openai-to-gemini-sse.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/openai-to-gemini-sse.ts) converts Gemini's incremental generation patterns into OpenAI-compatible Server-Sent Events chunks, ensuring low-latency streaming regardless of the upstream provider's native protocol.

### Where is the translation logic implemented in the OmniRoute codebase?

All translation logic resides within the `open-sse/translator` directory. Entry points live in [`index.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/index.ts), registry mappings in [`registry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/registry.ts), provider-specific request handlers in `request/`, response handlers in `response/`, and shared utilities in `helpers/`. Supporting services for budget enforcement and role normalization are located in `open-sse/services/`.