@standardagents/openrouter
OpenRouter provider package for Standard Agents - access multiple LLM providers through a unified gateway
Overview
The @standardagents/openrouter package provides the OpenRouter provider factory for Standard Agents. OpenRouter is a multi-provider gateway that routes requests to various LLM providers (OpenAI, Anthropic, Google, Meta, and more) through a single API.
- Access to models from multiple providers
- Automatic pricing data fetched from OpenRouter API
- Typed
providerOptionsfor routing configuration - Provider selection, fallbacks, and price limits
- Zero Data Retention (ZDR) endpoints
- Provider-executed OpenRouter server tools
Installation
npm
npm install @standardagents/openrouterpnpm
pnpm add @standardagents/openrouteryarn
yarn add @standardagents/openrouterQuick Start
import { defineModel } from '@standardagents/spec';
import { openrouter } from '@standardagents/openrouter';
export default defineModel({
name: 'claude-sonnet',
provider: openrouter,
model: 'anthropic/claude-sonnet-5.5',
});Provider Factory
The openrouter export is a provider factory function:
import { openrouter } from '@standardagents/openrouter';
defineModel({
name: 'my-model',
provider: openrouter, // Pass the factory, not a string
model: 'anthropic/claude-sonnet-5.5',
});Model ID Format
OpenRouter uses a provider/model-name format for model IDs:
| Provider | Example Model ID |
|---|---|
| OpenAI | openai/gpt-6.1-sol |
| Anthropic | anthropic/claude-sonnet-5.5 |
google/gemini-3.1-pro-preview |
|
| Meta | meta-llama/llama-3.3-70b-instruct |
| Mistral | mistralai/mistral-large |
| xAI | x-ai/grok-4 |
Browse all available models at openrouter.ai/models.
Provider Options
The openrouter factory includes a typed schema for routing configuration:
import { defineModel } from '@standardagents/spec';
import { openrouter } from '@standardagents/openrouter';
export default defineModel({
name: 'claude-secure',
provider: openrouter,
model: 'anthropic/claude-sonnet-5.5',
providerOptions: {
provider: {
zdr: true, // Zero Data Retention
only: ['anthropic'], // Only route to Anthropic
max_price: {
prompt: 5, // Max $5 per million input tokens
completion: 25, // Max $25 per million output tokens
},
},
},
});Routing Options
All routing options are nested under the provider key:
| Option | Type | Description |
|---|---|---|
order |
string[] |
Provider slugs to try in order |
allow_fallbacks |
boolean |
Allow fallback to other providers (default: true) |
require_parameters |
boolean |
Only use providers that support all request parameters |
data_collection |
'allow' | 'deny' |
Control data storage policies |
zdr |
boolean |
Restrict to Zero Data Retention endpoints |
only |
string[] |
Restrict to these providers only |
ignore |
string[] |
Skip these providers |
sort |
string | object |
Sort by price, throughput, or latency |
max_price |
object |
Maximum price constraints |
quantizations |
string[] |
Allowed quantization levels |
preferred_min_throughput |
number | object |
Minimum throughput preference |
preferred_max_latency |
number | object |
Maximum latency preference |
Server Tool Options
OpenRouter server tools are provider-executed tools. Enable the tool names with
providerTools, select them from prompts like normal tools, and pass optional
OpenRouter parameters through providerOptions.serverTools:
export default defineModel({
name: 'openrouter-research',
provider: openrouter,
model: 'openai/gpt-6.1-sol',
providerTools: ['web_search', 'web_fetch', 'datetime', 'image_generation'],
providerOptions: {
serverTools: {
web_search: { max_results: 5 },
web_fetch: { max_content_tokens: 50000 },
datetime: { timezone: 'America/New_York' },
image_generation: { quality: 'high' },
},
},
});serverTools configures native OpenRouter tool parameters only. It is stripped
from the request body after the provider converts selected tools into
openrouter:* tool definitions.
Price Limits
Set hard limits on pricing (request fails if no provider meets threshold):
providerOptions: {
provider: {
max_price: {
prompt: 1, // Max $1 per million input tokens
completion: 5, // Max $5 per million output tokens
request: 0.01, // Max $0.01 per request
image: 0.05, // Max $0.05 per image
},
},
}Provider Selection
Control which providers handle your requests:
// Only use specific providers
providerOptions: {
provider: {
only: ['anthropic', 'openai'],
},
}
// Prefer certain providers in order
providerOptions: {
provider: {
order: ['anthropic', 'openai', 'google'],
allow_fallbacks: true,
},
}
// Exclude specific providers
providerOptions: {
provider: {
ignore: ['azure'],
},
}Sorting
Sort available providers by different criteria:
// Sort by price (cheapest first)
providerOptions: {
provider: {
sort: 'price',
},
}
// Sort by throughput (fastest first)
providerOptions: {
provider: {
sort: 'throughput',
},
}
// Advanced sorting with partition
providerOptions: {
provider: {
sort: {
by: 'latency',
partition: 'model',
},
},
}Zero Data Retention (ZDR)
For sensitive data, restrict to ZDR endpoints:
providerOptions: {
provider: {
zdr: true, // Only use providers with Zero Data Retention
},
}Performance Preferences
Set soft preferences for throughput and latency:
providerOptions: {
provider: {
// Simple: apply to p50 percentile
preferred_min_throughput: 100, // 100 tokens/sec minimum
preferred_max_latency: 1, // 1 second max latency
},
}Use objects to set percentile thresholds:
providerOptions: {
provider: {
preferred_min_throughput: {
p50: 100,
p90: 50,
},
preferred_max_latency: {
p50: 0.5,
p99: 2,
},
},
}Type Safety
The providerOptions type is automatically inferred:
import { openrouter } from '@standardagents/openrouter';
import type { OpenRouterProviderOptions } from '@standardagents/openrouter';
const options: OpenRouterProviderOptions = {
provider: {
zdr: true,
only: ['anthropic'],
// zdr: 'yes', // Error: expected a boolean
},
};Model Capabilities
Set capabilities for proper framework behavior:
export default defineModel({
name: 'claude-sonnet',
provider: openrouter,
model: 'anthropic/claude-sonnet-5.5',
capabilities: {
supportsImages: true,
supportsToolCalls: true,
supportsStreaming: true,
maxContextTokens: 1000000,
},
});Environment Setup
Set your OpenRouter API key:
OPENROUTER_API_KEY=sk-or-...For a deployed project, set OPENROUTER_API_KEY in your project's environment settings on the Standard Agents platform.
Example Configurations
Budget-Conscious Model
import { defineModel } from '@standardagents/spec';
import { openrouter } from '@standardagents/openrouter';
export default defineModel({
name: 'budget-llm',
provider: openrouter,
model: 'meta-llama/llama-3.3-70b-instruct',
providerOptions: {
provider: {
sort: 'price',
max_price: {
prompt: 0.5,
completion: 1,
},
},
},
});High-Security Configuration
export default defineModel({
name: 'secure-claude',
provider: openrouter,
model: 'anthropic/claude-sonnet-5.5',
providerOptions: {
provider: {
zdr: true,
only: ['anthropic'],
data_collection: 'deny',
},
},
capabilities: {
supportsImages: true,
supportsToolCalls: true,
maxContextTokens: 1000000,
},
});Multi-Provider Fallback
export default defineModel({
name: 'resilient-model',
provider: openrouter,
model: 'openai/gpt-6.1-sol',
providerOptions: {
provider: {
order: ['openai', 'azure', 'anthropic'],
allow_fallbacks: true,
},
},
});Performance-Optimized
export default defineModel({
name: 'fast-model',
provider: openrouter,
model: 'anthropic/claude-sonnet-5.5',
providerOptions: {
provider: {
sort: 'throughput',
preferred_min_throughput: 100,
preferred_max_latency: 0.5,
},
},
});Tool Calling
OpenRouter tool calls are sent with strict function schemas. The provider normalizes object schemas for OpenAI-backed endpoints by listing every object property in required, while Standard Agents Builder still validates the returned tool arguments against the original tool Zod schema before execution.
When tools are present, tool_choice: "auto" is omitted because OpenRouter treats that as the default. This keeps endpoints that support tools but do not advertise the separate tool_choice parameter eligible for routing.
Provider-Executed Server Tools
The OpenRouter provider exposes these built-in server tools through getTools():
| Tool | Native OpenRouter type | Description |
|---|---|---|
web_search |
openrouter:web_search |
Search the web server-side |
web_fetch |
openrouter:web_fetch |
Fetch and extract URL content server-side |
datetime |
openrouter:datetime |
Resolve current date/time server-side |
image_generation |
openrouter:image_generation |
Generate images server-side |
Standard Agents Builder marks these tools as provider-executed. The OpenRouter provider
translates them to native openrouter:* tools for both Chat Completions and
Responses requests, and records completed server tool usage through the generic
provider-tool log path.
Responses API
Set providerOptions.useResponsesApi to true to select the Responses API.
This mode supports tool-call history and image inputs.
Generation settings apply to streaming and non-streaming requests.
inspectRequest() shows the serialized API fields.
Opaque provider options retain their wire field names.
Responses preserve canonical reasoningDetails across turns.
Builder also normalizes stored legacy summary and encrypted detail names before replay.
Encrypted details use the data field.
Each replayed reasoning item retains its provider ID.
A token-limit truncation reports the length finish reason.
Partial image events retain their generated bytes.
Tool-call arguments remain objects.
Invalid JSON argument values use an empty object.
Generation Metadata
Stream finish chunks carry a response ID for metadata lookups.
The provider keeps credentials in its configuration.
SDK request timeouts produce retryable provider errors.
Rate-limit errors retain the SDK response's Retry-After value in seconds.
OpenRouter provides additional metadata about request routing that can be fetched after completion:
import { fetchGenerationMetadata } from '@standardagents/openrouter';
const metadata = await fetchGenerationMetadata(apiKey, generationId);
// Returns: provider used, tokens, latency, etc.totalCost is null when OpenRouter reports no cost for the generation.
Standard Agents runs this lookup after requests that use your own OPENROUTER_API_KEY.
Requests routed through the Standard Agents platform skip it: their logs show the price the router charged.
Exports
import {
// Provider factory
openrouter,
// Provider options schema (Zod)
openrouterProviderOptions,
// Provider class (advanced usage)
OpenRouterProvider,
// Metadata utilities
fetchGenerationMetadata,
// Shared lab icon utilities
getLabIconDataUri,
getModelIconDataUri,
} from '@standardagents/openrouter';
import type {
// TypeScript types
OpenRouterProviderOptions,
OpenRouterConfig,
GenerationMetadata,
} from '@standardagents/openrouter';