> For the complete documentation index, see [llms.txt](https://infronai.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://infronai.gitbook.io/docs/frameworks-and-integrations/vercel-ai-sdk.md).

# Vercel AI SDK

Infron exposes an OpenAI-compatible API that can be used with the Vercel AI SDK through `@ai-sdk/openai-compatible`.

This guide shows how to configure the provider, run text generation, stream responses, use tool calling, enable request debugging, and pass Anthropic-specific tool options when needed.

### Install

```bash
npm install ai @ai-sdk/openai-compatible zod
```

### Environment

```bash
export INFRON_API_KEY="your-infron-api-key"
```

Do not expose this key in browser code. Use it from a server route, API route, or backend service.

### Basic Setup

```ts
import { createOpenAICompatible } from '@ai-sdk/openai-compatible';

const infron = createOpenAICompatible({
  name: 'infron',
  baseURL: 'https://llm.onerouter.pro/v1',
  apiKey: process.env.INFRON_API_KEY,
});
```

### Generate Text

```ts
import { generateText } from 'ai';
import { createOpenAICompatible } from '@ai-sdk/openai-compatible';

const infron = createOpenAICompatible({
  name: 'infron',
  baseURL: 'https://llm.onerouter.pro/v1',
  apiKey: process.env.INFRON_API_KEY,
});

const result = await generateText({
  model: infron('anthropic/claude-sonnet-4.6'),
  prompt: 'Reply with one short synthetic status sentence.',
});

console.log(result.text);
```

### Stream Text

```ts
import { streamText } from 'ai';
import { createOpenAICompatible } from '@ai-sdk/openai-compatible';

const infron = createOpenAICompatible({
  name: 'infron',
  baseURL: 'https://llm.onerouter.pro/v1',
  apiKey: process.env.INFRON_API_KEY,
});

const result = streamText({
  model: infron('anthropic/claude-sonnet-4.6'),
  prompt: 'Write three short bullets about a synthetic test workflow.',
});

for await (const chunk of result.textStream) {
  process.stdout.write(chunk);
}
```

### Next.js Route Handler

```ts
import { streamText } from 'ai';
import { createOpenAICompatible } from '@ai-sdk/openai-compatible';

const infron = createOpenAICompatible({
  name: 'infron',
  baseURL: 'https://llm.onerouter.pro/v1',
  apiKey: process.env.INFRON_API_KEY,
});

export async function POST(req: Request) {
  const { messages } = await req.json();

  const result = streamText({
    model: infron('anthropic/claude-sonnet-4.6'),
    messages,
  });

  return result.toUIMessageStreamResponse();
}
```

### Tool Calling

The Vercel AI SDK standardizes tool definitions into OpenAI-compatible tool schemas.

```ts
import { generateText, tool } from 'ai';
import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
import { z } from 'zod';

const infron = createOpenAICompatible({
  name: 'infron',
  baseURL: 'https://llm.onerouter.pro/v1',
  apiKey: process.env.INFRON_API_KEY,
});

const result = await generateText({
  model: infron('anthropic/claude-sonnet-4.6'),
  prompt: 'Use the mock lookup tool only if needed, then return a short status sentence.',
  tools: {
    lookup_mock_record: tool({
      description: 'Return a synthetic record for compatibility testing.',
      inputSchema: z.object({
        record_id: z.string().describe('Synthetic record id.'),
      }),
      execute: async ({ record_id }) => ({
        record_id,
        status: 'synthetic-ok',
      }),
    }),
  },
  toolChoice: 'auto',
});

console.log(result.text);
```

### Debugging Requests

Infron supports request and response debugging fields. They are useful when validating how an OpenAI-compatible request is mapped to an upstream provider request.

Pass `debug_request` and `debug_response` through `providerOptions.infron`.

```ts
import { generateText } from 'ai';
import { createOpenAICompatible } from '@ai-sdk/openai-compatible';

const infron = createOpenAICompatible({
  name: 'infron',
  baseURL: 'https://llm.onerouter.pro/v1',
  apiKey: process.env.INFRON_API_KEY,
});

const result = await generateText({
  model: infron('anthropic/claude-sonnet-4.6'),
  prompt: 'Reply with one short synthetic status sentence.',
  providerOptions: {
    infron: {
      debug_request: true,
      debug_response: true,
    },
  },
  include: {
    requestBody: true,
    responseBody: true,
  },
});

console.log(result.steps[0]?.response?.body);
```

When enabled, Infron responses may include `debug_info.request` and `debug_info.response` in the response body. Use these fields for development and validation only. Avoid logging them in production if prompts or payloads may contain sensitive data.

### Anthropic-Specific Tool Options

Some Anthropic features use fields that are not part of the standard OpenAI tool schema, such as:

* `defer_loading`
* `eager_input_streaming`
* tool-level `cache_control`

The Vercel AI SDK does not preserve arbitrary per-tool Anthropic fields by default because it normalizes tools into the OpenAI-compatible format.

To send these fields through Infron, use `transformRequestBody` on the OpenAI-compatible provider and inject the Anthropic-native fields into the final request body.

```ts
import { createOpenAICompatible } from '@ai-sdk/openai-compatible';

function injectAnthropicToolOptions(body: Record<string, any>) {
  const toolOptions = body.anthropic_tool_options;
  const next = structuredClone(body);
  delete next.anthropic_tool_options;

  if (!toolOptions || !Array.isArray(next.tools)) {
    return next;
  }

  next.tools = next.tools.map((item: any) => {
    const name = item?.function?.name;
    if (!name || !toolOptions[name]) {
      return item;
    }
    return {
      ...item,
      ...toolOptions[name],
    };
  });

  return next;
}

const infron = createOpenAICompatible({
  name: 'infron',
  baseURL: 'https://llm.onerouter.pro/v1',
  apiKey: process.env.INFRON_API_KEY,
  transformRequestBody: injectAnthropicToolOptions,
});
```

Use the provider with `providerOptions.infron.anthropic_tool_options`:

```ts
import { generateText, tool } from 'ai';
import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
import { z } from 'zod';

function injectAnthropicToolOptions(body: Record<string, any>) {
  const toolOptions = body.anthropic_tool_options;
  const next = structuredClone(body);
  delete next.anthropic_tool_options;

  if (!toolOptions || !Array.isArray(next.tools)) {
    return next;
  }

  next.tools = next.tools.map((item: any) => {
    const name = item?.function?.name;
    if (!name || !toolOptions[name]) {
      return item;
    }
    return {
      ...item,
      ...toolOptions[name],
    };
  });

  return next;
}

const infron = createOpenAICompatible({
  name: 'infron',
  baseURL: 'https://llm.onerouter.pro/v1',
  apiKey: process.env.INFRON_API_KEY,
  transformRequestBody: injectAnthropicToolOptions,
});

const result = await generateText({
  model: infron('anthropic/claude-sonnet-4.6'),
  prompt: 'Use mock tools only if needed, then return one short synthetic status sentence.',
  tools: {
    lookup_mock_deferred: tool({
      description: 'Return a synthetic deferred record.',
      inputSchema: z.object({
        record_id: z.string().describe('Synthetic record id.'),
      }),
    }),
    lookup_mock_regular: tool({
      description: 'Return a synthetic regular record.',
      inputSchema: z.object({
        record_id: z.string().describe('Synthetic record id.'),
      }),
    }),
  },
  toolChoice: 'auto',
  maxOutputTokens: 96,
  providerOptions: {
    infron: {
      debug_request: true,
      debug_response: true,
      thinking: { type: 'enabled', budget_tokens: 1024 },
      reasoning: { effort: 'low' },
      anthropic_tool_options: {
        lookup_mock_deferred: {
          defer_loading: true,
          eager_input_streaming: true,
        },
        lookup_mock_regular: {
          defer_loading: false,
          eager_input_streaming: true,
          cache_control: { type: 'ephemeral' },
        },
      },
    },
  },
  include: {
    requestBody: true,
    responseBody: true,
  },
});
```

{% hint style="info" %}
Infron routes requests across available providers based on model availability, reliability, latency, and provider capability.

When a request is naturally routed to a provider that does not support a given Anthropic-specific option, that option may not appear in the final upstream request body. Use `debug_request` / `debug_response` during integration testing to confirm the actual upstream request.
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://infronai.gitbook.io/docs/frameworks-and-integrations/vercel-ai-sdk.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
