provider_options.go

  1// Package openrouter provides an implementation of the fantasy AI SDK for OpenRouter's language models.
  2package openrouter
  3
  4import (
  5	"encoding/json"
  6
  7	"charm.land/fantasy"
  8)
  9
 10// ReasoningEffort represents the reasoning effort level for OpenRouter models.
 11type ReasoningEffort string
 12
 13const (
 14	// ReasoningEffortLow represents low reasoning effort.
 15	ReasoningEffortLow ReasoningEffort = "low"
 16	// ReasoningEffortMedium represents medium reasoning effort.
 17	ReasoningEffortMedium ReasoningEffort = "medium"
 18	// ReasoningEffortHigh represents high reasoning effort.
 19	ReasoningEffortHigh ReasoningEffort = "high"
 20)
 21
 22// Global type identifiers for OpenRouter-specific provider data.
 23const (
 24	TypeProviderOptions  = Name + ".options"
 25	TypeProviderMetadata = Name + ".metadata"
 26)
 27
 28// Register OpenRouter provider-specific types with the global registry.
 29func init() {
 30	fantasy.RegisterProviderType(TypeProviderOptions, func(data []byte) (fantasy.ProviderOptionsData, error) {
 31		var v ProviderOptions
 32		if err := json.Unmarshal(data, &v); err != nil {
 33			return nil, err
 34		}
 35		return &v, nil
 36	})
 37	fantasy.RegisterProviderType(TypeProviderMetadata, func(data []byte) (fantasy.ProviderOptionsData, error) {
 38		var v ProviderMetadata
 39		if err := json.Unmarshal(data, &v); err != nil {
 40			return nil, err
 41		}
 42		return &v, nil
 43	})
 44}
 45
 46// PromptTokensDetails represents details about prompt tokens for OpenRouter.
 47type PromptTokensDetails struct {
 48	CachedTokens int64 `json:"cached_tokens"`
 49}
 50
 51// CompletionTokensDetails represents details about completion tokens for OpenRouter.
 52type CompletionTokensDetails struct {
 53	ReasoningTokens int64 `json:"reasoning_tokens"`
 54}
 55
 56// CostDetails represents cost details for OpenRouter.
 57type CostDetails struct {
 58	UpstreamInferenceCost            float64 `json:"upstream_inference_cost"`
 59	UpstreamInferencePromptCost      float64 `json:"upstream_inference_prompt_cost"`
 60	UpstreamInferenceCompletionsCost float64 `json:"upstream_inference_completions_cost"`
 61}
 62
 63// UsageAccounting represents usage accounting details for OpenRouter.
 64type UsageAccounting struct {
 65	PromptTokens            int64                   `json:"prompt_tokens"`
 66	PromptTokensDetails     PromptTokensDetails     `json:"prompt_tokens_details"`
 67	CompletionTokens        int64                   `json:"completion_tokens"`
 68	CompletionTokensDetails CompletionTokensDetails `json:"completion_tokens_details"`
 69	TotalTokens             int64                   `json:"total_tokens"`
 70	Cost                    float64                 `json:"cost"`
 71	CostDetails             CostDetails             `json:"cost_details"`
 72}
 73
 74// ProviderMetadata represents metadata from OpenRouter provider.
 75type ProviderMetadata struct {
 76	Provider string          `json:"provider"`
 77	Usage    UsageAccounting `json:"usage"`
 78}
 79
 80// Options implements the ProviderOptionsData interface for ProviderMetadata.
 81func (*ProviderMetadata) Options() {}
 82
 83// MarshalJSON implements custom JSON marshaling with type info for ProviderMetadata.
 84func (m ProviderMetadata) MarshalJSON() ([]byte, error) {
 85	type plain ProviderMetadata
 86	return fantasy.MarshalProviderType(TypeProviderMetadata, plain(m))
 87}
 88
 89// UnmarshalJSON implements custom JSON unmarshaling with type info for ProviderMetadata.
 90func (m *ProviderMetadata) UnmarshalJSON(data []byte) error {
 91	type plain ProviderMetadata
 92	var p plain
 93	if err := fantasy.UnmarshalProviderType(data, &p); err != nil {
 94		return err
 95	}
 96	*m = ProviderMetadata(p)
 97	return nil
 98}
 99
