openrouter.go

 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}