1package openrouter
  2
  3import (
  4	"charm.land/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 ReasoningMetadata struct {
 47	Signature string `json:"signature"`
 48}
 49
 50func (*ReasoningMetadata) Options() {}
 51
 52type ReasoningOptions struct {
 53	// Whether reasoning is enabled
 54	Enabled *bool `json:"enabled,omitempty"`
 55	// Whether to exclude reasoning from the response
 56	Exclude *bool `json:"exclude,omitempty"`
 57	// Maximum number of tokens to use for reasoning
 58	MaxTokens *int64 `json:"max_tokens,omitempty"`
 59	// Reasoning effort level: "low" | "medium" | "high"
 60	Effort *ReasoningEffort `json:"effort,omitempty"`
 61}
 62
 63type Provider struct {
 64	// List of provider slugs to try in order (e.g. ["anthropic", "openai"])
 65	Order []string `json:"order,omitempty"`
 66	// Whether to allow backup providers when primary is unavailable (default: true)
 67	AllowFallbacks *bool `json:"allow_fallbacks,omitempty"`
 68	// Only use providers that support all parameters in your request (default: false)
 69	RequireParameters *bool `json:"require_parameters,omitempty"`
 70	// Control whether to use providers that may store data: "allow" | "deny"
 71	DataCollection *string `json:"data_collection,omitempty"`
 72	// List of provider slugs to allow for this request
 73	Only []string `json:"only,omitempty"`
 74	// List of provider slugs to skip for this request
 75	Ignore []string `json:"ignore,omitempty"`
 76	// List of quantization levels to filter by (e.g. ["int4", "int8"])
 77	Quantizations []string `json:"quantizations,omitempty"`
 78	// Sort providers by "price" | "throughput" | "latency"
 79	Sort *string `json:"sort,omitempty"`
 80}
 81
 82type ProviderOptions struct {
 83	Reasoning    *ReasoningOptions `json:"reasoning,omitempty"`
 84	ExtraBody    map[string]any    `json:"extra_body,omitempty"`
 85	IncludeUsage *bool             `json:"include_usage,omitempty"`
 86	// Modify the likelihood of specified tokens appearing in the completion.
 87	// Accepts a map that maps tokens (specified by their token ID) to an associated bias value from -100 to 100.
 88	// The bias is added to the logits generated by the model prior to sampling.
 89	LogitBias map[string]int64 `json:"logit_bias,omitempty"`
 90	// Return the log probabilities of the tokens. Including logprobs will increase the response size.
 91	// Setting to true will return the log probabilities of the tokens that were generated.
 92	LogProbs *bool `json:"log_probs,omitempty"`
 93	// Whether to enable parallel function calling during tool use. Default to true.
 94	ParallelToolCalls *bool `json:"parallel_tool_calls,omitempty"`
 95	// A unique identifier representing your end-user, which can help OpenRouter to monitor and detect abuse.
 96	User *string `json:"user,omitempty"`
 97	// Provider routing preferences to control request routing behavior
 98	Provider *Provider `json:"provider,omitempty"`
 99	// TODO: add the web search plugin config
100}
101
102func (*ProviderOptions) Options() {}
103
104type ReasoningDetail struct {
105	Type      string `json:"type"`
106	Text      string `json:"text"`
107	Summary   string `json:"summary"`
108	Signature string `json:"signature"`
109}
110type ReasoningData struct {
111	Reasoning        string            `json:"reasoning"`
112	ReasoningDetails []ReasoningDetail `json:"reasoning_details"`
113}
114
115func ReasoningEffortOption(e ReasoningEffort) *ReasoningEffort {
116	return &e
117}
118
119func NewProviderOptions(opts *ProviderOptions) ai.ProviderOptions {
120	return ai.ProviderOptions{
121		Name: opts,
122	}
123}
124
125func ParseOptions(data map[string]any) (*ProviderOptions, error) {
126	var options ProviderOptions
127	if err := ai.ParseOptions(data, &options); err != nil {
128		return nil, err
129	}
130	return &options, nil
131}