Skip to content

Add CrossModel provider#1747

Open
hujuncheng wants to merge 2 commits into
steipete:mainfrom
hujuncheng:feat/crossmodel-provider
Open

Add CrossModel provider#1747
hujuncheng wants to merge 2 commits into
steipete:mainfrom
hujuncheng:feat/crossmodel-provider

Conversation

@hujuncheng

@hujuncheng hujuncheng commented Jun 25, 2026

Copy link
Copy Markdown

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).

  • Data source — two read-only endpoints, integer micro units (1 USD = 1,000,000 micro):
    • GET /v1/credits → wallet balance (+ in-flight holds)
    • GET /v1/usage → UTC day/week/month cost + tokens + request counts
  • Display — balance in the identity line (and optional menu bar), today/this week/this month spend, and the shared inline dashboard. No quota meter (prepaid wallet, no per-key limit).
  • AuthCROSSMODEL_API_KEY env var or Settings/CLI config; base URL override via CROSSMODEL_API_URL (loopback HTTP allowed for local testing). Wired into the config→env override so Settings/CLI-saved keys resolve.
  • Docsdocs/crossmodel.md + docs/providers.md; new string fully localized.
  • Defaults to disabled (defaultEnabled: false).

Commands run

  • swift build
  • make check — clean (swiftformat + swiftlint + locale + generated parser hash)
  • swift test --filter CrossModel → 6/6
  • swift test --filter ProviderConfigEnvironmentTests → incl. new CrossModel regression
  • Live: swift run CodexBarCLI usage --provider crossmodel --source api against production, verified with both an env-var key and a Settings/CLI-saved key

Verification (real behavior proof)

Built locally with Swift 6.3.2 / Xcode 26.5. Live data from production api.crossmodel.ai.

Build & tests

$ swift build            # Build complete! (95s, exit 0)
$ swift test --filter CrossModel
  CrossModelUsageStatsTests — 6 tests, 6 passed (decode, micro→USD,
  best-effort usage, 401 invalid-credentials, redaction, snapshot round-trip)

Path 1 — saved key (~/.config/codexbar/config.json, no env var)

$ env -u CROSSMODEL_API_KEY CodexBarCLI usage --provider crossmodel --source api --format json
[{ "provider":"crossmodel", "source":"api",
   "usage":{ "dataConfidence":"exact",
     "identity":{"providerID":"crossmodel","loginMethod":"Balance: $8.06"},
     "crossModelUsage":{ "currency":"USD",
       "balanceUSD":8.059489, "uncollectedUSD":0,
       "daily":  {"costUSD":0.005746,"totalTokens":12467,  "requestCount":9,   "successCount":9},
       "weekly": {"costUSD":0.665033,"totalTokens":1925790, "requestCount":529, "successCount":529},
       "monthly":{"costUSD":5.368746,"totalTokens":35412471,"requestCount":3166,"successCount":3057}
     }}}]

Path 2 — env var (CROSSMODEL_API_KEY set, config removed) — identical result

$ CROSSMODEL_API_KEY=cm-************************ CodexBarCLI usage --provider crossmodel --source api --format json
[{ "provider":"crossmodel", "source":"api",
   "usage":{ ... "balanceUSD":8.059489, "daily.costUSD":0.005746,
             "weekly.costUSD":0.665033, "monthly.costUSD":5.368746 ... }}]

Menu card — balance + Today/Week/Month spend:

CodexBar-CrossModel

Settings → Providers → CrossModel — Enabled, api source, secure API-key field:
CodexBar-CrossModel-config

@clawsweeper

clawsweeper Bot commented Jun 25, 2026

Copy link
Copy Markdown

Codex review: needs maintainer review before merge. Reviewed June 25, 2026, 4:39 AM ET / 08:39 UTC.

Summary
The PR adds a disabled CrossModel API-key usage provider with credits/usage fetching, env/config credential resolution, menu/settings display, docs, localization, and focused tests.

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.

  • Diff surface: 55 files, +1000/-7. The provider addition spans core provider plumbing, app UI, widgets, docs, localization, and tests, so maintainer review should cover integration points.
  • Provider default: 1 provider added, defaultEnabled false. Existing users should not see CrossModel enabled automatically on upgrade, which limits runtime blast radius.
  • Focused test coverage: 5 test files changed, 1 new CrossModel suite. The PR includes targeted coverage for parsing, auth/config resolution, debug output, and persisted snapshot behavior.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🦞 diamond lobster
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Maintainer should confirm CrossModel belongs in bundled providers and approve the endpoint override policy.

