Skip to content

feat(zai): add Z.AI support - #5354

Closed
abilliontokens wants to merge 2 commits into
stablyai:mainfrom
abilliontokens:oldschoola/zai
Closed

abilliontokens wants to merge 2 commits into
stablyai:mainfrom
abilliontokens:oldschoola/zai

Conversation

@abilliontokens

@abilliontokens abilliontokens commented Jun 14, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • add the Z.AI API-key flow in Settings → AI Provider Accounts for Anthropic-compatible usage and quota reads
  • refresh Z.AI rate limits immediately after save/clear so the bottom-left usage chip appears without waiting for the poll interval
  • wire Z.AI into the quota fetcher, status bar, preload IPC, and localization updates while removing the unused managed-account fallback plumbing

Testing

  • pnpm exec vitest run --config config/vitest.config.ts src/main/zai-api-key-store.test.ts src/main/rate-limits/zai-fetcher.test.ts src/main/rate-limits/service.test.ts src/main/ipc/register-core-handlers.test.ts src/renderer/src/components/settings/AccountsPane.test.tsx src/renderer/src/components/status-bar/tooltip.test.ts src/renderer/src/components/status-bar/status-bar-agent-gating.test.ts src/renderer/src/store/slices/ui.test.ts
  • pnpm run sync:localization-catalog
  • pnpm run verify:localization-catalog
  • pnpm run verify:localization-coverage
  • pnpm run typecheck

Notes

  • during implementation the live Z.AI callback returned an authorization code, so this PR ships the API-key path instead of describing that behavior as an Orca-owned OAuth regression
  • verified the live Z.AI quota endpoint with the provided API key: session quota returned at 100% and monthly quota at 2%
  • no API key or token material is persisted in the repository

ELI5

Adds Z.AI as an AI provider account: save an API key, see quota in the status bar, and use Anthropic-compatible Z.AI from Orca.

Replace the broken Z.AI OAuth account flow with the documented API-key fallback in settings and preload IPC.

Refresh Z.AI quota state immediately after save and clear so the bottom-left status chip appears without waiting for the poll interval.

Wire Z.AI into the shared rate-limit surfaces, status bar, and localization updates while removing the unused managed-account plumbing from the fallback branch.
@abilliontokens abilliontokens changed the title feat(zai): add API-key usage tracking feat(zai): add Z.AI support Jun 14, 2026
@coderabbitai

coderabbitai Bot commented Jun 14, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This PR integrates Z.AI as a new rate-limited provider across the full application stack. It adds 'zai' to shared type unions (StatusBarItem, ProviderRateLimits, RateLimitState), introduces an encrypted API key store (~/.orca/zai-api-key.enc) backed by electron.safeStorage, and adds a quota fetcher that maps Z.AI session/weekly/monthly windows. IPC handlers expose zaiApiKey:getStatus/save/clear routes wired through the Electron preload bridge. RateLimitService gains a setZaiApiKeyResolver method and fetches Z.AI in its polling cycle. The renderer store adds zai to the rate-limits slice and a one-shot default-on status bar migration. The status bar renders a ZaiIcon, tooltip, and usage menu when configured. AccountsPane gains a Z.AI API key section with save/clear controls, search integration, and settings metadata updates. Localization strings are added across five locales (English, Spanish, Japanese, Korean, Chinese).

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 6.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ⚠️ Warning The PR description covers summary, testing, and notes, but omits the required Screenshots, AI Review Report, and Security Audit sections from the template. Add the missing template sections, or mark Screenshots as 'No visual change' and include an AI review and security audit summary with cross-platform verification notes.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(zai): add Z.AI support' accurately describes the main change—adding Z.AI provider support. It is concise, clear, and specific enough for understanding the primary contribution without covering every detail.
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.

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.

@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: 12

🧹 Nitpick comments (3)
src/preload/index.ts (1)

1631-1635: ⚡ Quick win

Bind the new Z.AI bridge to PreloadApi['zaiApiKey'].

