# How to Integrate Headroom with Vercel AI SDK Using wrapLanguageModel

> Integrate Headroom with Vercel AI SDK using wrapLanguageModel to automatically compress prompts. Learn how to optimize your LLM calls with this powerful technique.

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

---

**The Headroom TypeScript SDK provides a `headroomMiddleware` function that implements the Vercel AI SDK `LanguageModelV3Middleware` interface, allowing you to wrap any language model with `wrapLanguageModel` to automatically compress prompts before they reach the LLM.**

Headroom is an open-source prompt compression proxy designed to reduce token costs in LLM applications. By integrating Headroom with the Vercel AI SDK using the `wrapLanguageModel` function, you can transparently compress conversation history and system prompts without modifying your existing AI generation logic.

## Understanding the Middleware Architecture

The integration relies on the Vercel AI SDK's middleware system, which intercepts model calls before they reach the provider.

### The LanguageModelV3Middleware Contract

According to the Headroom source code in [`sdk/typescript/src/adapters/vercel-ai.ts`](https://github.com/chopratejas/headroom/blob/main/sdk/typescript/src/adapters/vercel-ai.ts), the `headroomMiddleware` function conforms to the Vercel AI SDK `LanguageModelV3Middleware` interface. This contract requires implementing a `transformParams` hook that receives the request parameters—including the `prompt` and `messages` array—before the SDK invokes the underlying language model.

The middleware intercepts calls through this structure:

```typescript
const headroomMiddleware = (options: HeadroomOptions) => ({
  transformParams: async (params) => {
    // Compression executes here before reaching the LLM
    return transformedParams;
  }
});

```

### The Compression Flow

When you call `generateText` or `generateObject` with a wrapped model, the execution flow follows this pattern:

1. **Vercel AI SDK** invokes `headroomMiddleware.transformParams`
2. **Format conversion** translates Vercel `ModelMessage[]` to OpenAI-compatible format using `vercelToOpenAI` (defined in [`sdk/typescript/src/utils/format.ts`](https://github.com/chopratejas/headroom/blob/main/sdk/typescript/src/utils/format.ts))
3. **Compression** sends the translated messages to the Headroom proxy via the `compress()` API
4. **Transformation** converts the compressed OpenAI messages back to Vercel format using `openAIToVercel`
5. **Return** modified parameters to the SDK, which proceeds to the underlying LLM with the compressed prompt

This architecture keeps the heavy processing on the Headroom proxy (or Headroom Cloud) while maintaining **zero runtime dependencies** for the client-side code.

## Setting Up the Integration

You can integrate Headroom using three approaches depending on your abstraction preferences.

### Using wrapLanguageModel with headroomMiddleware

The explicit approach uses the `wrapLanguageModel` function from the `ai` package combined with `headroomMiddleware` from `headroom-ai/vercel-ai`. This pattern gives you full control over the middleware configuration.

```typescript
import { headroomMiddleware } from 'headroom-ai/vercel-ai';
import { wrapLanguageModel, generateText } from 'ai';
import { openai } from '@ai-sdk/openai';

// Wrap the OpenAI model with Headroom compression
const model = wrapLanguageModel({
  model: openai('gpt-4o'),
  middleware: headroomMiddleware({ baseUrl: 'http://localhost:8787' }),
});

// The SDK automatically compresses large contexts before sending to the LLM
const { text } = await generateText({
  model,
  messages: longConversation,
});

```

**Key implementation detail**: The `headroomMiddleware` object in [`sdk/typescript/src/adapters/vercel-ai.ts`](https://github.com/chopratejas/headroom/blob/main/sdk/typescript/src/adapters/vercel-ai.ts) intercepts the request parameters, compresses them via the proxy, and returns modified params where the `prompt` contains the compressed content.

### The withHeadroom Convenience Wrapper

For cleaner code, Headroom provides the `withHeadroom()` helper function, which implements exactly what the Vercel AI SDK documentation suggests: it loads the `ai` package, grabs `wrapLanguageModel`, and returns a model pre-configured with `headroomMiddleware`.

```typescript
import { withHeadroom } from 'headroom-ai/vercel-ai';
import { openai } from '@ai-sdk/openai';
import { generateText } from 'ai';

const model = withHeadroom(openai('gpt-4o'), {
  baseUrl: 'http://localhost:8787',
});

const { text } = await generateText({ model, messages: longConversation });

```

This wrapper is defined in [`sdk/typescript/src/adapters/vercel-ai.ts`](https://github.com/chopratejas/headroom/blob/main/sdk/typescript/src/adapters/vercel-ai.ts) and handles the composition of `wrapLanguageModel` and `headroomMiddleware` under the hood.

### Direct Message Compression

If you need manual control over when compression occurs, use the `compressVercelMessages` function. This bypasses the middleware pattern and returns the compressed messages directly.

```typescript
import { compressVercelMessages } from 'headroom-ai/vercel-ai';

const result = await compressVercelMessages(vercelMessages, {
  model: 'gpt-4o',
  baseUrl: 'http://localhost:8787',
});

console.log('Tokens saved:', result.tokensSaved);
const compressed = result.messages; // Still Vercel ModelMessage[] format

```

Note that `compressVercelMessages` is also located in [`sdk/typescript/src/adapters/vercel-ai.ts`](https://github.com/chopratejas/headroom/blob/main/sdk/typescript/src/adapters/vercel-ai.ts) and provides access to the `CompressResult` statistics including token savings.

## Technical Implementation Details

Understanding the internal transformations helps debug integration issues and optimize performance.

### Format Conversion Between Vercel and OpenAI Schemas

Headroom's compression engine operates on OpenAI-style chat schemas. The `vercelToOpenAI` function in [`sdk/typescript/src/utils/format.ts`](https://github.com/chopratejas/headroom/blob/main/sdk/typescript/src/utils/format.ts) handles the bidirectional translation:

- **Outgoing**: Converts Vercel's `ModelMessage[]` (which may include provider-specific formats) into a standardized OpenAI-compatible array
- **Incoming**: Uses `openAIToVercel` to transform the compressed OpenAI messages back into Vercel's native format

This conversion ensures compatibility with Headroom's SmartCrusher, ContentRouter, and CacheAligner components while maintaining the Vercel AI SDK's abstraction layer.

### Proxy Communication and Zero-Runtime Dependencies

The integration architecture maintains **zero runtime dependencies** for the client. The only requirement is the optional peer dependency `ai` (the Vercel AI SDK package). All heavy processing—including the full Headroom pipeline—executes on the Headroom proxy side (either self-hosted or Headroom Cloud).

When the middleware calls `compress()`, it sends the translated messages to the configured `baseUrl` endpoint. The proxy processes the request through its compression pipeline and returns a `CompressResult` containing:
- `compressed`: Boolean indicating success
- `messages`: The compressed message array
- `tokensSaved`: Statistics on compression efficiency

## Summary

- **Headroom** provides a Vercel AI SDK adapter in [`sdk/typescript/src/adapters/vercel-ai.ts`](https://github.com/chopratejas/headroom/blob/main/sdk/typescript/src/adapters/vercel-ai.ts) that implements the `LanguageModelV3Middleware` interface.
- **Use `wrapLanguageModel`** with `headroomMiddleware` to intercept and compress prompts automatically before they reach the LLM.
- **Format conversion** happens transparently via `vercelToOpenAI` and `openAIToVercel` in [`sdk/typescript/src/utils/format.ts`](https://github.com/chopratejas/headroom/blob/main/sdk/typescript/src/utils/format.ts).
- **The `withHeadroom` helper** offers a concise alternative to manually composing `wrapLanguageModel` and `headroomMiddleware`.
- **Zero runtime dependencies** means the client only needs the optional `ai` peer dependency; compression logic runs on the Headroom proxy.

## Frequently Asked Questions

### What is the difference between using headroomMiddleware directly versus the withHeadroom helper?

Both approaches achieve the same result, but `withHeadroom` provides a more concise API. The `withHeadroom` function in [`sdk/typescript/src/adapters/vercel-ai.ts`](https://github.com/chopratejas/headroom/blob/main/sdk/typescript/src/adapters/vercel-ai.ts) internally calls `wrapLanguageModel` with `headroomMiddleware`, following the exact pattern recommended in the Vercel AI SDK documentation. Use `headroomMiddleware` directly when you need to compose multiple middlewares or customize the middleware configuration beyond the standard options.

### Does Headroom require additional runtime dependencies in my Vercel AI SDK project?

No. Headroom's integration is designed with **zero runtime dependencies** for the client. The only requirement is the optional peer dependency `ai` (the Vercel AI SDK package itself). The actual compression logic—including the SmartCrusher and ContentRouter pipelines—executes on the Headroom proxy server or Headroom Cloud, not in your application runtime.

### How does Headroom handle message format differences between Vercel AI SDK and OpenAI?

The middleware automatically handles format conversion through utility functions in [`sdk/typescript/src/utils/format.ts`](https://github.com/chopratejas/headroom/blob/main/sdk/typescript/src/utils/format.ts). Before sending to the Headroom proxy, `vercelToOpenAI` converts Vercel's `ModelMessage[]` to OpenAI-compatible format. After compression, `openAIToVercel` transforms the messages back to Vercel's expected format. This bidirectional translation ensures compatibility with Headroom's OpenAI-centric compression engine while maintaining the Vercel AI SDK's abstraction layer.

### Can I use Headroom middleware with other Vercel AI SDK middlewares?

Yes. Since `headroomMiddleware` conforms to the standard `LanguageModelV3Middleware` interface, you can compose it with other middlewares using `wrapLanguageModel`. The middleware composition pattern allows you to chain multiple transformations. For implementation examples, see [`sdk/typescript/examples/middleware-composition.ts`](https://github.com/chopratejas/headroom/blob/main/sdk/typescript/examples/middleware-composition.ts) in the Headroom repository, which demonstrates combining Headroom compression with caching or logging middlewares.