content.go

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