use super::*;
const LAST_EXCERPT_CHARS: usize = 400;
#[derive(Debug, Clone)]
pub(crate) struct LastMsg {
pub(crate) ts_utc: Option<String>,
pub(crate) text: String,
pub(crate) truncated: bool,
}
#[derive(Debug, Clone, Default)]
pub(crate) struct LastMessages {
pub(crate) user: Option<LastMsg>,
pub(crate) agent: Option<LastMsg>,
}
fn excerpt(ts: Option<String>, text: &str) -> LastMsg {
let norm = crate::model::normalize_line(text);
let truncated = norm.chars().count() > LAST_EXCERPT_CHARS;
LastMsg {
ts_utc: ts,
text: crate::text::truncate_excerpt(&norm, LAST_EXCERPT_CHARS),
truncated,
}
}
pub(crate) fn last_messages(path: &Path) -> Result<LastMessages> {
let mut out = LastMessages::default();
crate::parse::tail_records_prefiltered(path, crate::parse::line_has_role_marker, 0, |rec| {
if out.agent.is_none() {
if let Some(t) = rec.agent_text() {
out.agent = Some(excerpt(rec.timestamp.clone(), &t));
}
}
if out.user.is_none() {
let text = rec.automation_label().or_else(|| {
rec.is_genuine_user()
.then(|| rec.reconstructed_user_text(None))
.flatten()
});
if let Some(t) = text {
out.user = Some(excerpt(rec.timestamp.clone(), &t));
}
}
out.user.is_none() || out.agent.is_none()
})?;
Ok(out)
}