Skip to content

Add AnyRouter provider#2218

Closed
joeVenner wants to merge 8 commits into
steipete:mainfrom
joeVenner:codex/anyrouter-provider
Closed

Add AnyRouter provider#2218
joeVenner wants to merge 8 commits into
steipete:mainfrom
joeVenner:codex/anyrouter-provider

Conversation

@joeVenner

@joeVenner joeVenner commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds the AnyRouter provider from Add AnyRouter provider #2171.
  • Covers management-key credit fetching, scoped-out key handling, provider registration, docs, icons, and parser hash update for this standalone branch.
  • Aligns setup guidance, Settings token-account copy, and errors with AnyRouter's /credits credential contract: use an ak_... management key with read:credits; inference keys like sk-ar-v1-... are not accepted by that endpoint.
  • Includes the black logo simplification from the source PR follow-up commits.

Verification

  • swift test --filter AnyRouter
  • make check

duyet and others added 5 commits July 16, 2026 12:55
AnyRouter is an OpenAI-compatible model-routing gateway billed from a shared
credit balance. Read the balance from its credits API and surface spend in the
menu bar like the other API-key providers.

Only /api/v1/credits is reachable with an sk-ar-v1- inference key: /api/v1/key
requires dashboard session auth, so key-scoped rate limits are not available.
Unlike OpenRouter, the credits payload is flat rather than wrapped in `data`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J7Ussus9GfDUGjdabsqyL5
Co-Authored-By: duyetbot <101855044+duyetbot@users.noreply.github.com>
Use the shared UsageFormatter.currencyString instead of a local NumberFormatter,
drop the settings error case that could never be thrown, and stop decoding the
three credits fields nothing displays (they were required keys, so dropping them
also removes a way a payload change could break decoding).

Use the black brand logo and a matching graphite accent; the orange mark is
retired.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J7Ussus9GfDUGjdabsqyL5
Co-Authored-By: duyetbot <101855044+duyetbot@users.noreply.github.com>
A key whose allowed_endpoints list omits /api/v1/credits is valid but scoped
out; AnyRouter answers 403 insufficient_scope. Reporting that as "key rejected"
pointed users at the wrong fix, so give it its own error and document it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J7Ussus9GfDUGjdabsqyL5
Co-Authored-By: duyetbot <101855044+duyetbot@users.noreply.github.com>

@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: 6a1a8dd00a

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +134 to +135
subtitle: "Store one labeled AnyRouter inference key per environment you want to monitor.",
placeholder: "Paste AnyRouter API key (sk-ar-v1-…)…",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Require AnyRouter management keys for credits

