mod types;
pub use types::*;
use std::path::PathBuf;
use async_trait::async_trait;
use crate::Result;
use crate::harness::events::{AgentEvent, EventSink};
use crate::harness::tool::SandboxMode;
pub async fn prepare_workspace(
isolation: &dyn WorkspaceIsolation,
events: &EventSink,
run_id: &str,
agent: Option<&str>,
) -> Result<WorkspaceDescriptor> {
let descriptor = isolation.prepare(run_id, agent).await?;
events.emit(AgentEvent::WorkspacePrepared {
policy_id: descriptor.policy_id.clone(),
root: descriptor.root.display().to_string(),
});
Ok(descriptor)
}
pub async fn cleanup_workspace(
isolation: &dyn WorkspaceIsolation,
events: &EventSink,
descriptor: &WorkspaceDescriptor,
) -> Result<()> {
let result = isolation.cleanup(descriptor).await;
events.emit(AgentEvent::WorkspaceCleanup {
policy_id: descriptor.policy_id.clone(),
error: result.as_ref().err().map(|e| e.to_string()),
});
result
}
#[derive(Clone, Debug)]
pub struct SharedRootWorkspace {
root: PathBuf,
sandbox: SandboxMode,
}
impl SharedRootWorkspace {
pub fn new(root: impl Into<PathBuf>) -> Self {
Self {
root: root.into(),
sandbox: SandboxMode::Inherit,
}
}
pub fn with_sandbox(mut self, sandbox: SandboxMode) -> Self {
self.sandbox = sandbox;
self
}
}
#[async_trait]
impl WorkspaceIsolation for SharedRootWorkspace {
async fn prepare(&self, run_id: &str, _agent: Option<&str>) -> Result<WorkspaceDescriptor> {
Ok(WorkspaceDescriptor::new(self.root.clone())
.with_policy_id(run_id)
.with_sandbox(self.sandbox))
}
async fn cleanup(&self, _descriptor: &WorkspaceDescriptor) -> Result<()> {
Ok(())
}
}
#[cfg(test)]
mod test;