From 472ff739274818a6654f5b384f78f1925368a2d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E5=91=98=E9=98=BF=E6=B1=9F=28Relakkes?= =?UTF-8?q?=29?= Date: Mon, 4 May 2026 21:10:08 +0800 Subject: [PATCH] Stabilize OpenAI auth PR quality gates PR 217 combined OpenAI OAuth model options with env-configured provider models, but the picker path returned before appending third-party model aliases. The desktop workspace test also exercised Prism highlighting for every expanded line, which was costly enough to time out on CI runners. The docs job did not need the root React Vite plugin; the desktop package owns that dependency.\n\nConstraint: PR Quality must pass server, desktop, and docs jobs before merge.\nRejected: Increase Vitest timeout | keeps the expensive render path and hides the CI regression.\nRejected: Add root Vite 8 peer dependencies | root only builds VitePress docs; React Vite plugin belongs in desktop/.\nConfidence: high\nScope-risk: narrow\nTested: npm ci --ignore-scripts; npm run docs:build; bun test src/server/__tests__/settings.test.ts src/server/__tests__/conversation-service.test.ts; bun run check:server; bun run check:desktop\nNot-tested: live provider OAuth login --- .../components/workspace/WorkspacePanel.tsx | 3 +-- package.json | 1 - src/server/__tests__/settings.test.ts | 26 ++++++++++++++----- src/utils/model/modelOptions.ts | 2 +- 4 files changed, 21 insertions(+), 11 deletions(-) diff --git a/desktop/src/components/workspace/WorkspacePanel.tsx b/desktop/src/components/workspace/WorkspacePanel.tsx index 333061be..bcc46d06 100644 --- a/desktop/src/components/workspace/WorkspacePanel.tsx +++ b/desktop/src/components/workspace/WorkspacePanel.tsx @@ -20,7 +20,6 @@ import { MarkdownRenderer } from '../markdown/MarkdownRenderer' import { getFileExtension, normalizePrismLanguage, - WORKSPACE_PLAIN_TEXT_LINE_THRESHOLD, WORKSPACE_PREVIEW_LINE_LIMIT, WorkspaceDiffSurface, workspacePrismTheme, @@ -321,7 +320,7 @@ function CodeSurface({ const lines = value.split('\n') const visibleLines = showAllLines ? lines : lines.slice(0, WORKSPACE_PREVIEW_LINE_LIMIT) const activeQuote = commentLine ? visibleLines[commentLine - 1] ?? '' : '' - const usePlainLargePreview = showAllLines && lines.length > WORKSPACE_PLAIN_TEXT_LINE_THRESHOLD + const usePlainLargePreview = showAllLines && lines.length > WORKSPACE_PREVIEW_LINE_LIMIT const visibleCode = usePlainLargePreview ? '' : visibleLines.join('\n') useEffect(() => { diff --git a/package.json b/package.json index 790a99da..84e03205 100644 --- a/package.json +++ b/package.json @@ -93,7 +93,6 @@ "zod": "^4.3.6" }, "devDependencies": { - "@vitejs/plugin-react": "^6.0.1", "mermaid": "^11.14.0", "vitepress": "^1.6.3", "vitepress-plugin-mermaid": "^2.0.17", diff --git a/src/server/__tests__/settings.test.ts b/src/server/__tests__/settings.test.ts index 0f80f3b0..5737b009 100644 --- a/src/server/__tests__/settings.test.ts +++ b/src/server/__tests__/settings.test.ts @@ -13,9 +13,13 @@ import { handleStatusApi, resetUsage, addUsage } from '../api/status.js' import { ProviderService } from '../services/providerService.js' import { clearOpenAIOAuthTokenCache, - deleteOpenAIOAuthTokens, - saveOpenAIOAuthTokens, } from '../../services/openaiAuth/storage.js' +import { plainTextStorage } from '../../utils/secureStorage/plainTextStorage.js' +import { + clearKeychainCache, + primeKeychainCacheFromPrefetch, +} from '../../utils/secureStorage/macOsKeychainHelpers.js' +import type { OpenAIOAuthTokens } from '../../services/openaiAuth/types.js' import { getModelOptions } from '../../utils/model/modelOptions.js' // ─── Test helpers ───────────────────────────────────────────────────────────── @@ -59,10 +63,16 @@ async function setup() { delete process.env.ANTHROPIC_DEFAULT_HAIKU_MODEL delete process.env.ANTHROPIC_DEFAULT_SONNET_MODEL delete process.env.ANTHROPIC_DEFAULT_OPUS_MODEL + clearKeychainCache() + primeKeychainCacheFromPrefetch(null) clearOpenAIOAuthTokenCache() } async function teardown() { + plainTextStorage.delete() + clearKeychainCache() + clearOpenAIOAuthTokenCache() + if (originalConfigDir !== undefined) { process.env.CLAUDE_CONFIG_DIR = originalConfigDir } else { @@ -135,12 +145,14 @@ async function teardown() { delete process.env.ANTHROPIC_DEFAULT_OPUS_MODEL } - deleteOpenAIOAuthTokens() - clearOpenAIOAuthTokenCache() - await fs.rm(tmpDir, { recursive: true, force: true }) } +function saveTestOpenAIOAuthTokens(tokens: OpenAIOAuthTokens) { + plainTextStorage.update({ openaiCodexOauth: tokens }) + clearOpenAIOAuthTokenCache() +} + /** 创建一个模拟 Request */ function makeRequest( method: string, @@ -395,7 +407,7 @@ describe('Models API', () => { process.env.ANTHROPIC_DEFAULT_HAIKU_MODEL = 'deepseek-v4-flash' process.env.ANTHROPIC_DEFAULT_SONNET_MODEL = 'deepseek-v4-pro' process.env.ANTHROPIC_DEFAULT_OPUS_MODEL = 'deepseek-v4-pro' - saveOpenAIOAuthTokens({ + saveTestOpenAIOAuthTokens({ accessToken: 'access-token', refreshToken: 'refresh-token', expiresAt: Date.now() + 60_000, @@ -564,7 +576,7 @@ describe('Model Options', () => { process.env.ANTHROPIC_DEFAULT_HAIKU_MODEL = 'deepseek-v4-flash' process.env.ANTHROPIC_DEFAULT_SONNET_MODEL = 'deepseek-v4-pro' process.env.ANTHROPIC_DEFAULT_OPUS_MODEL = 'deepseek-v4-pro' - saveOpenAIOAuthTokens({ + saveTestOpenAIOAuthTokens({ accessToken: 'access-token', refreshToken: 'refresh-token', expiresAt: Date.now() + 60_000, diff --git a/src/utils/model/modelOptions.ts b/src/utils/model/modelOptions.ts index 5e72ad30..fbcd2cc9 100644 --- a/src/utils/model/modelOptions.ts +++ b/src/utils/model/modelOptions.ts @@ -330,7 +330,7 @@ function getAzureOpenAICodexOptions(): ModelOption[] { } function getOpenAIModelOptions(): ModelOption[] { - return [ + const options = [ getDefaultOptionForUser(), ...OPENAI_CODEX_MODEL_CATALOG.map(model => ({ value: model.value,