Skip to content

Add ai& spend provider#2256

Merged
steipete merged 4 commits into
steipete:mainfrom
jethac:feat/aiand-provider
Jul 17, 2026
Merged

Add ai& spend provider#2256
steipete merged 4 commits into
steipete:mainfrom
jethac:feat/aiand-provider

Conversation

@jethac

@jethac jethac commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Adds ai& (aiand.com) as a spend-only provider.

Why this provider fits CodexBar

ai& is an OpenAI/Anthropic-compatible inference gateway that positions itself as a backend for coding agents — its docs ship dedicated integration guides for Claude Code, Codex CLI, and opencode. Measured against the provider bar articulated in #1997 and #1367:

  • Documented usage contractGET https://api.aiand.com/analytics/summary?range=30days is a public, documented endpoint (docs) described as the billing-grade aggregate. No scraping, no undocumented endpoints.
  • Safe credential boundary — static org-scoped sk- API key, sent only as an Authorization: Bearer header (asserted in tests). No cookies, no JWT/session import, no browser access. Key stored via the standard CodexBar config-file / AIAND_API_KEY path.
  • Descriptor-driven, zero bespoke UI — mirrors the ZenMux structure file-for-file; renders through the existing generic API-spend card.
  • Fixture-based testsProviderHTTPTransportStub throughout; no live calls in the suite.

What it shows

Last-30-days organization spend, in the organization's own billing currency (ai& bills in USD or JPY per org). Spend is summed from the documented request-log endpoint (GET /logs) with dual-cursor pagination and Decimal money arithmetic, because — as live testing with a funded account revealed — the /analytics/summary endpoint's documented cost_usd field does not exist in the live API, and /analytics/metrics has no cost series either; /logs matches its documentation exactly and is the only public source of cost. The fetch is capped at 10 pages (1,000 newest requests); if an org exceeds that, the row is labeled "Last 30 days (partial)" with downgraded data confidence — no silent truncation. A window with zero priced rows shows the provider's no-data path rather than a zero in a guessed currency, since the billing currency is only observable from the account's own log rows. ai& is prepaid with no quota windows, so no rate windows are synthesized — same rule LiteLLM applies when no budget exists. The credit balance is console-only (no public API), so it is deliberately not shown rather than guessed at.

Commits

  1. feat: add ai& spend provider — core descriptor/fetcher/settings reader, all registry + exhaustive-switch registrations, icon, AiAndProviderTests (17 tests: real-shape log fixtures with JPY as the primary currency, dual-cursor pagination, page-cap partial labeling, mixed-currency and no-currency edge cases, exact Decimal summation, bearer-only credential, 401/402/429 mapping, parse failures, registry presence).
  2. feat: render ai& spend through the shared cost card — one-line membership in the API-spend cost section (MenuCardView+Costs), icon-resource test slug, menu-card rendering test. Without the membership line a spend-only provider is silently invisible in the menu — the new test locks the rendering in.
  3. docs: document the ai& providerdocs/aiand.md (auth, data source, 120 s server-side cache caveat, org-scoped key note, troubleshooting), providers.md row + section, configuration.md, CHANGELOG.

Verification

  • CI: green directly on this PR's current head (4c2d47ec): https://github.com/steipete/CodexBar/actions/runs/29598984940 — lint, both Linux CLI builds, both macOS test shards, aggregate check, GitGuardian all pass.
  • make check clean (SwiftFormat 0 changes, SwiftLint 0 violations in 1520 files).
  • Full sharded make test: 691 selections, 58/58 groups green, 0 failures.
  • swift test --filter AiAndProviderTests: 17/17.
  • CLI proof without a key: CodexBarCLI config providers lists aiand: disabled (ai&); usage --provider aiand (and aliases ai& / ai-and) exits with the standard "No available fetch strategy" error — identical to ZenMux's no-key path.
  • Live 401 path exercised once against the real API with a throwaway fake key → the friendly "ai& rejected the API key" message.

