@@ -116,16 +116,21 @@ type openAIToDashScopeSpeechTranslator struct {
116116// {"model":"qwen3-tts-flash","input":{"text":"hello","voice":"Cherry","language_type":"Auto"}}
117117//
118118// Voice, instructions, response_format, speed, and stream_format are not translated:
119- // - voice: passed through verbatim — the AIGatewayRoute owner is expected to supply a
120- // DashScope-side voice name (e.g. "Cherry"); OpenAI voice presets do not have a natural
121- // mapping and forcing one here would silently pick the wrong timbre.
122- // - instructions/speed: DashScope has no equivalent.
123- // - response_format: DashScope's non-streaming response is always WAV via URL; ignored here
124- // and the outbound content-type is set to audio/wav in ResponseHeaders.
125- // - stream_format: only non-streaming is implemented in this first cut; SSE support would
126- // require calling DashScope's streaming synthesis API (different endpoint) and is out of
127- // scope until we see demand.
128- func (o * openAIToDashScopeSpeechTranslator ) RequestBody (original []byte , req * openai.SpeechRequest , forceBodyMutation bool ) (
119+ // - voice: passed through verbatim — the AIGatewayRoute owner is expected to supply a
120+ // DashScope-side voice name (e.g. "Cherry"); OpenAI voice presets do not have a natural
121+ // mapping and forcing one here would silently pick the wrong timbre.
122+ // - instructions/speed: DashScope has no equivalent.
123+ // - response_format: DashScope's non-streaming response is always WAV via URL; ignored here
124+ // and the outbound content-type is set to audio/wav in ResponseHeaders.
125+ // - stream_format: only non-streaming is implemented in this first cut; SSE support would
126+ // require calling DashScope's streaming synthesis API (different endpoint) and is out of
127+ // scope until we see demand.
128+ //
129+ // The `original` byte slice is intentionally ignored — the DashScope wire format differs
130+ // enough from the OpenAI request that we always re-marshal from the parsed struct rather
131+ // than patching the original body. Same reason forceBodyMutation is ignored: the response is
132+ // always a body replacement, never a passthrough.
133+ func (o * openAIToDashScopeSpeechTranslator ) RequestBody (_ []byte , req * openai.SpeechRequest , _ bool ) (
129134 newHeaders []internalapi.Header , newBody []byte , err error ,
130135) {
131136 if req == nil {
@@ -134,7 +139,7 @@ func (o *openAIToDashScopeSpeechTranslator) RequestBody(original []byte, req *op
134139
135140 model := req .Model
136141 if o .modelNameOverride != "" {
137- model = string ( o .modelNameOverride )
142+ model = o .modelNameOverride
138143 }
139144 o .requestModel = model
140145
@@ -154,7 +159,6 @@ func (o *openAIToDashScopeSpeechTranslator) RequestBody(original []byte, req *op
154159 {pathHeaderName , o .path },
155160 {contentLengthHeaderName , strconv .Itoa (len (newBody ))},
156161 }
157- _ = forceBodyMutation // always a shape change → always mutate.
158162 return
159163}
160164
@@ -186,7 +190,7 @@ func (o *openAIToDashScopeSpeechTranslator) ResponseBody(_ map[string]string, bo
186190 if envelope .Output .Audio .URL == "" {
187191 return nil , nil , tokenUsage , "" , fmt .Errorf ("dashscope speech: response missing output.audio.url; body=%s" , truncate (raw , 512 ))
188192 }
189- if err : = validateDashScopeAudioURL (envelope .Output .Audio .URL ); err != nil {
193+ if err = validateDashScopeAudioURL (envelope .Output .Audio .URL ); err != nil {
190194 return nil , nil , tokenUsage , "" , err
191195 }
192196
0 commit comments