Skip to content

feat: add DeepSeek status bar usage provider - #12873

Open
innocarpe wants to merge 1 commit into
stablyai:mainfrom
innocarpe:fix/deepseek-status-bar-usage
Open

innocarpe wants to merge 1 commit into
stablyai:mainfrom
innocarpe:fix/deepseek-status-bar-usage

Conversation

@innocarpe

@innocarpe innocarpe commented Aug 6, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Show DeepSeek prepaid balance in the status bar when DEEPSEEK_API_KEY is set.

Fetches GET https://api.deepseek.com/user/balance (Bearer key), prefers the USD balance row, and maps remaining credit into the existing rate-limit / usage pipeline (provider: 'deepseek', monthly window + balance text).

Screenshots

No visual change beyond a new optional status-bar usage chip when a DeepSeek API key is configured (same roster/tooltip chrome as other providers). A dedicated monogram “DS” icon is used; no new layout surfaces.

Focused fix

Issue #12869 lists three contribution slices. This PR lands types + fetcher + status-bar wiring with env-only auth so usage is useful without shipping a full Accounts surface in the same review. Accounts UI will be a separate focused PR after this lands (tracked on #12869).

Preserves

  • Existing provider poll cadence, activation retry, and stale-data policy for other providers
  • No new secret store or IPC auth surface in v1 (reads process env only; key never written by Orca)

Testing

  • Focused vitest: deepseek-fetcher, service, status-bar-provider-visibility, appearance search, ui migration, usage-error-copy, settings-target, agent-gating (292 passed on pre-push set; rebased onto latest upstream/main)
  • pnpm lint — not re-run full-tree this pass (no product code change in this follow-up; body-only + rebase)
  • pnpm typecheck — same
  • pnpm build — CI package job
  • Added high-quality fetcher + visibility regression tests (no key → unavailable; USD prefer; 401/parse/network errors)

Evidence

pnpm exec vitest run --config config/vitest.config.ts \
  src/main/rate-limits/deepseek-fetcher.test.ts \
  src/main/rate-limits/service.test.ts \
  src/renderer/src/components/status-bar/status-bar-provider-visibility.test.ts
Condition Status bar
No DEEPSEEK_API_KEY Hidden (unavailable, deepseekAuthConfigured: false)
Key set, OK balance Monthly meter + balance text (e.g. USD 110.00)
Key set, HTTP/network fail Visible error (stale policy keeps last good)

AI Review Report

Reviewed with an AI coding agent (Grok Build) against the Orca merge playbook (focused fix / preserves intent / regression coverage).

Main risks checked:

  • Cross-platform (macOS / Linux / Windows): fetcher uses Electron net.fetch + process.env.DEEPSEEK_API_KEY only — no path separators, no shell quoting, no keyboard accelerators. Status-bar UI reuses existing roster chrome (no new shortcuts/labels that differ by platform).
  • SSH / remote: usage fetch runs in the desktop main process against the public DeepSeek API; no remote PATH or host-specific credential files in v1.
  • Secrets: key is read from env for outbound Authorization header only; not logged; not persisted by this PR.
  • Scope: no Reasonix agent registration; no drive-by provider refactors.

Flagged / resolved during authoring:

  • Balance is prepaid remaining credit, not a rolling % quota → document tradeoff; map to monthly window with 0%/100% used + amount in resetDescription so hasUsageData works without inventing fake session/weekly limits.
  • Accounts UI deferred deliberately for reviewability (issue suggested slices).

Security Audit

  • Input handling: no new user-controlled command strings; balance JSON parsed with type guards.
  • Command execution: none.
  • Path handling: none for credentials (env only).
  • Auth / secrets: Bearer token from env; 401/403 → stale-token failure kind without echoing the key.
  • Dependencies / IPC: no new deps; rate-limit state only extends existing snapshot shape (mobile/web schemas updated in lockstep).
  • Follow-up: Accounts UI must use the same desktop-safe secret patterns as other providers (not plain settings JSON) when implemented.

