feat: add usage cost reporting

This commit is contained in:
Peter Steinberger
2026-01-09 02:21:17 +00:00
parent dfbee10377
commit 151523f47b
29 changed files with 696 additions and 184 deletions

View File

@@ -11,7 +11,8 @@ read_when:
- No estimated costs; only the provider-reported windows.
## Where it shows up
- `/status` in chats: adds a short “Usage” line (only if available).
- `/status` in chats: compact oneliner with session tokens + estimated cost (API key only) and provider quota windows when available.
- `/cost on|off` in chats: toggles perresponse usage lines (OAuth shows tokens only).
- CLI: `clawdbot status --usage` prints a full per-provider breakdown.
- CLI: `clawdbot providers list` prints the same usage snapshot alongside provider config (use `--no-usage` to skip).
- macOS menu bar: “Usage” section under Context (only if available).

View File

@@ -556,6 +556,7 @@
"concepts/agent",
"concepts/agent-loop",
"concepts/system-prompt",
"token-use",
"concepts/oauth",
"concepts/agent-workspace",
"concepts/multi-agent",

72
docs/token-use.md Normal file
View File

@@ -0,0 +1,72 @@
---
summary: "How Clawdbot builds prompt context and reports token usage + costs"
read_when:
- Explaining token usage, costs, or context windows
- Debugging context growth or compaction behavior
---
# Token use & costs
Clawdbot tracks **tokens**, not characters. Tokens are model-specific, but most
OpenAI-style models average ~4 characters per token for English text.
## How the system prompt is built
Clawdbot assembles its own system prompt on every run. It includes:
- Tool list + short descriptions
- Skills list (only metadata; instructions are loaded on demand with `read`)
- Self-update instructions
- Workspace + bootstrap files (`AGENTS.md`, `SOUL.md`, `TOOLS.md`, `IDENTITY.md`, `USER.md`, `HEARTBEAT.md`, `BOOTSTRAP.md` when new)
- Time (UTC + user timezone)
- Reply tags + heartbeat behavior
- Runtime metadata (host/OS/model/thinking)
See the full breakdown in [System Prompt](/concepts/system-prompt).
## What counts in the context window
Everything the model receives counts toward the context limit:
- System prompt (all sections listed above)
- Conversation history (user + assistant messages)
- Tool calls and tool results
- Attachments/transcripts (images, audio, files)
- Compaction summaries and pruning artifacts
- Provider wrappers or safety headers (not visible, but still counted)
## How to see current token usage
Use these in chat:
- `/status`**compact oneliner** with the session model, context usage,
last response input/output tokens, and **estimated cost** (API key only).
- `/cost on|off` → appends a **per-response usage line** to every reply.
- Persists per session (stored as `responseUsage`).
- OAuth auth **hides cost** (tokens only).
Other surfaces:
- **TUI/Web TUI:** `/status` + `/cost` are supported.
- **CLI:** `clawdbot status --usage` and `clawdbot providers list` show
provider quota windows (not per-response costs).
## Cost estimation (when shown)
Costs are estimated from your model pricing config:
```
models.providers.<provider>.models[].cost
```
These are **USD per 1M tokens** for `input`, `output`, `cacheRead`, and
`cacheWrite`. If pricing is missing, Clawdbot shows tokens only. OAuth tokens
never show dollar cost.
## Tips for reducing token pressure
- Use `/compact` to summarize long sessions.
- Trim large tool outputs in your workflows.
- Keep skill descriptions short (skill list is injected into the prompt).
- Prefer smaller models for verbose, exploratory work.
See [Skills](/tools/skills) for the exact skill list overhead formula.

View File

@@ -163,6 +163,23 @@ This is **scoped to the agent run**, not a global shell environment.
Clawdbot snapshots the eligible skills **when a session starts** and reuses that list for subsequent turns in the same session. Changes to skills or config take effect on the next new session.
## Token impact (skills list)
When skills are eligible, Clawdbot injects a compact XML list of available skills into the system prompt (via `formatSkillsForPrompt` in `pi-coding-agent`). The cost is deterministic:
- **Base overhead (only when ≥1 skill):** 195 characters.
- **Per skill:** 97 characters + the length of the XML-escaped `<name>`, `<description>`, and `<location>` values.
Formula (characters):
```
total = 195 + Σ (97 + len(name_escaped) + len(description_escaped) + len(location_escaped))
```
Notes:
- XML escaping expands `& < > " '` into entities (`&amp;`, `&lt;`, etc.), increasing length.
- Token counts vary by model tokenizer. A rough OpenAI-style estimate is ~4 chars/token, so **97 chars ≈ 24 tokens** per skill plus your actual field lengths.
## Managed skills lifecycle
Clawdbot ships a baseline set of skills as **bundled skills** as part of the

View File

@@ -35,6 +35,7 @@ Directives (`/think`, `/verbose`, `/reasoning`, `/elevated`) are parsed even whe
Text + native (when enabled):
- `/help`
- `/status`
- `/cost on|off` (toggle per-response usage line)
- `/stop`
- `/restart`
- `/activation mention|always` (groups only)
@@ -52,6 +53,7 @@ Text-only:
Notes:
- Commands accept an optional `:` between the command and args (e.g. `/think: high`, `/send: on`, `/help:`).
- `/cost` appends per-response token usage; it only shows dollar cost when the model uses an API key (OAuth hides cost).
- `/verbose` is meant for debugging and extra visibility; keep it **off** in normal use.
- `/reasoning` (and `/verbose`) are risky in group settings: they may reveal internal reasoning or tool output you did not intend to expose. Prefer leaving them off, especially in group chats.

View File

@@ -77,6 +77,7 @@ Session controls:
- `/think <off|minimal|low|medium|high>`
- `/verbose <on|off>`
- `/reasoning <on|off|stream>`
- `/cost <on|off>`
- `/elevated <on|off>` (alias: `/elev`)
- `/activation <mention|always>`
- `/deliver <on|off>`

View File

@@ -53,6 +53,7 @@ Use SSH tunneling or Tailscale to reach the Gateway WS.
- `/think <off|minimal|low|medium|high>`
- `/verbose <on|off>`
- `/reasoning <on|off|stream>` (stream = Telegram draft only)
- `/cost <on|off>`
- `/elevated <on|off>`
- `/elev <on|off>`
- `/activation <mention|always>`