pub mod binding;
pub mod mcp;
pub use mcp::{ComputerUseMcpConfig, ComputerUseMcpRuntime, TraceCorrelation};
use crate::{
ActionEnvelope, ActionPreview, ComputerUseError, ControlLease, ExecutionReceipt,
TargetReservation,
};
use async_trait::async_trait;
use serde_json::Value;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum VerificationOutcome {
Verified,
CommittedUnverified {
reason: String,
},
Failed {
reason: String,
},
}
impl VerificationOutcome {
pub fn is_verified(&self) -> bool {
matches!(self, VerificationOutcome::Verified)
}
pub fn is_committed(&self) -> bool {
matches!(
self,
VerificationOutcome::Verified | VerificationOutcome::CommittedUnverified { .. }
)
}
pub fn status(&self) -> &'static str {
match self {
VerificationOutcome::Verified => "completed",
VerificationOutcome::CommittedUnverified { .. } => "committed_unverified",
VerificationOutcome::Failed { .. } => "verification_failed",
}
}
}
#[async_trait]
pub trait ComputerUseRuntime: Send + Sync {
async fn discover_capabilities(&self) -> Result<Value, ComputerUseError>;
async fn observe_visual(&self) -> Result<Value, ComputerUseError>;
async fn observe_semantic(&self) -> Result<Value, ComputerUseError>;
async fn preview_action(
&self,
proposed_action: Value,
) -> Result<ActionPreview, ComputerUseError>;
async fn reserve_target(
&self,
_envelope: &ActionEnvelope,
) -> Result<Option<TargetReservation>, ComputerUseError> {
Ok(None)
}
async fn release_target(
&self,
_reservation: &TargetReservation,
) -> Result<(), ComputerUseError> {
Ok(())
}
async fn acquire_lease(
&self,
envelope: &ActionEnvelope,
) -> Result<ControlLease, ComputerUseError>;
async fn execute_action(
&self,
envelope: &ActionEnvelope,
lease: &ControlLease,
approval_grant_id: Option<&str>,
) -> Result<ExecutionReceipt, ComputerUseError>;
async fn verify(
&self,
receipt: &ExecutionReceipt,
postcondition: Option<&crate::ActionPostcondition>,
) -> Result<VerificationOutcome, ComputerUseError>;
async fn pause_session(
&self,
_session_id: &str,
_reason: &str,
) -> Result<(), ComputerUseError> {
Err(ComputerUseError::Unsupported { operation: "pause_session" })
}
async fn stop_session(&self, _session_id: &str, _reason: &str) -> Result<(), ComputerUseError> {
Err(ComputerUseError::Unsupported { operation: "stop_session" })
}
async fn emergency_stop(&self, _reason: &str) -> Result<(), ComputerUseError> {
Err(ComputerUseError::Unsupported { operation: "emergency_stop" })
}
}