Add Venice API balance provider#865
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b14d485f73
ℹ️ 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".
| case mistral | ||
| case deepseek | ||
| case codebuff | ||
| case venice |
There was a problem hiding this comment.
Update exhaustive provider switches for Venice
Adding the .venice enum case makes every exhaustive switch UsageProvider require a Venice branch. I checked Sources/CodexBar/Providers/Shared/ProviderImplementationRegistry.swift and the widget switches in Sources/CodexBarWidget/CodexBarWidgetProvider.swift / CodexBarWidgetViews.swift; they still stop at .codebuff with no default, so the app/widget targets will fail to compile as soon as this case is introduced.
Useful? React with 👍 / 👎.
| if !self.canConsume { | ||
| balanceDetail = "Balance unavailable for API calls" | ||
| usedPercent = 100 | ||
| } else if let diem = self.diemBalance, let allocation = self.diemEpochAllocation, allocation > 0 { |
There was a problem hiding this comment.
Use the active Venice consumption currency
When the balance response contains both DIEM and USD but consumptionCurrency is USD, this branch still reports DIEM first and can show DIEM allocation progress even though Venice says API calls will consume USD. Since the API includes consumptionCurrency specifically to identify the active billing currency, users with both balances can see the wrong remaining balance in the menu bar.
Useful? React with 👍 / 👎.
|
Clean follow-up (previous comment had shell-escaped markdown issues): Addressed both review items in commit 1c7c3d2.
|
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1c7c3d25ee
ℹ️ 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".
| case mistral | ||
| case deepseek | ||
| case codebuff | ||
| case venice |
There was a problem hiding this comment.
Add Venice to remaining exhaustive provider switches
Adding a new UsageProvider case requires updating every exhaustive switch; this commit updates several call sites but leaves others, including Sources/CodexBarCLI/TokenAccountCLI.swift:81, Sources/CodexBar/UsageStore.swift:836, and Sources/CodexBarCore/Vendored/CostUsage/CostUsageScanner.swift:225, without a .venice branch or default. As soon as the app/CLI targets are built with this enum case, those switches are non-exhaustive and the package cannot compile.
Useful? React with 👍 / 👎.
|
Checked — new Codex P1 was valid. Addressed in Added
Branch is updated and pushed. |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0b5d0e901f
ℹ️ 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".
| private static func parseSnapshot(data: Data) throws -> VeniceUsageSnapshot { | ||
| let decoded: VeniceBalanceResponse | ||
| do { | ||
| decoded = try JSONDecoder().decode(VeniceBalanceResponse.self, from: data) |
There was a problem hiding this comment.
Accept string-encoded Venice balances
When Venice returns balance numbers as JSON strings, this strict decode into Double? fields fails and the provider reports parseFailed instead of showing the balance. Venice’s API docs note that numeric balance values may be returned as strings to avoid precision loss (https://docs.venice.ai/api-reference/api-spec), so the balance response should decode both numeric and string forms for balances and diemEpochAllocation.
Useful? React with 👍 / 👎.
|
Status update: a new Codex P2 landed ( Fixed in
Branch pushed and ready for re-review. |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2b506fdaf6
ℹ️ 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".
| let usdStr = String(format: "%.2f", usd) | ||
| balanceDetail = "$\(usdStr) USD remaining" | ||
| usedPercent = 0 | ||
| } else if activeCurrency == "DIEM", let diem = self.diemBalance, let allocation = self.diemEpochAllocation, allocation > 0 { |
There was a problem hiding this comment.
Handle bundled-credit DIEM allocations
For accounts where Venice returns consumptionCurrency: "BUNDLED_CREDITS" with balances.diem and diemEpochAllocation (a documented response shape), this condition is skipped because it only accepts DIEM; the code then falls through to the generic DIEM balance branch and reports usedPercent = 0 instead of the allocation progress. This makes staked/bundled-credit accounts with partial usage look completely unused in the menu bar.
Useful? React with 👍 / 👎.
|
Checked now — latest Codex P2 was valid ( Fixed in
Branch pushed. |
|
@codex review |
|
Codex Review: Didn't find any major issues. Keep it up! ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
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 Venice as first-class UsageProvider with .venice enum case - Implement VeniceSettingsReader for VENICE_API_KEY / VENICE_KEY env resolution - Implement VeniceUsageFetcher for GET /api/v1/billing/balance endpoint - Add VeniceProviderDescriptor with macro registration and API fetch strategy - Add token account support in TokenAccountSupportCatalog+Data - Add config environment injection in ProviderConfigEnvironment - Implement VeniceProviderImplementation for menu bar integration - Add VeniceSettingsReaderTests with env key resolution coverage - Add VeniceUsageFetcherTests with DIEM/USD/epoch allocation scenarios - Display honest balance (no fake quota %) - Add docs/venice.md and update README / providers documentation API: stable /api/v1/billing/balance endpoint only (no beta history endpoints) Scope: balance display with canConsume flag and optional epoch allocation Dashboard: https://venice.ai/settings/api
4abdf58 to
48f3474
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 48f34749ab
ℹ️ 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".
| Self.scheduleAppGroupMigration() | ||
| appGroupMigration = AppGroupSupport.MigrationResult(status: .targetUnavailable) | ||
| } |
There was a problem hiding this comment.
Run app-group migration before reading settings
Calling scheduleAppGroupMigration() here makes migration asynchronous, but loadDefaultsState runs immediately afterward and reads defaults before legacy app-group keys are copied. On first launch after upgrade, users who only have legacy values (e.g. debugDisableKeychainAccess / widgetSelectedProvider) will run with stale settings until a restart, because this initializer never reloads defaults after the detached task finishes.
Useful? React with 👍 / 👎.
| if try self.decodeNil(forKey: key) { | ||
| return nil | ||
| } |
There was a problem hiding this comment.
Treat omitted Venice balance fields as optional
decodeFlexibleDoubleIfPresent begins with decodeNil(forKey:), which throws keyNotFound when the key is absent, so these optional numeric fields become effectively required. If Venice omits diem, usd, or diemEpochAllocation (instead of sending explicit null), parsing fails and the provider reports parseFailed for an otherwise valid response.
Useful? React with 👍 / 👎.
steipete
left a comment
There was a problem hiding this comment.
Reviewed provider wiring, decoder behavior, token-account/env routing, Linux compatibility, and live app smoke. Local + CI green.
Add Venice API balance provider
Summary
This PR adds Venice as a first-class CodexBar provider, enabling users to monitor their Venice API balance (DIEM or USD) directly from the menu bar.
Scope: Stable balance endpoint only (
GET /api/v1/billing/balance). No beta history or usage-analytics endpoints in this PR.Changes
Core provider setup
.venicecase toUsageProviderandIconStyleenumsVeniceProviderDescriptorwith macro registration and fetch strategyVeniceSettingsReaderfor env key resolution (VENICE_API_KEY/VENICE_KEY)API integration
VeniceUsageFetcherfor/api/v1/billing/balanceendpoint with bearer auth (15s timeout)canConsume,consumptionCurrency,balances.diem,balances.usd,diemEpochAllocation"DIEM 90.50 / 100.00 epoch allocation"or"$25.00 USD remaining"or"Balance unavailable"Token & settings integration
veniceToken()andveniceResolution()toProviderTokenResolverTokenAccountSupportCatalog+Datawith environment injectionveniceUsagelog categoryProviderConfigEnvironmentfor API key injectionApp-side implementation
VeniceProviderImplementationfollowing DeepSeek pattern (available when key exists or token accounts exist)Testing
VeniceSettingsReaderTests: 10 tests covering env key resolution, quoting, trimming, and precedenceVeniceUsageFetcherTests: 19 tests covering DIEM/USD parsing, epoch allocation,canConsume=false, edge cases, and error handlingDocumentation
docs/venice.mdwith setup instructions, balance types, and troubleshootingREADME.mdto include Venice in provider listdocs/providers.mdwith Venice details and API endpoint infoImplementation notes
RateWindowwith honest remaining amounts (prefers DIEM with allocation percentage when available; USD or DIEM remaining otherwise)AGENTS.mdcontribution guidelines and existing provider patterns (DeepSeek/OpenRouter)Testing
Run locally (on macOS):
Dashboard & Setup
VENICE_API_KEY(primary),VENICE_KEY(fallback)https://api.venice.ai/api/v1/billing/balance(stable, v1)