What Is the Role of the Translator Module in OmniRoute? Core Architecture and Translation Flow

The translator module in OmniRoute acts as the central hub-and-spoke conversion layer that transforms request and response payloads between over 350 heterogeneous LLM provider formats, normalizing all traffic through a canonical OpenAI-compatible schema.

The OmniRoute repository (diegosouzapw/OmniRoute) provides a universal routing layer for large language model APIs. At its core, the translator module located in open-sse/translator/ abstracts away provider-specific payload differences, enabling seamless interoperability between Claude, Gemini, OpenAI, and hundreds of other providers without requiring client-side changes. This component handles schema conversion, tool-call normalization, and reasoning replay across disparate API specifications.

Core Translation Functions

The translation pipeline centers on two primary orchestration functions exported from open-sse/translator/index.ts. These functions manage the bidirectional flow of data between client expectations and provider requirements.

Request Normalization with translateRequest

Every incoming chat or completions request first passes through translateRequest, implemented at source lines 7‑90. This function receives the source format (e.g., Claude, Gemini, OpenAI-Responses) and the target format required by the downstream provider, then applies a series of critical normalizations:

  • Thinking-budget enforcement and reasoning-routing directives
  • Role normalization to ensure consistent system/user/assistant mappings
  • Tool-call ID handling, including missing tool-response insertion and orphaned-tool filtering
  • Provider-specific quirks, such as inserting synthetic user turns for GLM-family models or preserving cache-control markers for providers that honor them

Response Conversion with translateResponse

After the provider returns a response chunk, translateResponse (source lines 93‑108) performs the inverse mapping. The function first attempts to find a direct translator from the target format back to the source format (e.g., Gemini → Claude). If no direct path exists, it falls back to the hub-and-spoke model, routing through the OpenAI format as an intermediate canonical representation.

Reasoning Replay and Caching

For models that require a reasoning_content field on replay turns—including DeepSeek, Kimi, and Xiaomi-Mimo—the translator injects cached reasoning or placeholder content to prevent upstream API rejection. This reasoning replay logic is handled in the dedicated caching block at source lines 390‑420 of the main index file. The module maintains state across streaming chunks to ensure that reasoning traces remain consistent throughout multi-turn conversations.

The Translator Registry Architecture

Rather than hardcoding format mappings, the module delegates actual conversion logic to a dynamic registry of specialized translator functions. The bootstrapTranslatorRegistry function (source lines 24‑26) populates this registry on module initialization by scanning:

  • open-sse/translator/request/ – Contains individual request translators such as openai-to-gemini.ts and openai-to-claude.ts
  • open-sse/translator/response/ – Houses response translators like gemini-to-openai.ts
  • open-sse/translator/helpers/ – Utility modules for tool-call handling, role normalization, and provider-specific edge cases

This registry pattern allows OmniRoute to support new providers by simply adding new translator files without modifying the core orchestration logic.

Implementation Examples

The following examples demonstrate converting between Claude and Gemini formats using the translator module's public API.

Converting Claude Requests to Gemini Format

When a client submits a request in Claude format but the route selects a Gemini provider, use translateRequest to normalize the payload:

import { translateRequest, FORMATS } from '@/open-sse/translator';

// Client payload in Claude format
const claudePayload = { 
  messages: [{ role: 'user', content: 'Hello' }],
  max_tokens: 1024 
};

// Convert Claude → Gemini (target format)
const translated = translateRequest(
  FORMATS.CLAUDE,        // sourceFormat
  FORMATS.GEMINI,        // targetFormat
  'gemini-1.5-flash',    // model
  claudePayload,
  true,                  // stream
  null,                  // credentials
  'gemini',              // provider
  null,                  // logger
  { preserveCacheControl: true }
);

// translated.body now contains Gemini-compatible JSON

Mapping Gemini Responses Back to Claude

After receiving chunks from the Gemini executor, convert them back to the client's expected Claude format:

import { translateResponse, FORMATS } from '@/open-sse/translator';

// Chunk received from Gemini executor
const geminiChunk = { 
  candidates: [{ content: { parts: [{ text: 'Hi there' }] } }] 
};

// Convert Gemini → Claude (sourceFormat = GEMINI, targetFormat = CLAUDE)
const clientChunks = translateResponse(
  FORMATS.CLAUDE,
  FORMATS.GEMINI,
  geminiChunk,
  {}                     // streaming state object
);

// clientChunks contains Claude-compatible SSE events

Key Source Files

The translator module spans several coordinated files within the open-sse/translator/ directory:

  • index.ts – Central orchestration containing translateRequest and translateResponse logic
  • registry.ts – Maintains the mapping of source-to-target translator functions
  • bootstrap.ts – Initializes the translator registry on module load
  • request/*.ts – Provider-specific request normalization (e.g., openai-to-gemini.ts)
  • response/*.ts – Response format converters (e.g., gemini-to-openai.ts)
  • helpers/*.ts – Shared utilities for tool-call ID management and reasoning replay

Summary

  • The translator module in OmniRoute serves as the central hub-and-spoke conversion layer between 350+ LLM provider formats.
  • translateRequest normalizes incoming payloads to a canonical OpenAI-compatible shape while applying provider-specific adjustments like GLM synthetic turns and cache-control preservation.
  • translateResponse reverses the mapping, falling back to OpenAI format as an intermediate when direct translators are unavailable.
  • Reasoning replay logic at lines 390‑420 handles reasoning_content requirements for DeepSeek, Kimi, and similar models.
  • The registry architecture in bootstrap.ts enables modular expansion without core code changes.

Frequently Asked Questions

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

The translator module acts as a bidirectional conversion layer that transforms requests and responses between disparate LLM provider formats. It ensures that a client using Claude-style requests can communicate with a Gemini backend (or vice versa) by normalizing all traffic through an OpenAI-compatible canonical schema.

How does OmniRoute handle provider-specific API quirks?

Within translateRequest, the module applies targeted normalizations for individual providers. For example, it inserts synthetic user turns for GLM-family models and preserves cache-control markers only for providers that explicitly support them. These adjustments occur at the normalization stage before the request reaches the executor.

What is the hub-and-spoke translation model?

The hub-and-spoke model uses OpenAI's request/response format as a central "hub." When no direct translator exists between the source and target formats (e.g., Claude → Gemini), the system first converts to OpenAI format, then to the target format. This minimizes the number of required translators from O(n²) to O(n) while maintaining compatibility across all supported providers.

Where is the reasoning replay logic implemented?

The reasoning replay and caching logic is implemented in open-sse/translator/index.ts at source lines 390‑420. This section handles the injection of cached reasoning_content fields for models like DeepSeek and Kimi that require reasoning traces on replay turns to avoid API rejection.

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 →