agent: foundation — sync incremental changes from legacy codebase

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
jake
2026-03-21 10:50:32 +00:00
parent 387e7d7acc
commit 4c0fd0aeda
10 changed files with 22 additions and 15 deletions

View File

@@ -71,7 +71,7 @@ static ALL_MODELS: LazyLock<Vec<ModelEntry>> = LazyLock::new(|| {
languages: LanguageSupport::EnglishOnly, languages: LanguageSupport::EnglishOnly,
files: vec![ files: vec![
ModelFile { ModelFile {
filename: "model_int8.onnx", filename: "encoder-model.onnx",
url: "https://huggingface.co/onnx-community/parakeet-ctc-0.6b-ONNX/resolve/main/onnx/model_int8.onnx", url: "https://huggingface.co/onnx-community/parakeet-ctc-0.6b-ONNX/resolve/main/onnx/model_int8.onnx",
size: Megabytes(1), size: Megabytes(1),
}, },

View File

@@ -91,7 +91,7 @@ async fn download_file(
); );
let client = reqwest::Client::builder() let client = reqwest::Client::builder()
.timeout(std::time::Duration::from_secs(30)) .connect_timeout(std::time::Duration::from_secs(30))
.build() .build()
.map_err(|e| KonError::DownloadFailed(e.to_string()))?; .map_err(|e| KonError::DownloadFailed(e.to_string()))?;

View File

@@ -123,6 +123,7 @@ pub async fn transcribe_pcm_parakeet(
remove_fillers: bool, remove_fillers: bool,
british_english: bool, british_english: bool,
anti_hallucination: bool, anti_hallucination: bool,
format_mode: String,
) -> Result<(), String> { ) -> Result<(), String> {
let engine = state.parakeet_engine.clone(); let engine = state.parakeet_engine.clone();
let audio = kon_core::AudioSamples::mono_16khz(samples); let audio = kon_core::AudioSamples::mono_16khz(samples);
@@ -141,7 +142,7 @@ pub async fn transcribe_pcm_parakeet(
remove_fillers, remove_fillers,
british_english, british_english,
anti_hallucination, anti_hallucination,
format_mode: FormatMode::parse("Clean"), format_mode: FormatMode::parse(&format_mode),
}, },
); );

View File

@@ -322,6 +322,7 @@
removeFillers: settings.removeFillers, removeFillers: settings.removeFillers,
britishEnglish: settings.britishEnglish, britishEnglish: settings.britishEnglish,
antiHallucination: settings.antiHallucination, antiHallucination: settings.antiHallucination,
formatMode: settings.formatMode,
}); });
} else { } else {
await invoke("transcribe_pcm", { await invoke("transcribe_pcm", {

View File

@@ -124,7 +124,8 @@
if (!fileTranscript) return; if (!fileTranscript) return;
showExportMenu = false; showExportMenu = false;
const content = exportTranscript(fileTranscript, segments, format); const content = exportTranscript(fileTranscript, segments, format);
const ext = format === "vtt" ? "vtt" : format === "srt" ? "srt" : format === "md" ? "md" : "txt"; const extMap = { vtt: "vtt", srt: "srt", md: "md", csv: "csv", html: "html" };
const ext = extMap[format] || "txt";
const blob = new Blob([content], { type: "text/plain" }); const blob = new Blob([content], { type: "text/plain" });
const url = URL.createObjectURL(blob); const url = URL.createObjectURL(blob);
const a = document.createElement("a"); const a = document.createElement("a");
@@ -230,7 +231,7 @@
>Export</button> >Export</button>
{#if showExportMenu} {#if showExportMenu}
<div class="absolute left-0 bottom-full mb-1 bg-bg-card border border-border rounded-lg shadow-lg py-1 z-10 animate-fade-in min-w-[120px]"> <div class="absolute left-0 bottom-full mb-1 bg-bg-card border border-border rounded-lg shadow-lg py-1 z-10 animate-fade-in min-w-[120px]">
{#each [["txt", "Plain Text"], ["md", "Markdown"], ["srt", "SRT Subtitles"], ["vtt", "WebVTT"]] as [fmt, label]} {#each [["txt", "Plain Text"], ["md", "Markdown"], ["csv", "CSV"], ["html", "HTML"], ["srt", "SRT Subtitles"], ["vtt", "WebVTT"]] as [fmt, label]}
<button <button
class="w-full text-left btn-md text-text-secondary hover:bg-hover hover:text-text" class="w-full text-left btn-md text-text-secondary hover:bg-hover hover:text-text"
onclick={() => handleExport(fmt)} onclick={() => handleExport(fmt)}

View File

@@ -35,6 +35,7 @@
); );
function clearAll() { function clearAll() {
if (!confirm("Delete all history? This can't be undone.")) return;
history.splice(0); history.splice(0);
saveHistory(); saveHistory();
expandedId = null; expandedId = null;

View File

@@ -100,8 +100,9 @@
await invoke("download_model", { size }); await invoke("download_model", { size });
downloadedModels = await invoke("list_models"); downloadedModels = await invoke("list_models");
downloadingModel = ""; downloadingModel = "";
} catch { } catch (err) {
downloadingModel = ""; downloadingModel = "";
engineStatus = typeof err === "string" ? err : "Download failed";
} }
} }
@@ -138,9 +139,9 @@
parakeetDownloaded = true; parakeetDownloaded = true;
parakeetDownloading = false; parakeetDownloading = false;
parakeetStatus = "Downloaded (not loaded)"; parakeetStatus = "Downloaded (not loaded)";
} catch { } catch (err) {
parakeetDownloading = false; parakeetDownloading = false;
parakeetStatus = "Download failed"; parakeetStatus = typeof err === "string" ? err : "Download failed";
} }
} }

