Files
linshen 5de5614664 refactor(core): 重构LLM服务为Adapter模式架构
重大架构升级:
- 引入Adapter模式,实现Provider解耦
- 新增7个Provider适配器(OpenAI、Gemini、Anthropic等)
- 精简LLMService从2000+行到300+行
- 引入TextModelConfig新类型系统,支持向后兼容
- 完善类型定义和测试覆盖

架构改进:
- 抽象基类AbstractTextProviderAdapter提供模板方法
- TextAdapterRegistry统一管理所有适配器
- 支持动态模型获取(OpenAI兼容API)
- 提供配置转换器实现平滑升级

新增文件:
- packages/core/src/services/llm/adapters/ (8个文件)
- packages/core/src/services/model/converter.ts
- packages/core/src/services/model/text-model-defaults.ts
- docs/architecture/llm-refactor.md
- 9个新增测试文件

修改文件:
- packages/core/src/services/llm/service.ts
- packages/core/src/services/model/types.ts
- packages/core/src/index.ts
- 31个测试文件更新
- UI组件和composables适配新类型

BREAKING CHANGE: 模型配置结构从ModelConfig升级为TextModelConfig
(已提供converter.ts确保向后兼容和自动转换)

测试结果:
✅ TypeScript类型检查通过 (core + ui)
✅ 563个测试通过,90个跳过
✅ Core包构建成功
2025-10-04 01:01:08 +08:00

121 lines
3.7 KiB
TypeScript

import { vi, describe, beforeEach, it, expect, afterEach } from 'vitest'
import {
createLLMService,
createModelManager,
createTemplateManager,
createHistoryManager,
PromptService,
OptimizationRequest,
OptimizationError,
TestError,
IStorageProvider,
MemoryStorageProvider,
} from '../../../src'
import { TextModelConfig } from '../../../src/services/model/types'
import { TextAdapterRegistry } from '../../../src/services/llm/adapters/registry'
import { createTemplateLanguageService } from '../../../src/services/template/languageService'
describe('PromptService', () => {
let storageProvider: IStorageProvider;
let promptService: PromptService;
let modelManager: any;
let llmService: any;
let templateManager: any;
let historyManager: any;
let languageService: any;
let registry: TextAdapterRegistry;
beforeEach(async () => {
storageProvider = new MemoryStorageProvider();
// 清理存储状态
await storageProvider.clearAll();
// Create all required services
registry = new TextAdapterRegistry();
languageService = createTemplateLanguageService(storageProvider);
templateManager = createTemplateManager(storageProvider, languageService);
historyManager = createHistoryManager(storageProvider);
modelManager = createModelManager(storageProvider);
llmService = createLLMService(modelManager);
// Create TextModelConfig
const adapter = registry.getAdapter('openai');
const mockModelConfig: TextModelConfig = {
id: 'test-model',
name: 'test-model',
enabled: true,
providerMeta: adapter.getProvider(),
modelMeta: adapter.buildDefaultModel('test-model'),
connectionConfig: {
apiKey: 'test-key',
baseURL: 'https://test.api'
},
paramOverrides: {}
};
// Initialize services
await modelManager.addModel('test-model', mockModelConfig);
// Create PromptService directly
promptService = new PromptService(modelManager, llmService, templateManager, historyManager);
});
afterEach(() => {
vi.restoreAllMocks();
});
describe('optimizePrompt', () => {
it('应该成功优化提示词', async () => {
vi.spyOn(llmService, 'sendMessage').mockResolvedValue('优化后的提示词');
const request: OptimizationRequest = {
optimizationMode: 'system',
targetPrompt: 'test prompt',
modelKey: 'test-model',
};
const result = await promptService.optimizePrompt(request);
expect(result).toBe('优化后的提示词');
expect(llmService.sendMessage).toHaveBeenCalled();
});
it('当模型不存在时应抛出错误', async () => {
const request: OptimizationRequest = {
optimizationMode: 'system',
targetPrompt: 'test prompt',
modelKey: 'non-existent-model',
};
await expect(promptService.optimizePrompt(request)).rejects.toThrow(OptimizationError);
});
});
describe('testPrompt', () => {
it('应该成功测试提示词', async () => {
vi.spyOn(llmService, 'sendMessage').mockResolvedValue('测试结果');
const result = await promptService.testPrompt(
'system prompt',
'user prompt',
'test-model',
);
expect(result).toBe('测试结果');
});
it('当模型不存在时应抛出错误', async () => {
await expect(
promptService.testPrompt(
'system prompt',
'user prompt',
'non-existent-model',
),
).rejects.toThrow(TestError);
});
});
describe('getHistory', () => {
it('应该返回历史记录', async () => {
const history = await promptService.getHistory();
expect(Array.isArray(history)).toBe(true);
});
});
});