@lobehub/chat 1.51.7 → 1.51.8
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.
- package/CHANGELOG.md +25 -0
- package/README.ja-JP.md +8 -8
- package/README.md +8 -8
- package/README.zh-CN.md +8 -8
- package/changelog/v1.json +9 -0
- package/package.json +1 -1
- package/src/app/(backend)/webapi/chat/models/[provider]/route.ts +1 -1
- package/src/libs/agent-runtime/ai360/index.ts +8 -1
- package/src/libs/agent-runtime/anthropic/index.ts +2 -1
- package/src/libs/agent-runtime/baichuan/index.ts +1 -1
- package/src/libs/agent-runtime/cloudflare/index.test.ts +0 -117
- package/src/libs/agent-runtime/cloudflare/index.ts +32 -11
- package/src/libs/agent-runtime/deepseek/index.ts +4 -1
- package/src/libs/agent-runtime/fireworksai/index.ts +8 -1
- package/src/libs/agent-runtime/giteeai/index.ts +9 -1
- package/src/libs/agent-runtime/github/index.test.ts +5 -16
- package/src/libs/agent-runtime/github/index.ts +31 -33
- package/src/libs/agent-runtime/google/index.ts +2 -1
- package/src/libs/agent-runtime/groq/index.ts +7 -1
- package/src/libs/agent-runtime/higress/index.ts +2 -1
- package/src/libs/agent-runtime/huggingface/index.ts +10 -1
- package/src/libs/agent-runtime/hunyuan/index.ts +3 -1
- package/src/libs/agent-runtime/internlm/index.ts +3 -1
- package/src/libs/agent-runtime/mistral/index.ts +2 -1
- package/src/libs/agent-runtime/moonshot/index.ts +3 -1
- package/src/libs/agent-runtime/novita/__snapshots__/index.test.ts.snap +48 -12
- package/src/libs/agent-runtime/novita/index.ts +9 -1
- package/src/libs/agent-runtime/openai/__snapshots__/index.test.ts.snap +70 -66
- package/src/libs/agent-runtime/openai/index.ts +37 -0
- package/src/libs/agent-runtime/openrouter/__snapshots__/index.test.ts.snap +172 -4
- package/src/libs/agent-runtime/openrouter/index.ts +17 -2
- package/src/libs/agent-runtime/qwen/index.ts +10 -1
- package/src/libs/agent-runtime/sensenova/index.ts +3 -1
- package/src/libs/agent-runtime/siliconcloud/index.ts +10 -1
- package/src/libs/agent-runtime/stepfun/index.ts +3 -1
- package/src/libs/agent-runtime/togetherai/__snapshots__/index.test.ts.snap +1309 -5
- package/src/libs/agent-runtime/togetherai/index.test.ts +0 -13
- package/src/libs/agent-runtime/togetherai/index.ts +25 -20
- package/src/libs/agent-runtime/utils/cloudflareHelpers.test.ts +0 -99
- package/src/libs/agent-runtime/utils/cloudflareHelpers.ts +0 -70
- package/src/libs/agent-runtime/xai/index.ts +3 -1
- package/src/libs/agent-runtime/zeroone/index.ts +3 -1
- package/src/libs/agent-runtime/zhipu/index.ts +3 -1
@@ -297,17 +297,4 @@ describe('LobeTogetherAI', () => {
|
|
297
297
|
});
|
298
298
|
});
|
299
299
|
});
|
300
|
-
|
301
|
-
describe('models', () => {
|
302
|
-
it('should get models', async () => {
|
303
|
-
vi.spyOn(globalThis, 'fetch').mockResolvedValueOnce({
|
304
|
-
json: async () => models,
|
305
|
-
ok: true,
|
306
|
-
} as Response);
|
307
|
-
|
308
|
-
const list = await instance.models();
|
309
|
-
|
310
|
-
expect(list).toMatchSnapshot();
|
311
|
-
});
|
312
|
-
});
|
313
300
|
});
|
@@ -1,12 +1,12 @@
|
|
1
|
-
import { LOBE_DEFAULT_MODEL_LIST } from '@/config/modelProviders';
|
2
|
-
|
3
1
|
import { ModelProvider } from '../types';
|
4
2
|
import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory';
|
5
3
|
import { TogetherAIModel } from './type';
|
6
4
|
|
7
|
-
|
5
|
+
import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels';
|
6
|
+
import type { ChatModelCard } from '@/types/llm';
|
7
|
+
|
8
8
|
export const LobeTogetherAI = LobeOpenAICompatibleFactory({
|
9
|
-
baseURL:
|
9
|
+
baseURL: 'https://api.together.xyz/v1',
|
10
10
|
constructorOptions: {
|
11
11
|
defaultHeaders: {
|
12
12
|
'HTTP-Referer': 'https://chat-preview.lobehub.com',
|
@@ -17,32 +17,37 @@ export const LobeTogetherAI = LobeOpenAICompatibleFactory({
|
|
17
17
|
chatCompletion: () => process.env.DEBUG_TOGETHERAI_CHAT_COMPLETION === '1',
|
18
18
|
},
|
19
19
|
models: async ({ client }) => {
|
20
|
-
const
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
20
|
+
const visionKeywords = [
|
21
|
+
'qvq',
|
22
|
+
'vision',
|
23
|
+
];
|
24
|
+
|
25
|
+
const reasoningKeywords = [
|
26
|
+
'deepseek-r1',
|
27
|
+
'qwq',
|
28
|
+
];
|
29
|
+
|
30
|
+
client.baseURL = 'https://api.together.xyz/api';
|
29
31
|
|
30
|
-
const
|
32
|
+
const modelsPage = await client.models.list() as any;
|
33
|
+
const modelList: TogetherAIModel[] = modelsPage.body;
|
31
34
|
|
32
|
-
return
|
33
|
-
.filter((m) => m.display_type === 'chat')
|
35
|
+
return modelList
|
34
36
|
.map((model) => {
|
35
37
|
return {
|
38
|
+
contextWindowTokens: LOBE_DEFAULT_MODEL_LIST.find((m) => model.name === m.id)?.contextWindowTokens ?? undefined,
|
36
39
|
description: model.description,
|
37
40
|
displayName: model.display_name,
|
38
|
-
enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.name
|
39
|
-
functionCall: model.description?.includes('function calling'),
|
41
|
+
enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.name === m.id)?.enabled || false,
|
42
|
+
functionCall: model.description?.toLowerCase().includes('function calling'),
|
40
43
|
id: model.name,
|
41
44
|
maxOutput: model.context_length,
|
45
|
+
reasoning: reasoningKeywords.some(keyword => model.name.toLowerCase().includes(keyword)),
|
42
46
|
tokens: model.context_length,
|
43
|
-
vision: model.description?.includes('vision') || model.name?.includes(
|
47
|
+
vision: model.description?.toLowerCase().includes('vision') || visionKeywords.some(keyword => model.name?.toLowerCase().includes(keyword)),
|
44
48
|
};
|
45
|
-
})
|
49
|
+
})
|
50
|
+
.filter(Boolean) as ChatModelCard[];
|
46
51
|
},
|
47
52
|
provider: ModelProvider.TogetherAI,
|
48
53
|
});
|
@@ -6,25 +6,8 @@ import {
|
|
6
6
|
CloudflareStreamTransformer,
|
7
7
|
desensitizeCloudflareUrl,
|
8
8
|
fillUrl,
|
9
|
-
getModelBeta,
|
10
|
-
getModelDisplayName,
|
11
|
-
getModelFunctionCalling,
|
12
|
-
getModelTokens,
|
13
9
|
} from './cloudflareHelpers';
|
14
10
|
|
15
|
-
//const {
|
16
|
-
// getModelBeta,
|
17
|
-
// getModelDisplayName,
|
18
|
-
// getModelFunctionCalling,
|
19
|
-
// getModelTokens,
|
20
|
-
//} = require('./cloudflareHelpers');
|
21
|
-
|
22
|
-
//const cloudflareHelpers = require('./cloudflareHelpers');
|
23
|
-
//const getModelBeta = cloudflareHelpers.__get__('getModelBeta');
|
24
|
-
//const getModelDisplayName = cloudflareHelpers.__get__('getModelDisplayName');
|
25
|
-
//const getModelFunctionCalling = cloudflareHelpers.__get__('getModelFunctionCalling');
|
26
|
-
//const getModelTokens = cloudflareHelpers.__get__('getModelTokens');
|
27
|
-
|
28
11
|
afterEach(() => {
|
29
12
|
vi.restoreAllMocks();
|
30
13
|
});
|
@@ -254,86 +237,4 @@ describe('cloudflareHelpers', () => {
|
|
254
237
|
});
|
255
238
|
});
|
256
239
|
});
|
257
|
-
|
258
|
-
describe('modelManifest', () => {
|
259
|
-
describe('getModelBeta', () => {
|
260
|
-
it('should get beta property', () => {
|
261
|
-
const model = { properties: [{ property_id: 'beta', value: 'true' }] };
|
262
|
-
const beta = getModelBeta(model);
|
263
|
-
expect(beta).toBe(true);
|
264
|
-
});
|
265
|
-
|
266
|
-
it('should return false if beta property is false', () => {
|
267
|
-
const model = { properties: [{ property_id: 'beta', value: 'false' }] };
|
268
|
-
const beta = getModelBeta(model);
|
269
|
-
expect(beta).toBe(false);
|
270
|
-
});
|
271
|
-
|
272
|
-
it('should return false if beta property is not present', () => {
|
273
|
-
const model = { properties: [] };
|
274
|
-
const beta = getModelBeta(model);
|
275
|
-
expect(beta).toBe(false);
|
276
|
-
});
|
277
|
-
});
|
278
|
-
|
279
|
-
describe('getModelDisplayName', () => {
|
280
|
-
it('should return display name with beta suffix', () => {
|
281
|
-
const model = { name: 'model', properties: [{ property_id: 'beta', value: 'true' }] };
|
282
|
-
const name = getModelDisplayName(model, true);
|
283
|
-
expect(name).toBe('model (Beta)');
|
284
|
-
});
|
285
|
-
|
286
|
-
it('should return display name without beta suffix', () => {
|
287
|
-
const model = { name: 'model', properties: [] };
|
288
|
-
const name = getModelDisplayName(model, false);
|
289
|
-
expect(name).toBe('model');
|
290
|
-
});
|
291
|
-
|
292
|
-
it('should return model["name"]', () => {
|
293
|
-
const model = { id: 'modelID', name: 'modelName' };
|
294
|
-
const name = getModelDisplayName(model, false);
|
295
|
-
expect(name).toBe('modelName');
|
296
|
-
});
|
297
|
-
|
298
|
-
it('should return last part of model["name"]', () => {
|
299
|
-
const model = { name: '@provider/modelFamily/modelName' };
|
300
|
-
const name = getModelDisplayName(model, false);
|
301
|
-
expect(name).toBe('modelName');
|
302
|
-
});
|
303
|
-
});
|
304
|
-
|
305
|
-
describe('getModelFunctionCalling', () => {
|
306
|
-
it('should return true if function_calling property is true', () => {
|
307
|
-
const model = { properties: [{ property_id: 'function_calling', value: 'true' }] };
|
308
|
-
const functionCalling = getModelFunctionCalling(model);
|
309
|
-
expect(functionCalling).toBe(true);
|
310
|
-
});
|
311
|
-
|
312
|
-
it('should return false if function_calling property is false', () => {
|
313
|
-
const model = { properties: [{ property_id: 'function_calling', value: 'false' }] };
|
314
|
-
const functionCalling = getModelFunctionCalling(model);
|
315
|
-
expect(functionCalling).toBe(false);
|
316
|
-
});
|
317
|
-
|
318
|
-
it('should return false if function_calling property is not set', () => {
|
319
|
-
const model = { properties: [] };
|
320
|
-
const functionCalling = getModelFunctionCalling(model);
|
321
|
-
expect(functionCalling).toBe(false);
|
322
|
-
});
|
323
|
-
});
|
324
|
-
|
325
|
-
describe('getModelTokens', () => {
|
326
|
-
it('should return tokens property value', () => {
|
327
|
-
const model = { properties: [{ property_id: 'max_total_tokens', value: '100' }] };
|
328
|
-
const tokens = getModelTokens(model);
|
329
|
-
expect(tokens).toBe(100);
|
330
|
-
});
|
331
|
-
|
332
|
-
it('should return undefined if tokens property is not present', () => {
|
333
|
-
const model = { properties: [] };
|
334
|
-
const tokens = getModelTokens(model);
|
335
|
-
expect(tokens).toBeUndefined();
|
336
|
-
});
|
337
|
-
});
|
338
|
-
});
|
339
240
|
});
|
@@ -32,7 +32,6 @@ class CloudflareStreamTransformer {
|
|
32
32
|
}
|
33
33
|
}
|
34
34
|
|
35
|
-
const CF_PROPERTY_NAME = 'property_id';
|
36
35
|
const DEFAULT_BASE_URL_PREFIX = 'https://api.cloudflare.com';
|
37
36
|
|
38
37
|
function fillUrl(accountID: string): string {
|
@@ -57,78 +56,9 @@ function desensitizeCloudflareUrl(url: string): string {
|
|
57
56
|
}
|
58
57
|
}
|
59
58
|
|
60
|
-
function getModelBeta(model: any): boolean {
|
61
|
-
try {
|
62
|
-
const betaProperty = model['properties'].filter(
|
63
|
-
(property: any) => property[CF_PROPERTY_NAME] === 'beta',
|
64
|
-
);
|
65
|
-
if (betaProperty.length === 1) {
|
66
|
-
return betaProperty[0]['value'] === 'true'; // This is a string now.
|
67
|
-
}
|
68
|
-
return false;
|
69
|
-
} catch {
|
70
|
-
return false;
|
71
|
-
}
|
72
|
-
}
|
73
|
-
|
74
|
-
function getModelDisplayName(model: any, beta: boolean): string {
|
75
|
-
const modelId = model['name'];
|
76
|
-
let name = modelId.split('/').at(-1)!;
|
77
|
-
if (beta) {
|
78
|
-
name += ' (Beta)';
|
79
|
-
}
|
80
|
-
return name;
|
81
|
-
}
|
82
|
-
|
83
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars, unused-imports/no-unused-vars
|
84
|
-
function getModelFunctionCalling(model: any): boolean {
|
85
|
-
try {
|
86
|
-
const fcProperty = model['properties'].filter(
|
87
|
-
(property: any) => property[CF_PROPERTY_NAME] === 'function_calling',
|
88
|
-
);
|
89
|
-
if (fcProperty.length === 1) {
|
90
|
-
return fcProperty[0]['value'] === 'true';
|
91
|
-
}
|
92
|
-
return false;
|
93
|
-
} catch {
|
94
|
-
return false;
|
95
|
-
}
|
96
|
-
}
|
97
|
-
|
98
|
-
function getModelTokens(model: any): number | undefined {
|
99
|
-
try {
|
100
|
-
const tokensProperty = model['properties'].filter(
|
101
|
-
(property: any) => property[CF_PROPERTY_NAME] === 'max_total_tokens',
|
102
|
-
);
|
103
|
-
if (tokensProperty.length === 1) {
|
104
|
-
return parseInt(tokensProperty[0]['value']);
|
105
|
-
}
|
106
|
-
return undefined;
|
107
|
-
} catch {
|
108
|
-
return undefined;
|
109
|
-
}
|
110
|
-
}
|
111
|
-
|
112
|
-
function convertModelManifest(model: any) {
|
113
|
-
const modelBeta = getModelBeta(model);
|
114
|
-
return {
|
115
|
-
description: model['description'],
|
116
|
-
displayName: getModelDisplayName(model, modelBeta),
|
117
|
-
enabled: !modelBeta,
|
118
|
-
functionCall: false, //getModelFunctionCalling(model),
|
119
|
-
id: model['name'],
|
120
|
-
tokens: getModelTokens(model),
|
121
|
-
};
|
122
|
-
}
|
123
|
-
|
124
59
|
export {
|
125
60
|
CloudflareStreamTransformer,
|
126
|
-
convertModelManifest,
|
127
61
|
DEFAULT_BASE_URL_PREFIX,
|
128
62
|
desensitizeCloudflareUrl,
|
129
63
|
fillUrl,
|
130
|
-
getModelBeta,
|
131
|
-
getModelDisplayName,
|
132
|
-
getModelFunctionCalling,
|
133
|
-
getModelTokens,
|
134
64
|
};
|
@@ -17,7 +17,9 @@ export const LobeXAI = LobeOpenAICompatibleFactory({
|
|
17
17
|
const model = m as unknown as XAIModelCard;
|
18
18
|
|
19
19
|
return {
|
20
|
-
|
20
|
+
contextWindowTokens: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.contextWindowTokens ?? undefined,
|
21
|
+
displayName: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.displayName ?? undefined,
|
22
|
+
enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.enabled || false,
|
21
23
|
functionCall: true,
|
22
24
|
id: model.id,
|
23
25
|
vision: model.id.toLowerCase().includes('vision'),
|
@@ -17,7 +17,9 @@ export const LobeZeroOneAI = LobeOpenAICompatibleFactory({
|
|
17
17
|
const model = m as unknown as ZeroOneModelCard;
|
18
18
|
|
19
19
|
return {
|
20
|
-
|
20
|
+
contextWindowTokens: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.contextWindowTokens ?? undefined,
|
21
|
+
displayName: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.displayName ?? undefined,
|
22
|
+
enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.enabled || false,
|
21
23
|
functionCall: model.id.toLowerCase().includes('fc'),
|
22
24
|
id: model.id,
|
23
25
|
vision: model.id.toLowerCase().includes('vision'),
|
@@ -53,11 +53,13 @@ export const LobeZhipuAI = LobeOpenAICompatibleFactory({
|
|
53
53
|
return modelList
|
54
54
|
.map((model) => {
|
55
55
|
return {
|
56
|
+
contextWindowTokens: LOBE_DEFAULT_MODEL_LIST.find((m) => model.modelCode === m.id)?.contextWindowTokens ?? undefined,
|
56
57
|
description: model.description,
|
57
58
|
displayName: model.modelName,
|
58
|
-
enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.modelCode
|
59
|
+
enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.modelCode === m.id)?.enabled || false,
|
59
60
|
functionCall: model.modelCode.toLowerCase().includes('glm-4') && !model.modelCode.toLowerCase().includes('glm-4v'),
|
60
61
|
id: model.modelCode,
|
62
|
+
reasoning: model.modelCode.toLowerCase().includes('glm-zero-preview'),
|
61
63
|
vision: model.modelCode.toLowerCase().includes('glm-4v'),
|
62
64
|
};
|
63
65
|
})
|