Merge b7537fec0a into sapling-pr-archive-rhan-oai

This commit is contained in:
rhan-oai
2026-04-03 18:04:16 -07:00
committed by GitHub
2 changed files with 34 additions and 5 deletions
@@ -1800,7 +1800,14 @@ pub(crate) async fn apply_bespoke_event_handling(
thread_watch_manager
.note_turn_interrupted(&conversation_id.to_string())
.await;
handle_turn_interrupted(conversation_id, event_turn_id, &outgoing, &thread_state).await;
handle_turn_interrupted(
conversation_id,
event_turn_id,
Some(&analytics_events_client),
&outgoing,
&thread_state,
)
.await;
}
EventMsg::ThreadRolledBack(_rollback_event) => {
let pending = {
@@ -2158,6 +2165,7 @@ async fn handle_turn_complete(
async fn handle_turn_interrupted(
conversation_id: ThreadId,
event_turn_id: String,
analytics_events_client: Option<&AnalyticsEventsClient>,
outgoing: &ThreadScopedOutgoingMessageSender,
thread_state: &Arc<Mutex<ThreadState>>,
) {
@@ -2169,7 +2177,7 @@ async fn handle_turn_interrupted(
TurnStatus::Interrupted,
/*error*/ None,
turn_summary.started_at_ms,
/*analytics_events_client*/ None,
analytics_events_client,
outgoing,
)
.await;
@@ -3392,6 +3400,7 @@ mod tests {
handle_turn_interrupted(
conversation_id,
event_turn_id.clone(),
/*analytics_events_client*/ None,
&outgoing,
&thread_state,
)
@@ -5,6 +5,7 @@ use app_test_support::McpProcess;
use app_test_support::create_mock_responses_server_sequence;
use app_test_support::create_shell_command_sse_response;
use app_test_support::to_response;
use app_test_support::write_mock_responses_config_toml_with_chatgpt_base_url;
use codex_app_server_protocol::JSONRPCNotification;
use codex_app_server_protocol::JSONRPCResponse;
use codex_app_server_protocol::RequestId;
@@ -22,6 +23,9 @@ use codex_app_server_protocol::UserInput as V2UserInput;
use tempfile::TempDir;
use tokio::time::timeout;
use super::analytics::enable_analytics_capture;
use super::analytics::wait_for_analytics_event;
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
#[tokio::test]
@@ -50,7 +54,12 @@ async fn turn_interrupt_aborts_running_turn() -> Result<()> {
"call_sleep",
)?])
.await;
create_config_toml(&codex_home, &server.uri(), "never")?;
write_mock_responses_config_toml_with_chatgpt_base_url(
&codex_home,
&server.uri(),
&server.uri(),
)?;
enable_analytics_capture(&server, &codex_home).await?;
let mut mcp = McpProcess::new(&codex_home).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
@@ -87,6 +96,7 @@ async fn turn_interrupt_aborts_running_turn() -> Result<()> {
)
.await??;
let TurnStartResponse { turn } = to_response::<TurnStartResponse>(turn_resp)?;
let turn_id = turn.id.clone();
// Give the command a brief moment to start.
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
@@ -96,7 +106,7 @@ async fn turn_interrupt_aborts_running_turn() -> Result<()> {
let interrupt_id = mcp
.send_turn_interrupt_request(TurnInterruptParams {
thread_id: thread_id.clone(),
turn_id: turn.id,
turn_id: turn_id.clone(),
})
.await?;
let interrupt_resp: JSONRPCResponse = timeout(
@@ -119,6 +129,12 @@ async fn turn_interrupt_aborts_running_turn() -> Result<()> {
assert_eq!(completed.thread_id, thread_id);
assert_eq!(completed.turn.status, TurnStatus::Interrupted);
let event = wait_for_analytics_event(&server, DEFAULT_READ_TIMEOUT, "codex_turn_event").await?;
assert_eq!(event["event_params"]["thread_id"], thread_id);
assert_eq!(event["event_params"]["turn_id"], turn_id);
assert_eq!(event["event_params"]["status"], "interrupted");
assert_eq!(event["event_params"]["turn_error"], serde_json::Value::Null);
Ok(())
}
@@ -131,7 +147,11 @@ async fn turn_interrupt_resolves_pending_command_approval_request() -> Result<()
"Start-Sleep -Seconds 10".to_string(),
];
#[cfg(not(target_os = "windows"))]
let shell_command = vec!["sleep".to_string(), "10".to_string()];
let shell_command = vec![
"python3".to_string(),
"-c".to_string(),
"import time; time.sleep(10)".to_string(),
];
let tmp = TempDir::new()?;
let codex_home = tmp.path().join("codex_home");