use super::super::super::super::types::App;
use super::super::super::super::types::CompactOutcome;
use super::super::super::tests_support::idle_app;
use super::support::five_turns;
use crate::interactive::auto_compact::{auto_failure_message, auto_success_message};
use crate::interactive::session_compact::{apply, plan};
use crate::interactive::session_state::SessionState;
#[test]
fn polling_an_automatic_success_applies_summary_plus_verbatim_tail() {
let (mut app, mut state) = five_turns_app();
let history = state.provider_history();
let planned = plan(&state.turns, &history).expect("long history plans");
let summary = "older turns: q0 q1 q2 discussed orders.";
let (tx, rx) = std::sync::mpsc::channel();
app.compact_task = Some(rx);
tx.send(CompactOutcome {
message: crate::interactive::session_compact::success_message(
planned.compacted_turns,
summary,
),
failed: false,
usage: None,
automatic: true,
summary: Some(summary.into()),
compacted_turns: planned.compacted_turns,
})
.expect("the worker's outcome sends");
crate::interactive::compact_task::poll(&mut app, &mut state);
assert!(app.compact_task.is_none(), "a polled worker is cleared");
let replayed = state.provider_history();
assert!(
replayed[0].content.contains(summary),
"the summary replays first: {replayed:?}"
);
assert!(
replayed
.iter()
.any(|message| message.content == "a4" && message.role == "assistant"),
"the newest answer survives verbatim: {replayed:?}"
);
assert!(
app.transcript
.blocks()
.iter()
.any(|block| block.text == auto_success_message(planned.compacted_turns, summary)),
"the transcript states the automatic origin with the manual message"
);
assert!(
!state.auto_compact_failed,
"a successful automatic compaction clears the no-retry flag"
);
}
fn five_turns_app() -> (App, SessionState) {
(idle_app(), five_turns())
}
#[test]
fn polling_an_automatic_failure_sets_the_flag_and_states_the_policy() {
let (mut app, mut state) = five_turns_app();
let before = state.provider_history();
let (tx, rx) = std::sync::mpsc::channel();
app.compact_task = Some(rx);
tx.send(CompactOutcome {
message: "the summariser timed out".into(),
failed: true,
usage: None,
automatic: true,
summary: None,
compacted_turns: 0,
})
.expect("the worker's outcome sends");
crate::interactive::compact_task::poll(&mut app, &mut state);
assert!(
state.auto_compact_failed,
"a failed automatic compaction sets the session-scoped flag"
);
assert_eq!(
state.provider_history(),
before,
"a failed automatic compaction leaves the conversation exactly as it was"
);
assert!(
app.transcript
.blocks()
.iter()
.any(|block| block.text == auto_failure_message("the summariser timed out")),
"the transcript states the origin and the no-retry policy"
);
}
#[test]
fn automatic_and_manual_paths_produce_byte_identical_results() {
let history_of = |state: &SessionState| state.provider_history();
let mut manual_state = five_turns();
let mut auto_state = five_turns();
let manual_history = history_of(&manual_state);
let auto_history = history_of(&auto_state);
let manual_plan = plan(&manual_state.turns, &manual_history).expect("plans");
let auto_plan = plan(&auto_state.turns, &auto_history).expect("plans");
assert_eq!(
manual_plan.compacted_turns, auto_plan.compacted_turns,
"the same history plans the same turns"
);
assert_eq!(manual_plan.pinned, auto_plan.pinned);
let summary = "older turns: q0 q1 q2 discussed orders.";
apply(&mut manual_state, &manual_plan, summary).expect("manual applies");
apply(&mut auto_state, &auto_plan, summary).expect("automatic applies");
let manual_message =
crate::interactive::session_compact::success_message(manual_plan.compacted_turns, summary);
assert_eq!(
auto_success_message(auto_plan.compacted_turns, summary),
format!("Automatic compaction: {manual_message}"),
"the automatic presentation is the manual message with its origin stated"
);
assert_eq!(
manual_state.provider_history(),
auto_state.provider_history(),
"the two triggers leave byte-identical conversations"
);
assert_eq!(
manual_state.compaction_summary, auto_state.compaction_summary,
"the two triggers store byte-identical summaries"
);
}