use super::*;
#[test]
fn agent_msg_is_rich_each_signal_arm_flips_a_short_body() {
let c = rich_cfg();
assert!(agent_msg_is_rich("12 passed 3 failed", &c));
assert!(agent_msg_is_rich("ran 45 tests", &c));
assert!(agent_msg_is_rich("now at 12/40 done", &c));
assert!(agent_msg_is_rich("3 of 5 complete", &c));
assert!(agent_msg_is_rich("fix landed in a1b2c3d", &c));
assert!(agent_msg_is_rich("see deadbeef now", &c));
assert!(agent_msg_is_rich("the bug is at src/turns.rs:402", &c));
assert!(agent_msg_is_rich("edited src/cli.rs today", &c));
assert!(agent_msg_is_rich("the `agents` vec holds it", &c));
assert!(agent_msg_is_rich("root cause confirmed here", &c));
assert!(agent_msg_is_rich("found the real issue", &c));
assert!(agent_msg_is_rich("regression verified", &c));
let long = "z".repeat(280);
assert!(agent_msg_is_rich(&long, &c));
}
#[test]
fn agent_msg_is_rich_rejects_a_short_signalless_declaration() {
let c = rich_cfg();
assert!(!agent_msg_is_rich("let me read the file", &c));
assert!(!agent_msg_is_rich("now i will look into this", &c));
assert!(!agent_msg_is_rich("step 1 next", &c));
}
#[test]
fn agent_msg_is_rich_is_codepoint_safe_for_multibyte_with_a_digit() {
let c = rich_cfg();
let _ = agent_msg_is_rich("🤖 07:40 watching 🚀, 9 left to go", &c);
let _ = agent_msg_is_rich("🤖 confirmed 42 times, root cause at src/x.rs:9", &c);
let _ = agent_msg_is_rich("🤖 step 7 done", &c);
assert!(agent_msg_is_rich("🤖 root cause confirmed at line 42", &c));
let _ = agent_msg_is_droppable("🤖 looking at the 07:40 log", &c);
}
#[test]
fn agent_msg_is_droppable_and_keep_on_doubt() {
let c = rich_cfg();
assert!(agent_msg_is_droppable("let me read the file", &c));
assert!(agent_msg_is_droppable("now i will open this file", &c));
assert!(!agent_msg_is_droppable(
"let me note: root cause confirmed in src/x.rs:42",
&c
));
assert!(!agent_msg_is_rich(
"the boundary handling here is subtle",
&c
));
assert!(!agent_msg_is_droppable(
"the boundary handling here is subtle",
&c
));
let long_decl = format!("let me {}", "x".repeat(210));
assert!(!agent_msg_is_droppable(&long_decl, &c));
}
#[test]
fn longest_default_keeps_the_longest_not_the_last() {
let rich_response = body_chars("RICHRESP", 600); let wrap_up = "Done — let me know if you'd like anything else."; assert!(wrap_up.chars().count() < 60);
let t = mk_turn_agents(0, Some("ask"), &[&rich_response, wrap_up], 0);
let lane = select_agent_messages(&t, &longest_cfg());
let kept: Vec<&str> = lane
.iter()
.filter_map(|r| match r {
AgentRender::Kept(a) => Some(a.unit.text.as_str()),
_ => None,
})
.collect();
assert_eq!(kept.len(), 1, "only the longest survives: {lane:?}");
assert!(
kept[0].contains("RICHRESP"),
"the LONGEST (Rich Response) is kept, not the wrap-up: {kept:?}"
);
let phs = lane
.iter()
.filter(|r| matches!(r, AgentRender::Placeholder(_)))
.count();
assert_eq!(phs, 1, "the throwaway wrap-up collapses into a placeholder");
}
#[test]
fn longest_default_longest_is_a_middle_message() {
let opener = "Let me look into this."; let middle = body_chars("MIDRESP", 700); let wrap_up = "All set."; let t = mk_turn_agents(0, Some("ask"), &[opener, &middle, wrap_up], 0);
let lane = select_agent_messages(&t, &longest_cfg());
let kept: Vec<&str> = lane
.iter()
.filter_map(|r| match r {
AgentRender::Kept(a) => Some(a.unit.text.as_str()),
_ => None,
})
.collect();
assert_eq!(kept.len(), 1, "only the middle longest survives: {lane:?}");
assert!(kept[0].contains("MIDRESP"), "the middle Rich Response wins");
}
#[test]
fn longest_default_also_keeps_a_substantive_first() {
let first = body_chars("PLANFIRST", 400); let middle = body_chars("BIGMID", 900); let wrap_up = "ok done"; let t = mk_turn_agents(0, Some("ask"), &[&first, &middle, wrap_up], 0);
let lane = select_agent_messages(&t, &longest_cfg());
let kept: Vec<&str> = lane
.iter()
.filter_map(|r| match r {
AgentRender::Kept(a) => Some(a.unit.text.as_str()),
_ => None,
})
.collect();
assert!(
kept.iter().any(|k| k.contains("PLANFIRST")),
"a substantive first is ALSO kept: {kept:?}"
);
assert!(
kept.iter().any(|k| k.contains("BIGMID")),
"the longest is always kept: {kept:?}"
);
assert_eq!(kept.len(), 2, "exactly first + longest: {lane:?}");
}
#[test]
fn longest_default_drops_a_non_substantive_first() {
let first = "let me start"; let middle = body_chars("ONLYLONG", 600); let wrap_up = "fin"; let t = mk_turn_agents(0, Some("ask"), &[first, &middle, wrap_up], 0);
let lane = select_agent_messages(&t, &longest_cfg());
let kept: Vec<&str> = lane
.iter()
.filter_map(|r| match r {
AgentRender::Kept(a) => Some(a.unit.text.as_str()),
_ => None,
})
.collect();
assert_eq!(kept.len(), 1, "non-substantive first is dropped: {lane:?}");
assert!(kept[0].contains("ONLYLONG"));
}
#[test]
fn longest_default_keeps_a_rich_middle_with_a_major_finding() {
let opener = "starting now"; let finding = "12 passed 3 failed in src/x.rs:9"; let longest = body_chars("FINALANS", 500); let t = mk_turn_agents(0, Some("ask"), &[opener, finding, &longest], 0);
let lane = select_agent_messages(&t, &longest_cfg());
let kept: Vec<&str> = lane
.iter()
.filter_map(|r| match r {
AgentRender::Kept(a) => Some(a.unit.text.as_str()),
_ => None,
})
.collect();
assert!(
kept.iter().any(|k| k.contains("src/x.rs:9")),
"the rich middle finding survives: {kept:?}"
);
assert!(
kept.iter().any(|k| k.contains("FINALANS")),
"the longest survives: {kept:?}"
);
}
#[test]
fn longest_default_single_message_turn_keeps_it() {
let t = mk_turn_agents(0, Some("ask"), &["let me look into this"], 0);
let lane = select_agent_messages(&t, &longest_cfg());
assert_eq!(lane.len(), 1);
assert!(matches!(lane[0], AgentRender::Kept(_)));
}
#[test]
fn longest_default_tie_breaks_to_the_last_maximum() {
let a = "alpha beta gamma"; let b = "delta epsilon ze"; let c = "eta theta iota k"; assert_eq!(a.chars().count(), b.chars().count());
assert_eq!(b.chars().count(), c.chars().count());
let t = mk_turn_agents(0, Some("ask"), &[a, b, c], 0);
let lane = select_agent_messages(&t, &longest_cfg());
let kept: Vec<&str> = lane
.iter()
.filter_map(|r| match r {
AgentRender::Kept(a) => Some(a.unit.text.as_str()),
_ => None,
})
.collect();
assert_eq!(
kept,
vec![c],
"tie → the LAST maximum (== old agents.last())"
);
}
#[test]
fn longest_default_collapses_contiguous_runs_into_separate_placeholders() {
let t = mk_turn_agents(
0,
Some("ask"),
&[
"let me a", "let me b", "found 12 cases in src/z.rs:3", "let me c", "let me d", &body_chars("THEANSWER", 400), ],
0,
);
let lane = select_agent_messages(&t, &longest_cfg());
let phs = lane
.iter()
.filter(|r| matches!(r, AgentRender::Placeholder(_)))
.count();
assert_eq!(
phs, 2,
"two declaration runs split by the rich middle: {lane:?}"
);
let kept: Vec<&str> = lane
.iter()
.filter_map(|r| match r {
AgentRender::Kept(a) => Some(a.unit.text.as_str()),
_ => None,
})
.collect();
assert!(kept.iter().any(|k| k.contains("src/z.rs:3")));
assert!(kept.iter().any(|k| k.contains("THEANSWER")));
}
#[test]
fn longest_default_keep_flag_tunes_the_substantive_first_gate() {
let first = body_chars("TUNEFIRST", 300);
let longest = body_chars("TUNELONG", 800);
let wrap_up = "bye";
let t = mk_turn_agents(0, Some("ask"), &[&first, &longest, wrap_up], 0);
let default_kept: Vec<String> = select_agent_messages(&t, &longest_cfg())
.iter()
.filter_map(|r| match r {
AgentRender::Kept(a) => Some(a.unit.text.clone()),
_ => None,
})
.collect();
assert!(
default_kept.iter().any(|k| k.contains("TUNEFIRST")),
"300-char first IS substantive at the default 280 gate"
);
let raised = RichnessCfg {
rich_min_chars: 500,
..longest_cfg()
};
let raised_kept: Vec<String> = select_agent_messages(&t, &raised)
.iter()
.filter_map(|r| match r {
AgentRender::Kept(a) => Some(a.unit.text.clone()),
_ => None,
})
.collect();
assert!(
!raised_kept.iter().any(|k| k.contains("TUNEFIRST")),
"the same 300-char first is NOT substantive once the gate is raised to 500"
);
assert!(
raised_kept.iter().any(|k| k.contains("TUNELONG")),
"the longest still survives regardless of the gate"
);
}
#[test]
fn richness_cfg_default_is_longest() {
let d = RichnessCfg::default();
assert_eq!(d.mode, AgentMsgMode::Longest);
assert_eq!(d.run_threshold, 6);
assert_eq!(d.rich_min_chars, 280);
assert_eq!(d.declaration_max_chars, 200);
assert!(d.keep_first);
}