/** * Work out what a regenerate should send, separately from sending it. * * TORUK Core defines regenerate in terms of its edit path * (`useMessageActions.handleRefresh` calls `handleEditSubmit` with unchanged * content): find the user turn the answer belongs to, drop everything from there * on, and re-send that question with the preceding conversation as history. * * The decision is pure, so it is tested on its own — the parts with edge cases * are which turn owns the answer, what counts as context, and not duplicating the * question when the caller re-adds it. */ import type { MessageType } from '@/widget/types'; /** What the engine accepts as prior context (`IMessage` in the server's interface). */ export type PredictionHistoryMessage = { message: string; type: 'userMessage' | 'apiMessage'; }; export type RegeneratePlan = { /** The question to send again. */ question: string; /** The transcript with the superseded exchange removed, ending before the question. */ prefix: MessageType[]; /** Conversation context for the new answer. */ history: PredictionHistoryMessage[]; /** Transcript index of the user turn being replaced — the point the conversation forks at. */ userIndex: number; }; /** * Plan a regenerate of the assistant turn at `assistantIndex`, or return null when * there is nothing to regenerate — the index is not an assistant turn, or no user * turn precedes it, or that turn has no text to re-send. * * The prefix stops *before* the user turn because the caller's submit path re-adds * the question; including it here would duplicate it. */ export declare function planRegenerate(messages: readonly MessageType[], assistantIndex: number): RegeneratePlan | null; /** * Plan an edit of the user turn at `userIndex`, resending it as `newContent`. * * The same shape as a regenerate, and for the same reason Core implements one in terms of the * other: replacing a turn and re-answering it are the same operation on the transcript, differing * only in whether the question changes. * * Returns null when the index is not a user turn or the replacement is blank — an empty edit is a * cancel, not a turn. */ export declare function planEdit(messages: readonly MessageType[], userIndex: number, newContent: string): RegeneratePlan | null;