fix: disable SSML when not support
This commit is contained in:
@@ -126,6 +126,39 @@ describe('speech store helpers', () => {
|
||||
expect(request.input).toContain('volume="-5%"')
|
||||
})
|
||||
|
||||
/**
|
||||
* @example
|
||||
* speechStore.resolveVoicePackSpeechInput({ text, voice, forceSSML: true, supportsSSML: false, supportsAdapterProsody: true })
|
||||
*/
|
||||
it('keeps official adapter-backed speech input as plain text when global SSML is enabled', () => {
|
||||
const speechStore = useSpeechStore()
|
||||
const voice = {
|
||||
id: 'voice-1',
|
||||
name: 'Voice 1',
|
||||
provider: OFFICIAL_SPEECH_PROVIDER_ID,
|
||||
languages: [{ code: 'en-US', title: 'English' }],
|
||||
gender: 'neutral',
|
||||
}
|
||||
|
||||
// ROOT CAUSE:
|
||||
//
|
||||
// Auto TTS can enable global SSML before the server routes the official
|
||||
// speech provider to DashScope CosyVoice. DashScope rejects `<speak>...`
|
||||
// payloads with `SSML text is not supported at the moment!`, so providers
|
||||
// that apply prosody through adapter options must keep the text field plain.
|
||||
const request = speechStore.resolveVoicePackSpeechInput({
|
||||
text: 'hello',
|
||||
voice,
|
||||
providerConfig: { pitch: 0 },
|
||||
forceSSML: true,
|
||||
supportsSSML: false,
|
||||
supportsAdapterProsody: true,
|
||||
})
|
||||
|
||||
expect(request.input).toBe('hello')
|
||||
expect(request.input).not.toContain('<speak')
|
||||
})
|
||||
|
||||
/**
|
||||
* @example
|
||||
* speechStore.resolveVoicePackSpeechInput({ text, voice, params: { pitch: '+20%' }, supportsAdapterProsody: true })
|
||||
|
||||
@@ -473,10 +473,11 @@ export const useSpeechStore = defineStore('speech', () => {
|
||||
|
||||
function resolveVoicePackSpeechInput(options: VoicePackSpeechInputOptions): VoicePackSpeechInput {
|
||||
const providerConfig = { ...options.providerConfig }
|
||||
const canUseSSML = options.supportsSSML === true
|
||||
|
||||
if (!options.params) {
|
||||
return {
|
||||
input: options.forceSSML
|
||||
input: options.forceSSML === true && canUseSSML
|
||||
? generateSSML(options.text, options.voice, providerConfig)
|
||||
: options.text,
|
||||
providerConfig,
|
||||
@@ -493,6 +494,8 @@ export const useSpeechStore = defineStore('speech', () => {
|
||||
if (speed != null)
|
||||
providerConfig.speed = speed
|
||||
|
||||
const shouldUseSSML = canUseSSML && (options.forceSSML === true || (needsProsody && !options.supportsAdapterProsody))
|
||||
|
||||
if (options.voicePack) {
|
||||
providerConfig.extraBody = {
|
||||
...(providerConfig.extraBody as Record<string, unknown> | undefined),
|
||||
@@ -511,11 +514,11 @@ export const useSpeechStore = defineStore('speech', () => {
|
||||
voice_pack: { pitch, volume },
|
||||
}
|
||||
}
|
||||
else if (needsProsody && !options.forceSSML && !options.supportsSSML) {
|
||||
else if (needsProsody && !options.supportsAdapterProsody && !shouldUseSSML) {
|
||||
throw new Error('Voice Pack pitch and volume parameters require an SSML-capable speech provider.')
|
||||
}
|
||||
|
||||
if (!options.forceSSML && (!needsProsody || options.supportsAdapterProsody)) {
|
||||
if (!shouldUseSSML && (!needsProsody || options.supportsAdapterProsody)) {
|
||||
return {
|
||||
input: options.text,
|
||||
providerConfig,
|
||||
|
||||
Reference in New Issue
Block a user