These methods currently return Promise<unknown>, so this file will not fail typecheck if the IPC response shape drifts from src/preload/api-types.ts. Please lock the new bridge to the declared contract here as well.

♻️ Proposed fix
-  zaiApiKey: {
-    getStatus: (): Promise<unknown> => ipcRenderer.invoke('zaiApiKey:getStatus'),
-    save: (apiKey: string): Promise<unknown> => ipcRenderer.invoke('zaiApiKey:save', apiKey),
-    clear: (): Promise<unknown> => ipcRenderer.invoke('zaiApiKey:clear')
-  },
+  zaiApiKey: {
+    getStatus: (): Promise<{ configured: boolean }> => ipcRenderer.invoke('zaiApiKey:getStatus'),
+    save: (apiKey: string): Promise<{ configured: boolean }> =>
+      ipcRenderer.invoke('zaiApiKey:save', apiKey),
+    clear: (): Promise<{ configured: boolean }> => ipcRenderer.invoke('zaiApiKey:clear')
+  } satisfies PreloadApi['zaiApiKey'],
src/renderer/src/web/web-preload-api.ts (1)

2249-2255: ⚡ Quick win

Document why the web Z.AI bridge always reports configured: false.

This stub is intentionally non-obvious; a short why-comment here would keep the next caller from treating it like a broken implementation instead of a browser-only limitation.

Suggested comment
 function createZaiApiKeyApi(): NonNullable<Partial<PreloadApi>['zaiApiKey']> {
+  // Why: paired web clients cannot access the desktop-local encrypted key
+  // store, so Z.AI API-key management stays unavailable in the browser adapter.
   return {
     getStatus: () => Promise.resolve({ configured: false }),
     save: () => Promise.resolve({ configured: false }),
     clear: () => Promise.resolve({ configured: false })
   }
 }

