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

@ -12,8 +12,8 @@ use application::{
AgentTicketState, AppError, AttachLiveAgentOutput, ConversationPreviewStatus,
ConversationTurnWorkPreview, ConversationWorkSummary, CreateProjectInput, CreateProjectOutput,
GitGraphOutput, HealthInput, HealthReport, LayoutKind, ListProjectsOutput, LiveSessionKind,
OpenProjectOutput, ProjectWorkState, StopLiveAgentOutput, TicketWorkSource, TicketWorkStatus,
TurnPage, TurnSource, TurnView,
LiveSessionSnapshot, OpenProjectOutput, ProjectWorkState, StopLiveAgentOutput,
TicketWorkSource, TicketWorkStatus, TurnPage, TurnSource, TurnView,
};
use domain::{AgentBusyState, PageCursor, PageDirection, Project, ProjectId, TurnRole};
@ -1460,6 +1460,8 @@ pub struct LiveAgentDto {
/// The live PTY session id, used to reattach a newly-opened cell without
/// respawning the agent.
pub session_id: String,
/// Runtime family that owns the session (`pty`/`structured`).
pub kind: LiveWorkSessionKindDto,
}
/// Response DTO for `list_live_agents` (transparent array on the wire).
@ -1468,7 +1470,7 @@ pub struct LiveAgentDto {
pub struct LiveAgentListDto(pub Vec<LiveAgentDto>);
impl LiveAgentListDto {
/// Builds the wire list from the registry's `(AgentId, NodeId, SessionId)` tuples.
/// Builds the wire list from the registry's live-session snapshots.
///
/// De-duplicates by `agent_id`: the "one live session per agent" invariant
/// guarantees an agent is live in at most one registry (PTY **or**
@ -1476,16 +1478,17 @@ impl LiveAgentListDto {
/// twice; the UI contract is a dup-free set (each agent appears once), so we
/// keep the first occurrence and drop any later one for the same agent.
#[must_use]
pub fn from_pairs(pairs: Vec<(AgentId, NodeId, domain::SessionId)>) -> Self {
pub fn from_snapshots(pairs: Vec<LiveSessionSnapshot>) -> Self {
let mut seen = std::collections::HashSet::new();
Self(
pairs
.into_iter()
.filter(|(agent_id, _, _)| seen.insert(*agent_id))
.map(|(agent_id, node_id, session_id)| LiveAgentDto {
agent_id: agent_id.to_string(),
node_id: node_id.to_string(),
session_id: session_id.to_string(),
.filter(|snapshot| seen.insert(snapshot.agent_id))
.map(|snapshot| LiveAgentDto {
agent_id: snapshot.agent_id.to_string(),
node_id: snapshot.node_id.to_string(),
session_id: snapshot.session_id.to_string(),
kind: snapshot.kind.into(),
})
.collect(),
)