trading_agent.journal.usage_tracker
¶
Counts each desk's model usage today, and keeps Claude's latest subscription limit status, for /usage.
It listens to the model_usage and rate_limit events every backend publishes. Totals are per India day, desk and backend: model calls, prompt tokens, completion tokens and, for Claude, tokens read from the prompt cache and what the same usage would cost on the API. An OpenAI-compatible backend whose prices are set in trading_agent.toml also gets its cost in rupees. When the gateway starts, today's journal is read back, so a restart does not reset the day's totals.
Typical usage example:
tracker = UsageTracker(event_bus, layout, ['main'], backends) task = asyncio.create_task(tracker.run()) text = tracker.summary_text('main')
BackendUsage
dataclass
¶
BackendUsage(calls=0, prompt_tokens=0, completion_tokens=0, cache_read_tokens=0, api_equivalent_cost_usd=0.0, cost_usd=0.0)
One desk's use of one backend on one day.
Attributes:
| Name | Type | Description |
|---|---|---|
calls |
int
|
Model calls; for Claude, turns. |
prompt_tokens |
int
|
Tokens sent. |
completion_tokens |
int
|
Tokens written by the model. |
cache_read_tokens |
int
|
Tokens the server read from its prompt cache, for Claude and DeepSeek. |
api_equivalent_cost_usd |
float
|
What Claude's usage would have cost on the API, in US dollars. |
cost_usd |
float
|
What a paid API, such as DeepSeek's, actually charged, in US dollars. |
UsageTracker
¶
Today's model usage per desk and backend.
Subscribes to the bus at once, so no usage is missed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event_bus
|
EventBus
|
The bus to listen to. |
required |
layout
|
WorkspaceLayout
|
Where the desks' journals are, for the replay at start. |
required |
desk_names
|
Sequence[str]
|
The desks whose journals to replay. |
required |
backends
|
Mapping[str, BackendConfiguration]
|
The backends, for their prices. |
required |
clock
|
Callable[[], datetime] | None
|
Returns the current time; None uses the system clock. |
None
|
Source code in src/trading_agent/journal/usage_tracker.py
run
async
¶
Replays today's journal, then counts new events until cancelled.
Source code in src/trading_agent/journal/usage_tracker.py
replay_today
¶
Counts the usage already in today's journals, from before the tracker started.
Source code in src/trading_agent/journal/usage_tracker.py
record
¶
Counts one event.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
published_event
|
Event
|
The event; only model_usage and rate_limit count. |
required |
Source code in src/trading_agent/journal/usage_tracker.py
today
¶
A desk's usage today, by backend.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
desk_name
|
str
|
The desk. |
required |
Returns:
| Type | Description |
|---|---|
dict[str, BackendUsage]
|
The usage, keyed by backend name. |
Source code in src/trading_agent/journal/usage_tracker.py
rate_limits
¶
The latest rate-limit report from each backend that sends them, such as Claude's.
Returns:
| Type | Description |
|---|---|
dict[str, dict[str, Any]]
|
Each report, keyed by backend name. |
Source code in src/trading_agent/journal/usage_tracker.py
summary_text
¶
The /usage reply for a desk.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
desk_name
|
str
|
The desk. |
required |
Returns:
| Type | Description |
|---|---|
str
|
Today's usage per backend, and each backend's latest limit status. |