Download codex-rs/core/src/agent/control/interrupt.rs from SaylorTwift/codex: direct link, hf CLI and curl.
- Browser
- Download file 2.44 kB
-
https://huggingface.co/SaylorTwift/codex/resolve/main/codex-rs/core/src/agent/control/interrupt.rs
- Command line
-
hf download hf://SaylorTwift/codex/codex-rs/core/src/agent/control/interrupt.rs
-
curl -L -o interrupt.rs https://huggingface.co/SaylorTwift/codex/resolve/main/codex-rs/core/src/agent/control/interrupt.rs
2.44 kB
| //! Applies V2 interruption rules to a registered agent without loading its runtime. | |
| //! | |
| //! Root and self targets are rejected. An unloaded or already-dead runtime is a successful | |
| //! interruption; this operation never reloads it. | |
| use super::AgentControl; | |
| use crate::agent::AgentStatus; | |
| use codex_protocol::AgentPath; | |
| use codex_protocol::ThreadId; | |
| use codex_protocol::error::CodexErr; | |
| use codex_protocol::error::CodexErrorDetails; | |
| pub(crate) struct AgentInterruptOutcome { | |
| pub(crate) agent_path: AgentPath, | |
| pub(crate) previous_status: AgentStatus, | |
| } | |
| /// Keeps request validation distinct from runtime failures for the tool adapter's error mapping. | |
| pub(crate) enum AgentInterruptError { | |
| InvalidRequest(String), | |
| Agent(CodexErr), | |
| } | |
| impl AgentControl { | |
| /// Interrupts a spawned agent's current task, preserving the status observed before dispatch. | |
| pub(crate) async fn interrupt_spawned_agent( | |
| &self, | |
| caller: ThreadId, | |
| target: ThreadId, | |
| ) -> Result<AgentInterruptOutcome, AgentInterruptError> { | |
| let receiver_agent = self | |
| .ensure_agent_known(target) | |
| .map_err(AgentInterruptError::Agent)?; | |
| if receiver_agent | |
| .agent_path | |
| .as_ref() | |
| .is_some_and(AgentPath::is_root) | |
| { | |
| return Err(AgentInterruptError::InvalidRequest( | |
| "root is not a spawned agent".to_string(), | |
| )); | |
| } | |
| if target == caller { | |
| return Err(AgentInterruptError::InvalidRequest( | |
| "an agent cannot interrupt itself; return your result and let the parent interrupt you if needed" | |
| .to_string(), | |
| )); | |
| } | |
| let agent_path = receiver_agent.agent_path.clone().ok_or_else(|| { | |
| AgentInterruptError::InvalidRequest("target agent is missing an agent_path".to_string()) | |
| })?; | |
| let previous_status = self.get_status(target).await; | |
| match self.interrupt_agent(target).await { | |
| Ok(_) => {} | |
| Err(err) | |
| if matches!( | |
| err.details(), | |
| CodexErrorDetails::ThreadNotFound(_) | CodexErrorDetails::InternalAgentDied | |
| ) => {} | |
| Err(err) => return Err(AgentInterruptError::Agent(err)), | |
| } | |
| Ok(AgentInterruptOutcome { | |
| agent_path, | |
| previous_status, | |
| }) | |
| } | |
| } | |