feat(backend,application,frontend,domain,web-server,app-tauri): bouton Redémarrer l'agent dans la barre supérieure des cellules — #317 (QA verte)

La cellule expose un bouton Redémarrer l'agent valable pour les trois
modes de présentation (headless, TUI native, CLI custom), sans jamais
prendre la présentation pour vérité runtime.

- Application: use case RestartCellAgentRuntime validant le binding
  exact cellule/runtime via les snapshots live (RestartRuntimeNotFound,
  ConflictAgentVisibleElsewhere, AgentNotBoundToCell) puis déléguant au
  scheduler self-restart existant (schedule_cell); CellAgentPresentation
  purement informationnelle.
- Backend/app-tauri/web-server: commande restart_cell_agent sur contrat
  DTO identique Tauri/HTTP, stop borné par timeout typé
  (RestartStopTimeout), relance préservant routage TUI natif, géométrie
  de cellule (node/rows/cols) et conversation; évenements domaine
  enrichis.
- Frontend: bouton dans la barre de cellule avec confirmation,
  overlay d'état Redémarrage…/échec (libellés par code d'erreur, Fermer/
  Réessayer), gardes d'identité de cellule et de restarts externes,
  gateway/mock/http adapters et ports alignés.
- Tests: dto_agents, workstate_actions, contrats web-server,
  LayoutGrid.cellControlsLayering, adapters agent/mock/http.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-09-11 15:00:43 +02:00
parent 46449bdf46
commit 7fb9d8bb86
26 changed files with 1404 additions and 58 deletions

View File

@ -26,11 +26,12 @@ use application::{
ReadAgentContextInput, ReadConversationPageInput, ReadMcpToolPermissionsInput,
ReadMemoryIndexInput, ReadProjectContextInput, RecallMemoryInput, RenameDeviceInput,
RenameLayoutInput, ResolveAgentPermissionsInput, ResolveAgentSystemPermissionsInput,
ResolveMemoryLinksInput, RevokeDeviceInput, RotateConversationLogInput, SaveChatDraftInput,
SetActiveLayoutInput, SetAgentMcpToolAllowedInput, SlashCommandEffect,
SnapshotRunningAgentsInput, StopLiveAgentInput, SyncAgentWithTemplateInput,
UnassignSkillFromAgentInput, UpdateAgentContactableInput, UpdateAgentContextInput,
UpdateAgentEffortInput, UpdateAgentMcpToolPermissionsInput, UpdateAgentPermissionsInput,
ResolveMemoryLinksInput, RestartCellAgentRuntimeInput, RevokeDeviceInput,
RotateConversationLogInput, SaveChatDraftInput, SetActiveLayoutInput,
SetAgentMcpToolAllowedInput, SlashCommandEffect, SnapshotRunningAgentsInput,
StopLiveAgentInput, SyncAgentWithTemplateInput, UnassignSkillFromAgentInput,
UpdateAgentContactableInput, UpdateAgentContextInput, UpdateAgentEffortInput,
UpdateAgentMcpToolPermissionsInput, UpdateAgentPermissionsInput,
UpdateAgentSystemPermissionsInput, UpdateMemoryInput, UpdateProjectContextInput,
UpdateProjectMcpToolPermissionsInput, UpdateProjectOrchestratorInput,
UpdateProjectPermissionsInput, UpdateProjectSystemPermissionsInput, UpdateSkillInput,
@ -73,6 +74,7 @@ use crate::dto::{
RemoveProjectResponseDto, RenameLayoutRequestDto, ReplyChunk, ResizeTerminalRequestDto,
ResolveAgentPermissionsRequestDto, ResolveAgentPermissionsResponseDto,
ResolveAgentSystemPermissionsRequestDto, ResolvedAgentSystemPermissionsDto,
RestartCellAgentRuntimeRequestDto, RestartCellAgentRuntimeResponseDto,
RestoreOpenProjectsOutputDto, ResumableAgentListDto, RetryOpenProjectRestoreRequestDto,
SaveChatDraftRequestDto, SaveEmbedderProfileRequestDto, SaveModelServerRequestDto,
SaveOpenCodeProviderProfileRequestDto, SaveOpenProjectRestoreOrderRequestDto,
@ -2268,6 +2270,32 @@ pub async fn stop_live_agent(
.map_err(ErrorDto::from)
}
/// Atomically restarts the runtime bound to an exact visible agent cell.
///
/// The presentation hint is retained for correlation only. Runtime selection,
/// stop ordering and relaunch are owned by the backend restart coordinator.
#[tauri::command]
pub async fn restart_cell_agent_runtime(
request: RestartCellAgentRuntimeRequestDto,
state: State<'_, AppState>,
) -> Result<RestartCellAgentRuntimeResponseDto, ErrorDto> {
let project = resolve_project(&request.project_id, &state).await?;
let output = state
.restart_cell_agent_runtime
.execute(RestartCellAgentRuntimeInput {
project,
node_id: parse_node_id(&request.node_id)?,
agent_id: parse_agent_id(&request.agent_id)?,
presentation: request.presentation.into(),
layout_id: request
.layout_id
.as_deref()
.map(parse_layout_id)
.transpose()?,
})?;
Ok(output.into())
}
/// `read_agent_context` — read an agent's Markdown context.
///
/// # Errors

View File

@ -351,6 +351,7 @@ pub fn run() {
commands::list_live_agents,
commands::attach_live_agent,
commands::stop_live_agent,
commands::restart_cell_agent_runtime,
commands::read_agent_context,
commands::update_agent_context,
commands::delete_agent,