@lobehub/chat 1.138.2 → 1.138.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/changelog/v1.json +18 -0
  3. package/docker-compose/local/docker-compose.yml +1 -1
  4. package/docker-compose/local/grafana/docker-compose.yml +1 -1
  5. package/docker-compose/production/grafana/docker-compose.yml +1 -1
  6. package/package.json +1 -1
  7. package/packages/database/src/models/topic.ts +0 -1
  8. package/packages/database/src/repositories/aiInfra/index.test.ts +656 -0
  9. package/packages/database/src/repositories/aiInfra/index.ts +19 -13
  10. package/packages/model-runtime/src/core/contextBuilders/google.test.ts +585 -0
  11. package/packages/model-runtime/src/core/contextBuilders/google.ts +201 -0
  12. package/packages/model-runtime/src/core/openaiCompatibleFactory/index.test.ts +191 -179
  13. package/packages/model-runtime/src/core/openaiCompatibleFactory/index.ts +305 -47
  14. package/packages/model-runtime/src/providers/anthropic/generateObject.test.ts +93 -84
  15. package/packages/model-runtime/src/providers/anthropic/generateObject.ts +3 -3
  16. package/packages/model-runtime/src/providers/google/generateObject.test.ts +588 -83
  17. package/packages/model-runtime/src/providers/google/generateObject.ts +104 -6
  18. package/packages/model-runtime/src/providers/google/index.test.ts +0 -395
  19. package/packages/model-runtime/src/providers/google/index.ts +28 -194
  20. package/packages/model-runtime/src/providers/openai/index.test.ts +18 -17
  21. package/packages/model-runtime/src/types/structureOutput.ts +3 -4
  22. package/packages/obervability-otel/package.json +4 -4
  23. package/packages/prompts/CLAUDE.md +289 -43
  24. package/packages/prompts/package.json +2 -1
  25. package/packages/prompts/promptfoo/supervisor/productive/eval.yaml +51 -0
  26. package/packages/prompts/promptfoo/supervisor/productive/prompt.ts +18 -0
  27. package/packages/prompts/promptfoo/supervisor/productive/tests/basic-case.ts +54 -0
  28. package/packages/prompts/promptfoo/supervisor/productive/tests/role.ts +58 -0
  29. package/packages/prompts/promptfoo/supervisor/productive/tools.json +80 -0
  30. package/packages/prompts/src/contexts/index.ts +1 -0
  31. package/packages/prompts/src/contexts/supervisor/index.ts +2 -0
  32. package/packages/prompts/src/contexts/supervisor/makeDecision.ts +68 -0
  33. package/packages/prompts/src/contexts/supervisor/tools.ts +102 -0
  34. package/packages/prompts/src/index.ts +1 -0
  35. package/packages/types/src/aiChat.ts +9 -4
  36. package/src/server/routers/lambda/aiChat.ts +0 -1
  37. package/src/server/services/aiChat/index.test.ts +1 -1
  38. package/src/server/services/aiChat/index.ts +1 -1
  39. package/src/services/topic/client.ts +1 -1
  40. package/src/store/chat/slices/message/supervisor.test.ts +12 -5
  41. package/src/store/chat/slices/message/supervisor.ts +16 -129
