From 90018b6fd9380bfd1f88020c6e26e9e7912d89b4 Mon Sep 17 00:00:00 2001 From: Charles Packer Date: Tue, 6 Jan 2026 15:05:16 -0800 Subject: [PATCH] fix: cache pending approval denials on ESC interrupt (#479) Co-authored-by: Letta --- src/cli/App.tsx | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/cli/App.tsx b/src/cli/App.tsx index 04b310f..0522bef 100644 --- a/src/cli/App.tsx +++ b/src/cli/App.tsx @@ -2234,7 +2234,19 @@ export default function App({ } refreshDerived(); - // Clear any pending approvals since we're cancelling + // Cache any pending approvals as denials to send with the next message + // This tells the server "I'm rejecting these approvals" so it doesn't stay stuck waiting + if (pendingApprovals.length > 0) { + const denialResults = pendingApprovals.map((approval) => ({ + type: "approval" as const, + tool_call_id: approval.toolCallId, + approve: false, + reason: "User interrupted the stream", + })); + setQueuedApprovalResults(denialResults); + } + + // Clear local approval state setPendingApprovals([]); setApprovalContexts([]); setApprovalResults([]); @@ -2282,6 +2294,7 @@ export default function App({ isExecutingTool, refreshDerived, setStreaming, + pendingApprovals, ]); // Keep ref to latest processConversation to avoid circular deps in useEffect