État durable de `.ideai/` accumulé pendant le chantier `idea-serve`, séparé du code applicatif conformément aux précédents `8e481ae` / `ad1f225`. - Tickets : #13 clôturé (server/client mode livré), #65 passé en QA avec son carnet de chantier complet (arbitrages Architect sur le propriétaire canonique des DTO, structure livrée, vérif QA, incident de topologie et sa leçon). #64/#66/#67 rattachés au sprint. Nouveaux tickets #68 (activer le serveur depuis le desktop, dépend de #65), #69 (adaptabilité client téléphone, en QA) et #70 (gestion des modèles locaux llama.cpp). - Mémoire : note `web-client-is-single-column-no-desktop-shell` — le client web n'a pas de shell desktop, à lire avant tout cadrage responsive sur cette surface. - Journal des tâches de fond : complétions enregistrées. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3.2 KiB
id, number, title, status, priority, sprint, links, agentRefs, createdBy, updatedBy, createdAt, updatedAt, version
| id | number | title | status | priority | sprint | links | agentRefs | createdBy | updatedBy | createdAt | updatedAt | version | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 623b1719-c71d-448e-a0ef-3c7d5823b8a3 | 60 | [Bug] Assistant IA d'édition de ticket : aucune réponse dans la conversation (stream sans Final non signalé) | inProgress | high | e28a4d53-8bd2-446a-b0ac-2a017373b8b2 |
|
|
|
1784094260499 | 1784194089605 | 3 |
Rapporté par l'utilisateur (2026-07-15) : dans l'édition d'un ticket, le bouton « Assistant IA » ouvre une conversation, mais l'envoi d'un message ne produit JAMAIS de réponse visible — la conversation reste muette. PROFIL UTILISÉ : modèle local OpenAI-compatible (llamacpp).
CAUSE (Architect) :
- CONFIRMÉ code — silence sur stream sans Final : agent_send draine le flux et détache le canal SANS rien émettre si aucun ReplyChunk::Final n'est produit (commands.rs:1661-1691). Le frontend ne termine que sur
final(useTicketAssistant.ts:138-144). + finally setBusy(false) prématuré (useTicketAssistant.ts:147-151). - PROBABLE runtime (local OpenAI-compatible) — Final VIDE : le chemin HTTP émet bien un Final quand le serveur renvoie choices[0].message.content ou SSE delta.content (openai_compat.rs:348-397/517-538/286-292), mais llama.cpp peut renvoyer un flux sans delta.content utile (reasoning_content / tool_calls / contenu vide) → ReplyEvent::Final { content: "" } → le frontend remplace le tour par une chaîne vide (useTicketAssistant.ts:138-140) = « muet ».
PÉRIMÈTRE DE CE TICKET (#60) — Lot A robustesse + gestion Final vide, B+F, S/M :
- Backend : étendre ReplyChunk avec Error { message } (crates/app-tauri/src/dto.rs). agent_send : si le stream finit sans Final → émettre ReplyChunk::Error avant detach_if. Traiter Final { content: "" } comme terminal visible (Error « réponse vide du modèle » ou fallback explicite). Si l'adapter dispose d'un reasoning_content non vide, envisager de le surfacer plutôt que de le jeter (à confirmer selon payload).
- Frontend : ReplyChunk TS + useTicketAssistant gère
error, termine le pending, affiche le message, busy tombe sur final OU error, suppression du finally setBusy(false) prématuré.
Effet attendu : l'assistant ne reste JAMAIS muet — soit une réponse, soit une erreur/vide explicite visible.
QA :
- Backend agent_send : fake AgentSession renvoie Heartbeat puis EOF sans Final → le channel reçoit ReplyChunk::Error.
- Backend OpenAI-compatible : fake HTTP renvoie SSE [DONE] sans delta.content → terminal visible (erreur/non vide), jamais un tour muet.
- Frontend : sendTicketChat reçoit
error→ tour non pending, busy=false, message visible.
HORS PÉRIMÈTRE (→ ticket de suivi) : identité requester explicite (port AgentSessionFactory::start, factory.rs:153-157 dérive le requester du cwd → devient le n° de ticket au lieu de ticket-assistant::) + branchement de ToolPolicyRegistry sur l'invoker OpenAI-compatible (openai_tools.rs:92-145) + éventuel local_model_server_id sur HttpChatConfig. Concerne un port figé + la sécurité des tool calls.
Relations : #25, #27 (mêmes surfaces, déjà fermées).