package domain import ( "encoding/json" "fmt" "strings" ) // OpenAI API 请求结构体 type OpenAICompletionsRequest struct { Model string `json:"model" validate:"required"` Messages []OpenAIMessage `json:"messages" validate:"required"` Stream bool `json:"stream,omitempty"` StreamOptions *OpenAIStreamOptions `json:"stream_options,omitempty"` Temperature *float64 `json:"temperature,omitempty"` MaxTokens *int `json:"max_tokens,omitempty"` TopP *float64 `json:"top_p,omitempty"` FrequencyPenalty *float64 `json:"frequency_penalty,omitempty"` PresencePenalty *float64 `json:"presence_penalty,omitempty"` Stop []string `json:"stop,omitempty"` User string `json:"user,omitempty"` Tools []OpenAITool `json:"tools,omitempty"` ToolChoice *OpenAIToolChoice `json:"tool_choice,omitempty"` ResponseFormat *OpenAIResponseFormat `json:"response_format,omitempty"` } type OpenAIStreamOptions struct { IncludeUsage bool `json:"include_usage,omitempty"` } // MessageContent 支持字符串或内容数组 type MessageContent struct { isString bool strValue string arrValue []OpenAIContentPart } // OpenAIContentPart 表示内容数组中的单个元素 type OpenAIContentPart struct { Type string `json:"type"` Text string `json:"text,omitempty"` ImageURL *OpenAIContentPartURL `json:"image_url,omitempty"` } // OpenAIContentPartURL represents the image_url field in content parts type OpenAIContentPartURL struct { URL string `json:"url"` } // UnmarshalJSON 自定义解析,支持 string 或 array 格式 func (mc *MessageContent) UnmarshalJSON(data []byte) error { // 尝试解析为字符串 var str string if err := json.Unmarshal(data, &str); err == nil { mc.isString = true mc.strValue = str return nil } // 尝试解析为数组 var arr []OpenAIContentPart if err := json.Unmarshal(data, &arr); err == nil { mc.isString = false mc.arrValue = arr return nil } return fmt.Errorf("content must be string or array") } // MarshalJSON 自定义序列化 func (mc *MessageContent) MarshalJSON() ([]byte, error) { if mc.isString { return json.Marshal(mc.strValue) } return json.Marshal(mc.arrValue) } // NewStringContent 创建字符串类型的 MessageContent func NewStringContent(s string) *MessageContent { return &MessageContent{ isString: true, strValue: s, } } // NewArrayContent 创建数组类型的 MessageContent func NewArrayContent(parts []OpenAIContentPart) *MessageContent { return &MessageContent{ isString: false, arrValue: parts, } } // String 获取文本内容 func (mc *MessageContent) String() string { if mc.isString { return mc.strValue } // 从数组中提取文本 var builder strings.Builder for _, part := range mc.arrValue { if part.Type == "text" { if builder.Len() > 0 && part.Text != "" { builder.WriteString(" ") } builder.WriteString(part.Text) } } return builder.String() } type OpenAIMessage struct { Role string `json:"role" validate:"required"` Content *MessageContent `json:"content,omitempty"` Name string `json:"name,omitempty"` ToolCalls []OpenAIToolCall `json:"tool_calls,omitempty"` ToolCallID string `json:"tool_call_id,omitempty"` } type OpenAITool struct { Type string `json:"type" validate:"required"` Function *OpenAIFunction `json:"function,omitempty"` } type OpenAIFunction struct { Name string `json:"name" validate:"required"` Description string `json:"description,omitempty"` Parameters map[string]interface{} `json:"parameters,omitempty"` } type OpenAIToolCall struct { ID string `json:"id" validate:"required"` Type string `json:"type" validate:"required"` Function OpenAIFunctionCall `json:"function" validate:"required"` } type OpenAIFunctionCall struct { Name string `json:"name" validate:"required"` Arguments string `json:"arguments" validate:"required"` } type OpenAIToolChoice struct { Type string `json:"type,omitempty"` Function *OpenAIFunctionChoice `json:"function,omitempty"` } type OpenAIFunctionChoice struct { Name string `json:"name" validate:"required"` } type OpenAIResponseFormat struct { Type string `json:"type" validate:"required"` } // OpenAI API 响应结构体 type OpenAICompletionsResponse struct { ID string `json:"id"` Object string `json:"object"` Created int64 `json:"created"` Model string `json:"model"` Choices []OpenAIChoice `json:"choices"` Usage *OpenAIUsage `json:"usage,omitempty"` } type OpenAIChoice struct { Index int `json:"index"` Message OpenAIMessage `json:"message"` FinishReason string `json:"finish_reason"` Delta *OpenAIMessage `json:"delta,omitempty"` // for streaming } type OpenAIUsage struct { PromptTokens int `json:"prompt_tokens"` CompletionTokens int `json:"completion_tokens"` TotalTokens int `json:"total_tokens"` } // OpenAI 流式响应结构体 type OpenAIStreamResponse struct { ID string `json:"id"` Object string `json:"object"` Created int64 `json:"created"` Model string `json:"model"` Choices []OpenAIStreamChoice `json:"choices"` Usage *OpenAIUsage `json:"usage,omitempty"` } type OpenAIStreamChoice struct { Index int `json:"index"` Delta OpenAIMessage `json:"delta"` FinishReason *string `json:"finish_reason,omitempty"` } // OpenAI 错误响应结构体 type OpenAIErrorResponse struct { Error OpenAIError `json:"error"` } type OpenAIError struct { Message string `json:"message"` Type string `json:"type"` Code string `json:"code,omitempty"` Param string `json:"param,omitempty"` }