Documentation
¶
Overview ¶
Package openrouter provides a Genkit plugin for OpenRouter, a gateway that serves models from many providers behind one OpenAI-compatible endpoint.
OpenRouter is not a model vendor, so this plugin carries no model catalog. Every model resolves by name on demand, under an ID that keeps the upstream vendor's prefix:
ai.WithModelName("openrouter/anthropic/claude-sonnet-4.5")
A resolved model is described with permissive capabilities, which is what makes an arbitrary model usable without an entry per model. Correct a model whose real capabilities are narrower through OpenRouter.Models.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ModelRef ¶
func ModelRef(id string, config *ChatConfig) ai.ModelRef
ModelRef names a model and carries the config to generate with, so the config is typed at the call site instead of an any the model checks at runtime. A nil config leaves the request's config unset.
ai.WithModel(openrouter.ModelRef("anthropic/claude-sonnet-4.5", &openrouter.ChatConfig{
Provider: &openrouter.ProviderRouting{Sort: openrouter.ProviderSortThroughput},
}))
id is the model ID, with or without this plugin's provider prefix. It keeps the upstream vendor's prefix either way.
Types ¶
type ChatConfig ¶
type ChatConfig struct {
compat_oai.RequestConfig
// Temperature controls the degree of randomness in token selection, from
// 0 to 2.
Temperature *float64 `` /* 153-byte string literal not displayed */
// TopP is the nucleus sampling threshold, from 0 to 1.
TopP *float64 `` /* 190-byte string literal not displayed */
// TopK limits sampling to the K most likely tokens, sent as the API's
// top_k. 0, the default, applies no limit. Some vendors ignore it.
TopK *int `` /* 173-byte string literal not displayed */
// MaxOutputTokens is the maximum number of tokens to generate, sent as
// the API's max_tokens.
MaxOutputTokens int `` /* 148-byte string literal not displayed */
// StopSequences stop generation when produced by the model, up to four.
StopSequences []string `` /* 145-byte string literal not displayed */
// FrequencyPenalty penalizes tokens by their frequency so far, from -2.0
// to 2.0.
FrequencyPenalty *float64 `` /* 154-byte string literal not displayed */
// PresencePenalty penalizes tokens that have appeared at all, from -2.0
// to 2.0.
PresencePenalty *float64 `` /* 153-byte string literal not displayed */
// RepetitionPenalty penalizes tokens by whether they appeared in the
// input, from 0 to 2, sent as the API's repetition_penalty. 1 is neutral.
RepetitionPenalty *float64 `` /* 213-byte string literal not displayed */
// MinP is the minimum probability a token needs relative to the most
// likely one, from 0 to 1, sent as the API's min_p.
MinP *float64 `` /* 184-byte string literal not displayed */
// TopA filters tokens by a threshold scaled from the most likely token's
// probability, from 0 to 1, sent as the API's top_a.
TopA *float64 `` /* 196-byte string literal not displayed */
// Seed makes generation reproducible across calls when set, on a
// best-effort basis.
Seed *int `json:"seed,omitempty" jsonschema_description:"Makes generation reproducible across calls when set, on a best-effort basis."`
// LogProbs requests log probabilities for the output tokens.
LogProbs *bool `json:"logProbs,omitempty" jsonschema_description:"Requests log probabilities for the output tokens."`
// TopLogProbs is how many of the most likely tokens to return log
// probabilities for at each position, from 0 to 20; it requires LogProbs.
TopLogProbs *int `` /* 205-byte string literal not displayed */
// ParallelToolCalls lets the model request several tool calls in one
// response, which it may do by default. It applies to a request that
// carries tools.
ParallelToolCalls *bool `` /* 186-byte string literal not displayed */
// User identifies the end user a request is made for, which OpenRouter
// uses to isolate abuse to one user rather than the whole key.
User string `` /* 171-byte string literal not displayed */
// Models lists further models to fall back to, in order, when the
// requested one is unavailable, rate-limited, or refuses. The model the
// request names is tried first.
Models []string `` /* 191-byte string literal not displayed */
// Provider chooses which upstream providers may serve the request.
Provider *ProviderRouting `json:"provider,omitempty" jsonschema_description:"Chooses which upstream providers may serve the request, and in what order."`
// Reasoning controls the reasoning the model does before answering.
Reasoning *ReasoningConfig `json:"reasoning,omitempty" jsonschema_description:"Controls the reasoning the model does before answering."`
// Plugins enables OpenRouter's request plugins, such as web search and
// file parsing, each an object with an id and that plugin's own options:
//
// Plugins: []map[string]any{{"id": "web", "max_results": 3}}
//
// They are sent verbatim rather than typed: the roster and each plugin's
// options change on OpenRouter's schedule, and a struct here would reject
// an option the gateway accepts. See
// https://openrouter.ai/docs/features/web-search.
Plugins []map[string]any `` /* 214-byte string literal not displayed */
// Transforms are the prompt transforms to apply, currently "middle-out",
// which compresses a prompt that would overflow the model's context by
// dropping from the middle.
Transforms []string `` /* 197-byte string literal not displayed */
// SessionID groups related requests so they keep reaching the same
// upstream provider, sent as the API's session_id. It is what keeps a
// multi-turn conversation on one provider's prompt cache.
SessionID string `` /* 222-byte string literal not displayed */
// ServiceTier selects how the request is scheduled and billed upstream.
ServiceTier ServiceTier `` /* 231-byte string literal not displayed */
// Metadata attaches key-value pairs to the request, readable later on
// OpenRouter's activity pages. It takes up to 16 pairs, with keys up to
// 64 characters and values up to 512.
Metadata map[string]string `` /* 201-byte string literal not displayed */
}
ChatConfig is the per-request config for models served through OpenRouter: the sampling fields the gateway normalizes across vendors, plus the routing controls that are the reason to route through it at all. See https://openrouter.ai/docs/api-reference/chat-completion.
Several documented request fields are deliberately absent. n asks for several completion choices and bills for all of them, while Genkit reads only the first. route and usage are deprecated by OpenRouter and have no effect. cache_control is a message annotation rather than a request field, so it has no home in a config. Anything undeclared still reaches the wire through compat_oai.RequestConfig.Extra.
func (ChatConfig) ApplyToChatCompletion ¶
func (c ChatConfig) ApplyToChatCompletion(params *openai.ChatCompletionNewParams)
ApplyToChatCompletion implements compat_oai.ChatConfig: the fields the OpenAI schema already has land on their chat completion counterparts, and the sampling knobs and routing controls OpenRouter adds ride as extra request fields.
type DataCollection ¶
type DataCollection string
DataCollection is whether a request may reach a provider that may store it.
const ( // DataCollectionAllow permits any provider, which is the default. DataCollectionAllow DataCollection = "allow" // DataCollectionDeny restricts routing to providers that do not store // request data. DataCollectionDeny DataCollection = "deny" )
type MaxPrice ¶
type MaxPrice struct {
// Prompt is the cap on the input price, per million tokens.
Prompt *float64 `json:"prompt,omitempty" jsonschema:"minimum=0" jsonschema_description:"Cap on the input price, in USD per million tokens."`
// Completion is the cap on the output price, per million tokens.
Completion *float64 `` /* 127-byte string literal not displayed */
// Request is the cap on the per-request price.
Request *float64 `json:"request,omitempty" jsonschema:"minimum=0" jsonschema_description:"Cap on the per-request price, in USD."`
// Image is the cap on the per-image price.
Image *float64 `json:"image,omitempty" jsonschema:"minimum=0" jsonschema_description:"Cap on the per-image price, in USD."`
}
MaxPrice caps what a request may cost, in USD per million tokens for the token fields. A request that no provider can serve within the cap fails rather than falling back to a dearer one.
type OpenRouter ¶
type OpenRouter struct {
// APIKey is the OpenRouter API key. If empty, OPENROUTER_API_KEY is
// consulted.
APIKey string
// SiteURL identifies the calling application on OpenRouter's rankings,
// sent as the HTTP-Referer header. It is optional and affects
// attribution only.
SiteURL string
// AppName is the title the calling application appears under on
// OpenRouter's rankings, sent as the X-Title header. It is optional and
// affects attribution only.
AppName string
// Opts contains additional OpenAI client request options, such as
// [option.WithBaseURL] for a different endpoint (OPENROUTER_BASE_URL
// works too). Options supplied here are applied after the plugin
// defaults, so they win on overlap.
Opts []option.RequestOption
// Models overrides what the plugin knows about a model, keyed by model
// ID, bare or provider-prefixed. Every model already works without an
// entry: OpenRouter serves hundreds of models from dozens of vendors and
// adds more weekly, so the plugin curates no catalog and describes every
// model it resolves with the same deliberately permissive capabilities.
// The two ways to be wrong are not symmetric: a capability declared too
// narrow is refused by Genkit before the request is sent, which blocks a
// model that would have worked, while one declared too wide reaches
// OpenRouter, which answers with the real reason the model cannot serve
// it. Constrained output is the exception, left unclaimed on purpose:
// a large share of the catalog lacks it natively, and unset, Genkit
// falls back to putting the schema in the prompt, which every model
// handles and which returns the same typed result.
//
// Supply an entry to correct what a model can actually do:
//
// &openrouter.OpenRouter{Models: map[string]ai.ModelOptions{
// // A text-only model, so Genkit refuses media locally rather
// // than paying for the upstream rejection.
// "mistralai/mistral-7b-instruct": {Supports: &ai.ModelSupports{
// Multiturn: true, Tools: true, SystemRole: true,
// }},
// }}
//
// Fields left at their zero value keep what the plugin resolves, so an
// entry can pin one capability without restating the rest. The model ID
// keeps the upstream vendor's prefix, so it contains a slash; the
// optional provider prefix is this plugin's own, as in
// "openrouter/mistralai/mistral-7b-instruct".
Models map[string]ai.ModelOptions
// contains filtered or unexported fields
}
OpenRouter configures the OpenRouter plugin.
func (*OpenRouter) Init ¶
func (o *OpenRouter) Init(ctx context.Context) []api.Action
Init implements genkit.Plugin. It registers no models: OpenRouter's catalog is too large and too fast-moving to enumerate, so every model is resolved on demand by OpenRouter.ResolveAction.
func (*OpenRouter) ListActions ¶
func (o *OpenRouter) ListActions(ctx context.Context) []api.ActionDesc
ListActions returns no descriptors. OpenRouter serves hundreds of models, and a descriptor carries a full copy of the request and response schemas, so listing the catalog would put megabytes on every reflection poll for a list nobody reads in full. Models stay reachable by name through OpenRouter.ResolveAction.
func (*OpenRouter) ResolveAction ¶
func (o *OpenRouter) ResolveAction(atype api.ActionType, id string) api.Action
ResolveAction dynamically builds a model served by OpenRouter, described by the plugin's config schema and capabilities. Any model ID the gateway serves resolves, whether or not this plugin has heard of it.
type ProviderRouting ¶
type ProviderRouting struct {
// Order lists provider slugs to try in order before any fallback.
Order []string `` /* 127-byte string literal not displayed */
// Only restricts routing to these provider slugs.
Only []string `json:"only,omitempty" jsonschema_description:"Restricts routing to these provider slugs."`
// Ignore skips these provider slugs.
Ignore []string `json:"ignore,omitempty" jsonschema_description:"Skips these provider slugs."`
// AllowFallbacks lets another provider serve the request when the chosen
// ones fail. It defaults to true; false fails the request instead.
AllowFallbacks *bool `` /* 174-byte string literal not displayed */
// RequireParameters routes only to providers that honor every parameter
// the request carries, rather than to one that would ignore some.
RequireParameters *bool `` /* 175-byte string literal not displayed */
// DataCollection restricts routing to providers that do not store request
// data when set to deny.
DataCollection DataCollection `` /* 189-byte string literal not displayed */
// ZDR restricts routing to zero data retention endpoints.
ZDR *bool `json:"zdr,omitempty" jsonschema_description:"Restricts routing to zero data retention endpoints."`
// Sort ranks providers by one metric instead of OpenRouter's default load
// balancing.
Sort ProviderSort `` /* 187-byte string literal not displayed */
// Quantizations restricts routing to providers serving the model at these
// quantization levels, e.g. int4, int8, fp8, fp16, bf16, or fp32. The
// set is not enumerated in the schema: OpenRouter adds levels as hardware
// gains them, and a closed list here would reject a level it accepts.
Quantizations []string `` /* 177-byte string literal not displayed */
// MaxPrice caps what the request may cost.
MaxPrice *MaxPrice `` /* 177-byte string literal not displayed */
// PreferredMinThroughput deprioritizes providers below this many output
// tokens per second. They stay eligible as a fallback.
PreferredMinThroughput *float64 `` /* 187-byte string literal not displayed */
// PreferredMaxLatency deprioritizes providers slower than this many
// seconds to first token. They stay eligible as a fallback.
PreferredMaxLatency *float64 `` /* 188-byte string literal not displayed */
}
ProviderRouting chooses which upstream providers may serve a request and in what order, sent as the API's provider object. This is the control the gateway exists for: the same model is served by several providers at different prices, speeds, and data policies.
Sort, PreferredMinThroughput, and PreferredMaxLatency also have an object form (a partition, or per-percentile thresholds) that this struct does not declare. Send the whole provider object through compat_oai.RequestConfig.Extra to reach it: an extra wins over the field it collides with, so the raw object replaces this one wholesale.
type ProviderSort ¶
type ProviderSort string
ProviderSort is the metric upstream providers are ranked by, replacing OpenRouter's default load balancing.
const ( // ProviderSortPrice ranks the cheapest provider first. ProviderSortPrice ProviderSort = "price" // ProviderSortThroughput ranks the fastest provider first. ProviderSortThroughput ProviderSort = "throughput" // ProviderSortLatency ranks the provider with the lowest time to first // token first. ProviderSortLatency ProviderSort = "latency" )
type ReasoningConfig ¶
type ReasoningConfig struct {
// Effort is how much reasoning to spend, from none to max. Vendors that
// budget in tokens rather than levels take MaxTokens instead.
Effort ReasoningEffort `` /* 220-byte string literal not displayed */
// MaxTokens is the exact token budget to reason with, sent as the API's
// max_tokens inside the reasoning object. It overrides Effort. Vendors
// that take a budget usually reject one under 1,024 tokens, which is a
// per-vendor limit rather than a documented API-wide one.
MaxTokens int `` /* 199-byte string literal not displayed */
// Exclude keeps the reasoning out of the response without stopping the
// model from reasoning.
Exclude *bool `` /* 132-byte string literal not displayed */
// Enabled turns reasoning on with the vendor's own defaults, which
// OpenRouter treats as medium effort. Effort and MaxTokens imply it.
Enabled *bool `` /* 169-byte string literal not displayed */
}
ReasoningConfig controls the reasoning a model does before it answers, sent as the API's reasoning object. See https://openrouter.ai/docs/use-cases/reasoning-tokens.
type ReasoningEffort ¶
type ReasoningEffort string
ReasoningEffort is how much reasoning a reasoning-capable model spends before it answers. OpenRouter normalizes the level across vendors, so the same value reaches an OpenAI, an Anthropic, and a Gemini model.
Which levels a model takes is the model's to decide: a level the upstream vendor does not offer is an error from OpenRouter rather than one from here.
const ( // ReasoningEffortNone disables reasoning. Models that always reason // reject it. ReasoningEffortNone ReasoningEffort = "none" // ReasoningEffortMinimal is the shallowest level that still reasons. ReasoningEffortMinimal ReasoningEffort = "minimal" // ReasoningEffortLow is fast reasoning, for latency-sensitive work. ReasoningEffortLow ReasoningEffort = "low" // ReasoningEffortMedium is the level [ReasoningConfig.Enabled] selects on // its own. ReasoningEffortMedium ReasoningEffort = "medium" // ReasoningEffortHigh is deeper thinking, for hard multi-step problems. ReasoningEffortHigh ReasoningEffort = "high" // ReasoningEffortXHigh is deeper still, offered by a few vendors. ReasoningEffortXHigh ReasoningEffort = "xhigh" // ReasoningEffortMax is the deepest level any vendor offers. ReasoningEffortMax ReasoningEffort = "max" )
type ServiceTier ¶
type ServiceTier string
ServiceTier selects how a request is scheduled and billed upstream.
It is declared here rather than reused from openai.ChatCompletionNewParamsServiceTier because the sets differ: a config advertising the SDK's type would omit "fast" and "scale".
const ( // ServiceTierAuto lets OpenRouter pick the tier. ServiceTierAuto ServiceTier = "auto" // ServiceTierDefault is standard scheduling and billing. ServiceTierDefault ServiceTier = "default" // ServiceTierFast buys faster scheduling. ServiceTierFast ServiceTier = "fast" // ServiceTierFlex trades latency for a lower rate. ServiceTierFlex ServiceTier = "flex" // ServiceTierPriority buys the fastest scheduling at the highest rate. ServiceTierPriority ServiceTier = "priority" // ServiceTierScale is the tier for sustained high volume. ServiceTierScale ServiceTier = "scale" )