refactor: input contract — one extracted phrase per line (spec §1a)
split_segments now treats each non-empty trimmed line as one retrieval unit; blank lines are skipped, not paragraph delimiters. Name/signature retained (minimal-churn decision). Full suite 45/0. End-to-end: feeding the GP dictation as extracted phrases recovers I10.90 (rank 4) which was entirely missing in both modes under the paragraph contract, and largely dissolves the cross-segment diabetes crowding. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+12
-19
@@ -1,20 +1,13 @@
|
|||||||
/// Split a dictation into Befund segments on Markdown paragraph
|
/// Split the caller-extracted phrase list into retrieval units: one
|
||||||
/// breaks (one or more blank lines). Trims each segment; drops empties.
|
/// non-empty (trimmed) input line = one unit. Blank/whitespace-only
|
||||||
pub fn split_segments(dictation: &str) -> Vec<String> {
|
/// lines are skipped. Rev 2026-05-18 (spec §1a): input is extracted
|
||||||
let mut segments = Vec::new();
|
/// diagnostic phrases, not a blank-line-segmented dictation. Name and
|
||||||
let mut current: Vec<&str> = Vec::new();
|
/// signature kept; a "segment" now denotes one extracted phrase.
|
||||||
for line in dictation.lines() {
|
pub fn split_segments(phrases: &str) -> Vec<String> {
|
||||||
if line.trim().is_empty() {
|
phrases
|
||||||
if !current.is_empty() {
|
.lines()
|
||||||
segments.push(current.join("\n").trim().to_string());
|
.map(|l| l.trim())
|
||||||
current.clear();
|
.filter(|l| !l.is_empty())
|
||||||
}
|
.map(|l| l.to_string())
|
||||||
} else {
|
.collect()
|
||||||
current.push(line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !current.is_empty() {
|
|
||||||
segments.push(current.join("\n").trim().to_string());
|
|
||||||
}
|
|
||||||
segments.into_iter().filter(|s| !s.is_empty()).collect()
|
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-10
@@ -1,22 +1,30 @@
|
|||||||
use alpha_id::segment::split_segments;
|
use alpha_id::segment::split_segments;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn splits_on_blank_lines() {
|
fn one_unit_per_nonempty_line() {
|
||||||
let d = "Befund eins\nmit Zeile zwei\n\nBefund zwei\n\n\nBefund drei\n";
|
let input = "arterielle Hypertonie\nTyp-2-Diabetes mit Polyneuropathie\ngemischte Hyperlipidämie";
|
||||||
let segs = split_segments(d);
|
assert_eq!(split_segments(input), vec![
|
||||||
assert_eq!(segs, vec![
|
"arterielle Hypertonie".to_string(),
|
||||||
"Befund eins\nmit Zeile zwei".to_string(),
|
"Typ-2-Diabetes mit Polyneuropathie".to_string(),
|
||||||
"Befund zwei".to_string(),
|
"gemischte Hyperlipidämie".to_string(),
|
||||||
"Befund drei".to_string(),
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn single_segment_when_no_blank_line() {
|
fn blank_and_whitespace_lines_are_skipped_and_each_line_trimmed() {
|
||||||
assert_eq!(split_segments("nur ein Befund"), vec!["nur ein Befund".to_string()]);
|
let input = " \n\n Kreuzschmerz \n \nGonarthrose rechts\n\n";
|
||||||
|
assert_eq!(split_segments(input), vec![
|
||||||
|
"Kreuzschmerz".to_string(),
|
||||||
|
"Gonarthrose rechts".to_string(),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn empty_input_yields_no_segments() {
|
fn single_phrase_is_one_unit() {
|
||||||
|
assert_eq!(split_segments("nur eine Diagnose"), vec!["nur eine Diagnose".to_string()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn empty_or_whitespace_only_input_yields_no_units() {
|
||||||
assert!(split_segments(" \n\n").is_empty());
|
assert!(split_segments(" \n\n").is_empty());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user