Shared STT pre-pass (#734): for every message carrying audio, attach the
spoken words as a { type: "text" } part — reusing an existing text sibling
when present, else transcribing the audio chunk via the resolved
STTProvider. Optionally keeps or drops the raw audio part.
This is the single implementation behind BOTH the judge's
prepareJudgeInput pre-pass and the user-simulator's STT fallback: EL
can fail to send agent_response for a turn, leaving the simulator with a
bare [audio message]; running this before stripAudioContent gives the
text-only simulator real words instead. Extracting it here keeps the STT
plumbing in ONE place rather than duplicating it into the simulator.
The input array is never mutated — a new message list is returned. STT
failures degrade gracefully (audio dropped on the text-only path, a warning
logged) so the caller still processes the rest of the conversation.
Shared STT pre-pass (#734): for every message carrying audio, attach the spoken words as a
{ type: "text" }part — reusing an existing text sibling when present, else transcribing the audio chunk via the resolved STTProvider. Optionally keeps or drops the raw audio part.This is the single implementation behind BOTH the judge's prepareJudgeInput pre-pass and the user-simulator's STT fallback: EL can fail to send
agent_responsefor a turn, leaving the simulator with a bare[audio message]; running this beforestripAudioContentgives the text-only simulator real words instead. Extracting it here keeps the STT plumbing in ONE place rather than duplicating it into the simulator.The input array is never mutated — a new message list is returned. STT failures degrade gracefully (audio dropped on the text-only path, a warning logged) so the caller still processes the rest of the conversation.