6342a46e59
问题: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 端点
145 lines
3.2 KiB
TypeScript
145 lines
3.2 KiB
TypeScript
/**
|
|
* SessionManager Mock 工厂
|
|
*
|
|
* 提供会话管理器的 mock 实现
|
|
*
|
|
* 注意:消息存储已移至 Core 层,SessionManager 只负责会话元数据管理
|
|
*/
|
|
|
|
import { vi } from 'vitest';
|
|
|
|
export interface MockSession {
|
|
id: string;
|
|
name?: string;
|
|
status: 'idle' | 'busy';
|
|
createdAt: number;
|
|
updatedAt: number;
|
|
workdir?: string;
|
|
messageCount: number;
|
|
}
|
|
|
|
export interface MockMessage {
|
|
id: string;
|
|
role: 'user' | 'assistant';
|
|
content: string;
|
|
timestamp: number;
|
|
}
|
|
|
|
/**
|
|
* 创建 Mock SessionManager
|
|
*/
|
|
export function createMockSessionManager() {
|
|
const sessions = new Map<string, MockSession>();
|
|
|
|
const manager = {
|
|
// 初始化
|
|
init: vi.fn().mockResolvedValue(undefined),
|
|
|
|
// Session CRUD
|
|
exists: vi.fn((id: string) => sessions.has(id)),
|
|
|
|
get: vi.fn((id: string) => sessions.get(id)),
|
|
|
|
create: vi.fn((data?: Partial<MockSession>) => {
|
|
const id = data?.id ?? `session-${Date.now()}`;
|
|
const session: MockSession = {
|
|
id,
|
|
name: data?.name,
|
|
status: 'idle',
|
|
createdAt: Date.now(),
|
|
updatedAt: Date.now(),
|
|
workdir: data?.workdir ?? process.cwd(),
|
|
messageCount: 0,
|
|
};
|
|
sessions.set(id, session);
|
|
return session;
|
|
}),
|
|
|
|
delete: vi.fn(async (id: string) => {
|
|
const existed = sessions.has(id);
|
|
sessions.delete(id);
|
|
return existed;
|
|
}),
|
|
|
|
list: vi.fn(() => Array.from(sessions.values())),
|
|
|
|
// 状态更新
|
|
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) => {
|
|
const session = sessions.get(id);
|
|
if (session) {
|
|
session.name = name;
|
|
session.updatedAt = Date.now();
|
|
return session;
|
|
}
|
|
return null;
|
|
}),
|
|
|
|
// Storage 访问
|
|
getStorage: vi.fn(() => null),
|
|
getProjectId: vi.fn((_sessionId: string) => 'default-project'),
|
|
|
|
// 测试辅助方法
|
|
_addSession: (session: MockSession) => {
|
|
sessions.set(session.id, session);
|
|
},
|
|
|
|
_clear: () => {
|
|
sessions.clear();
|
|
},
|
|
|
|
_getSessions: () => sessions,
|
|
};
|
|
|
|
return manager;
|
|
}
|
|
|
|
/**
|
|
* 创建测试用的 Session 数据
|
|
*/
|
|
export function createTestSession(overrides: Partial<MockSession> = {}): MockSession {
|
|
return {
|
|
id: 'test-session-1',
|
|
name: 'Test Session',
|
|
status: 'idle',
|
|
createdAt: Date.now(),
|
|
updatedAt: Date.now(),
|
|
workdir: '/test/workdir',
|
|
messageCount: 0,
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 创建测试用的 Message 数据
|
|
*/
|
|
export function createTestMessage(overrides: Partial<MockMessage> = {}): MockMessage {
|
|
return {
|
|
id: 'test-msg-1',
|
|
role: 'user',
|
|
content: 'Test message',
|
|
timestamp: Date.now(),
|
|
...overrides,
|
|
};
|
|
}
|