refactor(storage): 统一消息存储到 Core 层
问题:Server 端只存储最终文本响应,工具调用的中间消息丢失。 解决方案: - Agent.chat() 返回 ChatResult,包含完整消息链 - Server SessionManager 简化为只管理会话元数据 - 消息 API 改为从 Core Storage 读取 - 移除 Server 端的消息存储和 addMessage 方法 影响范围: - core: Agent.chat() 返回类型变更 - server: SessionManager 接口变更,移除消息存储 - server: GET /sessions/:id/messages 从 Core 读取 - server: 移除 POST /sessions/:id/messages 端点
This commit is contained in:
@@ -12,7 +12,13 @@ import { vi } from 'vitest';
|
||||
export function createMockAgent() {
|
||||
return {
|
||||
setRegistry: vi.fn(),
|
||||
chat: vi.fn().mockResolvedValue('mock response'),
|
||||
chat: vi.fn().mockResolvedValue({
|
||||
text: 'mock response',
|
||||
messages: [
|
||||
{ role: 'user', content: 'test' },
|
||||
{ role: 'assistant', content: 'mock response' },
|
||||
],
|
||||
}),
|
||||
getToolCount: vi.fn().mockReturnValue({ core: 5, discovered: 0, total: 5 }),
|
||||
getContextUsageFormatted: vi.fn().mockReturnValue('10k / 200k'),
|
||||
getContextUsage: vi.fn().mockReturnValue({
|
||||
@@ -25,6 +31,10 @@ export function createMockAgent() {
|
||||
getCompressionManager: vi.fn().mockReturnValue({
|
||||
shouldCompress: vi.fn().mockReturnValue(false),
|
||||
}),
|
||||
getHistory: vi.fn().mockReturnValue([
|
||||
{ role: 'user', content: 'test' },
|
||||
{ role: 'assistant', content: 'mock response' },
|
||||
]),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
* SessionManager Mock 工厂
|
||||
*
|
||||
* 提供会话管理器的 mock 实现
|
||||
*
|
||||
* 注意:消息存储已移至 Core 层,SessionManager 只负责会话元数据管理
|
||||
*/
|
||||
|
||||
import { vi } from 'vitest';
|
||||
@@ -13,6 +15,7 @@ export interface MockSession {
|
||||
createdAt: number;
|
||||
updatedAt: number;
|
||||
workdir?: string;
|
||||
messageCount: number;
|
||||
}
|
||||
|
||||
export interface MockMessage {
|
||||
@@ -27,8 +30,6 @@ export interface MockMessage {
|
||||
*/
|
||||
export function createMockSessionManager() {
|
||||
const sessions = new Map<string, MockSession>();
|
||||
const messages = new Map<string, MockMessage[]>();
|
||||
let messageIdCounter = 1;
|
||||
|
||||
const manager = {
|
||||
// 初始化
|
||||
@@ -48,44 +49,40 @@ export function createMockSessionManager() {
|
||||
createdAt: Date.now(),
|
||||
updatedAt: Date.now(),
|
||||
workdir: data?.workdir ?? process.cwd(),
|
||||
messageCount: 0,
|
||||
};
|
||||
sessions.set(id, session);
|
||||
messages.set(id, []);
|
||||
return session;
|
||||
}),
|
||||
|
||||
delete: vi.fn(async (id: string) => {
|
||||
const existed = sessions.has(id);
|
||||
sessions.delete(id);
|
||||
messages.delete(id);
|
||||
return existed;
|
||||
}),
|
||||
|
||||
list: vi.fn(() => Array.from(sessions.values())),
|
||||
|
||||
// 消息管理
|
||||
addMessage: vi.fn(async (sessionId: string, msg: { role: 'user' | 'assistant'; content: string }) => {
|
||||
const msgList = messages.get(sessionId) || [];
|
||||
const newMsg: MockMessage = {
|
||||
id: `msg-${messageIdCounter++}`,
|
||||
role: msg.role,
|
||||
content: msg.content,
|
||||
timestamp: Date.now(),
|
||||
};
|
||||
msgList.push(newMsg);
|
||||
messages.set(sessionId, msgList);
|
||||
return newMsg;
|
||||
}),
|
||||
|
||||
getMessages: vi.fn((id: string) => messages.get(id) || []),
|
||||
|
||||
// 状态更新
|
||||
updateStatus: vi.fn((id: string, status: 'idle' | 'busy') => {
|
||||
const session = sessions.get(id);
|
||||
if (session) {
|
||||
session.status = status;
|
||||
session.updatedAt = Date.now();
|
||||
return session;
|
||||
}
|
||||
return undefined;
|
||||
}),
|
||||
|
||||
// 更新消息计数
|
||||
updateMessageCount: vi.fn((id: string, count: number) => {
|
||||
const session = sessions.get(id);
|
||||
if (session) {
|
||||
session.messageCount = count;
|
||||
session.updatedAt = Date.now();
|
||||
return session;
|
||||
}
|
||||
return undefined;
|
||||
}),
|
||||
|
||||
updateSessionName: vi.fn(async (id: string, name: string) => {
|
||||
@@ -98,26 +95,20 @@ export function createMockSessionManager() {
|
||||
return null;
|
||||
}),
|
||||
|
||||
// Storage 访问
|
||||
getStorage: vi.fn(() => null),
|
||||
getProjectId: vi.fn((_sessionId: string) => 'default-project'),
|
||||
|
||||
// 测试辅助方法
|
||||
_addSession: (session: MockSession) => {
|
||||
sessions.set(session.id, session);
|
||||
messages.set(session.id, []);
|
||||
},
|
||||
|
||||
_addMessage: (sessionId: string, message: MockMessage) => {
|
||||
const msgList = messages.get(sessionId) || [];
|
||||
msgList.push(message);
|
||||
messages.set(sessionId, msgList);
|
||||
},
|
||||
|
||||
_clear: () => {
|
||||
sessions.clear();
|
||||
messages.clear();
|
||||
messageIdCounter = 1;
|
||||
},
|
||||
|
||||
_getSessions: () => sessions,
|
||||
_getMessages: () => messages,
|
||||
};
|
||||
|
||||
return manager;
|
||||
@@ -134,6 +125,7 @@ export function createTestSession(overrides: Partial<MockSession> = {}): MockSes
|
||||
createdAt: Date.now(),
|
||||
updatedAt: Date.now(),
|
||||
workdir: '/test/workdir',
|
||||
messageCount: 0,
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user