core: clear active turn on task abort to avoid stale turn state (#4173)

This commit is contained in:
jif-oai
2025-09-24 18:13:34 +01:00
committed by GitHub
parent e553ff6f17
commit fa75e63824
4 changed files with 14 additions and 26 deletions

View File

@@ -116,9 +116,9 @@ use crate::rollout::RolloutRecorderParams;
use crate::safety::SafetyCheck;
use crate::safety::assess_command_safety;
use crate::safety::assess_safety_for_untrusted_command;
use crate::services::SessionServices;
use crate::shell;
use crate::state::ActiveTurn;
use crate::state::SessionServices;
use crate::turn_diff_tracker::TurnDiffTracker;
use crate::unified_exec::UnifiedExecSessionManager;
use crate::user_instructions::UserInstructions;
@@ -1191,15 +1191,19 @@ impl AgentTask {
// TOCTOU?
if !self.handle.is_finished() {
self.handle.abort();
let sub_id = self.sub_id.clone();
let is_review = self.kind == AgentTaskKind::Review;
let sess = self.sess;
let event = Event {
id: self.sub_id.clone(),
id: sub_id.clone(),
msg: EventMsg::TurnAborted(TurnAbortedEvent { reason }),
};
let sess = self.sess;
tokio::spawn(async move {
if self.kind == AgentTaskKind::Review {
exit_review_mode(sess.clone(), self.sub_id, None).await;
if is_review {
exit_review_mode(sess.clone(), sub_id.clone(), None).await;
}
// Ensure active turn state is cleared when a task is aborted.
sess.remove_task(&sub_id).await;
sess.send_event(event).await;
});
}

View File

@@ -47,7 +47,6 @@ pub use model_provider_info::create_oss_provider_with_base_url;
mod conversation_manager;
mod event_mapping;
pub mod review_format;
mod services;
pub use codex_protocol::protocol::InitialHistory;
pub use conversation_manager::ConversationManager;
pub use conversation_manager::NewConversation;

View File

@@ -1,18 +1,8 @@
//! Session/turn state module.
//!
//! Encapsulates all mutable state for a Codex session and the currently active
//! turn. The goal is to present lock-safe, narrow APIs so other modules never
//! need to poke at raw mutexes or internal fields.
//!
//! Locking guidelines
//! - Lock ordering: `SessionState` → `ActiveTurn` → `TurnState`.
//! - Never hold a lock across an `.await`. Extract minimal data and drop the
//! guard before awaiting.
//! - Prefer helper methods on these types rather than exposing fields.
mod service;
mod session;
mod turn;
pub(crate) use service::SessionServices;
pub(crate) use session::SessionState;
pub(crate) use turn::ActiveTurn;
pub(crate) use turn::TurnState;

View File

@@ -1,16 +1,11 @@
//! Group longlived helpers/managers for a session.
use std::path::PathBuf;
use tokio::sync::Mutex;
use crate::RolloutRecorder;
use crate::exec_command::ExecSessionManager;
use crate::mcp_connection_manager::McpConnectionManager;
use crate::rollout::RolloutRecorder;
use crate::unified_exec::UnifiedExecSessionManager;
use crate::user_notification::UserNotifier;
use std::path::PathBuf;
use tokio::sync::Mutex;
/// Container for sideeffectful services and helpers used by `Session`.
pub(crate) struct SessionServices {
pub(crate) mcp_connection_manager: McpConnectionManager,
pub(crate) session_manager: ExecSessionManager,