Skip to content

Port upstream 0.67.0: Add Aixy provider (stacked on #619) - #661

Draft
Finesssee wants to merge 1 commit into
codex/port-0.65-provider-packfrom
port/micro-0.67.0-aixy
Draft

Finesssee wants to merge 1 commit into
codex/port-0.65-provider-packfrom
port/micro-0.67.0-aixy

Conversation

@Finesssee

Copy link
Copy Markdown
Collaborator

Summary

Ports the upstream CodexBar 0.67.0 Aixy provider. Aixy reads the API key's own usage and applicable budget balances from GET {base}/v1/usage (Bearer key, no cookies, redirects off).

  • Budgets are sorted hard first, then known first, then higher used percent, then id. The top two known budgets become the primary and secondary windows; every other budget becomes a named window (aixy-<id>) that keeps its known/unknown state. Overlapping budgets are never summed.
  • Detail rows show key, project, observation time, each budget (remaining / limit, spent, reserved) and 7-day requests, tokens and coverage. Attributed 7-day spend is reported as provider cost only when the response has it.
  • Strict response validation mirrors the upstream plugin (lazy amount/count validation on the selected branch); any contract violation is a generic parse error and the body is never echoed.
  • Base URL: empty means the hosted gateway (https://api.aixy-gateway.com); AIXY_BASE_URL and the new Base URL field in Settings cover self-hosted gateways. /v1 and path prefixes are accepted; HTTPS is required except for localhost, private-network and .local hosts; embedded credentials, query and fragment are rejected. The URL is validated before the credential is resolved.
  • Key from Settings, token accounts (Environment injection), or AIXY_API_KEY. Menu-bar metric is Automatic only.
  • Bug fix in the shell: build_fetch_context only passed the saved gateway URL to Wayfinder, so a saved Bifrost or Aixy Base URL never reached tray refresh. It now passes the saved URL for every provider that has one.
  • Shared is_private_network_host helper extracted from Bifrost (Bifrost now delegates to it).
  • Gateway settings section generalised to Wayfinder / Bifrost / Aixy with locale keys (five new keys, en-US).

Upstream reference

CodexBar v0.67.0, Aixy provider and AixyPluginTests.swift (the key-usage fixture is vendored verbatim at rust/src/providers/aixy/fixtures/key-usage.json). Read-only, pinned to the release tag.

Ported

  • Provider module, model, presentation, fixture-driven tests (mapping, sort order, absent/unknown/zero budgets, cross-key and invalid-currency violations, lazy validation, amount/count forms, sanitisation, URL rules, Bearer-only request, status table, non-echo of bodies, redirects not followed).
  • ProviderId::Aixy, factory arm, aliases, token account config, API key config, dashboard link, icon, brand color, usage source policy, catalog entries, docs.

Deferred

  • AixySettingsTests.swift was not available locally, so settings-field behaviour beyond URL validation is not mirrored.
  • Upstream sectioned details are flattened into rows with prefixed titles; upstream's 24-rows-per-chunk budget layout is a UI concern and is not reproduced.
  • Locales other than en-US fall back to English for the new keys.
  • The CLI usage command builds its FetchContext with gateway_url: None, so the CLI honours AIXY_BASE_URL only (pre-existing, shared with the other gateway providers).
  • Dates are parsed as RFC 3339 only (upstream's date helper is broader); identifier fields must be strings (stricter than upstream).

Validation

  • cargo +1.98.0 fmt --all clean
  • cargo +1.98.0 clippy --workspace --all-targets -- -D warnings clean
  • cargo test -p codexbar -- --test-threads=4: 2274 passed, 0 failed, 1 ignored
  • cargo test -p codexbar-desktop-tauri -- --test-threads=4: 490 passed, 0 failed
  • pnpm test (apps/desktop-tauri): 69 files, 413 tests passed
  • pnpm run lint: only pre-existing warnings; locale drift check OK (887 keys)
  • pnpm run build: tsc and vite build OK

Affected areas

rust/src/providers/aixy/ (new), rust/src/core/{provider,provider_factory,token_accounts}.rs, rust/src/providers/{mod,bifrost}, rust/src/settings/api_keys.rs, locale files, Tauri commands/{provider_settings,providers}.rs, gateway settings section, menu-bar metric section, provider icon/catalog, docs.

UI proof

Pending: coordinator will capture CUA proof on a fresh build (Aixy in Settings > Providers with Base URL field, tray card with budget windows).

Stacked on #619.

@coderabbitai

coderabbitai Bot commented Sep 29, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Finesssee

Copy link
Copy Markdown
Collaborator Author

CUA proof for the Aixy provider (local Windows debug build, cua-driver CLI).

Build: commit a1980aeb (PR head, detached). pnpm --dir apps/desktop-tauri run tauri:build:debug finished with exit 0.

Isolation: the exe ran with an empty CODEX_HOME, a settings root redirected to a temp folder, and a dummy AIXY_API_KEY. The redirect came from a throwaway, uncommitted one-line patch to logging::config_root that read CODEXBAR_PROOF_CONFIG_ROOT; it was reverted after the build and the worktree holds no content change. The user's real settings were not touched. Aixy was pointed at a local mock gateway (http://127.0.0.1:8765) that serves the vendored fixtures/key-usage.json at /v1/usage. This exercises the real fetch path (saved Base URL, then Bearer request, then parse, then bridge). No seeded snapshots were used.

Commands: CODEXBAR_PROOF_MODE=settings:providers and CODEXBAR_PROOF_MODE=trayPanel; cua-driver serve, then cua-driver call list_windows | get_window_state --screenshot-out-file | click | press_key | scroll.

# Assertion Result
1 Saved Base URL reaches tray refresh (shell fix in build_fetch_context): mock received GET /v1/usage from the app PASS
2 Request carries Authorization: Bearer ... (key value not logged) PASS
3 Providers list shows Aixy with api 30% and it is enabled from settings PASS
4 Detail pane shows Session 30% and Weekly 40% windows (top two budgets), plus named window Organization · Daily · Shared · Hard at 0% (unknown state) PASS
5 Detail rows: Key Developer CLI, Project Engineering, Observed 2026-09-24T12:00:00.000Z PASS
6 Budget rows: $70.00 / $100.00 remaining, Organization ... Unavailable, $60.00 / $100.00 remaining PASS
7 7-day rows: Requests 12, Tokens 1,200, Attributed spend $1.25, Cost coverage 10 / 12 requests PASS
8 Settings shows the Aixy gateway section with a Base URL edit (value http://127.0.0.1:8765), help text and Save button PASS
9 Menu bar metric section: Automatic only (not exercised beyond the section header being present); not asserted NOT CHECKED
10 Tray panel shows Aixy card: Budget 30% used, Secondary budget 40% used, same detail rows PASS
11 Dark theme kept (theme auto) in settings and tray panel PASS
12 Screenshots contain no emails or tokens PASS

Observation (cosmetic, not blocking): in the tray card the balance text and the spent/reserved secondary value are laid out on one line with no gap (remaining$20.00 spent · $10.00 reserved, remaining$40.00 spent). See 06-tray.png.

Notes: the first launch of the settings surface listed the machine's ambient Codex account, which contains a personal email. That screenshot was discarded and none of the kept screenshots contain it. Locale, CLI and non-UI paths are covered by the PR's test run, not by this proof.

Local screenshots (not committed): C:\Users\FSOS\AppData\Local\Temp\port-audit\proof\661\

  • 02-aixy-detail.png (Providers, Aixy selected)
  • 04-aixy-baseurl.png (Aixy gateway / Base URL field)
  • 05-aixy-details.png (detail rows)
  • 06-tray.png (tray panel card)
  • UIA dumps: *-uia.txt; mock request log: mock-requests.log

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant