content.go

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