1package openrouter
 2
 3import (
 4	"encoding/json"
 5
 6	"github.com/charmbracelet/fantasy/ai"
 7	"github.com/charmbracelet/fantasy/openai"
 8	"github.com/openai/openai-go/v2/option"
 9)
10
11type options struct {
12	openaiOptions []openai.Option
13}
14
15const (
16	DefaultURL = "https://openrouter.ai/api/v1"
17	Name       = "openrouter"
18)
19
20type Option = func(*options)
21
22func New(opts ...Option) ai.Provider {
23	providerOptions := options{
24		openaiOptions: []openai.Option{
25			openai.WithName(Name),
26			openai.WithBaseURL(DefaultURL),
27			openai.WithLanguageModelOptions(
28				openai.WithLanguageModelPrepareCallFunc(languagePrepareModelCall),
29				openai.WithLanguageModelUsageFunc(languageModelUsage),
30				openai.WithLanguageModelStreamUsageFunc(languageModelStreamUsage),
31				openai.WithLanguageModelStreamExtraFunc(languageModelStreamExtra),
32				openai.WithLanguageModelExtraContentFunc(languageModelExtraContent),
33				openai.WithLanguageModelMapFinishReasonFunc(languageModelMapFinishReason),
34			),
35		},
36	}
37	for _, o := range opts {
38		o(&providerOptions)
39	}
40	return openai.New(providerOptions.openaiOptions...)
41}
42
43func WithAPIKey(apiKey string) Option {
44	return func(o *options) {
45		o.openaiOptions = append(o.openaiOptions, openai.WithAPIKey(apiKey))
46	}
47}
48
49func WithName(name string) Option {
50	return func(o *options) {
51		o.openaiOptions = append(o.openaiOptions, openai.WithName(name))
52	}
53}
54
55func WithHeaders(headers map[string]string) Option {
56	return func(o *options) {
57		o.openaiOptions = append(o.openaiOptions, openai.WithHeaders(headers))
58	}
59}
60
61func WithHTTPClient(client option.HTTPClient) Option {
62	return func(o *options) {
63		o.openaiOptions = append(o.openaiOptions, openai.WithHTTPClient(client))
64	}
65}
66
67func structToMapJSON(s any) (map[string]any, error) {
68	var result map[string]any
69	jsonBytes, err := json.Marshal(s)
70	if err != nil {
71		return nil, err
72	}
73	err = json.Unmarshal(jsonBytes, &result)
74	if err != nil {
75		return nil, err
76	}
77	return result, nil
78}