core/src/agent/control/legacy.rs
84 lines
use super::*;impl AgentControl { /// Submit a shutdown request for a live agent without marking it explicitly closed in /// persisted spawn-edge state. pub(crate) async fn shutdown_live_agent(&self, agent_id: ThreadId) -> CodexResult<String> { let state = self.upgrade()?; let result = if let Ok(thread) = state.get_thread(agent_id).await { thread.codex.session.ensure_rollout_materialized().await; thread.codex.session.flush_rollout().await?; let result = if matches!(thread.agent_status().await, AgentStatus::Shutdown) { Ok(String::new()) } else { state.send_op(agent_id, Op::Shutdown {}).await }; thread.wait_until_terminated().await; result } else { state.send_op(agent_id, Op::Shutdown {}).await }; let _ = state.remove_thread(&agent_id).await; self.forget_v2_residency(agent_id); self.state.release_spawned_thread(agent_id); result } /// Mark `agent_id` as explicitly closed in persisted spawn-edge state, then shut down the /// agent and any live descendants reached from the in-memory tree. pub(crate) async fn close_agent(&self, agent_id: ThreadId) -> CodexResult<String> { let state = self.upgrade()?; let known_agent = self.state.agent_metadata_for_thread(agent_id).is_some(); match state.get_thread(agent_id).await { Ok(thread) => { if let Some(state_db_ctx) = thread.state_db() && let Err(err) = state_db_ctx .set_thread_spawn_edge_status( agent_id, DirectionalThreadSpawnEdgeStatus::Closed, ) .await { warn!("failed to persist thread-spawn edge status for {agent_id}: {err}"); } } Err(CodexErr::ThreadNotFound(_)) if known_agent => { if let Some(state_db_ctx) = state.state_db() && let Err(err) = state_db_ctx .set_thread_spawn_edge_status( agent_id, DirectionalThreadSpawnEdgeStatus::Closed, ) .await { return Err(CodexErr::Fatal(format!( "failed to persist stale thread-spawn edge status for {agent_id}: {err}" ))); } } Err(CodexErr::ThreadNotFound(_)) => {} Err(err) => { warn!("failed to inspect agent before close {agent_id}: {err}"); } } match Box::pin(self.shutdown_agent_tree(agent_id)).await { Err(CodexErr::ThreadNotFound(_)) | Err(CodexErr::InternalAgentDied) if known_agent => { Ok(String::new()) } result => result, } } /// Shut down `agent_id` and any live descendants reachable from the in-memory spawn tree. pub(crate) async fn shutdown_agent_tree(&self, agent_id: ThreadId) -> CodexResult<String> { let descendant_ids = self.live_thread_spawn_descendants(agent_id).await?; let result = self.shutdown_live_agent(agent_id).await; for descendant_id in descendant_ids { match self.shutdown_live_agent(descendant_id).await { Ok(_) | Err(CodexErr::ThreadNotFound(_)) | Err(CodexErr::InternalAgentDied) => {} Err(err) => return Err(err), } } result }}