feat(domain,application,infrastructure,backend,web-server,app-tauri,frontend): persistance et reprise des conversations de CLI custom par agent — index durable <projet>/.ideai/conversations/custom-index.json borné aux conversations non vides par agent (conversation_id logique, titre dérivé de la première invite, created/updated_at_ms), port CustomConversationIndex + adaptateur FsCustomConversationIndex, persistence des messages utilisateur et finals agent dans le log de conversation existant, DTO/commandes app-tauri et routes web-server pour lister/rouvrir, CustomAgentChatView: ouverture par défaut sur une nouvelle conversation, menu reprise d'une conversation passée ou nouvelle conversation, replay de l'historique sauvegardé (user+finals) à la réouverture, affichage normal des nouveaux messages après reprise, /clean ouvre une nouvelle conversation, aucune entrée créée si la conversation courante est vide, injection de l'historique dans le contexte agent différée au premier nouveau message après reprise — #363 (QA verte: git diff --check, cargo fmt --all -- --check, cargo tests ciblés infrastructure/application/web-server/app-tauri/backend, npm run typecheck, tests frontend ciblés et CustomAgentChatView, npm run build)

This commit is contained in:
2026-09-16 23:20:31 +02:00
parent 83b78f438f
commit 943c4525d7
30 changed files with 1794 additions and 109 deletions

View File

@ -107,6 +107,7 @@ import type {
TicketPriority,
TicketStatus,
TurnPage,
TurnView,
Unsubscribe,
} from "@/domain";
@ -207,10 +208,23 @@ export interface AgentChatHandle {
readonly cellKind: "chat";
/** Conversation id assigned by launch when the backend minted one. */
readonly assignedConversationId?: string;
/** Durable Prompt/Final history returned only for an explicit reopen. */
readonly history?: TurnView[];
readonly historyHasMore?: boolean;
readonly historyNextAnchor?: string;
readonly resumed?: boolean;
/** Why a successful structured open has no replayable transcript. */
readonly transcriptUnavailableReason?: ConversationTranscriptUnavailableReason;
}
/** One non-empty durable custom-CLI conversation in the agent menu. */
export interface CustomAgentConversationSummary {
conversationId: string;
title: string;
createdAtMs: number;
updatedAtMs: number;
}
export type ConversationTranscriptUnavailableReason =
| "missingTranscript"
| "emptyConversation";
@ -364,6 +378,12 @@ export interface AgentGateway {
agentId: string,
options: OpenTerminalOptions,
): Promise<AgentChatHandle>;
/** Lists the latest durable custom-CLI conversations for one agent. */
listCustomAgentConversations?(
projectId: string,
agentId: string,
limit?: number,
): Promise<CustomAgentConversationSummary[]>;
/**
* Re-attaches a custom chat view to a still-live structured session, replaying
* retained reply chunks before subsequent live chunks arrive.