UNPKG

@lobehub/chat

Version:

Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.

251 lines (210 loc) • 7.79 kB
// @vitest-environment node import { ModelProvider } from 'model-bank'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import { testProvider } from '../../providerTestUtils'; import { LobeModelScopeAI, ModelScopeModelCard, params } from './index'; const provider = ModelProvider.ModelScope; const defaultBaseURL = 'https://api-inference.modelscope.cn/v1'; // Basic provider tests testProvider({ Runtime: LobeModelScopeAI, provider, defaultBaseURL, chatDebugEnv: 'DEBUG_MODELSCOPE_CHAT_COMPLETION', chatModel: 'qwen2-7b-instruct', test: { skipAPICall: true, }, }); // Custom feature tests describe('LobeModelScopeAI - custom features', () => { describe('params export', () => { it('should export params object', () => { expect(params).toBeDefined(); expect(params.baseURL).toBe(defaultBaseURL); expect(params.provider).toBe(provider); expect(params.debug).toBeDefined(); expect(params.models).toBeDefined(); }); }); describe('debug configuration', () => { it('should disable debug mode by default', () => { delete process.env.DEBUG_MODELSCOPE_CHAT_COMPLETION; const result = params.debug.chatCompletion(); expect(result).toBe(false); }); it('should enable debug mode when env is set to 1', () => { process.env.DEBUG_MODELSCOPE_CHAT_COMPLETION = '1'; const result = params.debug.chatCompletion(); expect(result).toBe(true); }); it('should disable debug mode when env is not 1', () => { process.env.DEBUG_MODELSCOPE_CHAT_COMPLETION = '0'; const result = params.debug.chatCompletion(); expect(result).toBe(false); }); }); describe('models function', () => { let mockClient: any; let consoleWarnSpy: any; beforeEach(() => { mockClient = { models: { list: vi.fn(), }, }; consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}); }); it('should fetch and process models successfully', async () => { const mockModelData: ModelScopeModelCard[] = [ { id: 'qwen2-7b-instruct', object: 'model', created: 1234567890, owned_by: 'qwen', }, { id: 'qwen2.5-72b-instruct', object: 'model', created: 1234567891, owned_by: 'qwen', }, ]; mockClient.models.list.mockResolvedValue({ data: mockModelData, }); const models = await params.models({ client: mockClient }); expect(mockClient.models.list).toHaveBeenCalledTimes(1); expect(models).toBeDefined(); expect(Array.isArray(models)).toBe(true); expect(consoleWarnSpy).not.toHaveBeenCalled(); }); it('should handle empty model list', async () => { mockClient.models.list.mockResolvedValue({ data: [], }); const models = await params.models({ client: mockClient }); expect(mockClient.models.list).toHaveBeenCalledTimes(1); expect(models).toBeDefined(); expect(Array.isArray(models)).toBe(true); expect(models).toHaveLength(0); expect(consoleWarnSpy).not.toHaveBeenCalled(); }); it('should handle missing data field', async () => { mockClient.models.list.mockResolvedValue({}); const models = await params.models({ client: mockClient }); expect(mockClient.models.list).toHaveBeenCalledTimes(1); expect(models).toBeDefined(); expect(Array.isArray(models)).toBe(true); expect(models).toHaveLength(0); expect(consoleWarnSpy).not.toHaveBeenCalled(); }); it('should handle API errors gracefully', async () => { const mockError = new Error('API Error'); mockClient.models.list.mockRejectedValue(mockError); const models = await params.models({ client: mockClient }); expect(mockClient.models.list).toHaveBeenCalledTimes(1); expect(models).toEqual([]); expect(consoleWarnSpy).toHaveBeenCalledWith( 'Failed to fetch ModelScope models. Please ensure your ModelScope API key is valid and your Alibaba Cloud account is properly bound:', mockError, ); }); it('should handle network errors', async () => { const networkError = new Error('Network timeout'); mockClient.models.list.mockRejectedValue(networkError); const models = await params.models({ client: mockClient }); expect(models).toEqual([]); expect(consoleWarnSpy).toHaveBeenCalledWith( 'Failed to fetch ModelScope models. Please ensure your ModelScope API key is valid and your Alibaba Cloud account is properly bound:', networkError, ); }); it('should handle invalid API key errors', async () => { const authError = new Error('Invalid API key'); mockClient.models.list.mockRejectedValue(authError); const models = await params.models({ client: mockClient }); expect(models).toEqual([]); expect(consoleWarnSpy).toHaveBeenCalledWith( 'Failed to fetch ModelScope models. Please ensure your ModelScope API key is valid and your Alibaba Cloud account is properly bound:', authError, ); }); it('should process models with processMultiProviderModelList', async () => { const mockModelData: ModelScopeModelCard[] = [ { id: 'qwen-plus', object: 'model', created: 1234567890, owned_by: 'qwen', }, { id: 'qwen-turbo', object: 'model', created: 1234567891, owned_by: 'qwen', }, ]; mockClient.models.list.mockResolvedValue({ data: mockModelData, }); const models = await params.models({ client: mockClient }); expect(models).toBeDefined(); expect(Array.isArray(models)).toBe(true); // processMultiProviderModelList should process the models expect(mockClient.models.list).toHaveBeenCalledTimes(1); }); it('should handle models with different owned_by values', async () => { const mockModelData: ModelScopeModelCard[] = [ { id: 'model-1', object: 'model', created: 1234567890, owned_by: 'provider-1', }, { id: 'model-2', object: 'model', created: 1234567891, owned_by: 'provider-2', }, ]; mockClient.models.list.mockResolvedValue({ data: mockModelData, }); const models = await params.models({ client: mockClient }); expect(models).toBeDefined(); expect(Array.isArray(models)).toBe(true); }); }); describe('ModelScopeModelCard interface', () => { it('should have correct structure', () => { const mockCard: ModelScopeModelCard = { id: 'test-model', object: 'model', created: 1234567890, owned_by: 'test-provider', }; expect(mockCard.id).toBe('test-model'); expect(mockCard.object).toBe('model'); expect(mockCard.created).toBe(1234567890); expect(mockCard.owned_by).toBe('test-provider'); }); }); describe('runtime instantiation', () => { it('should create runtime instance with default config', () => { const instance = new LobeModelScopeAI({ apiKey: 'test_api_key' }); expect(instance).toBeDefined(); expect(instance.baseURL).toBe(defaultBaseURL); }); it('should create runtime instance with custom baseURL', () => { const customBaseURL = 'https://custom.modelscope.cn/v1'; const instance = new LobeModelScopeAI({ apiKey: 'test_api_key', baseURL: customBaseURL, }); expect(instance).toBeDefined(); expect(instance.baseURL).toBe(customBaseURL); }); }); });