UNPKG

@tanstack/ai

Version:

Type-safe TypeScript AI SDK for streaming chat, tool calling, agents, structured outputs, and multimodal generation.

109 lines (90 loc) • 3.69 kB
# OpenRouter Adapter Reference ## Package ``` @tanstack/ai-openrouter ``` ## Adapter Factories | Factory | Type | Description | | --------------------- | --------- | ------------------ | | `openRouterText` | Text/Chat | Chat completions | | `openRouterImage` | Image | Image generation | | `openRouterSummarize` | Summarize | Text summarization | ## Import ```typescript import { openRouterText } from '@tanstack/ai-openrouter' ``` ## Key Models OpenRouter routes to hundreds of models across providers. Model IDs use the format `provider/model-name`: | Model ID | Notes | | ----------------------------- | -------------------------- | | `anthropic/claude-sonnet-4` | Claude via OpenRouter | | `openai/gpt-5.2` | GPT-5.2 via OpenRouter | | `google/gemini-2.5-pro` | Gemini via OpenRouter | | `meta-llama/llama-4-maverick` | Open-source via OpenRouter | | `deepseek/deepseek-r1` | Reasoning model | ## Provider-Specific modelOptions OpenRouter has unique routing and provider selection options: ```typescript import { chat } from '@tanstack/ai' import { openRouterText } from '@tanstack/ai-openrouter' const messages = [{ role: 'user' as const, content: 'Hello' }] // Options are narrowed per model from OpenRouter's published metadata — // e.g. 'anthropic/claude-sonnet-4' only accepts temperature/topP/ // maxCompletionTokens/stop/toolChoice/reasoning. This model takes the full set. chat({ adapter: openRouterText('deepseek/deepseek-v4-pro'), messages, // Reasoning: goes out as reasoning.effort ('off' sends 'none') reasoning: 'high', modelOptions: { // Sampling temperature: 0.7, topP: 0.9, frequencyPenalty: 0.5, presencePenalty: 0.5, seed: 42, // Token limits maxCompletionTokens: 8192, // Stop sequences stop: ['\n\n'], // Tool calling toolChoice: 'auto', parallelToolCalls: true, // Response format responseFormat: { type: 'json_object' }, // Routing (available on every model) variant: 'nitro', // 'free' | 'nitro' | 'online' | 'exacto' | 'extended' | 'thinking' models: ['deepseek/deepseek-v4-flash'], // fallbacks, tried in order provider: { order: ['DeepSeek'], allowFallbacks: true }, plugins: [{ id: 'web' }], // web search // Logprobs logprobs: true, topLogprobs: 5, }, }) ``` ## Environment Variable ``` OPENROUTER_API_KEY ``` ## Gotchas - Model IDs are `provider/model-name` format (e.g., `openai/gpt-5.2`). - OpenRouter has unique features not found in direct provider adapters: - `variant` option: `'free'`, `'nitro'`, `'online'`, `'exacto'`, `'extended'`, `'thinking'` - `provider` routing preferences (`order`, `allowFallbacks`, data collection policies — camelCase keys) - `models` array of fallback ids, tried in order - `plugins: [{ id: 'web' }]` for web search (also `file-parser`, `response-healing`, `moderation`, `auto-router`) - Uses `camelCase` for option names (e.g., `topP`, `frequencyPenalty`, `maxCompletionTokens`), unlike OpenAI's `snake_case`. - `chat({ reasoning })` goes out as `reasoning.effort`. `off` sends `effort: 'none'`. The chat adapter takes no `budgetTokens`. The Responses adapter sends `budgetTokens` as `reasoning.maxTokens`. - Per-model options are narrowed from OpenRouter's published metadata, so keys like `frequencyPenalty`, `seed`, `logprobs`, or `responseFormat` are only accepted on models that support them. `topK`, `minP`, `repetitionPenalty`, `webSearchOptions`, `verbosity`, `transforms`, and `route` are not exposed by the adapter.