feat(workstate): read-model live-state minimal des conversations/délégations (Lot A backend)
Introduit le module application `workstate` (modèle de read-model live + snapshots des conversations/délégations en cours) et l'expose via la couche terminal (exports mod/registry). Câble la surface Tauri : DTO, commande et state pour exposer le live-state au frontend (lib + state + commands), avec tests. QA verte. Réserve environnementale non bloquante : tests loopback socket Unix réels non exécutables en sandbox (UnixListener::bind PermissionDenied), alternatives avec skips vertes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -9,7 +9,8 @@ use app_tauri_lib::dto::{
|
||||
};
|
||||
use application::AppError;
|
||||
use application::{
|
||||
CreateAgentOutput, InspectConversationOutput, LaunchAgentOutput, ListAgentsOutput,
|
||||
AgentWorkState, CreateAgentOutput, InspectConversationOutput, LaunchAgentOutput,
|
||||
ListAgentsOutput, LiveSessionKind, LiveWorkSession, ProjectWorkState,
|
||||
};
|
||||
use domain::ids::{AgentId, NodeId, ProfileId, SessionId};
|
||||
use domain::ports::ConversationDetails;
|
||||
@ -197,6 +198,44 @@ fn live_agent_list_dto_serialises_camelcase_array() {
|
||||
assert!(arr[0].get("node_id").is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn project_work_state_dto_serialises_live_and_busy_camelcase() {
|
||||
let agent = AgentId::from_uuid(Uuid::from_u128(11));
|
||||
let profile = ProfileId::from_uuid(Uuid::from_u128(12));
|
||||
let node = NodeId::from_uuid(Uuid::from_u128(13));
|
||||
let session = SessionId::from_uuid(Uuid::from_u128(14));
|
||||
let ticket = domain::TicketId::from_uuid(Uuid::from_u128(15));
|
||||
let dto = app_tauri_lib::dto::ProjectWorkStateDto::from(ProjectWorkState {
|
||||
agents: vec![AgentWorkState {
|
||||
agent_id: agent,
|
||||
name: "Worker".to_owned(),
|
||||
profile_id: profile,
|
||||
live: Some(LiveWorkSession {
|
||||
node_id: node,
|
||||
session_id: session,
|
||||
kind: LiveSessionKind::Structured,
|
||||
}),
|
||||
busy: domain::AgentBusyState::Busy {
|
||||
ticket,
|
||||
since_ms: 1_234,
|
||||
},
|
||||
}],
|
||||
});
|
||||
|
||||
let v = serde_json::to_value(&dto).unwrap();
|
||||
assert_eq!(v["agents"][0]["agentId"], agent.to_string());
|
||||
assert_eq!(v["agents"][0]["profileId"], profile.to_string());
|
||||
assert_eq!(v["agents"][0]["live"]["nodeId"], node.to_string());
|
||||
assert_eq!(v["agents"][0]["live"]["sessionId"], session.to_string());
|
||||
assert_eq!(v["agents"][0]["live"]["kind"], "structured");
|
||||
assert_eq!(v["agents"][0]["busy"]["state"], "busy");
|
||||
assert_eq!(v["agents"][0]["busy"]["ticket"], ticket.to_string());
|
||||
assert_eq!(v["agents"][0]["busy"]["sinceMs"], 1_234);
|
||||
assert!(v["agents"][0].get("agent_id").is_none());
|
||||
assert!(v["agents"][0]["live"].get("session_id").is_none());
|
||||
assert!(v["agents"][0]["busy"].get("since_ms").is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn launch_agent_request_carries_conversation_id_for_resume() {
|
||||
let raw = json!({
|
||||
|
||||
Reference in New Issue
Block a user