| 185 | } |
| 186 | |
| 187 | JsonValue derive_warmup_request( |
| 188 | const JsonValue & request, |
| 189 | const std::filesystem::path & repo_root, |
| 190 | const std::filesystem::path & temp_dir) { |
| 191 | JsonObject out = request.as_object(); |
| 192 | const auto shorten_field = [&](const char * key, size_t limit) { |
| 193 | const auto it = out.find(key); |
| 194 | if (it != out.end() && it->second.is_string()) { |
| 195 | it->second = JsonValue::make_string(shorten_text(it->second.as_string(), limit)); |
| 196 | } |
| 197 | }; |
| 198 | shorten_field("text", 80); |
| 199 | shorten_field("target_text", 80); |
| 200 | shorten_field("style_ref_text", 80); |
| 201 | shorten_field("reference_text", 80); |
| 202 | shorten_field("lyrics", 80); |
| 203 | shorten_field("instruct", 64); |
| 204 | |
| 205 | const auto clip_field = [&](const char * key) { |
| 206 | const auto it = out.find(key); |
| 207 | if (it != out.end() && it->second.is_string()) { |
| 208 | it->second = clip_audio_path_field(it->second, repo_root, temp_dir, 2.0); |
| 209 | } |
| 210 | }; |
| 211 | clip_field("audio"); |
| 212 | clip_field("voice_ref"); |
| 213 | clip_field("source_audio"); |
| 214 | clip_field("target_voice"); |
| 215 | clip_field("prosody_ref"); |
| 216 | clip_field("style_ref"); |
| 217 | |
| 218 | const auto it_duration = out.find("duration_seconds"); |
| 219 | if (it_duration != out.end() && it_duration->second.is_number()) { |
| 220 | it_duration->second = JsonValue::make_number(std::min(4.0, it_duration->second.as_number())); |
| 221 | } |
| 222 | |
| 223 | const auto it_max_tokens = out.find("max_tokens"); |
| 224 | if (it_max_tokens != out.end() && it_max_tokens->second.is_number()) { |
| 225 | it_max_tokens->second = JsonValue::make_number(std::min<int64_t>(64, it_max_tokens->second.as_i64())); |
| 226 | } |
| 227 | |
| 228 | if (const auto options_it = out.find("options"); options_it != out.end() && options_it->second.is_object()) { |
| 229 | JsonObject options = options_it->second.as_object(); |
| 230 | const auto reduce_numeric_option = [&](const char * key, double cap) { |
| 231 | const auto it = options.find(key); |
| 232 | if (it != options.end() && it->second.is_number()) { |
| 233 | it->second = JsonValue::make_number(std::min(cap, it->second.as_number())); |
| 234 | } |
| 235 | }; |
| 236 | reduce_numeric_option("duration_seconds", 4.0); |
| 237 | reduce_numeric_option("target_duration_seconds", 4.0); |
| 238 | options_it->second = JsonValue::make_object(std::move(options)); |
| 239 | } |
| 240 | |
| 241 | return JsonValue::make_object(std::move(out)); |
| 242 | } |
| 243 | |
| 244 | const JsonValue & require_case(const JsonValue & root, const std::string & case_id) { |