vercel.go

  1// Package vercel provides an implementation of the fantasy AI SDK for Vercel AI Gateway.
  2package vercel
  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	objectMode           fantasy.ObjectMode
 15}
 16
 17const (
 18	// DefaultURL is the default URL for the Vercel AI Gateway API.
 19	DefaultURL = "https://ai-gateway.vercel.sh/v1"
 20	// Name is the name of the Vercel provider.
 21	Name = "vercel"
 22)
 23
 24// Option defines a function that configures Vercel provider options.
 25type Option = func(*options)
 26
 27// New creates a new Vercel AI Gateway provider with the given options.
 28func New(opts ...Option) (fantasy.Provider, error) {
 29	providerOptions := options{
 30		openaiOptions: []openai.Option{
 31			openai.WithName(Name),
 32			openai.WithBaseURL(DefaultURL),
 33		},
 34		languageModelOptions: []openai.LanguageModelOption{
 35			openai.WithLanguageModelPrepareCallFunc(languagePrepareModelCall),
 36			openai.WithLanguageModelUsageFunc(languageModelUsage),
 37			openai.WithLanguageModelStreamUsageFunc(languageModelStreamUsage),
 38			openai.WithLanguageModelStreamExtraFunc(languageModelStreamExtra),
 39			openai.WithLanguageModelExtraContentFunc(languageModelExtraContent),
 40			openai.WithLanguageModelToPromptFunc(languageModelToPrompt),
 41		},
 42		objectMode: fantasy.ObjectModeTool, // Default to tool mode for vercel
 43	}
 44	for _, o := range opts {
 45		o(&providerOptions)
 46	}
 47
 48	// Handle object mode: convert unsupported modes to tool
 49	// Vercel AI Gateway doesn't support native JSON mode, so we use tool or text
 50	objectMode := providerOptions.objectMode
 51	if objectMode == fantasy.ObjectModeAuto || objectMode == fantasy.ObjectModeJSON {
 52		objectMode = fantasy.ObjectModeTool
 53	}
 54
 55	providerOptions.openaiOptions = append(
 56		providerOptions.openaiOptions,
 57		openai.WithSDKOptions(providerOptions.sdkOptions...),
 58		openai.WithLanguageModelOptions(providerOptions.languageModelOptions...),
 59		openai.WithObjectMode(objectMode),
 60	)
 61	return openai.New(providerOptions.openaiOptions...)
 62}
 63
 64// WithAPIKey sets the API key for the Vercel provider.
 65func WithAPIKey(apiKey string) Option {
 66	return func(o *options) {
 67		o.openaiOptions = append(o.openaiOptions, openai.WithAPIKey(apiKey))
 68	}
 69}
 70
 71// WithBaseURL sets the base URL for the Vercel provider.
 72func WithBaseURL(url string) Option {
 73	return func(o *options) {
 74		o.openaiOptions = append(o.openaiOptions, openai.WithBaseURL(url))
 75	}
 76}
 77
 78// WithName sets the name for the Vercel provider.
 79func WithName(name string) Option {
 80	return func(o *options) {
 81		o.openaiOptions = append(o.openaiOptions, openai.WithName(name))
 82	}
 83}
 84
 85// WithHeaders sets the headers for the Vercel provider.
 86func WithHeaders(headers map[string]string) Option {
 87	return func(o *options) {
 88		o.openaiOptions = append(o.openaiOptions, openai.WithHeaders(headers))
 89	}
 90}
 91
 92// WithHTTPClient sets the HTTP client for the Vercel provider.
 93func WithHTTPClient(client option.HTTPClient) Option {
 94	return func(o *options) {
 95		o.openaiOptions = append(o.openaiOptions, openai.WithHTTPClient(client))
 96	}
 97}
 98
 99// WithSDKOptions sets the SDK options for the Vercel provider.
100func WithSDKOptions(opts ...option.RequestOption) Option {
101	return func(o *options) {
102		o.sdkOptions = append(o.sdkOptions, opts...)
103	}
104}
105
106// WithObjectMode sets the object generation mode for the Vercel provider.
107// Supported modes: ObjectModeTool, ObjectModeText.
108// ObjectModeAuto and ObjectModeJSON are automatically converted to ObjectModeTool
109// since Vercel AI Gateway doesn't support native JSON mode.
110func WithObjectMode(om fantasy.ObjectMode) Option {
111	return func(o *options) {
112		o.objectMode = om
113	}
114}