Updates since first review

  • Rebased onto current main (only conflict: the generated Codex parser hash, regenerated via Scripts/regenerate-codex-parser-hash.sh).

  • Adopted the new curated confetti palette introduced on main: the deprecated 3-arg ProviderBranding init's [color, color] fallback fails ProviderRegistryTests on current main, so the descriptor now provides a 3-color palette (base 0xE25C2B, tint 0xF2A17E, dark neutral 0x33231C).

  • Addressed the review finding on the settings subtitle: now path-neutral ("Stored in CodexBar's config file") instead of naming only the legacy ~/.codexbar/config.json — new installs resolve ~/.config/codexbar/config.json. (ZenMux's subtitle has the same staleness on main; happy to fix that in a follow-up if wanted.)

  • Rebased over the Neuralwatt provider landing (Add Neuralwatt provider #2220): union-merged the shared registration lists, regenerated the vendored-parser hash, and corrected the advertised provider count to 62 — both branches had bumped it to the same "61", so git merged the count strings silently while the registry gained two providers; make check's count assertions caught it.

  • Live-key verification drove a fetcher rework (2026-07-18): the documented /analytics/summary cost_usd field turned out not to exist in the live API, so spend now comes from the documented /logs endpoint (per-request decimal cost + per-org currency). See the live-proof comment below for the redacted transcript. docs/aiand.md records the docs-vs-API discrepancy.

Notes for review

  • Icon is an original monochrome ampersand mark (24×24, currentColor, stroke conventions matching LiteLLM/Bedrock). Happy to swap in a traced ai& brand asset if preferred.
  • Naming: & isn't a valid Swift identifier, so the slug is aiand (enum case, CLI name, config key, asset name) with ai&/ai-and as CLI aliases; the display name stays ai&.
  • A live usage transcript with a real funded key can be supplied on request (redacted).

🤖 Generated with Claude Code

@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. P3 Low-risk cleanup, docs, polish, ergonomics, or speculative feature. labels Jul 17, 2026
@clawsweeper

clawsweeper Bot commented Jul 17, 2026

Copy link
Copy Markdown

Codex review: found issues before merge. Reviewed July 17, 2026, 3:00 PM ET / 19:00 UTC.

Summary
Adds ai& as a default-disabled API-key spend provider using 30-day request-log aggregation, with shared menu/CLI integration, tests, icons, and documentation.

Reproducibility: not applicable. as a bug reproduction. The contributor nevertheless supplied a high-signal redacted terminal run against a funded ai& organization, plus an invalid-key runtime path.

Review metrics: 1 noteworthy metric.

  • Integration surface: 27 files affected; 1,086 additions and 83 deletions. The new provider touches core provider registration, UI, CLI, widget, tests, assets, and docs, so owner sponsorship matters more than a narrow fetcher-only review.

Merge readiness
Overall: 🦐 gold shrimp
Proof: 🦞 diamond lobster
Patch quality: 🦐 gold shrimp
Result: needs maintainer review before merge.

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

Rank-up moves:

  • [P2] Move ai& to the current provider registration macro path and add the focused coverage required by that path.
  • Correct the July 18, 2026 live-testing references to match the actual proof date.
  • Obtain explicit repository-owner sponsorship for permanently adding ai& to the built-in provider set.

Risk before merge

  • [P1] Merging creates a new permanent built-in provider and API-key configuration surface; repository-owner approval is needed before treating ai& as part of the supported provider set.
  • [P1] The PR body and proof comment describe the live fetcher rework as occurring on July 18, 2026, while this review date and the displayed runtime timestamps are July 17, 2026; reconcile that provenance before merge.

Maintainer options:

  1. Decide the mitigation before merge
    If the repository owner wants ai& supported in core, retain the default-disabled API-key-only design, move registration to the current macro path, and correct the future-dated narrative before merging.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge

  • [P2] The next action is owner sponsorship or rejection of the new permanent provider surface; the concrete registration repair should follow only if that direction is approved.

Maintainer decision needed

  • Question: Should ai& be accepted as a permanently supported built-in CodexBar provider rather than remaining outside the curated core provider set?
  • Rationale: The implementation is technically bounded and has real runtime evidence, but deciding which third-party providers receive permanent core support is a repository product and maintenance commitment that code review cannot infer.
  • Likely owner: steipete — The current head integration and repository-level product scope both point most strongly to steipete.
  • Options:
    • Sponsor ai& as a core provider (recommended): Approve the default-disabled API-key provider after the registration-macro repair and provenance correction.
    • Keep the core provider set narrower: Decline this provider direction and invite a future proposal only if the repository’s provider policy changes.

Security
Cleared: The diff adds no dependency, workflow, package-resolution, or broad secret-access change; its provider credential path is a bearer key directed to the fixed ai& HTTPS API.

Review findings

  • [P1] Register ai& through the provider registration macros — Sources/CodexBarCore/Providers/Providers.swift:67
Review details

Best possible solution:

If the repository owner wants ai& supported in core, retain the default-disabled API-key-only design, move registration to the current macro path, and correct the future-dated narrative before merging.

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

Not applicable as a bug reproduction. The contributor nevertheless supplied a high-signal redacted terminal run against a funded ai& organization, plus an invalid-key runtime path.

Is this the best way to solve the issue?

Unclear until product direction is confirmed. The API-key-only, default-disabled design is a narrow implementation path, but core inclusion itself needs explicit owner approval and the registration path must follow current architecture.

Full review comments:

  • [P1] Register ai& through the provider registration macros — Sources/CodexBarCore/Providers/Providers.swift:67
    The new provider is still threaded through manually maintained enum and registry surfaces rather than the current macro registration path flagged in the prior review. Move ai& onto that path so generated provider integration and exhaustive coverage remain aligned.
    Confidence: 0.9

Overall correctness: patch is incorrect
Overall confidence: 0.88

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 863241aa5a29.

Label changes

Label justifications:

  • P3: This is an optional new provider capability with a default-disabled configuration path, not an urgent regression.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦞 diamond lobster and patch quality is 🦐 gold shrimp.
  • status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (terminal): The contributor posted redacted terminal output from a funded ai& organization showing the after-fix JPY spend result and invalid-key behavior; correct the future-dated prose, but the observed runtime path itself is meaningful proof.
  • proof: sufficient: Contributor real behavior proof is sufficient. The contributor posted redacted terminal output from a funded ai& organization showing the after-fix JPY spend result and invalid-key behavior; correct the future-dated prose, but the observed runtime path itself is meaningful proof.
Evidence reviewed

What I checked:

Likely related people:

  • steipete: Authored the current head merge that integrates main into this provider branch and is the strongest available signal for both core-provider scope and current integration direction. (role: current-head integrator and likely product decision owner; confidence: high; commits: 9c4856fb6efd; files: Sources/CodexBarCore/Providers/Providers.swift, Sources/CodexBar/Providers/Shared/ProviderImplementationRegistry.swift)
  • joeVenner: The recently merged Neuralwatt provider traversed the same provider registration and UI integration surfaces, making this a useful technical routing candidate for the integration pattern. (role: recent adjacent provider contributor; confidence: medium; commits: 82f161bd1ffe; files: Sources/CodexBarCore/Providers/ProviderDescriptor.swift, Sources/CodexBar/Providers/Shared/ProviderImplementationRegistry.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 (9 earlier review cycles; latest 8 shown)
  • reviewed 2026-07-17T09:52:53.827Z sha 844afa9 :: needs real behavior proof before merge. :: [P1] Register the provider through the current macros | [P3] Use the resolved config path in the settings subtitle
  • reviewed 2026-07-17T10:06:01.636Z sha 58d55b4 :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-17T10:38:57.062Z sha 927697e :: needs real behavior proof before merge. :: [P3] Remove the release-owned changelog entry
  • reviewed 2026-07-17T11:14:49.087Z sha 927697e :: needs real behavior proof before merge. :: [P3] Remove the release-owned changelog entry
  • reviewed 2026-07-17T12:01:04.250Z sha 0cc7904 :: needs real behavior proof before merge. :: [P3] Remove the release-owned changelog entry
  • reviewed 2026-07-17T12:35:11.389Z sha 0cc7904 :: needs real behavior proof before merge. :: [P3] Remove the release-owned changelog entry
  • reviewed 2026-07-17T17:15:02.697Z sha 4c2d47e :: found issues before merge. :: [P3] Remove the release-owned changelog entry
  • reviewed 2026-07-17T17:49:41.126Z sha 4c2d47e :: found issues before merge. :: [P1] Register ai& through the current provider macros | [P3] Remove the release-owned changelog entry | [P3] Correct the future-dated API observation

@jethac
jethac marked this pull request as ready for review July 17, 2026 09:47
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. labels Jul 17, 2026
@jethac
jethac force-pushed the feat/aiand-provider branch from 844afa9 to 58d55b4 Compare July 17, 2026 10:00
@jethac
jethac force-pushed the feat/aiand-provider branch from 58d55b4 to 927697e Compare July 17, 2026 10:34
@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Jul 17, 2026
@jethac
jethac force-pushed the feat/aiand-provider branch from 927697e to 0cc7904 Compare July 17, 2026 11:57
jethac added 3 commits July 18, 2026 01:48
Sum 30-day organization spend from ai&'s documented request-log API with
an org-scoped API key (AIAND_API_KEY or ~/.codexbar/config.json), parsing
per-request cost strings as exact decimals in the org's billing currency
and following dual-cursor pagination capped at 10 pages (capped totals
are labeled partial, never silently truncated). ai& is prepaid with no
quota windows, so the snapshot carries only the cost figure and no rate
windows. Covers descriptor, fetcher, settings reader/store, registries,
widget and CLI switches, provider icon, and fixture-based tests.
Route the uncapped ai& cost snapshot through the generic API-spend menu
section (spend-only providers with limit 0 are otherwise hidden), register
the icon slug in the resource test, and cover the menu card rendering.
Add docs/aiand.md, list ai& in the provider table and sections, mention
AIAND_API_KEY in configuration docs, and record the change in the
changelog.
@jethac
jethac force-pushed the feat/aiand-provider branch from 0cc7904 to 4c2d47e Compare July 17, 2026 17:09
@jethac

jethac commented Jul 17, 2026

Copy link
Copy Markdown
Contributor Author

Live funded-account proof (redacted)

Run on 2026-07-18 against a real, funded ai& organization (billing currency JPY), key redacted, on this PR's head.

What live testing found first: the initial implementation followed the documented /analytics/summary schema (cost_usd field) and failed against the real API — the live endpoint returns only request/token counts with no cost field (nor does /analytics/metrics expose a cost series). The only documented cost source is GET /logs (per-request cost decimal string + currency). The provider was reworked accordingly: spend is summed from the request log over the 30-day window (dual-cursor pagination, 10-page cap with an honest "(partial)" label + downgraded confidence when hit), and the billing currency is taken from the account's own rows — never assumed. docs/aiand.md documents the docs-vs-API discrepancy.

$ export AIAND_API_KEY=sk-REDACTED
$ codexbar usage --provider aiand --json
[{"provider":"aiand","usage":{"dataConfidence":"exact","providerCost":{"used":1183.622885,
"currencyCode":"JPY","updatedAt":"2026-07-17T17:04:00Z","period":"Last 30 days","limit":0},
"primary":null,"secondary":null,"tertiary":null,"updatedAt":"2026-07-17T17:04:00Z"},"source":"api"}]

$ codexbar usage --provider aiand
== ai& (api) ==
Cost: 1183.6 / 0.0
$ echo $?
0

$ AIAND_API_KEY=sk-WRONG codexbar usage --provider aiand
Error: ai& rejected the API key. Create a new key at console.aiand.com and update Settings.
$ echo $?
1

The org's 391 requests over the window (4 log pages) sum to ¥1,183.62. The menu app renders this through the shared API-spend card with proper JPY formatting (locked in by a unit test asserting the Last 30 days: ¥… spend line). The plain-text Cost: 1183.6 / 0.0 line is the pre-existing generic CLI fallback shared with LiteLLM-without-budget (no currency symbol, vestigial / 0.0 limit) — left as-is for parity, flagged in "Notes for review" as a candidate follow-up.

@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. 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: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. 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 Jul 17, 2026
@steipete
steipete merged commit 35422a1 into steipete:main Jul 17, 2026
14 of 15 checks passed
@steipete

Copy link
Copy Markdown
Owner

Merged as 35422a17c4ed50b7f720d55dacfbfa0eb317d6eb.

Verification:

  • Merged current origin/main into the contributor branch without force-pushing. Resolved the changelog conflict by leaving the batch-owned 0.44.1 — Unreleased section unchanged.
  • Reviewed the complete provider diff and registration paths. CodexBar's current provider guide requires explicit core/app registries, so no registration macros were added.
  • Audited the official ai& /logs contract: bearer auth, paired after/after_id cursors, maximum page size 100, and has_more. The 10-page provider cap and missing-cursor case both surface Last 30 days (partial) with estimated confidence rather than silently claiming completeness.
  • Added/kept synthetic coverage for exact decimal summing, paired-cursor pagination, 10-page truncation, missing-cursor truncation, mixed/missing currencies, credential projection, bearer-only auth, status mapping, registry wiring, and menu rendering.
  • swift test --filter AiAndProviderTests: 19 tests passed, 0 failed.
  • make check: app locales 22/22 against 1,220 English keys; SwiftFormat 0/1,540 files; SwiftLint 0 violations in 1,539 files; parser/package/signing/docs/site-locale/repository checks passed.
  • Exact final tree autoreview (autoreview --mode commit --commit d2bf81ed3ee692f82ae40bd1298bedf95ad98be6 --stream-engine-output): clean, no accepted/actionable findings. Reviewed tree exactly matched pushed head 9c4856fb6efdc776338b406f725fdf2e30df014d.
  • Contributor funded-account live proof: Add ai& spend provider #2256 (comment) — 391 requests over 4 pages, JPY spend rendered, JSON confidence exact, and invalid-key error verified.
  • Exact-head CI green: changes, lint, Linux x64, Linux arm64, both macOS test shards, aggregate lint/build/test, and GitGuardian. Linux x64 initially hit an unrelated PlatformGatingTests flake (Claude CLI runtime skips logged out interactive fallback); the failed job rerun passed on the same head.

Thank you @jethac for the provider implementation and live funded-account proof.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P3 Low-risk cleanup, docs, polish, ergonomics, or speculative feature. 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.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants