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:
@@ -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),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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()))?;
|
||||||
|
|
||||||
|
|||||||
@@ -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),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -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", {
|
||||||
|
|||||||
@@ -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)}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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">
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,6 +54,10 @@ function toCSV(segments) {
|
|||||||
return csv;
|
return csv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function escapeHtml(str) {
|
||||||
|
return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
||||||
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
|||||||
Reference in New Issue
Block a user