| 125 | } |
| 126 | |
| 127 | static json normalize_template(json messages) { |
| 128 | json template_message = json::array(); |
| 129 | |
| 130 | for (auto& message : messages) { |
| 131 | json new_message = message; |
| 132 | std::string merged_text; |
| 133 | nlohmann::ordered_json::array_t merged_images; |
| 134 | nlohmann::ordered_json::array_t merged_audio; |
| 135 | |
| 136 | if (message["content"].is_string()) { |
| 137 | // Simple format: just text |
| 138 | merged_text = message["content"].get<std::string>(); |
| 139 | } |
| 140 | else if (message["content"].is_array()) { |
| 141 | // Structured format: extract text and image URLs |
| 142 | for (auto& contentItem : message["content"]) { |
| 143 | if (contentItem.contains("type") && contentItem["type"] == "text") { |
| 144 | merged_text += contentItem["text"].get<std::string>(); |
| 145 | } |
| 146 | else if (contentItem.contains("type") && contentItem["type"] == "image_url") { |
| 147 | std::string image_url = contentItem["image_url"]["url"].get<std::string>(); |
| 148 | const std::vector<std::string> prefixes = { |
| 149 | "data:image/png;base64,", |
| 150 | "data:image/jpeg;base64,", |
| 151 | "data:image/jpg;base64," |
| 152 | }; |
| 153 | for (const auto& prefix : prefixes) { |
| 154 | if (image_url.substr(0, prefix.length()) == prefix) { |
| 155 | image_url = image_url.substr(prefix.length()); |
| 156 | break; |
| 157 | } |
| 158 | } |
| 159 | if (image_url.substr(0, 5) == "data:") { |
| 160 | header_print("Warning", "Unsupported image format, skipping this image."); |
| 161 | continue; |
| 162 | } |
| 163 | if (image_url.empty()) { |
| 164 | header_print("Warning", "Empty image, skipping this image."); |
| 165 | continue; |
| 166 | } |
| 167 | merged_images.push_back(image_url); |
| 168 | } |
| 169 | else if (contentItem.contains("type") && contentItem["type"] == "input_audio") { |
| 170 | std::string audio_base64 = contentItem["input_audio"]["data"].get<std::string>(); |
| 171 | if (audio_base64.empty()) { |
| 172 | header_print("Warning", "Empty audio, skipping this audio."); |
| 173 | continue; |
| 174 | } |
| 175 | merged_audio.push_back(audio_base64); |
| 176 | } |
| 177 | } |
| 178 | } |
| 179 | |
| 180 | //new_message["role"] = message["role"]; |
| 181 | new_message["content"] = merged_text; |
| 182 | if (!merged_images.empty()) { |
| 183 | new_message["images"] = merged_images; |
| 184 | } |