When users add AnyRouter through Settings, this prompts them to store an inference key (sk-ar-v1-…), but the current AnyRouter Credits API docs state that GET /api/v1/credits requires a Management key (ak_…) with read:credits and that LLM keys are not accepted (https://docs.anyrouter.dev/api-reference/credits). Users following this UI/docs path will consistently get rejected credentials and the new provider will never load; the setup should ask for an ak_… management key and the required scope instead.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. 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. labels Jul 16, 2026
@clawsweeper

clawsweeper Bot commented Jul 16, 2026

Copy link
Copy Markdown

Codex review: needs real behavior proof before merge. Reviewed July 16, 2026, 4:32 PM ET / 20:32 UTC.

Summary
Adds AnyRouter credit-balance and lifetime-spend tracking across provider registration, Settings, CLI configuration, documentation, icons, widgets, and focused tests.

Reproducibility: yes. at source level: use a snapshot with large cumulative used and a newly replenished current balance; the added formula reports near-total utilization despite fresh available credit. A live AnyRouter reproduction has not been supplied.

Review metrics: 2 noteworthy metrics.

  • Patch surface: 33 files; 775 additions, 81 deletions. The provider touches central registration, authentication, presentation, CLI, widget, documentation, generated-hash, and release surfaces.
  • Focused test surface: 2 new AnyRouter test files. Parser, HTTP-status, settings, and presentation mapping receive coverage, but the tests remain fixture-based rather than account-bound proof.

Root-cause cluster
Relationship: canonical
Canonical: #2218
Summary: This PR is the corrected standalone AnyRouter landing candidate, while the older source PR retains the obsolete inference-key contract and the closed batch PR was only a broader packaging attempt.

Members:

  • superseded: Add AnyRouter provider #2171 - It proposes the same provider but still documents an inference key rather than the required scoped management key and lacks positive live proof.
  • partial_overlap: Add provider usage integrations batch #2215 - The closed-unmerged batch PR included AnyRouter among several unrelated provider integrations and is not a viable canonical landing branch.

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
Patch quality: 🦐 gold shrimp
Result: blocked until real behavior proof from a real setup is added.

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

Rank-up moves:

  • Replace the lifetime-spend utilization meter with period-correct presentation and update its regression test.
  • [P1] Add redacted live /credits and resulting CodexBar CLI or app output to the PR body.

Proof guidance:

  • [P1] Needs real behavior proof before merge: Focused fixture tests and checks are present, but merge still needs redacted live AnyRouter /credits output and the resulting CodexBar CLI or app display; after adding it, update the PR body to trigger review or ask a maintainer to comment @clawsweeper re-review, and redact keys, account data, endpoints, and other private details.

Risk before merge

  • [P1] Existing AnyRouter users with substantial lifetime spend could see an almost-full usage meter immediately after receiving a fresh monthly balance because the numerator and denominator cover different periods.
  • [P1] The management-key authentication and response mapping have only fixture-based validation; an API-contract mismatch could leave the newly added provider unusable despite green unit tests.
  • [P1] Both AnyRouter PRs remain open, so maintainers should avoid landing divergent credential or meter semantics from the older branch.

Maintainer options:

  1. Correct the meter and prove the live flow (recommended)
    Remove or replace the cross-period utilization calculation, add its regression coverage, and provide redacted live /credits plus CodexBar output before merge.
  2. Pause the provider integration
    Keep this PR open without landing until a real AnyRouter account confirms the credential, payload, and presentation semantics.

Next step before merge

  • [P1] The contributor should correct the meter and supply account-bound proof; after that, a maintainer should select this corrected branch rather than the older AnyRouter PR.

Security
Cleared: The diff adds no dependencies, downloaded code, workflow permissions, or new secret exposure beyond the established token-account and environment-key storage paths.

Review findings

  • [P2] Do not derive utilization from lifetime spend — Tests/CodexBarTests/AnyRouterUsageFetcherTests.swift:42
Review details

Best possible solution:

Keep the scoped ak_ management-key integration, but display current balance and lifetime spend without a utilization percentage unless AnyRouter exposes a numerator and denominator for the same billing period, then confirm the result with redacted live CLI or app output.

Do we have a high-confidence way to reproduce the issue?

Yes at source level: use a snapshot with large cumulative used and a newly replenished current balance; the added formula reports near-total utilization despite fresh available credit. A live AnyRouter reproduction has not been supplied.

Is this the best way to solve the issue?

No. The provider integration follows existing architecture, but lifetime spend should not be converted into a quota percentage using a current-period balance; balance and lifetime spend should remain separate until period-matched fields exist.

Full review comments:

  • [P2] Do not derive utilization from lifetime spend — Tests/CodexBarTests/AnyRouterUsageFetcherTests.swift:42
    used is cumulative lifetime spend, while balance is currently available monthly and top-up credit. Computing used / (used + balance) therefore trends toward 100% across renewals and can show a freshly funded account as nearly exhausted; expose balance and lifetime spend separately, or use period-matched API fields for a percentage.
    Confidence: 0.96

Overall correctness: patch is incorrect
Overall confidence: 0.93

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 65e2ae6a6363.

Label changes

Label changes:

  • add rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🦐 gold shrimp.
  • remove rating: 🦪 silver shellfish: Current PR rating is rating: 🧂 unranked krab, so this older rating label is no longer current.
  • remove merge-risk: 🚨 compatibility: Current PR review merge-risk labels are merge-risk: 🚨 auth-provider.

Label justifications:

  • P2: This is a bounded new-provider integration with a concrete presentation defect and no impact on existing default-enabled providers.
  • merge-risk: 🚨 auth-provider: The PR introduces management-key handling and a new credits endpoint whose real credential and response behavior have not yet been demonstrated.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🦐 gold shrimp.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: Focused fixture tests and checks are present, but merge still needs redacted live AnyRouter /credits output and the resulting CodexBar CLI or app display; after adding it, update the PR body to trigger review or ask a maintainer to comment @clawsweeper re-review, and redact keys, account data, endpoints, and other private details.
Evidence reviewed

What I checked:

  • Credential contract corrected: The current head requests an ak_ management key with read:credits in Settings, documentation, errors, and tests, resolving the findings from earlier review cycles. (Sources/CodexBarCore/TokenAccountSupportCatalog+Data.swift:132, 7ccfc947babf)
  • Mismatched meter periods: The added test defines total credits as lifetime used plus current balance and expects utilization from that sum, although the AnyRouter contract describes used as cumulative while balance fields represent currently available credit; this diverges further after renewals. citeturn262769view0turn262769view2. (Tests/CodexBarTests/AnyRouterUsageFetcherTests.swift:42, 7ccfc947babf)
  • No real behavior proof: The PR body and follow-up comments report focused tests and make check, but provide no redacted live /credits response or resulting CodexBar CLI/app output from an AnyRouter account. (7ccfc947babf)
  • Current main does not provide AnyRouter: The supplied current-main state still lists 60 providers and contains no AnyRouter registration, so the provider capability remains genuinely additive rather than already implemented. citeturn452478view0turn452478view2. (Sources/CodexBarCore/Providers/Providers.swift:62, 65e2ae6a6363)
  • Earlier source branch is not a safe replacement: The related open PR Add AnyRouter provider #2171 still documents an inference key for the credits endpoint and also lacks real account proof; this branch contains the newer management-key corrections. (docs/anyrouter.md:14, 7ccfc947babf)
  • Repository validation policy applied: The repository requires focused tests plus make check after code changes and prohibits unrequested live account probes that might access credentials; the reported commands are supplemental, while contributor-supplied redacted runtime proof remains necessary. (AGENTS.md:255, 65e2ae6a6363)

Likely related people:

  • steipete: The change spans the central provider descriptor, registration, token-account, CLI, widget, and release surfaces, making the repository owner the strongest available routing candidate for integration semantics and landing choice. (role: repository owner and provider-framework decision owner; confidence: medium; commits: 65e2ae6a6363; files: Sources/CodexBarCore/Providers/ProviderDescriptor.swift, Sources/CodexBarCore/TokenAccountSupportCatalog+Data.swift, Sources/CodexBar/Providers/Shared/ProviderImplementationRegistry.swift)
  • willytop8: Release history associates this contributor with OpenRouter API-cost and credit-balance work, the closest established provider pattern to the proposed AnyRouter balance/spend presentation. citeturn389326view0. (role: adjacent provider-meter contributor; confidence: low; files: Sources/CodexBarCore/Providers/OpenRouter, Sources/CodexBarCore/Providers/AnyRouter/AnyRouterUsageFetcher.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.
Review history (6 earlier review cycles)
  • reviewed 2026-07-16T12:32:47.015Z sha 86b80be :: needs real behavior proof before merge. :: [P1] Align credits authentication with the current API contract
  • reviewed 2026-07-16T13:20:48.107Z sha 86b80be :: needs real behavior proof before merge. :: [P1] Align setup with the credential accepted by /credits
  • reviewed 2026-07-16T15:10:39.174Z sha 211791b :: needs real behavior proof before merge. :: [P1] Port AnyRouter to the current provider registry | [P1] Require a management key in the Settings prompt
  • reviewed 2026-07-16T16:31:41.125Z sha 211791b :: needs real behavior proof before merge. :: [P1] Require management keys in the Settings account prompt
  • reviewed 2026-07-16T18:53:52.292Z sha 7ccfc94 :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-16T19:35:44.102Z sha 7ccfc94 :: needs real behavior proof before merge. :: [P1] Port AnyRouter to the macro-generated registries | [P3] Remove the release-owned changelog entry

@joeVenner

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

Updated AnyRouter to match the current Credits API contract: management key (ak_...) with read:credits, not sk-ar-v1 inference keys. Local verification passed: swift test --filter AnyRouter; make check.

@clawsweeper

clawsweeper Bot commented Jul 16, 2026

Copy link
Copy Markdown

🦞👀
ClawSweeper picked this up.

Command router queued. I will update this comment with the next step.

@joeVenner

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

The previous review placeholder for 211791b appears stale after its lease expired. The PR body now reflects the management-key credential contract and local verification: swift test --filter AnyRouter; make check. Please re-review current head.

@clawsweeper

clawsweeper Bot commented Jul 16, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@joeVenner

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

Retrying because the previous re-review for 211791b is still marked Interrupted and the durable retry has not started. CI is clean; PR body includes the management-key credential fix and verification. Please re-review current head.

@joeVenner

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

The active review placeholder for 211791b expired without a verdict. CI is clean and the PR body includes the AnyRouter management-key credential fix plus make check verification. Please re-review current head.

@joeVenner

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

The review placeholder for 211791b expired again without a verdict. CI is clean and the PR body includes the AnyRouter management-key credential fix plus make check verification. Please re-review current head.

@joeVenner

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

Addressed the remaining AnyRouter Settings prompt finding at 7ccfc94: token-account copy now asks for an ak_ management key with read:credits, and a regression test covers the title/subtitle/placeholder/env injection. Local verification passed: swift test --filter AnyRouter; make check.

@clawsweeper

clawsweeper Bot commented Jul 16, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. labels Jul 16, 2026
@steipete

Copy link
Copy Markdown
Owner

Thanks for the work here — the integration code itself is clean (single read-only endpoint, HTTPS-validated override, tests), and that's appreciated.

That said, I'm declining AnyRouter as a tracked provider for now. Shipping a provider in CodexBar is an implicit endorsement, so for aggregator/relay services I hold a higher bar than code quality:

  1. Identifiable operator. AnyRouter's own Terms currently say governing law is "the jurisdiction in which AnyRouter's operator is established," with no named entity. I can't point users at a service whose operator I can't identify.
  2. Clearly authorized upstream access. The service's model — pooled/donated provider keys and subscriptions with auto-failover, with compliance responsibility placed on key donors per its Terms — sits in tension with the account-sharing and resale provisions of the upstream providers' terms. If there are reseller or API agreements in place that make this authorized, I'd genuinely like to see that stated publicly.
  3. Track record. The service is very new. Users tracking quota through CodexBar get burned when a provider disappears or gets cut off upstream.

Happy to revisit once there's a named operator, clarity on upstream authorization, and some operating history. None of this is a judgment on your contribution — if the service matures, this PR would be a good starting point.

@steipete steipete closed this Jul 17, 2026
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. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants