Add last_failure to worker state

The `WorkerSnapshot` now includes `last_failure`, which tracks the time
of the last recorded error. This allows the UI to display a more
accurate status, especially when a failure occurs after a recent
success.

The `pick_footer_status` function has been updated to prioritize
`last_failure`. If a failure occurred more recently than the last
success, the footer will show `Offline`, regardless of the success age.
This addresses scenarios where the server might have temporarily failed,
and the UI should reflect that immediately.

The `run_loop` function now updates `last_failure` upon transient or
terminal upload errors and poll failures. This ensures that the new
state information is correctly propagated.
This commit is contained in:
2026-04-18 13:45:21 +02:00
parent 305d739f56
commit 79e91246c6
4 changed files with 144 additions and 47 deletions
+1 -1
View File
@@ -7,7 +7,7 @@ use tracing::debug;
/// the transcript itself (no hallucination) so the doctor can recognize the
/// case from the watch face. English instructions for small-model
/// robustness, German output.
const SYSTEM_PROMPT: &str = "You are a keyword-extraction assistant for a German medical dictation app. Given a transcript, output a short German one-line label for the case.\n\nCRITICAL — empty-string rule:\nIf the transcript is empty, silent, or contains no identifiable medical keyword, respond with an EMPTY STRING. Do not guess, do not produce filler, do not write \"Unbekannt\" or \"Kein Befund\". An empty answer is correct.\n\nRules:\n- 2-4 words, at most 50 characters, single line.\n- Start with the most important noun from the transcript: body region, organ, imaging modality, or key finding.\n- Use ONLY terms that appear in the transcript. Do not invent, translate, or paraphrase. Do not add diagnoses the doctor did not mention.\n- No filler prefixes: \"Patient\", \"Fall\", \"Verdacht auf\", \"Untersuchung\", \"Diktat\", articles.\n- No intensifiers (\"massiv\", \"ausgeprägt\", \"deutlich\", \"hochgradig\").\n- No quotes, no trailing period, no introductory phrase.\n- If the doctor explicitly names the case (\"Bezeichnung: X\", \"Fall-ID: X\"), start with that exact string.\n- Respond in German. One line only.\n\nExamples:\n\nTranscript: \"Bezeichnung: Schulter links. Patient klagt über...\"\nOutput: Schulter links\n\nTranscript: \"...V.a. Bandscheibenvorfall in der LWS, Schmerzen strahlen...\"\nOutput: LWS, V.a. Bandscheibenvorfall\n\nREMINDER: For silent, empty, or non-medical transcripts, respond with nothing at all — an empty string. Never invent content.";
const SYSTEM_PROMPT: &str = "You are a keyword-extraction assistant for a German medical dictation app. Given a transcript, output a short German one-line label for the case.\n\nCRITICAL — silence rule:\nIf the transcript is empty, silent, or contains no identifiable medical keyword, return no text at all. Leave your answer completely blank. Do NOT echo the words 'empty', 'nothing', 'none', 'N/A', 'null', '-', a placeholder, or any description of emptiness. Emit zero characters.\n\nRules:\n- 2-4 words, at most 50 characters, single line.\n- Start with the most important noun from the transcript: body region, organ, imaging modality, or key finding.\n- Use ONLY terms that appear in the transcript. Do not invent, translate, or paraphrase. Do not add diagnoses the doctor did not mention.\n- No filler prefixes: \"Patient\", \"Fall\", \"Verdacht auf\", \"Untersuchung\", \"Diktat\", articles.\n- No intensifiers (\"massiv\", \"ausgeprägt\", \"deutlich\", \"hochgradig\").\n- No quotes, no trailing period, no introductory phrase.\n- If the doctor explicitly names the case (\"Bezeichnung: X\", \"Fall-ID: X\"), start with that exact string.\n- Respond in German. One line only.\n\nExamples:\n\nTranscript: \"Bezeichnung: Schulter links. Patient klagt über...\"\nOutput: Schulter links\n\nTranscript: \"...V.a. Bandscheibenvorfall in der LWS, Schmerzen strahlen...\"\nOutput: LWS, V.a. Bandscheibenvorfall\n\nREMINDER: For silent, empty, or non-medical transcripts, emit zero characters. Do not write the words 'empty', 'nothing', 'none', or any placeholder — just produce no output.";
/// Deterministic leading-filler prefixes stripped after the LLM response.
/// The trailing space is part of the match — we only strip whole tokens.