Notes

  • Linked-issue gap (Accounts UI): intentional v1 deferral. Issue [Feature]: DeepSeek usage in the status bar (rate-limit / usage provider) #12869 proposed multi-PR slices; this PR is slice 1+3 with env auth. Please treat Accounts UI as a follow-up, not a blocker for landing the provider pipeline.
  • Docstring coverage warning: project style (AGENTS.md) prefers concise why comments only when non-obvious — not JSDoc on every function. The new fetcher has a short module/export doc for the balance mapping; bulk docstrings would fight repo conventions.
  • Prepaid balance UX: meter shows 0% used with credit left and 100% when depleted/unavailable; currency amount is in the window description / provenance.

Fixes #12869
Refs #12200

@coderabbitai

coderabbitai Bot commented Aug 6, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
Walkthrough

The change adds DeepSeek prepaid-balance fetching and integrates its results into rate-limit state and refresh handling. It adds DeepSeek visibility, fetching-state behavior, and provider presentation to the status bar. It also adds status-bar controls, search metadata, localization, default-item migration, and shared type updates. Tests cover fetcher responses, service refresh behavior, provider visibility, and persisted UI migration.

Merge Risk: High · previous review 92f3a

As written, the change breaks the rate-limit service module and fails typechecking, so the app cannot build or run correctly. Once those errors are fixed, the DeepSeek status-bar item shows a 0% or 100% monthly meter rather than the prepaid balance it is meant to display. Fix the syntax error and the provider map, and render the balance, before merging.

Security architecture risk: Moderate · up to 64bd3

A configured DeepSeek key now triggers an external balance request and makes balance information available in the usage interface. The request’s redirect protection is not established, and a balance result is not tied to the key that initiated it. No credential disclosure has been verified.

Retained concerns

  • Medium · security · observed: The new Bearer-authenticated request leaves redirect handling implicit. Cross-origin credential forwarding is not established, so this is a transport-control uncertainty, not a verified disclosure.
  • Low · security · inferred: If the process key is changed or removed during an in-flight request, the old balance can be applied without checking that it belongs to the current credential. Runtime key rotation is not established for this env-only release.
Security review details

Security Blast Radius

  • inferred — Credential exposure is bounded in the reviewed path to a desktop process with DEEPSEEK_API_KEY configured and its outbound provider request. Balance and error results enter shared UI state; the mobile schema accepts the identifier, but automatic mobile transmission of this balance was not established.

Security Findings and Attack Paths

  • observed — No verified Security finding is retained for this PR. The credential-disclosure candidate remains deferred because the available evidence does not determine cross-origin redirect handling; it must not be read as a demonstrated leak.

Trust Boundaries and Controls

  • observed — The main process reads the environment key and sends it to a fixed HTTPS provider URL with a timeout and optional cancellation signal. The code supplies no explicit redirect-destination control.

Resilience and Maintainability Implications

  • inferred — Cycle serialization and abort checks limit competing writes, but they do not bind a completed DeepSeek result to the credential currently in the environment. A subsequent completed no-key cycle returns unavailable and clears the prior balance.

Hardening Proposals

  • proposed — Establish the pinned Electron version’s cross-origin redirect behavior and explicitly constrain redirect destinations if Bearer headers can survive such a redirect. If live key changes are supported, associate results with a credential generation before applying them; avoid forwarding raw transport error text until its contents are characterized.
Pre-merge checks: Passed 5

Check name Status Explanation
Title check Passed The title clearly and concisely identifies the main change: adding DeepSeek status-bar usage support.
Description check Passed The description provides detailed scope, rationale, linked issue, implementation details, testing evidence, security considerations, and deferred work. It uses headings that differ from the repository…
Docstring Coverage Passed Docstring coverage is inconclusive: files from earlier reviews still need to be rechecked within the check's analysis limits. Not blocking.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Description check

Explanation

The description provides detailed scope, rationale, linked issue, implementation details, testing evidence, security considerations, and deferred work. It uses headings that differ from the repository template and does not include actual before/after visual proof, but it is sufficiently complete and relevant.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@innocarpe

Copy link
Copy Markdown
Contributor Author

Addressing CodeRabbit pre-merge check warnings:

  1. Description check — PR body rewritten to the full template (Summary, Screenshots, Testing, AI Review Report, Security Audit, Notes), plus merge-playbook Focused fix / Preserves / Evidence.

  2. Linked Issues / Accounts UI — intentional v1 deferral, not an accidental miss. Issue [Feature]: DeepSeek usage in the status bar (rate-limit / usage provider) #12869 suggested multi-slice PRs; this PR lands types + fetcher + status-bar wiring with env-only DEEPSEEK_API_KEY. Desktop-safe credential storage + Accounts UI will be a separate focused follow-up on the same issue after this lands (keeping the review surface small).

  3. Docstring coverage — non-actionable against Orca AGENTS.md (concise why comments only when non-obvious). The fetcher documents the balance→monthly mapping; bulk JSDoc would fight repo conventions.

