mirror of
https://github.com/openai/codex.git
synced 2026-04-28 00:25:56 +00:00
add fast mode toggle (#13212)
- add a local Fast mode setting in codex-core (similar to how model id is currently stored on disk locally) - send `service_tier=priority` on requests when Fast is enabled - add `/fast` in the TUI and persist it locally - feature flag
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
use anyhow::Result;
|
||||
use codex_core::features::Feature;
|
||||
use codex_protocol::config_types::ServiceTier;
|
||||
use core_test_support::responses::WebSocketConnectionConfig;
|
||||
use core_test_support::responses::ev_assistant_message;
|
||||
use core_test_support::responses::ev_completed;
|
||||
@@ -244,3 +245,171 @@ async fn websocket_v2_test_codex_shell_chain() -> Result<()> {
|
||||
server.shutdown().await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn websocket_v2_first_turn_uses_updated_fast_tier_after_startup_prewarm() -> Result<()> {
|
||||
skip_if_no_network!(Ok(()));
|
||||
|
||||
let server = start_websocket_server(vec![vec![
|
||||
vec![ev_response_created("warm-1"), ev_done_with_id("warm-1")],
|
||||
vec![
|
||||
ev_response_created("resp-1"),
|
||||
ev_assistant_message("msg-1", "fast"),
|
||||
ev_completed("resp-1"),
|
||||
],
|
||||
]])
|
||||
.await;
|
||||
|
||||
let mut builder = test_codex().with_config(|config| {
|
||||
config.features.enable(Feature::ResponsesWebsocketsV2);
|
||||
});
|
||||
let test = builder.build_with_websocket_server(&server).await?;
|
||||
|
||||
let warmup = server.wait_for_request(0, 0).await.body_json();
|
||||
assert_eq!(warmup["type"].as_str(), Some("response.create"));
|
||||
assert_eq!(warmup["generate"].as_bool(), Some(false));
|
||||
assert_eq!(warmup.get("service_tier"), None);
|
||||
|
||||
test.submit_turn_with_service_tier("hello", Some(ServiceTier::Fast))
|
||||
.await?;
|
||||
|
||||
assert_eq!(server.handshakes().len(), 1);
|
||||
let connection = server.single_connection();
|
||||
assert_eq!(connection.len(), 2);
|
||||
let first_turn = connection
|
||||
.get(1)
|
||||
.expect("missing first turn request")
|
||||
.body_json();
|
||||
|
||||
assert_eq!(first_turn["type"].as_str(), Some("response.create"));
|
||||
assert_eq!(first_turn["service_tier"].as_str(), Some("priority"));
|
||||
assert_eq!(first_turn.get("previous_response_id"), None);
|
||||
assert!(
|
||||
first_turn
|
||||
.get("input")
|
||||
.and_then(Value::as_array)
|
||||
.is_some_and(|items| !items.is_empty())
|
||||
);
|
||||
|
||||
server.shutdown().await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn websocket_v2_first_turn_drops_fast_tier_after_startup_prewarm() -> Result<()> {
|
||||
skip_if_no_network!(Ok(()));
|
||||
|
||||
let server = start_websocket_server(vec![vec![
|
||||
vec![ev_response_created("warm-1"), ev_done_with_id("warm-1")],
|
||||
vec![
|
||||
ev_response_created("resp-1"),
|
||||
ev_assistant_message("msg-1", "standard"),
|
||||
ev_completed("resp-1"),
|
||||
],
|
||||
]])
|
||||
.await;
|
||||
|
||||
let mut builder = test_codex().with_config(|config| {
|
||||
config.features.enable(Feature::ResponsesWebsocketsV2);
|
||||
config.service_tier = Some(ServiceTier::Fast);
|
||||
});
|
||||
let test = builder.build_with_websocket_server(&server).await?;
|
||||
|
||||
let warmup = server.wait_for_request(0, 0).await.body_json();
|
||||
assert_eq!(warmup["type"].as_str(), Some("response.create"));
|
||||
assert_eq!(warmup["generate"].as_bool(), Some(false));
|
||||
assert_eq!(warmup["service_tier"].as_str(), Some("priority"));
|
||||
|
||||
test.submit_turn_with_service_tier("hello", None).await?;
|
||||
|
||||
assert_eq!(server.handshakes().len(), 1);
|
||||
let connection = server.single_connection();
|
||||
assert_eq!(connection.len(), 2);
|
||||
let first_turn = connection
|
||||
.get(1)
|
||||
.expect("missing first turn request")
|
||||
.body_json();
|
||||
|
||||
assert_eq!(first_turn["type"].as_str(), Some("response.create"));
|
||||
assert_eq!(first_turn.get("service_tier"), None);
|
||||
assert_eq!(first_turn.get("previous_response_id"), None);
|
||||
assert!(
|
||||
first_turn
|
||||
.get("input")
|
||||
.and_then(Value::as_array)
|
||||
.is_some_and(|items| !items.is_empty())
|
||||
);
|
||||
|
||||
server.shutdown().await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn websocket_v2_next_turn_uses_updated_service_tier() -> Result<()> {
|
||||
skip_if_no_network!(Ok(()));
|
||||
|
||||
let server = start_websocket_server(vec![vec![
|
||||
vec![ev_response_created("warm-1"), ev_done_with_id("warm-1")],
|
||||
vec![
|
||||
ev_response_created("resp-1"),
|
||||
ev_assistant_message("msg-1", "fast"),
|
||||
ev_completed("resp-1"),
|
||||
],
|
||||
vec![
|
||||
ev_response_created("resp-2"),
|
||||
ev_assistant_message("msg-2", "standard"),
|
||||
ev_completed("resp-2"),
|
||||
],
|
||||
]])
|
||||
.await;
|
||||
|
||||
let mut builder = test_codex().with_config(|config| {
|
||||
config.features.enable(Feature::ResponsesWebsocketsV2);
|
||||
});
|
||||
let test = builder.build_with_websocket_server(&server).await?;
|
||||
|
||||
let warmup = server.wait_for_request(0, 0).await.body_json();
|
||||
assert_eq!(warmup["type"].as_str(), Some("response.create"));
|
||||
assert_eq!(warmup["generate"].as_bool(), Some(false));
|
||||
assert_eq!(warmup.get("service_tier"), None);
|
||||
|
||||
test.submit_turn_with_service_tier("first", Some(ServiceTier::Fast))
|
||||
.await?;
|
||||
test.submit_turn_with_service_tier("second", None).await?;
|
||||
|
||||
assert_eq!(server.handshakes().len(), 1);
|
||||
let connection = server.single_connection();
|
||||
assert_eq!(connection.len(), 3);
|
||||
|
||||
let first_turn = connection
|
||||
.get(1)
|
||||
.expect("missing first turn request")
|
||||
.body_json();
|
||||
let second_turn = connection
|
||||
.get(2)
|
||||
.expect("missing second turn request")
|
||||
.body_json();
|
||||
|
||||
assert_eq!(first_turn["type"].as_str(), Some("response.create"));
|
||||
assert_eq!(first_turn["service_tier"].as_str(), Some("priority"));
|
||||
assert_eq!(first_turn.get("previous_response_id"), None);
|
||||
assert!(
|
||||
first_turn
|
||||
.get("input")
|
||||
.and_then(Value::as_array)
|
||||
.is_some_and(|items| !items.is_empty())
|
||||
);
|
||||
|
||||
assert_eq!(second_turn["type"].as_str(), Some("response.create"));
|
||||
assert_eq!(second_turn.get("service_tier"), None);
|
||||
assert_eq!(second_turn.get("previous_response_id"), None);
|
||||
assert!(
|
||||
second_turn
|
||||
.get("input")
|
||||
.and_then(Value::as_array)
|
||||
.is_some_and(|items| !items.is_empty())
|
||||
);
|
||||
|
||||
server.shutdown().await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user