Skip to content

Add Abacus AI provider#479

Open
ChrisGVE wants to merge 28 commits intosteipete:mainfrom
ChrisGVE:abacus.ai
Open

Add Abacus AI provider#479
ChrisGVE wants to merge 28 commits intosteipete:mainfrom
ChrisGVE:abacus.ai

Conversation

@ChrisGVE
Copy link
Copy Markdown

@ChrisGVE ChrisGVE commented Mar 4, 2026

Summary

  • Add Abacus AI as a new cookie-based provider for tracking ChatLLM/RouteLLM compute credit usage
  • Fetches credit usage from _getOrganizationComputePoints (GET) and billing cycle from _getBillingInfo (POST), both called concurrently
  • Shows monthly credit gauge with pace tick, reserve/deficit estimate, and reset date
  • Cookie auth via SweetCookieKit browser import (Safari, Chrome, etc.) with manual override option
  • Supports Basic and Pro subscription tiers

New files

  • AbacusProviderDescriptor.swift — provider metadata, branding (cyan), web-only fetch strategy
  • AbacusUsageFetcher.swift — cookie importer, API fetcher, JSON parsing
  • AbacusProviderImplementation.swift — settings UI (cookie source picker)
  • AbacusSettingsStore.swift — settings persistence
  • ProviderIcon-abacus.svg — provider icon
  • docs/abacus.md — provider documentation (setup, API details, troubleshooting)

Modified files

  • Providers.swift.abacus enum case
  • ProviderSettingsSnapshot.swiftAbacusProviderSettings
  • ProviderDescriptor.swift, ProviderImplementationRegistry.swift — registration
  • MenuCardView.swift, MenuDescriptor.swift — Abacus-specific display (pace tick, credit detail)
  • UsagePaceText.swift — enable pace calculation for Abacus
  • docs/providers.md — added Abacus AI to strategy table and detailed provider section
  • README.md — added Abacus AI to provider list
  • Exhaustive switch updates in CLI, widget, store, and scanner files

Test plan

  • Enable Abacus AI in preferences, verify cookie import from Safari
  • Verify credit values match the Abacus dashboard
  • Verify reset date matches billing cycle (nextBillingDate from API)
  • Verify pace tick and reserve/deficit text display correctly
  • Test with expired cookies — should re-import from browser
  • Run codexbar usage --provider abacusai --verbose to verify CLI output

Copy link
Copy Markdown

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

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: e316c9d4c7

ℹ️ 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".

@ChrisGVE
Copy link
Copy Markdown
Author

@steipete is there anything else do to for you to approve this PR?

@ratulsarna
Copy link
Copy Markdown
Collaborator

@codex review

Copy link
Copy Markdown

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

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: e035df3211

ℹ️ 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".

@ratulsarna
Copy link
Copy Markdown
Collaborator

@ChrisGVE Please resolve comments raised by codex.

@ChrisGVE
Copy link
Copy Markdown
Author

@codex review

ChrisGVE added 12 commits April 13, 2026 12:04
Add support for Abacus AI (ChatLLM/RouteLLM) as a new provider. Uses
browser cookie authentication against the describeUser API endpoint to
fetch compute point usage. Values are in centi-credits (divided by 100
for display). Primary window shows monthly credit usage as percentage,
secondary window shows 7-day usage. Reset date derived from lastBilledAt
+ 1 month.
- Fix credits format string (Swift String(format:) has no comma flag;
  use NumberFormatter for thousands separators)
- Remove secondary weekly window (Abacus has monthly billing only)
- Show credits detail below gauge (follow Warp/Kilo pattern for
  resetDescription rendering)
- Add pace/reserve/deficit estimate on primary monthly window
- Remove inactive status page URL (abacus.statuspage.io is inactive)
- Hide account email/org from menu (not relevant for display)
- Set windowMinutes to 30 days so pace calculation works correctly
- Show pace indicator tick (green/red) on the primary gauge bar
- Add reserve/deficit line below gauge with pace right label
- Show credits used/total as detail text below the gauge
- Restore account identity (email, org, plan tier) in card header
Switch from describeUser (stale centi-credit values, no billing date)
to _getOrganizationComputePoints (accurate credits in real units) and
_getBillingInfo (exact nextBillingDate and subscription tier). Both
endpoints are fetched concurrently.
Skip browser cookie sets that only contain anonymous/marketing cookies
by checking for session/auth cookie names before accepting a set. This
prevents using invalid cookies when a valid session exists in a later
browser profile.