As per coding guidelines, **/*.{ts,tsx,js,jsx}: "When writing or modifying code driven by a design doc or non-obvious constraint, add a comment explaining why the code behaves the way it does."

Source: Coding guidelines

src/renderer/src/components/settings/AccountsPane.tsx (1)

1217-1221: ⚡ Quick win

Add a short “why” comment for Z.AI keyword flattening.

This flattening is non-obvious and mirrors the Codex search behavior; a 1–2 line rationale here will prevent accidental regressions.

As per coding guidelines, “When writing or modifying code driven by a design doc or non-obvious constraint, add a comment explaining why the code behaves the way it does.”

Source: Coding guidelines


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 916c4b9f-f87a-4d76-9d5a-98b8b9639aeb

📥 Commits

Reviewing files that changed from the base of the PR and between c377ec1 and bea49d0.

📒 Files selected for processing (38)
  • src/main/index.ts
  • src/main/ipc/register-core-handlers.test.ts
  • src/main/ipc/register-core-handlers.ts
  • src/main/ipc/zai-api-key.ts
  • src/main/rate-limits/service.test.ts
  • src/main/rate-limits/service.ts
  • src/main/rate-limits/zai-fetcher.test.ts
  • src/main/rate-limits/zai-fetcher.ts
  • src/main/runtime/rpc/methods/accounts.ts
  • src/main/zai-api-key-store.test.ts
  • src/main/zai-api-key-store.ts
  • src/preload/api-types.ts
  • src/preload/index.ts
  • src/renderer/src/components/settings/AccountsPane.test.tsx
  • src/renderer/src/components/settings/AccountsPane.tsx
  • src/renderer/src/components/settings/AppearancePane.tsx
  • src/renderer/src/components/settings/accounts-search.ts
  • src/renderer/src/components/settings/appearance-status-bar-search.ts
  • src/renderer/src/components/status-bar/StatusBar.tsx
  • src/renderer/src/components/status-bar/StatusBarUsageEmptyCta.tsx
  • src/renderer/src/components/status-bar/icons.tsx
  • src/renderer/src/components/status-bar/status-bar-agent-gating.test.ts
  • src/renderer/src/components/status-bar/status-bar-agent-gating.ts
  • src/renderer/src/components/status-bar/tooltip.test.ts
  • src/renderer/src/components/status-bar/tooltip.tsx
  • src/renderer/src/hooks/useSettingsNavigationMetadata.ts
  • src/renderer/src/i18n/locales/en.json
  • src/renderer/src/i18n/locales/es.json
  • src/renderer/src/i18n/locales/ja.json
  • src/renderer/src/i18n/locales/ko.json
  • src/renderer/src/i18n/locales/zh.json
  • src/renderer/src/store/slices/rate-limits.ts
  • src/renderer/src/store/slices/ui.test.ts
  • src/renderer/src/store/slices/ui.ts
  • src/renderer/src/web/web-preload-api.ts
  • src/shared/rate-limit-types.ts
  • src/shared/status-bar-defaults.ts
  • src/shared/types.ts

Comment thread src/main/rate-limits/service.ts Resolved
Comment thread src/main/zai-api-key-store.ts Resolved
Comment thread src/renderer/src/i18n/locales/en.json Resolved
Comment thread src/renderer/src/i18n/locales/es.json Resolved
Comment thread src/renderer/src/i18n/locales/ja.json Resolved
Comment thread src/renderer/src/i18n/locales/ja.json Resolved
Comment thread src/renderer/src/i18n/locales/ko.json Resolved
Comment thread src/renderer/src/i18n/locales/zh.json Resolved
Type the preload bridge, harden Z.AI key loading against resolver and storage mode changes, and translate the remaining locale copy for the API-key flow.
@abilliontokens

Copy link
Copy Markdown
Contributor Author

Addressed the remaining non-threaded CodeRabbit quick wins as well: the Z.AI preload bridge is now typed against PreloadApi['zaiApiKey'], the web preload stub documents why it always reports configured: false, and the Z.AI settings keyword flattening now carries a short why-comment.

@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.

♻️ Duplicate comments (1)
src/renderer/src/i18n/locales/zh.json (1)

4200-4200: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Untranslated English string remains in the Chinese locale

Line 4200 is still English ("Use your current"), which will produce mixed-language UI in zh. Translate this key to Simplified Chinese for consistency.

Suggested fix
-          "350b2a1aa7": "Use your current",
+          "350b2a1aa7": "使用您当前的",

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 64a46069-7a37-4e20-92ac-fcf534fac824

📥 Commits

Reviewing files that changed from the base of the PR and between bea49d0 and d751692.

📒 Files selected for processing (13)
  • src/main/ipc/register-core-handlers.test.ts
  • src/main/rate-limits/service.test.ts
  • src/main/rate-limits/service.ts
  • src/main/zai-api-key-store.test.ts
  • src/main/zai-api-key-store.ts
  • src/preload/index.ts
  • src/renderer/src/components/settings/AccountsPane.tsx
  • src/renderer/src/i18n/locales/en.json
  • src/renderer/src/i18n/locales/es.json
  • src/renderer/src/i18n/locales/ja.json
  • src/renderer/src/i18n/locales/ko.json
  • src/renderer/src/i18n/locales/zh.json
  • src/renderer/src/web/web-preload-api.ts
✅ Files skipped from review due to trivial changes (2)
  • src/renderer/src/i18n/locales/ko.json
  • src/renderer/src/i18n/locales/ja.json
🚧 Files skipped from review as they are similar to previous changes (7)
  • src/preload/index.ts
  • src/main/ipc/register-core-handlers.test.ts
  • src/main/zai-api-key-store.test.ts
  • src/main/zai-api-key-store.ts
  • src/main/rate-limits/service.test.ts
  • src/main/rate-limits/service.ts
  • src/renderer/src/components/settings/AccountsPane.tsx

@nwparker nwparker added the enhancement New feature or request label Jul 27, 2026
@nwparker

Copy link
Copy Markdown
Contributor

Thanks for being early on Z.AI support. It now ships on main via ZCode (#24674), so we're closing this as superseded. We appreciate the contribution.

@nwparker nwparker closed this Oct 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants