From 1dc14cefa174268115914a9d80e3fcef0ac012da Mon Sep 17 00:00:00 2001 From: Michael Bolin Date: Fri, 16 May 2025 17:08:18 -0700 Subject: [PATCH 1/4] fix: make codex-mini-latest the default model in the Rust TUI (#972) It's time to make `codex-mini-latest` the new default, as this should be an "evergreen" model pointer. * Equivalent change in TypeScript https://github.com/openai/codex/pull/951 * See some notes about using `codex-mini-latest` with MCP in https://github.com/openai/codex/pull/961 --- codex-rs/README.md | 2 +- codex-rs/core/src/flags.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/codex-rs/README.md b/codex-rs/README.md index 2c95976c39..bedce9f22d 100644 --- a/codex-rs/README.md +++ b/codex-rs/README.md @@ -32,7 +32,7 @@ The `config.toml` file supports the following options: The model that Codex should use. ```toml -model = "o3" # overrides the default of "o4-mini" +model = "o3" # overrides the default of "codex-mini-latest" ``` ### model_provider diff --git a/codex-rs/core/src/flags.rs b/codex-rs/core/src/flags.rs index e8cc973c99..c21ef67026 100644 --- a/codex-rs/core/src/flags.rs +++ b/codex-rs/core/src/flags.rs @@ -3,7 +3,7 @@ use std::time::Duration; use env_flags::env_flags; env_flags! { - pub OPENAI_DEFAULT_MODEL: &str = "o4-mini"; + pub OPENAI_DEFAULT_MODEL: &str = "codex-mini-latest"; pub OPENAI_API_BASE: &str = "https://api.openai.com/v1"; /// Fallback when the provider-specific key is not set. From c7312c9d524783971c2ce6ee4a80f03ebf76950c Mon Sep 17 00:00:00 2001 From: Trevor Creech Date: Fri, 16 May 2025 17:11:57 -0700 Subject: [PATCH 2/4] Fix CLA link in workflow (#964) ## Summary - fix the CLA link posted by the bot - docs suggest using an absolute URL: https://github.com/marketplace/actions/cla-assistant-lite --- .github/workflows/cla.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml index a7f6c62865..521e917e95 100644 --- a/.github/workflows/cla.yml +++ b/.github/workflows/cla.yml @@ -23,7 +23,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - path-to-document: docs/CLA.md + path-to-document: https://github.com/openai/codex/blob/main/docs/CLA.md path-to-signatures: signatures/cla.json branch: cla-signatures allowlist: dependabot[bot] From 3e19e8fd598d09d549962166533b1039c5500084 Mon Sep 17 00:00:00 2001 From: Fouad Matin <169186268+fouad-openai@users.noreply.github.com> Date: Fri, 16 May 2025 17:55:08 -0700 Subject: [PATCH 3/4] add: sign in with chatgpt credits (#974) --- codex-cli/src/utils/get-api-key.tsx | 114 ++++++++++++++++++++++++++-- 1 file changed, 109 insertions(+), 5 deletions(-) diff --git a/codex-cli/src/utils/get-api-key.tsx b/codex-cli/src/utils/get-api-key.tsx index 0dd52f7315..ad5ce1c0f3 100644 --- a/codex-cli/src/utils/get-api-key.tsx +++ b/codex-cli/src/utils/get-api-key.tsx @@ -3,6 +3,7 @@ import type { Request, Response } from "express"; import { ApiKeyPrompt, WaitingForAuth } from "./get-api-key-components"; import { clearTerminal } from "./terminal"; +import chalk from "chalk"; import express from "express"; import fs from "fs/promises"; import { render } from "ink"; @@ -189,10 +190,10 @@ async function handleCallback( ); const chatgptPlanType = accessTokenClaims["https://api.openai.com/auth"]?.chatgpt_plan_type; - let needsSetup = false; - if (chatgptPlanType === "plus" || chatgptPlanType === "pro") { - needsSetup = !completedOnboarding; - } + const isOrgOwner = Boolean( + idTokenClaims["https://api.openai.com/auth"]?.is_org_owner, + ); + const needsSetup = !completedOnboarding && isOrgOwner; // Build the success URL on the same host/port as the callback and // include the required query parameters for the front-end page. @@ -230,6 +231,58 @@ async function handleCallback( console.warn("Unable to save auth file:", err); } + if ( + !needsSetup && + (chatgptPlanType === "plus" || chatgptPlanType === "pro") + ) { + const apiHost = + issuer === "https://auth.openai.com" + ? "https://api.openai.com" + : "https://api.openai.org"; + + try { + const redeemRes = await fetch(`${apiHost}/v1/billing/redeem_credits`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ id_token: tokenData.id_token }), + }); + + if (!redeemRes.ok) { + // eslint-disable-next-line no-console + console.warn( + `Credit redemption request failed: ${redeemRes.status} ${redeemRes.statusText}`, + ); + } else { + // Attempt to parse the JSON response and surface a success message + try { + const redeemData = (await redeemRes.json()) as { + granted_chatgpt_subscriber_api_credits?: number; + }; + const granted = + redeemData?.granted_chatgpt_subscriber_api_credits ?? 0; + if (granted > 0) { + // eslint-disable-next-line no-console + console.log( + chalk.green( + `\u2728 Granted ${chatgptPlanType === "plus" ? "$5" : "$50"} in API credits for being a ChatGPT ${ + chatgptPlanType === "plus" ? "Plus" : "Pro" + } subscriber!`, + ), + ); + } + } catch (parseErr) { + // eslint-disable-next-line no-console + console.warn("Unable to parse credit redemption response:", parseErr); + } + } + } catch (err) { + // eslint-disable-next-line no-console + console.warn("Unable to redeem ChatGPT subscriber API credits:", err); + } + } + return { access_token: exchanged.access_token, success_url: successUrl.toString(), @@ -363,11 +416,62 @@ const LOGIN_SUCCESS_HTML = String.raw`
Signed in to Codex CLI
-
+ +
+ `; From 25d55ac285b85e8a6d8d9934496be69ba9da9ba2 Mon Sep 17 00:00:00 2001 From: Michael Bolin Date: Fri, 16 May 2025 18:17:13 -0700 Subject: [PATCH 4/4] fix: do not let Tab keypress flow through to composer when used to toggle focus --- codex-rs/tui/src/chatwidget.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/codex-rs/tui/src/chatwidget.rs b/codex-rs/tui/src/chatwidget.rs index 24d37c4c0a..17f57fc053 100644 --- a/codex-rs/tui/src/chatwidget.rs +++ b/codex-rs/tui/src/chatwidget.rs @@ -129,6 +129,7 @@ impl ChatWidget<'_> { self.bottom_pane .set_input_focus(self.input_focus == InputFocus::BottomPane); self.request_redraw(); + return; } match self.input_focus {