From c6e8bee85ff4abc0fc02f4c2a6a66a98a38f3053 Mon Sep 17 00:00:00 2001 From: Douwe Osinga Date: Tue, 5 Aug 2025 11:24:39 +0200 Subject: [PATCH] Tell the user to hit compact --- ui/desktop/src/components/BaseChat.tsx | 4 +-- ui/desktop/src/components/ChatInput.tsx | 18 ++++++------- .../context_management/ChatContextManager.tsx | 21 +++++++-------- .../context_management/ContextHandler.tsx | 8 +++--- ...maryButton.tsx => ManualCompactButton.tsx} | 27 ++++++++++--------- 5 files changed, 38 insertions(+), 40 deletions(-) rename ui/desktop/src/components/context_management/{ManualSummaryButton.tsx => ManualCompactButton.tsx} (76%) diff --git a/ui/desktop/src/components/BaseChat.tsx b/ui/desktop/src/components/BaseChat.tsx index 3681eadf1989..dd85dafcca83 100644 --- a/ui/desktop/src/components/BaseChat.tsx +++ b/ui/desktop/src/components/BaseChat.tsx @@ -127,7 +127,7 @@ function BaseChatContent({ summaryContent, summarizedThread, isSummaryModalOpen, - isLoadingSummary, + isLoadingCompaction, resetMessagesWithSummary, closeSummaryModal, updateSummary, @@ -513,7 +513,7 @@ function BaseChatContent({ {chatState !== ChatState.Idle && (
diff --git a/ui/desktop/src/components/ChatInput.tsx b/ui/desktop/src/components/ChatInput.tsx index 1f15d921a8db..10bc69cf1fa5 100644 --- a/ui/desktop/src/components/ChatInput.tsx +++ b/ui/desktop/src/components/ChatInput.tsx @@ -12,7 +12,7 @@ import { Message } from '../types/message'; import { DirSwitcher } from './bottom_menu/DirSwitcher'; import ModelsBottomBar from './settings/models/bottom_bar/ModelsBottomBar'; import { BottomMenuModeSelection } from './bottom_menu/BottomMenuModeSelection'; -import { ManualSummarizeButton } from './context_management/ManualSummaryButton'; +import { ManualCompactButton } from './context_management/ManualCompactButton'; import { AlertType, useAlerts } from './alerts'; import { useToolCount } from './alerts/useToolCount'; import { useConfig } from './ConfigContext'; @@ -110,7 +110,7 @@ export default function ChatInput({ const { alerts, addAlert, clearAlerts } = useAlerts(); const dropdownRef = useRef(null); const toolCount = useToolCount(); - const { isLoadingSummary } = useChatContextManager(); + const { isLoadingCompaction } = useChatContextManager(); const { getProviders, read } = useConfig(); const { getCurrentModelAndProvider, currentModel, currentProvider } = useModelAndProvider(); const [tokenLimit, setTokenLimit] = useState(TOKEN_LIMIT_DEFAULT); @@ -416,7 +416,7 @@ export default function ChatInput({ // Only show warning alert when approaching limit addAlert({ type: AlertType.Warning, - message: `Approaching token limit (${numTokens.toLocaleString()}/${tokenLimit.toLocaleString()}) \n You're reaching the model's conversation limit. The session will be saved — copy anything important and start a new one to continue.`, + message: `Approaching token limit (${numTokens.toLocaleString()}/${tokenLimit.toLocaleString()}) \n You're reaching the model's conversation limit. Consider compacting the conversation to continue.`, autoShow: true, // Auto-show token limit warnings }); } else { @@ -880,7 +880,7 @@ export default function ChatInput({ evt.preventDefault(); const canSubmit = !isLoading && - !isLoadingSummary && + !isLoadingCompaction && (displayValue.trim() || pastedImages.some((img) => img.filePath && !img.error && !img.isLoading) || allDroppedFiles.some((file) => !file.error && !file.isLoading)); @@ -894,7 +894,7 @@ export default function ChatInput({ e.preventDefault(); const canSubmit = !isLoading && - !isLoadingSummary && + !isLoadingCompaction && (displayValue.trim() || pastedImages.some((img) => img.filePath && !img.error && !img.isLoading) || allDroppedFiles.some((file) => !file.error && !file.isLoading)); @@ -1073,7 +1073,7 @@ export default function ChatInput({ isAnyDroppedFileLoading || isRecording || isTranscribing || - isLoadingSummary + isLoadingCompaction } className={`rounded-full px-10 py-2 flex items-center gap-2 ${ !hasSubmittableContent || @@ -1081,12 +1081,12 @@ export default function ChatInput({ isAnyDroppedFileLoading || isRecording || isTranscribing || - isLoadingSummary + isLoadingCompaction ? 'bg-slate-600 text-white cursor-not-allowed opacity-50 border-slate-600' : 'bg-slate-600 text-white hover:bg-slate-700 border-slate-600 hover:cursor-pointer' }`} title={ - isLoadingSummary + isLoadingCompaction ? 'Summarizing conversation...' : isAnyImageLoading ? 'Waiting for images to save...' @@ -1287,7 +1287,7 @@ export default function ChatInput({
{messages.length > 0 && ( - boolean; getContextHandlerType: (message: Message) => 'contextLengthExceeded' | 'summarizationRequested'; handleContextLengthExceeded: (messages: Message[]) => Promise; - handleManualSummarization: ( - messages: Message[], - setMessages: (messages: Message[]) => void - ) => void; + handleManualCompaction: (messages: Message[], setMessages: (messages: Message[]) => void) => void; } // Create the context @@ -50,12 +47,12 @@ export const ChatContextManagerProvider: React.FC<{ children: React.ReactNode }> const [summaryContent, setSummaryContent] = useState(''); const [summarizedThread, setSummarizedThread] = useState([]); const [isSummaryModalOpen, setIsSummaryModalOpen] = useState(false); - const [isLoadingSummary, setIsLoadingSummary] = useState(false); + const [isLoadingCompaction, setIsLoadingCompaction] = useState(false); const [errorLoadingSummary, setErrorLoadingSummary] = useState(false); const [preparingManualSummary, setPreparingManualSummary] = useState(false); const handleContextLengthExceeded = async (messages: Message[]): Promise => { - setIsLoadingSummary(true); + setIsLoadingCompaction(true); setErrorLoadingSummary(false); setPreparingManualSummary(true); @@ -79,17 +76,17 @@ export const ChatContextManagerProvider: React.FC<{ children: React.ReactNode }> setSummarizedThread(convertedMessages); } - setIsLoadingSummary(false); + setIsLoadingCompaction(false); } catch (err) { console.error('Error handling context length exceeded:', err); setErrorLoadingSummary(true); - setIsLoadingSummary(false); + setIsLoadingCompaction(false); } finally { setPreparingManualSummary(false); } }; - const handleManualSummarization = ( + const handleManualCompaction = ( messages: Message[], setMessages: (messages: Message[]) => void ): void => { @@ -242,7 +239,7 @@ export const ChatContextManagerProvider: React.FC<{ children: React.ReactNode }> summaryContent, summarizedThread, isSummaryModalOpen, - isLoadingSummary, + isLoadingCompaction, errorLoadingSummary, preparingManualSummary, @@ -256,7 +253,7 @@ export const ChatContextManagerProvider: React.FC<{ children: React.ReactNode }> hasSummarizationRequestedContent, getContextHandlerType, handleContextLengthExceeded, - handleManualSummarization, + handleManualCompaction, }; return ( diff --git a/ui/desktop/src/components/context_management/ContextHandler.tsx b/ui/desktop/src/components/context_management/ContextHandler.tsx index 0610e5915e9f..6685ada7580b 100644 --- a/ui/desktop/src/components/context_management/ContextHandler.tsx +++ b/ui/desktop/src/components/context_management/ContextHandler.tsx @@ -22,7 +22,7 @@ export const ContextHandler: React.FC = ({ }) => { const { summaryContent, - isLoadingSummary, + isLoadingCompaction, errorLoadingSummary, openSummaryModal, handleContextLengthExceeded, @@ -62,13 +62,13 @@ export const ContextHandler: React.FC = ({ // Scroll when summarization starts (loading state) useEffect(() => { - if (isLoadingSummary && shouldAllowSummaryInteraction) { + if (isLoadingCompaction && shouldAllowSummaryInteraction) { // Delay the scroll slightly to ensure the loading content is rendered setTimeout(() => { onSummaryComplete?.(); }, 100); } - }, [isLoadingSummary, shouldAllowSummaryInteraction, onSummaryComplete]); + }, [isLoadingCompaction, shouldAllowSummaryInteraction, onSummaryComplete]); // Function to trigger the async operation properly const triggerContextLengthExceeded = () => { @@ -234,7 +234,7 @@ export const ContextHandler: React.FC = ({
- {isLoadingSummary && shouldAllowSummaryInteraction + {isLoadingCompaction && shouldAllowSummaryInteraction ? renderLoadingState() : renderContentState()} diff --git a/ui/desktop/src/components/context_management/ManualSummaryButton.tsx b/ui/desktop/src/components/context_management/ManualCompactButton.tsx similarity index 76% rename from ui/desktop/src/components/context_management/ManualSummaryButton.tsx rename to ui/desktop/src/components/context_management/ManualCompactButton.tsx index 867b9c59a1d3..daf1b52d3c15 100644 --- a/ui/desktop/src/components/context_management/ManualSummaryButton.tsx +++ b/ui/desktop/src/components/context_management/ManualCompactButton.tsx @@ -14,18 +14,18 @@ import { Tooltip, TooltipContent, TooltipTrigger } from '../ui/Tooltip'; import { useChatContextManager } from './ChatContextManager'; import { Message } from '../../types/message'; -interface ManualSummarizeButtonProps { +interface ManualCompactButtonProps { messages: Message[]; isLoading?: boolean; // need this prop to know if Goose is responding setMessages: (messages: Message[]) => void; // context management is triggered via special message content types } -export const ManualSummarizeButton: React.FC = ({ +export const ManualCompactButton: React.FC = ({ messages, isLoading = false, setMessages, }) => { - const { handleManualSummarization, isLoadingSummary } = useChatContextManager(); + const { handleManualCompaction, isLoadingCompaction } = useChatContextManager(); const [isConfirmationOpen, setIsConfirmationOpen] = useState(false); @@ -33,13 +33,13 @@ export const ManualSummarizeButton: React.FC = ({ setIsConfirmationOpen(true); }; - const handleSummarize = async () => { + const handleCompaction = async () => { setIsConfirmationOpen(false); try { - handleManualSummarization(messages, setMessages); + handleManualCompaction(messages, setMessages); } catch (error) { - console.error('Error in handleSummarize:', error); + console.error('Error in handleCompaction:', error); } }; @@ -57,17 +57,17 @@ export const ManualSummarizeButton: React.FC = ({ type="button" className={cn( 'flex items-center justify-center text-text-default/70 hover:text-text-default text-xs cursor-pointer transition-colors', - (isLoadingSummary || isLoading) && + (isLoadingCompaction || isLoading) && 'cursor-not-allowed text-text-default/30 hover:text-text-default/30 opacity-50' )} onClick={handleClick} - disabled={isLoadingSummary || isLoading} + disabled={isLoadingCompaction || isLoading} > - {isLoadingSummary ? 'Summarizing conversation...' : 'Summarize conversation context'} + {isLoadingCompaction ? 'Compacting conversation...' : 'Compact conversation context'} @@ -78,10 +78,11 @@ export const ManualSummarizeButton: React.FC = ({ - Summarize Conversation + Compact Conversation - This will summarize your conversation history to save context space. + This will compact your conversation by summarizing the context into a single message + and will help you save context space for future interactions. @@ -97,8 +98,8 @@ export const ManualSummarizeButton: React.FC = ({ -