{"repo": "bzcasper/dev-projects", "files": {"prompt-optimizer/packages/core/tests/integration/llm/openai.test.js": {"0b4c8ef1f163270c9981bfb72e2fea72a7b74e59": {"t": 1785746673.0333135, "n": 14973, "h": "6f0969ebb344fcec", "c": "import { createLLMService, ModelManager, LocalStorageProvider } from '../../../src/index.js';\nimport { expect, describe, it, beforeEach, beforeAll } from 'vitest';\nimport dotenv from 'dotenv';\nimport path from 'path';\n\n// 加载环境变量\nbeforeAll(() => {\n dotenv.config({ path: path.resolve(process.cwd(), '.env.local') });\n});\n\ndescribe('OpenAI API 真实连接测试', () => {\n // 检查OpenAI兼容的环境变量(任何一个存在就可以运行测试)\n const openaiCompatibleKeys = [\n 'OPENAI_API_KEY', 'VITE_OPENAI_API_KEY',\n 'DEEPSEEK_API_KEY', 'VITE_DEEPSEEK_API_KEY', \n 'SILICONFLOW_API_KEY', 'VITE_SILICONFLOW_API_KEY',\n 'ZHIPU_API_KEY', 'VITE_ZHIPU_API_KEY',\n 'CUSTOM_API_KEY', 'VITE_CUSTOM_API_KEY'\n ];\n\n const availableKeys = openaiCompatibleKeys.filter(key => \n process.env[key] && process.env[key].trim()\n );\n\n if (availableKeys.length === 0) {\n console.log('跳过 OpenAI 真实API测试:未设置任何 OpenAI 兼容的 API 密钥');\n it.skip('应该能正确调用 OpenAI 兼容的 API', () => {});\n it.skip('应该能正确处理多轮对话', () => {});\n it.skip('应该能正确使用高级参数', () => {});\n return;\n }\n\n // 选择第一个可用的密钥和对应的配置\n const getModelConfig = () => {\n if (process.env.SILICONFLOW_API_KEY || process.env.VITE_SILICONFLOW_API_KEY) {\n return {\n key: 'siliconflow',\n apiKey: process.env.SILICONFLOW_API_KEY || process.env.VITE_SILICONFLOW_API_KEY,\n baseURL: 'https://api.siliconflow.cn/v1',\n defaultModel: 'Qwen/Qwen3-8B'\n };\n }\n if (process.env.OPENAI_API_KEY || process.env.VITE_OPENAI_API_KEY) {\n return {\n key: 'openai',\n apiKey: process.env.OPENAI_API_KEY || process.env.VITE_OPENAI_API_KEY,\n baseURL: 'https://api.openai.com/v1',\n defaultModel: 'gpt-3.5-turbo'\n };\n }\n if (process.env.DEEPSEEK_API_KEY || process.env.VITE_DEEPSEEK_API_KEY) {\n return {\n key: 'deepseek',\n apiKey: process.env.DEEPSEEK_API_KEY || process.env.VITE_DEEPSEEK_API_KEY,\n baseURL: 'https://api.deepseek.com/v1',\n defaultModel: 'deepseek-chat'\n };\n }\n if (process.env.ZHIPU_API_KEY || process.env.VITE_ZHIPU_API_KEY) {\n return {\n key: 'zhipu',\n apiKey: process.env.ZHIPU_API_KEY || process.env.VITE_ZHIPU_API_KEY,\n baseURL: 'https://open.bigmodel.cn/api/paas/v4',\n defaultModel: 'glm-4-flash'\n };\n }\n if (process.env.CUSTOM_API_KEY || process.env.VITE_CUSTOM_API_KEY) {\n const baseURL = process.env.CUSTOM_API_BASE_URL || process.env.VITE_CUSTOM_API_BASE_URL;\n const model = process.env.CUSTOM_API_MODEL || process.env.VITE_CUSTOM_API_MODEL;\n \n // 只有当baseURL和model都有值时才返回custom配置\n if (baseURL && model) {\n return {\n key: 'custom',\n apiKey: process.env.CUSTOM_API_KEY || process.env.VITE_CUSTOM_API_KEY,\n baseURL: baseURL,\n defaultModel: model\n };\n }\n }\n return null;\n };\n\n const modelConfig = getModelConfig();\n \n if (!modelConfig) {\n console.log('跳过 OpenAI 真实API测试:无有效的模型配置');\n it.skip('应该能正确调用 OpenAI 兼容的 API', () => {});\n it.skip('应该能正确处理多轮对话', () => {});\n it.skip('应该能正确使用高级参数', () => {});\n return;\n }\n\n console.log(`使用 ${modelConfig.key} 进行 OpenAI 兼容 API 测试,模型: ${modelConfig.defaultModel}`);\n\n it('应该能正确调用 OpenAI 兼容的 API', async () => {\n const storage = new LocalStorageProvider();\n const modelManager = new ModelManager(storage);\n const llmService = createLLMService(modelManager);\n\n try {\n // 更新模型配置\n await modelManager.updateModel(modelConfig.key, {\n apiKey: modelConfig.apiKey,\n baseURL: modelConfig.baseURL,\n defaultModel: modelConfig.defaultModel,\n enabled: true,\n provider: 'openai' // 所有兼容提供商都使用openai提供商类型\n });\n\n const messages = [\n { role: 'user', content: '你好,请用一句话介绍你自己' }\n ];\n\n const response = await llmService.sendMessage(messages, modelConfig.key);\n expect(response).toBeDefined();\n expect(typeof response).toBe('string');\n expect(response.length).toBeGreaterThan(0);\n } catch (error) {\n console.error(`API调用失败 (${modelConfig.key}):`, error.message);\n // 如果是400错误,可能是配置问题,跳过测试\n if (error.message.includes('400')) {\n console.log(`跳过测试:${modelConfig.key} API配置可能有问题`);\n return;\n }\n throw error;\n }\n }, 300000);\n\n it('应该能正确处理多轮对话', async () => {\n const storage = new LocalStorageProvider();\n const modelManager = new ModelManager(storage);\n const llmService = createLLMService(modelManager);\n\n try {\n // 更新模型配置\n await modelManager.updateModel(modelConfig.key, {\n apiKey: modelConfig.apiKey,\n baseURL: modelConfig.baseURL,\n defaultModel: modelConfig.defaultModel,\n enabled: true,\n provider: 'openai'\n });\n\n const messages = [\n { role: 'user', content: '你好,我们来玩个游戏' },\n { role: 'assistant', content: '好啊,你想玩什么游戏?' },\n { role: 'user', content: '我们来玩猜数字游戏,1到100之间' }\n ];\n\n const response = await llmService.sendMessage(messages, modelConfig.key);\n expect(response).toBeDefined();\n expect(typeof response).toBe('string');\n expect(response.length).toBeGreaterThan(0);\n } catch (error) {\n console.error(`多轮对话测试失败 (${modelConfig.key}):`, error.message);\n if (error.message.includes('400')) {\n console.log(`跳过测试:${modelConfig.key} API配置可能有问题`);\n return;\n }\n throw error;\n }\n }, 300000);\n\n it('应该能正确使用高级参数', async () => {\n const storage = new LocalStorageProvider();\n const modelManager = new ModelManager(storage);\n const llmService = createLLMService(modelManager);\n\n try {\n // 更新模型配置,包含高级参数\n await modelManager.updateModel(modelConfig.key, {\n apiKey: modelConfig.apiKey,\n baseURL: modelConfig.baseURL,\n defaultModel: modelConfig.defaultModel,\n enabled: true,\n provider: 'openai',\n llmParams: {\n temperature: 0.3,\n max_tokens: 100\n }\n });\n\n const messages = [\n { role: 'user', content: '请用一句话回答:什么是人工智能?' }\n ];\n\n const response = await llmService.sendMessage(messages, modelConfig.key);\n expect(response).toBeDefined();\n expect(typeof response).toBe('string');\n expect(response.length).toBeGreaterThan(0);\n // 由于设置了max_tokens=100,响应应该相对较短\n expect(response.length).toBeLessThan(200);\n } catch (error) {\n console.error(`高级参数测试失败 (${modelConfig.key}):`, error.message);\n if (error.message.includes('400')) {\n console.log(`跳过测试:${modelConfig.key} API配置可能有问题`);\n return;\n }\n throw error;\n }\n }, 300000);\n\n it('应该能兼容处理所有模型的响应格式(reasoning_content + think标签 + 普通文本)', async () => {\n const storage = new LocalStorageProvider();\n const modelManager = new ModelManager(storage);\n const llmService = createLLMService(modelManager);\n\n try {\n // 测试通用兼容性处理\n await modelManager.updateModel(modelConfig.key, {\n apiKey: modelConfig.apiKey,\n baseURL: modelConfig.baseURL,\n defaultModel: modelConfig.defaultModel,\n enabled: true,\n provider: 'openai',\n llmParams: {\n temperature: 0.1,\n max_tokens: 100\n }\n });\n\n const testMessages = [\n {\n role: 'user',\n content: '请简单回答:什么是AI?'\n }\n ];\n\n // 测试非流式处理\n const result = await llmService.sendMessage(testMessages, modelConfig.key);\n \n expect(result).toBeTruthy();\n expect(typeof result).toBe('string');\n expect(result.length).toBeGreaterThan(0);\n \n console.log('兼容性测试结果:', {\n hasThinkTags: result.includes(''),\n hasContent: result.length > 0,\n result: result\n });\n\n // 测试流式处理\n let streamResult = '';\n let tokenCount = 0;\n let isCompleted = false;\n let hasError = false;\n\n await llmService.sendMessageStream(testMessages, modelConfig.key, {\n onToken: (token) => {\n streamResult += token;\n tokenCount++;\n },\n onComplete: (response) => {\n isCompleted = true;\n },\n onError: (error) => {\n hasError = true;\n console.error('流式测试错误:', error);\n }\n });\n\n expect(hasError).toBe(false);\n expect(isCompleted).toBe(true);\n expect(streamResult.length).toBeGreaterThan(0);\n expect(tokenCount).toBeGreaterThan(0);\n\n console.log('流式兼容性测试结果:', {\n tokenCount,\n hasThinkTags: streamResult.includes(''),\n streamLength: streamResult.length,\n isCompleted\n });\n\n } catch (error) {\n console.error('兼容性测试失败:', error);\n throw error;\n }\n },300000);\n\n it('应该能正确处理reasoning_content的流式输出', async () => {\n const storage = new LocalStorageProvider();\n const modelManager = new ModelManager(storage);\n const llmService = createLLMService(modelManager);\n\n try {\n // 配置模型\n await modelManager.updateModel(modelConfig.key, {\n apiKey: modelConfig.apiKey,\n baseURL: modelConfig.baseURL,\n defaultModel: modelConfig.defaultModel,\n enabled: true,\n provider: 'openai',\n llmParams: {\n temperature: 0.1,\n max_tokens: 2000\n }\n });\n\n const testMessages = [\n {\n role: 'user',\n content: '你是谁'\n }\n ];\n\n // 模拟包含reasoning_content的流式响应\n let fullResult = '';\n let tokenCount = 0;\n let hasThinkTags = false;\n let thinkTagsClosed = false;\n let isCompleted = false;\n let hasError = false;\n\n await llmService.sendMessageStream(testMessages, modelConfig.key, {\n onToken: (token) => {\n fullResult += token;\n tokenCount++;\n \n // 检查think标签的完整性\n if (token.includes('')) {\n hasThinkTags = true;\n }\n if (token.includes('')) {\n thinkTagsClosed = true;\n }\n },\n onComplete: (response) => {\n isCompleted = true;\n },\n onError: (error) => {\n hasError = true;\n console.error('流式测试错误:', error);\n }\n });\n\n // 等待流式完成\n await new Promise(resolve => setTimeout(resolve, 1000));\n\n console.log('reasoning_content流式测试结果:', {\n tokenCount,\n hasThinkTags,\n thinkTagsClosed,\n isCompleted,\n hasError,\n resultLength: fullResult.length,\n fullResult: fullResult\n });\n\n expect(isCompleted).toBe(true);\n expect(hasError).toBe(false);\n expect(tokenCount).toBeGreaterThan(0);\n expect(fullResult.length).toBeGreaterThan(0);\n \n // 如果有think标签,检查它们是否正确闭合\n const thinkOpenCount = (fullResult.match(//g) || []).length;\n const thinkCloseCount = (fullResult.match(/<\\/think>/g) || []).length;\n \n if (thinkOpenCount > 0) {\n expect(thinkOpenCount).toBe(thinkCloseCount);\n console.log(`✅ Think标签匹配: ${thinkOpenCount} 个开始标签, ${thinkCloseCount} 个结束标签`);\n }\n\n } catch (error) {\n console.error('reasoning_content流式测试失败:', error);\n throw error;\n }\n },300000);\n\n it('应该能使用结构化API发送消息', async () => {\n const storage = new LocalStorageProvider();\n const modelManager = new ModelManager(storage);\n const llmService = createLLMService(modelManager);\n\n try {\n // 配置模型\n await modelManager.updateModel(modelConfig.key, {\n apiKey: modelConfig.apiKey,\n baseURL: modelConfig.baseURL,\n defaultModel: modelConfig.defaultModel,\n enabled: true,\n provider: 'openai',\n llmParams: {\n temperature: 0.3,\n max_tokens: 100\n }\n });\n\n const testMessages = [\n {\n role: 'user',\n content: '请简单回答:什么是AI?'\n }\n ];\n\n // 测试结构化API\n const response = await llmService.sendMessageStructured(testMessages, modelConfig.key);\n \n expect(response).toBeDefined();\n expect(typeof response).toBe('object');\n expect(response.content).toBeDefined();\n expect(typeof response.content).toBe('string');\n expect(response.content.length).toBeGreaterThan(0);\n \n // 检查元数据\n expect(response.metadata).toBeDefined();\n expect(response.metadata.model).toBe(modelConfig.defaultModel);\n \n console.log('结构化API测试结果:', {\n hasContent: response.content.length > 0,\n hasReasoning: !!response.reasoning,\n content: response.content,\n reasoning: response.reasoning,\n model: response.metadata?.model\n });\n\n } catch (error) {\n console.error('结构化API测试失败:', error);\n throw error;\n }\n }, 300000);\n\n it('应该能使用结构化回调进行流式处理', async () => {\n const storage = new LocalStorageProvider();\n const modelManager = new ModelManager(storage);\n const llmService = createLLMService(modelManager);\n\n try {\n // 配置模型\n await modelManager.updateModel(modelConfig.key, {\n apiKey: modelConfig.apiKey,\n baseURL: modelConfig.baseURL,\n defaultModel: modelConfig.defaultModel,\n enabled: true,\n provider: 'openai',\n llmParams: {\n temperature: 0.1,\n max_tokens: 1500\n }\n });\n\n const testMessages = [\n {\n role: 'user',\n content: '请简单回答:什么是AI?'\n }\n ];\n\n let contentTokens = '';\n let reasoningTokens = '';\n let finalResponse = null;\n let contentTokenCount = 0;\n let reasoningTokenCount = 0;\n let isCompleted = false;\n let hasError = false;\n\n await llmService.sendMessageStream(testMessages, modelConfig.key, {\n onToken: (token) => {\n contentTokens += token;\n contentTokenCount++;\n },\n onReasoningToken: (token) => {\n reasoningTokens += token;\n reasoningTokenCount++;\n },\n onComplete: (response) => {\n finalResponse = response;\n isCompleted = true;\n },\n onError: (error) => {\n hasError = true;\n console.error('结构化流式测试错误:', error);\n }\n });\n\n // 等待流式完成\n await new Promise(resolve => setTimeout(resolve, 1000));\n\n console.log('结构化流式测试结果:', {\n contentTokenCount,\n reasoningTokenCount,\n isCompleted,\n hasError,\n content: contentTokens,\n reasoning: reasoningTokens,\n finalResponse: finalResponse\n });\n\n expect(isCompleted).toBe(true);\n expect(hasError).toBe(false);\n expect(finalResponse).toBeDefined();\n expect(finalResponse.content).toBeDefined();\n expect(contentTokenCount).toBeGreaterThan(0);\n expect(contentTokens.length).toBeGreaterThan(0);\n \n // 验证内容一致性\n expect(contentTokens).toBe(finalResponse.content);\n \n // 如果有推理内容,验证一致性\n if (reasoningTokenCount > 0) {\n expect(reasoningTokens).toBe(finalResponse.reasoning || '');\n }\n\n } catch (error) {\n console.error('结构化流式测试失败:', error);\n throw error;\n }\n }, 300000);\n}); "}, "efe8e75ac7c39bb3679157d41d7949388eefe5ee": {"t": 1785766739.266065, "n": 14973, "h": "6f0969ebb344fcec", "c": "import { createLLMService, ModelManager, LocalStorageProvider } from '../../../src/index.js';\nimport { expect, describe, it, beforeEach, beforeAll } from 'vitest';\nimport dotenv from 'dotenv';\nimport path from 'path';\n\n// 加载环境变量\nbeforeAll(() => {\n dotenv.config({ path: path.resolve(process.cwd(), '.env.local') });\n});\n\ndescribe('OpenAI API 真实连接测试', () => {\n // 检查OpenAI兼容的环境变量(任何一个存在就可以运行测试)\n const openaiCompatibleKeys = [\n 'OPENAI_API_KEY', 'VITE_OPENAI_API_KEY',\n 'DEEPSEEK_API_KEY', 'VITE_DEEPSEEK_API_KEY', \n 'SILICONFLOW_API_KEY', 'VITE_SILICONFLOW_API_KEY',\n 'ZHIPU_API_KEY', 'VITE_ZHIPU_API_KEY',\n 'CUSTOM_API_KEY', 'VITE_CUSTOM_API_KEY'\n ];\n\n const availableKeys = openaiCompatibleKeys.filter(key => \n process.env[key] && process.env[key].trim()\n );\n\n if (availableKeys.length === 0) {\n console.log('跳过 OpenAI 真实API测试:未设置任何 OpenAI 兼容的 API 密钥');\n it.skip('应该能正确调用 OpenAI 兼容的 API', () => {});\n it.skip('应该能正确处理多轮对话', () => {});\n it.skip('应该能正确使用高级参数', () => {});\n return;\n }\n\n // 选择第一个可用的密钥和对应的配置\n const getModelConfig = () => {\n if (process.env.SILICONFLOW_API_KEY || process.env.VITE_SILICONFLOW_API_KEY) {\n return {\n key: 'siliconflow',\n apiKey: process.env.SILICONFLOW_API_KEY || process.env.VITE_SILICONFLOW_API_KEY,\n baseURL: 'https://api.siliconflow.cn/v1',\n defaultModel: 'Qwen/Qwen3-8B'\n };\n }\n if (process.env.OPENAI_API_KEY || process.env.VITE_OPENAI_API_KEY) {\n return {\n key: 'openai',\n apiKey: process.env.OPENAI_API_KEY || process.env.VITE_OPENAI_API_KEY,\n baseURL: 'https://api.openai.com/v1',\n defaultModel: 'gpt-3.5-turbo'\n };\n }\n if (process.env.DEEPSEEK_API_KEY || process.env.VITE_DEEPSEEK_API_KEY) {\n return {\n key: 'deepseek',\n apiKey: process.env.DEEPSEEK_API_KEY || process.env.VITE_DEEPSEEK_API_KEY,\n baseURL: 'https://api.deepseek.com/v1',\n defaultModel: 'deepseek-chat'\n };\n }\n if (process.env.ZHIPU_API_KEY || process.env.VITE_ZHIPU_API_KEY) {\n return {\n key: 'zhipu',\n apiKey: process.env.ZHIPU_API_KEY || process.env.VITE_ZHIPU_API_KEY,\n baseURL: 'https://open.bigmodel.cn/api/paas/v4',\n defaultModel: 'glm-4-flash'\n };\n }\n if (process.env.CUSTOM_API_KEY || process.env.VITE_CUSTOM_API_KEY) {\n const baseURL = process.env.CUSTOM_API_BASE_URL || process.env.VITE_CUSTOM_API_BASE_URL;\n const model = process.env.CUSTOM_API_MODEL || process.env.VITE_CUSTOM_API_MODEL;\n \n // 只有当baseURL和model都有值时才返回custom配置\n if (baseURL && model) {\n return {\n key: 'custom',\n apiKey: process.env.CUSTOM_API_KEY || process.env.VITE_CUSTOM_API_KEY,\n baseURL: baseURL,\n defaultModel: model\n };\n }\n }\n return null;\n };\n\n const modelConfig = getModelConfig();\n \n if (!modelConfig) {\n console.log('跳过 OpenAI 真实API测试:无有效的模型配置');\n it.skip('应该能正确调用 OpenAI 兼容的 API', () => {});\n it.skip('应该能正确处理多轮对话', () => {});\n it.skip('应该能正确使用高级参数', () => {});\n return;\n }\n\n console.log(`使用 ${modelConfig.key} 进行 OpenAI 兼容 API 测试,模型: ${modelConfig.defaultModel}`);\n\n it('应该能正确调用 OpenAI 兼容的 API', async () => {\n const storage = new LocalStorageProvider();\n const modelManager = new ModelManager(storage);\n const llmService = createLLMService(modelManager);\n\n try {\n // 更新模型配置\n await modelManager.updateModel(modelConfig.key, {\n apiKey: modelConfig.apiKey,\n baseURL: modelConfig.baseURL,\n defaultModel: modelConfig.defaultModel,\n enabled: true,\n provider: 'openai' // 所有兼容提供商都使用openai提供商类型\n });\n\n const messages = [\n { role: 'user', content: '你好,请用一句话介绍你自己' }\n ];\n\n const response = await llmService.sendMessage(messages, modelConfig.key);\n expect(response).toBeDefined();\n expect(typeof response).toBe('string');\n expect(response.length).toBeGreaterThan(0);\n } catch (error) {\n console.error(`API调用失败 (${modelConfig.key}):`, error.message);\n // 如果是400错误,可能是配置问题,跳过测试\n if (error.message.includes('400')) {\n console.log(`跳过测试:${modelConfig.key} API配置可能有问题`);\n return;\n }\n throw error;\n }\n }, 300000);\n\n it('应该能正确处理多轮对话', async () => {\n const storage = new LocalStorageProvider();\n const modelManager = new ModelManager(storage);\n const llmService = createLLMService(modelManager);\n\n try {\n // 更新模型配置\n await modelManager.updateModel(modelConfig.key, {\n apiKey: modelConfig.apiKey,\n baseURL: modelConfig.baseURL,\n defaultModel: modelConfig.defaultModel,\n enabled: true,\n provider: 'openai'\n });\n\n const messages = [\n { role: 'user', content: '你好,我们来玩个游戏' },\n { role: 'assistant', content: '好啊,你想玩什么游戏?' },\n { role: 'user', content: '我们来玩猜数字游戏,1到100之间' }\n ];\n\n const response = await llmService.sendMessage(messages, modelConfig.key);\n expect(response).toBeDefined();\n expect(typeof response).toBe('string');\n expect(response.length).toBeGreaterThan(0);\n } catch (error) {\n console.error(`多轮对话测试失败 (${modelConfig.key}):`, error.message);\n if (error.message.includes('400')) {\n console.log(`跳过测试:${modelConfig.key} API配置可能有问题`);\n return;\n }\n throw error;\n }\n }, 300000);\n\n it('应该能正确使用高级参数', async () => {\n const storage = new LocalStorageProvider();\n const modelManager = new ModelManager(storage);\n const llmService = createLLMService(modelManager);\n\n try {\n // 更新模型配置,包含高级参数\n await modelManager.updateModel(modelConfig.key, {\n apiKey: modelConfig.apiKey,\n baseURL: modelConfig.baseURL,\n defaultModel: modelConfig.defaultModel,\n enabled: true,\n provider: 'openai',\n llmParams: {\n temperature: 0.3,\n max_tokens: 100\n }\n });\n\n const messages = [\n { role: 'user', content: '请用一句话回答:什么是人工智能?' }\n ];\n\n const response = await llmService.sendMessage(messages, modelConfig.key);\n expect(response).toBeDefined();\n expect(typeof response).toBe('string');\n expect(response.length).toBeGreaterThan(0);\n // 由于设置了max_tokens=100,响应应该相对较短\n expect(response.length).toBeLessThan(200);\n } catch (error) {\n console.error(`高级参数测试失败 (${modelConfig.key}):`, error.message);\n if (error.message.includes('400')) {\n console.log(`跳过测试:${modelConfig.key} API配置可能有问题`);\n return;\n }\n throw error;\n }\n }, 300000);\n\n it('应该能兼容处理所有模型的响应格式(reasoning_content + think标签 + 普通文本)', async () => {\n const storage = new LocalStorageProvider();\n const modelManager = new ModelManager(storage);\n const llmService = createLLMService(modelManager);\n\n try {\n // 测试通用兼容性处理\n await modelManager.updateModel(modelConfig.key, {\n apiKey: modelConfig.apiKey,\n baseURL: modelConfig.baseURL,\n defaultModel: modelConfig.defaultModel,\n enabled: true,\n provider: 'openai',\n llmParams: {\n temperature: 0.1,\n max_tokens: 100\n }\n });\n\n const testMessages = [\n {\n role: 'user',\n content: '请简单回答:什么是AI?'\n }\n ];\n\n // 测试非流式处理\n const result = await llmService.sendMessage(testMessages, modelConfig.key);\n \n expect(result).toBeTruthy();\n expect(typeof result).toBe('string');\n expect(result.length).toBeGreaterThan(0);\n \n console.log('兼容性测试结果:', {\n hasThinkTags: result.includes(''),\n hasContent: result.length > 0,\n result: result\n });\n\n // 测试流式处理\n let streamResult = '';\n let tokenCount = 0;\n let isCompleted = false;\n let hasError = false;\n\n await llmService.sendMessageStream(testMessages, modelConfig.key, {\n onToken: (token) => {\n streamResult += token;\n tokenCount++;\n },\n onComplete: (response) => {\n isCompleted = true;\n },\n onError: (error) => {\n hasError = true;\n console.error('流式测试错误:', error);\n }\n });\n\n expect(hasError).toBe(false);\n expect(isCompleted).toBe(true);\n expect(streamResult.length).toBeGreaterThan(0);\n expect(tokenCount).toBeGreaterThan(0);\n\n console.log('流式兼容性测试结果:', {\n tokenCount,\n hasThinkTags: streamResult.includes(''),\n streamLength: streamResult.length,\n isCompleted\n });\n\n } catch (error) {\n console.error('兼容性测试失败:', error);\n throw error;\n }\n },300000);\n\n it('应该能正确处理reasoning_content的流式输出', async () => {\n const storage = new LocalStorageProvider();\n const modelManager = new ModelManager(storage);\n const llmService = createLLMService(modelManager);\n\n try {\n // 配置模型\n await modelManager.updateModel(modelConfig.key, {\n apiKey: modelConfig.apiKey,\n baseURL: modelConfig.baseURL,\n defaultModel: modelConfig.defaultModel,\n enabled: true,\n provider: 'openai',\n llmParams: {\n temperature: 0.1,\n max_tokens: 2000\n }\n });\n\n const testMessages = [\n {\n role: 'user',\n content: '你是谁'\n }\n ];\n\n // 模拟包含reasoning_content的流式响应\n let fullResult = '';\n let tokenCount = 0;\n let hasThinkTags = false;\n let thinkTagsClosed = false;\n let isCompleted = false;\n let hasError = false;\n\n await llmService.sendMessageStream(testMessages, modelConfig.key, {\n onToken: (token) => {\n fullResult += token;\n tokenCount++;\n \n // 检查think标签的完整性\n if (token.includes('')) {\n hasThinkTags = true;\n }\n if (token.includes('')) {\n thinkTagsClosed = true;\n }\n },\n onComplete: (response) => {\n isCompleted = true;\n },\n onError: (error) => {\n hasError = true;\n console.error('流式测试错误:', error);\n }\n });\n\n // 等待流式完成\n await new Promise(resolve => setTimeout(resolve, 1000));\n\n console.log('reasoning_content流式测试结果:', {\n tokenCount,\n hasThinkTags,\n thinkTagsClosed,\n isCompleted,\n hasError,\n resultLength: fullResult.length,\n fullResult: fullResult\n });\n\n expect(isCompleted).toBe(true);\n expect(hasError).toBe(false);\n expect(tokenCount).toBeGreaterThan(0);\n expect(fullResult.length).toBeGreaterThan(0);\n \n // 如果有think标签,检查它们是否正确闭合\n const thinkOpenCount = (fullResult.match(//g) || []).length;\n const thinkCloseCount = (fullResult.match(/<\\/think>/g) || []).length;\n \n if (thinkOpenCount > 0) {\n expect(thinkOpenCount).toBe(thinkCloseCount);\n console.log(`✅ Think标签匹配: ${thinkOpenCount} 个开始标签, ${thinkCloseCount} 个结束标签`);\n }\n\n } catch (error) {\n console.error('reasoning_content流式测试失败:', error);\n throw error;\n }\n },300000);\n\n it('应该能使用结构化API发送消息', async () => {\n const storage = new LocalStorageProvider();\n const modelManager = new ModelManager(storage);\n const llmService = createLLMService(modelManager);\n\n try {\n // 配置模型\n await modelManager.updateModel(modelConfig.key, {\n apiKey: modelConfig.apiKey,\n baseURL: modelConfig.baseURL,\n defaultModel: modelConfig.defaultModel,\n enabled: true,\n provider: 'openai',\n llmParams: {\n temperature: 0.3,\n max_tokens: 100\n }\n });\n\n const testMessages = [\n {\n role: 'user',\n content: '请简单回答:什么是AI?'\n }\n ];\n\n // 测试结构化API\n const response = await llmService.sendMessageStructured(testMessages, modelConfig.key);\n \n expect(response).toBeDefined();\n expect(typeof response).toBe('object');\n expect(response.content).toBeDefined();\n expect(typeof response.content).toBe('string');\n expect(response.content.length).toBeGreaterThan(0);\n \n // 检查元数据\n expect(response.metadata).toBeDefined();\n expect(response.metadata.model).toBe(modelConfig.defaultModel);\n \n console.log('结构化API测试结果:', {\n hasContent: response.content.length > 0,\n hasReasoning: !!response.reasoning,\n content: response.content,\n reasoning: response.reasoning,\n model: response.metadata?.model\n });\n\n } catch (error) {\n console.error('结构化API测试失败:', error);\n throw error;\n }\n }, 300000);\n\n it('应该能使用结构化回调进行流式处理', async () => {\n const storage = new LocalStorageProvider();\n const modelManager = new ModelManager(storage);\n const llmService = createLLMService(modelManager);\n\n try {\n // 配置模型\n await modelManager.updateModel(modelConfig.key, {\n apiKey: modelConfig.apiKey,\n baseURL: modelConfig.baseURL,\n defaultModel: modelConfig.defaultModel,\n enabled: true,\n provider: 'openai',\n llmParams: {\n temperature: 0.1,\n max_tokens: 1500\n }\n });\n\n const testMessages = [\n {\n role: 'user',\n content: '请简单回答:什么是AI?'\n }\n ];\n\n let contentTokens = '';\n let reasoningTokens = '';\n let finalResponse = null;\n let contentTokenCount = 0;\n let reasoningTokenCount = 0;\n let isCompleted = false;\n let hasError = false;\n\n await llmService.sendMessageStream(testMessages, modelConfig.key, {\n onToken: (token) => {\n contentTokens += token;\n contentTokenCount++;\n },\n onReasoningToken: (token) => {\n reasoningTokens += token;\n reasoningTokenCount++;\n },\n onComplete: (response) => {\n finalResponse = response;\n isCompleted = true;\n },\n onError: (error) => {\n hasError = true;\n console.error('结构化流式测试错误:', error);\n }\n });\n\n // 等待流式完成\n await new Promise(resolve => setTimeout(resolve, 1000));\n\n console.log('结构化流式测试结果:', {\n contentTokenCount,\n reasoningTokenCount,\n isCompleted,\n hasError,\n content: contentTokens,\n reasoning: reasoningTokens,\n finalResponse: finalResponse\n });\n\n expect(isCompleted).toBe(true);\n expect(hasError).toBe(false);\n expect(finalResponse).toBeDefined();\n expect(finalResponse.content).toBeDefined();\n expect(contentTokenCount).toBeGreaterThan(0);\n expect(contentTokens.length).toBeGreaterThan(0);\n \n // 验证内容一致性\n expect(contentTokens).toBe(finalResponse.content);\n \n // 如果有推理内容,验证一致性\n if (reasoningTokenCount > 0) {\n expect(reasoningTokens).toBe(finalResponse.reasoning || '');\n }\n\n } catch (error) {\n console.error('结构化流式测试失败:', error);\n throw error;\n }\n }, 300000);\n}); "}}}}