Usage Reporting

Zero-config local token and cost reporting for PraisonAI sessions

See how many tokens and dollars your agents have spent โ€” locally, with one command, no external service.

bash
praisonai usage
Diagram

praisonai usage

๐Ÿ’พ Local Session Store

๐Ÿ“… Filter by Days

๐Ÿ“Š Group by Day / Model / Project

๐Ÿ“‹ Table

๐Ÿงพ JSON

Quick Start

  1. See your spend
    bash
    praisonai usage
  2. Change the grouping
    bash
    praisonai usage --by model
    praisonai usage --by project
  3. Narrow the window or script it
    bash
    praisonai usage --days 7
    praisonai usage --json
  4. See per-tool reliability
    bash
    praisonai usage --by tool

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


How It Works

Diagram
Global Default StoreCurrent-project Storepraisonai CLIUserGlobal Default StoreCurrent-project Storepraisonai CLIUserpraisonai usagelist_sessions()sessions (tokens, cost)list_sessions()sessions (tokens, cost)de-dup by session_id, filter, group, sumTable or JSON

The command reads the already-persisted total_tokens and cost fields on each session record in the local session store, filters by --days, groups by --by, and renders a table or JSON. No new data is written, no network calls, no configuration.

BehaviourDetail
Two stores readWithout --project, both the current-project store and the global default store are read, tagged current / global.
De-duplicationSessions shared across both stores are collapsed by session_id.
Bounded scanUp to 100,000 sessions per store are read.
Cost sourceThe persisted cost uses the same ModelPricing table as praisonai tracker, so numbers match.

Choosing --by

Pick the dimension that answers your question.

Diagram

How much this week?

Which model costs most?

Which workspace burns budget?

Which tool is flaky or slow?

What do you want to know?

–by day

–by model

–by project

–by tool

day sorts chronologically; model and project sort by highest token count first. tool sorts by most-called first, so your busiest (or busiest-failing) tool rises to the top.


Options

OptionShortTypeDefaultValuesDescription
--days-dint30any int; 0 = allOnly include sessions updated in the last N days.
--by-bstrdayday \model \project \toolGroup rows by dimension. Invalid values exit 1.
--project-pstrNoneany project idRestrict to a specific project’s session store.
--jsonโ€”boolFalseflagEmit machine-readable JSON instead of a table.

An invalid --by value prints --by must be one of: day, model, project, tool and exits with code 1.


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.


Output Formats

Table

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Day        โ”‚ Tokens โ”‚ Cost    โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ 2026-07-19 โ”‚ 12,345 โ”‚ $0.1234 โ”‚
โ”‚ Total      โ”‚ 12,345 โ”‚ $0.1234 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Zero values render as -, and a final Total row sums the report.

JSON

json
{
  "by": "day",
  "days": 30,
  "project": null,
  "rows": [{"key": "2026-07-19", "total_tokens": 12345, "cost": 0.1234}],
  "total_tokens": 12345,
  "cost": 0.1234,
  "errors": []
}

JSON (–by tool)

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.


Empty Stores and Warnings

Empty and broken reports are always distinguishable.

  • No sessions yet? The command prints No usage recorded yet and exits 0.
  • A damaged or unreadable store surfaces as Usage may be incomplete: ... in table mode, or in the top-level errors array in JSON mode.

Best Practices

Alert on spend in CI

Wire praisonai usage --days 7 --json into a cron or CI job and alert if cost exceeds a threshold.

Find your most expensive model

Run praisonai usage --by model weekly to see which model your agents actually spend the most on.

Compare workspaces

Use praisonai usage --project <id> inside a workspace and praisonai usage --by project in the default shell to compare workloads.

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.

Script with jq

--json is stable for scripting โ€” pipe into jq or a small dashboard rather than parsing the table.


Related