mirror of
https://github.com/openai/codex.git
synced 2026-04-24 14:45:27 +00:00
codex: stabilize realtime startup context websockets
This commit is contained in:
@@ -660,21 +660,23 @@ async fn conversation_uses_experimental_realtime_ws_backend_prompt_override() ->
|
||||
async fn conversation_uses_experimental_realtime_ws_startup_context_override() -> Result<()> {
|
||||
skip_if_no_network!(Ok(()));
|
||||
|
||||
let server = start_websocket_server(vec![
|
||||
vec![],
|
||||
vec![vec![json!({
|
||||
"type": "session.updated",
|
||||
"session": { "id": "sess_custom_context", "instructions": "prompt from config" }
|
||||
})]],
|
||||
])
|
||||
let startup_server = start_websocket_server(vec![vec![]]).await;
|
||||
let realtime_server = start_websocket_server(vec![vec![vec![json!({
|
||||
"type": "session.updated",
|
||||
"session": { "id": "sess_custom_context", "instructions": "prompt from config" }
|
||||
})]]])
|
||||
.await;
|
||||
|
||||
let mut builder = test_codex().with_config(|config| {
|
||||
config.experimental_realtime_ws_backend_prompt = Some("prompt from config".to_string());
|
||||
config.experimental_realtime_ws_startup_context =
|
||||
Some("custom startup context".to_string());
|
||||
let mut builder = test_codex().with_config({
|
||||
let realtime_base_url = realtime_server.uri().to_string();
|
||||
move |config| {
|
||||
config.experimental_realtime_ws_base_url = Some(realtime_base_url);
|
||||
config.experimental_realtime_ws_backend_prompt = Some("prompt from config".to_string());
|
||||
config.experimental_realtime_ws_startup_context =
|
||||
Some("custom startup context".to_string());
|
||||
}
|
||||
});
|
||||
let test = builder.build_with_websocket_server(&server).await?;
|
||||
let test = builder.build_with_websocket_server(&startup_server).await?;
|
||||
seed_recent_thread(
|
||||
&test,
|
||||
"Recent work: cleaned up startup flows and reviewed websocket routing.",
|
||||
@@ -684,7 +686,11 @@ async fn conversation_uses_experimental_realtime_ws_startup_context_override() -
|
||||
.await?;
|
||||
fs::create_dir_all(test.workspace_path("docs"))?;
|
||||
fs::write(test.workspace_path("README.md"), "workspace marker")?;
|
||||
assert!(server.wait_for_handshakes(1, Duration::from_secs(2)).await);
|
||||
assert!(
|
||||
startup_server
|
||||
.wait_for_handshakes(1, Duration::from_secs(2))
|
||||
.await
|
||||
);
|
||||
|
||||
test.codex
|
||||
.submit(Op::RealtimeConversationStart(ConversationStartParams {
|
||||
@@ -694,7 +700,7 @@ async fn conversation_uses_experimental_realtime_ws_startup_context_override() -
|
||||
.await?;
|
||||
|
||||
let startup_context_request = wait_for_matching_websocket_request(
|
||||
&server,
|
||||
&realtime_server,
|
||||
"startup context request with instructions",
|
||||
|request| websocket_request_instructions(request).is_some(),
|
||||
)
|
||||
@@ -706,7 +712,8 @@ async fn conversation_uses_experimental_realtime_ws_startup_context_override() -
|
||||
assert!(!instructions.contains(STARTUP_CONTEXT_HEADER));
|
||||
assert!(!instructions.contains("## Machine / Workspace Map"));
|
||||
|
||||
server.shutdown().await;
|
||||
startup_server.shutdown().await;
|
||||
realtime_server.shutdown().await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -714,20 +721,22 @@ async fn conversation_uses_experimental_realtime_ws_startup_context_override() -
|
||||
async fn conversation_disables_realtime_startup_context_with_empty_override() -> Result<()> {
|
||||
skip_if_no_network!(Ok(()));
|
||||
|
||||
let server = start_websocket_server(vec![
|
||||
vec![],
|
||||
vec![vec![json!({
|
||||
"type": "session.updated",
|
||||
"session": { "id": "sess_no_context", "instructions": "prompt from config" }
|
||||
})]],
|
||||
])
|
||||
let startup_server = start_websocket_server(vec![vec![]]).await;
|
||||
let realtime_server = start_websocket_server(vec![vec![vec![json!({
|
||||
"type": "session.updated",
|
||||
"session": { "id": "sess_no_context", "instructions": "prompt from config" }
|
||||
})]]])
|
||||
.await;
|
||||
|
||||
let mut builder = test_codex().with_config(|config| {
|
||||
config.experimental_realtime_ws_backend_prompt = Some("prompt from config".to_string());
|
||||
config.experimental_realtime_ws_startup_context = Some(String::new());
|
||||
let mut builder = test_codex().with_config({
|
||||
let realtime_base_url = realtime_server.uri().to_string();
|
||||
move |config| {
|
||||
config.experimental_realtime_ws_base_url = Some(realtime_base_url);
|
||||
config.experimental_realtime_ws_backend_prompt = Some("prompt from config".to_string());
|
||||
config.experimental_realtime_ws_startup_context = Some(String::new());
|
||||
}
|
||||
});
|
||||
let test = builder.build_with_websocket_server(&server).await?;
|
||||
let test = builder.build_with_websocket_server(&startup_server).await?;
|
||||
seed_recent_thread(
|
||||
&test,
|
||||
"Recent work: cleaned up startup flows and reviewed websocket routing.",
|
||||
@@ -737,7 +746,11 @@ async fn conversation_disables_realtime_startup_context_with_empty_override() ->
|
||||
.await?;
|
||||
fs::create_dir_all(test.workspace_path("docs"))?;
|
||||
fs::write(test.workspace_path("README.md"), "workspace marker")?;
|
||||
assert!(server.wait_for_handshakes(1, Duration::from_secs(2)).await);
|
||||
assert!(
|
||||
startup_server
|
||||
.wait_for_handshakes(1, Duration::from_secs(2))
|
||||
.await
|
||||
);
|
||||
|
||||
test.codex
|
||||
.submit(Op::RealtimeConversationStart(ConversationStartParams {
|
||||
@@ -747,7 +760,7 @@ async fn conversation_disables_realtime_startup_context_with_empty_override() ->
|
||||
.await?;
|
||||
|
||||
let startup_context_request = wait_for_matching_websocket_request(
|
||||
&server,
|
||||
&realtime_server,
|
||||
"startup context disable request with instructions",
|
||||
|request| websocket_request_instructions(request).is_some(),
|
||||
)
|
||||
@@ -759,7 +772,8 @@ async fn conversation_disables_realtime_startup_context_with_empty_override() ->
|
||||
assert!(!instructions.contains(STARTUP_CONTEXT_HEADER));
|
||||
assert!(!instructions.contains("## Machine / Workspace Map"));
|
||||
|
||||
server.shutdown().await;
|
||||
startup_server.shutdown().await;
|
||||
realtime_server.shutdown().await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -767,17 +781,20 @@ async fn conversation_disables_realtime_startup_context_with_empty_override() ->
|
||||
async fn conversation_start_injects_startup_context_from_thread_history() -> Result<()> {
|
||||
skip_if_no_network!(Ok(()));
|
||||
|
||||
let server = start_websocket_server(vec![
|
||||
vec![],
|
||||
vec![vec![json!({
|
||||
"type": "session.updated",
|
||||
"session": { "id": "sess_context", "instructions": "backend prompt" }
|
||||
})]],
|
||||
])
|
||||
let startup_server = start_websocket_server(vec![vec![]]).await;
|
||||
let realtime_server = start_websocket_server(vec![vec![vec![json!({
|
||||
"type": "session.updated",
|
||||
"session": { "id": "sess_context", "instructions": "backend prompt" }
|
||||
})]]])
|
||||
.await;
|
||||
|
||||
let mut builder = test_codex();
|
||||
let test = builder.build_with_websocket_server(&server).await?;
|
||||
let mut builder = test_codex().with_config({
|
||||
let realtime_base_url = realtime_server.uri().to_string();
|
||||
move |config| {
|
||||
config.experimental_realtime_ws_base_url = Some(realtime_base_url);
|
||||
}
|
||||
});
|
||||
let test = builder.build_with_websocket_server(&startup_server).await?;
|
||||
seed_recent_thread(
|
||||
&test,
|
||||
"Recent work: cleaned up startup flows and reviewed websocket routing.",
|
||||
@@ -796,7 +813,7 @@ async fn conversation_start_injects_startup_context_from_thread_history() -> Res
|
||||
.await?;
|
||||
|
||||
let startup_context_request = wait_for_matching_websocket_request(
|
||||
&server,
|
||||
&realtime_server,
|
||||
"startup context request with instructions",
|
||||
|request| websocket_request_instructions(request).is_some(),
|
||||
)
|
||||
@@ -815,7 +832,8 @@ async fn conversation_start_injects_startup_context_from_thread_history() -> Res
|
||||
assert!(startup_context.contains("README.md"));
|
||||
assert!(!startup_context.contains(MEMORY_PROMPT_PHRASE));
|
||||
|
||||
server.shutdown().await;
|
||||
startup_server.shutdown().await;
|
||||
realtime_server.shutdown().await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -823,17 +841,20 @@ async fn conversation_start_injects_startup_context_from_thread_history() -> Res
|
||||
async fn conversation_startup_context_falls_back_to_workspace_map() -> Result<()> {
|
||||
skip_if_no_network!(Ok(()));
|
||||
|
||||
let server = start_websocket_server(vec![
|
||||
vec![],
|
||||
vec![vec![json!({
|
||||
"type": "session.updated",
|
||||
"session": { "id": "sess_workspace", "instructions": "backend prompt" }
|
||||
})]],
|
||||
])
|
||||
let startup_server = start_websocket_server(vec![vec![]]).await;
|
||||
let realtime_server = start_websocket_server(vec![vec![vec![json!({
|
||||
"type": "session.updated",
|
||||
"session": { "id": "sess_workspace", "instructions": "backend prompt" }
|
||||
})]]])
|
||||
.await;
|
||||
|
||||
let mut builder = test_codex();
|
||||
let test = builder.build_with_websocket_server(&server).await?;
|
||||
let mut builder = test_codex().with_config({
|
||||
let realtime_base_url = realtime_server.uri().to_string();
|
||||
move |config| {
|
||||
config.experimental_realtime_ws_base_url = Some(realtime_base_url);
|
||||
}
|
||||
});
|
||||
let test = builder.build_with_websocket_server(&startup_server).await?;
|
||||
fs::create_dir_all(test.workspace_path("codex-rs/core"))?;
|
||||
fs::write(test.workspace_path("notes.txt"), "workspace marker")?;
|
||||
|
||||
@@ -845,7 +866,7 @@ async fn conversation_startup_context_falls_back_to_workspace_map() -> Result<()
|
||||
.await?;
|
||||
|
||||
let startup_context_request = wait_for_matching_websocket_request(
|
||||
&server,
|
||||
&realtime_server,
|
||||
"workspace-map startup context request with instructions",
|
||||
|request| websocket_request_instructions(request).is_some(),
|
||||
)
|
||||
@@ -858,7 +879,8 @@ async fn conversation_startup_context_falls_back_to_workspace_map() -> Result<()
|
||||
assert!(startup_context.contains("notes.txt"));
|
||||
assert!(startup_context.contains("codex-rs/"));
|
||||
|
||||
server.shutdown().await;
|
||||
startup_server.shutdown().await;
|
||||
realtime_server.shutdown().await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -866,21 +888,24 @@ async fn conversation_startup_context_falls_back_to_workspace_map() -> Result<()
|
||||
async fn conversation_startup_context_is_truncated_and_sent_once_per_start() -> Result<()> {
|
||||
skip_if_no_network!(Ok(()));
|
||||
|
||||
let server = start_websocket_server(vec![
|
||||
let startup_server = start_websocket_server(vec![vec![]]).await;
|
||||
let realtime_server = start_websocket_server(vec![vec![vec![
|
||||
vec![json!({
|
||||
"type": "session.updated",
|
||||
"session": { "id": "sess_truncated", "instructions": "backend prompt" }
|
||||
})],
|
||||
vec![],
|
||||
vec![
|
||||
vec![json!({
|
||||
"type": "session.updated",
|
||||
"session": { "id": "sess_truncated", "instructions": "backend prompt" }
|
||||
})],
|
||||
vec![],
|
||||
],
|
||||
])
|
||||
]]])
|
||||
.await;
|
||||
|
||||
let oversized_summary = "recent work ".repeat(3_500);
|
||||
let mut builder = test_codex();
|
||||
let test = builder.build_with_websocket_server(&server).await?;
|
||||
let mut builder = test_codex().with_config({
|
||||
let realtime_base_url = realtime_server.uri().to_string();
|
||||
move |config| {
|
||||
config.experimental_realtime_ws_base_url = Some(realtime_base_url);
|
||||
}
|
||||
});
|
||||
let test = builder.build_with_websocket_server(&startup_server).await?;
|
||||
seed_recent_thread(&test, &oversized_summary, "summary", "oversized").await?;
|
||||
fs::write(test.workspace_path("marker.txt"), "marker")?;
|
||||
|
||||
@@ -892,7 +917,7 @@ async fn conversation_startup_context_is_truncated_and_sent_once_per_start() ->
|
||||
.await?;
|
||||
|
||||
let startup_context_request = wait_for_matching_websocket_request(
|
||||
&server,
|
||||
&realtime_server,
|
||||
"truncated startup context request with instructions",
|
||||
|request| websocket_request_instructions(request).is_some(),
|
||||
)
|
||||
@@ -908,17 +933,19 @@ async fn conversation_startup_context_is_truncated_and_sent_once_per_start() ->
|
||||
}))
|
||||
.await?;
|
||||
|
||||
let explicit_text_request =
|
||||
wait_for_matching_websocket_request(&server, "explicit realtime text request", |request| {
|
||||
websocket_request_text(request).as_deref() == Some("hello")
|
||||
})
|
||||
.await;
|
||||
let explicit_text_request = wait_for_matching_websocket_request(
|
||||
&realtime_server,
|
||||
"explicit realtime text request",
|
||||
|request| websocket_request_text(request).as_deref() == Some("hello"),
|
||||
)
|
||||
.await;
|
||||
assert_eq!(
|
||||
websocket_request_text(&explicit_text_request),
|
||||
Some("hello".to_string())
|
||||
);
|
||||
|
||||
server.shutdown().await;
|
||||
startup_server.shutdown().await;
|
||||
realtime_server.shutdown().await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user