use anyhow::Result;
use super::approval::{ApprovalDecision, UserInputDecision};
use super::{CancelReason, EngineHandle, Op, UserInputResponse};
impl EngineHandle {
pub async fn send(&self, op: Op) -> Result<()> {
self.tx_op.send(op).await?;
Ok(())
}
pub fn cancel(&self) {
self.cancel_with_reason(CancelReason::User);
}
pub fn cancel_with_reason(&self, reason: CancelReason) {
match self.cancel_reason.lock() {
Ok(mut slot) => *slot = Some(reason),
Err(poisoned) => *poisoned.into_inner() = Some(reason),
}
match self.cancel_token.lock() {
Ok(token) => token.cancel(),
Err(poisoned) => poisoned.into_inner().cancel(),
}
crate::retry_status::clear();
}
#[must_use]
#[allow(dead_code)]
pub fn is_cancelled(&self) -> bool {
match self.cancel_token.lock() {
Ok(token) => token.is_cancelled(),
Err(poisoned) => poisoned.into_inner().is_cancelled(),
}
}
pub fn set_paused(&self, paused: bool) {
match self.shared_paused.lock() {
Ok(mut slot) => *slot = paused,
Err(poisoned) => *poisoned.into_inner() = paused,
}
}
#[cfg(test)]
#[must_use]
pub fn is_paused(&self) -> bool {
match self.shared_paused.lock() {
Ok(slot) => *slot,
Err(poisoned) => *poisoned.into_inner(),
}
}
pub async fn approve_tool_call(&self, id: impl Into<String>) -> Result<()> {
self.tx_approval
.send(ApprovalDecision::Approved { id: id.into() })
.await?;
Ok(())
}
pub async fn deny_tool_call(&self, id: impl Into<String>) -> Result<()> {
self.tx_approval
.send(ApprovalDecision::Denied { id: id.into() })
.await?;
Ok(())
}
pub async fn retry_tool_with_policy(
&self,
id: impl Into<String>,
policy: crate::sandbox::SandboxPolicy,
) -> Result<()> {
self.tx_approval
.send(ApprovalDecision::RetryWithPolicy {
id: id.into(),
policy,
})
.await?;
Ok(())
}
pub async fn submit_user_input(
&self,
id: impl Into<String>,
response: UserInputResponse,
) -> Result<()> {
self.tx_user_input
.send(UserInputDecision::Submitted {
id: id.into(),
response,
})
.await?;
Ok(())
}
pub async fn cancel_user_input(&self, id: impl Into<String>) -> Result<()> {
self.tx_user_input
.send(UserInputDecision::Cancelled { id: id.into() })
.await?;
Ok(())
}
pub async fn steer(&self, content: impl Into<String>) -> Result<()> {
self.tx_steer.send(content.into()).await?;
Ok(())
}
pub async fn get_session_snapshot(&self) -> Result<crate::core::ops::SessionSnapshot> {
let (tx, rx) = tokio::sync::oneshot::channel();
let tx = std::sync::Arc::new(std::sync::Mutex::new(Some(tx)));
self.send(Op::GetSessionSnapshot { tx }).await?;
rx.await
.map_err(|_| anyhow::anyhow!("Engine dropped session snapshot oneshot"))
}
}