#![allow(
clippy::print_stdout,
clippy::expect_used,
unused_crate_dependencies,
reason = "demo binary"
)]
use std::sync::Arc;
use machi::{
AgentBuilder, ChatStateHandle, FilePersistence, MockSampler, NoopMetrics, Session, TurnInput,
TurnOptions,
};
use tempfile::tempdir;
#[tokio::main]
async fn main() {
let dir = tempdir().expect("tmp");
let store = FilePersistence::for_session(dir.path(), "demo_sess");
println!("checkpoint={}", store.path().display());
let sampler = Arc::new(MockSampler::new());
sampler.push_text("first-turn");
sampler.push_text("second-turn");
let agent = AgentBuilder::named("assistant")
.instructions("Be brief.")
.model("mock")
.build()
.expect("agent");
let mut session = Session::new();
let (h1, o1) = session
.open_checkpointed_turn(
&agent,
sampler.as_ref(),
&store,
TurnInput::Text("hi".into()),
TurnOptions::default(),
&NoopMetrics,
)
.await
.expect("turn1");
println!("turn1={}", o1.output_text);
assert_eq!(o1.output_text, "first-turn", "first checkpointed turn");
let n1 = h1.messages().await.len();
h1.shutdown().await;
assert!(store.exists(), "checkpoint file must exist after turn1");
let h2 = ChatStateHandle::open_or_new(&store).await.expect("reload");
let n2 = h2.messages().await.len();
assert_eq!(n1, n2, "reload must restore message history");
println!("reloaded_messages={n2}");
let o2 = session
.run_turn_on_handle_checkpointed(
&agent,
sampler.as_ref(),
&h2,
TurnInput::Text("again".into()),
TurnOptions::default(),
&NoopMetrics,
Some(&store),
)
.await
.expect("turn2");
println!("turn2={}", o2.output_text);
assert_eq!(o2.output_text, "second-turn", "second turn after resume");
assert!(
h2.messages().await.len() > n2,
"history must grow after second turn"
);
h2.shutdown().await;
println!("session_resume_ok=true");
}