Also rebased onto latest upstream/main after the review; focused vitest still green (deepseek-fetcher + service + provider-visibility).

@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

jasonyuezhang pushed a commit to jasonyuezhang/orca that referenced this pull request Aug 11, 2026
…es after deepseek merge

Merging stablyai#12873 pushed appearance-status-bar-search.ts and client-ui-schemas.ts
past the 300-line cap. Extract the Gemini toggle entry to its own file (matching
the antigravity/grok/deepseek pattern) and derive the StatusBarItem zod enum from
a new shared STATUS_BAR_ITEMS const, removing a drift-prone hand-copied union.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
jasonyuezhang pushed a commit to jasonyuezhang/orca that referenced this pull request Aug 11, 2026
…es after deepseek merge

Merging stablyai#12873 pushed appearance-status-bar-search.ts and client-ui-schemas.ts
past the 300-line cap. Extract the Gemini toggle entry to its own file (matching
the antigravity/grok/deepseek pattern) and derive the StatusBarItem zod enum from
a new shared STATUS_BAR_ITEMS const, removing a drift-prone hand-copied union.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
jasonyuezhang pushed a commit to jasonyuezhang/orca that referenced this pull request Aug 11, 2026
…es after deepseek merge

Merging stablyai#12873 pushed appearance-status-bar-search.ts and client-ui-schemas.ts
past the 300-line cap. Extract the Gemini toggle entry to its own file (matching
the antigravity/grok/deepseek pattern) and derive the StatusBarItem zod enum from
a new shared STATUS_BAR_ITEMS const, removing a drift-prone hand-copied union.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@nwparker nwparker removed the P2 label Aug 19, 2026
@nwparker

Copy link
Copy Markdown
Contributor

Heads-up: first-class DeepSeek Harness support is up for review in #22468, with an installable test build at v1.4.210-adhoc (macOS signed/notarized, Windows unsigned — SmartScreen warns once).

You can test it now and give any feedback. Once we get feedback that it works, we'll release to stable.

It covers detect/launch, status, question state, resume, orchestration and headless Source Control AI, routed through DeepSeek's own @deepseek-ai/dsh-hooks-claude-code bridge. Full instructions and the two known gaps are on the tracking issue: #14323 (comment)

Since you worked on this area, your read on whether it matches what you needed would be especially useful — including if it conflicts with or supersedes what you have here.

@innocarpe

innocarpe commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor Author

Thanks for the heads-up. #22468 does not supersede this PR.

#22468 is the DeepSeek Harness agent: detect, launch, hooks, resume, orchestration, and headless Source Control AI. This PR is only the status-bar usage provider. It fetches DeepSeek rate-limit usage and shows it in the status bar (src/main/rate-limits/deepseek-fetcher.ts and the status-bar provider wiring). Those files are not in #22468, so the two changes do not overlap.

I have since run the v1.4.210-adhoc build beside the installed app, with a temporary DSH home and stock dsh-tui 0.11.0 so the session used DEEPSEEK_API_KEY rather than an OpenRouter profile.

  • worktree create --agent dsh launched DeepSeek Harness. The tab title showed the whale mark, and the TUI reported deepseek-flash.
  • ask_user_question marked the pane waiting, and answering it produced a normal reply.
  • Closing the tab and running dsh-tui --resume <id> restored that session.

Not covered: SSH, Windows, headless Source Control AI, and this usage-provider PR itself. terminal wait --for tui-idle still timed out while the composer was ready, and the send receipt reported delivery as unsupported for this provider.

I am leaving this usage PR open unless you would rather fold quota display into the harness work.

@innocarpe

Copy link
Copy Markdown
Contributor Author

Sync update (64bd377c17)

Rebased onto current main. The rate-limit service is split now, so DeepSeek is wired through that provider cycle (service-full-cycle-preparation.ts / service-full-cycle-application.ts) instead of the old monolithic service.ts.

