|
|
|
@@ -1,5 +1,6 @@
|
|
|
|
|
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|
|
|
|
import type { ModelMessage, LanguageModel } from 'ai';
|
|
|
|
|
import { CompressionStatus } from '../../../src/context/types.js';
|
|
|
|
|
|
|
|
|
|
// Mock prune module
|
|
|
|
|
const mockPrune = vi.fn();
|
|
|
|
@@ -45,13 +46,13 @@ describe('CompressionManager - 压缩管理器扩展测试', () => {
|
|
|
|
|
vi.clearAllMocks();
|
|
|
|
|
manager = new CompressionManager();
|
|
|
|
|
|
|
|
|
|
// 默认 mock 返回值
|
|
|
|
|
// 默认 mock 返回值 - 使用 DetailedCompressionResult
|
|
|
|
|
mockEstimateMessages.mockReturnValue(1000);
|
|
|
|
|
mockFormat.mockReturnValue('1K');
|
|
|
|
|
mockPrune.mockReturnValue({ messages: [], freedTokens: 0 });
|
|
|
|
|
mockFilterCompacted.mockImplementation((msgs) => msgs);
|
|
|
|
|
mockCompact.mockResolvedValue({ messages: [], freedTokens: 0 });
|
|
|
|
|
mockSimpleCompact.mockReturnValue({ messages: [], freedTokens: 0 });
|
|
|
|
|
mockCompact.mockResolvedValue({ messages: [], freedTokens: 0, type: 'none', status: CompressionStatus.NOOP });
|
|
|
|
|
mockSimpleCompact.mockReturnValue({ messages: [], freedTokens: 0, type: 'none', status: CompressionStatus.NOOP });
|
|
|
|
|
mockIsSummaryMessage.mockReturnValue(false);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
@@ -174,7 +175,7 @@ describe('CompressionManager - 压缩管理器扩展测试', () => {
|
|
|
|
|
it('有模型时使用 AI 压缩', async () => {
|
|
|
|
|
const mockModel = {} as LanguageModel;
|
|
|
|
|
manager.setModel(mockModel);
|
|
|
|
|
mockCompact.mockResolvedValue({ messages: [], freedTokens: 2000 });
|
|
|
|
|
mockCompact.mockResolvedValue({ messages: [], freedTokens: 2000, type: 'compaction', status: CompressionStatus.SUCCESS });
|
|
|
|
|
|
|
|
|
|
const messages = createMessages(5);
|
|
|
|
|
const result = await manager.compact(messages);
|
|
|
|
@@ -184,7 +185,7 @@ describe('CompressionManager - 压缩管理器扩展测试', () => {
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('无模型时使用简单压缩', async () => {
|
|
|
|
|
mockSimpleCompact.mockReturnValue({ messages: [], freedTokens: 500 });
|
|
|
|
|
mockSimpleCompact.mockReturnValue({ messages: [], freedTokens: 500, type: 'compaction', status: CompressionStatus.SUCCESS });
|
|
|
|
|
|
|
|
|
|
const messages = createMessages(5);
|
|
|
|
|
const result = await manager.compact(messages);
|
|
|
|
@@ -196,7 +197,9 @@ describe('CompressionManager - 压缩管理器扩展测试', () => {
|
|
|
|
|
|
|
|
|
|
describe('compress - 自动压缩', () => {
|
|
|
|
|
it('先 prune 后不需要 compact', async () => {
|
|
|
|
|
mockEstimateMessages.mockReturnValue(10000); // 低于阈值
|
|
|
|
|
mockEstimateMessages
|
|
|
|
|
.mockReturnValueOnce(150000) // shouldCompress check - 高于阈值
|
|
|
|
|
.mockReturnValueOnce(10000); // 第二次 shouldCompress check - prune 后低于阈值
|
|
|
|
|
mockPrune.mockReturnValue({ messages: [], freedTokens: 500 });
|
|
|
|
|
|
|
|
|
|
const messages = createMessages(5);
|
|
|
|
@@ -210,7 +213,7 @@ describe('CompressionManager - 压缩管理器扩展测试', () => {
|
|
|
|
|
it('prune 后仍需 compact', async () => {
|
|
|
|
|
mockEstimateMessages.mockReturnValue(150000); // 高于阈值
|
|
|
|
|
mockPrune.mockReturnValue({ messages: createMessages(3), freedTokens: 500 });
|
|
|
|
|
mockSimpleCompact.mockReturnValue({ messages: [], freedTokens: 1000 });
|
|
|
|
|
mockSimpleCompact.mockReturnValue({ messages: [], freedTokens: 1000, type: 'compaction', status: CompressionStatus.SUCCESS });
|
|
|
|
|
|
|
|
|
|
const messages = createMessages(5);
|
|
|
|
|
const result = await manager.compress(messages);
|
|
|
|
@@ -222,7 +225,7 @@ describe('CompressionManager - 压缩管理器扩展测试', () => {
|
|
|
|
|
it('只 compact 时类型为 compaction', async () => {
|
|
|
|
|
mockEstimateMessages.mockReturnValue(150000);
|
|
|
|
|
mockPrune.mockReturnValue({ messages: createMessages(5), freedTokens: 0 });
|
|
|
|
|
mockSimpleCompact.mockReturnValue({ messages: [], freedTokens: 1000 });
|
|
|
|
|
mockSimpleCompact.mockReturnValue({ messages: [], freedTokens: 1000, type: 'compaction', status: CompressionStatus.SUCCESS });
|
|
|
|
|
|
|
|
|
|
const messages = createMessages(5);
|
|
|
|
|
const result = await manager.compress(messages);
|
|
|
|
@@ -243,7 +246,7 @@ describe('CompressionManager - 压缩管理器扩展测试', () => {
|
|
|
|
|
it('足够消息时执行压缩', async () => {
|
|
|
|
|
mockEstimateMessages.mockReturnValue(10000);
|
|
|
|
|
mockPrune.mockReturnValue({ messages: createMessages(3), freedTokens: 500 });
|
|
|
|
|
mockSimpleCompact.mockReturnValue({ messages: createMessages(2), freedTokens: 300 });
|
|
|
|
|
mockSimpleCompact.mockReturnValue({ messages: createMessages(2), freedTokens: 300, type: 'compaction', status: CompressionStatus.SUCCESS });
|
|
|
|
|
|
|
|
|
|
const messages = createMessages(10);
|
|
|
|
|
const result = await manager.forceCompress(messages);
|
|
|
|
@@ -256,7 +259,7 @@ describe('CompressionManager - 压缩管理器扩展测试', () => {
|
|
|
|
|
manager.setModel(mockModel);
|
|
|
|
|
mockEstimateMessages.mockReturnValue(10000);
|
|
|
|
|
mockPrune.mockReturnValue({ messages: createMessages(5), freedTokens: 500 });
|
|
|
|
|
mockCompact.mockResolvedValue({ messages: createMessages(2), freedTokens: 1000 });
|
|
|
|
|
mockCompact.mockResolvedValue({ messages: createMessages(2), freedTokens: 1000, type: 'compaction', status: CompressionStatus.SUCCESS });
|
|
|
|
|
|
|
|
|
|
const messages = createMessages(10);
|
|
|
|
|
await manager.forceCompress(messages);
|
|
|
|
@@ -269,8 +272,9 @@ describe('CompressionManager - 压缩管理器扩展测试', () => {
|
|
|
|
|
manager.setModel(mockModel);
|
|
|
|
|
mockEstimateMessages.mockReturnValue(10000);
|
|
|
|
|
mockPrune.mockReturnValue({ messages: createMessages(5), freedTokens: 500 });
|
|
|
|
|
mockCompact.mockRejectedValue(new Error('AI error'));
|
|
|
|
|
mockSimpleCompact.mockReturnValue({ messages: createMessages(2), freedTokens: 800 });
|
|
|
|
|
// 使用 FAILED 状态而不是 reject
|
|
|
|
|
mockCompact.mockResolvedValue({ messages: createMessages(5), freedTokens: 0, type: 'none', status: CompressionStatus.FAILED_ERROR });
|
|
|
|
|
mockSimpleCompact.mockReturnValue({ messages: createMessages(2), freedTokens: 800, type: 'compaction', status: CompressionStatus.SUCCESS });
|
|
|
|
|
|
|
|
|
|
const messages = createMessages(10);
|
|
|
|
|
const result = await manager.forceCompress(messages);
|
|
|
|
|