content.go

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