Usage

See how many tokens and how much money your agents are spending — from your local machine.

See exactly where your tokens (and dollars) are going — no dashboard, no API key, no config.

praisonai usage reads the same local session store that praisonai session list uses and rolls it up per day, per model, or per project — or per tool, to show reliability and latency.

Diagram

Local usage report

day

model

project

💾 Session Store

📖 Read totals

📊 Group by

📅 Day

🤖 Model

📁 Project

Quick Start

  1. Run the default report

    Show the last 30 days grouped by day:

    bash
    praisonai usage
    Usage
    ┏━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━┓
    ┃ Day        ┃  Tokens ┃    Cost ┃
    ┡━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━┩
    │ 2026-07-15 │   4,320 │ $0.0180 │
    │ 2026-07-18 │  12,500 │ $0.0512 │
    │ Total      │  16,820 │ $0.0692 │
    └────────────┴─────────┴─────────┘
  2. Group by cost driver

    Find your most expensive model:

    bash
    praisonai usage --by model
  3. See per-tool reliability
    bash
    praisonai usage --by tool

    Reports calls, success rate, average latency, and the last error for each tool used.


Choose Your View

Four groupings answer four different questions.

Diagram

When did I spend?

Which model costs most?

Which project costs most?

Which tool is flaky or slow?

What do you want
to know?

–by day

–by model

–by project

–by tool

tool sorts by most-called first, so your busiest (or busiest-failing) tool rises to the top.


Options

praisonai usage [--days N] [--by day|model|project|tool] [--project ID] [--json]
OptionShortTypeDefaultDescription
--days-dint30Only include sessions updated in the last N days (0 = all time)
--by-bstr"day"Group by day, model, project, or tool
--project-pstr(none)Restrict to a specific project ID
--json—boolFalseEmit machine-readable JSON instead of a table

Per-Tool Reliability

praisonai usage --by tool reports per-tool call counts, success rate, average and last latency, and the last error — read from the local session store, same as every other grouping.

Diagram

praisonai usage –by tool

🪝 AFTER_TOOL hook

📊 Per-tool tally

💾 Session metadata

✅ Tool report

                                 Tool usage
┏━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━┓
┃ Tool       ┃ Calls ┃ Success ┃ Avg ms ┃ Last ms ┃ Last error ┃
┡━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━┩
│ search     │     3 │  66.7%  │   200  │   200   │ timeout    │
│ write_file │     1 │ 100.0%  │     5  │     5   │ -          │
└────────────┴───────┴─────────┴────────┴─────────┴────────────┘
ColumnMeaning
ToolTool name as the runtime saw it
CallsHow many times the tool was invoked
SuccessPercentage of calls that returned without an error
Avg msAverage execution time across all calls
Last msLatency of the most recent call
Last errorLast error message (truncated to 60 chars in the table, 500 in JSON)

Last ms and Last error are picked by when the tool itself last ran, not by when the session was last updated. If no tool calls are recorded, the command prints No tool usage recorded yet.

Python: read the same data with a hook

Prefer Python? The same per-call data is available via the AFTER_TOOL hook — no new API is needed.

python
from praisonaiagents.hooks import add_hook, HookEvent

def on_tool(data):
    print(data.tool_name, data.execution_time_ms, data.tool_error)

add_hook(HookEvent.AFTER_TOOL, on_tool)

The CLI tally reads exactly these three fields.


Common Patterns

Check last week only:

bash
praisonai usage --days 7

Break a single project down by model:

bash
praisonai usage --project my-app --by model

Pipe into jq to flag expensive rows:

bash
praisonai usage --json | jq '.rows[] | select(.cost > 1)'

The JSON output shape:

json
{
  "by": "model",
  "days": 30,
  "project": null,
  "rows": [
    { "key": "gpt-4o",      "total_tokens": 12500, "cost": 0.0512 },
    { "key": "gpt-4o-mini", "total_tokens":  4320, "cost": 0.0180 }
  ],
  "total_tokens": 16820,
  "cost": 0.0692,
  "errors": []
}

The --by tool JSON shape:

json
{
  "by": "tool",
  "days": 30,
  "project": null,
  "rows": [
    {
      "tool": "search",
      "calls": 3,
      "successes": 2,
      "errors": 1,
      "success_rate": 0.6667,
      "avg_ms": 200.0,
      "last_ms": 200.0,
      "last_error": "timeout"
    }
  ],
  "errors": []
}

Tool mode omits the top-level total_tokens / cost fields — it reports outcomes, not spend.

Spot flaky or slow tools:

bash
# Spot flaky tools over the last week
praisonai usage --by tool --days 7

# Find the slowest tool across all history
praisonai usage --by tool --days 0 --json | jq '.rows | sort_by(-.avg_ms) | .[0]'

# Alert on tool failure rate in CI
praisonai usage --by tool --json | jq '.rows[] | select(.success_rate < 0.9)'

How It Works

praisonai usage reads the on-disk session store — the same store surfaced by praisonai session list. No network calls, no configuration, no external observability platform.

Diagram
sequenceDiagram
    participant User
    participant CLI as praisonai CLI
    participant Store as Session store

    User->>CLI: praisonai run "task" (session active)
    CLI->>Store: accumulate token + cost totals
    Note over User: later...
    User->>CLI: praisonai usage --by model
    CLI->>Store: read totals (last N days)
    Store-->>CLI: per-session tokens + cost
    CLI-->>User: grouped table (or --json)

    classDef user fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef cli fill:#8B0000,stroke:#7C90A0,color:#fff
    classDef store fill:#189AB4,stroke:#7C90A0,color:#fff

With no --project, both the current-project store and the global default store are read. Rows keep their originating identity (current or global), and a session that appears in both stores is counted once.

BehaviourWhat happens
--days 0No time filter — includes every session
Empty storePrints No usage recorded yet (no table)
Store read failureReports Usage may be incomplete: ... (or an errors array in --json) instead of returning zero
Invalid --by valueExits with code 1 and prints --by must be one of: day, model, project, tool

Costs come from the existing per-run ModelPricing tracker — usage aggregates what was already recorded, it does not re-price.


Best Practices

Run a quick weekly check-in

Use --days 7 for a fast look at the current week before it grows into a surprise bill.

bash
praisonai usage --days 7
Compare models before switching providers

Group by model to see which model drives your spend, then decide whether a cheaper one fits.

bash
praisonai usage --by model
Alert on runaway spend in CI

Use --json in cron or CI and act on the numbers with jq.

bash
praisonai usage --json | jq '.cost'
Spot flaky or slow tools before users notice

Run praisonai usage --by tool --days 7 as part of your weekly review. Rows are sorted by call count first, so the busiest tool is on top — and the Success column immediately shows which ones are quietly failing. Pipe --json into jq in CI to fail a build when any tool drops below your target success rate.

Remember it counts local spend only

Numbers reflect only what was recorded to the local session store. For team-wide totals across machines, use an observability integration such as Langfuse.


Related