4.0 KiB
Ollama Usage Poller — Continuous Collection
Context
The /usage skill shows Ollama Cloud credit usage on demand. The user wants
continuous collection: poll GET https://ollama.com/api/usage every minute,
store a sample whenever anything changed since the last one. Goal: later
analysis of how much each nanobot session cost, and when.
Constraints found in exploration:
- The API (
ollama.com/api/usage, Bearer key fromworkspace/.env) returns:limits.session.usage(fraction of plan limit, rolling 1-hour window),limits.weekly.usage(weekly window), per-modelrequest_countfor both windows,activity.cost(broken, always $0.00000 on Pro). - No reset timestamps, no per-model cost split, no token counts in the API.
- Existing pattern: per-minute system crontab entries running
uv run <script>with output toworkspace/log/<name>_cron.log(remind, wiki-compile, wiki-sync). Reuse this pattern. - Session attribution later needs
memory/history.jsonl(per-request timestamps, token counts, session ids) — out of scope for this plan, this plan only builds the collector + a delta report.
Steps
-
Collector —
scripts/ollama_usage_poll.py(English, stdlib only, reuseload_api_keyfromskills/usage/scripts/ollama_usage.py):- GET the API, on network/HTTP error log to stderr and exit 0 (never noisy, never blocks cron).
- SQLite
db/ollama_usage.sqlite, tablesamples:CREATE TABLE IF NOT EXISTS samples ( ts TEXT PRIMARY KEY, -- UTC ISO 8601 session REAL NOT NULL, -- limits.session.usage fraction weekly REAL NOT NULL, -- limits.weekly.usage fraction models TEXT NOT NULL -- JSON: weekly {"model": count} ); - Write-on-change: compare against the latest row; insert only when session, weekly, or models JSON differ. Unchanged minutes are noise.
- Session-window reset detection (usage drops instead of rising) is implicit — we store raw values; deltas are computed at report time.
-
Crontab — add system crontab entry (user's crontab, alongside the existing ones):
# ollama-usage: continuous usage sampling into db/ollama_usage.sqlite * * * * * uv run /home/nanobot/.nanobot/workspace/scripts/ollama_usage_poll.py >> /home/nanobot/.nanobot/workspace/log/ollama_usage_cron.log 2>&1 -
Report —
scripts/ollama_usage_report.py(English, stdlib only):- No args: last 24 h delta summary (session/weekly spend per hour, model request deltas).
--since ISO/--until ISO: arbitrary window.- Output: plain text table — for each consecutive sample pair:
ts, Δsession %, Δweekly %, Δrequests per model. Detect hourly reset (session drops) and mark it as a new window boundary. - Extend the
/usageskill SKILL.md with a "Reports" section pointing at this script (does not change the on-demand output format).
-
Skill update —
skills/usage/SKILL.md: add a short note that continuous sampling runs via crontab intodb/ollama_usage.sqliteand reports are available viascripts/ollama_usage_report.py. -
Git commit — workspace repo, timestamped message.
Out of scope (later)
- Session-level attribution (join with
memory/history.jsonltoken counts per session) — separate plan once we have a few days of samples. - Notification thresholds (e.g. Telegram alert at 80 % weekly).
- Retention/compaction of the samples table (1 row per change, negligible size for months).
Verification
- Run
uv run scripts/ollama_usage_poll.pytwice back to back → second run writes nothing (no change), DB has 1 row. - Wait for a real request (or make one via nanobot) → next poll writes a new row with changed session fraction / model counts.
- Run the report script → delta table renders, hourly reset detected as boundary when a session window rolls over.
crontab -lshows the new entry; after ~5 minuteslog/ollama_usage_cron.logis empty or minimal, DB grew.