Compare commits

...

1 Commits

Author SHA1 Message Date
4eec7491a7 fix(cron): include token usage in cron job output (#490)
Some checks failed
Forge CI / smoke-and-build (pull_request) Failing after 1m7s
Cron job run_job() ran the agent but never extracted token
counts from the result dict. Usage data was accumulated by
the agent during the conversation, then discarded on return.

Fix: Add _format_token_usage() helper that extracts
input_tokens, output_tokens, total_tokens, api_calls, and
estimated_cost_usd from the agent result. Include a Token
Usage section in all three output templates (success,
script failure, sync fallback).

Closes #490
2026-04-14 11:39:37 +00:00

View File

@@ -643,6 +643,27 @@ def _build_job_prompt(job: dict) -> str:
return "\n".join(parts)
def _format_token_usage(result: dict) -> str:
"""Extract token usage from agent result dict for cron output display."""
inp = result.get("input_tokens", 0) or 0
out = result.get("output_tokens", 0) or 0
total = result.get("total_tokens", 0) or 0
cost = result.get("estimated_cost_usd")
calls = result.get("api_calls", 0) or 0
if inp == 0 and out == 0 and total == 0:
return "" # No usage data available
lines = [f"- Input tokens: {inp:,}"]
lines.append(f"- Output tokens: {out:,}")
lines.append(f"- Total tokens: {total:,}")
lines.append(f"- API calls: {calls}")
if cost is not None:
lines.append(f"- Estimated cost: ${cost:.4f}")
return "\n".join(lines)
def run_job(job: dict) -> tuple[bool, str, str, Optional[str]]:
"""
Execute a single cron job.
@@ -877,6 +898,8 @@ def run_job(job: dict) -> tuple[bool, str, str, Optional[str]]:
result = agent.run_conversation(prompt)
final_response = result.get("final_response", "") or ""
logged_response = final_response if final_response else "(No response generated)"
_token_usage = _format_token_usage(result)
_token_section = f"\n## Token Usage\n\n{_token_usage}\n" if _token_usage else ""
output = f"""# Cron Job: {job_name}
**Job ID:** {job_id}
@@ -890,7 +913,7 @@ def run_job(job: dict) -> tuple[bool, str, str, Optional[str]]:
## Response
{logged_response}
"""
{_token_section}"""
logger.info("Job '%s' completed (sync fallback)", job_name)
return True, output, final_response, None
@@ -969,6 +992,8 @@ def run_job(job: dict) -> tuple[bool, str, str, Optional[str]]:
"Job '%s': agent reported script failure — %s",
job_name, _script_failed_reason,
)
_token_usage = _format_token_usage(result)
_token_section = f"\n## Token Usage\n\n{_token_usage}\n" if _token_usage else ""
output = f"""# Cron Job: {job_name} (SCRIPT FAILED)
**Job ID:** {job_id}
@@ -982,9 +1007,11 @@ def run_job(job: dict) -> tuple[bool, str, str, Optional[str]]:
## Response
{logged_response}
"""
{_token_section}"""
return False, output, final_response, _script_failed_reason
_token_usage = _format_token_usage(result)
_token_section = f"\n## Token Usage\n\n{_token_usage}\n" if _token_usage else ""
output = f"""# Cron Job: {job_name}
**Job ID:** {job_id}
@@ -998,7 +1025,7 @@ def run_job(job: dict) -> tuple[bool, str, str, Optional[str]]:
## Response
{logged_response}
"""
{_token_section}"""
logger.info("Job '%s' completed successfully", job_name)
return True, output, final_response, None