Merge feature/ticket60-ticket-assistant-no-reply into develop (#60)
Rendre visible l'échec « aucune réponse » de l'assistant de ticket : stream sans Final ou Final vide → ReplyChunk::Error terminal visible, plus jamais de tour muet. Backend + frontend, tests verts. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -405,6 +405,13 @@ pub enum ReplyEvent {
|
||||
/// humain, §21.1 niveau 3). Jamais une `Instant` monotone (cf. §21.2-T1).
|
||||
resets_at_ms: Option<i64>,
|
||||
},
|
||||
/// Erreur terminale du moteur structurée et affichable côté chat. Porte un
|
||||
/// message déjà nettoyé par l'adapter ; les détails propres à la CLI restent
|
||||
/// confinés côté infrastructure.
|
||||
Error {
|
||||
/// Message humain-lisible à rendre dans la cellule chat.
|
||||
message: String,
|
||||
},
|
||||
/// **Événement terminal déterministe** d'un tour : l'adapter l'émet quand il a
|
||||
/// lu le message `result` documenté de la CLI. Porte le contenu final agrégé.
|
||||
/// Après `Final`, le flux se termine (plus aucun événement).
|
||||
@ -415,11 +422,13 @@ pub enum ReplyEvent {
|
||||
}
|
||||
|
||||
/// Flux borné d'événements de réponse d'UN tour (ARCHITECTURE §17.1). Se termine
|
||||
/// après le [`ReplyEvent::Final`] (ou sur erreur). Calqué sur [`OutputStream`],
|
||||
/// après le [`ReplyEvent::Final`] / [`ReplyEvent::Error`] (ou sur erreur de transport).
|
||||
/// Calqué sur [`OutputStream`],
|
||||
/// mais **typé** : deltas de texte → activités d'outil → battements de cœur*
|
||||
/// ([`ReplyEvent::Heartbeat`], non terminaux, en nombre quelconque et entrelacés) →
|
||||
/// **un** `Final` terminal déterministe, plutôt que des octets bruts. Seul le `Final`
|
||||
/// clôt le flux ; deltas, activités et heartbeats sont tous non terminaux.
|
||||
/// **un** terminal déterministe, plutôt que des octets bruts. `Final` clôt un tour
|
||||
/// réussi ; `Error` clôt un tour échoué avec un message visible. Deltas, activités
|
||||
/// et heartbeats sont tous non terminaux.
|
||||
pub type ReplyStream = Box<dyn Iterator<Item = ReplyEvent> + Send>;
|
||||
|
||||
/// Description pure d'un outil exposé à un modèle OpenAI-compatible.
|
||||
|
||||
@ -85,6 +85,7 @@ impl ReadinessPolicy {
|
||||
/// l'application (planifier la reprise à `resets_at_ms`). L'heure de reset est
|
||||
/// propagée telle quelle.
|
||||
/// - [`ReplyEvent::TextDelta`] / [`ReplyEvent::Announcement`] /
|
||||
/// [`ReplyEvent::Error`] /
|
||||
/// [`ReplyEvent::ToolActivity`] /
|
||||
/// [`ReplyEvent::Heartbeat`] ⇒ `None` : tous **non terminaux** (le flux
|
||||
/// continue). Un heartbeat prouve la vivacité mais ne termine pas le tour.
|
||||
@ -97,6 +98,7 @@ impl ReadinessPolicy {
|
||||
}),
|
||||
ReplyEvent::TextDelta { .. }
|
||||
| ReplyEvent::Announcement { .. }
|
||||
| ReplyEvent::Error { .. }
|
||||
| ReplyEvent::ToolActivity { .. }
|
||||
| ReplyEvent::Heartbeat => None,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user