@@ -119,11 +119,11 @@ describe('LobeOpenAICompatibleFactory', () => {
119
119
  max_tokens: 1024,
120
120
  messages: [{ content: 'Hello', role: 'user' }],
121
121
  model: 'mistralai/mistral-7b-instruct:free',
122
- temperature: 0.7,
123
122
  stream: true,
124
123
  stream_options: {
125
124
  include_usage: true,
126
125
  },
126
+ temperature: 0.7,
127
127
  top_p: 1,
128
128
  },
129
129
  { headers: { Accept: '*/*' } },
@@ -136,14 +136,14 @@ describe('LobeOpenAICompatibleFactory', () => {
136
136
  const mockStream = new ReadableStream({
137
137
  start(controller) {
138
138
  controller.enqueue({
139
+ choices: [
140
+ { delta: { content: 'hello' }, finish_reason: null, index: 0, logprobs: null },
141
+ ],
142
+ created: 1_709_125_675,
139
143
  id: 'a',
140
- object: 'chat.completion.chunk',
141
- created: 1709125675,
142
144
  model: 'mistralai/mistral-7b-instruct:free',
145
+ object: 'chat.completion.chunk',
143
146
  system_fingerprint: 'fp_86156a94a0',
144
- choices: [
145
- { index: 0, delta: { content: 'hello' }, logprobs: null, finish_reason: null },
146
- ],
147
147
  });
148
148
  controller.close();
149
149
  },
@@ -163,6 +163,7 @@ describe('LobeOpenAICompatibleFactory', () => {
163
163
 
164
164
  // Collect all chunks
165
165
  const chunks = [];
166
+ // eslint-disable-next-line no-constant-condition
166
167
  while (true) {
167
168
  const { value, done } = await reader.read();
168
169
  if (done) break;
@@ -185,13 +186,13 @@ describe('LobeOpenAICompatibleFactory', () => {
185
186
  object: '',
186
187
  prompt_filter_results: [
187
188
  {
188
- prompt_index: 0,
189
189
  content_filter_results: {
190
190
  hate: { filtered: false, severity: 'safe' },
191
191
  self_harm: { filtered: false, severity: 'safe' },
192
192
  sexual: { filtered: false, severity: 'safe' },
193
193
  violence: { filtered: false, severity: 'safe' },
194
194
  },
195
+ prompt_index: 0,
195
196
  },
196
197
  ],
197
198
  },
@@ -204,7 +205,7 @@ describe('LobeOpenAICompatibleFactory', () => {
204
205
  logprobs: null,
205
206
  },
206
207
  ],
207
- created: 1717249403,
208
+ created: 1_717_249_403,
208
209
  id: 'chatcmpl-9VJIxA3qNM2C2YdAnNYA2KgDYfFnX',
209
210
  model: 'gpt-4o-2024-05-13',
210
211
  object: 'chat.completion.chunk',
@@ -212,7 +213,7 @@ describe('LobeOpenAICompatibleFactory', () => {
212
213
  },
213
214
  {
214
215
  choices: [{ delta: { content: '1' }, finish_reason: null, index: 0, logprobs: null }],
215
- created: 1717249403,
216
+ created: 1_717_249_403,
216
217
  id: 'chatcmpl-9VJIxA3qNM2C2YdAnNYA2KgDYfFnX',
217
218
  model: 'gpt-4o-2024-05-13',
218
219
  object: 'chat.completion.chunk',
@@ -220,7 +221,7 @@ describe('LobeOpenAICompatibleFactory', () => {
220
221
  },
221
222
  {
222
223
  choices: [{ delta: {}, finish_reason: 'stop', index: 0, logprobs: null }],
223
- created: 1717249403,
224
+ created: 1_717_249_403,
224
225
  id: 'chatcmpl-9VJIxA3qNM2C2YdAnNYA2KgDYfFnX',
225
226
  model: 'gpt-4o-2024-05-13',
226
227
  object: 'chat.completion.chunk',
@@ -229,7 +230,7 @@ describe('LobeOpenAICompatibleFactory', () => {
229
230
  {
230
231
  choices: [
231
232
  {
232
- content_filter_offsets: { check_offset: 35, start_offset: 35, end_offset: 36 },
233
+ content_filter_offsets: { check_offset: 35, end_offset: 36, start_offset: 35 },
233
234
  content_filter_results: {
234
235
  hate: { filtered: false, severity: 'safe' },
235
236
  self_harm: { filtered: false, severity: 'safe' },
@@ -268,6 +269,7 @@ describe('LobeOpenAICompatibleFactory', () => {
268
269
  const decoder = new TextDecoder();
269
270
  const reader = result.body!.getReader();
270
271
 
272
+ // eslint-disable-next-line no-constant-condition
271
273
  while (true) {
272
274
  const { value, done } = await reader.read();
273
275
  if (done) break;
@@ -278,7 +280,7 @@ describe('LobeOpenAICompatibleFactory', () => {
278
280
  [
279
281
  'id: ',
280
282
  'event: data',
281
- 'data: {"choices":[],"created":0,"id":"","model":"","object":"","prompt_filter_results":[{"prompt_index":0,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}}}]}\n',
283
+ 'data: {"choices":[],"created":0,"id":"","model":"","object":"","prompt_filter_results":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"prompt_index":0}]}\n',
282
284
  'id: chatcmpl-9VJIxA3qNM2C2YdAnNYA2KgDYfFnX',
283
285
  'event: text',
284
286
  'data: ""\n',
@@ -299,21 +301,21 @@ describe('LobeOpenAICompatibleFactory', () => {
299
301
  vi.useFakeTimers();
300
302
 
301
303
  const mockResponse = {
302
- id: 'a',
303
- object: 'chat.completion',
304
- created: 123,
305
- model: 'mistralai/mistral-7b-instruct:free',
306
304
  choices: [
307
305
  {
308
- index: 0,
309
- message: { role: 'assistant', content: 'Hello' },
310
306
  finish_reason: 'stop',
307
+ index: 0,
311
308
  logprobs: null,
309
+ message: { content: 'Hello', role: 'assistant' },
312
310
  },
313
311
  ],
312
+ created: 123,
313
+ id: 'a',
314
+ model: 'mistralai/mistral-7b-instruct:free',
315
+ object: 'chat.completion',
314
316
  usage: {
315
- prompt_tokens: 5,
316
317
  completion_tokens: 5,
318
+ prompt_tokens: 5,
317
319
  total_tokens: 10,
318
320
  },
319
321
  } as OpenAI.ChatCompletion;
@@ -324,8 +326,8 @@ describe('LobeOpenAICompatibleFactory', () => {
324
326
  const chatPromise = instance.chat({
325
327
  messages: [{ content: 'Hello', role: 'user' }],
326
328
  model: 'mistralai/mistral-7b-instruct:free',
327
- temperature: 0,
328
329
  stream: false,
330
+ temperature: 0,
329
331
  });
330
332
 
331
333
  // Advance time to simulate processing delay
@@ -337,6 +339,7 @@ describe('LobeOpenAICompatibleFactory', () => {
337
339
  const reader = result.body!.getReader();
338
340
  const stream: string[] = [];
339
341
 
342
+ // eslint-disable-next-line no-constant-condition
340
343
  while (true) {
341
344
  const { value, done } = await reader.read();
342
345
  if (done) break;
@@ -352,13 +355,14 @@ describe('LobeOpenAICompatibleFactory', () => {
352
355
  'data: {"inputTextTokens":5,"outputTextTokens":5,"totalInputTokens":5,"totalOutputTokens":5,"totalTokens":10}\n\n',
353
356
  'id: output_speed\n',
354
357
  'event: speed\n',
355
- expect.stringMatching(/^data: \{.*"tps":.*,"ttft":.*}\n\n$/), // tps ttft should be calculated with elapsed time
358
+ expect.stringMatching(/^data: {.*"tps":.*,"ttft":.*}\n\n$/), // tps ttft should be calculated with elapsed time
356
359
  'id: a\n',
357
360
  'event: stop\n',
358
361
  'data: "stop"\n\n',
359
362
  ]);
360
363
 
361
- expect((await reader.read()).done).toBe(true);
364
+ const finalRead = await reader.read();
365
+ expect(finalRead.done).toBe(true);
362
366
 
363
367
  vi.useRealTimers();
364
368
  });
@@ -367,25 +371,25 @@ describe('LobeOpenAICompatibleFactory', () => {
367
371
  vi.useFakeTimers();
368
372
 
369
373
  const mockResponse = {
370
- id: 'a',
371
- object: 'chat.completion',
372
- created: 123,
373
- model: 'deepseek/deepseek-reasoner',
374
374
  choices: [
375
375
  {
376
+ finish_reason: 'stop',
376
377
  index: 0,
378
+ logprobs: null,
377
379
  message: {
378
- role: 'assistant',
379
380
  content: 'Hello',
380
381
  reasoning_content: 'Thinking content',
382
+ role: 'assistant',
381
383
  },
382
- finish_reason: 'stop',
383
- logprobs: null,
384
384
  },
385
385
  ],
386
+ created: 123,
387
+ id: 'a',
388
+ model: 'deepseek/deepseek-reasoner',
389
+ object: 'chat.completion',
386
390
  usage: {
387
- prompt_tokens: 5,
388
391
  completion_tokens: 5,
392
+ prompt_tokens: 5,
389
393
  total_tokens: 10,
390
394
  },
391
395
  } as unknown as OpenAI.ChatCompletion;
@@ -396,8 +400,8 @@ describe('LobeOpenAICompatibleFactory', () => {
396
400
  const chatPromise = instance.chat({
397
401
  messages: [{ content: 'Hello', role: 'user' }],
398
402
  model: 'deepseek/deepseek-reasoner',
399
- temperature: 0,
400
403
  stream: false,
404
+ temperature: 0,
401
405
  });
402
406
 
403
407
  // Advance time to simulate processing delay
@@ -409,6 +413,7 @@ describe('LobeOpenAICompatibleFactory', () => {
409
413
  const reader = result.body!.getReader();
410
414
  const stream: string[] = [];
411
415
 
416
+ // eslint-disable-next-line no-constant-condition
412
417
  while (true) {
413
418
  const { value, done } = await reader.read();
414
419
  if (done) break;
@@ -427,13 +432,14 @@ describe('LobeOpenAICompatibleFactory', () => {
427
432
  'data: {"inputTextTokens":5,"outputTextTokens":5,"totalInputTokens":5,"totalOutputTokens":5,"totalTokens":10}\n\n',
428
433
  'id: output_speed\n',
429
434
  'event: speed\n',
430
- expect.stringMatching(/^data: \{.*"tps":.*,"ttft":.*}\n\n$/), // tps ttft should be calculated with elapsed time
435
+ expect.stringMatching(/^data: {.*"tps":.*,"ttft":.*}\n\n$/), // tps ttft should be calculated with elapsed time
431
436
  'id: a\n',
432
437
  'event: stop\n',
433
438
  'data: "stop"\n\n',
434
439
  ]);
435
440
 
436
- expect((await reader.read()).done).toBe(true);
441
+ const finalRead = await reader.read();
442
+ expect(finalRead.done).toBe(true);
437
443
 
438
444
  vi.useRealTimers();
439
445
  });
@@ -607,10 +613,10 @@ describe('LobeOpenAICompatibleFactory', () => {
607
613
  const apiError = new OpenAI.APIError(
608
614
  400,
609
615
  {
610
- status: 400,
611
616
  error: {
612
617
  message: 'Bad Request',
613
618
  },
619
+ status: 400,
614
620
  },
615
621
  'Error message',
616
622
  {},
@@ -770,13 +776,13 @@ describe('LobeOpenAICompatibleFactory', () => {
770
776
  } catch (e) {
771
777
  expect(e).toEqual({
772
778
  endpoint: defaultBaseURL,
773
- errorType: 'AgentRuntimeError',
774
- provider,
775
779
  error: {
776
- name: genericError.name,
777
780
  cause: genericError.cause,
778
781
  message: genericError.message,
782
+ name: genericError.name,
779
783
  },
784
+ errorType: 'AgentRuntimeError',
785
+ provider,
780
786
  });
781
787
  }
782
788
  });
@@ -791,14 +797,14 @@ describe('LobeOpenAICompatibleFactory', () => {
791
797
  new ReadableStream({
792
798
  start(controller) {
793
799
  controller.enqueue({
800
+ choices: [
801
+ { delta: { content: 'hello' }, finish_reason: null, index: 0, logprobs: null },
802
+ ],
803
+ created: 1_709_125_675,
794
804
  id: 'chatcmpl-8xDx5AETP8mESQN7UB30GxTN2H1SO',
795
- object: 'chat.completion.chunk',
796
- created: 1709125675,
797
805
  model: 'mistralai/mistral-7b-instruct:free',
806
+ object: 'chat.completion.chunk',
798
807
  system_fingerprint: 'fp_86156a94a0',
799
- choices: [
800
- { index: 0, delta: { content: 'hello' }, logprobs: null, finish_reason: null },
801
- ],
802
808
  });
803
809
  controller.close();
804
810
  },
@@ -807,8 +813,8 @@ describe('LobeOpenAICompatibleFactory', () => {
807
813
 
808
814
  // Prepare callback and headers
809
815
  const mockCallback: ChatStreamCallbacks = {
810
- onStart: vi.fn(),
811
816
  onCompletion: vi.fn(),
817
+ onStart: vi.fn(),
812
818
  };
813
819
  const mockHeaders = { 'Custom-Header': 'TestValue' };
814
820
 
@@ -848,6 +854,7 @@ describe('LobeOpenAICompatibleFactory', () => {
848
854
  const reader = readableStream.getReader();
849
855
  const process = async () => {
850
856
  try {
857
+ // eslint-disable-next-line no-constant-condition
851
858
  while (true) {
852
859
  const { done, value } = await reader.read();
853
860
  if (done) break;
@@ -877,9 +884,9 @@ describe('LobeOpenAICompatibleFactory', () => {
877
884
  const mockStream = new ReadableStream({
878
885
  start(controller) {
879
886
  controller.enqueue({
880
- id: 'test-id',
881
887
  choices: [{ delta: { content: 'Hello' }, index: 0 }],
882
888
  created: Date.now(),
889
+ id: 'test-id',
883
890
  model: 'test-model',
884
891
  object: 'chat.completion.chunk',
885
892
  });
@@ -908,12 +915,12 @@ describe('LobeOpenAICompatibleFactory', () => {
908
915
  start(controller) {
909
916
  // Transform the completion to chunk format
910
917
  controller.enqueue({
911
- id: data.id,
912
918
  choices: data.choices.map((choice) => ({
913
919
  delta: { content: choice.message.content },
914
920
  index: choice.index,
915
921
  })),
916
922
  created: data.created,
923
+ id: data.id,
917
924
  model: data.model,
918
925
  object: 'chat.completion.chunk',
919
926
  });
@@ -933,20 +940,20 @@ describe('LobeOpenAICompatibleFactory', () => {
933
940
  const instance = new LobeMockProvider({ apiKey: 'test' });
934
941
 
935
942
  const mockResponse: OpenAI.ChatCompletion = {
936
- id: 'test-id',
937
943
  choices: [
938
944
  {
945
+ finish_reason: 'stop',
939
946
  index: 0,
947
+ logprobs: null,
940
948
  message: {
941
- role: 'assistant',
942
949
  content: 'Test response',
943
950
  refusal: null,
951
+ role: 'assistant',
944
952
  },
945
- logprobs: null,
946
- finish_reason: 'stop',
947
953
  },
948
954
  ],
949
955
  created: Date.now(),
956
+ id: 'test-id',
950
957
  model: 'test-model',
951
958
  object: 'chat.completion',
952
959
  usage: { completion_tokens: 2, prompt_tokens: 1, total_tokens: 3 },
@@ -959,8 +966,8 @@ describe('LobeOpenAICompatibleFactory', () => {
959
966
  const payload: ChatStreamPayload = {
960
967
  messages: [{ content: 'Test', role: 'user' }],
961
968
  model: 'test-model',
962
- temperature: 0.7,
963
969
  stream: false,
970
+ temperature: 0.7,
964
971
  };
965
972
 
966
973
  await instance.chat(payload);
@@ -1110,8 +1117,8 @@ describe('LobeOpenAICompatibleFactory', () => {
1110
1117
  model: 'dall-e-3',
1111
1118
  params: {
1112
1119
  prompt: 'A beautiful sunset',
1113
- size: '1024x1024',
1114
1120
  quality: 'standard',
1121
+ size: '1024x1024',
1115
1122
  },
1116
1123
  };
1117
1124
 
@@ -1121,9 +1128,9 @@ describe('LobeOpenAICompatibleFactory', () => {
1121
1128
  model: 'dall-e-3',
1122
1129
  n: 1,
1123
1130
  prompt: 'A beautiful sunset',
1124
- size: '1024x1024',
1125
1131
  quality: 'standard',
1126
1132
  response_format: 'b64_json',
1133
+ size: '1024x1024',
1127
1134
  });
1128
1135
 
1129
1136
  expect(result).toEqual({
@@ -1200,9 +1207,9 @@ describe('LobeOpenAICompatibleFactory', () => {
1200
1207
  const payload = {
1201
1208
  model: 'dall-e-2',
1202
1209
  params: {
1203
- prompt: 'Add a rainbow to this image',
1204
1210
  imageUrls: ['https://example.com/image1.jpg'],
1205
1211
  mask: 'https://example.com/mask.jpg',
1212
+ prompt: 'Add a rainbow to this image',
1206
1213
  },
1207
1214
  };
1208
1215
 
@@ -1212,13 +1219,13 @@ describe('LobeOpenAICompatibleFactory', () => {
1212
1219
  'https://example.com/image1.jpg',
1213
1220
  );
1214
1221
  expect(instance['client'].images.edit).toHaveBeenCalledWith({
1222
+ image: expect.any(File),
1223
+ input_fidelity: 'high',
1224
+ mask: 'https://example.com/mask.jpg',
1215
1225
  model: 'dall-e-2',
1216
1226
  n: 1,
1217
1227
  prompt: 'Add a rainbow to this image',
1218
- image: expect.any(File),
1219
- mask: 'https://example.com/mask.jpg',
1220
1228
  response_format: 'b64_json',
1221
- input_fidelity: 'high',
1222
1229
  });
1223
1230
 
1224
1231
  expect(result).toEqual({
@@ -1243,8 +1250,8 @@ describe('LobeOpenAICompatibleFactory', () => {
1243
1250
  const payload = {
1244
1251
  model: 'dall-e-2',
1245
1252
  params: {
1246
- prompt: 'Merge these images',
1247
1253
  imageUrls: ['https://example.com/image1.jpg', 'https://example.com/image2.jpg'],
1254
+ prompt: 'Merge these images',
1248
1255
  },
1249
1256
  };
1250
1257
 
@@ -1259,12 +1266,12 @@ describe('LobeOpenAICompatibleFactory', () => {
1259
1266
  );
1260
1267
 
1261
1268
  expect(instance['client'].images.edit).toHaveBeenCalledWith({
1269
+ image: [mockFile1, mockFile2],
1270
+ input_fidelity: 'high',
1262
1271
  model: 'dall-e-2',
1263
1272
  n: 1,
1264
1273
  prompt: 'Merge these images',
1265
- image: [mockFile1, mockFile2],
1266
1274
  response_format: 'b64_json',
1267
- input_fidelity: 'high',
1268
1275
  });
1269
1276
 
1270
1277
  expect(result).toEqual({
@@ -1280,8 +1287,8 @@ describe('LobeOpenAICompatibleFactory', () => {
1280
1287
  const payload = {
1281
1288
  model: 'dall-e-2',
1282
1289
  params: {
1283
- prompt: 'Edit this image',
1284
1290
  imageUrls: ['https://invalid-url.com/image.jpg'],
1291
+ prompt: 'Edit this image',
1285
1292
  },
1286
1293
  };
1287
1294
 
@@ -1379,22 +1386,22 @@ describe('LobeOpenAICompatibleFactory', () => {
1379
1386
  const payload = {
1380
1387
  model: 'dall-e-2',
1381
1388
  params: {
1382
- prompt: 'Test prompt',
1383
- imageUrls: ['https://example.com/image.jpg'],
1384
1389
  customParam: 'should remain unchanged',
1390
+ imageUrls: ['https://example.com/image.jpg'],
1391
+ prompt: 'Test prompt',
1385
1392
  },
1386
1393
  };
1387
1394
 
1388
1395
  await (instance as any).createImage(payload);
1389
1396
 
1390
1397
  expect(instance['client'].images.edit).toHaveBeenCalledWith({
1398
+ customParam: 'should remain unchanged',
1399
+ image: expect.any(File),
1400
+ input_fidelity: 'high',
1391
1401
  model: 'dall-e-2',
1392
1402
  n: 1,
1393
1403
  prompt: 'Test prompt',
1394
- image: expect.any(File),
1395
- customParam: 'should remain unchanged',
1396
1404
  response_format: 'b64_json',
1397
- input_fidelity: 'high',
1398
1405
  });
1399
1406
  });
1400
1407
 
@@ -1421,8 +1428,8 @@ describe('LobeOpenAICompatibleFactory', () => {
1421
1428
  n: 1,
1422
1429
  prompt: 'Test prompt',
1423
1430
  quality: 'hd',
1424
- style: 'vivid',
1425
1431
  response_format: 'b64_json',
1432
+ style: 'vivid',
1426
1433
  });
1427
1434
  });
1428
1435
  });
@@ -1438,17 +1445,17 @@ describe('LobeOpenAICompatibleFactory', () => {
1438
1445
 
1439
1446
  const payload = {
1440
1447
  messages: [{ content: 'Generate a person object', role: 'user' as const }],
1448
+ model: 'gpt-4o',
1449
+ responseApi: true,
1441
1450
  schema: {
1442
- name: 'person_extractor',
1443
1451
  description: 'Extract person information',
1452
+ name: 'person_extractor',
1444
1453
  schema: {
1454
+ properties: { age: { type: 'number' }, name: { type: 'string' } },
1445
1455
  type: 'object' as const,
1446
- properties: { name: { type: 'string' }, age: { type: 'number' } },
1447
1456
  },
1448
1457
  strict: true,
1449
1458
  },
1450
- model: 'gpt-4o',
1451
- responseApi: true,
1452
1459
  };
1453
1460
 
1454
1461
  const result = await instance.generateObject(payload);
@@ -1464,7 +1471,7 @@ describe('LobeOpenAICompatibleFactory', () => {
1464
1471
  { headers: undefined, signal: undefined },
1465
1472
  );
1466
1473
 
1467
- expect(result).toEqual({ name: 'John', age: 30 });
1474
+ expect(result).toEqual({ age: 30, name: 'John' });
1468
1475
  });
1469
1476
 
1470
1477
  it('should handle options correctly', async () => {
@@ -1476,18 +1483,18 @@ describe('LobeOpenAICompatibleFactory', () => {
1476
1483
 
1477
1484
  const payload = {
1478
1485
  messages: [{ content: 'Generate status', role: 'user' as const }],
1486
+ model: 'gpt-4o',
1487
+ responseApi: true,
1479
1488
  schema: {
1480
1489
  name: 'status_extractor',
1481
- schema: { type: 'object' as const, properties: { status: { type: 'string' } } },
1490
+ schema: { properties: { status: { type: 'string' } }, type: 'object' as const },
1482
1491
  },
1483
- model: 'gpt-4o',
1484
- responseApi: true,
1485
1492
  };
1486
1493
 
1487
1494
  const options = {
1488
1495
  headers: { 'Custom-Header': 'test-value' },
1489
- user: 'test-user',
1490
1496
  signal: new AbortController().signal,
1497
+ user: 'test-user',
1491
1498
  };
1492
1499
 
1493
1500
  const result = await instance.generateObject(payload, options);
@@ -1516,12 +1523,12 @@ describe('LobeOpenAICompatibleFactory', () => {
1516
1523
 
1517
1524
  const payload = {
1518
1525
  messages: [{ content: 'Generate data', role: 'user' as const }],
1526
+ model: 'gpt-4o',
1527
+ responseApi: true,
1519
1528
  schema: {
1520
1529
  name: 'test_tool',
1521
- schema: { type: 'object' as const, properties: {} },
1530
+ schema: { properties: {}, type: 'object' as const },
1522
1531
  },
1523
- model: 'gpt-4o',
1524
- responseApi: true,
1525
1532
  };
1526
1533
 
1527
1534
  const result = await instance.generateObject(payload);
@@ -1542,12 +1549,12 @@ describe('LobeOpenAICompatibleFactory', () => {
1542
1549
 
1543
1550
  const payload = {
1544
1551
  messages: [{ content: 'Generate data', role: 'user' as const }],
1552
+ model: 'gpt-4o',
1553
+ responseApi: true,
1545
1554
  schema: {
1546
1555
  name: 'test_tool',
1547
- schema: { type: 'object' as const, properties: {} },
1556
+ schema: { properties: {}, type: 'object' as const },
1548
1557
  },
1549
- model: 'gpt-4o',
1550
- responseApi: true,
1551
1558
  };
1552
1559
 
1553
1560
  const result = await instance.generateObject(payload);
@@ -1568,35 +1575,38 @@ describe('LobeOpenAICompatibleFactory', () => {
1568
1575
 
1569
1576
  const payload = {
1570
1577
  messages: [{ content: 'Generate complex user data', role: 'user' as const }],
1578
+ model: 'gpt-4o',
1579
+ responseApi: true,
1571
1580
  schema: {
1572
1581
  name: 'user_extractor',
1573
1582
  schema: {
1574
- type: 'object' as const,
1575
1583
  properties: {
1584
+ metadata: { type: 'object' },
1576
1585
  user: {
1577
- type: 'object',
1578
1586
  properties: {
1579
1587
  name: { type: 'string' },
1580
1588
  profile: {
1581
- type: 'object',
1582
1589
  properties: {
1583
1590
  age: { type: 'number' },
1584
- preferences: { type: 'array', items: { type: 'string' } },
1591
+ preferences: { items: { type: 'string' }, type: 'array' },
1585
1592
  },
1593
+ type: 'object',
1586
1594
  },
1587
1595
  },
1596
+ type: 'object',
1588
1597
  },
1589
- metadata: { type: 'object' },
1590
1598
  },
1599
+ type: 'object' as const,
1591
1600
  },
1592
1601
  },
1593
- model: 'gpt-4o',
1594
- responseApi: true,
1595
1602
  };
1596
1603
 
1597
1604
  const result = await instance.generateObject(payload);
1598
1605
 
1599
1606
  expect(result).toEqual({
1607
+ metadata: {
1608
+ created: '2024-01-01',
1609
+ },
1600
1610
  user: {
1601
1611
  name: 'Alice',
1602
1612
  profile: {
@@ -1604,9 +1614,6 @@ describe('LobeOpenAICompatibleFactory', () => {
1604
1614
  preferences: ['music', 'sports'],
1605
1615
  },
1606
1616
  },
1607
- metadata: {
1608
- created: '2024-01-01',
1609
- },
1610
1617
  });
1611
1618
  });
1612
1619
 
@@ -1617,12 +1624,12 @@ describe('LobeOpenAICompatibleFactory', () => {
1617
1624
 
1618
1625
  const payload = {
1619
1626
  messages: [{ content: 'Generate data', role: 'user' as const }],
1627
+ model: 'gpt-4o',
1628
+ responseApi: true,
1620
1629
  schema: {
1621
1630
  name: 'test_tool',
1622
- schema: { type: 'object' as const, properties: {} },
1631
+ schema: { properties: {}, type: 'object' as const },
1623
1632
  },
1624
- model: 'gpt-4o',
1625
- responseApi: true,
1626
1633
  };
1627
1634
 
1628
1635
  await expect(instance.generateObject(payload)).rejects.toThrow(
@@ -1648,14 +1655,14 @@ describe('LobeOpenAICompatibleFactory', () => {
1648
1655
 
1649
1656
  const payload = {
1650
1657
  messages: [{ content: 'Generate a person object', role: 'user' as const }],
1658
+ model: 'gpt-4o',
1651
1659
  schema: {
1652
1660
  name: 'person_extractor',
1653
1661
  schema: {
1662
+ properties: { age: { type: 'number' }, name: { type: 'string' } },
1654
1663
  type: 'object' as const,
1655
- properties: { name: { type: 'string' }, age: { type: 'number' } },
1656
1664
  },
1657
1665
  },
1658
- model: 'gpt-4o',
1659
1666
  // responseApi: false or undefined - uses chat completions API
1660
1667
  };
1661
1668
 
@@ -1671,7 +1678,7 @@ describe('LobeOpenAICompatibleFactory', () => {
1671
1678
  { headers: undefined, signal: undefined },
1672
1679
  );
1673
1680
 
1674
- expect(result).toEqual({ name: 'Bob', age: 25 });
1681
+ expect(result).toEqual({ age: 25, name: 'Bob' });
1675
1682
  });
1676
1683
 
1677
1684
  it('should handle options correctly with chat completions API', async () => {
@@ -1691,18 +1698,18 @@ describe('LobeOpenAICompatibleFactory', () => {
1691
1698
 
1692
1699
  const payload = {
1693
1700
  messages: [{ content: 'Generate status', role: 'user' as const }],
1701
+ model: 'gpt-4o',
1702
+ responseApi: false,
1694
1703
  schema: {
1695
1704
  name: 'status_extractor',
1696
- schema: { type: 'object' as const, properties: { status: { type: 'string' } } },
1705
+ schema: { properties: { status: { type: 'string' } }, type: 'object' as const },
1697
1706
  },
1698
- model: 'gpt-4o',
1699
- responseApi: false,
1700
1707
  };
1701
1708
 
1702
1709
  const options = {
1703
1710
  headers: { Authorization: 'Bearer token' },
1704
- user: 'test-user-123',
1705
1711
  signal: new AbortController().signal,
1712
+ user: 'test-user-123',
1706
1713
  };
1707
1714
 
1708
1715
  const result = await instance.generateObject(payload, options);
@@ -1738,12 +1745,12 @@ describe('LobeOpenAICompatibleFactory', () => {
1738
1745
 
1739
1746
  const payload = {
1740
1747
  messages: [{ content: 'Generate data', role: 'user' as const }],
1748
+ model: 'gpt-4o',
1749
+ responseApi: false,
1741
1750
  schema: {
1742
1751
  name: 'test_tool',
1743
- schema: { type: 'object' as const, properties: {} },
1752
+ schema: { properties: {}, type: 'object' as const },
1744
1753
  },
1745
- model: 'gpt-4o',
1746
- responseApi: false,
1747
1754
  };
1748
1755
 
1749
1756
  const result = await instance.generateObject(payload);
@@ -1772,12 +1779,12 @@ describe('LobeOpenAICompatibleFactory', () => {
1772
1779
 
1773
1780
  const payload = {
1774
1781
  messages: [{ content: 'Generate data', role: 'user' as const }],
1782
+ model: 'gpt-4o',
1783
+ responseApi: false,
1775
1784
  schema: {
1776
1785
  name: 'test_tool',
1777
- schema: { type: 'object' as const, properties: {} },
1786
+ schema: { properties: {}, type: 'object' as const },
1778
1787
  },
1779
- model: 'gpt-4o',
1780
- responseApi: false,
1781
1788
  };
1782
1789
 
1783
1790
  const result = await instance.generateObject(payload);
@@ -1806,26 +1813,26 @@ describe('LobeOpenAICompatibleFactory', () => {
1806
1813
 
1807
1814
  const payload = {
1808
1815
  messages: [{ content: 'Generate items list', role: 'user' as const }],
1816
+ model: 'gpt-4o',
1809
1817
  schema: {
1810
1818
  name: 'abc',
1811
1819
  schema: {
1812
- type: 'object' as const,
1813
1820
  properties: {
1814
1821
  items: {
1815
- type: 'array',
1816
1822
  items: {
1817
- type: 'object',
1818
1823
  properties: {
1819
1824
  id: { type: 'number' },
1820
1825
  name: { type: 'string' },
1821
1826
  },
1827
+ type: 'object',
1822
1828
  },
1829
+ type: 'array',
1823
1830
  },
1824
1831
  total: { type: 'number' },
1825
1832
  },
1833
+ type: 'object' as const,
1826
1834
  },
1827
1835
  },
1828
- model: 'gpt-4o',
1829
1836
  };
1830
1837
 
1831
1838
  const result = await instance.generateObject(payload);
@@ -1846,9 +1853,9 @@ describe('LobeOpenAICompatibleFactory', () => {
1846
1853
 
1847
1854
  const payload = {
1848
1855
  messages: [{ content: 'Generate data', role: 'user' as const }],
1849
- schema: { name: 'abc', schema: { type: 'object' } as any },
1850
1856
  model: 'gpt-4o',
1851
1857
  responseApi: false,
1858
+ schema: { name: 'abc', schema: { type: 'object' } as any },
1852
1859
  };
1853
1860
 
1854
1861
  await expect(instance.generateObject(payload)).rejects.toThrow(
@@ -1865,18 +1872,18 @@ describe('LobeOpenAICompatibleFactory', () => {
1865
1872
  message: {
1866
1873
  tool_calls: [
1867
1874
  {
1868
- type: 'function' as const,
1869
1875
  function: {
1870
- name: 'get_weather',
1871
1876
  arguments: '{"city":"Tokyo","unit":"celsius"}',
1877
+ name: 'get_weather',
1872
1878
  },
1879
+ type: 'function' as const,
1873
1880
  },
1874
1881
  {
1875
- type: 'function' as const,
1876
1882
  function: {
1877
- name: 'get_time',
1878
1883
  arguments: '{"timezone":"Asia/Tokyo"}',
1884
+ name: 'get_time',
1879
1885
  },
1886
+ type: 'function' as const,
1880
1887
  },
1881
1888
  ],
1882
1889
  },
@@ -1890,32 +1897,38 @@ describe('LobeOpenAICompatibleFactory', () => {
1890
1897
 
1891
1898
  const payload = {
1892
1899
  messages: [{ content: 'What is the weather and time in Tokyo?', role: 'user' as const }],
1900
+ model: 'gpt-4o',
1893
1901
  tools: [
1894
1902
  {
1895
- name: 'get_weather',
1896
- description: 'Get weather information',
1897
- parameters: {
1898
- type: 'object' as const,
1899
- properties: {
1900
- city: { type: 'string' },
1901
- unit: { type: 'string' },
1903
+ function: {
1904
+ description: 'Get weather information',
1905
+ name: 'get_weather',
1906
+ parameters: {
1907
+ properties: {
1908
+ city: { type: 'string' },
1909
+ unit: { type: 'string' },
1910
+ },
1911
+ required: ['city'],
1912
+ type: 'object' as const,
1902
1913
  },
1903
- required: ['city'],
1904
1914
  },
1915
+ type: 'function' as const,
1905
1916
  },
1906
1917
  {
1907
- name: 'get_time',
1908
- description: 'Get current time',
1909
- parameters: {
1910
- type: 'object' as const,
1911
- properties: {
1912
- timezone: { type: 'string' },
1918
+ function: {
1919
+ description: 'Get current time',
1920
+ name: 'get_time',
1921
+ parameters: {
1922
+ properties: {
1923
+ timezone: { type: 'string' },
1924
+ },
1925
+ required: ['timezone'],
1926
+ type: 'object' as const,
1913
1927
  },
1914
- required: ['timezone'],
1915
1928
  },
1929
+ type: 'function' as const,
1916
1930
  },
1917
1931
  ],
1918
- model: 'gpt-4o',
1919
1932
  };
1920
1933
 
1921
1934
  const result = await instance.generateObject(payload);
@@ -1927,33 +1940,33 @@ describe('LobeOpenAICompatibleFactory', () => {
1927
1940
  tool_choice: 'required',
1928
1941
  tools: [
1929
1942
  {
1930
- type: 'function',
1931
1943
  function: {
1932
- name: 'get_weather',
1933
1944
  description: 'Get weather information',
1945
+ name: 'get_weather',
1934
1946
  parameters: {
1935
- type: 'object',
1936
1947
  properties: {
1937
1948
  city: { type: 'string' },
1938
1949
  unit: { type: 'string' },
1939
1950
  },
1940
1951
  required: ['city'],
1952
+ type: 'object',
1941
1953
  },
1942
1954
  },
1955
+ type: 'function',
1943
1956
  },
1944
1957
  {
1945
- type: 'function',
1946
1958
  function: {
1947
- name: 'get_time',
1948
1959
  description: 'Get current time',
1960
+ name: 'get_time',
1949
1961
  parameters: {
1950
- type: 'object',
1951
1962
  properties: {
1952
1963
  timezone: { type: 'string' },
1953
1964
  },
1954
1965
  required: ['timezone'],
1966
+ type: 'object',
1955
1967
  },
1956
1968
  },
1969
+ type: 'function',
1957
1970
  },
1958
1971
  ],
1959
1972
  user: undefined,
@@ -1974,11 +1987,11 @@ describe('LobeOpenAICompatibleFactory', () => {
1974
1987
  message: {
1975
1988
  tool_calls: [
1976
1989
  {
1977
- type: 'function' as const,
1978
1990
  function: {
1979
- name: 'calculate',
1980
1991
  arguments: '{"result":8}',
1992
+ name: 'calculate',
1981
1993
  },
1994
+ type: 'function' as const,
1982
1995
  },
1983
1996
  ],
1984
1997
  },
@@ -1992,31 +2005,30 @@ describe('LobeOpenAICompatibleFactory', () => {
1992
2005
 
1993
2006
  const payload = {
1994
2007
  messages: [{ content: 'Add 5 and 3', role: 'user' as const }],
2008
+ model: 'gpt-4o',
1995
2009
  tools: [
1996
2010
  {
1997
- name: 'calculate',
1998
- description: 'Perform calculation',
1999
- parameters: {
2000
- type: 'object' as const,
2001
- properties: {
2002
- result: { type: 'number' },
2011
+ function: {
2012
+ description: 'Perform calculation',
2013
+ name: 'calculate',
2014
+ parameters: {
2015
+ properties: {
2016
+ result: { type: 'number' },
2017
+ },
2018
+ required: ['result'],
2019
+ type: 'object' as const,
2003
2020
  },
2004
- required: ['result'],
2005
2021
  },
2022
+ type: 'function' as const,
2006
2023
  },
2007
2024
  ],
2008
- systemRole: 'You are a helpful calculator',
2009
- model: 'gpt-4o',
2010
2025
  };
2011
2026
 
2012
2027
  const result = await instance.generateObject(payload);
2013
2028
 
2014
2029
  expect(instance['client'].chat.completions.create).toHaveBeenCalledWith(
2015
2030
  expect.objectContaining({
2016
- messages: [
2017
- { content: 'Add 5 and 3', role: 'user' },
2018
- { content: 'You are a helpful calculator', role: 'system' },
2019
- ],
2031
+ messages: [{ content: 'Add 5 and 3', role: 'user' }],
2020
2032
  }),
2021
2033
  expect.any(Object),
2022
2034
  );
@@ -2058,11 +2070,11 @@ describe('LobeOpenAICompatibleFactory', () => {
2058
2070
  message: {
2059
2071
  tool_calls: [
2060
2072
  {
2061
- type: 'function' as const,
2062
2073
  function: {
2063
- name: 'person_extractor',
2064
2074
  arguments: '{"name":"Alice","age":28}',
2075
+ name: 'person_extractor',
2065
2076
  },
2077
+ type: 'function' as const,
2066
2078
  },
2067
2079
  ],
2068
2080
  },
@@ -2076,15 +2088,15 @@ describe('LobeOpenAICompatibleFactory', () => {
2076
2088
 
2077
2089
  const payload = {
2078
2090
  messages: [{ content: 'Extract person info', role: 'user' as const }],
2091
+ model: 'test-model',
2079
2092
  schema: {
2080
- name: 'person_extractor',
2081
2093
  description: 'Extract person information',
2094
+ name: 'person_extractor',
2082
2095
  schema: {
2096
+ properties: { age: { type: 'number' }, name: { type: 'string' } },
2083
2097
  type: 'object' as const,
2084
- properties: { name: { type: 'string' }, age: { type: 'number' } },
2085
2098
  },
2086
2099
  },
2087
- model: 'test-model',
2088
2100
  };
2089
2101
 
2090
2102
  const result = await instanceWithToolCalling.generateObject(payload);
@@ -2093,24 +2105,24 @@ describe('LobeOpenAICompatibleFactory', () => {
2093
2105
  {
2094
2106
  messages: payload.messages,
2095
2107
  model: payload.model,
2108
+ tool_choice: { function: { name: 'person_extractor' }, type: 'function' },
2096
2109
  tools: [
2097
2110
  {
2098
- type: 'function',
2099
2111
  function: {
2100
- name: 'person_extractor',
2101
2112
  description: 'Extract person information',
2113
+ name: 'person_extractor',
2102
2114
  parameters: payload.schema.schema,
2103
2115
  },
2116
+ type: 'function',
2104
2117
  },
2105
2118
  ],
2106
- tool_choice: { type: 'function', function: { name: 'person_extractor' } },
2107
2119
  user: undefined,
2108
2120
  },
2109
2121
  { headers: undefined, signal: undefined },
2110
2122
  );
2111
2123
 
2112
2124
  expect(result).toEqual([
2113
- { arguments: { name: 'Alice', age: 28 }, name: 'person_extractor' },
2125
+ { arguments: { age: 28, name: 'Alice' }, name: 'person_extractor' },
2114
2126
  ]);
2115
2127
  });
2116
2128
 
@@ -2132,11 +2144,11 @@ describe('LobeOpenAICompatibleFactory', () => {
2132
2144
 
2133
2145
  const payload = {
2134
2146
  messages: [{ content: 'Generate data', role: 'user' as const }],
2147
+ model: 'test-model',
2135
2148
  schema: {
2136
2149
  name: 'test_tool',
2137
- schema: { type: 'object' as const, properties: {} },
2150
+ schema: { properties: {}, type: 'object' as const },
2138
2151
  },
2139
- model: 'test-model',
2140
2152
  };
2141
2153
 
2142
2154
  const result = await instanceWithToolCalling.generateObject(payload);
@@ -2154,11 +2166,11 @@ describe('LobeOpenAICompatibleFactory', () => {
2154
2166
  message: {
2155
2167
  tool_calls: [
2156
2168
  {
2157
- type: 'function' as const,
2158
2169
  function: {
2159
- name: 'test_tool',
2160
2170
  arguments: 'invalid json',
2171
+ name: 'test_tool',
2161
2172
  },
2173
+ type: 'function' as const,
2162
2174
  },
2163
2175
  ],
2164
2176
  },
@@ -2173,11 +2185,11 @@ describe('LobeOpenAICompatibleFactory', () => {
2173
2185
 
2174
2186
  const payload = {
2175
2187
  messages: [{ content: 'Generate data', role: 'user' as const }],
2188
+ model: 'test-model',
2176
2189
  schema: {
2177
2190
  name: 'test_tool',
2178
- schema: { type: 'object' as const, properties: {} },
2191
+ schema: { properties: {}, type: 'object' as const },
2179
2192
  },
2180
- model: 'test-model',
2181
2193
  };
2182
2194
 
2183
2195
  const result = await instanceWithToolCalling.generateObject(payload);
@@ -2198,11 +2210,11 @@ describe('LobeOpenAICompatibleFactory', () => {
2198
2210
  message: {
2199
2211
  tool_calls: [
2200
2212
  {
2201
- type: 'function' as const,
2202
2213
  function: {
2203
- name: 'data_extractor',
2204
2214
  arguments: '{"data":"test"}',
2215
+ name: 'data_extractor',
2205
2216
  },
2217
+ type: 'function' as const,
2206
2218
  },
2207
2219
  ],
2208
2220
  },
@@ -2216,17 +2228,17 @@ describe('LobeOpenAICompatibleFactory', () => {
2216
2228
 
2217
2229
  const payload = {
2218
2230
  messages: [{ content: 'Extract data', role: 'user' as const }],
2231
+ model: 'test-model',
2219
2232
  schema: {
2220
2233
  name: 'data_extractor',
2221
- schema: { type: 'object' as const, properties: { data: { type: 'string' } } },
2234
+ schema: { properties: { data: { type: 'string' } }, type: 'object' as const },
2222
2235
  },
2223
- model: 'test-model',
2224
2236
  };
2225
2237
 
2226
2238
  const options = {
2227
2239
  headers: { 'X-Custom': 'header' },
2228
- user: 'test-user',
2229
2240
  signal: new AbortController().signal,
2241
+ user: 'test-user',
2230
2242
  };
2231
2243
 
2232
2244
  const result = await instanceWithToolCalling.generateObject(payload, options);
@@ -2245,10 +2257,10 @@ describe('LobeOpenAICompatibleFactory', () => {
2245
2257
  it('should get models with third party model list', async () => {
2246
2258
  vi.spyOn(instance['client'].models, 'list').mockResolvedValue({
2247
2259
  data: [
2248
- { id: 'gpt-4o', object: 'model', created: 1698218177 },
2260
+ { created: 1_698_218_177, id: 'gpt-4o', object: 'model' },
2249
2261
  { id: 'claude-3-haiku-20240307', object: 'model' },
2250
- { id: 'gpt-4o-mini', object: 'model', created: 1698318177 * 1000 },
2251
- { id: 'gemini', object: 'model', created: 1736499509125 },
2262
+ { created: 1_698_318_177 * 1000, id: 'gpt-4o-mini', object: 'model' },
2263
+ { created: 1_736_499_509_125, id: 'gemini', object: 'model' },
2252
2264
  ],
2253
2265
  } as any);
2254
2266
 
@@ -2263,7 +2275,7 @@ describe('LobeOpenAICompatibleFactory', () => {
2263
2275
  config: {
2264
2276
  deploymentName: 'gpt-4o',
2265
2277
  },
2266
- contextWindowTokens: 128000,
2278
+ contextWindowTokens: 128_000,
2267
2279
  description:
2268
2280
  'ChatGPT-4o 是一款动态模型,实时更新以保持当前最新版本。它结合了强大的语言理解与生成能力,适合于大规模应用场景,包括客户服务、教育和技术支持。',
2269
2281
  displayName: 'GPT-4o',
@@ -2302,7 +2314,7 @@ describe('LobeOpenAICompatibleFactory', () => {
2302
2314
  functionCall: true,
2303
2315
  vision: true,
2304
2316
  },
2305
- contextWindowTokens: 200000,
2317
+ contextWindowTokens: 200_000,
2306
2318
  description:
2307
2319
  'Claude 3 Haiku 是 Anthropic 的最快且最紧凑的模型,旨在实现近乎即时的响应。它具有快速且准确的定向性能。',
2308
2320
  displayName: 'Claude 3 Haiku',
@@ -2359,7 +2371,7 @@ describe('LobeOpenAICompatibleFactory', () => {
2359
2371
  config: {
2360
2372
  deploymentName: 'gpt-4o-mini',
2361
2373
  },
2362
- contextWindowTokens: 128000,
2374
+ contextWindowTokens: 128_000,
2363
2375
  description: 'GPT-4o Mini,小型高效模型,具备与GPT-4o相似的卓越性能。',
2364
2376
  displayName: 'GPT 4o Mini',
2365
2377
  enabled: false,