Sauvegarde de l'arbre de travail en cours (persistance P8, conversations C-series, write-portal frontend, médiation d'entrée) avant d'attaquer le support de la délégation inter-agents pour les profils Codex. Le round-trip inter-agent question/réponse est couvert sans tokens par les tests loopback existants (state::mcp_e2e_loopback_tests). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
5.7 KiB
5.7 KiB
upTo: 44bc8d1d-93e9-46b3-94a8-8d11ab72ae82
objective: Tâche : ajouter UN test fonctionnel anti-régression de la communication inter-agent (round-trip question/réponse) au plus haut niveau de fidélité possible SANS lancer de vrai CLI IA (zéro token). Cont
Objectif : Tâche : ajouter UN test fonctionnel anti-régression de la communication inter-agent (round-trip question/réponse) au plus haut niveau de fidélité possible SANS lancer de vrai CLI IA (zéro token). Cont
- Prompt: Tâche : ajouter UN test fonctionnel anti-régression de la communication inter-agent (round-trip question/réponse) au plus haut niveau de fidélité possible SANS lancer de vrai CLI IA (zéro token). Contexte précis ci-dessous, suis-le à la lettre. ## Où Fichier : crates/app-tauri/src/state.rs, dans le module de test existant
#[cfg(test)] mod mcp_serve_peer_tests(commence vers la ligne 1893). Ce module pilote déjà la fn privéeserve_peer<S>sur untokio::io::duplex(pas de socket, pas de process). Réutilise au maximum ses helpers existants :build_service,spawn_peer,handshake_line,tools_call_line,read_one_response,project(),project_id_arg,McpServer::new. ## Le trou à combler Le module couvre handshake+tools/list, propagation du requester, mismatch projet, pairs concurrents — MAIS PAS le round-tripidea_ask_agent→idea_replyà traversserve_peer. C'est la glue critique : l'identité de l'agent répondeur vient de la ligne de handshake (requester), et c'est elle qui permet àidea_replyde corréler la réponse au ticket en attente. Référence du comportement attendu :crates/infrastructure/tests/mcp_server.rs::ask_agent_returns_target_reply_inline(qui, lui, court-circuite le transport via handle_raw/for_requester ; ton test doit passer par serve_peer + handshake réel). ## Problème à régler d'abord Lebuild_serviceactuel du module construit l'OrchestratorServiceviaOrchestratorService::new(...)SANS câbler le médiateur d'entrée ni le mailbox ni le registre de conversations. Orask_agentexigewith_input_mediator(...)+ (idéalement)with_conversations(...), sinon il renvoie « la messagerie inter-agents n'est pas disponible ». => Ajoute dans le module unbuild_service_with_mailbox(contexts) -> (Arc<OrchestratorService>, Arc<TestMailbox>, Arc<TerminalSessions>)en PORTANT les fakes déjà éprouvés depuiscrates/application/tests/orchestrator_service.rs(sections après la ligne ~806) :TestMailbox(impldomain::mailbox::AgentMailbox),TestMediator(impldomain::input::InputMediator, écrit le tour dans le PTY lié + délègue l'enqueue au TestMailbox),TestConversations(impldomain::conversation::ConversationRegistry). Câble :.with_input_mediator(mediator, mailbox).with_conversations(conversations). Garde le profil Claude complet déjà présent dansbuild_service(adaptateur structuré + capacité MCP) pour passer la garde F2. Tu peux factoriser le profil pour éviter la duplication. Ajoute aussi un helperseed_live_pty(sessions, agent_id, session_id)(copie de celui d'orchestrator_service.rs) pour que la cible soit déjà vivante en PTY et qu'ask_agentla réutilise sans lancer de process. ## Le test à écrire (un seul, simple)async fn ask_reply_round_trips_over_serve_peer_via_handshake_requester(): 1.let proj = project();;let contexts = FakeContexts::new();;let target_id = contexts.seed_agent("architect");2.let (service, mailbox, sessions) = build_service_with_mailbox(contexts);3.seed_live_pty(&sessions, target_id, <SessionId quelconque>);(cible vivante → pas de spawn) 4.let server = Arc::new(McpServer::new(service, proj.clone()));5. Peer A (le demandeur = humain) :spawn_peer(Arc::clone(&server), project_id_arg(&proj)). Écrishandshake_line(&project_id_arg(&proj), "")(requester vide ⇒ ask d'origine humaine, le plus simple : évite la garde de cycle et le besoin que le demandeur soit un agent enregistré), puistools_call_line(7, "idea_ask_agent", json!({"target":"architect","task":"What is the answer?"})). NE bloque pas le test : lis la réponse de A dans une task spawnée OU lis-la après avoir débloqué via B (voir étape 7). 6. Attends (borné par TIMEOUT, via bouclemailbox.pending(&target_id) == 1+tokio::task::yield_now().await) que A ait enqueué son ticket et soit en attente. 7. Peer B (la cible qui répond) :spawn_peer(Arc::clone(&server), project_id_arg(&proj)). Écrishandshake_line(&project_id_arg(&proj), &target_id.to_string())(CRUCIAL : le requester du handshake = l'id de la cible, c'est ce qui fait queidea_replycorrèle au mailbox de la cible), puistools_call_line(8, "idea_reply", json!({"result":"the answer is 42"})). Lis la réponse de B :isError == false. 8. Lis la réponse de A :isError == falseet le texte inline == "the answer is 42" (le texte est dans result["content"][0]["text"], cf.result_textdans mcp_server.rs — réplique ce petit helper si besoin). GARDE-FOU obligatoire : borne chaque attente/lecture partokio::time::timeout(TIMEOUT, …)(TIMEOUT existe déjà dans le module) pour qu'une régression échoue vite au lieu de hang. ## Contraintes - Respecte l'archi hexagonale : les fakes implémentent les ports du domaine, aucune dépendance nouvelle. - Code lisible, commenté dans le style du module (doc-comments expliquant POURQUOI le handshake requester est le point testé). - Lance le test et rends-moi la SORTIE RÉELLE decargo test -p app-tauri-lib mcp_serve_peer_tests(ou le nom de crate exact). Si ça ne compile pas / échoue, débogue jusqu'au vert et rends le diagnostic. Rends ton résultat via idea_reply : (a) le diff/chemin du test ajouté, (b) la sortie cargo test réelle (vert ou rouge avec détail), (c) toute difficulté rencontrée.