fix(application,domain,infrastructure,web-server,app-tauri,frontend): arrêt d'agent fiable avec cascade sur l'arbre de propriété et statut cohérent — #320 (QA verte)
Symptôme: stopper un agent (ex Main sur UnityPlugin) laissait des travaux poursuivre, la cascade n'atteignait pas les agents lancés et la pastille restait orange pendant que l'agent continuait à en appeler d'autres. - barrière d'admission par génération d'exécution (ExecutionControl): un stop ferme l'admission de tout le sous-arbre propriété/attente AVANT toute annulation asynchrone — plus aucune nouvelle action inter-agents après stop - arbre de propriété durable en-process (launched_by) + dépendances d'attente actives: la cascade couvre transitivement agents et travaux lancés - commandes d'un agent arrêté rejetées (AppError::AgentStopped); stop lui-même admis pour rester idempotent; réactivation sur relance humaine (génération +1) et enregistrement du propriétaire au spawn - admission exposée aux adaptateurs hors commandes cœur (tickets, templates, plugins) via ensure_agent_execution_active; MCP server/tools, web-server et commandes Tauri alignés - cohérence live-state: statut Idle avec intent « Arrêté » ou « Arrêt incomplet — Certains travaux sont encore actifs » selon l'issue de la cascade; workstate et surfaces UI (AgentsPanel, LayoutGrid, ProjectWorkStatePanel) reflètent l'état réel, plus de pastille orange fantôme - tests: orchestrator_service (cascade/générations/idempotence), workstate_actions, background_task_cancel, error_codes, agents, layout, workstate QA verte sur fix/320-agent-stop-cascade. Aucun push.
This commit is contained in:
@ -472,6 +472,21 @@ impl McpServer {
|
||||
self.enforce_durable_tool_policy(&policy, &name)?;
|
||||
}
|
||||
|
||||
// Stop closes the entire MCP surface synchronously, including provider
|
||||
// tools that do not map through OrchestratorCommand. The stop tool itself
|
||||
// stays admitted so repeated/self stops remain idempotent.
|
||||
if name != "idea_stop_agent" {
|
||||
if let Ok(raw) = uuid::Uuid::parse_str(&self.requester) {
|
||||
if let Err(error) = self
|
||||
.service
|
||||
.ensure_agent_execution_active(&self.project, domain::AgentId::from_uuid(raw))
|
||||
{
|
||||
self.publish_processed(&name, false);
|
||||
return Ok(tool_result_text(&error.to_string(), true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Diagnostics begin beacon (best-effort, jamais le corps task/result) : trace
|
||||
// l'entrée d'un `tools/call`, son tool, le peer demandeur et la cible/longueurs.
|
||||
let started = Instant::now();
|
||||
|
||||
Reference in New Issue
Block a user