lobe-chat

Форк
0
/
parseModels.test.ts 
271 строка · 8.9 Кб
1
import { describe, expect, it } from 'vitest';
2

3
import { LOBE_DEFAULT_MODEL_LIST, OpenAIProviderCard } from '@/config/modelProviders';
4
import { ChatModelCard } from '@/types/llm';
5

6
import { parseModelString, transformToChatModelCards } from './parseModels';
7

8
describe('parseModelString', () => {
9
  it('custom deletion, addition, and renaming of models', () => {
10
    const result = parseModelString(
11
      '-all,+llama,+claude-2,-gpt-3.5-turbo,gpt-4-1106-preview=gpt-4-turbo,gpt-4-1106-preview=gpt-4-32k',
12
    );
13

14
    expect(result).toMatchSnapshot();
15
  });
16

17
  it('duplicate naming model', () => {
18
    const result = parseModelString('gpt-4-1106-preview=gpt-4-turbo,gpt-4-1106-preview=gpt-4-32k');
19
    expect(result).toMatchSnapshot();
20
  });
21

22
  it('only add the model', () => {
23
    const result = parseModelString('model1,model2,model3,model4');
24

25
    expect(result).toMatchSnapshot();
26
  });
27

28
  describe('extension capabilities', () => {
29
    it('with token', () => {
30
      const result = parseModelString('chatglm-6b=ChatGLM 6B<4096>');
31

32
      expect(result.add[0]).toEqual({
33
        displayName: 'ChatGLM 6B',
34
        id: 'chatglm-6b',
35
        tokens: 4096,
36
      });
37
    });
38

39
    it('token and function calling', () => {
40
      const result = parseModelString('spark-v3.5=讯飞星火 v3.5<8192:fc>');
41

42
      expect(result.add[0]).toEqual({
43
        displayName: '讯飞星火 v3.5',
44
        functionCall: true,
45
        id: 'spark-v3.5',
46
        tokens: 8192,
47
      });
48
    });
49

50
    it('multi models', () => {
51
      const result = parseModelString(
52
        'gemini-1.5-flash-latest=Gemini 1.5 Flash<16000:vision>,gpt-4-all=ChatGPT Plus<128000:fc:vision:file>',
53
      );
54

55
      expect(result.add).toEqual([
56
        {
57
          displayName: 'Gemini 1.5 Flash',
58
          vision: true,
59
          id: 'gemini-1.5-flash-latest',
60
          tokens: 16000,
61
        },
62
        {
63
          displayName: 'ChatGPT Plus',
64
          vision: true,
65
          functionCall: true,
66
          files: true,
67
          id: 'gpt-4-all',
68
          tokens: 128000,
69
        },
70
      ]);
71
    });
72

73
    it('should have file with builtin models like gpt-4-0125-preview', () => {
74
      const result = parseModelString(
75
        '-all,+gpt-4-0125-preview=ChatGPT-4<128000:fc:file>,+gpt-4-turbo-2024-04-09=ChatGPT-4 Vision<128000:fc:vision:file>',
76
      );
77
      expect(result.add).toEqual([
78
        {
79
          displayName: 'ChatGPT-4',
80
          files: true,
81
          functionCall: true,
82
          id: 'gpt-4-0125-preview',
83
          tokens: 128000,
84
        },
85
        {
86
          displayName: 'ChatGPT-4 Vision',
87
          files: true,
88
          functionCall: true,
89
          id: 'gpt-4-turbo-2024-04-09',
90
          tokens: 128000,
91
          vision: true,
92
        },
93
      ]);
94
    });
95

96
    it('should handle empty extension capability value', () => {
97
      const result = parseModelString('model1<1024:>');
98
      expect(result.add[0]).toEqual({ id: 'model1', tokens: 1024 });
99
    });
100

101
    it('should handle empty extension capability name', () => {
102
      const result = parseModelString('model1<1024::file>');
103
      expect(result.add[0]).toEqual({ id: 'model1', tokens: 1024, files: true });
104
    });
105

106
    it('should handle duplicate extension capabilities', () => {
107
      const result = parseModelString('model1<1024:vision:vision>');
108
      expect(result.add[0]).toEqual({ id: 'model1', tokens: 1024, vision: true });
109
    });
110

111
    it('should handle case-sensitive extension capability names', () => {
112
      const result = parseModelString('model1<1024:VISION:FC:file>');
113
      expect(result.add[0]).toEqual({ id: 'model1', tokens: 1024, files: true });
114
    });
115

116
    it('should handle case-sensitive extension capability values', () => {
117
      const result = parseModelString('model1<1024:vision:Fc:File>');
118
      expect(result.add[0]).toEqual({ id: 'model1', tokens: 1024, vision: true });
119
    });
120

121
    it('should handle empty angle brackets', () => {
122
      const result = parseModelString('model1<>');
123
      expect(result.add[0]).toEqual({ id: 'model1' });
124
    });
125

126
    it('should handle not close angle brackets', () => {
127
      const result = parseModelString('model1<,model2');
128
      expect(result.add).toEqual([{ id: 'model1' }, { id: 'model2' }]);
129
    });
130

131
    it('should handle multi close angle brackets', () => {
132
      const result = parseModelString('model1<>>,model2');
133
      expect(result.add).toEqual([{ id: 'model1' }, { id: 'model2' }]);
134
    });
135

136
    it('should handle only colon inside angle brackets', () => {
137
      const result = parseModelString('model1<:>');
138
      expect(result.add[0]).toEqual({ id: 'model1' });
139
    });
140

141
    it('should handle only non-digit characters inside angle brackets', () => {
142
      const result = parseModelString('model1<abc>');
143
      expect(result.add[0]).toEqual({ id: 'model1' });
144
    });
145

146
    it('should handle non-digit characters followed by digits inside angle brackets', () => {
147
      const result = parseModelString('model1<abc123>');
148
      expect(result.add[0]).toEqual({ id: 'model1' });
149
    });
150

151
    it('should handle digits followed by non-colon characters inside angle brackets', () => {
152
      const result = parseModelString('model1<1024abc>');
153
      expect(result.add[0]).toEqual({ id: 'model1', tokens: 1024 });
154
    });
155

156
    it('should handle digits followed by multiple colons inside angle brackets', () => {
157
      const result = parseModelString('model1<1024::>');
158
      expect(result.add[0]).toEqual({ id: 'model1', tokens: 1024 });
159
    });
160

161
    it('should handle digits followed by a colon and non-letter characters inside angle brackets', () => {
162
      const result = parseModelString('model1<1024:123>');
163
      expect(result.add[0]).toEqual({ id: 'model1', tokens: 1024 });
164
    });
165

166
    it('should handle digits followed by a colon and spaces inside angle brackets', () => {
167
      const result = parseModelString('model1<1024: vision>');
168
      expect(result.add[0]).toEqual({ id: 'model1', tokens: 1024 });
169
    });
170

171
    it('should handle digits followed by multiple colons and spaces inside angle brackets', () => {
172
      const result = parseModelString('model1<1024: : vision>');
173
      expect(result.add[0]).toEqual({ id: 'model1', tokens: 1024 });
174
    });
175
  });
176

177
  describe('deployment name', () => {
178
    it('should have same deployment name as id', () => {
179
      const result = parseModelString('model1=Model 1', true);
180
      expect(result.add[0]).toEqual({
181
        id: 'model1',
182
        displayName: 'Model 1',
183
        deploymentName: 'model1',
184
      });
185
    });
186

187
    it('should have diff deployment name as id', () => {
188
      const result = parseModelString('gpt-35-turbo->my-deploy=GPT 3.5 Turbo', true);
189
      expect(result.add[0]).toEqual({
190
        id: 'gpt-35-turbo',
191
        displayName: 'GPT 3.5 Turbo',
192
        deploymentName: 'my-deploy',
193
      });
194
    });
195
  });
196
});
197