View File

@@ -454,7 +454,7 @@
<!-- Delete --> <!-- Delete -->
<button <button
aria-label="Delete task" aria-label="Delete task"
class="mt-0.5 text-text-tertiary hover:text-danger opacity-0 group-hover:opacity-100 transition-opacity" class="mt-0.5 text-text-tertiary hover:text-danger opacity-0 group-hover:opacity-100 focus:opacity-100 transition-opacity"
onclick={() => deleteTask(task.id)} onclick={() => deleteTask(task.id)}
> >
<svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> <svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
@@ -499,7 +499,7 @@
</div> </div>
<button <button
aria-label="Delete completed task" aria-label="Delete completed task"
class="mt-0.5 text-text-tertiary hover:text-danger opacity-0 group-hover:opacity-100 transition-opacity" class="mt-0.5 text-text-tertiary hover:text-danger opacity-0 group-hover:opacity-100 focus:opacity-100 transition-opacity"
onclick={() => deleteTask(task.id)} onclick={() => deleteTask(task.id)}
> >
<svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> <svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">

View File

@@ -260,7 +260,7 @@ export function moveTaskListToProfile(listId, profileId) {
const list = taskLists.find((l) => l.id === listId); const list = taskLists.find((l) => l.id === listId);
if (list && !list.builtIn) { if (list && !list.builtIn) {
list.profileId = profileId || null; list.profileId = profileId || null;
if (profileId) list.name = profileId; if (profileId && !list.name) list.name = profileId;
saveTaskLists(); saveTaskLists();
} }
} }

View File

@@ -54,6 +54,10 @@ function toCSV(segments) {
return csv; return csv;
} }
function escapeHtml(str) {
return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
}
function toHTML(text, segments) { function toHTML(text, segments) {
let html = `<!DOCTYPE html> let html = `<!DOCTYPE html>
<html lang="en"> <html lang="en">
@@ -67,7 +71,6 @@ function toHTML(text, segments) {
.segment { display: flex; gap: 1rem; padding: 0.4rem 0; } .segment { display: flex; gap: 1rem; padding: 0.4rem 0; }
.timestamp { color: #9a9486; font-size: 0.8rem; min-width: 3rem; font-variant-numeric: tabular-nums; padding-top: 0.15rem; } .timestamp { color: #9a9486; font-size: 0.8rem; min-width: 3rem; font-variant-numeric: tabular-nums; padding-top: 0.15rem; }
.text { flex: 1; } .text { flex: 1; }
.starred { border-left: 3px solid #e8a87c; padding-left: 0.5rem; }
</style> </style>
</head> </head>
<body> <body>
@@ -83,11 +86,10 @@ function toHTML(text, segments) {
for (const seg of segments) { for (const seg of segments) {
const mins = Math.floor(seg.start / 60); const mins = Math.floor(seg.start / 60);
const secs = Math.floor(seg.start % 60); const secs = Math.floor(seg.start % 60);
const starClass = seg.starred ? ' starred' : ''; html += `<div class="segment"><span class="timestamp">${pad(mins)}:${pad(secs)}</span><span class="text">${escapeHtml(seg.text.trim())}</span></div>\n`;
html += `<div class="segment${starClass}"><span class="timestamp">${pad(mins)}:${pad(secs)}</span><span class="text">${seg.text.trim()}</span></div>\n`;
} }
} else { } else {
html += `<p>${text.replace(/\n/g, "<br>")}</p>`; html += `<p>${escapeHtml(text).replace(/\n/g, "<br>")}</p>`;
} }
html += `</body></html>`; html += `</body></html>`;
return html; return html;