use super::*;
use crate::git_tree::{Agent, AgentState};
fn branch(name: &str, state: AgentState) -> Agent {
Agent {
branch_name: format!("agents/{name}"),
agent_id: name.to_string(),
tip_oid: "0".repeat(40),
tip_short_oid: "0000000".to_string(),
tip_timestamp_unix: 0,
last_action_unix: 0,
messages: 0,
steps: vec![],
preview: None,
stream: crate::git_tree::Stream::default(),
tool_calls: vec![],
state,
state_uncertain: false,
truncated: false,
failure: None,
flagged: None,
pending: vec![],
conflicted_oid: None,
budget_oid: None,
abandoned_oid: None,
notify_oid: None,
held: None,
goal_ball: None,
name: None,
goal_name: None,
call_start_unix: None,
}
}
#[test]
fn stop_disabled_when_selection_is_none() {
let bs = vec![branch("foo", AgentState::InFlight)];
assert!(!stop_enabled(None, &bs));
}
#[test]
fn stop_disabled_when_selection_not_in_agents() {
let bs = vec![branch("foo", AgentState::InFlight)];
assert!(!stop_enabled(Some("bar"), &bs));
}
#[test]
fn stop_disabled_when_selected_agent_stopped() {
let bs = vec![branch("foo", AgentState::Stopped)];
assert!(!stop_enabled(Some("foo"), &bs));
}
#[test]
fn stop_disabled_when_selected_agent_quiescent() {
let bs = vec![branch("foo", AgentState::Quiescent)];
assert!(!stop_enabled(Some("foo"), &bs));
}
#[test]
fn stop_enabled_when_selection_is_in_flight() {
let bs = vec![branch("foo", AgentState::InFlight)];
assert!(stop_enabled(Some("foo"), &bs));
}
#[test]
fn stop_enabled_when_selection_is_live() {
let bs = vec![branch("foo", AgentState::Live)];
assert!(stop_enabled(Some("foo"), &bs));
}
#[test]
fn stop_disabled_when_agents_empty() {
let bs: Vec<Agent> = vec![];
assert!(!stop_enabled(Some("foo"), &bs));
}
#[test]
fn stop_picks_correct_agent_among_several() {
let bs = vec![
branch("a", AgentState::Stopped),
branch("b", AgentState::InFlight),
branch("c", AgentState::Quiescent),
branch("d", AgentState::Live),
];
assert!(stop_enabled(Some("b"), &bs));
assert!(stop_enabled(Some("d"), &bs));
assert!(!stop_enabled(Some("a"), &bs));
assert!(!stop_enabled(Some("c"), &bs));
}
#[test]
fn nudge_is_offered_exactly_where_stop_is_not() {
let bs = vec![
branch("a", AgentState::Stopped),
branch("b", AgentState::InFlight),
branch("c", AgentState::Quiescent),
branch("d", AgentState::Live),
];
for id in ["a", "b", "c", "d"] {
assert_ne!(
nudge_enabled(Some(id), &bs),
stop_enabled(Some(id), &bs),
"{id} is offered both or neither"
);
}
assert!(
nudge_enabled(Some("a"), &bs),
"a stopped turn re-dispatches"
);
assert!(nudge_enabled(Some("c"), &bs), "a quiescent one continues");
assert!(!nudge_enabled(None, &bs), "no selection");
assert!(!nudge_enabled(Some("zz"), &bs), "absent id");
assert!(!nudge_enabled(Some("a"), &[]), "no agents at all");
}
#[test]
fn a_truncated_turn_is_not_nudgeable() {
let mut cut_off = branch("a", AgentState::Stopped);
cut_off.truncated = true;
let mut settled_at_rest = branch("b", AgentState::Quiescent);
settled_at_rest.truncated = true;
let bs = vec![cut_off, settled_at_rest, branch("c", AgentState::Stopped)];
assert!(!nudge_enabled(Some("a"), &bs), "stopped and cut off");
assert!(!nudge_enabled(Some("b"), &bs), "quiescent and cut off");
assert!(
nudge_enabled(Some("c"), &bs),
"an ordinary resting conversation is unaffected"
);
assert!(!stop_enabled(Some("a"), &bs));
}
#[test]
fn stop_children_offered_only_with_a_descendant() {
let bs = vec![
branch("root-x", AgentState::Live),
branch("root-x-c1", AgentState::Stopped),
branch("root-y", AgentState::Live),
];
assert!(stop_children_offered("root-x", &bs), "has a child");
assert!(!stop_children_offered("root-y", &bs), "leaf agent");
let bs2 = vec![
branch("root-x", AgentState::Live),
branch("root-xx", AgentState::Live),
];
assert!(!stop_children_offered("root-x", &bs2));
}