1// Package vercel provides an implementation of the fantasy AI SDK for Vercel AI Gateway.
2package vercel
3
4import (
5 "encoding/json"
6
7 "charm.land/fantasy"
8)
9
10// Global type identifiers for Vercel-specific provider data.
11const (
12 TypeProviderOptions = Name + ".options"
13 TypeProviderMetadata = Name + ".metadata"
14)
15
16// Register Vercel provider-specific types with the global registry.
17func init() {
18 fantasy.RegisterProviderType(TypeProviderOptions, func(data []byte) (fantasy.ProviderOptionsData, error) {
19 var v ProviderOptions
20 if err := json.Unmarshal(data, &v); err != nil {
21 return nil, err
22 }
23 return &v, nil
24 })
25 fantasy.RegisterProviderType(TypeProviderMetadata, func(data []byte) (fantasy.ProviderOptionsData, error) {
26 var v ProviderMetadata
27 if err := json.Unmarshal(data, &v); err != nil {
28 return nil, err
29 }
30 return &v, nil
31 })
32}
33
34// ReasoningEffort represents the reasoning effort level for Vercel AI Gateway.
35type ReasoningEffort string
36
37const (
38 // ReasoningEffortNone disables reasoning.
39 ReasoningEffortNone ReasoningEffort = "none"
40 // ReasoningEffortMinimal represents minimal reasoning effort (~10% of max_tokens).
41 ReasoningEffortMinimal ReasoningEffort = "minimal"
42 // ReasoningEffortLow represents low reasoning effort (~20% of max_tokens).
43 ReasoningEffortLow ReasoningEffort = "low"
44 // ReasoningEffortMedium represents medium reasoning effort (~50% of max_tokens).
45 ReasoningEffortMedium ReasoningEffort = "medium"
46 // ReasoningEffortHigh represents high reasoning effort (~80% of max_tokens).
47 ReasoningEffortHigh ReasoningEffort = "high"
48 // ReasoningEffortXHigh represents extra high reasoning effort (~95% of max_tokens).
49 ReasoningEffortXHigh ReasoningEffort = "xhigh"
50)
51
52// ReasoningOptions represents reasoning configuration for Vercel AI Gateway.
53type ReasoningOptions struct {
54 // Enabled enables reasoning output. When true, the model will provide its reasoning process.
55 Enabled *bool `json:"enabled,omitempty"`
56 // MaxTokens is the maximum number of tokens to allocate for reasoning.
57 // Cannot be used with Effort.
58 MaxTokens *int64 `json:"max_tokens,omitempty"`
59 // Effort controls reasoning effort level.
60 // Mutually exclusive with MaxTokens.
61 Effort *ReasoningEffort `json:"effort,omitempty"`
62 // Exclude excludes reasoning content from the response but still generates it internally.
63 Exclude *bool `json:"exclude,omitempty"`
64}
65
66// GatewayProviderOptions represents provider routing preferences for Vercel AI Gateway.
67type GatewayProviderOptions struct {
68 // Order is the list of provider slugs to try in order (e.g. ["vertex", "anthropic"]).
69 Order []string `json:"order,omitempty"`
70 // Models is the list of fallback models to try if the primary model fails.
71 Models []string `json:"models,omitempty"`
72}
73
74// BYOKCredential represents a single provider credential for BYOK.
75type BYOKCredential struct {
76 APIKey string `json:"apiKey,omitempty"`
77}
78
79// BYOKOptions represents Bring Your Own Key options for Vercel AI Gateway.
80type BYOKOptions struct {
81 Anthropic map[string][]BYOKCredential `json:"anthropic,omitempty"`
82 OpenAI map[string][]BYOKCredential `json:"openai,omitempty"`
83 Vertex map[string][]BYOKCredential `json:"vertex,omitempty"`
84 Bedrock map[string][]BYOKCredential `json:"bedrock,omitempty"`
85}
86
87// ProviderOptions represents additional options for Vercel AI Gateway provider.
88type ProviderOptions struct {
89 // Reasoning configuration for models that support extended thinking.
90 Reasoning *ReasoningOptions `json:"reasoning,omitempty"`
91 // ProviderOptions for gateway routing preferences.
92 ProviderOptions *GatewayProviderOptions `json:"providerOptions,omitempty"`
93 // BYOK for request-scoped provider credentials.
94 BYOK *BYOKOptions `json:"byok,omitempty"`
95 // User is a unique identifier representing your end-user.
96 User *string `json:"user,omitempty"`
97 // LogitBias modifies the likelihood of specified tokens appearing in the completion.
98 LogitBias map[string]int64 `json:"logit_bias,omitempty"`
99 // LogProbs returns the log probabilities of the tokens.
100 LogProbs *bool `json:"logprobs,omitempty"`
101 // TopLogProbs is the number of top log probabilities to return.
102 TopLogProbs *int64 `json:"top_logprobs,omitempty"`
103 // ParallelToolCalls enables parallel function calling during tool use.
104 ParallelToolCalls *bool `json:"parallel_tool_calls,omitempty"`
105 // ExtraBody for additional request body fields.
106 ExtraBody map[string]any `json:"extra_body,omitempty"`
107}
108
109// Options implements the ProviderOptionsData interface for ProviderOptions.
110func (*ProviderOptions) Options() {}
111
112// MarshalJSON implements custom JSON marshaling with type info for ProviderOptions.
113func (o ProviderOptions) MarshalJSON() ([]byte, error) {
114 type plain ProviderOptions
115 return fantasy.MarshalProviderType(TypeProviderOptions, plain(o))
116}
117
118// UnmarshalJSON implements custom JSON unmarshaling with type info for ProviderOptions.
119func (o *ProviderOptions) UnmarshalJSON(data []byte) error {
120 type plain ProviderOptions
121 var p plain
122 if err := fantasy.UnmarshalProviderType(data, &p); err != nil {
123 return err
124 }
125 *o = ProviderOptions(p)
126 return nil
127}
128
129// ProviderMetadata represents metadata from Vercel AI Gateway provider.
130type ProviderMetadata struct {
131 Provider string `json:"provider,omitempty"`
132}
133
134// Options implements the ProviderOptionsData interface for ProviderMetadata.
135func (*ProviderMetadata) Options() {}
136
137// MarshalJSON implements custom JSON marshaling with type info for ProviderMetadata.
138func (m ProviderMetadata) MarshalJSON() ([]byte, error) {
139 type plain ProviderMetadata
140 return fantasy.MarshalProviderType(TypeProviderMetadata, plain(m))
141}
142
143// UnmarshalJSON implements custom JSON unmarshaling with type info for ProviderMetadata.
144func (m *ProviderMetadata) UnmarshalJSON(data []byte) error {
145 type plain ProviderMetadata
146 var p plain
147 if err := fantasy.UnmarshalProviderType(data, &p); err != nil {
148 return err
149 }
150 *m = ProviderMetadata(p)
151 return nil
152}
153
154// ReasoningDetail represents a reasoning detail from Vercel AI Gateway.
155type ReasoningDetail struct {
156 ID string `json:"id,omitempty"`
157 Type string `json:"type,omitempty"`
158 Text string `json:"text,omitempty"`
159 Data string `json:"data,omitempty"`
160 Format string `json:"format,omitempty"`
161 Summary string `json:"summary,omitempty"`
162 Signature string `json:"signature,omitempty"`
163 Index int `json:"index"`
164}
165
166// ReasoningData represents reasoning data from Vercel AI Gateway response.
167type ReasoningData struct {
168 Reasoning string `json:"reasoning,omitempty"`
169 ReasoningDetails []ReasoningDetail `json:"reasoning_details,omitempty"`
170}
171
172// ReasoningEffortOption creates a pointer to a ReasoningEffort value.
173func ReasoningEffortOption(e ReasoningEffort) *ReasoningEffort {
174 return &e
175}
176
177// NewProviderOptions creates new provider options for Vercel.
178func NewProviderOptions(opts *ProviderOptions) fantasy.ProviderOptions {
179 return fantasy.ProviderOptions{
180 Name: opts,
181 }
182}
183
184// ParseOptions parses provider options from a map for Vercel.
185func ParseOptions(data map[string]any) (*ProviderOptions, error) {
186 var options ProviderOptions
187 if err := fantasy.ParseOptions(data, &options); err != nil {
188 return nil, err
189 }
190 return &options, nil
191}