agent conversation fix

This commit is contained in:
2026-06-27 12:42:37 +02:00
parent c2d1a669c5
commit 1fc7869160
38 changed files with 1173 additions and 1549 deletions

View File

@ -10,8 +10,8 @@ use app_tauri_lib::dto::{
use application::AppError;
use application::{
AgentTicketState, AgentWorkState, CreateAgentOutput, InspectConversationOutput,
LaunchAgentOutput, ListAgentsOutput, LiveSessionKind, LiveWorkSession, ProjectWorkState,
TicketWorkSource, TicketWorkStatus,
LaunchAgentOutput, ListAgentsOutput, LiveSessionKind, LiveSessionSnapshot, LiveWorkSession,
ProjectWorkState, TicketWorkSource, TicketWorkStatus,
};
use domain::ids::{AgentId, NodeId, ProfileId, SessionId};
use domain::ports::ConversationDetails;
@ -187,13 +187,19 @@ fn live_agent_list_dto_serialises_camelcase_array() {
let agent_a = AgentId::from_uuid(Uuid::from_u128(11));
let node_a = NodeId::from_uuid(Uuid::from_u128(21));
let session_a = domain::SessionId::from_uuid(Uuid::from_u128(31));
let dto = LiveAgentListDto::from_pairs(vec![(agent_a, node_a, session_a)]);
let dto = LiveAgentListDto::from_snapshots(vec![LiveSessionSnapshot {
agent_id: agent_a,
node_id: node_a,
session_id: session_a,
kind: LiveSessionKind::Pty,
}]);
let v = serde_json::to_value(&dto).unwrap();
let arr = v.as_array().expect("transparent array");
assert_eq!(arr.len(), 1);
assert_eq!(arr[0]["agentId"], agent_a.to_string());
assert_eq!(arr[0]["nodeId"], node_a.to_string());
assert_eq!(arr[0]["sessionId"], session_a.to_string());
assert_eq!(arr[0]["kind"], "pty");
// No snake_case leak.
assert!(arr[0].get("agent_id").is_none());
assert!(arr[0].get("node_id").is_none());

View File

@ -5,7 +5,7 @@
//!
//! Ces tests reproduisent **exactement** ce que fait la commande
//! `list_live_agents` : construire un `LiveSessions` à partir des deux registres
//! partagés et passer `live_agents()` à `LiveAgentListDto::from_pairs`. Ils
//! partagés et passer `live_agent_snapshots()` à `LiveAgentListDto::from_snapshots`. Ils
//! exercent donc le câblage de l'agrégateur **et** la dé-duplication par agent
//! portée par le DTO (contrat de liveness pour l'UI). 100 % fakes, sans process.
@ -71,7 +71,7 @@ fn insert_pty(pty: &TerminalSessions, s: SessionId, a: AgentId, n: NodeId) {
/// Reproduit le corps de la commande `list_live_agents` (hors validation d'id).
fn dto_for(pty: &Arc<TerminalSessions>, structured: &Arc<StructuredSessions>) -> LiveAgentListDto {
let live = LiveSessions::new(Arc::clone(pty), Arc::clone(structured));
LiveAgentListDto::from_pairs(live.live_agents())
LiveAgentListDto::from_snapshots(live.live_agent_snapshots())
}
// ===========================================================================
@ -90,6 +90,8 @@ fn pty_live_agent_is_listed() {
assert_eq!(dto.0[0].agent_id, a.to_string());
assert_eq!(dto.0[0].node_id, nid(100).to_string());
assert_eq!(dto.0[0].session_id, sid(1).to_string());
let json = serde_json::to_value(&dto).unwrap();
assert_eq!(json[0]["kind"], "pty");
}
// ===========================================================================
@ -112,6 +114,8 @@ fn structured_live_agent_is_listed() {
assert_eq!(dto.0[0].agent_id, a.to_string());
assert_eq!(dto.0[0].node_id, nid(200).to_string());
assert_eq!(dto.0[0].session_id, sid(2).to_string());
let json = serde_json::to_value(&dto).unwrap();
assert_eq!(json[0]["kind"], "structured");
}
// ===========================================================================
@ -140,6 +144,15 @@ fn both_kinds_live_listed_without_duplicates() {
let mut uniq = ids.clone();
uniq.dedup();
assert_eq!(uniq.len(), dto.0.len(), "aucun doublon d'agent");
let json = serde_json::to_value(&dto).unwrap();
let mut kinds = json
.as_array()
.unwrap()
.iter()
.map(|row| row["kind"].as_str().unwrap())
.collect::<Vec<_>>();
kinds.sort_unstable();
assert_eq!(kinds, vec!["pty", "structured"]);
}
// ===========================================================================
@ -167,6 +180,8 @@ fn same_agent_in_both_registries_is_deduplicated() {
// On garde la première occurrence (PTY, listé en premier par l'agrégateur).
assert_eq!(dto.0[0].node_id, nid(100).to_string());
assert_eq!(dto.0[0].session_id, sid(1).to_string());
let json = serde_json::to_value(&dto).unwrap();
assert_eq!(json[0]["kind"], "pty");
}
// ===========================================================================