198
describe('transformToChatModelCards', () => {
199
  const defaultChatModels: ChatModelCard[] = [
200
    { id: 'model1', displayName: 'Model 1', enabled: true },
201
    { id: 'model2', displayName: 'Model 2', enabled: false },
202
  ];
203

204
  it('should return undefined when modelString is empty', () => {
205
    const result = transformToChatModelCards({
206
      modelString: '',
207
      defaultChatModels,
208
    });
209
    expect(result).toBeUndefined();
210
  });
211

212
  it('should remove all models when removeAll is true', () => {
213
    const result = transformToChatModelCards({
214
      modelString: '-all',
215
      defaultChatModels,
216
    });
217
    expect(result).toEqual([]);
218
  });
219

220
  it('should remove specified models', () => {
221
    const result = transformToChatModelCards({
222
      modelString: '-model1',
223
      defaultChatModels,
224
    });
225
    expect(result).toEqual([{ id: 'model2', displayName: 'Model 2', enabled: false }]);
226
  });
227

228
  it('should add a new known model', () => {
229
    const knownModel = LOBE_DEFAULT_MODEL_LIST[0];
230
    const result = transformToChatModelCards({
231
      modelString: `${knownModel.id}`,
232
      defaultChatModels,
233
    });
234
    expect(result).toContainEqual({
235
      ...knownModel,
236
      displayName: knownModel.displayName || knownModel.id,
237
      enabled: true,
238
    });
239
  });
240

241
  it('should update an existing known model', () => {
242
    const knownModel = LOBE_DEFAULT_MODEL_LIST[0];
243
    const result = transformToChatModelCards({
244
      modelString: `+${knownModel.id}=Updated Model`,
245
      defaultChatModels: [knownModel],
246
    });
247
    expect(result![0]).toEqual({ ...knownModel, displayName: 'Updated Model', enabled: true });
248
  });
249

250
  it('should add a new custom model', () => {
251
    const result = transformToChatModelCards({
252
      modelString: '+custom_model=Custom Model',
253
      defaultChatModels,
254
    });
255
    expect(result).toContainEqual({
256
      id: 'custom_model',
257
      displayName: 'Custom Model',
258
      enabled: true,
259
    });
260
  });
261

262
  it('should have file with builtin models like gpt-4-0125-preview', () => {
263
    const result = transformToChatModelCards({
264
      modelString:
265
        '-all,+gpt-4-0125-preview=ChatGPT-4<128000:fc:file>,+gpt-4-turbo-2024-04-09=ChatGPT-4 Vision<128000:fc:vision:file>',
266
      defaultChatModels: OpenAIProviderCard.chatModels,
267
    });
268

269
    expect(result).toMatchSnapshot();
270
  });
271
});
272

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.