mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-01 07:24:38 -07:00
feat(cli): lower compression threshold to 0.2 and update UX
- Change default compression threshold to 200k - Introduce 'ChatCompressing' event to handle UI loading - Subtly display context optimization in message footer - Fix associated snapshot tests
This commit is contained in:
@@ -1061,6 +1061,7 @@ Logging in with Google... Restarting Gemini CLI to continue.
|
|||||||
backgroundShells,
|
backgroundShells,
|
||||||
dismissBackgroundShell,
|
dismissBackgroundShell,
|
||||||
retryStatus,
|
retryStatus,
|
||||||
|
isCompressing,
|
||||||
} = useGeminiStream(
|
} = useGeminiStream(
|
||||||
config.getGeminiClient(),
|
config.getGeminiClient(),
|
||||||
historyManager.history,
|
historyManager.history,
|
||||||
@@ -1613,6 +1614,7 @@ Logging in with Google... Restarting Gemini CLI to continue.
|
|||||||
streamingState,
|
streamingState,
|
||||||
shouldShowFocusHint,
|
shouldShowFocusHint,
|
||||||
retryStatus,
|
retryStatus,
|
||||||
|
customWittyPhrases: isCompressing ? ['Optimizing context...'] : undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleGlobalKeypress = useCallback(
|
const handleGlobalKeypress = useCallback(
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import { ToolGroupMessage } from './messages/ToolGroupMessage.js';
|
|||||||
import { GeminiMessageContent } from './messages/GeminiMessageContent.js';
|
import { GeminiMessageContent } from './messages/GeminiMessageContent.js';
|
||||||
import { CompressionMessage } from './messages/CompressionMessage.js';
|
import { CompressionMessage } from './messages/CompressionMessage.js';
|
||||||
import { WarningMessage } from './messages/WarningMessage.js';
|
import { WarningMessage } from './messages/WarningMessage.js';
|
||||||
import { Box } from 'ink';
|
import { Box, Text } from 'ink';
|
||||||
import { AboutBox } from './AboutBox.js';
|
import { AboutBox } from './AboutBox.js';
|
||||||
import { StatsDisplay } from './StatsDisplay.js';
|
import { StatsDisplay } from './StatsDisplay.js';
|
||||||
import { ModelStatsDisplay } from './ModelStatsDisplay.js';
|
import { ModelStatsDisplay } from './ModelStatsDisplay.js';
|
||||||
@@ -75,6 +75,14 @@ export const HistoryItemDisplay: React.FC<HistoryItemDisplayProps> = ({
|
|||||||
{itemForDisplay.type === 'user_shell' && (
|
{itemForDisplay.type === 'user_shell' && (
|
||||||
<UserShellMessage text={itemForDisplay.text} width={terminalWidth} />
|
<UserShellMessage text={itemForDisplay.text} width={terminalWidth} />
|
||||||
)}
|
)}
|
||||||
|
{itemForDisplay.type === 'auto_compression' && (
|
||||||
|
<Box paddingLeft={2} marginTop={0}>
|
||||||
|
<Text dimColor>
|
||||||
|
(Context optimized: {itemForDisplay.compression.originalTokenCount}{' '}
|
||||||
|
→ {itemForDisplay.compression.newTokenCount} tokens)
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
{itemForDisplay.type === 'gemini' && (
|
{itemForDisplay.type === 'gemini' && (
|
||||||
<GeminiMessage
|
<GeminiMessage
|
||||||
text={itemForDisplay.text}
|
text={itemForDisplay.text}
|
||||||
|
|||||||
@@ -77,39 +77,6 @@ exports[`InputPrompt > mouse interaction > should toggle paste expansion on doub
|
|||||||
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄"
|
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`InputPrompt > mouse interaction > should toggle paste expansion on double-click 4`] = `
|
|
||||||
"▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
|
|
||||||
> [Pasted Text: 10 lines]
|
|
||||||
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`InputPrompt > mouse interaction > should toggle paste expansion on double-click 5`] = `
|
|
||||||
"[40m[30m▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀[39m[49m
|
|
||||||
[40m [97m> [7m[[27mPasted Text: 10 lines][39m [49m
|
|
||||||
[40m[30m▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄[39m[49m"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`InputPrompt > mouse interaction > should toggle paste expansion on double-click 6`] = `
|
|
||||||
"[40m[30m▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀[39m[49m
|
|
||||||
[40m [97m> [39m[7ml[27mine1 [49m
|
|
||||||
[40m line2 [49m
|
|
||||||
[40m line3 [49m
|
|
||||||
[40m line4 [49m
|
|
||||||
[40m line5 [49m
|
|
||||||
[40m line6 [49m
|
|
||||||
[40m line7 [49m
|
|
||||||
[40m line8 [49m
|
|
||||||
[40m line9 [49m
|
|
||||||
[40m line10 [49m
|
|
||||||
[40m[30m▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄[39m[49m"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`InputPrompt > mouse interaction > should toggle paste expansion on double-click 7`] = `
|
|
||||||
"[40m[30m▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀[39m[49m
|
|
||||||
[40m [97m> [7m[[27mPasted Text: 10 lines][39m [49m
|
|
||||||
[40m[30m▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄[39m[49m"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`InputPrompt > snapshots > should not show inverted cursor when shell is focused 1`] = `
|
exports[`InputPrompt > snapshots > should not show inverted cursor when shell is focused 1`] = `
|
||||||
"▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
|
"▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
|
||||||
> Type your message or @path/to/file
|
> Type your message or @path/to/file
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import { theme } from '../../semantic-colors.js';
|
|||||||
import { SCREEN_READER_MODEL_PREFIX } from '../../textConstants.js';
|
import { SCREEN_READER_MODEL_PREFIX } from '../../textConstants.js';
|
||||||
import { useUIState } from '../../contexts/UIStateContext.js';
|
import { useUIState } from '../../contexts/UIStateContext.js';
|
||||||
import { useAlternateBuffer } from '../../hooks/useAlternateBuffer.js';
|
import { useAlternateBuffer } from '../../hooks/useAlternateBuffer.js';
|
||||||
|
|
||||||
interface GeminiMessageProps {
|
interface GeminiMessageProps {
|
||||||
text: string;
|
text: string;
|
||||||
isPending: boolean;
|
isPending: boolean;
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ import { type Part, type PartListUnion, FinishReason } from '@google/genai';
|
|||||||
import type {
|
import type {
|
||||||
HistoryItem,
|
HistoryItem,
|
||||||
HistoryItemThinking,
|
HistoryItemThinking,
|
||||||
|
HistoryItemAutoCompression,
|
||||||
HistoryItemWithoutId,
|
HistoryItemWithoutId,
|
||||||
HistoryItemToolGroup,
|
HistoryItemToolGroup,
|
||||||
IndividualToolCallDisplay,
|
IndividualToolCallDisplay,
|
||||||
@@ -203,6 +204,8 @@ export const useGeminiStream = (
|
|||||||
const [pendingHistoryItem, pendingHistoryItemRef, setPendingHistoryItem] =
|
const [pendingHistoryItem, pendingHistoryItemRef, setPendingHistoryItem] =
|
||||||
useStateAndRef<HistoryItemWithoutId | null>(null);
|
useStateAndRef<HistoryItemWithoutId | null>(null);
|
||||||
|
|
||||||
|
const [isCompressing, setIsCompressing] = useState<boolean>(false);
|
||||||
|
|
||||||
const [lastGeminiActivityTime, setLastGeminiActivityTime] =
|
const [lastGeminiActivityTime, setLastGeminiActivityTime] =
|
||||||
useState<number>(0);
|
useState<number>(0);
|
||||||
const [pushedToolCallIds, pushedToolCallIdsRef, setPushedToolCallIds] =
|
const [pushedToolCallIds, pushedToolCallIdsRef, setPushedToolCallIds] =
|
||||||
@@ -765,7 +768,10 @@ export const useGeminiStream = (
|
|||||||
if (pendingHistoryItemRef.current) {
|
if (pendingHistoryItemRef.current) {
|
||||||
addItem(pendingHistoryItemRef.current, userMessageTimestamp);
|
addItem(pendingHistoryItemRef.current, userMessageTimestamp);
|
||||||
}
|
}
|
||||||
setPendingHistoryItem({ type: 'gemini', text: '' });
|
setPendingHistoryItem({
|
||||||
|
type: 'gemini',
|
||||||
|
text: '',
|
||||||
|
});
|
||||||
newGeminiMessageBuffer = eventValue;
|
newGeminiMessageBuffer = eventValue;
|
||||||
}
|
}
|
||||||
// Split large messages for better rendering performance. Ideally,
|
// Split large messages for better rendering performance. Ideally,
|
||||||
@@ -773,11 +779,23 @@ export const useGeminiStream = (
|
|||||||
const splitPoint = findLastSafeSplitPoint(newGeminiMessageBuffer);
|
const splitPoint = findLastSafeSplitPoint(newGeminiMessageBuffer);
|
||||||
if (splitPoint === newGeminiMessageBuffer.length) {
|
if (splitPoint === newGeminiMessageBuffer.length) {
|
||||||
// Update the existing message with accumulated content
|
// Update the existing message with accumulated content
|
||||||
setPendingHistoryItem((item) => ({
|
setPendingHistoryItem((item) => {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
if (!item) return null;
|
||||||
type: item?.type as 'gemini' | 'gemini_content',
|
if (item.type === 'gemini') {
|
||||||
text: newGeminiMessageBuffer,
|
return {
|
||||||
}));
|
...item,
|
||||||
|
type: 'gemini',
|
||||||
|
text: newGeminiMessageBuffer,
|
||||||
|
};
|
||||||
|
} else if (item.type === 'gemini_content') {
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
type: 'gemini_content',
|
||||||
|
text: newGeminiMessageBuffer,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
// This indicates that we need to split up this Gemini Message.
|
// This indicates that we need to split up this Gemini Message.
|
||||||
// Splitting a message is primarily a performance consideration. There is a
|
// Splitting a message is primarily a performance consideration. There is a
|
||||||
@@ -799,7 +817,10 @@ export const useGeminiStream = (
|
|||||||
},
|
},
|
||||||
userMessageTimestamp,
|
userMessageTimestamp,
|
||||||
);
|
);
|
||||||
setPendingHistoryItem({ type: 'gemini_content', text: afterText });
|
setPendingHistoryItem({
|
||||||
|
type: 'gemini_content',
|
||||||
|
text: afterText,
|
||||||
|
});
|
||||||
newGeminiMessageBuffer = afterText;
|
newGeminiMessageBuffer = afterText;
|
||||||
}
|
}
|
||||||
return newGeminiMessageBuffer;
|
return newGeminiMessageBuffer;
|
||||||
@@ -956,14 +977,16 @@ export const useGeminiStream = (
|
|||||||
addItem(pendingHistoryItemRef.current, userMessageTimestamp);
|
addItem(pendingHistoryItemRef.current, userMessageTimestamp);
|
||||||
setPendingHistoryItem(null);
|
setPendingHistoryItem(null);
|
||||||
}
|
}
|
||||||
return addItem({
|
|
||||||
type: 'info',
|
if (eventValue) {
|
||||||
text:
|
addItem(
|
||||||
`IMPORTANT: This conversation exceeded the compress threshold. ` +
|
{
|
||||||
`A compressed context will be sent for future messages (compressed from: ` +
|
type: 'auto_compression',
|
||||||
`${eventValue?.originalTokenCount ?? 'unknown'} to ` +
|
compression: eventValue,
|
||||||
`${eventValue?.newTokenCount ?? 'unknown'} tokens).`,
|
} as HistoryItemAutoCompression,
|
||||||
});
|
userMessageTimestamp,
|
||||||
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
[addItem, pendingHistoryItemRef, setPendingHistoryItem],
|
[addItem, pendingHistoryItemRef, setPendingHistoryItem],
|
||||||
);
|
);
|
||||||
@@ -1095,6 +1118,10 @@ export const useGeminiStream = (
|
|||||||
let geminiMessageBuffer = '';
|
let geminiMessageBuffer = '';
|
||||||
const toolCallRequests: ToolCallRequestInfo[] = [];
|
const toolCallRequests: ToolCallRequestInfo[] = [];
|
||||||
for await (const event of stream) {
|
for await (const event of stream) {
|
||||||
|
if (event.type !== ServerGeminiEventType.ChatCompressing) {
|
||||||
|
setIsCompressing(false);
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
event.type !== ServerGeminiEventType.Thought &&
|
event.type !== ServerGeminiEventType.Thought &&
|
||||||
thoughtRef.current !== null
|
thoughtRef.current !== null
|
||||||
@@ -1140,7 +1167,11 @@ export const useGeminiStream = (
|
|||||||
event.value.contextCleared,
|
event.value.contextCleared,
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
case ServerGeminiEventType.ChatCompressing:
|
||||||
|
setIsCompressing(true);
|
||||||
|
break;
|
||||||
case ServerGeminiEventType.ChatCompressed:
|
case ServerGeminiEventType.ChatCompressed:
|
||||||
|
setIsCompressing(false);
|
||||||
handleChatCompressionEvent(event.value, userMessageTimestamp);
|
handleChatCompressionEvent(event.value, userMessageTimestamp);
|
||||||
break;
|
break;
|
||||||
case ServerGeminiEventType.ToolCallConfirmation:
|
case ServerGeminiEventType.ToolCallConfirmation:
|
||||||
@@ -1683,6 +1714,7 @@ export const useGeminiStream = (
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
streamingState,
|
streamingState,
|
||||||
|
isCompressing,
|
||||||
submitQuery,
|
submitQuery,
|
||||||
initError,
|
initError,
|
||||||
pendingHistoryItems,
|
pendingHistoryItems,
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
type CompressionStatus,
|
type CompressionStatus,
|
||||||
|
type ChatCompressionInfo,
|
||||||
type GeminiCLIExtension,
|
type GeminiCLIExtension,
|
||||||
type MCPServerConfig,
|
type MCPServerConfig,
|
||||||
type ThoughtSummary,
|
type ThoughtSummary,
|
||||||
@@ -248,6 +249,11 @@ export type HistoryItemThinking = HistoryItemBase & {
|
|||||||
thought: ThoughtSummary;
|
thought: ThoughtSummary;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type HistoryItemAutoCompression = HistoryItemBase & {
|
||||||
|
type: 'auto_compression';
|
||||||
|
compression: ChatCompressionInfo;
|
||||||
|
};
|
||||||
|
|
||||||
export type HistoryItemChatList = HistoryItemBase & {
|
export type HistoryItemChatList = HistoryItemBase & {
|
||||||
type: 'chat_list';
|
type: 'chat_list';
|
||||||
chats: ChatDetail[];
|
chats: ChatDetail[];
|
||||||
@@ -372,6 +378,7 @@ export type HistoryItemWithoutId =
|
|||||||
| HistoryItemMcpStatus
|
| HistoryItemMcpStatus
|
||||||
| HistoryItemChatList
|
| HistoryItemChatList
|
||||||
| HistoryItemThinking
|
| HistoryItemThinking
|
||||||
|
| HistoryItemAutoCompression
|
||||||
| HistoryItemHooksList;
|
| HistoryItemHooksList;
|
||||||
|
|
||||||
export type HistoryItem = HistoryItemWithoutId & { id: number };
|
export type HistoryItem = HistoryItemWithoutId & { id: number };
|
||||||
|
|||||||
@@ -1077,6 +1077,7 @@ ${JSON.stringify(
|
|||||||
new AbortController().signal,
|
new AbortController().signal,
|
||||||
'test-prompt-id',
|
'test-prompt-id',
|
||||||
);
|
);
|
||||||
|
await stream.next(); // Trigger ChatCompressing
|
||||||
await stream.next(); // Trigger the generator
|
await stream.next(); // Trigger the generator
|
||||||
|
|
||||||
expect(countTokensSpy).toHaveBeenCalledWith(
|
expect(countTokensSpy).toHaveBeenCalledWith(
|
||||||
@@ -1924,8 +1925,10 @@ ${JSON.stringify(
|
|||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(events).toEqual([
|
expect(events).toEqual([
|
||||||
|
{ type: GeminiEventType.ChatCompressing },
|
||||||
{ type: GeminiEventType.ModelInfo, value: 'default-routed-model' },
|
{ type: GeminiEventType.ModelInfo, value: 'default-routed-model' },
|
||||||
{ type: GeminiEventType.InvalidStream },
|
{ type: GeminiEventType.InvalidStream },
|
||||||
|
{ type: GeminiEventType.ChatCompressing },
|
||||||
{ type: GeminiEventType.Content, value: 'Continued content' },
|
{ type: GeminiEventType.Content, value: 'Continued content' },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -1980,6 +1983,7 @@ ${JSON.stringify(
|
|||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(events).toEqual([
|
expect(events).toEqual([
|
||||||
|
{ type: GeminiEventType.ChatCompressing },
|
||||||
{ type: GeminiEventType.ModelInfo, value: 'default-routed-model' },
|
{ type: GeminiEventType.ModelInfo, value: 'default-routed-model' },
|
||||||
{ type: GeminiEventType.InvalidStream },
|
{ type: GeminiEventType.InvalidStream },
|
||||||
]);
|
]);
|
||||||
@@ -2017,8 +2021,8 @@ ${JSON.stringify(
|
|||||||
const events = await fromAsync(stream);
|
const events = await fromAsync(stream);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
// We expect 3 events (model_info + original + 1 retry)
|
// We expect 5 events (chat_compressing + model_info + original + 1 retry chat_compressing + 1 retry model_info)
|
||||||
expect(events.length).toBe(3);
|
expect(events.length).toBe(5);
|
||||||
expect(
|
expect(
|
||||||
events
|
events
|
||||||
.filter((e) => e.type === GeminiEventType.ModelInfo)
|
.filter((e) => e.type === GeminiEventType.ModelInfo)
|
||||||
|
|||||||
@@ -571,6 +571,7 @@ export class GeminiClient {
|
|||||||
// Check for context window overflow
|
// Check for context window overflow
|
||||||
const modelForLimitCheck = this._getActiveModelForCurrentTurn();
|
const modelForLimitCheck = this._getActiveModelForCurrentTurn();
|
||||||
|
|
||||||
|
yield { type: GeminiEventType.ChatCompressing };
|
||||||
const compressed = await this.tryCompressChat(prompt_id, false);
|
const compressed = await this.tryCompressChat(prompt_id, false);
|
||||||
|
|
||||||
if (compressed.compressionStatus === CompressionStatus.COMPRESSED) {
|
if (compressed.compressionStatus === CompressionStatus.COMPRESSED) {
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ export enum GeminiEventType {
|
|||||||
ModelInfo = 'model_info',
|
ModelInfo = 'model_info',
|
||||||
AgentExecutionStopped = 'agent_execution_stopped',
|
AgentExecutionStopped = 'agent_execution_stopped',
|
||||||
AgentExecutionBlocked = 'agent_execution_blocked',
|
AgentExecutionBlocked = 'agent_execution_blocked',
|
||||||
|
ChatCompressing = 'chat_compressing',
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ServerGeminiRetryEvent = {
|
export type ServerGeminiRetryEvent = {
|
||||||
@@ -192,6 +193,10 @@ export type ServerGeminiChatCompressedEvent = {
|
|||||||
value: ChatCompressionInfo | null;
|
value: ChatCompressionInfo | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type ServerGeminiChatCompressingEvent = {
|
||||||
|
type: GeminiEventType.ChatCompressing;
|
||||||
|
};
|
||||||
|
|
||||||
export type ServerGeminiMaxSessionTurnsEvent = {
|
export type ServerGeminiMaxSessionTurnsEvent = {
|
||||||
type: GeminiEventType.MaxSessionTurns;
|
type: GeminiEventType.MaxSessionTurns;
|
||||||
};
|
};
|
||||||
@@ -213,6 +218,7 @@ export type ServerGeminiCitationEvent = {
|
|||||||
// The original union type, now composed of the individual types
|
// The original union type, now composed of the individual types
|
||||||
export type ServerGeminiStreamEvent =
|
export type ServerGeminiStreamEvent =
|
||||||
| ServerGeminiChatCompressedEvent
|
| ServerGeminiChatCompressedEvent
|
||||||
|
| ServerGeminiChatCompressingEvent
|
||||||
| ServerGeminiCitationEvent
|
| ServerGeminiCitationEvent
|
||||||
| ServerGeminiContentEvent
|
| ServerGeminiContentEvent
|
||||||
| ServerGeminiErrorEvent
|
| ServerGeminiErrorEvent
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ import { PreCompressTrigger } from '../hooks/types.js';
|
|||||||
* Default threshold for compression token count as a fraction of the model's
|
* Default threshold for compression token count as a fraction of the model's
|
||||||
* token limit. If the chat history exceeds this threshold, it will be compressed.
|
* token limit. If the chat history exceeds this threshold, it will be compressed.
|
||||||
*/
|
*/
|
||||||
export const DEFAULT_COMPRESSION_TOKEN_THRESHOLD = 0.5;
|
export const DEFAULT_COMPRESSION_TOKEN_THRESHOLD = 0.2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The fraction of the latest chat history to keep. A value of 0.3
|
* The fraction of the latest chat history to keep. A value of 0.3
|
||||||
|
|||||||
Reference in New Issue
Block a user