use super::*;
fn now_utc() -> String {
let d = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap_or_default();
let secs = d.as_secs();
let nanos = d.subsec_nanos();
let (days, rem) = (secs / 86_400, secs % 86_400);
let (h, rem) = (rem / 3_600, rem % 3_600);
let (m, s) = (rem / 60, rem % 60);
let (mut y, mut mo, mut day) = (1970i64, 1u32, 1u32);
let mut remaining = days as i64;
loop {
let yd = if y % 4 == 0 && (y % 100 != 0 || y % 400 == 0) {
366
} else {
365
};
if remaining < yd {
break;
}
remaining -= yd;
y += 1;
}
let leap = y % 4 == 0 && (y % 100 != 0 || y % 400 == 0);
let mdays = [
31,
if leap { 29 } else { 28 },
31,
30,
31,
30,
31,
31,
30,
31,
30,
31,
];
for md in mdays {
if remaining < md as i64 {
break;
}
remaining -= md as i64;
mo += 1;
}
day += remaining as u32;
format!(
"{:04}-{:02}-{:02} {:02}:{:02}:{:02}.{:09}",
y, mo, day, h, m, s, nanos
)
}
pub fn new_snapshot(
session_id: String,
cwd: PathBuf,
store_path: PathBuf,
model: String,
base_url: String,
backend: BackendKind,
reasoning_effort: Option<ReasoningEffort>,
sandbox_spec: Option<SandboxSpec>,
messages: Vec<Message>,
) -> SessionSnapshot {
tracing::debug!(
session_id = %session_id,
cwd = %cwd.display(),
store_path = %store_path.display(),
model = %model,
backend = ?backend,
message_count = messages.len(),
sandboxed = sandbox_spec.is_some(),
"constructing new session snapshot"
);
let now = now_utc();
SessionSnapshot {
session_id,
cwd,
store_path,
model,
base_url,
backend,
reasoning_effort,
sandbox_spec,
messages,
last_response_duration_ms: None,
previous_response_duration_ms: None,
response_durations_ms: None,
timeline_json: None,
created_at: now.clone(),
updated_at: now,
}
}
pub fn refresh_snapshot(
snapshot: &SessionSnapshot,
messages: Vec<Message>,
last_response_duration_ms: Option<u64>,
previous_response_duration_ms: Option<u64>,
response_durations_ms: Option<Vec<Option<u64>>>,
timeline_json: Option<String>,
) -> SessionSnapshot {
tracing::debug!(
session_id = %snapshot.session_id,
cwd = %snapshot.cwd.display(),
store_path = %snapshot.store_path.display(),
model = %snapshot.model,
backend = ?snapshot.backend,
message_count = messages.len(),
sandboxed = snapshot.sandbox_spec.is_some(),
"refreshing session snapshot"
);
SessionSnapshot {
session_id: snapshot.session_id.clone(),
cwd: snapshot.cwd.clone(),
store_path: snapshot.store_path.clone(),
model: snapshot.model.clone(),
base_url: snapshot.base_url.clone(),
backend: snapshot.backend,
reasoning_effort: snapshot.reasoning_effort.clone(),
sandbox_spec: snapshot.sandbox_spec.clone(),
messages,
last_response_duration_ms,
previous_response_duration_ms,
response_durations_ms,
timeline_json,
created_at: snapshot.created_at.clone(),
updated_at: now_utc(),
}
}