fix(backend,orchestrator,chat): l'objectif suspendu guide le premier tour post-restart — #290 regression partielle (register_suspended_turn capture la demande utilisateur exacte au point d'entrée chat agent_send/chat.send avec source diagnostique, RestartRendezvousCoordinator conserve tour/objectif/restart_attempt_id, take_continuation consommable exactement une fois et seulement par la tentative courante: suspended_restart_continuation_prompt place l'objectif utilisateur avant toute consigne generique et StructuredHumanTurnTransition::Resume porte le prompt host-provided injecte au runtime de remplacement; nettoyage du tour suspendu sur succes, echec, annulation et abandon/expiration; diagnostics projet/agent/turn_id/restart_attempt_id/source; rendez-vous inter-agents #289 inchanges; QA verte reconfirmee par Git: cargo check --workspace, backend self_restart_contract_tests 3/3, orchestrator_service restart 10/10, workstate_actions 9/9, app-tauri chat_bridge 31/31, web-server websocket_chat_send 3/3, fmt --check, diff --check; restants: rebuild AppImage + validation live reprise objectif apres restart; carnet #290 iteration regression + passage store qa inclus; scripts/ hors périmètre; aucun push)
This commit is contained in:
@ -1131,7 +1131,9 @@ mod self_restart_contract_tests {
|
||||
coordinator.ready(key, &restart_id);
|
||||
assert_eq!(
|
||||
turn.transition_after_provider_terminal_async().await,
|
||||
StructuredHumanTurnTransition::Resume,
|
||||
StructuredHumanTurnTransition::Resume {
|
||||
prompt: application::suspended_restart_continuation_prompt("restart me"),
|
||||
},
|
||||
"the old provider terminal is a control transition, not the human Final"
|
||||
);
|
||||
coordinator
|
||||
@ -1453,7 +1455,10 @@ pub enum StructuredHumanTurnTransition {
|
||||
/// No self-restart owns this terminal event; it is authoritative for the UI.
|
||||
Complete,
|
||||
/// The old terminal event is superseded; continue on the replacement runtime.
|
||||
Resume,
|
||||
Resume {
|
||||
/// Host-provided first prompt for the replacement runtime.
|
||||
prompt: String,
|
||||
},
|
||||
/// Replacement failed explicitly.
|
||||
Failed(String),
|
||||
/// The user cancelled the logical turn while replacement was in flight.
|
||||
@ -1470,6 +1475,29 @@ impl StructuredHumanTurnGuard {
|
||||
project_id: ProjectId,
|
||||
agent_id: AgentId,
|
||||
prompt: &str,
|
||||
) -> Self {
|
||||
Self::start_with_source(
|
||||
input,
|
||||
mailbox,
|
||||
restart_rendezvous,
|
||||
project_id,
|
||||
agent_id,
|
||||
prompt,
|
||||
"direct_human_chat",
|
||||
)
|
||||
}
|
||||
|
||||
/// Starts a direct human turn while retaining its exact restart objective and
|
||||
/// diagnostic entry-point source in application state.
|
||||
#[must_use]
|
||||
pub fn start_with_source(
|
||||
input: Arc<dyn domain::input::InputMediator>,
|
||||
mailbox: Arc<dyn domain::mailbox::AgentMailbox>,
|
||||
restart_rendezvous: Arc<application::RestartRendezvousCoordinator>,
|
||||
project_id: ProjectId,
|
||||
agent_id: AgentId,
|
||||
prompt: &str,
|
||||
source: &str,
|
||||
) -> Self {
|
||||
let agent = domain::RuntimeAgentKey::new(project_id, agent_id);
|
||||
let ticket_id = domain::mailbox::TicketId::new_random();
|
||||
@ -1486,7 +1514,14 @@ impl StructuredHumanTurnGuard {
|
||||
agent,
|
||||
ticket_id,
|
||||
armed: Arc::new(std::sync::atomic::AtomicBool::new(owns_turn)),
|
||||
restart: owns_turn.then(|| restart_rendezvous.register(agent)),
|
||||
restart: owns_turn.then(|| {
|
||||
restart_rendezvous.register_suspended_turn(
|
||||
agent,
|
||||
ticket_id.to_string(),
|
||||
prompt.to_owned(),
|
||||
source.to_owned(),
|
||||
)
|
||||
}),
|
||||
finish_on_drop: true,
|
||||
}
|
||||
}
|
||||
@ -1527,8 +1562,16 @@ impl StructuredHumanTurnGuard {
|
||||
}
|
||||
}
|
||||
application::RestartRendezvousState::Ready { restart_id } => {
|
||||
let prompt = restart.take_continuation(&restart_id).map_or_else(
|
||||
|| application::SELF_RESTART_CONTINUATION_PROMPT.to_owned(),
|
||||
|continuation| {
|
||||
application::suspended_restart_continuation_prompt(
|
||||
&continuation.objective_text,
|
||||
)
|
||||
},
|
||||
);
|
||||
restart.accept_ready(&restart_id);
|
||||
return StructuredHumanTurnTransition::Resume;
|
||||
return StructuredHumanTurnTransition::Resume { prompt };
|
||||
}
|
||||
application::RestartRendezvousState::Failed { message, .. } => {
|
||||
return StructuredHumanTurnTransition::Failed(message);
|
||||
|
||||
Reference in New Issue
Block a user