# How Headroom Handles Mixed Content by Splitting and Routing Different Sections

> Discover how Headroom effectively handles mixed content by automatically splitting payloads into homogeneous sections, converting them to canonical OpenAI format, and routing them via gateways.

- Repository: [Tejas Chopra/headroom](https://github.com/chopratejas/headroom)
- Tags: how-to-guide
- Published: 2026-06-07

---

**Headroom automatically detects mixed-content payloads, splits them into homogeneous sections based on provider-specific schemas, converts each section to a canonical OpenAI format, and routes them through configured gateways.**

Headroom is an open-source proxy and SDK developed by `chopratejas/headroom` that normalizes disparate AI provider formats into a unified pipeline. When your application receives payloads containing mixed content from OpenAI, Anthropic, Vercel AI SDK, or Google Gemini, Headroom handles mixed content by splitting and routing different sections without requiring manual preprocessing.

## Detecting Provider Formats

Headroom identifies the source provider by scanning message arrays for **structural markers** unique to each schema. In [`sdk/typescript/src/utils/format.ts`](https://github.com/chopratejas/headroom/blob/main/sdk/typescript/src/utils/format.ts) (lines 24‑33), the `detectFormat` function examines keys such as `parts` versus `content`, or hyphenated `tool-call` versus underscored `tool_use`, to determine whether the payload originates from Anthropic, Vercel, Gemini, or OpenAI.

This detection is deterministic—no heuristic guessing occurs. The presence of a unique schema key immediately categorizes the entire message block, allowing Headroom to select the appropriate conversion routine.

```typescript
import { detectFormat } from "headroom/sdk/typescript/src/utils/format";

const fmt = detectFormat(mixedMessages);
console.log(`Detected format: ${fmt}`);   // → "anthropic"

```

## Splitting Content into Homogeneous Sections

Once the format is identified, Headroom groups consecutive messages that share the same **role** and **content-type** into discrete sections. For raw text streams, the generic helper in [`sdk/typescript/src/utils/stream.ts`](https://github.com/chopratejas/headroom/blob/main/sdk/typescript/src/utils/stream.ts) (line 21) uses `.split("\n")` to segment lines, while structured message arrays are processed by the conversion functions themselves, which expect uniform input arrays.

This splitting ensures that each section is internally consistent—contiguous blocks of user text, assistant responses, or tool calls from a single provider—before transformation begins.

## Converting and Routing Sections

After splitting, each homogeneous section is transformed into Headroom’s canonical **OpenAI schema**, then routed according to your gateway configuration.

### Provider-Specific Converters

Located in [`sdk/typescript/src/utils/format.ts`](https://github.com/chopratejas/headroom/blob/main/sdk/typescript/src/utils/format.ts) starting at line 74, dedicated converters handle the translation:

- **`anthropicToOpenAI`** – Transforms Anthropic text and tool blocks into OpenAI `assistant` messages with `tool_calls`.
- **`openAIToAnthropic`** – Performs the reverse conversion for responses.
- **Vercel and Gemini converters** – Follow the same pattern for their respective schemas.

```typescript
import { anthropicToOpenAI } from "headroom/sdk/typescript/src/utils/format";

const openaiMsgs = anthropicToOpenAI(anthropicMessages);

```

### Gateway Routing Logic

The converted OpenAI-shaped messages are handed to `HeadroomClient.compress` or `HeadroomClient.send`. The **OpenClaw plugin** then determines routing via `routeBaseUrlThroughProxy` in [`plugins/openclaw/src/gateway-config.ts`](https://github.com/chopratejas/headroom/blob/main/plugins/openclaw/src/gateway-config.ts) (lines 24‑31 and 99‑123). This function rewrites the base URL for selected providers when configuration flags such as `routeCodexViaProxy` are enabled.

```typescript
import { routeBaseUrlThroughProxy } from "headroom/plugins/openclaw/src/gateway-config";

const newBase = routeBaseUrlThroughProxy({
  baseUrl: "https://api.openai.com/v1",
  gatewayProviderIds: ["codex"],
  activeProxyUrl: "https://my-proxy.example.com",
  routeCodexViaProxy: true,
});
console.log(newBase);   // "https://my-proxy.example.com/v1"

```

## Shared Context Storage

When sections require **shared-context** persistence, [`sdk/typescript/src/shared-context.ts`](https://github.com/chopratejas/headroom/blob/main/sdk/typescript/src/shared-context.ts) provides compression and storage utilities. The `SharedContext.put` method compresses text via the proxy’s `compress` endpoint, stores the blob keyed by a hash, and automatically evicts expired entries using `evictExpired` and `evictIfFull` methods that respect TTL constraints.

```typescript
await sharedContext.put(
  "doc-section-1",
  "Long documentation text …",
  { agent: "doc-generator" }
);

```

## Summary

- **Structural detection** scans for unique provider keys (`parts`, `tool-call`, etc.) in [`sdk/typescript/src/utils/format.ts`](https://github.com/chopratejas/headroom/blob/main/sdk/typescript/src/utils/format.ts).
- **Section splitting** groups contiguous messages by role and content-type, using `splitLines` for streams or array logic for structured data.
- **Canonical conversion** transforms Anthropic, Vercel, and Gemini formats into unified OpenAI messages via dedicated converter functions.
- **Gateway routing** rewrites URLs through `routeBaseUrlThroughProxy` based on OpenClaw plugin configuration.
- **Shared-context storage** compresses and caches sections with automatic TTL eviction in [`sdk/typescript/src/shared-context.ts`](https://github.com/chopratejas/headroom/blob/main/sdk/typescript/src/shared-context.ts).

## Frequently Asked Questions

### What constitutes mixed content in Headroom?

Mixed content refers to payloads containing messages from multiple AI providers—such as Anthropic’s Claude, OpenAI’s GPT, or Google’s Gemini—within a single request, or messages with varying roles (user, assistant, tool) and content structures that require normalization before processing.

### How does Headroom detect the message format without heuristics?

Headroom uses the `detectFormat` function in [`sdk/typescript/src/utils/format.ts`](https://github.com/chopratejas/headroom/blob/main/sdk/typescript/src/utils/format.ts) to scan for structural markers unique to each provider, such as the presence of `parts` arrays in Gemini versus string `content` in OpenAI, or hyphenated `tool-call` keys versus underscored `tool_use` identifiers.

### Can I route specific providers through the proxy while sending others directly?

Yes. The OpenClaw plugin’s [`gateway-config.ts`](https://github.com/chopratejas/headroom/blob/main/gateway-config.ts) allows selective routing via the `routeBaseUrlThroughProxy` function. By specifying `gatewayProviderIds` and boolean flags like `routeCodexViaProxy`, you can rewrite base URLs for specific providers while allowing others to communicate directly with their native endpoints.

### How does shared-context storage handle large text sections?

The `SharedContext` class in [`sdk/typescript/src/shared-context.ts`](https://github.com/chopratejas/headroom/blob/main/sdk/typescript/src/shared-context.ts) compresses content using the proxy’s `compress` endpoint before storage, keys the compressed blob by a hash of the content, and manages memory through TTL-based eviction via `evictExpired` and capacity limits via `evictIfFull`.