diff options
| author | Jacob MacDonald <[email protected]> | 2025-06-13 21:21:40 -0700 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-06-14 04:21:40 +0000 |
| commit | d5c6bb9740a52d87b71d812e698d0e88abf10caa (patch) | |
| tree | 7cb990c0adbd1d76d60a655d3dfa15e22db033e3 /packages/cli/src/ui/hooks/slashCommandProcessor.ts | |
| parent | 1452bb4ca4ffe3b5c13aab81baaf510d4c45f06f (diff) | |
Add `/compress` command to force a compression of the context (#986)
Related to https://b.corp.google.com/issues/423605555 - I figured this might be a simpler solution to start with, while still also being useful on its own even if we do implement that.
Diffstat (limited to 'packages/cli/src/ui/hooks/slashCommandProcessor.ts')
| -rw-r--r-- | packages/cli/src/ui/hooks/slashCommandProcessor.ts | 68 |
1 files changed, 67 insertions, 1 deletions
diff --git a/packages/cli/src/ui/hooks/slashCommandProcessor.ts b/packages/cli/src/ui/hooks/slashCommandProcessor.ts index 861d7bd9..97374e4f 100644 --- a/packages/cli/src/ui/hooks/slashCommandProcessor.ts +++ b/packages/cli/src/ui/hooks/slashCommandProcessor.ts @@ -9,6 +9,7 @@ import { type PartListUnion } from '@google/genai'; import open from 'open'; import process from 'node:process'; import { UseHistoryManagerReturn } from './useHistoryManager.js'; +import { useStateAndRef } from './useStateAndRef.js'; import { Config, GitService, @@ -80,6 +81,13 @@ export const useSlashCommandProcessor = ( return new GitService(config.getProjectRoot()); }, [config]); + const pendingHistoryItems: HistoryItemWithoutId[] = []; + const [pendingCompressionItemRef, setPendingCompressionItem] = + useStateAndRef<HistoryItemWithoutId | null>(null); + if (pendingCompressionItemRef.current != null) { + pendingHistoryItems.push(pendingCompressionItemRef.current); + } + const addMessage = useCallback( (message: Message) => { // Convert Message to HistoryItemWithoutId @@ -105,6 +113,11 @@ export const useSlashCommandProcessor = ( stats: message.stats, duration: message.duration, }; + } else if (message.type === MessageType.COMPRESSION) { + historyItemContent = { + type: 'compression', + compression: message.compression, + }; } else { historyItemContent = { type: message.type as @@ -641,6 +654,57 @@ Add any other context about the problem here. }, 100); }, }, + { + name: 'compress', + altName: 'summarize', + description: 'Compresses the context by replacing it with a summary.', + action: async (_mainCommand, _subCommand, _args) => { + if (pendingCompressionItemRef.current !== null) { + addMessage({ + type: MessageType.ERROR, + content: + 'Already compressing, wait for previous request to complete', + timestamp: new Date(), + }); + return; + } + setPendingCompressionItem({ + type: MessageType.COMPRESSION, + compression: { + isPending: true, + }, + }); + try { + const compressed = await config! + .getGeminiClient()! + .tryCompressChat(true); + if (compressed) { + addMessage({ + type: MessageType.COMPRESSION, + compression: { + isPending: false, + originalTokenCount: compressed.originalTokenCount, + newTokenCount: compressed.newTokenCount, + }, + timestamp: new Date(), + }); + } else { + addMessage({ + type: MessageType.ERROR, + content: 'Failed to compress chat history.', + timestamp: new Date(), + }); + } + } catch (e) { + addMessage({ + type: MessageType.ERROR, + content: `Failed to compress chat history: ${e instanceof Error ? e.message : String(e)}`, + timestamp: new Date(), + }); + } + setPendingCompressionItem(null); + }, + }, ]; if (config?.getCheckpointEnabled()) { @@ -767,6 +831,8 @@ Add any other context about the problem here. loadHistory, addItem, setQuittingMessages, + pendingCompressionItemRef, + setPendingCompressionItem, ]); const handleSlashCommand = useCallback( @@ -830,5 +896,5 @@ Add any other context about the problem here. [addItem, slashCommands, addMessage], ); - return { handleSlashCommand, slashCommands }; + return { handleSlashCommand, slashCommands, pendingHistoryItems }; }; |