This is still only the status-bar usage provider: DEEPSEEK_API_KEY balance from GET /user/balance, mapped into the monthly slot. Accounts UI and desktop credential storage stay out of this PR. None of these files are in #22468, so that harness change does not supersede this one.

Preserves: the existing poll and stale-snapshot policy. A thrown balance refresh keeps the last balance and reports the error, and a missing key stays unavailable.

nwparker added a commit that referenced this pull request Oct 2, 2026
Store write-only API-key entries in protected execution-host storage and poll the documented balance endpoint through the existing account usage service.
Display each currency's exact monetary strings in Accounts and the status bar, with explicit unsupported hosts and stale errors.

Builds on the DeepSeek balance and mobile account work in #12873 and #23294.

Co-authored-by: Wooseong Kim <innocarpe@gmail.com>
@innocarpe
innocarpe force-pushed the fix/deepseek-status-bar-usage branch from 64bd377 to 92f3a14 Compare October 29, 2026 09:58
@greptile-apps

greptile-apps Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 4/5

[Medium impact] Adds DeepSeek provider to rate-limit monitoring and status bar.

The PR should not merge until the status bar actually renders the DeepSeek prepaid amount instead of only a synthetic monthly percentage.

Findings

  1. P1 Balance amount is never rendered ▶

Summary

The PR adds environment-authenticated DeepSeek balance polling and wires the resulting provider state through desktop/mobile contracts, polling, persistence, settings, and status-bar UI.

  • Adds a DeepSeek balance fetcher using DEEPSEEK_API_KEY.
  • Extends rate-limit service state and stale-result handling for DeepSeek.
  • Adds status-bar visibility controls, defaults, iconography, search metadata, and tests.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  E[DEEPSEEK_API_KEY] --> F[DeepSeek balance fetcher]
  F --> M[Synthetic monthly window]
  M --> S[Rate-limit service state]
  S --> R[Renderer status-bar controller]
  R --> C[Usage chip]
  R --> T[Provider tooltip]
Loading

Reviews (1) · Last reviewed commit: "feat: add DeepSeek status bar usage prov..." · Reviewed by Greptile

Comment on lines +87 to +93
const usedPercent = isAvailable && totalBalance > 0 ? 0 : 100
return {
usedPercent,
windowMinutes: MONTHLY_WINDOW_MINUTES,
resetsAt: null,
resetDescription: balanceLabel
}

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 Balance amount is never rendered

When DeepSeek returns a valid positive balance, this mapping stores the amount only in resetDescription and emits a synthetic 0% monthly window, but the status-bar chip and tooltip never render resetDescription, causing values such as USD 110.00 to appear only as “Monthly 0% used.”

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3


Review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 74c42b3e-0b35-43f4-b35d-0385be63f4e1
Commits

Reviewing files that changed from the base of the PR and between 64bd377 and 92f3a14.

Files selected for processing: 37
  • mobile/src/components/accounts-snapshot.ts
  • src/main/rate-limits/rate-limit-service-test-harness.ts
  • src/main/rate-limits/service-account-target-selection.test.ts
  • src/main/rate-limits/service-antigravity-usage.test.ts
  • src/main/rate-limits/service-cursor-usage.test.ts
  • src/main/rate-limits/service-deepseek-usage.test.ts
  • src/main/rate-limits/service-inactive-account-previews.test.ts
  • src/main/rate-limits/service-live-claude-usage.test.ts
  • src/main/rate-limits/service-minimax-usage.test.ts
  • src/main/rate-limits/service-refresh-orchestration.test.ts
  • src/main/rate-limits/service-window-activation.test.ts
  • src/main/rate-limits/service/service-configuration.ts
  • src/main/rate-limits/service/service-full-cycle-application.ts
  • src/main/rate-limits/service/service-full-cycle-preparation.ts
  • src/main/rate-limits/service/service-polling.ts
  • src/main/rate-limits/service/service-state.ts
  • src/main/rate-limits/service/service-types.ts
  • src/renderer/src/components/settings/appearance-status-bar-search.ts
  • src/renderer/src/components/status-bar/StatusBarProviderSegment.tsx
  • src/renderer/src/components/status-bar/StatusBarVisibilityMenu.tsx
  • src/renderer/src/components/status-bar/icons.tsx
  • src/renderer/src/components/status-bar/status-bar-provider-visibility.test.ts
  • src/renderer/src/components/status-bar/status-bar-provider-visibility.ts
  • src/renderer/src/components/status-bar/tooltip.tsx
  • src/renderer/src/components/status-bar/usage-error-copy.test.ts
  • src/renderer/src/components/status-bar/usage-error-copy.ts
  • src/renderer/src/components/status-bar/usage-provider-settings-target.ts
  • src/renderer/src/components/status-bar/use-status-bar-controller.ts
  • src/renderer/src/i18n/locales/en.json
  • src/renderer/src/store/slices/ui-hydration-workspace-preferences.test.ts
  • src/renderer/src/store/slices/ui/ui-slice-hydration-status-bar-items.ts
  • src/shared/persisted-ui-state-types.ts
  • src/shared/rate-limit-state-factory.ts
  • src/shared/rate-limit-types.ts
  • src/shared/rpc-contract/client-ui-params.ts
  • src/shared/status-bar-defaults.ts
  • src/shared/ui-chrome-types.ts
