mirror of
https://github.com/cline/cline.git
synced 2026-09-19 02:05:44 +08:00
* feat: add OpenAI Codex provider for ChatGPT Plus/Pro subscriptions Add a new provider that allows users with ChatGPT Plus or Pro subscriptions to use GPT-5 models directly through Cline without needing an API key. Key features: - OAuth authentication via OpenAI (PKCE flow) - Routes requests to chatgpt.com/backend-api/codex/responses - Subscription-based pricing (no per-token costs) - Models: gpt-5.2-codex, gpt-5.1-codex-max, gpt-5.1-codex-mini, gpt-5.2 New files: - src/integrations/openai-codex/oauth.ts: OAuth manager with PKCE, token storage/refresh - src/core/api/providers/openai-codex.ts: API handler for Codex backend - src/core/controller/account/openAiCodexSignIn.ts: Sign-in RPC handler - src/core/controller/account/openAiCodexSignOut.ts: Sign-out RPC handler - webview-ui/src/components/settings/providers/OpenAiCodexProvider.tsx: Settings UI * fix: force native tool calling for Responses API providers Providers using OpenAI's Responses API (openai-codex, some openai-native models) require native tool calling. XML tools don't work with these APIs, causing duplicate tool calls and malformed arguments. Changes: - Add openai-codex to isNextGenModelProvider() list so native variant matchers recognize it - Force enableNativeToolCalls=true when model uses ApiFormat.OPENAI_RESPONSES, regardless of user setting - Document Responses API provider requirements in CLAUDE.md * chore: rename OpenAI Codex provider label to ChatGPT Codex Subscription * fix: use shared fetch wrapper for proxy support in OpenAI Codex provider * revert: remove CLAUDE.md changes from this PR * fix: restore .clinerules/general.md to match main * chore: rename provider label to OpenAI Codex (ChatGPT Plus/Pro) * chore: add network.md reference to clinerules * feat: show VS Code notifications for OpenAI Codex OAuth success/failure
51 lines
1.7 KiB
TypeScript
51 lines
1.7 KiB
TypeScript
import { Empty, EmptyRequest } from "@shared/proto/cline/common"
|
|
import { openAiCodexOAuthManager } from "@/integrations/openai-codex/oauth"
|
|
import { HostProvider } from "@/hosts/host-provider"
|
|
import { openExternal } from "@/utils/env"
|
|
import { ShowMessageType } from "@shared/proto/host/window"
|
|
import { Controller } from ".."
|
|
|
|
/**
|
|
* Initiates OpenAI Codex OAuth authentication flow
|
|
* Opens the authorization URL in the user's browser
|
|
*/
|
|
export async function openAiCodexSignIn(controller: Controller, _: EmptyRequest): Promise<Empty> {
|
|
try {
|
|
// Start the authorization flow and get the auth URL
|
|
const authUrl = openAiCodexOAuthManager.startAuthorizationFlow()
|
|
|
|
// Open the auth URL in the browser
|
|
await openExternal(authUrl)
|
|
|
|
// Wait for the OAuth callback in the background
|
|
// The callback will save credentials when complete
|
|
openAiCodexOAuthManager
|
|
.waitForCallback()
|
|
.then(async () => {
|
|
HostProvider.window.showMessage({
|
|
type: ShowMessageType.INFORMATION,
|
|
message: "Successfully signed in to OpenAI Codex",
|
|
})
|
|
await controller.postStateToWebview()
|
|
})
|
|
.catch((error) => {
|
|
console.error("[openAiCodexSignIn] OAuth callback failed:", error)
|
|
openAiCodexOAuthManager.cancelAuthorizationFlow()
|
|
// Don't show notification for timeouts (user likely just abandoned)
|
|
const errorMessage = error instanceof Error ? error.message : String(error)
|
|
if (!errorMessage.includes("timed out")) {
|
|
HostProvider.window.showMessage({
|
|
type: ShowMessageType.ERROR,
|
|
message: `OpenAI Codex sign in failed: ${errorMessage}`,
|
|
})
|
|
}
|
|
})
|
|
} catch (error) {
|
|
console.error("[openAiCodexSignIn] Failed to start OAuth flow:", error)
|
|
openAiCodexOAuthManager.cancelAuthorizationFlow()
|
|
throw error
|
|
}
|
|
|
|
return {}
|
|
}
|