provider_options.go

  1// Package anthropic provides an implementation of the fantasy AI SDK for Anthropic's language models.
  2package anthropic
  3
  4import (
  5	"encoding/json"
  6
  7	"charm.land/fantasy"
  8)
  9
 10// Effort represents the output effort level for Anthropic models.
 11//
 12// This maps to Messages API `output_config.effort`.
 13type Effort string
 14
 15const (
 16	// EffortLow represents low output effort.
 17	EffortLow Effort = "low"
 18	// EffortMedium represents medium output effort.
 19	EffortMedium Effort = "medium"
 20	// EffortHigh represents high output effort.
 21	EffortHigh Effort = "high"
 22	// EffortXHigh represents extra-high output effort.
 23	EffortXHigh Effort = "xhigh"
 24	// EffortMax represents maximum output effort.
 25	EffortMax Effort = "max"
 26)
 27
 28// Global type identifiers for Anthropic-specific provider data.
 29const (
 30	TypeProviderOptions         = Name + ".options"
 31	TypeReasoningOptionMetadata = Name + ".reasoning_metadata"
 32	TypeProviderCacheControl    = Name + ".cache_control_options"
 33	TypeWebSearchResultMetadata = Name + ".web_search_result_metadata"
 34)
 35
 36// Register Anthropic provider-specific types with the global registry.
 37func init() {
 38	fantasy.RegisterProviderType(TypeProviderOptions, func(data []byte) (fantasy.ProviderOptionsData, error) {
 39		var v ProviderOptions
 40		if err := json.Unmarshal(data, &v); err != nil {
 41			return nil, err
 42		}
 43		return &v, nil
 44	})
 45	fantasy.RegisterProviderType(TypeReasoningOptionMetadata, func(data []byte) (fantasy.ProviderOptionsData, error) {
 46		var v ReasoningOptionMetadata
 47		if err := json.Unmarshal(data, &v); err != nil {
 48			return nil, err
 49		}
 50		return &v, nil
 51	})
 52	fantasy.RegisterProviderType(TypeProviderCacheControl, func(data []byte) (fantasy.ProviderOptionsData, error) {
 53		var v ProviderCacheControlOptions
 54		if err := json.Unmarshal(data, &v); err != nil {
 55			return nil, err
 56		}
 57		return &v, nil
 58	})
 59	fantasy.RegisterProviderType(TypeWebSearchResultMetadata, func(data []byte) (fantasy.ProviderOptionsData, error) {
 60		var v WebSearchResultMetadata
 61		if err := json.Unmarshal(data, &v); err != nil {
 62			return nil, err
 63		}
 64		return &v, nil
 65	})
 66}
 67
 68// ProviderOptions represents additional options for the Anthropic provider.
 69type ProviderOptions struct {
 70	SendReasoning          *bool                   `json:"send_reasoning"`
 71	Thinking               *ThinkingProviderOption `json:"thinking"`
 72	Effort                 *Effort                 `json:"effort"`
 73	DisableParallelToolUse *bool                   `json:"disable_parallel_tool_use"`
 74}
 75
 76// Options implements the ProviderOptions interface.
 77func (o *ProviderOptions) Options() {}
 78
 79// MarshalJSON implements custom JSON marshaling with type info for ProviderOptions.
 80func (o ProviderOptions) MarshalJSON() ([]byte, error) {
 81	type plain ProviderOptions
 82	return fantasy.MarshalProviderType(TypeProviderOptions, plain(o))
 83}
 84
 85// UnmarshalJSON implements custom JSON unmarshaling with type info for ProviderOptions.
 86func (o *ProviderOptions) UnmarshalJSON(data []byte) error {
 87	type plain ProviderOptions
 88	var p plain
 89	if err := fantasy.UnmarshalProviderType(data, &p); err != nil {
 90		return err
 91	}
 92	*o = ProviderOptions(p)
 93	return nil
 94}
 95
 96// ThinkingProviderOption represents thinking options for the Anthropic provider.
 97type ThinkingProviderOption struct {
 98	BudgetTokens int64 `json:"budget_tokens"`
 99}