100// ReasoningOptions represents reasoning options for OpenRouter.
101type ReasoningOptions struct {
102	// Whether reasoning is enabled
103	Enabled *bool `json:"enabled,omitempty"`
104	// Whether to exclude reasoning from the response
105	Exclude *bool `json:"exclude,omitempty"`
106	// Maximum number of tokens to use for reasoning
107	MaxTokens *int64 `json:"max_tokens,omitempty"`
108	// Reasoning effort level: "low" | "medium" | "high"
109	Effort *ReasoningEffort `json:"effort,omitempty"`
110}
111
112// Provider represents provider routing preferences for OpenRouter.
113type Provider struct {
114	// List of provider slugs to try in order (e.g. ["anthropic", "openai"])
115	Order []string `json:"order,omitempty"`
116	// Whether to allow backup providers when primary is unavailable (default: true)
117	AllowFallbacks *bool `json:"allow_fallbacks,omitempty"`
118	// Only use providers that support all parameters in your request (default: false)
119	RequireParameters *bool `json:"require_parameters,omitempty"`
120	// Control whether to use providers that may store data: "allow" | "deny"
121	DataCollection *string `json:"data_collection,omitempty"`
122	// List of provider slugs to allow for this request
123	Only []string `json:"only,omitempty"`
124	// List of provider slugs to skip for this request
125	Ignore []string `json:"ignore,omitempty"`
126	// List of quantization levels to filter by (e.g. ["int4", "int8"])
127	Quantizations []string `json:"quantizations,omitempty"`
128	// Sort providers by "price" | "throughput" | "latency"
129	Sort *string `json:"sort,omitempty"`
130}
131
132// ProviderOptions represents additional options for OpenRouter provider.
133type ProviderOptions struct {
134	Reasoning    *ReasoningOptions `json:"reasoning,omitempty"`
135	ExtraBody    map[string]any    `json:"extra_body,omitempty"`
136	IncludeUsage *bool             `json:"include_usage,omitempty"`
137	// Modify the likelihood of specified tokens appearing in the completion.
138	// Accepts a map that maps tokens (specified by their token ID) to an associated bias value from -100 to 100.
139	// The bias is added to the logits generated by the model prior to sampling.
140	LogitBias map[string]int64 `json:"logit_bias,omitempty"`
141	// Return the log probabilities of the tokens. Including logprobs will increase the response size.
142	// Setting to true will return the log probabilities of the tokens that were generated.
143	LogProbs *bool `json:"log_probs,omitempty"`
144	// Whether to enable parallel function calling during tool use. Default to true.
145	ParallelToolCalls *bool `json:"parallel_tool_calls,omitempty"`
146	// A unique identifier representing your end-user, which can help OpenRouter to monitor and detect abuse.
147	User *string `json:"user,omitempty"`
148	// Provider routing preferences to control request routing behavior
149	Provider *Provider `json:"provider,omitempty"`
150	// TODO: add the web search plugin config
151}
152
153// Options implements the ProviderOptionsData interface for ProviderOptions.
154func (*ProviderOptions) Options() {}
155
156// MarshalJSON implements custom JSON marshaling with type info for ProviderOptions.
157func (o ProviderOptions) MarshalJSON() ([]byte, error) {
158	type plain ProviderOptions
159	return fantasy.MarshalProviderType(TypeProviderOptions, plain(o))
160}
161
162// UnmarshalJSON implements custom JSON unmarshaling with type info for ProviderOptions.
163func (o *ProviderOptions) UnmarshalJSON(data []byte) error {
164	type plain ProviderOptions
165	var p plain
166	if err := fantasy.UnmarshalProviderType(data, &p); err != nil {
167		return err
168	}
169	*o = ProviderOptions(p)
170	return nil
171}
172
173// ReasoningDetail represents a reasoning detail for OpenRouter.
174type ReasoningDetail struct {
175	ID        string `json:"id,omitempty"`
176	Type      string `json:"type,omitempty"`
177	Text      string `json:"text,omitempty"`
178	Data      string `json:"data,omitempty"`
179	Format    string `json:"format,omitempty"`
180	Summary   string `json:"summary,omitempty"`
181	Signature string `json:"signature,omitempty"`
182	Index     int    `json:"index"`
183}
184
185// ReasoningData represents reasoning data for OpenRouter.
186type ReasoningData struct {
187	Reasoning        string            `json:"reasoning"`
188	ReasoningDetails []ReasoningDetail `json:"reasoning_details"`
189}
190
191// ReasoningEffortOption creates a pointer to a ReasoningEffort value for OpenRouter.
192func ReasoningEffortOption(e ReasoningEffort) *ReasoningEffort {
193	return &e
194}
195
196// NewProviderOptions creates new provider options for OpenRouter.
197func NewProviderOptions(opts *ProviderOptions) fantasy.ProviderOptions {
198	return fantasy.ProviderOptions{
199		Name: opts,
200	}
201}
202
203// ParseOptions parses provider options from a map for OpenRouter.
204func ParseOptions(data map[string]any) (*ProviderOptions, error) {
205	var options ProviderOptions
206	if err := fantasy.ParseOptions(data, &options); err != nil {
207		return nil, err
208	}
209	return &options, nil
210}