Repository navigation
Conversation
Codex CLI fronts any OpenAI-compatible backend: `--oss`, or a custom model_provider in config.toml aimed at Ollama, LM Studio, or a gateway. Those rollouts land in the same sessions directory as real ones, and the native scan counted them all, so a local model showed up in the agents panel as Codex subscription usage. On one machine `qwen3-coder:30b` was 40% of the tokens on that tab. The provider is recorded on session_meta, which the scan skipped past; turn_context carries the model but no provider at all. Read it there and drop the rollout when it names anything but the built-in openai backend, matching what the pi and opencode scans already do with foreign providers. Rollouts written before Codex recorded the field carry no provider, so the check only fires when one is present and differs - older history keeps counting. Limits are unaffected; they come from the app-server RPC, not from session files. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The subscription collectors each answer "what did this cost me", and every turn served by something else is dropped on the floor. Run Codex CLI against Ollama and the work simply vanishes from the panel - which is the right answer for the Codex tab and the wrong answer overall. Add a collector for the other side of that line. It counts exactly what the subscription collectors skip: Codex, pi, and opencode sessions served by an endpoint you host, whether that is this machine or a box on the network. An endpoint qualifies when its URL is loopback, private, link-local, or a bare/LAN hostname, so `server.home` counts the same as `localhost`; ids with no URL to resolve fall back to the well-known runtimes, and a custom gateway can be named in ~/.config/omarchy/agents/local.json. The two collectors partition the sessions directory, so no turn is lost between them and none is counted twice - asserted in the test. A third-party API that is neither the subscription nor your own hardware stays uncounted on purpose. No limits and no balance: nothing meters self-hosted work, so the panel draws the token history alone. Cross-device aggregation needs no changes; snapshots merge by provider id, so a homelab's numbers travel like any other agent's. Scans are cached behind the same versioned envelope the other collectors use, and the opencode provider filter is pushed into SQL rather than run over every historical message in Python. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Automated AI review
Outcome: four behaviours do not match the description: turns still in opencode's WAL, pi on Verified: the Local collector is wired in correctly.
opencode rows still in the WAL are not counted
Synthetic WAL-mode database, writer connection still open, rows committed but not checkpointed: Impact: while opencode is running, the Local tab misses its newest turns. The test builds its database with the default rollback journal, so it cannot catch this. The size of the lag on a live opencode was not measured. Suggested change: pi's
|
|
This is stacked on #12032, which is now closed unmerged, so the branch can't land as-is. Please restack the Local-tab commit onto current |
The collector and test parts of #12034; its Codex provider fix is already upstream. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Implements #12033.
The subscription collectors each answer "what did this cost me", so every turn served by something else is dropped on the floor. #12032 makes the Codex collector drop them correctly; this gives them somewhere to go.
A
localcollector counts exactly what the subscription collectors skip, across the same three sources they already read: native Codex rollouts, pi/omp sessions, and the opencode database.What counts as local
The endpoint, not a hardcoded runtime list. A URL qualifies when it is loopback, private, link-local, or a bare/LAN hostname — so a model served by another machine on your network counts the same as one on this one:
homelabhttp://server.home:11434/v1gpuhttp://10.0.0.50:8000/v1lanboxhttp://gpu-box:8080ollamaopenrouterhttps://openrouter.ai/api/v1openaiIds with no URL to resolve fall back to the well-known runtimes (Ollama, LM Studio, llama.cpp, vLLM, LocalAI, …), and a custom gateway can be named in
~/.config/omarchy/agents/local.json.The property that makes the pair safe
With the fix in place the two collectors partition the sessions directory — no turn lost between them, none counted twice. On real data:
That is asserted in the test, not merely observed once.
Shape
aggregateSnapshots()builds provider accumulators on demand, so a homelab's numbers travel like any other agent's. Untested, as I have only one machine.Tests
test/shell.d/agent-usage-local-scanner-test.sh, 11 assertions: LAN and loopback endpoints, configured ids, the no-limits shape, the partition property across both collectors, opencode filtering (paid providers, user messages, reasoning tokens, malformed rows), and the full cache lifecycle.Whole agent-usage suite is 77 assertions across 6 files, green. Full
test/shellis 236/242 files, with the same 6 environmental failures that reproduce on a cleanquattro.Deliberate omissions
assets/local.svg— the bar glyph stands in. Happy to add a mark if you want one, but it seemed wrong to invent branding in a drive-by PR.Entirely understand if the panel is not meant to grow this way — filed #12033 first so the idea could be rejected before the code mattered.