100
101// ReasoningOptionMetadata represents reasoning metadata for the Anthropic provider.
102type ReasoningOptionMetadata struct {
103	Signature    string `json:"signature"`
104	RedactedData string `json:"redacted_data"`
105}
106
107// Options implements the ProviderOptions interface.
108func (*ReasoningOptionMetadata) Options() {}
109
110// MarshalJSON implements custom JSON marshaling with type info for ReasoningOptionMetadata.
111func (m ReasoningOptionMetadata) MarshalJSON() ([]byte, error) {
112	type plain ReasoningOptionMetadata
113	return fantasy.MarshalProviderType(TypeReasoningOptionMetadata, plain(m))
114}
115
116// UnmarshalJSON implements custom JSON unmarshaling with type info for ReasoningOptionMetadata.
117func (m *ReasoningOptionMetadata) UnmarshalJSON(data []byte) error {
118	type plain ReasoningOptionMetadata
119	var p plain
120	if err := fantasy.UnmarshalProviderType(data, &p); err != nil {
121		return err
122	}
123	*m = ReasoningOptionMetadata(p)
124	return nil
125}
126
127// ProviderCacheControlOptions represents cache control options for the Anthropic provider.
128type ProviderCacheControlOptions struct {
129	CacheControl CacheControl `json:"cache_control"`
130}
131
132// Options implements the ProviderOptions interface.
133func (*ProviderCacheControlOptions) Options() {}
134
135// MarshalJSON implements custom JSON marshaling with type info for ProviderCacheControlOptions.
136func (o ProviderCacheControlOptions) MarshalJSON() ([]byte, error) {
137	type plain ProviderCacheControlOptions
138	return fantasy.MarshalProviderType(TypeProviderCacheControl, plain(o))
139}
140
141// UnmarshalJSON implements custom JSON unmarshaling with type info for ProviderCacheControlOptions.
142func (o *ProviderCacheControlOptions) UnmarshalJSON(data []byte) error {
143	type plain ProviderCacheControlOptions
144	var p plain
145	if err := fantasy.UnmarshalProviderType(data, &p); err != nil {
146		return err
147	}
148	*o = ProviderCacheControlOptions(p)
149	return nil
150}
151
152// WebSearchResultItem represents a single web search result for round-tripping.
153type WebSearchResultItem struct {
154	URL              string `json:"url"`
155	Title            string `json:"title"`
156	EncryptedContent string `json:"encrypted_content"`
157	// PageAge may be empty when the API does not return age info.
158	PageAge string `json:"page_age,omitempty"`
159}
160
161// WebSearchResultMetadata stores web search results from Anthropic's
162// server-executed web_search tool. The structured data (especially
163// EncryptedContent) must be preserved for multi-turn conversations.
164type WebSearchResultMetadata struct {
165	Results []WebSearchResultItem `json:"results"`
166}
167
168// Options implements the ProviderOptions interface.
169func (*WebSearchResultMetadata) Options() {}
170
171// MarshalJSON implements custom JSON marshaling with type info for WebSearchResultMetadata.
172func (m WebSearchResultMetadata) MarshalJSON() ([]byte, error) {
173	type plain WebSearchResultMetadata
174	return fantasy.MarshalProviderType(TypeWebSearchResultMetadata, plain(m))
175}
176
177// UnmarshalJSON implements custom JSON unmarshaling with type info for WebSearchResultMetadata.
178func (m *WebSearchResultMetadata) UnmarshalJSON(data []byte) error {
179	type plain WebSearchResultMetadata
180	var p plain
181	if err := fantasy.UnmarshalProviderType(data, &p); err != nil {
182		return err
183	}
184	*m = WebSearchResultMetadata(p)
185	return nil
186}
187
188// CacheControl represents cache control settings for the Anthropic provider.
189type CacheControl struct {
190	Type string `json:"type"`
191}
192
193// NewProviderOptions creates new provider options for the Anthropic provider.
194func NewProviderOptions(opts *ProviderOptions) fantasy.ProviderOptions {
195	return fantasy.ProviderOptions{
196		Name: opts,
197	}
198}
199
200// NewProviderCacheControlOptions creates new cache control options for the Anthropic provider.
201func NewProviderCacheControlOptions(opts *ProviderCacheControlOptions) fantasy.ProviderOptions {
202	return fantasy.ProviderOptions{
203		Name: opts,
204	}
205}
206
207// ParseOptions parses provider options from a map for the Anthropic provider.
208func ParseOptions(data map[string]any) (*ProviderOptions, error) {
209	var options ProviderOptions
210	if err := fantasy.ParseOptions(data, &options); err != nil {
211		return nil, err
212	}
213	return &options, nil
214}
215
216// UserLocation provides geographic context for web search results.
217type UserLocation struct {
218	City     string `json:"city,omitempty"`
219	Region   string `json:"region,omitempty"`
220	Country  string `json:"country,omitempty"`
221	Timezone string `json:"timezone,omitempty"`
222}
223
224// WebSearchToolOptions configures the Anthropic web search tool.
225type WebSearchToolOptions struct {
226	// MaxUses limits the number of web searches the model can
227	// perform within a single API request. Zero means no limit.
228	MaxUses int64
229	// AllowedDomains restricts results to these domains. Cannot
230	// be used together with BlockedDomains.
231	AllowedDomains []string
232	// BlockedDomains excludes these domains from results. Cannot
233	// be used together with AllowedDomains.
234	BlockedDomains []string
235	// UserLocation provides geographic context for more relevant
236	// search results.
237	UserLocation *UserLocation
238}
239
240// WebSearchTool creates a provider-defined web search tool for
241// Anthropic models. Pass nil for default options.
242func WebSearchTool(opts *WebSearchToolOptions) fantasy.ProviderDefinedTool {
243	tool := fantasy.ProviderDefinedTool{
244		ID:   "web_search",
245		Name: "web_search",
246	}
247	if opts == nil {
248		return tool
249	}
250	args := map[string]any{}
251	if opts.MaxUses > 0 {
252		args["max_uses"] = opts.MaxUses
253	}
254	if len(opts.AllowedDomains) > 0 {
255		args["allowed_domains"] = opts.AllowedDomains
256	}
257	if len(opts.BlockedDomains) > 0 {
258		args["blocked_domains"] = opts.BlockedDomains
259	}
260	if opts.UserLocation != nil {
261		args["user_location"] = opts.UserLocation
262	}
263	if len(args) > 0 {
264		tool.Args = args
265	}
266	return tool
267}