feat(transcribe): GPT cleanup pass + advanced options i18n

Adds optional post-transcription cleanup via GPT-4o/GPT-4o-mini to fix
mishearing errors, punctuation, and domain terms. Speaker role labelling
now accepts a deployment param. Adds i18n strings for advanced options
panel (task, VAD filter, Whisper model, AI cleanup) in all four languages.
Updates BvjAnalyzerAgent and DeepResearchAgent.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-18 07:23:01 +02:00
parent e32ee60e78
commit c4362738c1
5 changed files with 345 additions and 112 deletions
+61
View File
@@ -441,6 +441,20 @@ const TRANSCRIBE_I18N = {
traceProcessingDetail: () => 'Processing audio. Large files may take 13 minutes.',
traceStillLabel: (clip) => `${clip} — still processing…`,
traceStillDetail: (e) => { const m = Math.floor(e / 60), s = e % 60; return m > 0 ? `${m}m ${s}s elapsed — working through the audio.` : `${e}s elapsed — processing.`; },
advancedOptions: 'Advanced options',
task: 'Task',
taskTranscribe: 'Transcribe',
taskTranslate: 'Translate to English',
vadFilter: 'VAD filter',
vadFilterLabel: 'Remove silence / noise',
vadFilterHint: 'Improves accuracy on recordings with long pauses.',
whisperModel: 'Whisper model',
whisperModelHint: 'Used when Azure/GCP unavailable. large-v3 is the default.',
postModel: 'AI cleanup',
postModelNone: 'None',
postModelMini: 'GPT-4o Mini',
postModelFull: 'GPT-4o',
postModelHint: 'Fixes errors, punctuation, and domain terms after transcription.',
},
no: {
transcribeLang: 'Språk i lydfil',
@@ -481,6 +495,20 @@ const TRANSCRIBE_I18N = {
traceProcessingLabel: (clip) => `${clip} — transkriberer`,
traceProcessingDetail: () => 'Behandler lyden. Store filer tar 13 minutter.', traceStillLabel: (clip) => `${clip} — behandler fortsatt…`,
traceStillDetail: (e) => { const m = Math.floor(e / 60), s = e % 60; return m > 0 ? `${m} min ${s}s gått — jobber gjennom lyden.` : `${e}s gått — behandler.`; },
advancedOptions: 'Avanserte valg',
task: 'Oppgave',
taskTranscribe: 'Transkriber',
taskTranslate: 'Oversett til engelsk',
vadFilter: 'VAD-filter',
vadFilterLabel: 'Fjern stillhet / støy',
vadFilterHint: 'Forbedrer nøyaktigheten ved opptak med lange pauser.',
whisperModel: 'Whisper-modell',
whisperModelHint: 'Brukes når Azure/GCP ikke er tilgjengelig. large-v3 er standard.',
postModel: 'AI-opprydding',
postModelNone: 'Ingen',
postModelMini: 'GPT-4o Mini',
postModelFull: 'GPT-4o',
postModelHint: 'Retter feil, tegnsetting og fagtermer etter transkripsjon.',
},
uk: {
transcribeLang: 'Мова аудіо',
@@ -521,6 +549,20 @@ const TRANSCRIBE_I18N = {
traceProcessingLabel: (clip) => `${clip} — транскрибування`,
traceProcessingDetail: () => 'Обробка аудіо. Великі файли займають 1–3 хвилини.', traceStillLabel: (clip) => `${clip} — ще обробляється…`,
traceStillDetail: (e) => { const m = Math.floor(e / 60), s = e % 60; return m > 0 ? `Минуло ${m} хв ${s} с — обробка.` : `Минуло ${e} с — обробка.`; },
advancedOptions: 'Розширені параметри',
task: 'Завдання',
taskTranscribe: 'Транскрибувати',
taskTranslate: 'Перекласти на англійську',
vadFilter: 'VAD-фільтр',
vadFilterLabel: 'Видалити тишу / шум',
vadFilterHint: 'Покращує точність для записів з довгими паузами.',
whisperModel: 'Модель Whisper',
whisperModelHint: 'Використовується, якщо Azure/GCP недоступні. large-v3 за замовчуванням.',
postModel: 'AI-очищення',
postModelNone: 'Без',
postModelMini: 'GPT-4o Mini',
postModelFull: 'GPT-4o',
postModelHint: 'Виправляє помилки, пунктуацію та терміни після транскрипції.',
},
pl: {
transcribeLang: 'Język audio',
@@ -561,6 +603,20 @@ const TRANSCRIBE_I18N = {
traceProcessingLabel: (clip) => `${clip} — transkrybowanie`,
traceProcessingDetail: () => 'Przetwarzanie audio. Duże pliki zajmują 13 minuty.', traceStillLabel: (clip) => `${clip} — nadal przetwarza…`,
traceStillDetail: (e) => { const m = Math.floor(e / 60), s = e % 60; return m > 0 ? `Minęło ${m} min ${s} s — przetwarzanie audio.` : `Minęło ${e} s — przetwarzanie.`; },
advancedOptions: 'Opcje zaawansowane',
task: 'Zadanie',
taskTranscribe: 'Transkrypcja',
taskTranslate: 'Przetłumacz na angielski',
vadFilter: 'Filtr VAD',
vadFilterLabel: 'Usuń ciszę / szum',
vadFilterHint: 'Poprawia dokładność nagrań z długimi przerwami.',
whisperModel: 'Model Whisper',
whisperModelHint: 'Używany gdy Azure/GCP niedostępne. large-v3 jest domyślny.',
postModel: 'Korekta AI',
postModelNone: 'Brak',
postModelMini: 'GPT-4o Mini',
postModelFull: 'GPT-4o',
postModelHint: 'Poprawia błędy, interpunkcję i terminy po transkrypcji.',
},
};
@@ -1515,6 +1571,10 @@ async function runTranscribe() {
formData.append('time_offset', String(cumulativeOffset));
if (vadFilter) formData.append('vad_filter', '1');
if (initPrompt) formData.append('initial_prompt', initPrompt);
const whisperModel = document.getElementById('whisperModelSelect')?.value;
if (whisperModel) formData.append('model', whisperModel);
const postModel = document.querySelector('input[name="post_model"]:checked')?.value;
if (postModel) formData.append('post_model', postModel);
if (diarize) {
formData.append('diarize', '1');
if (numSpeakers >= 2) formData.append('num_speakers', String(numSpeakers));
@@ -1650,6 +1710,7 @@ function renderTranscriptResults(data) {
if (data.language) traceMeta.push({ label: `Language: ${data.language}`, detail: '', status: 'complete' });
if (data.num_speakers > 1) traceMeta.push({ label: `Speakers detected: ${data.num_speakers}`, detail: Object.entries(speakerRoles).map(([id, r]) => `${id}: ${r}`).join(', ') || '', status: 'complete' });
if (data.model) traceMeta.push({ label: data.model, detail: '', status: 'complete' });
if (data.cleaned_by) traceMeta.push({ label: `Cleaned by ${data.cleaned_by}`, detail: '', status: 'complete' });
renderTrace(traceMeta.length ? traceMeta : [{ label: 'Transcribed', detail: '', status: 'complete' }]);
}