import type { AutoCompactState } from "./types" import { RETRY_CONFIG } from "./types" import type { Client } from "./client" import { clearSessionState, getEmptyContentAttempt, getOrCreateRetryState } from "./state" import { sanitizeEmptyMessagesBeforeSummarize } from "./message-builder" import { fixEmptyMessages } from "./empty-content-recovery" export async function runSummarizeRetryStrategy(params: { sessionID: string msg: Record autoCompactState: AutoCompactState client: Client directory: string errorType?: string messageIndex?: number }): Promise { const retryState = getOrCreateRetryState(params.autoCompactState, params.sessionID) if (params.errorType?.includes("non-empty content")) { const attempt = getEmptyContentAttempt(params.autoCompactState, params.sessionID) if (attempt < 3) { const fixed = await fixEmptyMessages({ sessionID: params.sessionID, autoCompactState: params.autoCompactState, client: params.client, messageIndex: params.messageIndex, }) if (fixed) { setTimeout(() => { void runSummarizeRetryStrategy(params) }, 500) return } } else { await params.client.tui .showToast({ body: { title: "Recovery Failed", message: "Max recovery attempts (3) reached for empty content error. Please start a new session.", variant: "error", duration: 10000, }, }) .catch(() => {}) return } } if (Date.now() - retryState.lastAttemptTime > 300000) { retryState.attempt = 0 params.autoCompactState.truncateStateBySession.delete(params.sessionID) } if (retryState.attempt < RETRY_CONFIG.maxAttempts) { retryState.attempt++ retryState.lastAttemptTime = Date.now() const providerID = params.msg.providerID as string | undefined const modelID = params.msg.modelID as string | undefined if (providerID && modelID) { try { await sanitizeEmptyMessagesBeforeSummarize(params.sessionID, params.client) await params.client.tui .showToast({ body: { title: "Auto Compact", message: `Summarizing session (attempt ${retryState.attempt}/${RETRY_CONFIG.maxAttempts})...`, variant: "warning", duration: 3000, }, }) .catch(() => {}) const summarizeBody = { providerID, modelID, auto: true } await params.client.session.summarize({ path: { id: params.sessionID }, body: summarizeBody as never, query: { directory: params.directory }, }) return } catch { const delay = RETRY_CONFIG.initialDelayMs * Math.pow(RETRY_CONFIG.backoffFactor, retryState.attempt - 1) const cappedDelay = Math.min(delay, RETRY_CONFIG.maxDelayMs) setTimeout(() => { void runSummarizeRetryStrategy(params) }, cappedDelay) return } } else { await params.client.tui .showToast({ body: { title: "Summarize Skipped", message: "Missing providerID or modelID.", variant: "warning", duration: 3000, }, }) .catch(() => {}) } } clearSessionState(params.autoCompactState, params.sessionID) await params.client.tui .showToast({ body: { title: "Auto Compact Failed", message: "All recovery attempts failed. Please start a new session.", variant: "error", duration: 5000, }, }) .catch(() => {}) }