diff --git a/codex-rs/core/src/codex.rs b/codex-rs/core/src/codex.rs index 3a27a8839b..45118193f2 100644 --- a/codex-rs/core/src/codex.rs +++ b/codex-rs/core/src/codex.rs @@ -425,6 +425,7 @@ pub(crate) const SUBMISSION_CHANNEL_CAPACITY: usize = 512; const CYBER_VERIFY_URL: &str = "https://chatgpt.com/cyber"; const CYBER_SAFETY_URL: &str = "https://developers.openai.com/codex/concepts/cyber-safety"; const DIRECT_APP_TOOL_EXPOSURE_THRESHOLD: usize = 100; +const CLI_CREATE_API_KEY_INSTRUCTION: &str = "If a command fails because `OPENAI_API_KEY` is unset, tell the user to set `OPENAI_API_KEY` in this shell or pass `api_key=...` explicitly, and mention that they can run `/create-api-key` to create an OpenAI API key for the current Codex session."; impl Codex { /// Spawn a new [`Codex`] and initialize the session. @@ -3497,6 +3498,9 @@ impl Session { ) .into_text(), ); + if matches!(session_source, SessionSource::Cli) { + developer_sections.push(CLI_CREATE_API_KEY_INSTRUCTION.to_string()); + } let separate_guardian_developer_message = crate::guardian::is_guardian_reviewer_source(&session_source); // Keep the guardian policy prompt out of the aggregated developer bundle so it diff --git a/codex-rs/tui/src/chatwidget/create_api_key.rs b/codex-rs/tui/src/chatwidget/create_api_key.rs index 6d41e6a0db..c60a1b80e3 100644 --- a/codex-rs/tui/src/chatwidget/create_api_key.rs +++ b/codex-rs/tui/src/chatwidget/create_api_key.rs @@ -205,23 +205,39 @@ fn success_cell( .unwrap_or_else(|| provisioned.default_project_id.clone()); let masked_api_key = mask_api_key(&provisioned.project_api_key); let copy_status = match copy_result { - Ok(()) => "Copied the full key to your clipboard.".to_string(), + Ok(()) => "I copied the full key to your clipboard.".to_string(), Err(err) => format!("Could not copy the key to your clipboard: {err}"), }; let session_env_status = match session_env_result { - Ok(()) => { - format!("Set {OPENAI_API_KEY_ENV_VAR} in this Codex session for spawned commands.") - } + Ok(()) => format!( + "I also set {OPENAI_API_KEY_ENV_VAR} in this Codex session for future commands." + ), Err(err) => { format!("Could not set {OPENAI_API_KEY_ENV_VAR} in this Codex session: {err}") } }; - let hint = Some(format!("{copy_status} {session_env_status}")); - history_cell::new_info_event( - format!("Created an API key for {organization} / {project}: {masked_api_key}"), - hint, - ) + PlainHistoryCell::new(vec![ + vec![ + "• ".dim(), + format!("Created an API key for {organization} / {project}: {masked_api_key}.").into(), + ] + .into(), + vec![" ".into(), format!("{copy_status} {session_env_status}").into()].into(), + "".into(), + vec![ + " ".into(), + "To create more keys or monitor usage, go to platform.openai.com.".dark_gray(), + ] + .into(), + "".into(), + vec![ + " ".into(), + "You can start building with the OpenAI API with limited usage of gpt-5.4-nano. To use more models, add credits on platform.openai.com." + .dark_gray(), + ] + .into(), + ]) } fn mask_api_key(api_key: &str) -> String { diff --git a/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__create_api_key__tests__success_cell_snapshot.snap b/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__create_api_key__tests__success_cell_snapshot.snap index 57e054a59d..fe9633dbd7 100644 --- a/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__create_api_key__tests__success_cell_snapshot.snap +++ b/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__create_api_key__tests__success_cell_snapshot.snap @@ -1,6 +1,10 @@ --- source: tui/src/chatwidget/create_api_key.rs -assertion_line: 232 expression: render_cell(&cell) --- -• Created an API key for Default Org / Default Project: sk-proj-123 Copied the full key to your clipboard. Set OPENAI_API_KEY in this Codex session for spawned commands. +• Created an API key for Default Org / Default Project: sk-proj-123. + I copied the full key to your clipboard. I also set OPENAI_API_KEY in this Codex session for future commands. + + To create more keys or monitor usage, go to platform.openai.com. + + You can start building with the OpenAI API with limited usage of gpt-5.4-nano. To use more models, add credits on platform.openai.com. diff --git a/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__create_api_key__tests__success_cell_snapshot_when_clipboard_copy_fails.snap b/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__create_api_key__tests__success_cell_snapshot_when_clipboard_copy_fails.snap index 901fafb2eb..2f34af08fd 100644 --- a/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__create_api_key__tests__success_cell_snapshot_when_clipboard_copy_fails.snap +++ b/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__create_api_key__tests__success_cell_snapshot_when_clipboard_copy_fails.snap @@ -1,6 +1,10 @@ --- source: tui/src/chatwidget/create_api_key.rs -assertion_line: 249 expression: render_cell(&cell) --- -• Created an API key for org-default / proj-default: sk-proj-123 Could not copy the key to your clipboard: clipboard unavailable Could not set OPENAI_API_KEY in this Codex session: dependency env unavailable +• Created an API key for org-default / proj-default: sk-proj-123. + Could not copy the key to your clipboard: clipboard unavailable Could not set OPENAI_API_KEY in this Codex session: dependency env unavailable + + To create more keys or monitor usage, go to platform.openai.com. + + You can start building with the OpenAI API with limited usage of gpt-5.4-nano. To use more models, add credits on platform.openai.com.