How WorkWeave Router Handles Translation Between Different API Formats

WorkWeave Router uses a dedicated internal/translate package to convert OpenAI-compatible chat requests into provider-specific formats and back, ensuring clients always receive a unified OpenAI-style response regardless of the upstream LLM service.

The WorkWeave Router acts as an intelligent gateway that normalizes heterogeneous LLM provider APIs behind a single OpenAI-compatible interface. Understanding its translation between different API formats requires examining the internal/translate package, which encapsulates all provider-specific conversion logic without performing any I/O operations.

The Translation Architecture

The router positions itself between clients speaking the OpenAI /v1/chat/completions protocol and diverse upstream providers including Anthropic, Google Gemini, and OpenAI-compatible services. The internal/translate package serves as the inner-ring translation layer, converting inbound requests to native provider formats and transforming responses back to the canonical OpenAI schema.

This architecture ensures that streaming deltas, tool calls, usage headers, and finish reasons appear consistent to clients even when upstream services use incompatible data structures or Server-Sent Events (SSE) formats.

Core Translation Pipeline

The translation process follows a strict pipeline that sanitizes, validates, and converts data before it reaches the proxy layer.

Request Normalization with Strictify

Before any provider-specific logic executes, the strictify_openai.go module enforces the OpenAI schema on incoming payloads. This sanitization step validates required fields, restricts enum values, and prevents malformed JSON from propagating downstream to provider adapters.

// internal/translate/strictify_openai.go
// Enforces strict OpenAI schema compliance on inbound requests
func StrictifyRequest(req *OpenAIChatRequest) error {
    // Validation logic ensures schema compliance
}

Tool Call Validation

The toolcheck/toolcheck.go subsystem validates function signatures and JSON argument schemas before translation. This provider-agnostic validation layer ensures that tool specifications will execute correctly on the target platform, rewriting them into normalized representations that individual provider adapters can consume safely.

// internal/translate/toolcheck/toolcheck.go
func ValidateTools(tools []openai.Tool) error {
    // Ensure each tool's JSON schema is well-formed,
    // rewrite into a provider-agnostic representation.
}

Provider-Specific Adapters

The central dispatcher in translate.go routes normalized requests to provider-specific implementations. Each adapter implements the Translator interface and handles the final shape adjustments required by the target service.

// internal/translate/translate.go – core entry point
func TranslateRequest(req openai.ChatRequest, p providers.Provider) (
    any,               // provider-specific request payload
    Translator,        // object that knows how to decode responses
    error,
) {
    switch p {
    case providers.ProviderAnthropic:
        return translateAnthropic(req)
    case providers.ProviderGoogle:
        return translateGemini(req)
    // …other providers…
    default:
        return nil, nil, fmt.Errorf("unsupported provider %s", p)
    }
}

Specialized files like anthropic_marker.go and anthropic_footer.go handle provider-specific quirks such as Anthropic's SSE marker lines or Gemini response footers, ensuring these implementation details never leak into the client-facing API.

Response Stream Conversion

For streaming completions, stream.go rewrites provider-specific delta formats into OpenAI-compatible "choices" arrays. The implementation preserves ordering, index values, and finish reasons while abstracting away differences in how Anthropic, Google, or other services chunk their SSE data.

// internal/translate/stream.go – converts provider stream chunks
func (t *anthropicTranslator) StreamChunk(chunk []byte) (openai.StreamDelta, error) {
    // Decode Anthropic-style chunk, map fields to OpenAI delta format
    // – e.g., content → delta.content, role → delta.role, etc.
}

Billing and Metadata Translation

The billing_header.go and available_tools.go modules translate provider-specific usage metrics and cost information into the OpenAI-style usage block. This ensures that client applications can monitor token consumption and tool availability through a consistent interface regardless of the upstream provider's native headers.

Implementing the Translation Layer

Integration occurs at the HTTP handler level, where the router unmarshals client JSON and invokes the translation pipeline before proxying requests.

Handler Integration

In internal/api/openai/handler.go, the router binds incoming JSON to an OpenAIChatRequest struct, selects the appropriate provider based on routing logic, and delegates conversion to the translate package:

// internal/api/openai/handler.go (simplified)
func handleChatCompletion(c *gin.Context) {
    var openaiReq openai.ChatRequest
    if err := c.BindJSON(&openaiReq); err != nil {
        // …handle error…
    }

    // Choose provider (e.g. Anthropic) based on routing logic
    provider := providers.ProviderAnthropic

    // Translate request → provider-specific payload
    transReq, translator, err := translate.TranslateRequest(openaiReq, provider)
    if err != nil {
        // …handle translation error…
    }

    // Dispatch via proxy.Service (I/O layer)
    respStream, err := proxySvc.Send(provider, transReq, translator)
    // …
}

The proxy service receives both the translated request payload and the Translator implementation, using the latter to convert responses back to OpenAI format before writing them to the client connection.

Extensibility and Design Principles

The translation layer follows three core design principles that facilitate maintenance and provider expansion:

  • I/O-Free Architecture: The internal/translate package contains pure Go code with no network operations, enabling comprehensive unit testing without mocking HTTP clients.
  • Interface-Based Adapters: New providers require only a small adapter implementing the Translator interface; the core pipeline in translate.go remains unchanged.
  • Schema Consistency: All outbound responses conform to the OpenAI specification, allowing the router to evolve upstream support without breaking the public API contract.

Summary

  • The internal/translate package provides bidirectional conversion between OpenAI-compatible formats and diverse LLM provider APIs.
  • Strictify modules enforce schema compliance before provider-specific translation occurs.
  • The Translator interface abstracts provider differences, implemented via dedicated adapters for Anthropic, Gemini, and other services.
  • Stream conversion in stream.go normalizes real-time responses into OpenAI delta format while preserving metadata integrity.
  • Tool validation occurs before translation to ensure function-calling compatibility across heterogeneous backends.
  • Billing and usage data normalize into OpenAI-style headers through billing_header.go.

Frequently Asked Questions

How does WorkWeave Router standardize responses from multiple LLM providers?

The router instantiates a provider-specific Translator implementation returned by TranslateRequest() in internal/translate/translate.go. This translator converts native response formats—including streaming chunks—into the OpenAI ChatCompletion schema before the HTTP handler writes data to the client, ensuring consistent field names, structures, and semantic meaning across all supported backends.

What is the role of the Translator interface in the WorkWeave Router architecture?

The Translator interface defines methods for converting provider-native responses and streaming chunks into OpenAI-compatible structures. Located in the internal/translate package, this interface allows the proxy service to remain provider-agnostic; it simply calls translator methods on response data without knowing whether the upstream service was Anthropic, Google, or another OpenAI-compatible endpoint.

How does WorkWeave Router handle streaming responses from different API formats?

The stream.go implementation, accessed through the Translator interface, rewrites provider-specific Server-Sent Events into OpenAI-style "delta" objects. For example, the anthropicTranslator.StreamChunk() method maps Anthropic's content fields to OpenAI's delta.content and delta.role fields, preserving ordering and finish reasons while hiding protocol differences from the client.

Why does the router validate tool calls before translation?

Validation in internal/translate/toolcheck/toolcheck.go occurs before provider-specific conversion to catch malformed JSON schemas or invalid function signatures early in the pipeline. This prevents errors from reaching upstream providers, reduces latency for invalid requests, and allows the router to normalize tool definitions into a provider-agnostic representation that any adapter can consume safely.

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 →