Add CrossModel provider#1747
Conversation
|
Codex review: needs maintainer review before merge. Reviewed June 25, 2026, 4:39 AM ET / 08:39 UTC. Summary Reproducibility: not applicable. as a feature PR rather than a bug report. The PR body provides after-change live CLI output and screenshots for the new provider paths. Review metrics: 3 noteworthy metrics.
Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Land only after maintainers explicitly accept CrossModel as a disabled bundled API-key provider and approve the HTTPS-or-loopback endpoint override policy. Do we have a high-confidence way to reproduce the issue? Not applicable as a feature PR rather than a bug report. The PR body provides after-change live CLI output and screenshots for the new provider paths. Is this the best way to solve the issue? Yes for implementation shape: it follows the existing API-token provider pattern, defaults disabled, and includes focused tests. The remaining question is maintainer acceptance of the new bundled provider and auth surface. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against ada3660e9d61. Label changesLabel justifications:
Evidence reviewedWhat I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
ada0215 to
c75d9f1
Compare
CrossModel (https://crossmodel.ai) is a multi-provider, OpenAI- and Anthropic-compatible API aggregation platform billed against a prepaid USD wallet. This adds it as an API-key usage provider, modeled on the OpenRouter provider since the data shape is nearly identical (wallet balance + daily/weekly/monthly spend). Data source (two read-only endpoints, integer micro units): - GET /v1/credits -> balance_micro, uncollected_micro - GET /v1/usage -> daily/weekly/monthly cost_micro + tokens + counts Display: balance in the identity line (and optional menu bar), today/ this week/this month spend in the menu card, and a shared inline dashboard. No quota meter (prepaid wallet, no per-key limit). Auth: CROSSMODEL_API_KEY env var or Settings/CLI config. Base URL override via CROSSMODEL_API_URL (loopback HTTP allowed for local testing). Tests: CrossModelUsageStatsTests (decode, micro->USD, best-effort usage, 401, redaction, round-trip) and a ProviderConfigEnvironment regression covering Settings/CLI-saved keys.
5cd1ff5 to
da4b482
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: da4b482d54
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if provider == .crossmodel, | ||
| self.settings.menuBarMetricPreference(for: provider, snapshot: snapshot) == .automatic, | ||
| let balance = snapshot?.crossModelUsage?.balanceUSD |
There was a problem hiding this comment.
Restrict CrossModel menu metrics to balance
When a user changes CrossModel's menu-bar metric away from Automatic, this new balance branch no longer runs; the settings UI still offers Primary/Secondary because CrossModel is not treated as a balance-only provider, but CrossModel snapshots only populate crossModelUsage and never provide primary/secondary RateWindows. In that configuration the generic metric resolver returns nil, so the menu-bar title disappears even though a balance is available; either make CrossModel balance-only or fall back to the balance for unsupported metric preferences.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Good catch — fixed in 4b524ff by making CrossModel balance-only (added .crossmodel to SettingsStore.isBalanceOnlyProvider), matching the existing DeepSeek/Mistral/Poe pattern.
Now menuBarMetricPreference(for: .crossmodel) always resolves to .automatic: the settings UI no longer offers Primary/Secondary, and any previously-persisted non-automatic preference is coerced back to Automatic, so the balance branch always runs and the menu-bar title can't disappear.
Added a regression in SettingsStoreAdditionalTests covering .crossmodel in the balance-only set.
eca3a73 to
4b524ff
Compare
Summary
Adds CrossModel as an API-key usage provider, modeled on the OpenRouter provider since the data shape is nearly identical (wallet balance + daily/weekly/monthly spend).
GET /v1/credits→ wallet balance (+ in-flight holds)GET /v1/usage→ UTC day/week/month cost + tokens + request countsCROSSMODEL_API_KEYenv var or Settings/CLI config; base URL override viaCROSSMODEL_API_URL(loopback HTTP allowed for local testing). Wired into the config→env override so Settings/CLI-saved keys resolve.docs/crossmodel.md+docs/providers.md; new string fully localized.defaultEnabled: false).Commands run
swift buildmake check— clean (swiftformat + swiftlint + locale + generated parser hash)swift test --filter CrossModel→ 6/6swift test --filter ProviderConfigEnvironmentTests→ incl. new CrossModel regressionswift run CodexBarCLI usage --provider crossmodel --source apiagainst production, verified with both an env-var key and a Settings/CLI-saved keyVerification (real behavior proof)
Built locally with Swift 6.3.2 / Xcode 26.5. Live data from production
api.crossmodel.ai.Build & tests
Path 1 — saved key (
~/.config/codexbar/config.json, no env var)Path 2 — env var (
CROSSMODEL_API_KEYset, config removed) — identical resultMenu card — balance + Today/Week/Month spend:
Settings → Providers → CrossModel — Enabled,

apisource, secure API-key field: