openrouter.go

 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)
18
19type Option = func(*options)
20
21func New(opts ...Option) ai.Provider {
22	providerOptions := options{
23		openaiOptions: []openai.Option{
24			openai.WithBaseURL(DefaultURL),
25			openai.WithLanguageModelOptions(
26				openai.WithPrepareLanguageModelCallFunc(prepareLanguageModelCall),
27			),
28		},
29	}
30	for _, o := range opts {
31		o(&providerOptions)
32	}
33	return openai.New(providerOptions.openaiOptions...)
34}
35
36func WithAPIKey(apiKey string) Option {
37	return func(o *options) {
38		o.openaiOptions = append(o.openaiOptions, openai.WithAPIKey(apiKey))
39	}
40}
41
42func WithName(name string) Option {
43	return func(o *options) {
44		o.openaiOptions = append(o.openaiOptions, openai.WithName(name))
45	}
46}
47
48func WithHeaders(headers map[string]string) Option {
49	return func(o *options) {
50		o.openaiOptions = append(o.openaiOptions, openai.WithHeaders(headers))
51	}
52}
53
54func WithHTTPClient(client option.HTTPClient) Option {
55	return func(o *options) {
56		o.openaiOptions = append(o.openaiOptions, openai.WithHTTPClient(client))
57	}
58}
59
60func structToMapJSON(s any) (map[string]any, error) {
61	var result map[string]any
62	jsonBytes, err := json.Marshal(s)
63	if err != nil {
64		return nil, err
65	}
66	err = json.Unmarshal(jsonBytes, &result)
67	if err != nil {
68		return nil, err
69	}
70	return result, nil
71}