feat(backend): modèle unifié streaming/progress/events provider-agnostic + pont app-tauri — foundation #156 (QA verte)
This commit is contained in:
@ -18,7 +18,10 @@ use std::sync::{Arc, Mutex};
|
||||
use async_trait::async_trait;
|
||||
use serde_json::Value;
|
||||
|
||||
use domain::ports::{AgentSession, AgentSessionError, ReplyEvent, ReplyStream};
|
||||
use domain::ports::{
|
||||
AgentSession, AgentSessionError, ReplyEvent, ReplyProgress, ReplyProgressKind,
|
||||
ReplyProgressSource, ReplyProgressStage, ReplyStream,
|
||||
};
|
||||
use domain::sandbox::{SandboxEnforcer, SandboxPlan};
|
||||
use domain::SessionId;
|
||||
|
||||
@ -88,7 +91,17 @@ pub fn parse_event(line: &str) -> Result<ParsedLine, AgentSessionError> {
|
||||
let events = match value.get("type").and_then(Value::as_str) {
|
||||
// init/handshake : on capte le session_id ET on émet un battement de cœur
|
||||
// (preuve de vivacité non terminale : la CLI a démarré et répond).
|
||||
Some("system") => vec![ReplyEvent::Heartbeat],
|
||||
Some("system") => vec![
|
||||
ReplyEvent::Progress {
|
||||
progress: provider_progress(
|
||||
ReplyProgressKind::Turn,
|
||||
ReplyProgressStage::Started,
|
||||
"session initialisée",
|
||||
"system",
|
||||
),
|
||||
},
|
||||
ReplyEvent::Heartbeat,
|
||||
],
|
||||
// Limite de session/débit (ARCHITECTURE §21, niveau 1) : on lit l'heure de
|
||||
// reset dans `rate_limit_info` (au lieu de la jeter) et on émet un
|
||||
// `RateLimited{resets_at_ms}` **non terminal**. Robuste : absence/illisibilité
|
||||
@ -140,6 +153,15 @@ fn assistant_events(value: &Value) -> Vec<ReplyEvent> {
|
||||
.and_then(Value::as_str)
|
||||
.unwrap_or("outil")
|
||||
.to_owned();
|
||||
events.push(ReplyEvent::Progress {
|
||||
progress: provider_progress(
|
||||
ReplyProgressKind::Tool,
|
||||
ReplyProgressStage::Started,
|
||||
label.clone(),
|
||||
"tool_use",
|
||||
)
|
||||
.with_tool_name(label.clone()),
|
||||
});
|
||||
events.push(ReplyEvent::ToolActivity { label });
|
||||
}
|
||||
_ => {}
|
||||
@ -148,6 +170,16 @@ fn assistant_events(value: &Value) -> Vec<ReplyEvent> {
|
||||
events
|
||||
}
|
||||
|
||||
fn provider_progress(
|
||||
kind: ReplyProgressKind,
|
||||
stage: ReplyProgressStage,
|
||||
label: impl Into<String>,
|
||||
native_event: impl Into<String>,
|
||||
) -> ReplyProgress {
|
||||
ReplyProgress::new(ReplyProgressSource::ProviderNative, kind, stage, label)
|
||||
.with_provider_event("claude", native_event)
|
||||
}
|
||||
|
||||
/// **Extrait l'heure de reset d'une limite de débit** depuis l'objet
|
||||
/// `rate_limit_info` d'un `rate_limit_event` Claude, **normalisée en époche-ms**
|
||||
/// (ARCHITECTURE §21, niveau 1 structuré). Fonction **pure** (aucune I/O, aucun
|
||||
|
||||
Reference in New Issue
Block a user