feat: add multilingual dictation and simplify chat STT picker
This commit is contained in:
+25
-6
@@ -7,7 +7,7 @@ import { createTeacherAgent } from "../src/agent/teacher-agent.ts";
|
||||
import { createPracticeAgent } from "../src/agent/teacher-agent.ts";
|
||||
import { sanitizeUserSettings } from "../src/core/settings.ts";
|
||||
import { parseGeneralSettingsBody } from "../src/server/settings-body.ts";
|
||||
import { countLabel, dictationUrl, resolveLanguage, systemLanguage, translate } from "../src/core/i18n.ts";
|
||||
import { countLabel, dictationUrl, resolveLanguage, resolveSttLanguage, systemLanguage, translate } from "../src/core/i18n.ts";
|
||||
import { sessionMarkdown } from "../src/core/session-markdown.ts";
|
||||
import type { LhMessage } from "../src/core/native-messages.ts";
|
||||
import { I18nProvider, LanguageSelect } from "../components/i18n.tsx";
|
||||
@@ -29,6 +29,15 @@ describe("language preferences", () => {
|
||||
assert.equal(resolveLanguage("en", "ru-RU"), "en");
|
||||
assert.equal(resolveLanguage("ru", "en-US"), "ru");
|
||||
});
|
||||
it("resolves multilingual only for STT and keeps system defaults independent", () => {
|
||||
assert.equal(resolveSttLanguage("multi", "ru-RU"), "multi");
|
||||
assert.equal(resolveSttLanguage("multi", "en-US"), "multi");
|
||||
assert.equal(resolveLanguage("multi", "ru-RU"), "ru");
|
||||
assert.equal(resolveSttLanguage(undefined, "ru-RU"), "ru");
|
||||
assert.equal(resolveSttLanguage(undefined, "de-DE"), "en");
|
||||
assert.equal(resolveSttLanguage("en", "ru-RU"), "en");
|
||||
assert.equal(resolveSttLanguage("ru", "en-US"), "ru");
|
||||
});
|
||||
it("validates both independent preferences without changing existing general options", () => {
|
||||
const general = { autoUpdate: false, language: "ru", sttLanguage: "en" };
|
||||
assert.deepEqual(parseGeneralSettingsBody(general), { ok: true, settings: general });
|
||||
@@ -38,15 +47,25 @@ describe("language preferences", () => {
|
||||
assert.equal(parseGeneralSettingsBody({ sttLanguage: "fr" }).ok, false);
|
||||
assert.deepEqual(sanitizeUserSettings({ version: 1, general: { language: null, sttLanguage: "fr", autoUpdate: false } })?.general, { autoUpdate: false });
|
||||
});
|
||||
it("accepts a multilingual STT preference without allowing a multilingual interface", () => {
|
||||
const general = { autoUpdate: false, language: "ru", sttLanguage: "multi" };
|
||||
assert.deepEqual(parseGeneralSettingsBody(general), { ok: true, settings: general });
|
||||
assert.deepEqual(sanitizeUserSettings({ version: 1, general })?.general, general);
|
||||
assert.equal(parseGeneralSettingsBody({ language: "multi" }).ok, false);
|
||||
assert.deepEqual(sanitizeUserSettings({ version: 1, general: { language: "multi", sttLanguage: "multi" } })?.general, { sttLanguage: "multi" });
|
||||
const invalid = parseGeneralSettingsBody({ sttLanguage: "auto" });
|
||||
assert(!invalid.ok);
|
||||
assert.equal(translate("ru", invalid.error), "Параметр sttLanguage должен иметь значение «en», «ru» или «multi»");
|
||||
});
|
||||
it("pins an explicit supported language in the STT provider request", () => {
|
||||
for (const language of ["en", "ru"] as const) {
|
||||
for (const language of ["en", "ru", "multi"] as const) {
|
||||
const url = new URL(dictationUrl(language));
|
||||
assert.equal(url.protocol, "wss:");
|
||||
assert.equal(url.hostname, "api.deepgram.com");
|
||||
assert.equal(url.searchParams.get("language"), language);
|
||||
assert.equal(url.searchParams.get("model"), "nova-3");
|
||||
assert.equal(url.searchParams.get("encoding"), "linear16");
|
||||
assert.equal(url.searchParams.get("sample_rate"), "16000");
|
||||
assert.deepEqual(Object.fromEntries(url.searchParams), {
|
||||
model: "nova-3", language, encoding: "linear16", sample_rate: "16000",
|
||||
channels: "1", smart_format: "true", punctuate: "true", endpointing: "300",
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user