Risk before merge

  • [P1] Merging this PR means CodexBar owns a new credentialed CrossModel provider, CROSSMODEL_API_KEY resolution, and a CROSSMODEL_API_URL override path; tests and live proof do not settle whether maintainers want that bundled auth/provider surface.

Maintainer options:

  1. Accept CrossModel as bundled provider
    Maintainers can merge after normal checks if they are comfortable owning the disabled API-key provider and endpoint override policy.
  2. Narrow the auth surface first
    If the endpoint override policy is too broad, ask for a focused update that restricts or documents the allowed override behavior before merge.
  3. Close if provider scope is wrong
    If CrossModel should not live in the bundled provider list, close this PR and ask for a separate external integration or docs-only direction.

Next step before merge

  • [P2] Needs maintainer acceptance of the new bundled provider and endpoint override; no narrow automated repair remains.

Security
Cleared: No concrete security or supply-chain issue was found; the diff adds credential handling and a validated HTTPS-or-loopback endpoint override without new dependencies, workflows, or secret-broadening automation.

Review details

Best 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 changes

Label justifications:

  • P2: This is a normal-priority provider feature with useful coverage and limited blast radius because the new provider defaults disabled.
  • merge-risk: 🚨 auth-provider: The diff adds API-key storage, env/config token resolution, provider routing, and an endpoint override for a new provider.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The PR body includes after-fix live production CLI output for saved-key and env-var auth paths, plus screenshots of the CrossModel menu card and settings field.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes after-fix live production CLI output for saved-key and env-var auth paths, plus screenshots of the CrossModel menu card and settings field.
Evidence reviewed

What I checked:

Likely related people:

  • steipete: Current main blame and the v0.37.2 base commit include the provider registry, OpenRouter provider pattern, endpoint override validator, and provider config environment that this PR extends. (role: current provider framework owner; confidence: high; commits: f380287041b8; files: Sources/CodexBarCore/Providers/OpenRouter/OpenRouterProviderDescriptor.swift, Sources/CodexBarCore/Providers/OpenRouter/OpenRouterUsageStats.swift, Sources/CodexBarCore/ProviderEndpointOverrideValidator.swift)
  • BAKEZQ: Recent z.ai BigModel work touched provider settings, config validation, provider environment resolution, provider descriptors, and tests adjacent to the CrossModel auth/config path. (role: recent adjacent provider/config contributor; confidence: medium; commits: 2435c93453fe; files: Sources/CodexBarCore/Providers/ProviderEnvironmentResolver.swift, Sources/CodexBarCore/Providers/Zai/ZaiProviderDescriptor.swift, Sources/CodexBarCore/Providers/Zai/ZaiSettingsReader.swift)
  • Zihao Qi: Recent work touched the inline dashboard and menu descriptor usage presentation surfaces that the CrossModel menu summary and dashboard extend. (role: recent adjacent usage UI contributor; confidence: medium; commits: 929d55aaf1d7; files: Sources/CodexBar/InlineUsageDashboardContent.swift, Sources/CodexBar/MenuDescriptor.swift, Tests/CodexBarTests/MenuCardModelTests.swift)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

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
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@hujuncheng hujuncheng force-pushed the feat/crossmodel-provider branch from ada0215 to c75d9f1 Compare June 25, 2026 05:57
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal priority bug or improvement with limited blast radius. merge-risk: 🚨 auth-provider 🚨 Merging this PR could break OAuth, tokens, provider routing, model choice, or credentials. proof: sufficient Contributor real behavior proof is sufficient. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 25, 2026
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.
@hujuncheng hujuncheng force-pushed the feat/crossmodel-provider branch from 5cd1ff5 to da4b482 Compare June 25, 2026 07:03
@clawsweeper clawsweeper Bot added rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Jun 25, 2026
@hujuncheng hujuncheng marked this pull request as ready for review June 25, 2026 07:13

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment on lines +678 to +680
if provider == .crossmodel,
self.settings.menuBarMetricPreference(for: provider, snapshot: snapshot) == .automatic,
let balance = snapshot?.crossModelUsage?.balanceUSD

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@clawsweeper clawsweeper Bot added proof: sufficient Contributor real behavior proof is sufficient. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed proof: sufficient Contributor real behavior proof is sufficient. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Jun 25, 2026
@hujuncheng hujuncheng force-pushed the feat/crossmodel-provider branch from eca3a73 to 4b524ff Compare June 25, 2026 08:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 auth-provider 🚨 Merging this PR could break OAuth, tokens, provider routing, model choice, or credentials. P2 Normal priority bug or improvement with limited blast radius. proof: sufficient Contributor real behavior proof is sufficient. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant