feat(persistence): P7 — reprise par injection du handoff au lancement
Au (re)lancement, l'agent retrouve sur quoi il travaillait : si la cellule a une conversation_id avec un handoff, son objectif + résumé sont injectés en dernière section du convention file (# Reprise de la conversation), best-effort et provider-indépendant. - application : port HandoffProvider (root par appel, comme MemoryRecall) ; LaunchAgent.with_handoff_provider + resolve_handoff (parse uuid + load, jamais bloquant) ; section rendue dans compose_convention_file après la mémoire projet - app-tauri : AppHandoffProvider (FsHandoffStore sur le root du projet) câblé - tests : 4 purs (objectif présent/None/blanc/absent) + 5 intégration (happy path, provider absent, conversation_id None, uuid invalide, sans handoff ⇒ lancement OK sans section) ; application 311 + app-tauri 204 verts Volet --resume/providers.json = P8 (swap cross-profile). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -82,6 +82,25 @@ impl RecordTurnProvider for AppRecordTurnProvider {
|
||||
}
|
||||
}
|
||||
|
||||
/// Implémente [`HandoffProvider`](application::HandoffProvider) (lot P7) en
|
||||
/// matérialisant un [`FsHandoffStore`] ciblant le **project root** du lancement en
|
||||
/// cours.
|
||||
///
|
||||
/// Même raison d'être que [`AppRecordTurnProvider`] : [`LaunchAgent`] est unique pour
|
||||
/// tous les projets, alors que le handoff est **par project root**
|
||||
/// (`<root>/.ideai/conversations/`). On construit donc un store frais par lancement,
|
||||
/// ciblant le bon dossier. Sans état (zéro champ), partagé via un simple `Arc`.
|
||||
struct AppHandoffProvider;
|
||||
|
||||
impl application::HandoffProvider for AppHandoffProvider {
|
||||
fn handoff_store_for(
|
||||
&self,
|
||||
root: &domain::project::ProjectPath,
|
||||
) -> Option<Arc<dyn domain::HandoffStore>> {
|
||||
Some(Arc::new(FsHandoffStore::new(root)) as Arc<dyn domain::HandoffStore>)
|
||||
}
|
||||
}
|
||||
|
||||
/// Everything the IPC layer needs at runtime, managed by Tauri.
|
||||
///
|
||||
/// Use cases are stored behind `Arc` so handlers clone cheaply. The concrete
|
||||
@ -590,19 +609,26 @@ impl AppState {
|
||||
// PTH : tout profil (Claude/Codex inclus) ouvre une cellule terminal. Le code
|
||||
// `launch_structured` reste en place (mort-code retiré au lot de nettoyage B-6).
|
||||
let _session_factory = session_factory; // décâblé en B-2 (nettoyage B-6)
|
||||
let launch_agent = Arc::new(LaunchAgent::new(
|
||||
Arc::clone(&contexts_port),
|
||||
Arc::clone(&profile_store_port),
|
||||
Arc::clone(&runtime_port),
|
||||
Arc::clone(&fs_port),
|
||||
Arc::clone(&pty_port),
|
||||
Arc::clone(&skill_store_port),
|
||||
Arc::clone(&terminal_sessions),
|
||||
Arc::clone(&events_port),
|
||||
Arc::clone(&ids) as Arc<dyn IdGenerator>,
|
||||
Arc::clone(&memory_recall_port),
|
||||
Some(Arc::clone(&check_embedder_suggestion)),
|
||||
));
|
||||
let launch_agent = Arc::new(
|
||||
LaunchAgent::new(
|
||||
Arc::clone(&contexts_port),
|
||||
Arc::clone(&profile_store_port),
|
||||
Arc::clone(&runtime_port),
|
||||
Arc::clone(&fs_port),
|
||||
Arc::clone(&pty_port),
|
||||
Arc::clone(&skill_store_port),
|
||||
Arc::clone(&terminal_sessions),
|
||||
Arc::clone(&events_port),
|
||||
Arc::clone(&ids) as Arc<dyn IdGenerator>,
|
||||
Arc::clone(&memory_recall_port),
|
||||
Some(Arc::clone(&check_embedder_suggestion)),
|
||||
)
|
||||
// Reprise conversationnelle (lot P7) : à chaque (re)lancement, si la cellule
|
||||
// porte une conversation et qu'un handoff existe (`<root>/.ideai/conversations/`),
|
||||
// son résumé est réinjecté dans le convention file. Best-effort, additif :
|
||||
// un handoff absent/illisible ⇒ lancement normal sans section.
|
||||
.with_handoff_provider(Arc::new(AppHandoffProvider) as Arc<dyn application::HandoffProvider>),
|
||||
);
|
||||
|
||||
// Hot-swap an agent's runtime profile (§15.1). Reuses the shared context/
|
||||
// profile/project/fs stores, the live-session registry and PTY port, and
|
||||
|
||||
Reference in New Issue
Block a user