refactor(server): 将 Core 模块从动态导入改为静态导入
- 移除 adapter.ts 中约 160 行冗余接口定义 - 简化 initCore 函数,改为初始化检查逻辑 - 简化 getOrCreateAgent,直接使用 ConfigurationError 类 - 更新缓存类型注解使用 Core 导出的类型 - 简化事件订阅代码,直接使用 agentEventEmitter - 在 Core index.ts 中添加 agentEventEmitter 导出 - 更新测试文件适配静态导入模式
This commit is contained in:
@@ -12,6 +12,8 @@ import { vi } from 'vitest';
|
||||
export function createMockAgent() {
|
||||
return {
|
||||
setRegistry: vi.fn(),
|
||||
setSessionManager: vi.fn(),
|
||||
setAgentMode: vi.fn(),
|
||||
chat: vi.fn().mockResolvedValue({
|
||||
text: 'mock response',
|
||||
messages: [
|
||||
@@ -38,6 +40,21 @@ export function createMockAgent() {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建 Mock SessionManager 实例
|
||||
*/
|
||||
export function createMockSessionManager() {
|
||||
return {
|
||||
init: vi.fn().mockResolvedValue(undefined),
|
||||
getSession: vi.fn().mockReturnValue({ id: 'session-1', messages: [] }),
|
||||
setMessages: vi.fn().mockResolvedValue(undefined),
|
||||
setDiscoveredTools: vi.fn().mockResolvedValue(undefined),
|
||||
save: vi.fn().mockResolvedValue(undefined),
|
||||
close: vi.fn().mockResolvedValue(undefined),
|
||||
restoreSession: vi.fn().mockResolvedValue({ id: 'session-1', messages: [] }),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建 Mock ProviderRegistry
|
||||
*/
|
||||
@@ -118,8 +135,148 @@ export function createMockToolRegistry(overrides: Partial<ReturnType<typeof crea
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建完整的 Core 模块 mock
|
||||
* 创建 Mock AgentEventEmitter
|
||||
*/
|
||||
export function createMockAgentEventEmitter() {
|
||||
return {
|
||||
on: vi.fn().mockReturnValue(() => {}), // 返回 unsubscribe 函数
|
||||
off: vi.fn(),
|
||||
emit: vi.fn(),
|
||||
clear: vi.fn(),
|
||||
};
|
||||
}
|
||||
|
||||
// 全局 mock 状态,用于测试时配置
|
||||
let mockProviderRegistry = createMockProviderRegistry();
|
||||
let mockAgentRegistry = createMockAgentRegistry();
|
||||
let mockPermissionManager = createMockPermissionManager();
|
||||
let mockToolRegistry = createMockToolRegistry();
|
||||
let mockAgentEventEmitter = createMockAgentEventEmitter();
|
||||
let mockAgent = createMockAgent();
|
||||
let mockSessionManager = createMockSessionManager();
|
||||
let loadConfigFn = vi.fn().mockReturnValue({
|
||||
provider: 'anthropic',
|
||||
apiKey: 'test-api-key',
|
||||
model: 'claude-sonnet-4-20250514',
|
||||
maxTokens: 4096,
|
||||
systemPrompt: 'test prompt',
|
||||
});
|
||||
|
||||
/**
|
||||
* 重置所有 mock 到默认状态
|
||||
*/
|
||||
export function resetCoreMocks() {
|
||||
mockProviderRegistry = createMockProviderRegistry();
|
||||
mockAgentRegistry = createMockAgentRegistry();
|
||||
mockPermissionManager = createMockPermissionManager();
|
||||
mockToolRegistry = createMockToolRegistry();
|
||||
mockAgentEventEmitter = createMockAgentEventEmitter();
|
||||
mockAgent = createMockAgent();
|
||||
mockSessionManager = createMockSessionManager();
|
||||
loadConfigFn = vi.fn().mockReturnValue({
|
||||
provider: 'anthropic',
|
||||
apiKey: 'test-api-key',
|
||||
model: 'claude-sonnet-4-20250514',
|
||||
maxTokens: 4096,
|
||||
systemPrompt: 'test prompt',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置 mock 行为
|
||||
*/
|
||||
export function configureMocks(config: {
|
||||
providerRegistry?: Partial<ReturnType<typeof createMockProviderRegistry>>;
|
||||
agentRegistry?: Partial<ReturnType<typeof createMockAgentRegistry>>;
|
||||
permissionManager?: Partial<ReturnType<typeof createMockPermissionManager>>;
|
||||
toolRegistry?: Partial<ReturnType<typeof createMockToolRegistry>>;
|
||||
agentEventEmitter?: Partial<ReturnType<typeof createMockAgentEventEmitter>>;
|
||||
agent?: Partial<ReturnType<typeof createMockAgent>>;
|
||||
sessionManager?: Partial<ReturnType<typeof createMockSessionManager>>;
|
||||
loadConfig?: ReturnType<typeof vi.fn>;
|
||||
}) {
|
||||
if (config.providerRegistry) {
|
||||
Object.assign(mockProviderRegistry, config.providerRegistry);
|
||||
}
|
||||
if (config.agentRegistry) {
|
||||
Object.assign(mockAgentRegistry, config.agentRegistry);
|
||||
}
|
||||
if (config.permissionManager) {
|
||||
Object.assign(mockPermissionManager, config.permissionManager);
|
||||
}
|
||||
if (config.toolRegistry) {
|
||||
Object.assign(mockToolRegistry, config.toolRegistry);
|
||||
}
|
||||
if (config.agentEventEmitter) {
|
||||
Object.assign(mockAgentEventEmitter, config.agentEventEmitter);
|
||||
}
|
||||
if (config.agent) {
|
||||
Object.assign(mockAgent, config.agent);
|
||||
}
|
||||
if (config.sessionManager) {
|
||||
Object.assign(mockSessionManager, config.sessionManager);
|
||||
}
|
||||
if (config.loadConfig) {
|
||||
loadConfigFn = config.loadConfig;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前 mock 状态(用于测试验证)
|
||||
*/
|
||||
export function getMocks() {
|
||||
return {
|
||||
providerRegistry: mockProviderRegistry,
|
||||
agentRegistry: mockAgentRegistry,
|
||||
permissionManager: mockPermissionManager,
|
||||
toolRegistry: mockToolRegistry,
|
||||
agentEventEmitter: mockAgentEventEmitter,
|
||||
agent: mockAgent,
|
||||
sessionManager: mockSessionManager,
|
||||
loadConfig: loadConfigFn,
|
||||
};
|
||||
}
|
||||
|
||||
// Mock Agent 类
|
||||
export const MockAgent = vi.fn().mockImplementation(function (this: any) {
|
||||
Object.assign(this, mockAgent);
|
||||
return this;
|
||||
});
|
||||
|
||||
// Mock SessionManager 类
|
||||
export const MockSessionManager = vi.fn().mockImplementation(function (this: any) {
|
||||
Object.assign(this, mockSessionManager);
|
||||
return this;
|
||||
});
|
||||
|
||||
// Mock ConfigurationError 类
|
||||
export class MockConfigurationError extends Error {
|
||||
provider: string;
|
||||
|
||||
constructor(message: string, provider: string = 'anthropic') {
|
||||
super(message);
|
||||
this.name = 'ConfigurationError';
|
||||
this.provider = provider;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出完整的 Core 模块 mock
|
||||
* 用于 vi.mock('@ai-assistant/core', ...)
|
||||
*/
|
||||
export const coreMock = {
|
||||
Agent: MockAgent,
|
||||
SessionManager: MockSessionManager,
|
||||
toolRegistry: mockToolRegistry,
|
||||
loadConfig: () => loadConfigFn(),
|
||||
getPermissionManager: () => mockPermissionManager,
|
||||
getProviderRegistry: () => mockProviderRegistry,
|
||||
agentRegistry: mockAgentRegistry,
|
||||
agentEventEmitter: mockAgentEventEmitter,
|
||||
ConfigurationError: MockConfigurationError,
|
||||
};
|
||||
|
||||
// 兼容旧 API
|
||||
export function createMockCoreModule(overrides: {
|
||||
agent?: Partial<ReturnType<typeof createMockAgent>>;
|
||||
providerRegistry?: Partial<ReturnType<typeof createMockProviderRegistry>>;
|
||||
@@ -129,39 +286,16 @@ export function createMockCoreModule(overrides: {
|
||||
loadConfig?: ReturnType<typeof vi.fn>;
|
||||
saveConfig?: ReturnType<typeof vi.fn>;
|
||||
} = {}) {
|
||||
const mockAgent = { ...createMockAgent(), ...overrides.agent };
|
||||
const mockProviderRegistry = createMockProviderRegistry(overrides.providerRegistry);
|
||||
const mockAgentRegistry = createMockAgentRegistry(overrides.agentRegistry);
|
||||
const mockPermissionManager = createMockPermissionManager(overrides.permissionManager);
|
||||
const mockToolRegistry = createMockToolRegistry(overrides.toolRegistry);
|
||||
|
||||
// 创建一个真正的类来模拟 Agent 构造函数
|
||||
const MockAgentClass = vi.fn().mockImplementation(function (this: any) {
|
||||
Object.assign(this, mockAgent);
|
||||
return this;
|
||||
configureMocks({
|
||||
agent: overrides.agent,
|
||||
providerRegistry: overrides.providerRegistry,
|
||||
agentRegistry: overrides.agentRegistry,
|
||||
permissionManager: overrides.permissionManager,
|
||||
toolRegistry: overrides.toolRegistry,
|
||||
loadConfig: overrides.loadConfig,
|
||||
});
|
||||
|
||||
return {
|
||||
Agent: MockAgentClass,
|
||||
toolRegistry: mockToolRegistry,
|
||||
loadConfig: overrides.loadConfig ?? vi.fn().mockReturnValue({
|
||||
provider: 'anthropic',
|
||||
apiKey: 'test-api-key',
|
||||
model: 'claude-sonnet-4-20250514',
|
||||
maxTokens: 4096,
|
||||
systemPrompt: 'test prompt',
|
||||
}),
|
||||
saveConfig: overrides.saveConfig ?? vi.fn(),
|
||||
getPermissionManager: vi.fn().mockReturnValue(mockPermissionManager),
|
||||
getProviderRegistry: vi.fn().mockReturnValue(mockProviderRegistry),
|
||||
agentRegistry: mockAgentRegistry,
|
||||
// 额外暴露内部 mock 以便测试验证
|
||||
_mockAgent: mockAgent,
|
||||
_mockProviderRegistry: mockProviderRegistry,
|
||||
_mockAgentRegistry: mockAgentRegistry,
|
||||
_mockPermissionManager: mockPermissionManager,
|
||||
_mockToolRegistry: mockToolRegistry,
|
||||
};
|
||||
return coreMock;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -169,9 +303,6 @@ export function createMockCoreModule(overrides: {
|
||||
*/
|
||||
export function createConfigurationErrorMock(message: string, provider: string = 'anthropic') {
|
||||
return vi.fn().mockImplementation(() => {
|
||||
const error = new Error(message) as Error & { provider: string };
|
||||
error.name = 'ConfigurationError';
|
||||
error.provider = provider;
|
||||
throw error;
|
||||
throw new MockConfigurationError(message, provider);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user