Files skipped from review as they are similar to previous changes: 1
  • src/renderer/src/i18n/locales/en.json

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 2 remain after this review.

import { fetchAntigravityRateLimits } from '../antigravity-usage-fetcher'
import { antigravityUsageDisabledSnapshot } from '../antigravity-usage-snapshot'
import { ZCODE_PLAN_SITE_BASE_URLS } from '../../../shared/zcode-plan-sites'
import { ZCODE_PLAN_SITE_BASE_URLS } from '../../../shared/zcode-plan-sites',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Critical · Functional Correctness · Quick win

Remove the comma after the import.

The comma after '../../../shared/zcode-plan-sites' is invalid import syntax. It prevents this service module from parsing, so the affected build and tests cannot run. (raw.githubusercontent.com)

Proposed fix
--- "a/src/main/rate-limits/service/service-full-cycle-preparation.ts"
+++ "b/src/main/rate-limits/service/service-full-cycle-preparation.ts"
@@ -8,7 +8,7 @@
 import { fetchZcodeRateLimits } from '../zcode-usage-fetcher'
 import { fetchAntigravityRateLimits } from '../antigravity-usage-fetcher'
 import { antigravityUsageDisabledSnapshot } from '../antigravity-usage-snapshot'
-import { ZCODE_PLAN_SITE_BASE_URLS } from '../../../shared/zcode-plan-sites',
+import { ZCODE_PLAN_SITE_BASE_URLS } from '../../../shared/zcode-plan-sites'
 import { fetchDeepSeekRateLimits, isDeepSeekAuthConfigured } from '../deepseek-fetcher'
 import { fetchMiniMaxRateLimits } from '../minimax/minimax-fetcher'
 import { createHash } from 'node:crypto'
Committable suggestion

IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { ZCODE_PLAN_SITE_BASE_URLS } from '../../../shared/zcode-plan-sites',
import { ZCODE_PLAN_SITE_BASE_URLS } from '../../../shared/zcode-plan-sites'
Tools
Biome (2.5.15)

[error] 11-11: Expected a semicolon or an implicit semicolon after a statement, but found none

(parse)

Source: Linters/SAST tools

showCursor ? visibleCursor : null,
showZcode ? visibleZcode : null
showZcode ? visibleZcode : null,
showDeepSeek ? visibleDeepSeek : null

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Major · Functional Correctness · Heavy lift

Supported by static analysis

Script executed:

cat src/main/rate-limits/deepseek-fetcher.ts
rg -n 'resetDescription' src/renderer/src/components/status-bar

Repository: stablyai/orca

Length of output: 16220


Script executed:

# Check whether authProvenance (which carries the balance text) is read by any renderer or shared code.
rg -n -F 'authProvenance' src/renderer src/shared || test "$?" -eq 1
# Check for any non-test status-bar source that mentions balance text.
rg -n -i -F 'balance' src/renderer/src/components/status-bar --glob '!*.test.*' || test "$?" -eq 1
# Check how the monthly window is rendered in non-test status-bar sources.
rg -n -F 'monthly' src/renderer/src/components/status-bar --glob '!*.test.*' || test "$?" -eq 1

Repository: stablyai/orca

Length of output: 9731


Script executed:

