From 072b913fd22b37f7cf07d5167f9a9cdd0caa6ec6 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, 18 May 2026 22:46:36 +0800 Subject: [PATCH] Keep ChatGPT Official activation metadata-only until OAuth runtime lands Task 1 should only persist the built-in provider selection. The generic managed env and proxy paths remain reserved for saved Anthropic-compatible providers until the dedicated OpenAI OAuth runtime is wired in a later task. Constraint: Task 1 must not write managed provider env for openai-official Rejected: Reuse buildManagedEnv for openai-official | writes placeholder Anthropic env before Task 3 runtime exists Rejected: Return generic proxy config for openai-official | lets empty-key proxy resolution masquerade as a working runtime Confidence: high Scope-risk: narrow Directive: Do not route openai-official through managed settings or generic proxy lookup until the dedicated OAuth runtime is implemented Tested: bun test src/server/__tests__/providers.test.ts --test-name-pattern "ChatGPT Official" Tested: bun test src/server/__tests__/providers.test.ts Tested: bun run check:server --- src/server/__tests__/providers.test.ts | 29 ++++++++++++++++++++++++++ src/server/services/providerService.ts | 16 ++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/src/server/__tests__/providers.test.ts b/src/server/__tests__/providers.test.ts index 23bc26c6..8d01edf7 100644 --- a/src/server/__tests__/providers.test.ts +++ b/src/server/__tests__/providers.test.ts @@ -313,6 +313,18 @@ describe('ProviderService', () => { }, }) }) + + test('activating ChatGPT Official only persists activeId for Task 1', async () => { + const svc = new ProviderService() + + await svc.activateProvider('openai-official') + + const config = await readProvidersConfig() + expect(config.activeId).toBe('openai-official') + await expect( + fs.readFile(path.join(tmpDir, 'cc-haha', 'settings.json'), 'utf-8'), + ).rejects.toThrow() + }) }) test('should throw 404 for non-existent id', async () => { @@ -740,6 +752,14 @@ describe('ProviderService', () => { expect(active).toBeNull() }) + test('should return null for explicit ChatGPT Official proxy lookup', async () => { + const svc = new ProviderService() + + const active = await svc.getProviderForProxy('openai-official') + + expect(active).toBeNull() + }) + test('should return the active provider proxy config', async () => { const svc = new ProviderService() const provider = await svc.addProvider(sampleInput()) @@ -751,6 +771,15 @@ describe('ProviderService', () => { expect(active!.apiKey).toBe(provider.apiKey) expect(active!.apiFormat).toBe('anthropic') }) + + test('should return null when ChatGPT Official is the active provider', async () => { + const svc = new ProviderService() + await svc.activateProvider('openai-official') + + const active = await svc.getProviderForProxy() + + expect(active).toBeNull() + }) }) describe('testProvider', () => { diff --git a/src/server/services/providerService.ts b/src/server/services/providerService.ts index a9783bfd..cc0fba8e 100644 --- a/src/server/services/providerService.ts +++ b/src/server/services/providerService.ts @@ -358,6 +358,10 @@ export class ProviderService { index.activeId = id await this.writeIndex(index) + if (isOpenAIOfficialProviderId(id)) { + return + } + if (provider.presetId === 'official') { await this.clearProviderFromSettings() } else { @@ -418,6 +422,12 @@ export class ProviderService { } async getProviderRuntimeEnv(id: string): Promise> { + if (isOpenAIOfficialProviderId(id)) { + // Task 1 only persists the built-in provider selection. Task 3 wires the + // dedicated OAuth runtime env for ChatGPT Official sessions. + return {} + } + const provider = await this.getProvider(id) return this.buildManagedEnv(provider, { proxyPath: `/proxy/providers/${provider.id}`, @@ -528,6 +538,9 @@ export class ProviderService { apiFormat: ApiFormat } | null> { if (providerId) { + if (isOpenAIOfficialProviderId(providerId)) { + return null + } const provider = await this.getProvider(providerId) return { baseUrl: provider.baseUrl, @@ -538,6 +551,9 @@ export class ProviderService { const index = await this.readIndex() if (!index.activeId) return null + if (isOpenAIOfficialProviderId(index.activeId)) { + return null + } const provider = await this.getProvider(index.activeId).catch(() => null) if (!provider) return null return {