mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-27 12:56:01 -06:00
refactor(elevenlabs): consolidate voice-setting directive parsing (#129988)
This commit is contained in:
committed by
GitHub
parent
bddd0aaa6f
commit
f73672ee08
@@ -45,6 +45,17 @@ const OUTPUT_FORMAT_CASES = [
|
||||
{ outputFormat: "future_123", fileExtension: ".bin", voiceCompatible: false },
|
||||
] as const;
|
||||
|
||||
const DIRECTIVE_POLICY = {
|
||||
enabled: true,
|
||||
allowText: true,
|
||||
allowProvider: true,
|
||||
allowVoice: true,
|
||||
allowModelId: true,
|
||||
allowVoiceSettings: true,
|
||||
allowNormalization: true,
|
||||
allowSeed: true,
|
||||
};
|
||||
|
||||
describe("elevenlabs speech provider", () => {
|
||||
const originalFetch = globalThis.fetch;
|
||||
|
||||
@@ -73,6 +84,49 @@ describe("elevenlabs speech provider", () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it.each([
|
||||
["stability", "0", { stability: 0 }],
|
||||
["similarity", "1", { similarityBoost: 1 }],
|
||||
["similarityboost", "0.25", { similarityBoost: 0.25 }],
|
||||
["similarity_boost", "5e-1", { similarityBoost: 0.5 }],
|
||||
["style", "1", { style: 1 }],
|
||||
["speed", ".5", { speed: 0.5 }],
|
||||
["speed", "2", { speed: 2 }],
|
||||
["stability", "-0.1", "stability must be between 0 and 1"],
|
||||
["similarity", "Infinity", "invalid similarityBoost value"],
|
||||
["similarity_boost", "1.1", "similarityBoost must be between 0 and 1"],
|
||||
["style", "0x1", "invalid style value"],
|
||||
["speed", ".49", "speed must be between 0.5 and 2"],
|
||||
["speed", "2.01", "speed must be between 0.5 and 2"],
|
||||
["speed", "invalid", undefined, false],
|
||||
] as const)(
|
||||
"preserves the %s=%s voice-setting directive",
|
||||
(key, value, expected, allowed?: boolean) => {
|
||||
const currentOverrides = { voiceId: "existing-voice", voiceSettings: { style: 0.25 } };
|
||||
const allowVoiceSettings = allowed ?? true;
|
||||
const parsed = buildElevenLabsSpeechProvider().parseDirectiveToken?.({
|
||||
key,
|
||||
value,
|
||||
policy: { ...DIRECTIVE_POLICY, allowVoiceSettings },
|
||||
currentOverrides,
|
||||
});
|
||||
|
||||
expect(parsed).toEqual(
|
||||
!allowVoiceSettings
|
||||
? { handled: true }
|
||||
: typeof expected === "string"
|
||||
? { handled: true, warnings: [expected] }
|
||||
: {
|
||||
handled: true,
|
||||
overrides: {
|
||||
...currentOverrides,
|
||||
voiceSettings: { ...currentOverrides.voiceSettings, ...expected },
|
||||
},
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
it("forwards the core-resolved voice-list timeout", async () => {
|
||||
globalThis.fetch = vi.fn(async () => Response.json({ voices: [] })) as unknown as typeof fetch;
|
||||
const provider = buildElevenLabsSpeechProvider();
|
||||
|
||||
@@ -269,54 +269,25 @@ function parseDirectiveToken(ctx: SpeechDirectiveTokenParseContext) {
|
||||
handled: true,
|
||||
overrides: { ...ctx.currentOverrides, modelId: normalizeElevenLabsTtsModelId(ctx.value) },
|
||||
};
|
||||
case "stability": {
|
||||
if (!ctx.policy.allowVoiceSettings) {
|
||||
return { handled: true };
|
||||
}
|
||||
const value = parseNumberValue(ctx.value);
|
||||
if (value == null) {
|
||||
return { handled: true, warnings: ["invalid stability value"] };
|
||||
}
|
||||
requireInRange(value, 0, 1, "stability");
|
||||
return { handled: true, overrides: mergeVoiceSettingsOverride(ctx, { stability: value }) };
|
||||
}
|
||||
case "stability":
|
||||
case "similarity":
|
||||
case "similarityboost":
|
||||
case "similarity_boost": {
|
||||
if (!ctx.policy.allowVoiceSettings) {
|
||||
return { handled: true };
|
||||
}
|
||||
const value = parseNumberValue(ctx.value);
|
||||
if (value == null) {
|
||||
return { handled: true, warnings: ["invalid similarityBoost value"] };
|
||||
}
|
||||
requireInRange(value, 0, 1, "similarityBoost");
|
||||
return {
|
||||
handled: true,
|
||||
overrides: mergeVoiceSettingsOverride(ctx, { similarityBoost: value }),
|
||||
};
|
||||
}
|
||||
case "style": {
|
||||
if (!ctx.policy.allowVoiceSettings) {
|
||||
return { handled: true };
|
||||
}
|
||||
const value = parseNumberValue(ctx.value);
|
||||
if (value == null) {
|
||||
return { handled: true, warnings: ["invalid style value"] };
|
||||
}
|
||||
requireInRange(value, 0, 1, "style");
|
||||
return { handled: true, overrides: mergeVoiceSettingsOverride(ctx, { style: value }) };
|
||||
}
|
||||
case "similarity_boost":
|
||||
case "style":
|
||||
case "speed": {
|
||||
if (!ctx.policy.allowVoiceSettings) {
|
||||
return { handled: true };
|
||||
}
|
||||
const setting = ctx.key.startsWith("similarity") ? "similarityBoost" : ctx.key;
|
||||
const value = parseNumberValue(ctx.value);
|
||||
if (value == null) {
|
||||
return { handled: true, warnings: ["invalid speed value"] };
|
||||
return { handled: true, warnings: [`invalid ${setting} value`] };
|
||||
}
|
||||
requireInRange(value, 0.5, 2, "speed");
|
||||
return { handled: true, overrides: mergeVoiceSettingsOverride(ctx, { speed: value }) };
|
||||
requireInRange(value, setting === "speed" ? 0.5 : 0, setting === "speed" ? 2 : 1, setting);
|
||||
return {
|
||||
handled: true,
|
||||
overrides: mergeVoiceSettingsOverride(ctx, { [setting]: value }),
|
||||
};
|
||||
}
|
||||
case "speakerboost":
|
||||
case "speaker_boost":
|
||||
|
||||
Reference in New Issue
Block a user