package model type Message struct { Role string `json:"role,omitempty"` Content any `json:"content,omitempty"` ReasoningContent any `json:"reasoning_content,omitempty"` Name *string `json:"name,omitempty"` ToolCalls []Tool `json:"tool_calls,omitempty"` ToolCallId string `json:"tool_call_id,omitempty"` } func (m Message) IsStringContent() bool { _, ok := m.Content.(string) return ok } func (m Message) StringContent() string { content, ok := m.Content.(string) if ok { return content } contentList, ok := m.Content.([]any) if ok { var contentStr string for _, contentItem := range contentList { contentMap, ok := contentItem.(map[string]any) if !ok { continue } if contentMap["type"] == ContentTypeText { if subStr, ok := contentMap["text"].(string); ok { contentStr += subStr } } } return contentStr } return "" } func (m Message) ParseContent() []MessageContent { var contentList []MessageContent content, ok := m.Content.(string) if ok { contentList = append(contentList, MessageContent{ Type: ContentTypeText, Text: content, }) return contentList } anyList, ok := m.Content.([]any) if ok { for _, contentItem := range anyList { contentMap, ok := contentItem.(map[string]any) if !ok { continue } switch contentMap["type"] { case ContentTypeText: if subStr, ok := contentMap["text"].(string); ok { contentList = append(contentList, MessageContent{ Type: ContentTypeText, Text: subStr, }) } case ContentTypeImageURL: if subObj, ok := contentMap["image_url"].(map[string]any); ok { contentList = append(contentList, MessageContent{ Type: ContentTypeImageURL, ImageURL: &ImageURL{ Url: subObj["url"].(string), }, }) } case ContentTypeVideoURL: if subObj, ok := contentMap["video_url"].(map[string]any); ok { if url, ok := subObj["url"].(string); ok { contentList = append(contentList, MessageContent{ Type: ContentTypeVideoURL, VideoURL: &VideoURL{Url: url}, }) } } case ContentTypeInputAudio: if subObj, ok := contentMap["input_audio"].(map[string]any); ok { data, _ := subObj["data"].(string) format, _ := subObj["format"].(string) if data != "" { contentList = append(contentList, MessageContent{ Type: ContentTypeInputAudio, InputAudio: &InputAudio{Data: data, Format: format}, }) } } } } return contentList } return nil } type ImageURL struct { Url string `json:"url,omitempty"` Detail string `json:"detail,omitempty"` } type VideoURL struct { Url string `json:"url,omitempty"` } type InputAudio struct { Data string `json:"data,omitempty"` // base64-encoded audio (no data: prefix) Format string `json:"format,omitempty"` // e.g. "mp3", "wav", "webm", "ogg" } type MessageContent struct { Type string `json:"type,omitempty"` Text string `json:"text"` ImageURL *ImageURL `json:"image_url,omitempty"` VideoURL *VideoURL `json:"video_url,omitempty"` InputAudio *InputAudio `json:"input_audio,omitempty"` }