package model import ( "encoding/json" "log" ) // ResponsesRequest — запрос к OpenAI Responses API (/responses или /v1/responses) type ResponsesRequest struct { Model string `json:"model"` Input json.RawMessage `json:"input"` // string или []ResponsesInputMessage Instructions string `json:"instructions,omitempty"` Stream *bool `json:"stream,omitempty"` } // ResponsesInputMessage — сообщение в формате Responses API // content может быть строкой или массивом [{type: "input_text", text: "..."}] type ResponsesInputMessage struct { Type string `json:"type,omitempty"` // "message" Role string `json:"role"` Content json.RawMessage `json:"content"` } // ContentPart — элемент массива content в Responses API type ContentPart struct { Type string `json:"type"` // "input_text", "output_text", etc. Text string `json:"text"` } // ToMessages конвертирует Input + Instructions в []Message для Ollama func (r *ResponsesRequest) ToMessages() []Message { var messages []Message // Instructions → system message if r.Instructions != "" { messages = append(messages, Message{Role: "system", Content: r.Instructions}) } if len(r.Input) == 0 { return messages } log.Printf("responses: raw input: %s", string(r.Input)) // Попробовать как строку var inputStr string if err := json.Unmarshal(r.Input, &inputStr); err == nil { messages = append(messages, Message{Role: "user", Content: inputStr}) return messages } // Попробовать как массив ResponsesInputMessage (формат Codex CLI) var inputMsgs []ResponsesInputMessage if err := json.Unmarshal(r.Input, &inputMsgs); err == nil { for _, msg := range inputMsgs { content := extractContent(msg.Content) role := msg.Role if role == "" { role = "user" } if content != "" { messages = append(messages, Message{Role: role, Content: content}) } } if len(messages) > 0 { return messages } } // Попробовать как простой массив Message (совместимость) var simpleMsgs []Message if err := json.Unmarshal(r.Input, &simpleMsgs); err == nil { messages = append(messages, simpleMsgs...) } return messages } // extractContent извлекает текст из content, которое может быть строкой или массивом ContentPart func extractContent(raw json.RawMessage) string { if len(raw) == 0 { return "" } // Как строку var s string if err := json.Unmarshal(raw, &s); err == nil { return s } // Как массив ContentPart var parts []ContentPart if err := json.Unmarshal(raw, &parts); err == nil { var text string for _, p := range parts { if p.Text != "" { if text != "" { text += "\n" } text += p.Text } } return text } return "" }