* Voice UX: simple speak toggle, onboarding pick, chat voice change Replace Kokoro-branded settings with a Kann sprechen / Spricht nicht toggle, onboarding voice personalization, and local chat commands for voice changes. German voice presets (Eva, Bernd) surface as friendly names; Kokoro stays under the hood via KOKORO_BASE_URL. Co-authored-by: cynarAI <cynarAI@users.noreply.github.com> * Fix import order in voice onboarding and settings Co-authored-by: cynarAI <cynarAI@users.noreply.github.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>
62 lines
2.0 KiB
TypeScript
62 lines
2.0 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { parseVoiceChatCommand } from "./voice-chat-command.js";
|
|
import { defaultVoiceForLocale, matchVoiceByName } from "./voice-labels.js";
|
|
|
|
describe("parseVoiceChatCommand", () => {
|
|
it("parses slash voice commands", () => {
|
|
expect(parseVoiceChatCommand("/stimme Eva")).toEqual({
|
|
kind: "set_voice",
|
|
voiceName: "Eva",
|
|
});
|
|
expect(parseVoiceChatCommand("/voice bernd")).toEqual({
|
|
kind: "set_voice",
|
|
voiceName: "bernd",
|
|
});
|
|
});
|
|
|
|
it("parses natural German voice change requests", () => {
|
|
expect(parseVoiceChatCommand("Wechsel deine Stimme zu Bernd")).toEqual({
|
|
kind: "set_voice",
|
|
voiceName: "Bernd",
|
|
});
|
|
expect(parseVoiceChatCommand("Sprich mit der Stimme Eva")).toEqual({
|
|
kind: "set_voice",
|
|
voiceName: "Eva",
|
|
});
|
|
});
|
|
|
|
it("parses speak on/off toggles", () => {
|
|
expect(parseVoiceChatCommand("Sprich nicht mehr")).toEqual({ kind: "speak_off" });
|
|
expect(parseVoiceChatCommand("/sprechen")).toEqual({ kind: "speak_on" });
|
|
expect(parseVoiceChatCommand("Read replies aloud")).toEqual({ kind: "speak_on" });
|
|
});
|
|
|
|
it("returns null for normal chat", () => {
|
|
expect(parseVoiceChatCommand("Summarize my inbox")).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe("matchVoiceByName", () => {
|
|
const voices = [
|
|
{ id: "df_eva", label: "Eva", description: "Deutsch · warm" },
|
|
{ id: "dm_bernd", label: "Bernd", description: "Deutsch · klar" },
|
|
];
|
|
|
|
it("matches label, id, and partial names", () => {
|
|
expect(matchVoiceByName(voices, "Eva")?.id).toBe("df_eva");
|
|
expect(matchVoiceByName(voices, "df_eva")?.id).toBe("df_eva");
|
|
expect(matchVoiceByName(voices, "bernd")?.id).toBe("dm_bernd");
|
|
});
|
|
});
|
|
|
|
describe("defaultVoiceForLocale", () => {
|
|
it("prefers Eva for German locale", () => {
|
|
const voices = [
|
|
{ id: "af_heart", label: "Heart" },
|
|
{ id: "df_eva", label: "Eva" },
|
|
{ id: "dm_bernd", label: "Bernd" },
|
|
];
|
|
expect(defaultVoiceForLocale(voices, "de")?.id).toBe("df_eva");
|
|
});
|
|
});
|