feat(app): auto-update live-state depuis le cycle de délégation (LS3)
Branche la mise à jour automatique du live-state sur le cycle de délégation de l'orchestrateur, en best-effort non bloquant. - Trait `LiveStateProvider` (résolution par root) + champ `Option` dans l'`OrchestratorService`, injecté via le builder `with_live_state` ; `None` ⇒ aucun effet (zéro régression). - Transitions dérivées du cycle : `ask` → entrée `Working`, `reply` → `Done` + `last_delegation`. - Helpers best-effort : un échec de mise à jour du live-state ne transforme jamais un succès de délégation en erreur. - `AppLiveStateProvider` + wiring côté app-tauri (provider par root). cargo test -p application : 0 échec ; --test orchestrator_service : 55/0 (dont 4 nouveaux tests LS3) ; cargo fmt --all --check : exit 0. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -22,17 +22,17 @@ use application::{
|
||||
GitCommit, GitGraph, GitInit, GitLog, GitStage, GitStatus, GitUnstage, HarvestMemoryFromTurn,
|
||||
HealthUseCase, InspectConversation, LaunchAgent, LaunchAgentInput, ListAgents, ListAgentsInput,
|
||||
ListEmbedderProfiles, ListLayouts, ListMemories, ListProfiles, ListProjects,
|
||||
ListResumableAgents, ListSkills, ListTemplates, LiveAgentRegistry, LiveSessions, LoadLayout,
|
||||
McpRuntime, MoveTabToNewWindow, MutateLayout, OnnxModelView, OpenProject, OpenTerminal,
|
||||
OrchestratorService, PermissionProjectorRegistry, ProposeContext, ReadAgentContext,
|
||||
ReadContext, ReadMemory, ReadMemoryIndex, ReadProjectContext, ReadSkill, RecallMemory,
|
||||
ReconcileLayouts, RecordTurn, RecordTurnProvider, ReferenceProfiles, RenameLayout,
|
||||
ResizeTerminal, ResolveAgentPermissions, ResolveMemoryLinks, SaveEmbedderProfile, SaveProfile,
|
||||
SessionLimitService, SetActiveLayout, SnapshotRunningAgents, StopLiveAgent, StructuredSessions,
|
||||
SuggestedThisSession, SyncAgentWithTemplate, TerminalSessions, UnassignSkillFromAgent,
|
||||
UpdateAgentContext, UpdateAgentPermissions, UpdateMemory, UpdateProjectContext,
|
||||
UpdateProjectPermissions, UpdateSkill, UpdateTemplate, WriteMemory, WriteToTerminal,
|
||||
AGENT_MEMORY_RECALL_BUDGET,
|
||||
ListResumableAgents, ListSkills, ListTemplates, LiveAgentRegistry, LiveSessions,
|
||||
LiveStateProvider, LoadLayout, McpRuntime, MoveTabToNewWindow, MutateLayout, OnnxModelView,
|
||||
OpenProject, OpenTerminal, OrchestratorService, PermissionProjectorRegistry, ProposeContext,
|
||||
ReadAgentContext, ReadContext, ReadMemory, ReadMemoryIndex, ReadProjectContext, ReadSkill,
|
||||
RecallMemory, ReconcileLayouts, RecordTurn, RecordTurnProvider, ReferenceProfiles,
|
||||
RenameLayout, ResizeTerminal, ResolveAgentPermissions, ResolveMemoryLinks, SaveEmbedderProfile,
|
||||
SaveProfile, SessionLimitService, SetActiveLayout, SnapshotRunningAgents, StopLiveAgent,
|
||||
StructuredSessions, SuggestedThisSession, SyncAgentWithTemplate, TerminalSessions,
|
||||
UnassignSkillFromAgent, UpdateAgentContext, UpdateAgentPermissions, UpdateLiveState,
|
||||
UpdateMemory, UpdateProjectContext, UpdateProjectPermissions, UpdateSkill, UpdateTemplate,
|
||||
WriteMemory, WriteToTerminal, AGENT_MEMORY_RECALL_BUDGET,
|
||||
};
|
||||
use domain::ports::{
|
||||
AgentContextStore, AgentRuntime, AgentSessionFactory, Clock, Embedder, EmbedderEnvInspector,
|
||||
@ -52,8 +52,8 @@ use infrastructure::{
|
||||
embedder_from_profile, AdaptiveMemoryRecall, ClaudePermissionProjector,
|
||||
ClaudeTranscriptInspector, CliAgentRuntime, CodexPermissionProjector, EmbedderEnvProbe,
|
||||
FsConversationLog, FsEmbedderProfileStore, FsEmbedderPromptStore, FsHandoffStore,
|
||||
FsMemoryStore, FsOrchestratorWatcher, FsPermissionStore, FsProfileStore, FsProjectStore,
|
||||
FsProviderSessionStore, FsSkillStore, FsTemplateStore, Git2Repository,
|
||||
FsLiveStateStore, FsMemoryStore, FsOrchestratorWatcher, FsPermissionStore, FsProfileStore,
|
||||
FsProjectStore, FsProviderSessionStore, FsSkillStore, FsTemplateStore, Git2Repository,
|
||||
HeuristicHandoffSummarizer, IdeaiContextStore, InMemoryConversationRegistry, InMemoryMailbox,
|
||||
LocalFileSystem, LocalProcessSpawner, McpServer, MediatedInbox, NaiveMemoryRecall,
|
||||
OrchestratorWatchHandle, PortablePtyAdapter, RwFileGuard, StructuredSessionFactory,
|
||||
@ -130,6 +130,29 @@ impl application::ConversationLogProvider for AppConversationLogProvider {
|
||||
}
|
||||
}
|
||||
|
||||
/// Implémente [`LiveStateProvider`] (programme live-state, lot LS3) en matérialisant un
|
||||
/// [`UpdateLiveState`] dont le [`FsLiveStateStore`] cible le **project root** du tour.
|
||||
///
|
||||
/// Même raison d'être que [`AppRecordTurnProvider`] : l'[`OrchestratorService`] est
|
||||
/// unique pour tous les projets, alors que le live-state est **par project root**
|
||||
/// (`<root>/.ideai/live-state.json`) et le store fixe sa racine à la construction. On
|
||||
/// construit donc un `UpdateLiveState` frais par transition, ciblant le bon dossier.
|
||||
/// Porte l'horloge (port [`Clock`]) injectée au composition root — `UpdateLiveState`
|
||||
/// l'utilise pour estampiller `updated_at_ms`.
|
||||
struct AppLiveStateProvider {
|
||||
clock: Arc<dyn Clock>,
|
||||
}
|
||||
|
||||
impl LiveStateProvider for AppLiveStateProvider {
|
||||
fn live_state_for(&self, root: &domain::project::ProjectPath) -> Option<Arc<UpdateLiveState>> {
|
||||
let store = Arc::new(FsLiveStateStore::new(root));
|
||||
Some(Arc::new(UpdateLiveState::new(
|
||||
store,
|
||||
Arc::clone(&self.clock),
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
/// Implémente [`ProviderSessionProvider`](application::ProviderSessionProvider) (lot
|
||||
/// P8b) en matérialisant un [`FsProviderSessionStore`] ciblant le **project root** du
|
||||
/// lancement en cours.
|
||||
@ -1196,7 +1219,15 @@ impl AppState {
|
||||
)))
|
||||
// Outil MCP `idea_skill_read` (feature « skills à la MCP ») : sans ça,
|
||||
// `skill.read` renverrait « not configured ». Compose le SkillStore existant.
|
||||
.with_read_skill(Arc::clone(&read_skill)),
|
||||
.with_read_skill(Arc::clone(&read_skill))
|
||||
// Auto-update du live-state (programme live-state, lot LS3) : dérivé des
|
||||
// transitions de délégation (ask→Working, reply→Done), zéro token agent.
|
||||
// Provider par root (`<root>/.ideai/live-state.json`) car le port fixe sa
|
||||
// racine à la construction. Best-effort strict : un échec n'altère jamais la
|
||||
// délégation.
|
||||
.with_live_state(Arc::new(AppLiveStateProvider {
|
||||
clock: Arc::clone(&clock) as Arc<dyn Clock>,
|
||||
}) as Arc<dyn LiveStateProvider>),
|
||||
// NB (régression corrigée) : on ne câble PAS `.with_structured(...)` ici.
|
||||
// Décision produit lot B-2 (« Option 1 Terminal + MCP », cf. construction
|
||||
// de `LaunchAgent` plus haut) : la fabrique structurée est décâblée, donc
|
||||
|
||||
Reference in New Issue
Block a user