| 738 | } |
| 739 | |
| 740 | std::string diarization_event_json( |
| 741 | const std::vector<engine::runtime::SpeakerTurn> & turns, |
| 742 | int sample_rate, |
| 743 | bool final, |
| 744 | const std::optional<double> & ttft_ms = std::nullopt) { |
| 745 | std::ostringstream out; |
| 746 | out << "{\"type\":\"diarization." << (final ? "done" : "delta") |
| 747 | << "\",\"speaker_turns\":" << speaker_turns_json(turns) |
| 748 | << ",\"sample_rate\":" << sample_rate; |
| 749 | if (final) { |
| 750 | out << ",\"timing\":" << (ttft_ms ? ttft_timing_json(*ttft_ms) : "{\"ttft_ms\":null}"); |
| 751 | } |
| 752 | out << "}"; |
| 753 | return out.str(); |
| 754 | } |
| 755 | |
| 756 | // Transcript detail arrays shared by /v1/tasks/run and /v1/audio/transcriptions. |
| 757 | // ASR models that produce timestamps populate only these fields, so a route that |
| 758 | // omits them silently discards work the model already did. |
| 759 | template <typename FieldFn> |
| 760 | void write_transcript_detail_fields( |
| 761 | std::ostringstream & out, |
nothing calls this directly
no test coverage detected