Separate the cookie import and API fetch try blocks so that network,
parse, or auth errors from the API are not misreported as "Browser
cookie import failed" and incorrectly replaced with noSessionCookie.
Update three call sites that still used the removed
UsagePaceText.weeklySummary(provider:window:) and
weeklyPaceDetail(provider:window:now:showUsed:) signatures.

MenuDescriptor and MenuCardView now use the store.weeklyPace()+
UsagePaceText.weeklySummary(pace:) pattern. StatusItemController
computes weeklyPace from primary for Abacus (no secondary window).
Remove Secondary (Weekly) from the menu bar metric picker since
Abacus has no secondary window; only Automatic and Primary (Credits)
are valid options.

Enable pace computation for Abacus in weeklyPace() so the bar
tick indicator (reserve/deficit/on-pace) is rendered correctly.
Abacus uses the simple UsagePace.weekly() path with the monthly
window already set in RateWindow (30 days).
Add docs/abacus.md with setup, API details, and troubleshooting for the
Abacus AI provider. Add Abacus AI entry to docs/providers.md strategy
table and detailed section. Add Abacus AI to README provider list.
Add AbacusProviderTests.swift with 23 tests in 3 suites covering:
- AbacusDescriptorTests: provider metadata, source modes, CLI config
- AbacusUsageSnapshotTests: credit conversion, formatting, edge cases
- AbacusErrorTests: error description completeness

