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,
|
||||
files: vec![
|
||||
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",
|
||||
size: Megabytes(1),
|
||||
},
|
||||
|
||||
@@ -91,7 +91,7 @@ async fn download_file(
|
||||
);
|
||||
|
||||
let client = reqwest::Client::builder()
|
||||
.timeout(std::time::Duration::from_secs(30))
|
||||
.connect_timeout(std::time::Duration::from_secs(30))
|
||||
.build()
|
||||
.map_err(|e| KonError::DownloadFailed(e.to_string()))?;
|
||||
|
||||
|
||||
@@ -123,6 +123,7 @@ pub async fn transcribe_pcm_parakeet(
|
||||
remove_fillers: bool,
|
||||
british_english: bool,
|
||||
anti_hallucination: bool,
|
||||
format_mode: String,
|
||||
) -> Result<(), String> {
|
||||
let engine = state.parakeet_engine.clone();
|
||||
let audio = kon_core::AudioSamples::mono_16khz(samples);
|
||||
@@ -141,7 +142,7 @@ pub async fn transcribe_pcm_parakeet(
|
||||
remove_fillers,
|
||||
british_english,
|
||||
anti_hallucination,
|
||||
format_mode: FormatMode::parse("Clean"),
|
||||
format_mode: FormatMode::parse(&format_mode),
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@@ -322,6 +322,7 @@
|
||||
removeFillers: settings.removeFillers,
|
||||
britishEnglish: settings.britishEnglish,
|
||||
antiHallucination: settings.antiHallucination,
|
||||
formatMode: settings.formatMode,
|
||||
});
|
||||
} else {
|
||||
await invoke("transcribe_pcm", {
|
||||
|
||||
@@ -124,7 +124,8 @@
|
||||
if (!fileTranscript) return;
|
||||
showExportMenu = false;
|
||||
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 url = URL.createObjectURL(blob);
|
||||
const a = document.createElement("a");
|
||||
@@ -230,7 +231,7 @@
|
||||
>Export</button>
|
||||
{#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]">
|
||||
{#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
|
||||
class="w-full text-left btn-md text-text-secondary hover:bg-hover hover:text-text"
|
||||
onclick={() => handleExport(fmt)}
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
);
|
||||
|
||||
function clearAll() {
|
||||
if (!confirm("Delete all history? This can't be undone.")) return;
|
||||
history.splice(0);
|
||||
saveHistory();
|
||||
expandedId = null;
|
||||
|
||||
@@ -100,8 +100,9 @@
|
||||
await invoke("download_model", { size });
|
||||
downloadedModels = await invoke("list_models");
|
||||
downloadingModel = "";
|
||||
} catch {
|
||||
} catch (err) {
|
||||
downloadingModel = "";
|
||||
engineStatus = typeof err === "string" ? err : "Download failed";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,9 +139,9 @@
|
||||
parakeetDownloaded = true;
|
||||
parakeetDownloading = false;
|
||||
parakeetStatus = "Downloaded (not loaded)";
|
||||
} catch {
|
||||
} catch (err) {
|
||||
parakeetDownloading = false;
|
||||
parakeetStatus = "Download failed";
|
||||
parakeetStatus = typeof err === "string" ? err : "Download failed";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -454,7 +454,7 @@
|
||||
<!-- Delete -->
|
||||
<button
|
||||
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)}
|
||||
>
|
||||
<svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
@@ -499,7 +499,7 @@
|
||||
</div>
|
||||
<button
|
||||
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)}
|
||||
>
|
||||
<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);
|
||||
if (list && !list.builtIn) {
|
||||
list.profileId = profileId || null;
|
||||
if (profileId) list.name = profileId;
|
||||
if (profileId && !list.name) list.name = profileId;
|
||||
saveTaskLists();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +54,10 @@ function toCSV(segments) {
|
||||
return csv;
|
||||
}
|
||||
|
||||
function escapeHtml(str) {
|
||||
return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
||||
}
|
||||
|
||||
function toHTML(text, segments) {
|
||||
let html = `<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
@@ -67,7 +71,6 @@ function toHTML(text, segments) {
|
||||
.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; }
|
||||
.text { flex: 1; }
|
||||
.starred { border-left: 3px solid #e8a87c; padding-left: 0.5rem; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -83,11 +86,10 @@ function toHTML(text, segments) {
|
||||
for (const seg of segments) {
|
||||
const mins = Math.floor(seg.start / 60);
|
||||
const secs = Math.floor(seg.start % 60);
|
||||
const starClass = seg.starred ? ' starred' : '';
|
||||
html += `<div class="segment${starClass}"><span class="timestamp">${pad(mins)}:${pad(secs)}</span><span class="text">${seg.text.trim()}</span></div>\n`;
|
||||
html += `<div class="segment"><span class="timestamp">${pad(mins)}:${pad(secs)}</span><span class="text">${escapeHtml(seg.text.trim())}</span></div>\n`;
|
||||
}
|
||||
} else {
|
||||
html += `<p>${text.replace(/\n/g, "<br>")}</p>`;
|
||||
html += `<p>${escapeHtml(text).replace(/\n/g, "<br>")}</p>`;
|
||||
}
|
||||
html += `</body></html>`;
|
||||
return html;
|
||||
|
||||
Reference in New Issue
Block a user