70425939b2
Introduces a new module `auto_trigger` responsible for opportunistically initiating LLM analysis jobs. This mechanism scans case directories for new or updated recordings and transcripts, automatically creating and queuing analysis jobs when appropriate. Key components: - `evaluate_case`: Pure function to determine if a case is ready for analysis based on recording status, transcriptions, document modification times, and existing job/failure markers. - `try_enqueue`: Orchestrates the analysis job creation and queuing process if `evaluate_case` returns `AutoDecision::Enqueue`. - `try_enqueue_all_for_user`: Iterates through all user cases to trigger `try_enqueue` for eligible ones. - `write_failure_marker`/`remove_failure_marker`: Handles persistent recording of analysis failures and their cleanup. This feature aims to reduce manual intervention by automatically analyzing new or changed case data.
52 lines
1.7 KiB
Rust
52 lines
1.7 KiB
Rust
use std::path::PathBuf;
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
use tokio::sync::mpsc;
|
|
|
|
pub mod auto_trigger;
|
|
pub mod llm;
|
|
pub mod prompt;
|
|
pub mod recovery;
|
|
pub mod render;
|
|
pub mod worker;
|
|
|
|
/// Single-document-per-case filenames. A re-analysis overwrites the
|
|
/// document in place (handler deletes it first; worker writes the fresh one).
|
|
pub const DOCUMENT_FILE: &str = "document.md";
|
|
pub const ANALYSIS_INPUT_FILE: &str = "analysis_input.json";
|
|
|
|
/// A single request to analyze a case. Payload is tiny (a path), so the
|
|
/// channel is unbounded — persistence lives in `analysis_input.json` on
|
|
/// disk, not in the queue. Recovery re-enqueues any inputs the server may
|
|
/// have held at crash time.
|
|
#[derive(Debug, Clone)]
|
|
pub struct AnalyzeJob {
|
|
pub case_dir: PathBuf,
|
|
}
|
|
|
|
pub type AnalyzeSender = mpsc::UnboundedSender<AnalyzeJob>;
|
|
pub type AnalyzeReceiver = mpsc::UnboundedReceiver<AnalyzeJob>;
|
|
|
|
pub fn channel() -> (AnalyzeSender, AnalyzeReceiver) {
|
|
mpsc::unbounded_channel()
|
|
}
|
|
|
|
/// Persistent input for a single analysis run. Written by the analyze
|
|
/// handler, consumed by the analyze worker, removed after a successful
|
|
/// document write.
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct AnalysisInput {
|
|
/// Latest filesystem mtime (server clock) of any `.m4a` in the case at
|
|
/// the moment the analyze button was clicked. Carried through for
|
|
/// diagnostics / future "Nachtrag" detection.
|
|
pub last_recording_mtime: String,
|
|
pub recordings: Vec<RecordingInput>,
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct RecordingInput {
|
|
/// Recording timestamp from the watch (filename-derived, ISO-8601).
|
|
pub recorded_at: String,
|
|
pub text: String,
|
|
}
|