Uses the Swift Testing framework (@test + #expect) matching the
convention established by recent upstream provider tests.
Swift 6.2.4 does not allow let bindings inside the else
branch of an if-expression. Move the paceWindow computation
before the if-expression to fix compilation.
Replace overly broad "id" substring pattern with exact known cookie
names (sessionid, auth_token, etc.) checked first, then conservative
substring fallback. Prevents selecting unauthenticated cookie sets
from browsers that only have analytics cookies for abacus.ai.
settingsFields was returning empty array, making Manual cookie mode
non-functional. Add secure text field bound to abacusCookieHeader,
visible only when cookie source is set to manual, with link to open
the Abacus AI dashboard.
Copy link
Copy Markdown

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

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: a69e6d6311

ℹ️ 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".

Use codexBarRecords instead of records directly so the access gate
cooldown is consulted before attempting Chromium keychain reads.
Also detect session-expired API error payloads and map them to
.sessionExpired so cached cookies are properly evicted.
Clear primaryResetText when resetsAt is nil to prevent displaying
a misleading "Resets ..." line that duplicates the credit detail.
@ChrisGVE
Copy link
Copy Markdown
Author

@codex review

Copy link
Copy Markdown

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

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: 9020793556

ℹ️ 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".

… errors

Remove csrftoken/csrf_token from knownSessionCookieNames — CSRF
tokens exist in anonymous jars and caused false-positive session
detection. Also replace try? on billing fetch with explicit error
handling that propagates auth errors while tolerating other failures.
@ChrisGVE
Copy link
Copy Markdown
Author

@codex review

Copy link
Copy Markdown

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

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: d29f5ddc6b

ℹ️ 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".

Remove "token" from fallback substrings (matched csrftoken). Add
excludedCookiePrefixes to reject csrf/analytics cookies even on
substring match. Change importSession to importSessions returning
all candidates so fetchUsage can try each in turn — stale session
in first source no longer blocks valid ones further down.
Copy link
Copy Markdown

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

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: b385e4d64a

ℹ️ 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".

Require both totalComputePoints and computePointsLeft in API
response — partial data no longer silently shows 0% usage.

Fall back to primary window for menu bar pace calculation when
secondary is nil, so Abacus pace renders in Pace/Both display
modes.
@ChrisGVE
Copy link
Copy Markdown
Author

@codex review

Copy link
Copy Markdown

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

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: f7e86a5b9a

ℹ️ 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".

The supportsWeeklyPace guard was too broad — it applied to all
pace-capable providers, causing Claude's 5-hour primary window
to be misused for pace calculation. Scope the fallback to .abacus
which is the only provider using primary window for pace.
@ChrisGVE
Copy link
Copy Markdown
Author

@codex review

Copy link
Copy Markdown

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

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: 0879072f24

ℹ️ 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".

Point Open Dashboard to /chatllm/admin/compute-points-usage matching
the provider's configured dashboardURL.
@ChrisGVE
Copy link
Copy Markdown
Author

@codex review

Copy link
Copy Markdown

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

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: 8ad450f17a

ℹ️ 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".

AGENTS.md mandates Chrome-only cookie imports by default. Change
browserCookieOrder from defaultImportOrder (all browsers) to
[.chrome] to avoid unnecessary browser/keychain prompts.
Critical fixes:
- Remove .parseFailed from isRecoverable (deterministic error,
  retrying other sessions gives same result)
- Fix NumberFormatter thread safety (allocate per call instead
  of mutating shared static state)

High fixes:
- Add public init on SessionInfo (API surface parity with peers)
- Consistent self. usage throughout fetcher (was mixing Self/self)
- Make notSupported public (thrown from public function)
- Add Equatable conformance to AbacusUsageError (peer pattern)
- Simplify isAuthRelated to delegate to isRecoverable

Medium fixes:
- Add MARK sections throughout all files
- Add #if canImport(FoundationNetworking) guard (Linux compat)
- Add explanatory comment on pace fallback in StatusItemController

Tests:
- Add isRecoverable/isAuthRelated classification tests for all
  five error cases (28 tests total, 4 suites)
@ChrisGVE
Copy link
Copy Markdown
Author

@codex review

Copy link
Copy Markdown

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

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: 82b4ffec3b

ℹ️ 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".

Add unauthorized/unauthenticated/forbidden to the API error keyword
detection so JSON-level auth failures (HTTP 200 with success:false)
throw .unauthorized instead of .parseFailed. This enables the
multi-session fallthrough for stale cookies that return auth errors
in the JSON payload rather than via HTTP status codes.
@ChrisGVE
Copy link
Copy Markdown
Author

@codex review

Copy link
Copy Markdown

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

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: a87fc9419b

ℹ️ 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".

Reconcile AGENTS.md Chrome-only guideline with real-world need to
support Safari/Firefox users. Match OpenCodeCookieImporter pattern:

- Descriptor browserCookieOrder: full defaultImportOrder (all browsers)
- AbacusCookieImporter.importSessions: preferredBrowsers: [.chrome]
  default, empty array falls back to the full descriptor order
- fetchUsage: try Chrome first, broaden to all browsers if Chrome
  yields no sessions
- isAvailable: same Chrome-first then fallback probe

Users with Chrome get single-browser probe (AGENTS.md compliant);
Safari/Firefox users still get their cookies imported when Chrome
is absent or empty.
@ChrisGVE
Copy link
Copy Markdown
Author

@codex review

Copy link
Copy Markdown

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

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: 0c8324fcb7

ℹ️ 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".

Previously, the all-browsers fallback only triggered when Chrome
import threw. If Chrome cookies existed but all returned expired/
unauthorized, the loop exhausted Chrome candidates and returned an
auth error without ever trying Safari/Firefox.

Extract browser-tier logic into tryFetchFromBrowsers helper; call
it first with [.chrome], then with [] (all browsers) if Chrome
yielded no valid snapshot for any reason (import failure OR all
sessions failing with recoverable errors).
@ChrisGVE
Copy link
Copy Markdown
Author

@codex review

Copy link
Copy Markdown

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

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: 551bb24455

ℹ️ 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".

… timeout

Two issues caught by Codex review:

- AbacusSettingsStore referenced TokenAccountSupportCatalog.support(
  for: .abacus) but no catalog entry existed, so token account
  overrides were dead code. Add cookie-header injection entry
  matching the pattern used by other cookie-based providers.

- Billing info fetch shared the full 15s timeout with credits. Cap
  it at min(timeout, 5s) so a slow/flaky billing endpoint doesn't
  delay credit rendering — billing is optional anyway.
@ChrisGVE
Copy link
Copy Markdown
Author

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. What shall we delve into next?

ℹ️ 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".

@ChrisGVE
Copy link
Copy Markdown
Author

@ratulsarna I think I finally satisfied Codex :) I hope this will allow to merge this PR, otherwise do let me know

@ChrisGVE
Copy link
Copy Markdown
Author

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Chef's kiss.

ℹ️ 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".

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants