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