From 9731ccaa7dfe144ae6140bdb5c73319ccdbe521a Mon Sep 17 00:00:00 2001 From: eric Date: Sun, 31 May 2026 18:34:52 -0700 Subject: [PATCH] [eric] ui: oversized file popup is now plain english (shrink it / remove), error toast no longer dumps backend stack traces --- .../ChatInput/hooks/useContextFiles.ts | 7 +- .../ChatInput/view/ChatInputOverlays.tsx | 76 ++++++++++--------- 2 files changed, 44 insertions(+), 39 deletions(-) diff --git a/frontend/src/app/pages/AgentChat/ChatInput/hooks/useContextFiles.ts b/frontend/src/app/pages/AgentChat/ChatInput/hooks/useContextFiles.ts index 14053956..c5ac32f3 100644 --- a/frontend/src/app/pages/AgentChat/ChatInput/hooks/useContextFiles.ts +++ b/frontend/src/app/pages/AgentChat/ChatInput/hooks/useContextFiles.ts @@ -102,8 +102,11 @@ export function useContextFiles( setContextPaths((prev) => prev.map((cp) => cp.path === path ? { ...cp, path: newPath, tokens: newTokens, kind: 'text', media_type: 'text/plain' } : cp)); setOversizeQueue((q) => q.filter((o) => o.path !== path)); } catch (err) { - const msg = err instanceof Error ? err.message : 'summarize failed'; - setSummarizeError(`${msg}. Detach the file or connect an aux provider in Settings.`); + // Don't show backend stack traces / model error JSON to users. The raw error + // ("Error code: 400 - {'error': {'message': '[claude/...] prompt is too long...'}}") + // is logged in console for devs; users see a plain English ask. + if (err instanceof Error) console.error('[summarize] failed:', err.message); + setSummarizeError('Could not shrink the file. Try removing it, or pick a model with a bigger window in Settings.'); } finally { setSummarizingPath(null); } diff --git a/frontend/src/app/pages/AgentChat/ChatInput/view/ChatInputOverlays.tsx b/frontend/src/app/pages/AgentChat/ChatInput/view/ChatInputOverlays.tsx index d73f13d0..7a1b3f22 100644 --- a/frontend/src/app/pages/AgentChat/ChatInput/view/ChatInputOverlays.tsx +++ b/frontend/src/app/pages/AgentChat/ChatInput/view/ChatInputOverlays.tsx @@ -74,46 +74,48 @@ export const ChatInputOverlays: React.FC = ({ anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }} sx={{ mb: 10 }} > - - oversizeQueue[0] && summarizeOversize(oversizeQueue[0].path)} - sx={{ - background: 'rgba(255,255,255,0.18)', color: 'inherit', border: 'none', - borderRadius: '6px', px: 1, py: 0.5, fontSize: '0.72rem', cursor: 'pointer', - '&:hover': { background: 'rgba(255,255,255,0.28)' }, - '&:disabled': { opacity: 0.6, cursor: 'wait' }, - }} - > - {summarizingPath === oversizeQueue[0]?.path ? 'Summarizing…' : 'Summarize instead'} - - oversizeQueue[0] && detachOversize(oversizeQueue[0].path)} - sx={{ - background: 'transparent', color: 'inherit', border: '1px solid rgba(255,255,255,0.4)', - borderRadius: '6px', px: 1, py: 0.5, fontSize: '0.72rem', cursor: 'pointer', - '&:hover': { background: 'rgba(255,255,255,0.12)' }, - }} - > - Detach - - - } + {oversizeQueue[0] ? ( - - {oversizeQueue[0].name} is ~{formatTokenCount(oversizeQueue[0].tokens)} tokens, over 50% of this model's window ({formatTokenCount(currentModelCtx)}). Summarize sends the file content to your configured aux provider. - + + This file is too big to fit. Want me to shrink it down to a summary, or just remove it? + ) : null} - + + oversizeQueue[0] && summarizeOversize(oversizeQueue[0].path)} + sx={{ + bgcolor: c.accent.primary, color: '#fff', + border: 'none', borderRadius: '6px', + px: 1.5, py: 0.6, fontSize: '0.8rem', fontWeight: 500, cursor: 'pointer', + '&:hover': { bgcolor: c.accent.hover }, + '&:disabled': { opacity: 0.6, cursor: 'wait' }, + }} + > + {summarizingPath === oversizeQueue[0]?.path ? 'Shrinking…' : 'Shrink it'} + + oversizeQueue[0] && detachOversize(oversizeQueue[0].path)} + sx={{ + bgcolor: 'transparent', color: c.text.secondary, + border: `1px solid ${c.border.medium}`, borderRadius: '6px', + px: 1.5, py: 0.6, fontSize: '0.8rem', cursor: 'pointer', + '&:hover': { bgcolor: c.bg.secondary, color: c.text.primary }, + }} + > + Remove + + +