feat(domain,infra,app): rotation/rétention log.jsonl + lecture paginée (LS6)
Backend uniquement (UI React repoussée à LS7) : - domain : port ConversationArchive + structs SegmentStats/PageCursor/PageDirection/ TurnSlice/RotationDecision/RotationThresholds, fn pures rotation_plan/clamp_page_limit + consts ; re-exports lib. - infrastructure : impl ConversationArchive pour FsConversationLog (stats/rotate/page + helpers), archive segmentée hors chemin chaud. - application : ReadConversationPage + DTO + ConversationArchiveProvider (conversation/paginate), RotateConversationLog (conversation/rotate), exports mod/lib. - app-tauri : AppConversationArchiveProvider + wiring (state), rotation détachée dans launch_agent + commande read_conversation_page (commands), DTOs (dto), commande enregistrée (generate_handler!). - tests (QA, verts) : conversation_log, conversation_rotate_paginate (nouveau), dto (module test). Pivots INV-LS6 et cohérence fold-après-rotation verts. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -26,14 +26,15 @@ use application::{
|
||||
LiveSessions, LiveStateLeanProvider, LiveStateProvider, LiveStateReadProvider, 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,
|
||||
ReadContext, ReadConversationPage, ReadMemory, ReadMemoryIndex, ReadProjectContext, ReadSkill,
|
||||
RecallMemory, ReconcileLayouts, RecordTurn, RecordTurnProvider, ReferenceProfiles,
|
||||
RenameLayout, ResizeTerminal, ResolveAgentPermissions, ResolveMemoryLinks,
|
||||
RotateConversationLog, 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,
|
||||
@ -93,6 +94,24 @@ impl RecordTurnProvider for AppRecordTurnProvider {
|
||||
}
|
||||
}
|
||||
|
||||
/// Implémente [`ConversationArchiveProvider`](application::ConversationArchiveProvider)
|
||||
/// (lot LS6) en matérialisant un [`FsConversationLog`] (qui implémente aussi
|
||||
/// [`domain::ConversationArchive`]) ciblant le **project root** courant.
|
||||
///
|
||||
/// Même raison d'être que [`AppRecordTurnProvider`] : les use cases d'archivage/pagination
|
||||
/// sont uniques pour tous les projets, alors que les logs sont **par project root**. On
|
||||
/// construit donc un archive frais par appel, ciblant le bon dossier. Sans état.
|
||||
struct AppConversationArchiveProvider;
|
||||
|
||||
impl application::ConversationArchiveProvider for AppConversationArchiveProvider {
|
||||
fn conversation_archive_for(
|
||||
&self,
|
||||
root: &domain::project::ProjectPath,
|
||||
) -> Option<Arc<dyn domain::ConversationArchive>> {
|
||||
Some(Arc::new(FsConversationLog::new(root)) as Arc<dyn domain::ConversationArchive>)
|
||||
}
|
||||
}
|
||||
|
||||
/// Implémente [`HandoffProvider`](application::HandoffProvider) (lot P7) en
|
||||
/// matérialisant un [`FsHandoffStore`] ciblant le **project root** du lancement en
|
||||
/// cours.
|
||||
@ -414,6 +433,10 @@ pub struct AppState {
|
||||
pub list_resumable_agents: Arc<ListResumableAgents>,
|
||||
/// Read-only live/busy state for the project's manifest agents.
|
||||
pub get_project_work_state: Arc<GetProjectWorkState>,
|
||||
/// Human paginated read of a conversation's full transcript (lot LS6).
|
||||
pub read_conversation_page: Arc<ReadConversationPage>,
|
||||
/// Best-effort log rotation, triggered off the hot path at thread resume/open (lot LS6).
|
||||
pub rotate_conversation_log: Arc<RotateConversationLog>,
|
||||
/// Rebinds an already-running agent's live session to a visible cell (Lot D).
|
||||
pub attach_live_agent: Arc<AttachLiveAgent>,
|
||||
/// Tears down an already-running agent's live session by agent id (Lot D).
|
||||
@ -1143,6 +1166,17 @@ impl AppState {
|
||||
as Arc<dyn application::ConversationLogProvider>,
|
||||
),
|
||||
);
|
||||
// Lot LS6 — rotation (hors chemin chaud) + lecture humaine paginée. Tous deux
|
||||
// composent le provider d'archive par root ; la rotation lit aussi le handoff
|
||||
// (plancher `up_to`, INV-LS6). Aucune persistance déclenchée par un `append`.
|
||||
let archive_provider = Arc::new(AppConversationArchiveProvider)
|
||||
as Arc<dyn application::ConversationArchiveProvider>;
|
||||
let read_conversation_page =
|
||||
Arc::new(ReadConversationPage::new(Arc::clone(&archive_provider)));
|
||||
let rotate_conversation_log = Arc::new(RotateConversationLog::new(
|
||||
Arc::clone(&archive_provider),
|
||||
Arc::new(AppHandoffProvider) as Arc<dyn application::HandoffProvider>,
|
||||
));
|
||||
// Lot D — actions contrôlées agent-level sur les sessions vivantes : attach
|
||||
// (rebind de la cellule-vue, zéro spawn) et stop (kill PTY via la primitive
|
||||
// `CloseTerminal` existante / shutdown structuré). Aucune création de session.
|
||||
@ -1343,6 +1377,8 @@ impl AppState {
|
||||
change_agent_profile,
|
||||
list_resumable_agents,
|
||||
get_project_work_state,
|
||||
read_conversation_page,
|
||||
rotate_conversation_log,
|
||||
attach_live_agent,
|
||||
stop_live_agent,
|
||||
inspect_conversation,
|
||||
|
||||
Reference in New Issue
Block a user