# Find every non-test renderer or shared source that reads resetDescription. The status-bar grep earlier did not cover formatter modules outside that directory.
rg -n -F 'resetDescription' src/renderer src/shared --glob '!*.test.*' || test "$?" -eq 1
# Locate the definition of the chip-label formatter used by the monthly chip and inline usage.
rg -n -F 'formatRateLimitWindowChipLabel' src/renderer src/shared --glob '!*.test.*' || test "$?" -eq 1

Repository: stablyai/orca

Length of output: 3982


Show the DeepSeek balance amount in the status bar.

A successful balance response reaches the status bar only as a monthly usage window. mapBalanceWindow sets usedPercent to 0 when is_available is true and total_balance is positive. Otherwise it sets usedPercent to 100. It stores the balance label, for example USD 110.00, in resetDescription. The status-bar renderers do not read resetDescription, and they do not read authProvenance for DeepSeek. The chip, roster, and tooltip therefore show only the usage percentage and window label. A balance of USD 110.00 appears as a 0% monthly chip, not as prepaid credit.

Add a field that carries the balance amount to the renderers. The status bar already renders extraUsage balances in provider-extra-usage-section.tsx and StatusBarProviderSegment.tsx. Setting that field from the fetcher may reuse the existing display. Confirm its activation rules before relying on it. Otherwise, add a dedicated field to ProviderRateLimits in src/shared/rate-limit-types.ts, and render it in the DeepSeek chip, roster, and tooltip. This change spans the fetcher, the shared type, and several status-bar components, so it is not a localized edit.

cursor: ProviderRateLimits | null
zcode: ProviderRateLimits | null
/** Cookie is stored outside GlobalSettings; this durable flag keeps MiniMax visible across reloads/snapshot refreshes. */
deepseek: ProviderRateLimits | null

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Major · Functional Correctness · Quick win

Supported by static analysis

Script executed:

cat src/renderer/src/components/status-bar/owner-usage-rate-limits.ts
rg -n 'UsageProviderKey|USAGE_PROVIDER_IDS' src

Repository: stablyai/orca

Length of output: 12057


Add the DeepSeek entry to the remote-owner provider map.

UsageProviderKey includes every RateLimitState field whose type is ProviderRateLimits | null. The new deepseek field matches that rule, so USAGE_PROVIDER_IDS must include it. Without the entry, the Record fails typechecking. mapProviders also iterates only the keys in that map. DeepSeek therefore never gets remote-owner placeholder handling or unverifiable-owner stamping.

Suggested fix

In src/renderer/src/components/status-bar/owner-usage-rate-limits.ts:

-  zcode: 'zcode'
+  zcode: 'zcode',
+  deepseek: 'deepseek'
 }

Older hosts omit deepseekAuthConfigured. The other *Configured flags in adoptRemoteRateLimits normalize missing values with === true. Add the DeepSeek flag to that list:

     zcodePlanApiKeyConfigured: partial.zcodePlanApiKeyConfigured === true,
+    deepseekAuthConfigured: partial.deepseekAuthConfigured === true,

@innocarpe
innocarpe force-pushed the fix/deepseek-status-bar-usage branch from 92f3a14 to a052fde Compare November 2, 2026 08:51
Map DEEPSEEK_API_KEY balance (GET /user/balance) into the status-bar
rate-limit pipeline so prepaid credit is visible alongside other providers.

Preserves: existing provider poll/stale policy and agent gating contracts.
Evidence: vitest deepseek-fetcher + provider-visibility + service suites.

Refs stablyai#12869
@innocarpe
innocarpe force-pushed the fix/deepseek-status-bar-usage branch from a052fde to 6eb3b58 Compare November 10, 2026 13:59
@innocarpe

Copy link
Copy Markdown
Contributor Author

Sync update (6eb3b58e6f)

Rebased onto current main. DeepSeek prepaid balance still comes from DEEPSEEK_API_KEY through GET /user/balance and now sits beside Muse in the rate-limit service, status-bar visibility, and default-on hydration. The mobile snapshot keeps the open string provider schema, and the DeepSeek display name lives in the shared provider map. Deleted test suites stay deleted; the DeepSeek assertions sit next to the current modules.

This branch has not been deployed

No deployments
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.

[Feature]: DeepSeek usage in the status bar (rate-limit / usage provider)

4 participants