import type { ConversationMessage, Turn } from './conversation'; /** * A conversation as an object, independent of any surface. Holds what the * user sees (items, in-flight draft, sending flag) and what the model sees * (turns), and notifies subscribers on change so React reads it through * useSyncExternalStore. Framework-free so the domain harness can test it and * so a conversation can outlive the panel showing it, be shown in two places, * or sit beside others in a tabbed view. */ export interface ConversationItem { id: number; proposalStatus?: string; } export interface ConversationSnapshot { items: readonly TItem[]; sending: boolean; draft: string; } export declare class Conversation { readonly id: string; /** Display name for a chat list or tab; empty until a host sets it. */ title: string; /** History as the model sees it — whole turns, see conversation.ts. */ turns: Turn[]; /** The one-time "older messages are no longer sent" notice has been shown. */ trimNoticeShown: boolean; private items; private sending; private draft; private nextItemId; /** Proposal item id → the tool message recording its outcome in `turns`. */ private outcomes; private listeners; private snapshot; constructor(id?: string); subscribe(listener: () => void): () => void; /** Stable between changes, new object after each — what useSyncExternalStore wants. */ getSnapshot(): ConversationSnapshot; get isSending(): boolean; get isEmpty(): boolean; pushItem(item: Omit): number; updateItem(id: number, patch: Partial): void; setSending(sending: boolean): void; setDraft(next: string | ((draft: string) => string)): void; appendTurn(turn: Turn): void; /** Remember which tool message in history records a proposal card's fate. */ recordProposalOutcome(itemId: number, message: ConversationMessage): void; /** * Marks a proposal item and rewrites its outcome in history, so the model's * next request says what the user did with the card. */ setProposalStatus(itemId: number, status: string, outcomeText: string): void; clear(): void; private emit; } /** * The app's conversations, keyed by id. A surface that names a conversation * id gets the same Conversation back across remounts; a tabbed view lists * them. Subscribable so a chat list re-renders when one is added or removed. */ export declare class ConversationStore { private byId; private listeners; private snapshot; get(id: string): Conversation | undefined; /** The conversation with this id, created on first use. */ ensure(id: string): Conversation; remove(id: string): void; /** Every conversation, in creation order. Stable until the set changes. */ list(): readonly Conversation[]; subscribe(listener: () => void): () => void; private emit; } //# sourceMappingURL=conversationState.d.ts.map