From 6d0c98ee5e8367ad07ec7b933b64d73118d607b1 Mon Sep 17 00:00:00 2001 From: Cameron Date: Mon, 12 Jan 2026 15:37:51 -0800 Subject: [PATCH] feat: add LETTA_BACKFILL env var to disable message history backfilling (#504) --- src/agent/check-approval.ts | 23 +++++++++++++++++++++++ src/cli/App.tsx | 23 +++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/src/agent/check-approval.ts b/src/agent/check-approval.ts index d785794..fa02ef8 100644 --- a/src/agent/check-approval.ts +++ b/src/agent/check-approval.ts @@ -10,6 +10,16 @@ import { debugWarn } from "../utils/debug"; // Number of recent messages to backfill when resuming a session const MESSAGE_HISTORY_LIMIT = 15; +/** + * Check if message backfilling is enabled via LETTA_BACKFILL env var. + * Defaults to true. Set LETTA_BACKFILL=0 or LETTA_BACKFILL=false to disable. + */ +function isBackfillEnabled(): boolean { + const val = process.env.LETTA_BACKFILL; + // Default to enabled (true) - only disable if explicitly set to "0" or "false" + return val !== "0" && val !== "false"; +} + export interface ResumeData { pendingApproval: ApprovalRequest | null; // Deprecated: use pendingApprovals pendingApprovals: ApprovalRequest[]; @@ -63,6 +73,14 @@ export async function getResumeData( "check-approval", `No in-context messages (message_ids empty/null) - no pending approvals`, ); + // Skip backfill if disabled via LETTA_BACKFILL=false + if (!isBackfillEnabled()) { + return { + pendingApproval: null, + pendingApprovals: [], + messageHistory: [], + }; + } const historyCount = Math.min(MESSAGE_HISTORY_LIMIT, messages.length); let messageHistory = messages.slice(-historyCount); if (messageHistory[0]?.message_type === "tool_return_message") { @@ -198,6 +216,11 @@ export async function getResumeData( } // Get last N messages for backfill (always use cursor messages for history) + // Skip backfill if disabled via LETTA_BACKFILL=false + if (!isBackfillEnabled()) { + return { pendingApproval, pendingApprovals, messageHistory: [] }; + } + const historyCount = Math.min(MESSAGE_HISTORY_LIMIT, messages.length); let messageHistory = messages.slice(-historyCount); diff --git a/src/cli/App.tsx b/src/cli/App.tsx index 959aaca..d705b55 100644 --- a/src/cli/App.tsx +++ b/src/cli/App.tsx @@ -6718,11 +6718,13 @@ Plan file path: ${planFilePath}`; }); buffersRef.current.order.push(statusId); refreshDerived(); + commitEligibleLines(buffersRef.current); } }, [ loadingState, continueSession, messageHistory.length, + commitEligibleLines, columns, agentProvenance, agentState, @@ -7145,6 +7147,27 @@ Plan file path: ${planFilePath}`; )} + {/* Fallback approval UI when backfill is disabled (no liveItems) */} + {liveItems.length === 0 && currentApproval && ( + + handleApproveCurrent()} + onApproveAlways={(scope) => handleApproveAlways(scope)} + onDeny={(reason) => handleDenyCurrent(reason)} + onCancel={handleCancelApprovals} + isFocused={true} + approveAlwaysText={ + currentApprovalContext?.approveAlwaysText + } + allowPersistence={ + currentApprovalContext?.allowPersistence ?? true + } + /> + + )} + {/* Subagent group display - shows running/completed subagents */}