huskies: merge 650_bug_watchdog_turns_used_and_budget_used_usd_accumulate_across_all_sessions_restart_counts_against_limits_from_prior_runs
This commit is contained in:
@@ -290,10 +290,10 @@ pub(super) fn tool_get_agent_remaining_turns_and_budget(
|
||||
let max_turns = agent_config.and_then(|a| a.max_turns);
|
||||
let max_budget_usd = agent_config.and_then(|a| a.max_budget_usd);
|
||||
|
||||
// Count turns by reading log files and counting assistant events.
|
||||
// ── Cumulative counters (all sessions) ─────────────────────────────
|
||||
let log_files =
|
||||
crate::agent_log::list_story_log_files(&project_root, story_id, Some(agent_name));
|
||||
let mut turns_used: u64 = 0;
|
||||
let mut cumulative_turns: u64 = 0;
|
||||
for path in &log_files {
|
||||
if let Ok(entries) = crate::agent_log::read_log(path) {
|
||||
for entry in &entries {
|
||||
@@ -301,15 +301,13 @@ pub(super) fn tool_get_agent_remaining_turns_and_budget(
|
||||
&& let Some(data) = entry.event.get("data")
|
||||
&& data.get("type").and_then(|v| v.as_str()) == Some("assistant")
|
||||
{
|
||||
turns_used += 1;
|
||||
cumulative_turns += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Compute budget from log-based per-message estimates (works for running
|
||||
// agents) and completed-session records from token_usage.jsonl.
|
||||
let log_cost = crate::agents::pool::auto_assign::watchdog::compute_budget_from_logs(
|
||||
let cumulative_log_cost = crate::agents::pool::auto_assign::watchdog::compute_budget_from_logs(
|
||||
&project_root,
|
||||
story_id,
|
||||
agent_name,
|
||||
@@ -320,19 +318,43 @@ pub(super) fn tool_get_agent_remaining_turns_and_budget(
|
||||
.filter(|r| r.story_id == story_id && r.agent_name == agent_name)
|
||||
.map(|r| r.usage.total_cost_usd)
|
||||
.sum();
|
||||
let budget_used_usd: f64 = log_cost.max(record_cost);
|
||||
let cumulative_budget: f64 = cumulative_log_cost.max(record_cost);
|
||||
|
||||
let remaining_turns = max_turns.map(|max| (max as i64) - (turns_used as i64));
|
||||
let remaining_budget_usd = max_budget_usd.map(|max| max - budget_used_usd);
|
||||
// ── Per-session counters (current session only — enforcement basis) ──
|
||||
use crate::agents::pool::auto_assign::watchdog::{
|
||||
compute_budget_from_single_log, count_turns_in_log, resolve_session_log,
|
||||
};
|
||||
let session_log = resolve_session_log(
|
||||
&project_root,
|
||||
story_id,
|
||||
agent_name,
|
||||
&agent_info.log_session_id,
|
||||
);
|
||||
let session_turns: u64 = session_log
|
||||
.as_ref()
|
||||
.map(|p| count_turns_in_log(p))
|
||||
.unwrap_or(0);
|
||||
let session_budget: f64 = session_log
|
||||
.as_ref()
|
||||
.map(|p| compute_budget_from_single_log(p))
|
||||
.unwrap_or(0.0);
|
||||
|
||||
let remaining_turns = max_turns.map(|max| (max as i64) - (session_turns as i64));
|
||||
let remaining_budget_usd = max_budget_usd.map(|max| max - session_budget);
|
||||
|
||||
serde_json::to_string_pretty(&json!({
|
||||
"story_id": story_id,
|
||||
"agent_name": agent_name,
|
||||
"status": agent_info.status.to_string(),
|
||||
"turns_used": turns_used,
|
||||
// Per-session values (watchdog enforcement basis):
|
||||
"turns_used": session_turns,
|
||||
"budget_used_usd": session_budget,
|
||||
// Cumulative values (all sessions, useful for cost analysis):
|
||||
"cumulative_turns_used": cumulative_turns,
|
||||
"cumulative_budget_used_usd": cumulative_budget,
|
||||
// Limits and remaining (computed from per-session values):
|
||||
"max_turns": max_turns,
|
||||
"remaining_turns": remaining_turns,
|
||||
"budget_used_usd": budget_used_usd,
|
||||
"max_budget_usd": max_budget_usd,
|
||||
"remaining_budget_usd": remaining_budget_usd,
|
||||
}))
|
||||
@@ -1038,9 +1060,13 @@ stage = "coder"
|
||||
assert_eq!(parsed["story_id"], "42_story");
|
||||
assert_eq!(parsed["agent_name"], "coder-1");
|
||||
assert_eq!(parsed["status"], "running");
|
||||
// Per-session values (enforcement basis).
|
||||
assert!(parsed.get("turns_used").is_some());
|
||||
assert!(parsed.get("budget_used_usd").is_some());
|
||||
// max_turns and max_budget_usd may be null if not configured
|
||||
// Cumulative values (all sessions, for cost analysis).
|
||||
assert!(parsed.get("cumulative_turns_used").is_some());
|
||||
assert!(parsed.get("cumulative_budget_used_usd").is_some());
|
||||
// Limits and remaining.
|
||||
assert!(parsed.get("max_turns").is_some());
|
||||
assert!(parsed.get("remaining_turns").is_some());
|
||||
assert!(parsed.get("max_budget_usd").is_some());
|
||||
|
||||
Reference in New Issue
Block a user