Implement transactional scripted prim builds (#131)
Some checks failed
CI / rust-skia (Rust only) (push) Successful in 2m46s
CI / required (push) Failing after 53s

This commit is contained in:
2026-08-18 11:32:32 +02:00
parent 08696cd2fe
commit 64edd8df46
11 changed files with 1766 additions and 20 deletions

View File

@@ -84,6 +84,7 @@ pub struct AgentControlTarget {
policy: Arc<PolicyGateway>,
audit: Arc<MemoryPolicyAudit>,
observability: Mutex<Option<Arc<Observability>>>,
build: Mutex<Option<Arc<dyn crate::build::BuildControl>>>,
behavior: BehaviorIngress,
commands: mpsc::Sender<RuntimeControlCommand>,
command_capacity: usize,
@@ -127,6 +128,7 @@ impl AgentControlTarget {
policy,
audit,
observability: Mutex::new(None),
build: Mutex::new(None),
behavior,
commands,
command_capacity,
@@ -142,6 +144,11 @@ impl AgentControlTarget {
*lock(&self.observability) = Some(observability);
}
/// Attaches transactional build cancellation to the operator action API.
pub fn attach_build_control(&self, build: Arc<dyn crate::build::BuildControl>) {
*lock(&self.build) = Some(build);
}
pub fn update_session(&self, session: SessionStatus) {
let mut state = lock(&self.state);
state.session = session;
@@ -237,6 +244,7 @@ impl AgentControlTarget {
ControlRequest::Runtime => {
let state = lock(&self.state).clone();
let usage = self.policy.global_budget_usage();
let build = lock(&self.build);
Ok(ControlPayload::Runtime(RuntimeView {
grid_state: state.session.state.as_str().to_owned(),
generation: state.session.generation,
@@ -252,6 +260,11 @@ impl AgentControlTarget {
control_queue_capacity: self.command_capacity,
budget_tool_calls_used: usage.tool_calls,
budget_movement_millimeters_used: usage.movement_millimeters,
active_build_transaction: build.as_ref().and_then(|build| build.active_build()),
build_progress: build.as_ref().and_then(|build| build.build_progress()),
build_orphan_ids: build
.as_ref()
.map_or_else(Vec::new, |build| build.build_orphans()),
}))
}
ControlRequest::ListSessions { page } => {
@@ -340,10 +353,13 @@ impl AgentControlTarget {
Ok(response)
}
ControlRequest::CancelAction { action_id } => {
let build_cancelled = lock(&self.build)
.as_ref()
.is_some_and(|build| build.cancel_build(&action_id));
let cancelled = self.behavior.cancel_action(&action_id).map_err(|_| {
control_error(ControlErrorCode::InvalidRequest, "invalid action ID", false)
})?;
if !cancelled {
if !cancelled && !build_cancelled {
return Err(control_error(
ControlErrorCode::NotFound,
"active behavior action not found",