Add oneliner generation from transcriptions

This commit introduces functionality to automatically generate a
one-liner summary from a completed transcription.

The `ensure_oneliner` function checks if `oneliner.txt` already exists
in the case directory. If not, it uses the Ollama API to generate a
summary from the full transcript. Any errors during generation or
writing are logged but do not halt the transcription process.
This commit is contained in:
2026-04-13 17:29:58 +02:00
parent 890f55ab8e
commit 33da841087
+44 -1
View File
@@ -1,11 +1,14 @@
use std::path::Path;
use std::sync::Arc;
use std::time::Duration;
use tracing::{error, info, warn};
use super::{ffmpeg, whisper, TranscribeReceiver};
use super::{ffmpeg, ollama, whisper, TranscribeReceiver};
use crate::config::Config;
const ONELINER_TIMEOUT: Duration = Duration::from_secs(60);
/// Consume transcription jobs sequentially. Whisper holds the GPU, so parallelism
/// here would only cause contention. One job in flight at a time.
pub async fn run(mut rx: TranscribeReceiver, config: Arc<Config>, client: reqwest::Client) {
@@ -48,7 +51,47 @@ pub async fn run(mut rx: TranscribeReceiver, config: Arc<Config>, client: reqwes
bytes = text.len(),
"Transcript written"
);
if let Some(case_dir) = audio_path.parent() {
ensure_oneliner(case_dir, &text, &client, &config).await;
}
}
warn!("Transcription worker stopped (channel closed)");
}
/// Generate `case_dir/oneliner.txt` from the given transcript iff the file
/// does not already exist. Errors are non-fatal: logged and swallowed.
async fn ensure_oneliner(
case_dir: &Path,
transcript: &str,
client: &reqwest::Client,
config: &Config,
) {
let path = case_dir.join("oneliner.txt");
if path.exists() {
return;
}
match ollama::generate_oneliner(
client,
&config.ollama_url,
&config.ollama_model,
config.ollama_keep_alive,
transcript,
ONELINER_TIMEOUT,
)
.await
{
Ok(line) => {
if let Err(e) = tokio::fs::write(&path, &line).await {
error!(path = %path.display(), error = %e, "writing oneliner failed");
} else {
info!(path = %path.display(), chars = line.chars().count(), "Oneliner written");
}
}
Err(e) => {
error!(case = %case_dir.display(), error = %e, "oneliner generation failed");
}
}
}