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