Implement pure Rust visual snapshots (#132)
This commit is contained in:
@@ -85,6 +85,7 @@ pub struct AgentControlTarget {
|
||||
audit: Arc<MemoryPolicyAudit>,
|
||||
observability: Mutex<Option<Arc<Observability>>>,
|
||||
build: Mutex<Option<Arc<dyn crate::build::BuildControl>>>,
|
||||
vision: Mutex<Option<Arc<dyn crate::vision::VisionControl>>>,
|
||||
behavior: BehaviorIngress,
|
||||
commands: mpsc::Sender<RuntimeControlCommand>,
|
||||
command_capacity: usize,
|
||||
@@ -129,6 +130,7 @@ impl AgentControlTarget {
|
||||
audit,
|
||||
observability: Mutex::new(None),
|
||||
build: Mutex::new(None),
|
||||
vision: Mutex::new(None),
|
||||
behavior,
|
||||
commands,
|
||||
command_capacity,
|
||||
@@ -149,6 +151,11 @@ impl AgentControlTarget {
|
||||
*lock(&self.build) = Some(build);
|
||||
}
|
||||
|
||||
/// Attaches synthetic viewport cancellation and metadata to operator control.
|
||||
pub fn attach_vision_control(&self, vision: Arc<dyn crate::vision::VisionControl>) {
|
||||
*lock(&self.vision) = Some(vision);
|
||||
}
|
||||
|
||||
pub fn update_session(&self, session: SessionStatus) {
|
||||
let mut state = lock(&self.state);
|
||||
state.session = session;
|
||||
@@ -245,6 +252,7 @@ impl AgentControlTarget {
|
||||
let state = lock(&self.state).clone();
|
||||
let usage = self.policy.global_budget_usage();
|
||||
let build = lock(&self.build);
|
||||
let vision = lock(&self.vision);
|
||||
Ok(ControlPayload::Runtime(RuntimeView {
|
||||
grid_state: state.session.state.as_str().to_owned(),
|
||||
generation: state.session.generation,
|
||||
@@ -265,6 +273,13 @@ impl AgentControlTarget {
|
||||
build_orphan_ids: build
|
||||
.as_ref()
|
||||
.map_or_else(Vec::new, |build| build.build_orphans()),
|
||||
active_visual_capture: vision
|
||||
.as_ref()
|
||||
.and_then(|vision| vision.active_capture()),
|
||||
visual_progress: vision.as_ref().and_then(|vision| vision.capture_progress()),
|
||||
visual_image_sha256: vision
|
||||
.as_ref()
|
||||
.and_then(|vision| vision.last_image_sha256()),
|
||||
}))
|
||||
}
|
||||
ControlRequest::ListSessions { page } => {
|
||||
@@ -345,6 +360,12 @@ impl AgentControlTarget {
|
||||
ControlRequest::PauseAutonomy => {
|
||||
let response = self.enqueue("pause", RuntimeControlCommand::Pause)?;
|
||||
self.behavior.pause();
|
||||
let vision = lock(&self.vision).clone();
|
||||
if let Some((vision, active)) =
|
||||
vision.and_then(|vision| vision.active_capture().map(|active| (vision, active)))
|
||||
{
|
||||
let _ = vision.cancel_capture(&active);
|
||||
}
|
||||
Ok(response)
|
||||
}
|
||||
ControlRequest::ResumeAutonomy => {
|
||||
@@ -356,10 +377,13 @@ impl AgentControlTarget {
|
||||
let build_cancelled = lock(&self.build)
|
||||
.as_ref()
|
||||
.is_some_and(|build| build.cancel_build(&action_id));
|
||||
let vision_cancelled = lock(&self.vision)
|
||||
.as_ref()
|
||||
.is_some_and(|vision| vision.cancel_capture(&action_id));
|
||||
let cancelled = self.behavior.cancel_action(&action_id).map_err(|_| {
|
||||
control_error(ControlErrorCode::InvalidRequest, "invalid action ID", false)
|
||||
})?;
|
||||
if !cancelled && !build_cancelled {
|
||||
if !cancelled && !build_cancelled && !vision_cancelled {
|
||||
return Err(control_error(
|
||||
ControlErrorCode::NotFound,
|
||||
"active behavior action not found",
|
||||
|
||||
Reference in New Issue
Block a user