fix(runtime): stop/restart d'agent visible robuste — kill réel, état stopped, relance froide (#196, QA verte)
Solidifie le cycle stop/restart d'un agent visible en cellule: - terminal/registry: kill effectif de la TUI native et de la CLI custom, arrêt idempotent du live runtime (PTY + structuré), distinction nette « agent stoppé » vs « pas de session ». - workstate + lifecycle: projection d'un état runtime explicite « stopped » (AgentRuntimeState: running/stopping/stopped/failedStart), réconcilié avec le live state; traitement des courses « agent not found ». - relance froide via freshStart: repart de zéro sans réattacher une session morte et recharge la configuration courante de l'agent (y compris changement de modèle). - contrat projeté côté adapters frontend (ports/domain/normalization/mock) pour la consommation UI future (#197/#198), sans surface UI ici. Tests QA verts: workstate_actions, orchestrator_service stop_agent, agent_lifecycle (reopen/fresh_start), workstate stopped runtime state, vitest adapter stop_live_agent.
This commit is contained in:
@ -1193,6 +1193,7 @@ fn launch_input(agent_id: AgentId) -> LaunchAgentInput {
|
||||
mcp_runtime: None,
|
||||
allow_structured_alongside_pty: false,
|
||||
require_structured: false,
|
||||
fresh_start: false,
|
||||
}
|
||||
}
|
||||
|
||||
@ -2946,6 +2947,33 @@ async fn launch_reopen_with_existing_conversation_id_resumes_without_new_id() {
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn launch_fresh_start_ignores_existing_conversation_id_and_mints_new_one() {
|
||||
let (launch, agent, _fs, _pty, _bus, _sessions, _tr, session) = launch_fixture_with_profile(
|
||||
profile_with_session(pid(9), Some("--session-id"), "--resume"),
|
||||
Some(ContextInjectionPlan::Stdin),
|
||||
);
|
||||
|
||||
let mut input = launch_input(agent.id);
|
||||
input.conversation_id = Some("conv-dead-session".to_owned());
|
||||
input.fresh_start = true;
|
||||
let out = launch.execute(input).await.expect("fresh restart launch");
|
||||
|
||||
let expected = Uuid::from_u128(1).to_string();
|
||||
assert_eq!(
|
||||
out.assigned_conversation_id.as_deref(),
|
||||
Some(expected.as_str()),
|
||||
"fresh restart must mint a new conversation id"
|
||||
);
|
||||
assert_eq!(
|
||||
*session.lock().unwrap(),
|
||||
Some(SessionPlan::Assign {
|
||||
conversation_id: expected
|
||||
}),
|
||||
"fresh restart must not reuse the dead conversation id"
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn launch_profile_without_session_block_passes_none() {
|
||||
// Non-regression: a profile with no session block behaves exactly as before.
|
||||
|
||||
Reference in New Issue
Block a user