1package openrouter
2
3import (
4 "github.com/charmbracelet/fantasy/ai"
5 "github.com/charmbracelet/fantasy/openai"
6 openaisdk "github.com/openai/openai-go/v2"
7 "github.com/openai/openai-go/v2/option"
8)
9
10type options struct {
11 openaiOptions []openai.Option
12}
13
14const (
15 DefaultURL = "https://openrouter.ai/api/v1"
16)
17
18type Option = func(*options)
19
20func prepareCallWithOptions(model ai.LanguageModel, params *openaisdk.ChatCompletionNewParams, call ai.Call) ([]ai.CallWarning, error) {
21 providerOptions := &ProviderOptions{}
22 if v, ok := call.ProviderOptions[Name]; ok {
23 providerOptions, ok = v.(*ProviderOptions)
24 if !ok {
25 return nil, ai.NewInvalidArgumentError("providerOptions", "openrouter provider options should be *openrouter.ProviderOptions", nil)
26 }
27 }
28 _ = providerOptions
29
30 // HANDLE OPENROUTER call modification here
31
32 return nil, nil
33}
34
35func New(opts ...Option) ai.Provider {
36 providerOptions := options{
37 openaiOptions: []openai.Option{
38 openai.WithBaseURL(DefaultURL),
39 openai.WithLanguageModelOptions(
40 openai.WithPrepareLanguageModelCallFunc(prepareCallWithOptions),
41 ),
42 },
43 }
44 for _, o := range opts {
45 o(&providerOptions)
46 }
47 return openai.New(providerOptions.openaiOptions...)
48}
49
50func WithAPIKey(apiKey string) Option {
51 return func(o *options) {
52 o.openaiOptions = append(o.openaiOptions, openai.WithAPIKey(apiKey))
53 }
54}
55
56func WithName(name string) Option {
57 return func(o *options) {
58 o.openaiOptions = append(o.openaiOptions, openai.WithName(name))
59 }
60}
61
62func WithHeaders(headers map[string]string) Option {
63 return func(o *options) {
64 o.openaiOptions = append(o.openaiOptions, openai.WithHeaders(headers))
65 }
66}
67
68func WithHTTPClient(client option.HTTPClient) Option {
69 return func(o *options) {
70 o.openaiOptions = append(o.openaiOptions, openai.WithHTTPClient(client))
71 }
72}