feat(maestro): serve structured session API
This commit is contained in:
@@ -417,6 +417,41 @@ impl SessionManager {
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
/// Begin an ACP turn only when the previous one has ended. The projection
|
||||
/// lock makes the rejection and lifecycle update one indivisible action.
|
||||
pub async fn begin_acp_turn(&self, id: Uuid) -> Result<Option<Arc<AcpSession>>, SessionError> {
|
||||
let (acp, stream) = {
|
||||
let sessions = self.inner.sessions.lock().await;
|
||||
let record = sessions.get(&id).ok_or(SessionError::NotFound(id))?;
|
||||
(record.acp.clone(), record.acp_events.clone())
|
||||
};
|
||||
let (Some(acp), Some(stream)) = (acp, stream) else {
|
||||
return Ok(None);
|
||||
};
|
||||
let mut stream = stream.lock().await;
|
||||
if stream.projection.turn_active() {
|
||||
return Ok(None);
|
||||
}
|
||||
let update = stream.projection.turn_lifecycle(TurnLifecycle::Begin);
|
||||
let _ = stream.projected_live.send(update);
|
||||
Ok(Some(acp))
|
||||
}
|
||||
|
||||
/// Cancel an ACP turn and immediately clear its client-facing lifecycle.
|
||||
pub async fn cancel_acp_turn(&self, id: Uuid) -> Result<bool, SessionError> {
|
||||
let acp = {
|
||||
let sessions = self.inner.sessions.lock().await;
|
||||
let record = sessions.get(&id).ok_or(SessionError::NotFound(id))?;
|
||||
record.acp.clone()
|
||||
};
|
||||
let Some(acp) = acp else {
|
||||
return Ok(false);
|
||||
};
|
||||
acp.cancel();
|
||||
self.apply_acp_turn_lifecycle(id, TurnLifecycle::Cancel)
|
||||
.await
|
||||
}
|
||||
|
||||
/// End every adapter child before the daemon exits (#134): each gets
|
||||
/// `session/cancel`, then SIGTERM, concurrently. The sessions stay in
|
||||
/// the map, marked Dead and written through to their sidecars, so what
|
||||
|
||||
Reference in New Issue
Block a user