Repository navigation
Add every coding agent and provider to the agents panel and the default agent - #14040
Conversation
[High impact] The PR appears safe to merge; the latest change fixes the remaining copied-prompt finding without introducing a new actionable issue. SummaryExpands the agents panel to 23 collectors, shares their readers and caches, and adds default-agent launchers.
Previously accepted decisions remain unchanged:
|
|
Thank you @dhh ! <3 |
|
One small robustness note, the same class of bug @ChaseC-130 found on #14039. In if parsed.tzinfo is None:
parsed = parsed.replace(tzinfo=dt.timezone.utc)
try:
return parsed.astimezone()
except (OverflowError, ValueError, OSError):
return None
|
|
Grok Bot could ride along here as a fifth collector: #14563 adds it as one self-contained commit (four new files, no overlap with this PR), and it cherry-picks cleanly onto the current head. Grok Bot runs on a Cursor account but has its own weekly pool, read from the dashboard's |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A model picked with -m on a resume or /model is written as thread_settings_applied ahead of any request on it, so a switch-time compaction was booked to the model before the switch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The collector's own reader read any rollout that changed again from the start, so every refresh during a long session reread it whole. The shared codex_rollouts() reads a grown rollout on from where it stopped, and now reads a rollout naming no session_meta as the built-in provider's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tor starts A forced read only reused what another forced read wrote after it began, so a collector reaching the rollouts after another had finished read them all again. omarchy-agent-usage-update now exports when the refresh began, and a forced read takes what any forced read of that refresh wrote. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lout Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…its stats Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lete Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…an booked Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…dex does Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…unts once Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
mise 2026.10.18 adds Goose to its registry as |
Claude Code signed in with an API key (pay as you go through the Anthropic Console) has no OAuth credentials, so the collector reported Waiting for auth and the panel asked for a sign-in the key makes unnecessary. Where the subscription would ask for one (there is none, or it expired), a key configured for the CLI now stands in, as omacom#14040 has Codex do: no plan, not even the one a registered account was saved with, no limits, nothing to sign in to, and the same note. The key is the CLI's own, an apiKeyHelper or env block in its user settings, or its exported variables, with the settings' env block applied over them and an ANTHROPIC_API_KEY the CLI was told not to use left out, as Claude Code does. Only whether a key is configured is checked. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This PR brings every open agents-panel collector PR and every default-agent launcher PR into one place, adapted so that every agent behaves the same. It supersedes #14039 (merged in here) and the community PRs credited below.
The panel goes from 6 collectors on
quattroto 23, andomarchy default agentgains 9 launchers. All of them follow one written contract,docs/agent-usage-collectors.md, withbin/omarchy-agent-usage-claudeas the reference.Agents panel collectors
cursorgrokbotopencodecopilotmusesession-index.dbhermesagyzaiollamaminimaxopenrouterdeepseekkimchidevinsynthetic/v2/quotaslocalqwenThe upstream
claude,codex,grok,kimi, andfireworkscollectors are brought in line with the same contract too. Codex now keeps its last good limits through a failed probe, building on #15249, #14298 (AnPod), #14630 (Harrison Kairalla), and #14550.What "uniform" means here
Every collector follows the contract:
--forcereuses nothing.limitsStale, and the panel shows its age on hover. A window whose reset has passed comes back at 0% instead of disappearing. Reset times are only ever the service's own.retryAdvisedis set only when the service couldn't be reached.PI_CODING_AGENT_DIR, andrg --no-ignore. Forks are deduplicated. Both of opencode's stores are read, deduplicated by message id, without a fork's copied history. Untrusted timestamps and token values skip their row, never the record.The plumbing every collector needs lives once, in
shell/plugins/agents/collectors.py. Each collector imports it through$OMARCHY_PATHand is only its own credentials, endpoint, provider filter, and record specifics. The module holds:It's about 1,260 lines, and the 23 collectors on top of it are 11,400. The same collectors were about 19,700 lines as standalone copies.
The collector tests share fixtures the same way:
test/shell.d/agent_usage_fixtures.pyandagent-usage-helpers.sh(about 1,150 lines) hold the sandbox, collector loading, HTTP fakes and stub servers, the pi/opencode/credential builders, and cache helpers.check_limits_contract/check_scan_cachepair runs each collector through the contract with a small adapter.The collector tests went from about 14,060 lines to 8,530, plus the helpers. Each converted test was checked by breaking its collector and watching it fail.
test/shell.d/agent-usage-partition-test.shenforces the counting rule across all 23 collectors at once. It builds one home with sessions on every claimed provider in every source and runs every collector offline against it. It asserts that each provider's tokens land in exactly one collector, once, that the totals add up, and that an unclaimed provider is counted by nobody. It also checks that every collector prints the contract's empty record on an unused machine.The panel's Sign-in required link is now offered only for agents
omarchy-agent-account-addcan sign in (Claude, Codex, Grok). Before, it would sign in the default agent instead. Ported from #11367 (Josh LeBlanc).Default agent launchers
Each launcher is declared the way
quattro's own agents are, as alazy = truemise tool inetc/mise/conf.d/omarchy-tools.toml, with:omarchy-agentcase and anomarchy-default-agentaliassetup.default.agent.<id>menu entryOne migration rebuilds the mise shims for existing users.
qwendshmcodekiro-clikilodevinampcommandcodeWhat changed from those PRs:
curl | bashscripts, and pipx are replaced with mise packages that install on a stock machine.omarchy-agentcopies the prompt to the clipboard, sends a notification, and opens the agent, with no Panel.qml change.Left out on purpose
cursor-agent.github:/aqua:backend. Their icon-font glyphs stay in the font, unused, sinceomarchy dev fontcan't remove a glyph. The Mistral Vibe usage collector stays.Decisions worth a look
"remote": falseincopilot.jsonsilences it for budget-only users.DSH_TELEMETRY_DISABLED=1, plus a config patch for the session-log uploader.omarchy-agent-account-staterelies on it.:cloudmodel reached through a Codex provider pointed at a local Ollama daemon is counted by nobody. Local leaves cloud models out, and the Ollama collector doesn't read Codex rollouts.limitsStale, but the panel only shows age on limit windows. Showing a stale balance's age would be a small panel follow-up.Pre-merge review
Five reviewers went over the whole diff fresh. Their two blockers are fixed:
About 50 should-fixes are fixed, each with a regression test that fails without it:
About 20 test coverage gaps are closed, each proven against a code change that used to slip through. The midnight-sensitive tests are frozen to the day they start. Every Greptile comment is answered inline.
Official marks
Every agent mark was checked against the brand's own site, favicon, press kit, or repo. These were wrong or generic and now use the official mark:
>_mark instead of the plain OpenAI blossom.The font README records every source. The font is package-owned, so the new glyphs reach desktops with the next
omarchy-settingsrelease; until then those entries draw no icon on a pulled checkout.Fuzzing
Six fuzzers threw adversarial input at all 23 collectors and the 9 launchers, sandboxed and offline: malformed files and replies, wrong types at every level, out-of-range and falsy times, every HTTP failure, dripping servers, corrupt and future-stamped caches, hostile keys. A skeptic reran each report; 45 reproduced and 35 were rejected. All 45 are fixed, each with a regression test that fails without it:
trusted_endpoint(), so a key never travels over plain HTTP to another host.~/.local/binruns ahead of mise's lazy shim.Final checks
omarchy-agentruns, and each answered--version/--help. The flags the launcher passes appear in each tool's help, except Amp's--dangerously-allow-all, which its own messages recommend. That found a bug Kimi already had onquattro: node is a lazy tool, and mise refuses to install an npm-backed agent without it, so picking Qwen Code, Amp, Kilo, MiniMax Code, DeepSeek Harness, Command Code, Freebuff or Kimi on a fresh machine failed. The install now names node alongside any npm-backed agent.quattro. All 54 agent and launcher test files pass in both timezones,./test/clipasses, and the full./test/shellfails only the 11 files that fail identically onquattroalone.~/.local/bincopy, and recognizes older one-line mise wrappers;~/.config/manicode/on its first run, outside mise.Validation against real agents
The fixtures above were written by us, so a misreading shared between a collector and its fixture would pass. To catch that, the collectors were validated against data and definitions that didn't come from us, in ten passes, each fixing what the last one found until a pass came back with nothing that miscounts:
What that changed, beyond the fuzzing fixes:
cost-stateusage beyond its replies (compactions, title and side queries, about a third of real Opus usage), Codex remote compactions (token_usage_record), pi compactions, and usage routed through another provider.ANTHROPIC_BASE_URL), Codex (model_providers,openai_base_url), MiniMax Code, DeepSeek Harness, Kimi Code, Qwen Code, Hermes, Vibe, Kimchi and Copilot BYOK traffic is placed by one shared classifier (PROVIDER_HOSTS, self-hosted endpoints to Local, Ollama cloud tags to Ollama), and the partition test holds every collector to it.Not verified
No collector's limits, plan or balance answer was checked against a real signed-in reply: those rest on official docs, upstream source and credential-free probes. Cursor, Antigravity, Devin and Copilot can't run without a sign-in, so their local readers were checked against upstream-shaped fixtures only. A few gaps are deliberate and documented: usage behind a gateway or host nothing can place counts nowhere, and requests an agent never records (interactive Codex's title queries, omp's compactions, Claude Code sessions with no
cost-state) can't be counted. The undocumented endpoints and on-disk formats come from the original PRs or were read from the agents' published source. The launchers were installed on x86_64 only; the aarch64 downloads for Kiro and Devin answer, but nothing was installed on ARM. The Default Agent menu was checked in a running shell with the new font. The new panel marks were checked through Qt's SVG renderer on dark and light surfaces, not in the live picker.Tests
test/shell.d/agent*-test.shpasses, including the partition test andagents-panel-test.sh. With the launcher tests below that's 57 files, run in both Pacific/Honolulu and Pacific/Kiritimati.default-agent-test.sh,menu-test.sh,mise-provision-test.sh, and every<id>-agent-test.shpass../test/cli: passes../test/shell: 15 files fail: battery-status, crash-capture, hyprland-workspace-layout, i18n, keybindings-menu, menu-plugin, migrate-notify, openclaw-cli, passwordless-grant-lifecycle, screenrecording, screenrecording-wf-audio, sleep-lock, system-power, tailscale-receive, and update-restart-kernel. All 15 fail identically on a cleanquattrocheckout in this environment, and the failing assertions in menu-plugin, i18n, and keybindings-menu are the same on both.Fixes found along the way:
quattro). It now retries.🤖 Generated with Claude Code
Posted by Claude on behalf of DHH