1// Package openaicompat provides an implementation of the fantasy AI SDK for OpenAI-compatible APIs.
2package openaicompat
3
4import (
5 "charm.land/fantasy"
6 "charm.land/fantasy/providers/openai"
7 "github.com/openai/openai-go/v2/option"
8)
9
10type options struct {
11 openaiOptions []openai.Option
12 languageModelOptions []openai.LanguageModelOption
13 sdkOptions []option.RequestOption
14}
15
16const (
17 // Name is the name of the OpenAI-compatible provider.
18 Name = "openai-compat"
19)
20
21// Option defines a function that configures OpenAI-compatible provider options.
22type Option = func(*options)
23
24// New creates a new OpenAI-compatible provider with the given options.
25func New(opts ...Option) fantasy.Provider {
26 providerOptions := options{
27 openaiOptions: []openai.Option{
28 openai.WithName(Name),
29 },
30 languageModelOptions: []openai.LanguageModelOption{
31 openai.WithLanguageModelPrepareCallFunc(PrepareCallFunc),
32 openai.WithLanguageModelStreamExtraFunc(StreamExtraFunc),
33 openai.WithLanguageModelExtraContentFunc(ExtraContentFunc),
34 },
35 }
36 for _, o := range opts {
37 o(&providerOptions)
38 }
39
40 providerOptions.openaiOptions = append(
41 providerOptions.openaiOptions,
42 openai.WithSDKOptions(providerOptions.sdkOptions...),
43 openai.WithLanguageModelOptions(providerOptions.languageModelOptions...),
44 )
45 return openai.New(providerOptions.openaiOptions...)
46}
47
48// WithBaseURL sets the base URL for the OpenAI-compatible provider.
49func WithBaseURL(url string) Option {
50 return func(o *options) {
51 o.openaiOptions = append(o.openaiOptions, openai.WithBaseURL(url))
52 }
53}
54
55// WithAPIKey sets the API key for the OpenAI-compatible provider.
56func WithAPIKey(apiKey string) Option {
57 return func(o *options) {
58 o.openaiOptions = append(o.openaiOptions, openai.WithAPIKey(apiKey))
59 }
60}
61
62// WithName sets the name for the OpenAI-compatible provider.
63func WithName(name string) Option {
64 return func(o *options) {
65 o.openaiOptions = append(o.openaiOptions, openai.WithName(name))
66 }
67}
68
69// WithHeaders sets the headers for the OpenAI-compatible provider.
70func WithHeaders(headers map[string]string) Option {
71 return func(o *options) {
72 o.openaiOptions = append(o.openaiOptions, openai.WithHeaders(headers))
73 }
74}
75
76// WithHTTPClient sets the HTTP client for the OpenAI-compatible provider.
77func WithHTTPClient(client option.HTTPClient) Option {
78 return func(o *options) {
79 o.openaiOptions = append(o.openaiOptions, openai.WithHTTPClient(client))
80 }
81}
82
83// WithSDKOptions sets the SDK options for the OpenAI-compatible provider.
84func WithSDKOptions(opts ...option.RequestOption) Option {
85 return func(o *options) {
86 o.sdkOptions = append(o.sdkOptions, opts...)
87 }
88}