Skip to content

feat(cli): add agentplay stats - #71

Merged
adityajha2005 merged 1 commit into
Entelligence-AI:mainfrom
coderwithsense:feat/63-stats-command
Nov 4, 2026
Merged

adityajha2005 merged 1 commit into
Entelligence-AI:mainfrom
coderwithsense:feat/63-stats-command

Conversation

@coderwithsense

Copy link
Copy Markdown
Contributor

Closes #63.

agentplay stats sums the sessions list would show, one row per agent, plus a total. It reads only ~/.agentplay/index.json, so it needs no map files and makes no network call.

$ agentplay stats --since 7d
             sessions    cost   time  calls  errors
claude-code        41  $38.20  11.4h  3,912     118
codex              12   $6.75   3.1h    804      22
cursor              5     n/a   0.9h    211       4
total              58  $44.95  15.4h  4,927     144

Shared filtering, not a copy: the --agents / --since loop moves out of cmd_list into _selected_rows, and the two flag definitions into _filter_flags, so a window selects the same sessions in both commands and cannot drift. Subagent and helper rows stay excluded, so work already counted in a parent map is not counted twice. cmd_list is unchanged behaviourally; the mtime fallback for imported maps and discovery's zero sentinel is now _changed_since.

Cost is None, shown as n/a and serialised as null, when no session in a row had a priced request. Cursor records no usable token counts, and a $0.00 there reads as free rather than unknown. This is the same distinction facts.hasCost already draws, computed from the same costUsd field rather than a second definition of "unpriced".

Rows order by spend descending, then session count, then name, so an agent with no cost data at all sorts last. Column widths are computed from the cells, so a long agent name (antigravity-cli) or a six-figure call count still lines up. The total row is bolded after padding, so the escape codes cannot shift a column, and NO_COLOR drops them.

--json emits {"agents": [...], "total": {...}} with pricedSessions alongside each costUsd, and still emits a zeroed report when nothing matches, so a script gets the same shape either way.

Tests (11, in test_cli_output.py): per-agent and overall totals, subagent/helper exclusion, both filters asserted to select the same sessions as list, the n/a case and its note, both empty messages, empty --json, and rejected filters.

make check passes: ruff, tsc, 1453 python tests, 354 viewer tests, the hygiene guard.

Summary

Test plan

  • make check passes
  • No prompt text, model output, tool input/output, file contents or command arguments can reach a map, a log line or the viewer (redaction contract)
  • No new network calls or Python runtime dependencies

Closes Entelligence-AI#63.

`agentplay stats` sums the sessions `list` would show, one row per agent,
plus a total. It reads only `~/.agentplay/index.json`, so it needs no map
files and makes no network call.

    $ agentplay stats --since 7d
                 sessions    cost   time  calls  errors
    claude-code        41  $38.20  11.4h  3,912     118
    codex              12   $6.75   3.1h    804      22
    cursor              5     n/a   0.9h    211       4
    total              58  $44.95  15.4h  4,927     144

Shared filtering, not a copy: the `--agents` / `--since` loop moves out of
`cmd_list` into `_selected_rows`, and the two flag definitions into
`_filter_flags`, so a window selects the same sessions in both commands
and cannot drift. Subagent and helper rows stay excluded, so work already
counted in a parent map is not counted twice. `cmd_list` is unchanged
behaviourally; the mtime fallback for imported maps and discovery's zero
sentinel is now `_changed_since`.

Cost is None, shown as `n/a` and serialised as `null`, when no session in
a row had a priced request. Cursor records no usable token counts, and a
$0.00 there reads as free rather than unknown. This is the same
distinction `facts.hasCost` already draws, computed from the same
`costUsd` field rather than a second definition of "unpriced".

Rows order by spend descending, then session count, then name, so an
agent with no cost data at all sorts last. Column widths are computed
from the cells, so a long agent name (`antigravity-cli`) or a six-figure
call count still lines up. The total row is bolded after padding, so the
escape codes cannot shift a column, and `NO_COLOR` drops them.

`--json` emits `{"agents": [...], "total": {...}}` with `pricedSessions`
alongside each `costUsd`, and still emits a zeroed report when nothing
matches, so a script gets the same shape either way.

Tests (11, in test_cli_output.py): per-agent and overall totals,
subagent/helper exclusion, both filters asserted to select the same
sessions as `list`, the n/a case and its note, both empty messages,
empty `--json`, and rejected filters.

make check passes: ruff, tsc, 1453 python tests, 354 viewer tests, the
hygiene guard.

@entelligence-ai-pr-reviews entelligence-ai-pr-reviews Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Entelligence: code quality 5/5 — Excellent.

@entelligence-ai-pr-reviews

Copy link
Copy Markdown

EntelligenceAI PR Summary

Adds agentplay stats to report per-agent and total session counts, estimated cost, duration, calls, and errors using only the local index. It shares list’s agent and date filters, excludes subagent/helper rows, and supports both table and JSON output, including null costs for unpriced agents.

flowchart TD
    classDef newBehavior fill:#dcfce7,stroke:#16a34a,color:#14532d;
    A["agentplay stats"] --> B["Read local index"]
    B --> C["Shared session filters"]
    C --> D["Group rows by agent"]
    D --> E["Sum metrics and totals"]
    E --> F["Table or JSON output"]
    G["agentplay list"] --> C
    class A,C,D,E,F newBehavior;
Loading

🟢 Green = new or changed in this PR


Review Scorecard

Dimension Rating Basis
Code Quality ●●●●● 5/5 — Excellent no critical/significant findings — rated Excellent
Blast Radius Low changed symbols are referenced only within their own file(s); no high-impact surface touched, 2 file(s) / ~174 line(s) changed (size only — not a blast signal)
Merge Confidence ●●●●● 5/5 — Safe to Merge equals code quality; blast radius is shown for context only
Test Coverage — unavailable dependencies failed to install
Security Scan No findings on changed lines SonarQube · Semgrep · TruffleHog on 3 changed files

Safe to merge with a low blast radius; code quality rated Excellent (5/5): the review found nothing to flag.

Key Findings:

  • No critical or significant issues found
Evaluated against
  • 3/3 changed files reviewed
  • criteria: correctness, security & access control, robustness & error handling, concurrency & data integrity, repo conventions / steering docs
  • steering docs: none found in repo
  • PR checks: unit tests (unavailable) · security scan (SonarQube, Semgrep, TruffleHog on 3 changed files)

@entelligence-ai-pr-reviews

Copy link
Copy Markdown

Walkthrough

Adds agentplay stats to aggregate session metrics by agent, with terminal and JSON output and shared --agents/--since filtering. Reuses session selection logic in list, documents the command and filtering behavior, and adds tests for aggregation, output formats, filtering, and edge cases.

Changes

Files

  • python/src/agentplay/cli.py
  • python/tests/test_cli_output.py

Added the stats command with per-agent and total session, cost, duration, call, and error metrics. Supports aligned terminal output, JSON, and shared filters with list; tests cover aggregation, sorting, output, cost notes, empty results, and invalid filters.

Files

  • README.md

Documented agentplay stats, its local-index behavior, cost availability, output fields, and supported flags. Clarified how --since selects sessions for both list and stats.

@adityajha2005
adityajha2005 merged commit da0c001 into Entelligence-AI:main Nov 4, 2026
18 checks passed
@adityajha2005

Copy link
Copy Markdown
Contributor

LGTM, thanks @coderwithsense for the contribution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

agentplay stats: cost, time and errors per agent over a window

2 participants