1package fantasy
  2
  3// ProviderOptionsData is an interface for provider-specific options data.
  4type ProviderOptionsData interface {
  5	Options()
  6}
  7
  8// ProviderMetadata represents additional provider-specific metadata.
  9// They are passed through from the provider to the AI SDK and enable
 10// provider-specific results that can be fully encapsulated in the provider.
 11//
 12// The outer map is keyed by the provider name, and the inner
 13// map is keyed by the provider-specific metadata key.
 14//
 15// Example:
 16//
 17//	{
 18//	  "anthropic": {
 19//	    "signature": "sig....."
 20//	  }
 21//	}
 22type ProviderMetadata map[string]ProviderOptionsData
 23
 24// ProviderOptions represents additional provider-specific options.
 25// Options are additional input to the provider. They are passed through
 26// to the provider from the AI SDK and enable provider-specific functionality
 27// that can be fully encapsulated in the provider.
 28//
 29// This enables us to quickly ship provider-specific functionality
 30// without affecting the core AI SDK.
 31//
 32// The outer map is keyed by the provider name, and the inner
 33// map is keyed by the provider-specific option key.
 34//
 35// Example:
 36//
 37//	{
 38//	  "anthropic": {
 39//	    "cacheControl": { "type": "ephemeral" }
 40//	  }
 41//	}
 42type ProviderOptions map[string]ProviderOptionsData
 43
 44// FinishReason represents why a language model finished generating a response.
 45//
 46// Can be one of the following:
 47// - `stop`: model generated stop sequence
 48// - `length`: model generated maximum number of tokens
 49// - `content-filter`: content filter violation stopped the model
 50// - `tool-calls`: model triggered tool calls
 51// - `error`: model stopped because of an error
 52// - `other`: model stopped for other reasons
 53// - `unknown`: the model has not transmitted a finish reason.
 54type FinishReason string
 55
 56const (
 57	// FinishReasonStop indicates the model generated a stop sequence.
 58	FinishReasonStop FinishReason = "stop" // model generated stop sequence
 59	// FinishReasonLength indicates the model generated maximum number of tokens.
 60	FinishReasonLength FinishReason = "length" // model generated maximum number of tokens
 61	// FinishReasonContentFilter indicates content filter violation stopped the model.
 62	FinishReasonContentFilter FinishReason = "content-filter" // content filter violation stopped the model
 63	// FinishReasonToolCalls indicates the model triggered tool calls.
 64	FinishReasonToolCalls FinishReason = "tool-calls" // model triggered tool calls
 65	// FinishReasonError indicates the model stopped because of an error.
 66	FinishReasonError FinishReason = "error" // model stopped because of an error
 67	// FinishReasonOther indicates the model stopped for other reasons.
 68	FinishReasonOther FinishReason = "other" // model stopped for other reasons
 69	// FinishReasonUnknown indicates the model has not transmitted a finish reason.
 70	FinishReasonUnknown FinishReason = "unknown" // the model has not transmitted a finish reason
 71)
 72
 73// Prompt represents a list of messages for the language model.
 74type Prompt []Message
 75
 76// MessageRole represents the role of a message.
 77type MessageRole string
 78
 79const (
 80	// MessageRoleSystem represents a system message.
 81	MessageRoleSystem MessageRole = "system"
 82	// MessageRoleUser represents a user message.
 83	MessageRoleUser MessageRole = "user"
 84	// MessageRoleAssistant represents an assistant message.
 85	MessageRoleAssistant MessageRole = "assistant"
 86	// MessageRoleTool represents a tool message.
 87	MessageRoleTool MessageRole = "tool"
 88)
 89
 90// Message represents a message in a prompt.
 91type Message struct {
 92	Role            MessageRole     `json:"role"`
 93	Content         []MessagePart   `json:"content"`
 94	ProviderOptions ProviderOptions `json:"provider_options"`
 95}
 96
 97// AsContentType converts a Content interface to a specific content type.
 98func AsContentType[T Content](content Content) (T, bool) {
 99	var zero T
100	if content == nil {
101		return zero, false
102	}
103	switch v := any(content).(type) {
104	case T:
105		return v, true
106	case *T:
107		return *v, true
108	default:
109		return zero, false
110	}
111}
112
113// AsMessagePart converts a MessagePart interface to a specific message part type.
114func AsMessagePart[T MessagePart](content MessagePart) (T, bool) {
115	var zero T
116	if content == nil {
117		return zero, false
118	}
119	switch v := any(content).(type) {
120	case T:
121		return v, true
122	case *T:
123		return *v, true
124	default:
125		return zero, false
126	}
127}
128
129// MessagePart represents a part of a message content.
130type MessagePart interface {
131	GetType() ContentType
132	Options() ProviderOptions
133}
134
135// TextPart represents text content in a message.
136type TextPart struct {
137	Text            string          `json:"text"`
138	ProviderOptions ProviderOptions `json:"provider_options"`
139}
140
141// GetType returns the type of the text part.
142func (t TextPart) GetType() ContentType {
143	return ContentTypeText
144}
145
146// Options returns the provider options for the text part.
147func (t TextPart) Options() ProviderOptions {
148	return t.ProviderOptions
149}
150
151// ReasoningPart represents reasoning content in a message.
152type ReasoningPart struct {
153	Text            string          `json:"text"`
154	ProviderOptions ProviderOptions `json:"provider_options"`
155}
156
157// GetType returns the type of the reasoning part.
158func (r ReasoningPart) GetType() ContentType {
159	return ContentTypeReasoning
160}
161
162// Options returns the provider options for the reasoning part.
163func (r ReasoningPart) Options() ProviderOptions {
164	return r.ProviderOptions
165}
166
167// FilePart represents file content in a message.
168type FilePart struct {
169	Filename        string          `json:"filename"`
170	Data            []byte          `json:"data"`
171	MediaType       string          `json:"media_type"`
172	ProviderOptions ProviderOptions `json:"provider_options"`
173}
174
175// GetType returns the type of the file part.
176func (f FilePart) GetType() ContentType {
177	return ContentTypeFile
178}
179
180// Options returns the provider options for the file part.
181func (f FilePart) Options() ProviderOptions {
182	return f.ProviderOptions
183}
184
185// ToolCallPart represents a tool call in a message.
186type ToolCallPart struct {
187	ToolCallID       string          `json:"tool_call_id"`
188	ToolName         string          `json:"tool_name"`
189	Input            string          `json:"input"` // the json string
190	ProviderExecuted bool            `json:"provider_executed"`
191	ProviderOptions  ProviderOptions `json:"provider_options"`
192}
193
194// GetType returns the type of the tool call part.
195func (t ToolCallPart) GetType() ContentType {
196	return ContentTypeToolCall
197}
198
199// Options returns the provider options for the tool call part.
200func (t ToolCallPart) Options() ProviderOptions {
201	return t.ProviderOptions
202}
203
204// ToolResultPart represents a tool result in a message.
205type ToolResultPart struct {
206	ToolCallID      string                  `json:"tool_call_id"`
207	Output          ToolResultOutputContent `json:"output"`
208	ProviderOptions ProviderOptions         `json:"provider_options"`
209}
210
211// GetType returns the type of the tool result part.
212func (t ToolResultPart) GetType() ContentType {
213	return ContentTypeToolResult
214}
215
216// Options returns the provider options for the tool result part.
217func (t ToolResultPart) Options() ProviderOptions {
218	return t.ProviderOptions
219}
220
221// ToolResultContentType represents the type of tool result output.
222type ToolResultContentType string
223
224const (
225	// ToolResultContentTypeText represents text output.
226	ToolResultContentTypeText ToolResultContentType = "text"
227	// ToolResultContentTypeError represents error text output.
228	ToolResultContentTypeError ToolResultContentType = "error"
229	// ToolResultContentTypeMedia represents content output.
230	ToolResultContentTypeMedia ToolResultContentType = "media"
231)
232
233// ToolResultOutputContent represents the output content of a tool result.
234type ToolResultOutputContent interface {
235	GetType() ToolResultContentType
236}
237
238// ToolResultOutputContentText represents text output content of a tool result.
239type ToolResultOutputContentText struct {
240	Text string `json:"text"`
241}
242
243// GetType returns the type of the tool result output content text.
244func (t ToolResultOutputContentText) GetType() ToolResultContentType {
245	return ToolResultContentTypeText
246}
247
248// ToolResultOutputContentError represents error output content of a tool result.
249type ToolResultOutputContentError struct {
250	Error error `json:"error"`
251}
252
253// GetType returns the type of the tool result output content error.
254func (t ToolResultOutputContentError) GetType() ToolResultContentType {
255	return ToolResultContentTypeError
256}
257
258// ToolResultOutputContentMedia represents media output content of a tool result.
259type ToolResultOutputContentMedia struct {
260	Data      string `json:"data"`       // for media type (base64)
261	MediaType string `json:"media_type"` // for media type
262}
263
264// GetType returns the type of the tool result output content media.
265func (t ToolResultOutputContentMedia) GetType() ToolResultContentType {
266	return ToolResultContentTypeMedia
267}
268
269// AsToolResultOutputType converts a ToolResultOutputContent interface to a specific type.
270func AsToolResultOutputType[T ToolResultOutputContent](content ToolResultOutputContent) (T, bool) {
271	var zero T
272	if content == nil {
273		return zero, false
274	}
275	switch v := any(content).(type) {
276	case T:
277		return v, true
278	case *T:
279		return *v, true
280	default:
281		return zero, false
282	}
283}
284
285// ContentType represents the type of content.
286type ContentType string
287
288const (
289	// ContentTypeText represents text content.
290	ContentTypeText ContentType = "text"
291	// ContentTypeReasoning represents reasoning content.
292	ContentTypeReasoning ContentType = "reasoning"
293	// ContentTypeFile represents file content.
294	ContentTypeFile ContentType = "file"
295	// ContentTypeSource represents source content.
296	ContentTypeSource ContentType = "source"
297	// ContentTypeToolCall represents a tool call.
298	ContentTypeToolCall ContentType = "tool-call"
299	// ContentTypeToolResult represents a tool result.
300	ContentTypeToolResult ContentType = "tool-result"
301)
302
303// Content represents generated content from the model.
304type Content interface {
305	GetType() ContentType
306}
307
308// TextContent represents text that the model has generated.
309type TextContent struct {
310	// The text content.
311	Text             string           `json:"text"`
312	ProviderMetadata ProviderMetadata `json:"provider_metadata"`
313}
314
315// GetType returns the type of the text content.
316func (t TextContent) GetType() ContentType {
317	return ContentTypeText
318}
319
320// ReasoningContent represents reasoning that the model has generated.
321type ReasoningContent struct {
322	Text             string           `json:"text"`
323	ProviderMetadata ProviderMetadata `json:"provider_metadata"`
324}
325
326// GetType returns the type of the reasoning content.
327func (r ReasoningContent) GetType() ContentType {
328	return ContentTypeReasoning
329}
330
331// FileContent represents a file that has been generated by the model.
332// Generated files as base64 encoded strings or binary data.
333// The files should be returned without any unnecessary conversion.
334type FileContent struct {
335	// The IANA media type of the file, e.g. `image/png` or `audio/mp3`.
336	// @see https://www.iana.org/assignments/media-types/media-types.xhtml
337	MediaType string `json:"media_type"`
338	// Generated file data as binary data.
339	Data             []byte           `json:"data"`
340	ProviderMetadata ProviderMetadata `json:"provider_metadata"`
341}
342
343// GetType returns the type of the file content.
344func (f FileContent) GetType() ContentType {
345	return ContentTypeFile
346}
347
348// SourceType represents the type of source.
349type SourceType string
350
351const (
352	// SourceTypeURL represents a URL source.
353	SourceTypeURL SourceType = "url"
354	// SourceTypeDocument represents a document source.
355	SourceTypeDocument SourceType = "document"
356)
357
358// SourceContent represents a source that has been used as input to generate the response.
359type SourceContent struct {
360	SourceType       SourceType       `json:"source_type"` // "url" or "document"
361	ID               string           `json:"id"`
362	URL              string           `json:"url"` // for URL sources
363	Title            string           `json:"title"`
364	MediaType        string           `json:"media_type"` // for document sources (IANA media type)
365	Filename         string           `json:"filename"`   // for document sources
366	ProviderMetadata ProviderMetadata `json:"provider_metadata"`
367}
368
369// GetType returns the type of the source content.
370func (s SourceContent) GetType() ContentType {
371	return ContentTypeSource
372}
373
374// ToolCallContent represents tool calls that the model has generated.
375type ToolCallContent struct {
376	ToolCallID string `json:"tool_call_id"`
377	ToolName   string `json:"tool_name"`
378	// Stringified JSON object with the tool call arguments.
379	// Must match the parameters schema of the tool.
380	Input string `json:"input"`
381	// Whether the tool call will be executed by the provider.
382	// If this flag is not set or is false, the tool call will be executed by the client.
383	ProviderExecuted bool `json:"provider_executed"`
384	// Additional provider-specific metadata for the tool call.
385	ProviderMetadata ProviderMetadata `json:"provider_metadata"`
386	// Whether this tool call is invalid (failed validation/parsing)
387	Invalid bool `json:"invalid,omitempty"`
388	// Error that occurred during validation/parsing (only set if Invalid is true)
389	ValidationError error `json:"validation_error,omitempty"`
390}
391
392// GetType returns the type of the tool call content.
393func (t ToolCallContent) GetType() ContentType {
394	return ContentTypeToolCall
395}
396
397// ToolResultContent represents result of a tool call that has been executed by the provider.
398type ToolResultContent struct {
399	// The ID of the tool call that this result is associated with.
400	ToolCallID string `json:"tool_call_id"`
401	// Name of the tool that generated this result.
402	ToolName string `json:"tool_name"`
403	// Result of the tool call. This is a JSON-serializable object.
404	Result         ToolResultOutputContent `json:"result"`
405	ClientMetadata string                  `json:"client_metadata"` // Metadata from the client that executed the tool
406	// Whether the tool result was generated by the provider.
407	// If this flag is set to true, the tool result was generated by the provider.
408	// If this flag is not set or is false, the tool result was generated by the client.
409	ProviderExecuted bool `json:"provider_executed"`
410	// Additional provider-specific metadata for the tool result.
411	ProviderMetadata ProviderMetadata `json:"provider_metadata"`
412}
413
414// GetType returns the type of the tool result content.
415func (t ToolResultContent) GetType() ContentType {
416	return ContentTypeToolResult
417}
418
419// ToolType represents the type of tool.
420type ToolType string
421
422const (
423	// ToolTypeFunction represents a function tool.
424	ToolTypeFunction ToolType = "function"
425	// ToolTypeProviderDefined represents a provider-defined tool.
426	ToolTypeProviderDefined ToolType = "provider-defined"
427)
428
429// Tool represents a tool that can be used by the model.
430//
431// Note: this is **not** the user-facing tool definition. The AI SDK methods will
432// map the user-facing tool definitions to this format.
433type Tool interface {
434	GetType() ToolType
435	GetName() string
436}
437
438// FunctionTool represents a function tool.
439//
440// A tool has a name, a description, and a set of parameters.
441type FunctionTool struct {
442	// Name of the tool. Unique within this model call.
443	Name string `json:"name"`
444	// Description of the tool. The language model uses this to understand the
445	// tool's purpose and to provide better completion suggestions.
446	Description string `json:"description"`
447	// InputSchema - the parameters that the tool expects. The language model uses this to
448	// understand the tool's input requirements and to provide matching suggestions.
449	InputSchema map[string]any `json:"input_schema"` // JSON Schema
450	// ProviderOptions are provider-specific options for the tool.
451	ProviderOptions ProviderOptions `json:"provider_options"`
452}
453
454// GetType returns the type of the function tool.
455func (f FunctionTool) GetType() ToolType {
456	return ToolTypeFunction
457}
458
459// GetName returns the name of the function tool.
460func (f FunctionTool) GetName() string {
461	return f.Name
462}
463
464// ProviderDefinedTool represents the configuration of a tool that is defined by the provider.
465type ProviderDefinedTool struct {
466	// ID of the tool. Should follow the format `<provider-name>.<unique-tool-name>`.
467	ID string `json:"id"`
468	// Name of the tool that the user must use in the tool set.
469	Name string `json:"name"`
470	// Args for configuring the tool. Must match the expected arguments defined by the provider for this tool.
471	Args map[string]any `json:"args"`
472}
473
474// GetType returns the type of the provider-defined tool.
475func (p ProviderDefinedTool) GetType() ToolType {
476	return ToolTypeProviderDefined
477}
478
479// GetName returns the name of the provider-defined tool.
480func (p ProviderDefinedTool) GetName() string {
481	return p.Name
482}
483
484// NewUserMessage creates a new user message with the given prompt and optional files.
485func NewUserMessage(prompt string, files ...FilePart) Message {
486	content := []MessagePart{
487		TextPart{
488			Text: prompt,
489		},
490	}
491
492	for _, f := range files {
493		content = append(content, f)
494	}
495
496	return Message{
497		Role:    MessageRoleUser,
498		Content: content,
499	}
500}
501
502// NewSystemMessage creates a new system message with the given prompts.
503func NewSystemMessage(prompt ...string) Message {
504	content := make([]MessagePart, 0, len(prompt))
505	for _, p := range prompt {
506		content = append(content, TextPart{Text: p})
507	}
508
509	return Message{
510		Role:    MessageRoleSystem,
511		Content: content,
512	}
513}