fix(chat): le bouton Stop de la CLI custom arrête l'agent en cascade (#187)
Le Stop du CustomAgentChatView n'annulait que le tour courant sans libérer la session ni toucher aux tâches enfants ou appels MCP en cours. Il appelle désormais stop_live_agent sur l'agent vivant, qui: - ajoute le port StopAgentExecutionCascade (best-effort, idempotent), implémenté par OrchestratorService pour annuler les idea_run_in_background rattachés au rendez-vous actif (via BackgroundTaskRunner.cancel); - cascade l'arrêt aux wait-dépendances (stop_turn_watch + preempt) pour interrompre les appels MCP et les attentes inter-agents; - libère et supprime la session structurée. UI: nouvel état "Arrêt en cours..." (bouton disabled + loading) pendant l'arrêt, libération du sessionId, label expliquant la cascade demandée. La Tauri command cancel_agent_chat est alignée sur stop_live_agent + stop_turn_watch agent et dépendances. Tests: SpyBackgroundRunner (cascade n'annule que les tâches rattachées), workstate_actions cascade best-effort, CustomAgentChatView stop+cascade feedback et fallback NOT_FOUND.
This commit is contained in:
@ -2764,29 +2764,39 @@ pub async fn interrupt_agent(
|
||||
.map_err(ErrorDto::from)
|
||||
}
|
||||
|
||||
/// `cancel_agent_chat` — interrupt the current turn of a live structured chat
|
||||
/// session without shutting the session down.
|
||||
/// `cancel_agent_chat` — stop a live structured chat session and cascade its
|
||||
/// running execution children best-effort.
|
||||
///
|
||||
/// This is the session-id based twin of [`interrupt_agent`] for a custom chat
|
||||
/// This is the session-id based twin of [`stop_live_agent`] for a custom chat
|
||||
/// surface that already owns the structured `sessionId`.
|
||||
///
|
||||
/// # Errors
|
||||
/// Returns an [`ErrorDto`] (`INVALID` for a malformed id, `NOT_FOUND` if no live
|
||||
/// structured session owns the id, `PROCESS` if a concrete cancel fails).
|
||||
/// structured session owns the id, `PROCESS` if a concrete stop fails).
|
||||
#[tauri::command]
|
||||
pub async fn cancel_agent_chat(
|
||||
session_id: String,
|
||||
state: State<'_, AppState>,
|
||||
) -> Result<(), ErrorDto> {
|
||||
let sid = parse_session_id(&session_id)?;
|
||||
let session = state
|
||||
let (project_id, agent_id, _, _) = state
|
||||
.structured_sessions
|
||||
.session(&sid)
|
||||
.meta_for_session(&sid)
|
||||
.ok_or_else(|| ErrorDto::from(AppError::NotFound(format!("structured session {sid}"))))?;
|
||||
session
|
||||
.cancel_current_turn()
|
||||
let project = resolve_project(&project_id.to_string(), &state).await?;
|
||||
let dependencies = state
|
||||
.orchestrator_service
|
||||
.active_wait_dependencies(agent_id);
|
||||
state.stop_turn_watch(project.id, agent_id);
|
||||
for dependency in dependencies {
|
||||
state.stop_turn_watch(project.id, dependency);
|
||||
}
|
||||
state
|
||||
.stop_live_agent
|
||||
.execute(StopLiveAgentInput { project, agent_id })
|
||||
.await
|
||||
.map_err(|e| ErrorDto::from(AppError::from(e)))
|
||||
.map(|_| ())
|
||||
.map_err(ErrorDto::from)
|
||||
}
|
||||
|
||||
async fn preferred_view_for_agent(
|
||||
|
||||
Reference in New Issue
Block a user