1b010fb1f8
聊天历史按有效消息分页并返回原生游标,保留默认原始切片接口 工具和推理记录不占聊天页名额,逐行过滤避免传回大段工具输出 隔离重新加载和项目切换的迟到响应,补齐单飞、重试与消息去重 补充原生和真实App回归测试,增加人工只读日志重放入口 更新B05状态、规范与PR验收记录,不提交用户原始日志
89 lines
2.8 KiB
TypeScript
89 lines
2.8 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
|
|
import {
|
|
directThreadHistoryItemsToMessages,
|
|
directThreadHistoryPage,
|
|
isDirectTurnInProgress,
|
|
prependDirectHistoryMessages,
|
|
} from '../src/features/project-workspace/directThreadEvents';
|
|
|
|
describe('Direct 回合状态与历史时间', () => {
|
|
it('游标来自原始切片,不从没有聊天消息的工具页倒推', () => {
|
|
const page = directThreadHistoryPage(
|
|
{
|
|
items: [{ id: 'tool-older', type: 'function_call_output' }],
|
|
hasMore: true,
|
|
oldestItemId: 'tool-older',
|
|
},
|
|
'message-newer',
|
|
);
|
|
expect(page.messages).toEqual([]);
|
|
expect(page.cursor).toBe('tool-older');
|
|
});
|
|
it('空历史结束,无 ID 或不前进的非终页明确失败而不循环', () => {
|
|
expect(directThreadHistoryPage({ items: [], hasMore: false })).toEqual({
|
|
messages: [],
|
|
cursor: null,
|
|
hasMore: false,
|
|
});
|
|
expect(() => directThreadHistoryPage({ items: [], hasMore: true })).toThrow(
|
|
'游标未前进',
|
|
);
|
|
expect(() =>
|
|
directThreadHistoryPage(
|
|
{
|
|
items: [{ id: 'same' }],
|
|
hasMore: true,
|
|
oldestItemId: 'same',
|
|
},
|
|
'same',
|
|
),
|
|
).toThrow('游标未前进');
|
|
});
|
|
it('重叠页按原始 ID 去重,保留当前正文,旧无 ID 消息不删除', () => {
|
|
const current = [
|
|
{ role: 'assistant' as const, text: '完整正文', messageId: 'a' },
|
|
];
|
|
const old = { role: 'user' as const, text: '用户输入', messageId: 'u' };
|
|
expect(
|
|
prependDirectHistoryMessages(current, [
|
|
old,
|
|
old,
|
|
{ role: 'assistant', text: '旧快照', messageId: 'a' },
|
|
{ role: 'assistant', text: '无身份旧消息' },
|
|
]),
|
|
).toEqual([old, { role: 'assistant', text: '无身份旧消息' }, ...current]);
|
|
});
|
|
|
|
it('终态和空状态不恢复为活动回合', () => {
|
|
for (const status of [
|
|
'completed',
|
|
'failed',
|
|
'interrupted',
|
|
null,
|
|
undefined,
|
|
]) {
|
|
expect(isDirectTurnInProgress(status)).toBe(false);
|
|
}
|
|
for (const status of ['accepted', 'running', 'streaming', 'finalizing']) {
|
|
expect(isDirectTurnInProgress(status)).toBe(true);
|
|
}
|
|
});
|
|
it('按消息 id 读取信封时间,旧记录不使用当前时间补造', () => {
|
|
const items = [
|
|
{
|
|
type: 'message',
|
|
role: 'user',
|
|
id: 'direct-codex:turn:user',
|
|
content: [{ type: 'input_text', text: '帮我修改游戏' }],
|
|
},
|
|
];
|
|
const timestamps = { 'direct-codex:turn:user': 1_800_000_000_001 };
|
|
expect(
|
|
directThreadHistoryItemsToMessages(items, timestamps)[0]?.updatedAt,
|
|
).toBe(1_800_000_000_001);
|
|
expect(directThreadHistoryItemsToMessages(items)[0]?.updatedAt).toBe(0);
|
|
expect(items[0]).not.toHaveProperty('recordedAt');
|
|
});
|
|
});
|