How to Integrate Headroom with Vercel AI SDK Using wrapLanguageModel

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, 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:

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)
  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.

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 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.

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 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.

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 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 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 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.
  • 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 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. 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 in the Headroom repository, which demonstrates combining Headroom compression with caching or logging middlewares.

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 →