feat: allow queuing messages during compression (#24071) (#26506)

This commit is contained in:
Coco Sheng
2026-05-05 13:52:08 -04:00
committed by GitHub
parent 7cc19c2a1b
commit e80d7cc083
6 changed files with 179 additions and 38 deletions
+62 -1
View File
@@ -100,7 +100,7 @@ import { type LoadedSettings } from '../config/settings.js';
import { createMockSettings } from '../test-utils/settings.js';
import type { InitializationResult } from '../core/initializer.js';
import { useQuotaAndFallback } from './hooks/useQuotaAndFallback.js';
import { StreamingState } from './types.js';
import { StreamingState, MessageType } from './types.js';
import { UIStateContext, type UIState } from './contexts/UIStateContext.js';
import {
UIActionsContext,
@@ -3576,4 +3576,65 @@ describe('AppContainer State Management', () => {
unmount();
});
});
describe('Compression Queuing', () => {
beforeEach(async () => {
const { checkPermissions } = await import(
'./hooks/atCommandProcessor.js'
);
vi.mocked(checkPermissions).mockResolvedValue([]);
vi.spyOn(mockConfig, 'isModelSteeringEnabled').mockReturnValue(true);
const actual = await vi.importActual('./hooks/useMessageQueue.js');
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const { useMessageQueue: realUseMessageQueue } = actual as any;
mockedUseMessageQueue.mockImplementation(realUseMessageQueue);
// Start compression by mocking pendingHistoryItems to include a pending compression
mockedUseGeminiStream.mockImplementation(() => ({
...DEFAULT_GEMINI_STREAM_MOCK,
pendingHistoryItems: [
{
type: MessageType.COMPRESSION,
compression: {
isPending: true,
originalTokenCount: null,
newTokenCount: null,
compressionStatus: null,
},
},
],
}));
});
it('queues messages during compression instead of handling as steering hints', async () => {
const { unmount } = await act(async () => renderAppContainer());
// Verify state isolation
expect(capturedUIState.streamingState).toBe(StreamingState.Idle);
// Submit a message
await act(async () =>
capturedUIActions.handleFinalSubmit('follow up message'),
);
// Verify it was queued, not submitted as steering hint
expect(capturedUIState.messageQueue).toContain('follow up message');
unmount();
});
it('executes slash commands immediately during compression', async () => {
const { unmount } = await act(async () => renderAppContainer());
// Submit a slash command
await act(async () => capturedUIActions.handleFinalSubmit('/help'));
// Verify it was NOT queued
expect(capturedUIState.messageQueue).not.toContain('/help');
unmount();
});
});
});