Skip to content

feat: add Ollama usage provider - #233

Closed
zzerbzz wants to merge 1 commit into
chattymin:mainfrom
zzerbzz:feat/ollama-usage-provider
Closed

zzerbzz wants to merge 1 commit into
chattymin:mainfrom
zzerbzz:feat/ollama-usage-provider

Conversation

@zzerbzz

@zzerbzz zzerbzz commented Aug 27, 2026

Copy link
Copy Markdown

What

Adds a local Ollama usage provider, following the exact pattern of the existing local providers (LocalClaudeProvider, LocalCodexProvider, …):

  • LocalOllamaUsageProvider.swift — LocalOllamaProvider: UsageProvider (id "ollama", displayName "Ollama", reportsCost = false, since local inference is free). It reads a JSONL ledger and reuses LocalUsageReader for daily totals, active-block, and week/month enrichment — no new counting logic.
  • UsageStore.swift — registers LocalOllamaProvider() in the provider list.
  • CustomScanRoots.swift — adds the "ollama" case so the existing Additional scan folders feature works for Ollama too.
  • OllamaUsageTests.swift — unit tests for the reader/parser.

Where the data comes from (the honest caveat)

Ollama reports exact prompt_tokens / completion_tokens on its final response object, but does not persist a usage ledger of its own. This provider reads NDJSON written under ~/.ollama/usage/YYYY-MM-DD.jsonl by a small transparent logging proxy that sits in front of the Ollama daemon and records each completed request, e.g.:

{"ts":"2026-08-27T10:25:57+00:00","source":"ollama","endpoint":"/api/chat","model":"qwen3.6:35b","prompt_tokens":35065,"completion_tokens":172,"total_tokens":35237}

The provider is intentionally decoupled from the proxy — it just treats that directory as a local usage source, and shows nothing if the ledger is absent (no crash, no error). Users who don't run such a proxy simply see no Ollama data, like any other provider whose logs aren't present.

Open question for the maintainer: how would you like the proxy dependency handled? (a) document the expected ~/.ollama/usage NDJSON format in the README and leave the proxy to the user; (b) I can contribute a tiny reference proxy in a follow-up; (c) if Ollama adds native usage persistence later, the provider can point at that with no interface change. Happy to go whichever way fits the project.

Notes

  • No dependency changes; matches existing provider conventions and the local-day/totalTokens accounting used across providers.
  • Tested locally against a real ~/.ollama/usage ledger; the app builds clean via scripts/build-app.sh.

Ollama returns exact prompt/completion counts on its final response object but does not persist a usage ledger, so this reads the NDJSON written under ~/.ollama/usage by a transparent logging proxy in front of Ollama and feeds it through LocalUsageReader like every other local provider. Registers LocalOllamaProvider in UsageStore and adds the "ollama" case to CustomScanRoots so Additional scan folders works for it too.
@zzerbzz
zzerbzz force-pushed the feat/ollama-usage-provider branch from c10f310 to 2966000 Compare August 27, 2026 13:37
@chattymin

Copy link
Copy Markdown
Owner

Thanks for this, and for stating the proxy dependency plainly instead of burying it — that's what made the decision straightforward.

I'm closing it, but I want to point at a different shape rather than just say no.

Why not this one. Every other provider in the app reads logs the tool itself writes; that's what lets the README promise "no external CLI needed". This one reads a ledger produced by a proxy the project doesn't ship, so a user would have to install and run an extra daemon before any data appears. And for local inference there isn't much to show even then: no cost and no quota, so two of the app's three surfaces (spend, official limits) are empty by definition, leaving only token counts feeding the companion.

The shape I would take. Ollama Cloud, not local inference. It has plan tiers, session and weekly quota windows, and reset timestamps — which is exactly the "official limits" model the app already implements for Claude, Codex and Antigravity. It also has a real credential: an API key from ollama.com/settings/keys, which is issued and revocable, rather than a scraped file.

Worth knowing before you start: the documented API doesn't appear to expose the quota windows, so the usage bars may need a browser session cookie. The app just took that tradeoff for Claude in #241, so it isn't disqualifying here, but it should be a deliberate part of the design rather than a surprise at the end.

Of your three options, (c) is closest to where I land: if Ollama adds native usage persistence for local inference, the provider can point at it with no interface change. Until then, the Cloud side is the part with something to show.

If you want to take a run at that, I'll review it.

@chattymin chattymin closed this Aug 30, 2026
LuceteYang added a commit to LuceteYang/PikaTokenBar that referenced this pull request Sep 10, 2026
Surveying rival token trackers is easy; the scarce thing is a candidate
upstream has not already been asked for, has not already refused, and that
survives this fork's two differences. So the skill is about order, not search
technique: read upstream's backlog before generating candidates, because a
list built the other way around ranks ideas without knowing which ones are
still open.

Written against a measured baseline. Running the same task without it
produced eight recommendations, five of which already existed upstream —
streak, share card and efficiency score were one issue (chattymin#260) between them —
while the two things the maintainer had labelled help wanted / good first
issue (chattymin#149, chattymin#115) appeared nowhere.

Verified with a fresh-context run: the agent read the backlog first, filled
every slot of the recommendation format, and caught the nuance the skill
warns about — chattymin#233 closed an Ollama provider while chattymin#115 recruits providers,
and the closing comment names the shape that would be accepted. It also
overstated a documented literal branch as an extension-rule violation, so a
row was added telling readers to read the comment around a grep hit before
calling it a defect.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants