fix(#1982): migrate-stats tolerates pre-session_id dbs + skips failed agents
This commit is contained in:
parent
a94fb9955f
commit
c68706e899
1 changed files with 32 additions and 7 deletions
|
|
@ -86,14 +86,23 @@ pub async fn run(
|
|||
let client = reqwest::Client::new();
|
||||
let mut total_points = 0usize;
|
||||
let mut hit_agents = 0usize;
|
||||
let mut failed = 0usize;
|
||||
for agent in &agents {
|
||||
let db = Coordinator::agent_harness_dir(agent).join("hyperhive-turn-stats.sqlite");
|
||||
if !db.exists() {
|
||||
continue;
|
||||
}
|
||||
let id_prefix = format!("{swarm}-{hive}-{agent}");
|
||||
let pts = collect_agent_points(&db, &id_prefix)
|
||||
.with_context(|| format!("read turn_stats for {agent}"))?;
|
||||
// Skip + warn on a bad db (e.g. an old schema) rather than aborting
|
||||
// the whole migration on the first failed agent.
|
||||
let pts = match collect_agent_points(&db, &id_prefix) {
|
||||
Ok(p) => p,
|
||||
Err(e) => {
|
||||
eprintln!("{agent}: skipped — {e:#}");
|
||||
failed += 1;
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let n = pts.token.len() + pts.session.len();
|
||||
if n == 0 {
|
||||
println!("{agent}: no token rows, skipping");
|
||||
|
|
@ -123,11 +132,16 @@ pub async fn run(
|
|||
}
|
||||
}
|
||||
println!(
|
||||
"migrate-stats: {hit_agents} agent(s) with stats, {total_points} datapoints {}",
|
||||
"migrate-stats: {hit_agents} agent(s) with stats, {total_points} datapoints {}{}",
|
||||
if dry_run {
|
||||
"(dry-run, nothing sent)"
|
||||
} else {
|
||||
"sent"
|
||||
},
|
||||
if failed > 0 {
|
||||
format!(" ({failed} agent(s) skipped on error)")
|
||||
} else {
|
||||
String::new()
|
||||
}
|
||||
);
|
||||
Ok(())
|
||||
|
|
@ -139,12 +153,23 @@ pub async fn run(
|
|||
fn collect_agent_points(db: &Path, id_prefix: &str) -> Result<AgentPoints> {
|
||||
let conn = Connection::open_with_flags(db, rusqlite::OpenFlags::SQLITE_OPEN_READ_ONLY)
|
||||
.context("open stats db read-only")?;
|
||||
// session_id last so the token column indices (3..=6) stay stable.
|
||||
let mut stmt = conn.prepare(
|
||||
// Older dbs predate the `session_id` migration. Probe for the column and
|
||||
// fall back to a `NULL AS session_id` placeholder so the row shape (col 7)
|
||||
// is identical either way (those rows get a synthetic session.id below).
|
||||
// session_id is selected last so the token column indices stay fixed.
|
||||
let has_session = conn
|
||||
.prepare("SELECT session_id FROM turn_stats LIMIT 1")
|
||||
.is_ok();
|
||||
let sql = if has_session {
|
||||
"SELECT started_at, ended_at, model, input_tokens, output_tokens, \
|
||||
cache_read_input_tokens, cache_creation_input_tokens, session_id \
|
||||
FROM turn_stats ORDER BY ended_at ASC",
|
||||
)?;
|
||||
FROM turn_stats ORDER BY ended_at ASC"
|
||||
} else {
|
||||
"SELECT started_at, ended_at, model, input_tokens, output_tokens, \
|
||||
cache_read_input_tokens, cache_creation_input_tokens, NULL AS session_id \
|
||||
FROM turn_stats ORDER BY ended_at ASC"
|
||||
};
|
||||
let mut stmt = conn.prepare(sql)?;
|
||||
let rows = stmt.query_map([], |r| {
|
||||
Ok((
|
||||
r.get::<_, i64>(0)?,
|
||||
|
|
|
|||
Loading…
Reference in a new issue