feat: arcticfox in the wild (#6906)

<img width="485" height="600" alt="image"
src="https://github.com/user-attachments/assets/4341740d-dd58-4a3e-b69a-33a3be0606c5"
/>

---------

Co-authored-by: jif-oai <jif@openai.com>
This commit is contained in:
Ahmed Ibrahimandjif-oai authored and GitHub committed 2025-11-19 16:31:06 +00:00
1 parent 1924500250
commit d5dfba2509
31 files changed
+375 -211

No files matched your search

+29 -13
View File
@@ -19,7 +19,7 @@ use crate::tui::TuiEvent;
use crate::update_action::UpdateAction;
use codex_ansi_escape::ansi_escape_line;
use codex_app_server_protocol::AuthMode;
use codex_common::model_presets::HIDE_ARCTICFOX_MIGRATION_PROMPT_CONFIG;
use codex_common::model_presets::HIDE_GPT_5_1_CODEX_MAX_MIGRATION_PROMPT_CONFIG;
use codex_common::model_presets::HIDE_GPT5_1_MIGRATION_PROMPT_CONFIG;
use codex_common::model_presets::ModelUpgrade;
use codex_common::model_presets::all_model_presets;
@@ -57,7 +57,7 @@ use tokio::sync::mpsc::unbounded_channel;
use crate::history_cell::UpdateAvailableHistoryCell;
const GPT_5_1_MIGRATION_AUTH_MODES: [AuthMode; 2] = [AuthMode::ChatGPT, AuthMode::ApiKey];
const ARCTICFOX_MIGRATION_AUTH_MODES: [AuthMode; 1] = [AuthMode::ChatGPT];
const GPT_5_1_CODEX_MIGRATION_AUTH_MODES: [AuthMode; 1] = [AuthMode::ChatGPT];
#[derive(Debug, Clone)]
pub struct AppExitInfo {
@@ -106,7 +106,9 @@ fn should_show_model_migration_prompt(
fn migration_prompt_hidden(config: &Config, migration_config_key: &str) -> Option<bool> {
match migration_config_key {
HIDE_ARCTICFOX_MIGRATION_PROMPT_CONFIG => config.notices.hide_arcticfox_migration_prompt,
HIDE_GPT_5_1_CODEX_MAX_MIGRATION_PROMPT_CONFIG => {
config.notices.hide_gpt_5_1_codex_max_migration_prompt
}
HIDE_GPT5_1_MIGRATION_PROMPT_CONFIG => config.notices.hide_gpt5_1_migration_prompt,
_ => None,
}
@@ -170,6 +172,11 @@ async fn handle_model_migration_prompt_if_needed(
effort: mapped_effort,
});
}
ModelMigrationOutcome::Rejected => {
app_event_tx.send(AppEvent::PersistModelMigrationPromptAcknowledged {
migration_config: migration_config_key.to_string(),
});
}
ModelMigrationOutcome::Exit => {
return Some(AppExitInfo {
token_usage: TokenUsage::default(),
@@ -641,19 +648,17 @@ impl App {
.await
{
Ok(()) => {
let effort_label = effort
.map(|eff| format!(" with {eff} reasoning"))
.unwrap_or_else(|| " with default reasoning".to_string());
let reasoning_label = Self::reasoning_label(effort);
if let Some(profile) = profile {
self.chat_widget.add_info_message(
format!(
"Model changed to {model}{effort_label} for {profile} profile"
"Model changed to {model} {reasoning_label} for {profile} profile"
),
None,
);
} else {
self.chat_widget.add_info_message(
format!("Model changed to {model}{effort_label}"),
format!("Model changed to {model} {reasoning_label}"),
None,
);
}
@@ -821,6 +826,17 @@ impl App {
Ok(true)
}
fn reasoning_label(reasoning_effort: Option<ReasoningEffortConfig>) -> &'static str {
match reasoning_effort {
Some(ReasoningEffortConfig::Minimal) => "minimal",
Some(ReasoningEffortConfig::Low) => "low",
Some(ReasoningEffortConfig::Medium) => "medium",
Some(ReasoningEffortConfig::High) => "high",
Some(ReasoningEffortConfig::XHigh) => "xhigh",
None | Some(ReasoningEffortConfig::None) => "default",
}
}
pub(crate) fn token_usage(&self) -> codex_core::protocol::TokenUsage {
self.chat_widget.token_usage()
}
@@ -946,7 +962,7 @@ impl App {
fn migration_prompt_allowed_auth_modes(migration_config_key: &str) -> Option<&'static [AuthMode]> {
match migration_config_key {
HIDE_GPT5_1_MIGRATION_PROMPT_CONFIG => Some(&GPT_5_1_MIGRATION_AUTH_MODES),
HIDE_ARCTICFOX_MIGRATION_PROMPT_CONFIG => Some(&ARCTICFOX_MIGRATION_AUTH_MODES),
HIDE_GPT_5_1_CODEX_MAX_MIGRATION_PROMPT_CONFIG => Some(&GPT_5_1_CODEX_MIGRATION_AUTH_MODES),
_ => None,
}
}
@@ -1034,7 +1050,7 @@ mod tests {
));
assert!(should_show_model_migration_prompt(
"gpt-5.1-codex",
"arcticfox",
"gpt-5.1-codex-max",
None
));
assert!(!should_show_model_migration_prompt(
@@ -1181,14 +1197,14 @@ mod tests {
}
#[test]
fn arcticfox_migration_limits_to_chatgpt() {
fn gpt_5_1_codex_max_migration_limits_to_chatgpt() {
assert!(migration_prompt_allows_auth_mode(
Some(AuthMode::ChatGPT),
HIDE_ARCTICFOX_MIGRATION_PROMPT_CONFIG,
HIDE_GPT_5_1_CODEX_MAX_MIGRATION_PROMPT_CONFIG,
));
assert!(!migration_prompt_allows_auth_mode(
Some(AuthMode::ApiKey),
HIDE_ARCTICFOX_MIGRATION_PROMPT_CONFIG,
HIDE_GPT_5_1_CODEX_MAX_MIGRATION_PROMPT_CONFIG,
));
}
+2 -2
View File
@@ -2030,8 +2030,8 @@ impl ChatWidget {
let effort_label = Self::reasoning_effort_label(effort);
format!("⚠ {effort_label} reasoning effort can quickly consume Plus plan rate limits.")
});
let warn_for_model =
preset.model.starts_with("gpt-5.1-codex") || preset.model.starts_with("arcticfox");
let warn_for_model = preset.model.starts_with("gpt-5.1-codex")
|| preset.model.starts_with("gpt-5.1-codex-max");
struct EffortChoice {
stored: Option<ReasoningEffortConfig>,
@@ -2,7 +2,7 @@
source: tui/src/chatwidget/tests.rs
expression: popup
---
Select Reasoning Level for arcticfox
Select Reasoning Level for gpt-5.1-codex-max
1. Low Fast responses with lighter reasoning
2. Medium (default) Balances speed and reasoning depth for everyday tasks
@@ -3,7 +3,7 @@ source: tui/src/chatwidget/tests.rs
assertion_line: 1548
expression: popup
---
Select Reasoning Level for arcticfox
Select Reasoning Level for gpt-5.1-codex-max
1. Low Fast responses with lighter reasoning
2. Medium (default) Balances speed and reasoning depth for everyday
+9 -9
View File
@@ -1526,13 +1526,13 @@ fn startup_prompts_for_windows_sandbox_when_agent_requested() {
fn model_reasoning_selection_popup_snapshot() {
let (mut chat, _rx, _op_rx) = make_chatwidget_manual();
chat.config.model = "arcticfox".to_string();
chat.config.model = "gpt-5.1-codex-max".to_string();
chat.config.model_reasoning_effort = Some(ReasoningEffortConfig::High);
let preset = builtin_model_presets(None)
.into_iter()
.find(|preset| preset.model == "arcticfox")
.expect("arcticfox preset");
.find(|preset| preset.model == "gpt-5.1-codex-max")
.expect("gpt-5.1-codex-max preset");
chat.open_reasoning_popup(preset);
let popup = render_bottom_popup(&chat, 80);
@@ -1543,13 +1543,13 @@ fn model_reasoning_selection_popup_snapshot() {
fn model_reasoning_selection_popup_extra_high_warning_snapshot() {
let (mut chat, _rx, _op_rx) = make_chatwidget_manual();
chat.config.model = "arcticfox".to_string();
chat.config.model = "gpt-5.1-codex-max".to_string();
chat.config.model_reasoning_effort = Some(ReasoningEffortConfig::XHigh);
let preset = builtin_model_presets(None)
.into_iter()
.find(|preset| preset.model == "arcticfox")
.expect("arcticfox preset");
.find(|preset| preset.model == "gpt-5.1-codex-max")
.expect("gpt-5.1-codex-max preset");
chat.open_reasoning_popup(preset);
let popup = render_bottom_popup(&chat, 80);
@@ -1560,12 +1560,12 @@ fn model_reasoning_selection_popup_extra_high_warning_snapshot() {
fn reasoning_popup_shows_extra_high_with_space() {
let (mut chat, _rx, _op_rx) = make_chatwidget_manual();
chat.config.model = "arcticfox".to_string();
chat.config.model = "gpt-5.1-codex-max".to_string();
let preset = builtin_model_presets(None)
.into_iter()
.find(|preset| preset.model == "arcticfox")
.expect("arcticfox preset");
.find(|preset| preset.model == "gpt-5.1-codex-max")
.expect("gpt-5.1-codex-max preset");
chat.open_reasoning_popup(preset);
let popup = render_bottom_popup(&chat, 120);
+162 -28
View File
@@ -1,11 +1,13 @@
use crate::key_hint;
use crate::render::Insets;
use crate::render::renderable::ColumnRenderable;
use crate::render::renderable::Renderable;
use crate::render::renderable::RenderableExt as _;
use crate::selection_list::selection_option_row;
use crate::tui::FrameRequester;
use crate::tui::Tui;
use crate::tui::TuiEvent;
use codex_common::model_presets::HIDE_ARCTICFOX_MIGRATION_PROMPT_CONFIG;
use codex_common::model_presets::HIDE_GPT_5_1_CODEX_MAX_MIGRATION_PROMPT_CONFIG;
use codex_common::model_presets::HIDE_GPT5_1_MIGRATION_PROMPT_CONFIG;
use crossterm::event::KeyCode;
use crossterm::event::KeyEvent;
@@ -22,8 +24,10 @@ use ratatui::widgets::Wrap;
use tokio_stream::StreamExt;
/// Outcome of the migration prompt.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum ModelMigrationOutcome {
Accepted,
Rejected,
Exit,
}
@@ -31,13 +35,33 @@ pub(crate) enum ModelMigrationOutcome {
pub(crate) struct ModelMigrationCopy {
pub heading: Vec<Span<'static>>,
pub content: Vec<Line<'static>>,
pub can_opt_out: bool,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
enum MigrationMenuOption {
TryNewModel,
UseExistingModel,
}
impl MigrationMenuOption {
fn all() -> [Self; 2] {
[Self::TryNewModel, Self::UseExistingModel]
}
fn label(self) -> &'static str {
match self {
Self::TryNewModel => "Try new model",
Self::UseExistingModel => "Use existing model",
}
}
}
pub(crate) fn migration_copy_for_config(migration_config_key: &str) -> ModelMigrationCopy {
match migration_config_key {
HIDE_GPT5_1_MIGRATION_PROMPT_CONFIG => gpt5_migration_copy(),
HIDE_ARCTICFOX_MIGRATION_PROMPT_CONFIG => arcticfox_migration_copy(),
_ => arcticfox_migration_copy(),
HIDE_GPT_5_1_CODEX_MAX_MIGRATION_PROMPT_CONFIG => gpt_5_1_codex_max_migration_copy(),
_ => gpt_5_1_codex_max_migration_copy(),
}
}
@@ -98,7 +122,8 @@ struct ModelMigrationScreen {
request_frame: FrameRequester,
copy: ModelMigrationCopy,
done: bool,
should_exit: bool,
outcome: ModelMigrationOutcome,
highlighted_option: MigrationMenuOption,
}
impl ModelMigrationScreen {
@@ -107,15 +132,47 @@ impl ModelMigrationScreen {
request_frame,
copy,
done: false,
should_exit: false,
outcome: ModelMigrationOutcome::Accepted,
highlighted_option: MigrationMenuOption::TryNewModel,
}
}
fn accept(&mut self) {
fn finish_with(&mut self, outcome: ModelMigrationOutcome) {
self.outcome = outcome;
self.done = true;
self.request_frame.schedule_frame();
}
fn accept(&mut self) {
self.finish_with(ModelMigrationOutcome::Accepted);
}
fn reject(&mut self) {
self.finish_with(ModelMigrationOutcome::Rejected);
}
fn exit(&mut self) {
self.finish_with(ModelMigrationOutcome::Exit);
}
fn confirm_selection(&mut self) {
if self.copy.can_opt_out {
match self.highlighted_option {
MigrationMenuOption::TryNewModel => self.accept(),
MigrationMenuOption::UseExistingModel => self.reject(),
}
} else {
self.accept();
}
}
fn highlight_option(&mut self, option: MigrationMenuOption) {
if self.highlighted_option != option {
self.highlighted_option = option;
self.request_frame.schedule_frame();
}
}
fn handle_key(&mut self, key_event: KeyEvent) {
if key_event.kind == KeyEventKind::Release {
return;
@@ -124,14 +181,36 @@ impl ModelMigrationScreen {
if key_event.modifiers.contains(KeyModifiers::CONTROL)
&& matches!(key_event.code, KeyCode::Char('c') | KeyCode::Char('d'))
{
self.should_exit = true;
self.done = true;
self.request_frame.schedule_frame();
self.exit();
return;
}
if matches!(key_event.code, KeyCode::Esc | KeyCode::Enter) {
self.accept();
if !self.copy.can_opt_out {
if matches!(key_event.code, KeyCode::Esc | KeyCode::Enter) {
self.accept();
}
return;
}
match key_event.code {
KeyCode::Up | KeyCode::Char('k') => {
self.highlight_option(MigrationMenuOption::TryNewModel);
}
KeyCode::Down | KeyCode::Char('j') => {
self.highlight_option(MigrationMenuOption::UseExistingModel);
}
KeyCode::Char('1') => {
self.highlight_option(MigrationMenuOption::TryNewModel);
self.accept();
}
KeyCode::Char('2') => {
self.highlight_option(MigrationMenuOption::UseExistingModel);
self.reject();
}
KeyCode::Enter | KeyCode::Esc => {
self.confirm_selection();
}
_ => {}
}
}
@@ -140,11 +219,7 @@ impl ModelMigrationScreen {
}
fn outcome(&self) -> ModelMigrationOutcome {
if self.should_exit {
ModelMigrationOutcome::Exit
} else {
ModelMigrationOutcome::Accepted
}
self.outcome
}
}
@@ -172,25 +247,56 @@ impl WidgetRef for &ModelMigrationScreen {
);
}
if self.copy.can_opt_out {
column.push(Line::from(""));
column.push(
Paragraph::new("Choose how you'd like Codex to proceed.")
.wrap(Wrap { trim: false })
.inset(Insets::tlbr(0, 2, 0, 0)),
);
column.push(Line::from(""));
for (idx, option) in MigrationMenuOption::all().into_iter().enumerate() {
column.push(selection_option_row(
idx,
option.label().to_string(),
self.highlighted_option == option,
));
}
column.push(Line::from(""));
column.push(
Line::from(vec![
"Use ".dim(),
key_hint::plain(KeyCode::Up).into(),
"/".dim(),
key_hint::plain(KeyCode::Down).into(),
" to move, press ".dim(),
key_hint::plain(KeyCode::Enter).into(),
" to confirm".dim(),
])
.inset(Insets::tlbr(0, 2, 0, 0)),
);
}
column.render(area, buf);
}
}
fn arcticfox_migration_copy() -> ModelMigrationCopy {
fn gpt_5_1_codex_max_migration_copy() -> ModelMigrationCopy {
ModelMigrationCopy {
heading: vec!["Introducing arcticfox".bold()],
heading: vec!["Codex just got an upgrade. Introducing gpt-5.1-codex-max".bold()],
content: vec![
Line::from("We've upgraded our family of models supported in Codex to arcticfox."),
Line::from(
"You can continue using legacy models by specifying them directly with the -m option or in your config.toml.",
"Codex is now powered by gpt-5.1-codex-max, our latest frontier agentic coding model. It is smarter and faster than its predecessors and capable of long-running project-scale work.",
),
Line::from(vec![
"Learn more at ".into(),
"www.openai.com/index/arcticfox".cyan().underlined(),
"www.openai.com/index/gpt-5-1-codex-max".cyan().underlined(),
".".into(),
]),
Line::from(vec!["Press enter to continue".dim()]),
],
can_opt_out: true,
}
}
@@ -211,13 +317,14 @@ fn gpt5_migration_copy() -> ModelMigrationCopy {
]),
Line::from(vec!["Press enter to continue".dim()]),
],
can_opt_out: false,
}
}
#[cfg(test)]
mod tests {
use super::ModelMigrationScreen;
use super::arcticfox_migration_copy;
use super::gpt_5_1_codex_max_migration_copy;
use super::migration_copy_for_config;
use crate::custom_terminal::Terminal;
use crate::test_backend::VT100Backend;
@@ -231,13 +338,15 @@ mod tests {
#[test]
fn prompt_snapshot() {
let width: u16 = 60;
let height: u16 = 12;
let height: u16 = 20;
let backend = VT100Backend::new(width, height);
let mut terminal = Terminal::with_options(backend).expect("terminal");
terminal.set_viewport_area(Rect::new(0, 0, width, height));
let screen =
ModelMigrationScreen::new(FrameRequester::test_dummy(), arcticfox_migration_copy());
let screen = ModelMigrationScreen::new(
FrameRequester::test_dummy(),
gpt_5_1_codex_max_migration_copy(),
);
{
let mut frame = terminal.get_frame();
@@ -304,8 +413,10 @@ mod tests {
#[test]
fn escape_key_accepts_prompt() {
let mut screen =
ModelMigrationScreen::new(FrameRequester::test_dummy(), arcticfox_migration_copy());
let mut screen = ModelMigrationScreen::new(
FrameRequester::test_dummy(),
gpt_5_1_codex_max_migration_copy(),
);
// Simulate pressing Escape
screen.handle_key(KeyEvent::new(
@@ -319,4 +430,27 @@ mod tests {
super::ModelMigrationOutcome::Accepted
));
}
#[test]
fn selecting_use_existing_model_rejects_upgrade() {
let mut screen = ModelMigrationScreen::new(
FrameRequester::test_dummy(),
gpt_5_1_codex_max_migration_copy(),
);
screen.handle_key(KeyEvent::new(
KeyCode::Down,
crossterm::event::KeyModifiers::NONE,
));
screen.handle_key(KeyEvent::new(
KeyCode::Enter,
crossterm::event::KeyModifiers::NONE,
));
assert!(screen.is_done());
assert!(matches!(
screen.outcome(),
super::ModelMigrationOutcome::Rejected
));
}
}
@@ -2,14 +2,18 @@
source: tui/src/model_migration.rs
expression: terminal.backend()
---
> Introducing arcticfox
> Codex just got an upgrade. Introducing gpt-5.1-codex-max
We've upgraded our family of models supported in Codex to
arcticfox.
Codex is now powered by gpt-5.1-codex-max, our latest
frontier agentic coding model. It is smarter and faster
than its predecessors and capable of long-running
project-scale work.
You can continue using legacy models by specifying them
directly with the -m option or in your config.toml.
Learn more at www.openai.com/index/gpt-5-1-codex-max.
Learn more at www.openai.com/index/arcticfox.
Choose how you'd like Codex to proceed.
Press enter to continue
› 1. Try new model
2. Use existing model
Use ↑/↓ to move, press enter to confirm
@@ -10,7 +10,7 @@ expression: sanitized
│ Visit https://chatgpt.com/codex/settings/usage for up-to-date │
│ information on rate limits and credits │
│ │
│ Model: arcticfox (reasoning none, summaries auto) │
│ Model: gpt-5.1-codex-max (reasoning none, summaries auto) │
│ Directory: [[workspace]] │
│ Approval: on-request │
│ Sandbox: read-only │
@@ -4,20 +4,20 @@ expression: sanitized
---
/status
╭───────────────────────────────────────────────────────────────────╮
│ >_ OpenAI Codex (v0.0.0) │
│ │
│ Visit https://chatgpt.com/codex/settings/usage for up-to-date │
│ information on rate limits and credits │
│ │
│ Model: arcticfox (reasoning high, summaries detailed) │
│ Directory: [[workspace]] │
│ Approval: on-request │
│ Sandbox: workspace-write │
│ Agents.md: <none> │
│ │
│ Token usage: 1.9K total (1K input + 900 output) │
│ Context window: 100% left (2.25K used / 272K) │
│ 5h limit: [██████░░░░░░░░░░░░░░] 28% left (resets 03:14) │
│ Weekly limit: [███████████░░░░░░░░░] 55% left (resets 03:24) │
╰───────────────────────────────────────────────────────────────────╯
╭───────────────────────────────────────────────────────────────────────────╮
│ >_ OpenAI Codex (v0.0.0) │
│ │
│ Visit https://chatgpt.com/codex/settings/usage for up-to-date │
│ information on rate limits and credits │
│ │
│ Model: gpt-5.1-codex-max (reasoning high, summaries detailed) │
│ Directory: [[workspace]] │
│ Approval: on-request │
│ Sandbox: workspace-write │
│ Agents.md: <none> │
│ │
│ Token usage: 1.9K total (1K input + 900 output) │
│ Context window: 100% left (2.25K used / 272K) │
│ 5h limit: [██████░░░░░░░░░░░░░░] 28% left (resets 03:14) │
│ Weekly limit: [███████████░░░░░░░░░] 55% left (resets 03:24) │
╰───────────────────────────────────────────────────────────────────────────╯
@@ -4,19 +4,19 @@ expression: sanitized
---
/status
╭───────────────────────────────────────────────────────────────╮
│ >_ OpenAI Codex (v0.0.0) │
│ │
│ Visit https://chatgpt.com/codex/settings/usage for up-to-date │
│ information on rate limits and credits │
│ │
│ Model: arcticfox (reasoning none, summaries auto) │
│ Directory: [[workspace]] │
│ Approval: on-request │
│ Sandbox: read-only │
│ Agents.md: <none> │
│ │
│ Token usage: 750 total (500 input + 250 output) │
│ Context window: 100% left (750 used / 272K) │
│ Limits: data not available yet │
╰───────────────────────────────────────────────────────────────╯
╭───────────────────────────────────────────────────────────────────────╮
│ >_ OpenAI Codex (v0.0.0) │
│ │
│ Visit https://chatgpt.com/codex/settings/usage for up-to-date │
│ information on rate limits and credits │
│ │
│ Model: gpt-5.1-codex-max (reasoning none, summaries auto) │
│ Directory: [[workspace]] │
│ Approval: on-request │
│ Sandbox: read-only │
│ Agents.md: <none> │
│ │
│ Token usage: 750 total (500 input + 250 output) │
│ Context window: 100% left (750 used / 272K) │
│ Limits: data not available yet │
╰───────────────────────────────────────────────────────────────────────╯
@@ -4,19 +4,19 @@ expression: sanitized
---
/status
╭───────────────────────────────────────────────────────────────╮
│ >_ OpenAI Codex (v0.0.0) │
│ │
│ Visit https://chatgpt.com/codex/settings/usage for up-to-date │
│ information on rate limits and credits │
│ │
│ Model: arcticfox (reasoning none, summaries auto) │
│ Directory: [[workspace]] │
│ Approval: on-request │
│ Sandbox: read-only │
│ Agents.md: <none> │
│ │
│ Token usage: 750 total (500 input + 250 output) │
│ Context window: 100% left (750 used / 272K) │
│ Limits: data not available yet │
╰───────────────────────────────────────────────────────────────╯
╭───────────────────────────────────────────────────────────────────────╮
│ >_ OpenAI Codex (v0.0.0) │
│ │
│ Visit https://chatgpt.com/codex/settings/usage for up-to-date │
│ information on rate limits and credits │
│ │
│ Model: gpt-5.1-codex-max (reasoning none, summaries auto) │
│ Directory: [[workspace]] │
│ Approval: on-request │
│ Sandbox: read-only │
│ Agents.md: <none> │
│ │
│ Token usage: 750 total (500 input + 250 output) │
│ Context window: 100% left (750 used / 272K) │
│ Limits: data not available yet │
╰───────────────────────────────────────────────────────────────────────╯
@@ -4,21 +4,21 @@ expression: sanitized
---
/status
╭─────────────────────────────────────────────────────────────────────╮
│ >_ OpenAI Codex (v0.0.0) │
│ │
│ Visit https://chatgpt.com/codex/settings/usage for up-to-date │
│ information on rate limits and credits │
│ │
│ Model: arcticfox (reasoning none, summaries auto) │
│ Directory: [[workspace]] │
│ Approval: on-request │
│ Sandbox: read-only │
│ Agents.md: <none> │
│ │
│ Token usage: 1.9K total (1K input + 900 output) │
│ Context window: 100% left (2.25K used / 272K) │
│ 5h limit: [██████░░░░░░░░░░░░░░] 28% left (resets 03:14) │
│ Weekly limit: [████████████░░░░░░░░] 60% left (resets 03:34) │
│ Warning: limits may be stale - start new turn to refresh. │
╰─────────────────────────────────────────────────────────────────────╯
╭───────────────────────────────────────────────────────────────────────╮
│ >_ OpenAI Codex (v0.0.0) │
│ │
│ Visit https://chatgpt.com/codex/settings/usage for up-to-date │
│ information on rate limits and credits │
│ │
│ Model: gpt-5.1-codex-max (reasoning none, summaries auto) │
│ Directory: [[workspace]] │
│ Approval: on-request │
│ Sandbox: read-only │
│ Agents.md: <none> │
│ │
│ Token usage: 1.9K total (1K input + 900 output) │
│ Context window: 100% left (2.25K used / 272K) │
│ 5h limit: [██████░░░░░░░░░░░░░░] 28% left (resets 03:14) │
│ Weekly limit: [████████████░░░░░░░░] 60% left (resets 03:34) │
│ Warning: limits may be stale - start new turn to refresh. │
╰───────────────────────────────────────────────────────────────────────╯
@@ -4,19 +4,19 @@ expression: sanitized
---
/status
╭───────────────────────────────────────────────────────────────────╮
│ >_ OpenAI Codex (v0.0.0) │
│ │
│ Visit https://chatgpt.com/codex/settings/usage for up-to-date │
│ information on rate limits and credits │
│ │
│ Model: arcticfox (reasoning high, summaries detailed) │
│ Directory: [[workspace]] │
│ Approval: on-request │
│ Sandbox: read-only │
│ Agents.md: <none> │
│ │
│ Token usage: 1.9K total (1K input + 900 output) │
│ Context window: 100% left (2.25K used / 272K) │
│ 5h limit: [██████░░░░░░░░░░░░░░] 28% left (resets 03:14) │
╰───────────────────────────────────────────────────────────────────╯
╭────────────────────────────────────────────────────────────────────╮
│ >_ OpenAI Codex (v0.0.0) │
│ │
│ Visit https://chatgpt.com/codex/settings/usage for up-to-date │
│ information on rate limits and credits │
│ │
│ Model: gpt-5.1-codex-max (reasoning high, summaries de │
│ Directory: [[workspace]] │
│ Approval: on-request │
│ Sandbox: read-only │
│ Agents.md: <none> │
│ │
│ Token usage: 1.9K total (1K input + 900 output) │
│ Context window: 100% left (2.25K used / 272K) │
│ 5h limit: [██████░░░░░░░░░░░░░░] 28% left (resets 03:14) │
╰────────────────────────────────────────────────────────────────────╯
+7 -7
View File
@@ -81,7 +81,7 @@ fn reset_at_from(captured_at: &chrono::DateTime<chrono::Local>, seconds: i64) ->
fn status_snapshot_includes_reasoning_details() {
let temp_home = TempDir::new().expect("temp home");
let mut config = test_config(&temp_home);
config.model = "arcticfox".to_string();
config.model = "gpt-5.1-codex-max".to_string();
config.model_provider_id = "openai".to_string();
config.model_reasoning_effort = Some(ReasoningEffort::High);
config.model_reasoning_summary = ReasoningSummary::Detailed;
@@ -144,7 +144,7 @@ fn status_snapshot_includes_reasoning_details() {
fn status_snapshot_includes_monthly_limit() {
let temp_home = TempDir::new().expect("temp home");
let mut config = test_config(&temp_home);
config.model = "arcticfox".to_string();
config.model = "gpt-5.1-codex-max".to_string();
config.model_provider_id = "openai".to_string();
config.cwd = PathBuf::from("/workspace/tests");
@@ -194,7 +194,7 @@ fn status_snapshot_includes_monthly_limit() {
fn status_card_token_usage_excludes_cached_tokens() {
let temp_home = TempDir::new().expect("temp home");
let mut config = test_config(&temp_home);
config.model = "arcticfox".to_string();
config.model = "gpt-5.1-codex-max".to_string();
config.cwd = PathBuf::from("/workspace/tests");
let auth_manager = test_auth_manager(&config);
@@ -232,7 +232,7 @@ fn status_card_token_usage_excludes_cached_tokens() {
fn status_snapshot_truncates_in_narrow_terminal() {
let temp_home = TempDir::new().expect("temp home");
let mut config = test_config(&temp_home);
config.model = "arcticfox".to_string();
config.model = "gpt-5.1-codex-max".to_string();
config.model_provider_id = "openai".to_string();
config.model_reasoning_effort = Some(ReasoningEffort::High);
config.model_reasoning_summary = ReasoningSummary::Detailed;
@@ -285,7 +285,7 @@ fn status_snapshot_truncates_in_narrow_terminal() {
fn status_snapshot_shows_missing_limits_message() {
let temp_home = TempDir::new().expect("temp home");
let mut config = test_config(&temp_home);
config.model = "arcticfox".to_string();
config.model = "gpt-5.1-codex-max".to_string();
config.cwd = PathBuf::from("/workspace/tests");
let auth_manager = test_auth_manager(&config);
@@ -325,7 +325,7 @@ fn status_snapshot_shows_missing_limits_message() {
fn status_snapshot_shows_empty_limits_message() {
let temp_home = TempDir::new().expect("temp home");
let mut config = test_config(&temp_home);
config.model = "arcticfox".to_string();
config.model = "gpt-5.1-codex-max".to_string();
config.cwd = PathBuf::from("/workspace/tests");
let auth_manager = test_auth_manager(&config);
@@ -370,7 +370,7 @@ fn status_snapshot_shows_empty_limits_message() {
fn status_snapshot_shows_stale_limits_message() {
let temp_home = TempDir::new().expect("temp home");
let mut config = test_config(&temp_home);
config.model = "arcticfox".to_string();
config.model = "gpt-5.1-codex-max".to_string();
config.cwd = PathBuf::from("/workspace/tests");
let auth_manager = test_auth_manager(&config);