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