feat(agent): fondation exécution structurée des agents IA (D0+D1) — §17
Pivot orchestration : agents IA pilotés via leur mode programmatique/JSON
(capture déterministe), au lieu du TUI brut + self-report. §16 (idea/MCP)
marquée remplacée comme voie principale.
- D0 (domaine) : port AgentSession + AgentSessionFactory, types ReplyEvent
/ReplyStream/AgentSessionError, champ AgentProfile.structured_adapter
(Option<StructuredAdapter{Claude,Codex}>, skip si None ⇒ zéro régression),
catalogue Claude/Codex annotés.
- D1 (application) : registre StructuredSessions (jumeau de TerminalSessions),
agrégateur LiveSessions{pty,structured} derrière LiveAgentRegistry (vivant si
PTY OU structuré, surface du trait inchangée), helper send_blocking (draine le
ReplyStream jusqu'au Final, Timeout sans tuer la session).
Tests : domaine 16+2 ; application registre 11 + send_blocking 9 ; workspace 0 échec.
A/B intacts. Aucun adapter concret (D2), pas de Tauri/front.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -118,6 +118,22 @@ impl SessionStrategy {
|
||||
}
|
||||
}
|
||||
|
||||
/// Adapter d'**exécution structurée** qui pilote un profil IA (ARCHITECTURE §17).
|
||||
///
|
||||
/// Déclaratif, Open/Closed (comme [`EmbedderStrategy`]) : un profil déclare quel
|
||||
/// adapter le pilote en mode programmatique. Ajouter un moteur structuré = une
|
||||
/// variante ici + un adapter infra (`infrastructure/src/session/`), sans toucher
|
||||
/// au cœur. Un profil **sans** `structured_adapter` reste un profil **TUI/PTY**
|
||||
/// (terminal brut, comportement historique).
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum StructuredAdapter {
|
||||
/// Piloté par `ClaudeSdkSession` (mode `-p --output-format stream-json` / SDK).
|
||||
Claude,
|
||||
/// Piloté par `CodexExecSession` (`codex exec` structuré).
|
||||
Codex,
|
||||
}
|
||||
|
||||
/// Declarative runtime configuration for one AI CLI.
|
||||
///
|
||||
/// Invariants:
|
||||
@ -148,6 +164,15 @@ pub struct AgentProfile {
|
||||
/// keeps today's behaviour.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub session: Option<SessionStrategy>,
|
||||
/// Adapter d'exécution **structurée** (ARCHITECTURE §17). `None` ⇒ agent
|
||||
/// **TUI/PTY** (cellule terminal brut, comportement historique). `Some(_)` ⇒
|
||||
/// agent **IA structuré** (cellule chat + port [`crate::ports::AgentSession`]).
|
||||
/// Open/Closed : ajouter un moteur = une variante + un adapter.
|
||||
///
|
||||
/// `skip_serializing_if = Option::is_none` ⇒ **zéro régression** de
|
||||
/// sérialisation : un profil sans adapter sérialise exactement comme avant.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub structured_adapter: Option<StructuredAdapter>,
|
||||
}
|
||||
|
||||
/// Embedding strategy of an [`EmbedderProfile`] (LOT C, étage 2 vectoriel).
|
||||
@ -281,6 +306,16 @@ impl AgentProfile {
|
||||
detect,
|
||||
cwd_template,
|
||||
session,
|
||||
structured_adapter: None,
|
||||
})
|
||||
}
|
||||
|
||||
/// Builder : fixe l'[`StructuredAdapter`] d'exécution structurée (§17) et
|
||||
/// renvoie le profil. Laisse [`AgentProfile::new`] stable (zéro régression
|
||||
/// d'appel) : les profils TUI/PTY ne l'appellent simplement pas.
|
||||
#[must_use]
|
||||
pub fn with_structured_adapter(mut self, adapter: StructuredAdapter) -> Self {
|
||||
self.structured_adapter = Some(adapter);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user