@lobehub/chat 1.133.4 → 1.133.6
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 +67 -0
- package/changelog/v1.json +24 -0
- package/locales/ar/models.json +7 -1
- package/locales/bg-BG/models.json +7 -1
- package/locales/de-DE/models.json +7 -1
- package/locales/en-US/models.json +7 -1
- package/locales/es-ES/models.json +7 -1
- package/locales/fa-IR/models.json +7 -1
- package/locales/fr-FR/models.json +7 -1
- package/locales/it-IT/models.json +7 -1
- package/locales/ja-JP/models.json +7 -1
- package/locales/ko-KR/models.json +7 -1
- package/locales/nl-NL/models.json +7 -1
- package/locales/pl-PL/models.json +7 -1
- package/locales/pt-BR/models.json +7 -1
- package/locales/ru-RU/models.json +7 -1
- package/locales/tr-TR/models.json +7 -1
- package/locales/vi-VN/models.json +7 -1
- package/locales/zh-CN/models.json +7 -1
- package/locales/zh-TW/models.json +7 -1
- package/package.json +2 -2
- package/packages/database/src/models/__tests__/aiModel.test.ts +3 -0
- package/packages/database/src/models/aiModel.ts +18 -2
- package/packages/model-bank/src/aiModels/aihubmix.ts +41 -1
- package/packages/model-bank/src/aiModels/deepseek.ts +12 -12
- package/packages/model-bank/src/aiModels/google.ts +225 -2
- package/packages/model-bank/src/aiModels/hunyuan.ts +39 -15
- package/packages/model-bank/src/aiModels/novita.ts +17 -3
- package/packages/model-bank/src/aiModels/siliconcloud.ts +68 -3
- package/packages/model-bank/src/types/aiModel.ts +13 -9
- package/packages/model-runtime/src/core/ModelRuntime.ts +1 -1
- package/packages/model-runtime/src/core/RouterRuntime/createRuntime.ts +0 -1
- package/packages/model-runtime/src/core/streams/protocol.ts +12 -12
- package/packages/model-runtime/src/providers/google/createImage.ts +13 -4
- package/packages/model-runtime/src/providers/google/index.test.ts +39 -1
- package/packages/model-runtime/src/providers/google/index.ts +62 -22
- package/packages/model-runtime/src/utils/modelParse.ts +1 -1
- package/packages/types/src/auth.ts +2 -0
- package/src/app/[variants]/(main)/settings/provider/features/ModelList/ModelItem.tsx +6 -3
- package/src/config/modelProviders/deepseek.ts +4 -7
- package/src/features/ChatInput/ActionBar/Model/ControlsForm.tsx +2 -2
- package/src/features/ChatInput/ActionBar/Model/ReasoningTokenSlider.tsx +12 -2
- package/src/features/ChatInput/ActionBar/Model/ThinkingBudgetSlider.tsx +29 -3
- package/src/server/modules/ModelRuntime/index.test.ts +13 -0
- package/src/server/modules/ModelRuntime/index.ts +4 -2
- package/src/server/routers/lambda/aiModel.test.ts +2 -0
- package/src/services/__tests__/models.test.ts +95 -5
- package/src/services/_auth.ts +8 -1
- package/src/services/chat/clientModelRuntime.test.ts +68 -17
- package/src/services/chat/clientModelRuntime.ts +15 -4
- package/src/services/chat/helper.ts +11 -0
- package/src/services/chat/index.ts +11 -15
- package/src/services/models.ts +14 -4
- package/packages/model-runtime/src/utils/usageConverter.test.ts +0 -351
- package/packages/model-runtime/src/utils/usageConverter.ts +0 -122
|
@@ -151,12 +151,14 @@ describe('aiModelRouter', () => {
|
|
|
151
151
|
id: 'model-1',
|
|
152
152
|
providerId: 'provider-1',
|
|
153
153
|
enabled: true,
|
|
154
|
+
type: 'embedding',
|
|
154
155
|
});
|
|
155
156
|
|
|
156
157
|
expect(mockToggle).toHaveBeenCalledWith({
|
|
157
158
|
id: 'model-1',
|
|
158
159
|
providerId: 'provider-1',
|
|
159
160
|
enabled: true,
|
|
161
|
+
type: 'embedding',
|
|
160
162
|
});
|
|
161
163
|
});
|
|
162
164
|
|
|
@@ -1,21 +1,111 @@
|
|
|
1
|
-
import { Mock, describe, expect, it, vi } from 'vitest';
|
|
1
|
+
import { Mock, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
2
|
|
|
3
|
+
import { aiProviderSelectors } from '@/store/aiInfra';
|
|
4
|
+
|
|
5
|
+
import { createHeaderWithAuth } from '../_auth';
|
|
6
|
+
import { initializeWithClientStore } from '../chat/clientModelRuntime';
|
|
7
|
+
import { resolveRuntimeProvider } from '../chat/helper';
|
|
3
8
|
import { ModelsService } from '../models';
|
|
4
9
|
|
|
5
10
|
vi.stubGlobal('fetch', vi.fn());
|
|
6
11
|
|
|
7
|
-
|
|
12
|
+
vi.mock('@/const/version', () => ({
|
|
13
|
+
isDeprecatedEdition: false,
|
|
14
|
+
}));
|
|
15
|
+
|
|
16
|
+
vi.mock('../_auth', () => ({
|
|
17
|
+
createHeaderWithAuth: vi.fn(async () => ({})),
|
|
18
|
+
}));
|
|
19
|
+
|
|
20
|
+
vi.mock('../chat/helper', () => ({
|
|
21
|
+
resolveRuntimeProvider: vi.fn((provider: string) => provider),
|
|
22
|
+
}));
|
|
23
|
+
|
|
24
|
+
vi.mock('../chat/clientModelRuntime', () => ({
|
|
25
|
+
initializeWithClientStore: vi.fn(),
|
|
26
|
+
}));
|
|
27
|
+
|
|
28
|
+
vi.mock('@/store/aiInfra', () => ({
|
|
29
|
+
aiProviderSelectors: {
|
|
30
|
+
isProviderFetchOnClient: () => () => false,
|
|
31
|
+
},
|
|
32
|
+
getAiInfraStoreState: () => ({}),
|
|
33
|
+
}));
|
|
8
34
|
|
|
35
|
+
vi.mock('@/store/user', () => ({
|
|
36
|
+
useUserStore: {
|
|
37
|
+
getState: vi.fn(),
|
|
38
|
+
},
|
|
39
|
+
}));
|
|
40
|
+
|
|
41
|
+
vi.mock('@/store/user/selectors', () => ({
|
|
42
|
+
modelConfigSelectors: {
|
|
43
|
+
isProviderFetchOnClient: () => () => false,
|
|
44
|
+
},
|
|
45
|
+
}));
|
|
46
|
+
|
|
47
|
+
// 创建一个测试用的 ModelsService 实例
|
|
9
48
|
const modelsService = new ModelsService();
|
|
10
49
|
|
|
50
|
+
const mockedCreateHeaderWithAuth = vi.mocked(createHeaderWithAuth);
|
|
51
|
+
const mockedResolveRuntimeProvider = vi.mocked(resolveRuntimeProvider);
|
|
52
|
+
const mockedInitializeWithClientStore = vi.mocked(initializeWithClientStore);
|
|
53
|
+
|
|
11
54
|
describe('ModelsService', () => {
|
|
55
|
+
beforeEach(() => {
|
|
56
|
+
(fetch as Mock).mockClear();
|
|
57
|
+
mockedCreateHeaderWithAuth.mockClear();
|
|
58
|
+
mockedResolveRuntimeProvider.mockReset();
|
|
59
|
+
mockedResolveRuntimeProvider.mockImplementation((provider: string) => provider);
|
|
60
|
+
mockedInitializeWithClientStore.mockClear();
|
|
61
|
+
});
|
|
62
|
+
|
|
12
63
|
describe('getModels', () => {
|
|
13
|
-
it('should call the
|
|
14
|
-
(fetch as Mock).mockResolvedValueOnce(
|
|
64
|
+
it('should call the endpoint for runtime provider when server fetching', async () => {
|
|
65
|
+
(fetch as Mock).mockResolvedValueOnce(
|
|
66
|
+
new Response(JSON.stringify({ models: [] }), { status: 200 }),
|
|
67
|
+
);
|
|
15
68
|
|
|
16
69
|
await modelsService.getModels('openai');
|
|
17
70
|
|
|
18
|
-
expect(
|
|
71
|
+
expect(mockedResolveRuntimeProvider).toHaveBeenCalledWith('openai');
|
|
72
|
+
expect(fetch).toHaveBeenCalledWith('/webapi/models/openai', { headers: {} });
|
|
73
|
+
expect(mockedInitializeWithClientStore).not.toHaveBeenCalled();
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('should map custom provider to runtime provider endpoint', async () => {
|
|
77
|
+
mockedResolveRuntimeProvider.mockImplementation(() => 'openai');
|
|
78
|
+
(fetch as Mock).mockResolvedValueOnce(
|
|
79
|
+
new Response(JSON.stringify({ models: [] }), { status: 200 }),
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
await modelsService.getModels('custom-provider');
|
|
83
|
+
|
|
84
|
+
expect(mockedResolveRuntimeProvider).toHaveBeenCalledWith('custom-provider');
|
|
85
|
+
expect(fetch).toHaveBeenCalledWith('/webapi/models/openai', { headers: {} });
|
|
86
|
+
expect(mockedInitializeWithClientStore).not.toHaveBeenCalled();
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('should fetch models on client when isProviderFetchOnClient is true', async () => {
|
|
90
|
+
// Mock isProviderFetchOnClient to return true
|
|
91
|
+
const spyIsClient = vi
|
|
92
|
+
.spyOn(aiProviderSelectors, 'isProviderFetchOnClient')
|
|
93
|
+
.mockReturnValue(() => true);
|
|
94
|
+
// Mock initializeWithClientStore to return a runtime with a models() method
|
|
95
|
+
const mockModels = vi.fn().mockResolvedValue({ models: ['model1', 'model2'] });
|
|
96
|
+
mockedInitializeWithClientStore.mockResolvedValue({ models: mockModels } as any);
|
|
97
|
+
|
|
98
|
+
const result = await modelsService.getModels('openai');
|
|
99
|
+
|
|
100
|
+
expect(spyIsClient).toHaveBeenCalledWith('openai');
|
|
101
|
+
expect(mockedInitializeWithClientStore).toHaveBeenCalledWith({
|
|
102
|
+
provider: 'openai',
|
|
103
|
+
runtimeProvider: 'openai',
|
|
104
|
+
});
|
|
105
|
+
expect(mockModels).toHaveBeenCalled();
|
|
106
|
+
expect(result).toEqual({ models: ['model1', 'model2'] });
|
|
107
|
+
|
|
108
|
+
spyIsClient.mockRestore();
|
|
19
109
|
});
|
|
20
110
|
});
|
|
21
111
|
});
|
package/src/services/_auth.ts
CHANGED
|
@@ -14,6 +14,8 @@ import { useUserStore } from '@/store/user';
|
|
|
14
14
|
import { keyVaultsConfigSelectors, userProfileSelectors } from '@/store/user/selectors';
|
|
15
15
|
import { obfuscatePayloadWithXOR } from '@/utils/client/xor-obfuscation';
|
|
16
16
|
|
|
17
|
+
import { resolveRuntimeProvider } from './chat/helper';
|
|
18
|
+
|
|
17
19
|
export const getProviderAuthPayload = (
|
|
18
20
|
provider: string,
|
|
19
21
|
keyVaults: OpenAICompatibleKeyVault &
|
|
@@ -104,7 +106,12 @@ export const createPayloadWithKeyVaults = (provider: string) => {
|
|
|
104
106
|
keyVaults = aiProviderSelectors.providerKeyVaults(provider)(useAiInfraStore.getState()) || {};
|
|
105
107
|
}
|
|
106
108
|
|
|
107
|
-
|
|
109
|
+
const runtimeProvider = resolveRuntimeProvider(provider);
|
|
110
|
+
|
|
111
|
+
return {
|
|
112
|
+
...getProviderAuthPayload(runtimeProvider, keyVaults as any),
|
|
113
|
+
runtimeProvider,
|
|
114
|
+
};
|
|
108
115
|
};
|
|
109
116
|
|
|
110
117
|
export const createXorKeyVaultsPayload = (provider: string) => {
|
|
@@ -108,7 +108,10 @@ describe('ModelRuntimeOnClient', () => {
|
|
|
108
108
|
},
|
|
109
109
|
},
|
|
110
110
|
} as UserSettingsState) as unknown as UserStore;
|
|
111
|
-
const runtime = await initializeWithClientStore(
|
|
111
|
+
const runtime = await initializeWithClientStore({
|
|
112
|
+
payload: {},
|
|
113
|
+
provider: ModelProvider.OpenAI,
|
|
114
|
+
});
|
|
112
115
|
expect(runtime).toBeInstanceOf(ModelRuntime);
|
|
113
116
|
expect(runtime['_runtime']).toBeInstanceOf(LobeOpenAI);
|
|
114
117
|
expect(runtime['_runtime'].baseURL).toBe('user-openai-endpoint');
|
|
@@ -127,7 +130,10 @@ describe('ModelRuntimeOnClient', () => {
|
|
|
127
130
|
},
|
|
128
131
|
} as UserSettingsState) as unknown as UserStore;
|
|
129
132
|
|
|
130
|
-
const runtime = await initializeWithClientStore(
|
|
133
|
+
const runtime = await initializeWithClientStore({
|
|
134
|
+
payload: {},
|
|
135
|
+
provider: ModelProvider.Azure,
|
|
136
|
+
});
|
|
131
137
|
expect(runtime).toBeInstanceOf(ModelRuntime);
|
|
132
138
|
expect(runtime['_runtime']).toBeInstanceOf(LobeAzureOpenAI);
|
|
133
139
|
});
|
|
@@ -142,7 +148,10 @@ describe('ModelRuntimeOnClient', () => {
|
|
|
142
148
|
},
|
|
143
149
|
},
|
|
144
150
|
} as UserSettingsState) as unknown as UserStore;
|
|
145
|
-
const runtime = await initializeWithClientStore(
|
|
151
|
+
const runtime = await initializeWithClientStore({
|
|
152
|
+
payload: {},
|
|
153
|
+
provider: ModelProvider.Google,
|
|
154
|
+
});
|
|
146
155
|
expect(runtime).toBeInstanceOf(ModelRuntime);
|
|
147
156
|
expect(runtime['_runtime']).toBeInstanceOf(LobeGoogleAI);
|
|
148
157
|
});
|
|
@@ -157,7 +166,10 @@ describe('ModelRuntimeOnClient', () => {
|
|
|
157
166
|
},
|
|
158
167
|
},
|
|
159
168
|
} as UserSettingsState) as unknown as UserStore;
|
|
160
|
-
const runtime = await initializeWithClientStore(
|
|
169
|
+
const runtime = await initializeWithClientStore({
|
|
170
|
+
payload: {},
|
|
171
|
+
provider: ModelProvider.Moonshot,
|
|
172
|
+
});
|
|
161
173
|
expect(runtime).toBeInstanceOf(ModelRuntime);
|
|
162
174
|
expect(runtime['_runtime']).toBeInstanceOf(LobeMoonshotAI);
|
|
163
175
|
});
|
|
@@ -174,7 +186,10 @@ describe('ModelRuntimeOnClient', () => {
|
|
|
174
186
|
},
|
|
175
187
|
},
|
|
176
188
|
} as UserSettingsState) as unknown as UserStore;
|
|
177
|
-
const runtime = await initializeWithClientStore(
|
|
189
|
+
const runtime = await initializeWithClientStore({
|
|
190
|
+
payload: {},
|
|
191
|
+
provider: ModelProvider.Bedrock,
|
|
192
|
+
});
|
|
178
193
|
expect(runtime).toBeInstanceOf(ModelRuntime);
|
|
179
194
|
expect(runtime['_runtime']).toBeInstanceOf(LobeBedrockAI);
|
|
180
195
|
});
|
|
@@ -189,7 +204,10 @@ describe('ModelRuntimeOnClient', () => {
|
|
|
189
204
|
},
|
|
190
205
|
},
|
|
191
206
|
} as UserSettingsState) as unknown as UserStore;
|
|
192
|
-
const runtime = await initializeWithClientStore(
|
|
207
|
+
const runtime = await initializeWithClientStore({
|
|
208
|
+
payload: {},
|
|
209
|
+
provider: ModelProvider.Ollama,
|
|
210
|
+
});
|
|
193
211
|
expect(runtime).toBeInstanceOf(ModelRuntime);
|
|
194
212
|
expect(runtime['_runtime']).toBeInstanceOf(LobeOllamaAI);
|
|
195
213
|
});
|
|
@@ -204,7 +222,10 @@ describe('ModelRuntimeOnClient', () => {
|
|
|
204
222
|
},
|
|
205
223
|
},
|
|
206
224
|
} as UserSettingsState) as unknown as UserStore;
|
|
207
|
-
const runtime = await initializeWithClientStore(
|
|
225
|
+
const runtime = await initializeWithClientStore({
|
|
226
|
+
payload: {},
|
|
227
|
+
provider: ModelProvider.Perplexity,
|
|
228
|
+
});
|
|
208
229
|
expect(runtime).toBeInstanceOf(ModelRuntime);
|
|
209
230
|
expect(runtime['_runtime']).toBeInstanceOf(LobePerplexityAI);
|
|
210
231
|
});
|
|
@@ -219,7 +240,10 @@ describe('ModelRuntimeOnClient', () => {
|
|
|
219
240
|
},
|
|
220
241
|
},
|
|
221
242
|
} as UserSettingsState) as unknown as UserStore;
|
|
222
|
-
const runtime = await initializeWithClientStore(
|
|
243
|
+
const runtime = await initializeWithClientStore({
|
|
244
|
+
payload: {},
|
|
245
|
+
provider: ModelProvider.Anthropic,
|
|
246
|
+
});
|
|
223
247
|
expect(runtime).toBeInstanceOf(ModelRuntime);
|
|
224
248
|
expect(runtime['_runtime']).toBeInstanceOf(LobeAnthropicAI);
|
|
225
249
|
});
|
|
@@ -234,7 +258,10 @@ describe('ModelRuntimeOnClient', () => {
|
|
|
234
258
|
},
|
|
235
259
|
},
|
|
236
260
|
} as UserSettingsState) as unknown as UserStore;
|
|
237
|
-
const runtime = await initializeWithClientStore(
|
|
261
|
+
const runtime = await initializeWithClientStore({
|
|
262
|
+
payload: {},
|
|
263
|
+
provider: ModelProvider.Mistral,
|
|
264
|
+
});
|
|
238
265
|
expect(runtime).toBeInstanceOf(ModelRuntime);
|
|
239
266
|
expect(runtime['_runtime']).toBeInstanceOf(LobeMistralAI);
|
|
240
267
|
});
|
|
@@ -249,7 +276,10 @@ describe('ModelRuntimeOnClient', () => {
|
|
|
249
276
|
},
|
|
250
277
|
},
|
|
251
278
|
} as UserSettingsState) as unknown as UserStore;
|
|
252
|
-
const runtime = await initializeWithClientStore(
|
|
279
|
+
const runtime = await initializeWithClientStore({
|
|
280
|
+
payload: {},
|
|
281
|
+
provider: ModelProvider.OpenRouter,
|
|
282
|
+
});
|
|
253
283
|
expect(runtime).toBeInstanceOf(ModelRuntime);
|
|
254
284
|
expect(runtime['_runtime']).toBeInstanceOf(LobeOpenRouterAI);
|
|
255
285
|
});
|
|
@@ -264,7 +294,10 @@ describe('ModelRuntimeOnClient', () => {
|
|
|
264
294
|
},
|
|
265
295
|
},
|
|
266
296
|
} as UserSettingsState) as unknown as UserStore;
|
|
267
|
-
const runtime = await initializeWithClientStore(
|
|
297
|
+
const runtime = await initializeWithClientStore({
|
|
298
|
+
payload: {},
|
|
299
|
+
provider: ModelProvider.TogetherAI,
|
|
300
|
+
});
|
|
268
301
|
expect(runtime).toBeInstanceOf(ModelRuntime);
|
|
269
302
|
expect(runtime['_runtime']).toBeInstanceOf(LobeTogetherAI);
|
|
270
303
|
});
|
|
@@ -279,7 +312,10 @@ describe('ModelRuntimeOnClient', () => {
|
|
|
279
312
|
},
|
|
280
313
|
},
|
|
281
314
|
} as UserSettingsState) as unknown as UserStore;
|
|
282
|
-
const runtime = await initializeWithClientStore(
|
|
315
|
+
const runtime = await initializeWithClientStore({
|
|
316
|
+
payload: {},
|
|
317
|
+
provider: ModelProvider.ZeroOne,
|
|
318
|
+
});
|
|
283
319
|
expect(runtime).toBeInstanceOf(ModelRuntime);
|
|
284
320
|
expect(runtime['_runtime']).toBeInstanceOf(LobeZeroOneAI);
|
|
285
321
|
});
|
|
@@ -295,7 +331,10 @@ describe('ModelRuntimeOnClient', () => {
|
|
|
295
331
|
},
|
|
296
332
|
},
|
|
297
333
|
} as UserSettingsState) as unknown as UserStore;
|
|
298
|
-
const runtime = await initializeWithClientStore(
|
|
334
|
+
const runtime = await initializeWithClientStore({
|
|
335
|
+
payload: {},
|
|
336
|
+
provider: ModelProvider.Groq,
|
|
337
|
+
});
|
|
299
338
|
expect(runtime).toBeInstanceOf(ModelRuntime);
|
|
300
339
|
const lobeOpenAICompatibleInstance = runtime['_runtime'] as LobeOpenAICompatibleRuntime;
|
|
301
340
|
expect(lobeOpenAICompatibleInstance).toBeInstanceOf(LobeGroq);
|
|
@@ -314,7 +353,10 @@ describe('ModelRuntimeOnClient', () => {
|
|
|
314
353
|
},
|
|
315
354
|
},
|
|
316
355
|
} as UserSettingsState) as unknown as UserStore;
|
|
317
|
-
const runtime = await initializeWithClientStore(
|
|
356
|
+
const runtime = await initializeWithClientStore({
|
|
357
|
+
payload: {},
|
|
358
|
+
provider: ModelProvider.DeepSeek,
|
|
359
|
+
});
|
|
318
360
|
expect(runtime).toBeInstanceOf(ModelRuntime);
|
|
319
361
|
expect(runtime['_runtime']).toBeInstanceOf(LobeDeepSeekAI);
|
|
320
362
|
});
|
|
@@ -329,7 +371,10 @@ describe('ModelRuntimeOnClient', () => {
|
|
|
329
371
|
},
|
|
330
372
|
},
|
|
331
373
|
} as UserSettingsState) as unknown as UserStore;
|
|
332
|
-
const runtime = await initializeWithClientStore(
|
|
374
|
+
const runtime = await initializeWithClientStore({
|
|
375
|
+
payload: {},
|
|
376
|
+
provider: ModelProvider.Qwen,
|
|
377
|
+
});
|
|
333
378
|
expect(runtime).toBeInstanceOf(ModelRuntime);
|
|
334
379
|
expect(runtime['_runtime']).toBeInstanceOf(LobeQwenAI);
|
|
335
380
|
});
|
|
@@ -349,7 +394,10 @@ describe('ModelRuntimeOnClient', () => {
|
|
|
349
394
|
},
|
|
350
395
|
},
|
|
351
396
|
} as any as UserSettingsState) as unknown as UserStore;
|
|
352
|
-
const runtime = await initializeWithClientStore(
|
|
397
|
+
const runtime = await initializeWithClientStore({
|
|
398
|
+
payload: {},
|
|
399
|
+
provider: 'unknown' as ModelProvider,
|
|
400
|
+
});
|
|
353
401
|
expect(runtime).toBeInstanceOf(ModelRuntime);
|
|
354
402
|
expect(runtime['_runtime']).toBeInstanceOf(LobeOpenAI);
|
|
355
403
|
});
|
|
@@ -376,7 +424,10 @@ describe('ModelRuntimeOnClient', () => {
|
|
|
376
424
|
},
|
|
377
425
|
},
|
|
378
426
|
} as UserSettingsState) as unknown as UserStore;
|
|
379
|
-
const runtime = await initializeWithClientStore(
|
|
427
|
+
const runtime = await initializeWithClientStore({
|
|
428
|
+
payload: {},
|
|
429
|
+
provider: ModelProvider.ZhiPu,
|
|
430
|
+
});
|
|
380
431
|
expect(runtime).toBeInstanceOf(ModelRuntime);
|
|
381
432
|
expect(runtime['_runtime']).toBeInstanceOf(LobeZhipuAI);
|
|
382
433
|
});
|
|
@@ -2,15 +2,26 @@ import { ModelRuntime } from '@lobechat/model-runtime';
|
|
|
2
2
|
|
|
3
3
|
import { createPayloadWithKeyVaults } from '../_auth';
|
|
4
4
|
|
|
5
|
+
export interface InitializeWithClientStoreOptions {
|
|
6
|
+
payload?: any;
|
|
7
|
+
provider: string;
|
|
8
|
+
runtimeProvider?: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
5
11
|
/**
|
|
6
12
|
* Initializes the AgentRuntime with the client store.
|
|
7
|
-
* @param provider -
|
|
8
|
-
* @param
|
|
13
|
+
* @param options.provider - Provider identifier used to resolve key vaults.
|
|
14
|
+
* @param options.runtimeProvider - Actual runtime implementation key (defaults to provider).
|
|
15
|
+
* @param options.payload - Additional initialization payload.
|
|
9
16
|
* @returns The initialized AgentRuntime instance
|
|
10
17
|
*
|
|
11
18
|
* **Note**: if you try to fetch directly, use `fetchOnClient` instead.
|
|
12
19
|
*/
|
|
13
|
-
export const initializeWithClientStore = (
|
|
20
|
+
export const initializeWithClientStore = ({
|
|
21
|
+
provider,
|
|
22
|
+
runtimeProvider,
|
|
23
|
+
payload,
|
|
24
|
+
}: InitializeWithClientStoreOptions) => {
|
|
14
25
|
/**
|
|
15
26
|
* Since #5267, we map parameters for client-fetch in function `getProviderAuthPayload`
|
|
16
27
|
* which called by `createPayloadWithKeyVaults` below.
|
|
@@ -26,7 +37,7 @@ export const initializeWithClientStore = (provider: string, payload?: any) => {
|
|
|
26
37
|
* Configuration override order:
|
|
27
38
|
* payload -> providerAuthPayload -> commonOptions
|
|
28
39
|
*/
|
|
29
|
-
return ModelRuntime.initializeWithProvider(provider, {
|
|
40
|
+
return ModelRuntime.initializeWithProvider(runtimeProvider ?? provider, {
|
|
30
41
|
...commonOptions,
|
|
31
42
|
...providerAuthPayload,
|
|
32
43
|
...payload,
|
|
@@ -54,3 +54,14 @@ export const isEnableFetchOnClient = (provider: string) => {
|
|
|
54
54
|
return aiProviderSelectors.isProviderFetchOnClient(provider)(getAiInfraStoreState());
|
|
55
55
|
}
|
|
56
56
|
};
|
|
57
|
+
|
|
58
|
+
export const resolveRuntimeProvider = (provider: string) => {
|
|
59
|
+
if (isDeprecatedEdition) return provider;
|
|
60
|
+
|
|
61
|
+
const isBuiltin = Object.values(ModelProvider).includes(provider as any);
|
|
62
|
+
if (isBuiltin) return provider;
|
|
63
|
+
|
|
64
|
+
const providerConfig = aiProviderSelectors.providerConfigById(provider)(getAiInfraStoreState());
|
|
65
|
+
|
|
66
|
+
return providerConfig?.settings.sdkType || 'openai';
|
|
67
|
+
};
|
|
@@ -6,7 +6,7 @@ import { ModelProvider } from 'model-bank';
|
|
|
6
6
|
|
|
7
7
|
import { enableAuth } from '@/const/auth';
|
|
8
8
|
import { DEFAULT_AGENT_CONFIG } from '@/const/settings';
|
|
9
|
-
import {
|
|
9
|
+
import { isDesktop } from '@/const/version';
|
|
10
10
|
import { getSearchConfig } from '@/helpers/getSearchConfig';
|
|
11
11
|
import { createChatToolsEngine, createToolsEngine } from '@/helpers/toolEngineering';
|
|
12
12
|
import { getAgentStoreState } from '@/store/agent';
|
|
@@ -38,7 +38,7 @@ import { createHeaderWithAuth } from '../_auth';
|
|
|
38
38
|
import { API_ENDPOINTS } from '../_url';
|
|
39
39
|
import { initializeWithClientStore } from './clientModelRuntime';
|
|
40
40
|
import { contextEngineering } from './contextEngineering';
|
|
41
|
-
import { findDeploymentName, isEnableFetchOnClient } from './helper';
|
|
41
|
+
import { findDeploymentName, isEnableFetchOnClient, resolveRuntimeProvider } from './helper';
|
|
42
42
|
import { FetchOptions } from './types';
|
|
43
43
|
|
|
44
44
|
interface GetChatCompletionPayload extends Partial<Omit<ChatStreamPayload, 'messages'>> {
|
|
@@ -268,6 +268,8 @@ class ChatService {
|
|
|
268
268
|
{ ...res, apiMode, model },
|
|
269
269
|
);
|
|
270
270
|
|
|
271
|
+
const sdkType = resolveRuntimeProvider(provider);
|
|
272
|
+
|
|
271
273
|
/**
|
|
272
274
|
* Use browser agent runtime
|
|
273
275
|
*/
|
|
@@ -287,7 +289,7 @@ class ChatService {
|
|
|
287
289
|
*/
|
|
288
290
|
fetcher = async () => {
|
|
289
291
|
try {
|
|
290
|
-
return await this.fetchOnClient({ payload, provider, signal });
|
|
292
|
+
return await this.fetchOnClient({ payload, provider, runtimeProvider: sdkType, signal });
|
|
291
293
|
} catch (e) {
|
|
292
294
|
const {
|
|
293
295
|
errorType = ChatErrorType.BadRequest,
|
|
@@ -314,17 +316,6 @@ class ChatService {
|
|
|
314
316
|
const { DEFAULT_MODEL_PROVIDER_LIST } = await import('@/config/modelProviders');
|
|
315
317
|
const providerConfig = DEFAULT_MODEL_PROVIDER_LIST.find((item) => item.id === provider);
|
|
316
318
|
|
|
317
|
-
let sdkType = provider;
|
|
318
|
-
const isBuiltin = Object.values(ModelProvider).includes(provider as any);
|
|
319
|
-
|
|
320
|
-
// TODO: remove `!isDeprecatedEdition` condition in V2.0
|
|
321
|
-
if (!isDeprecatedEdition && !isBuiltin) {
|
|
322
|
-
const providerConfig =
|
|
323
|
-
aiProviderSelectors.providerConfigById(provider)(getAiInfraStoreState());
|
|
324
|
-
|
|
325
|
-
sdkType = providerConfig?.settings.sdkType || 'openai';
|
|
326
|
-
}
|
|
327
|
-
|
|
328
319
|
const userPreferTransitionMode =
|
|
329
320
|
userGeneralSettingsSelectors.transitionMode(getUserStoreState());
|
|
330
321
|
|
|
@@ -461,6 +452,7 @@ class ChatService {
|
|
|
461
452
|
private fetchOnClient = async (params: {
|
|
462
453
|
payload: Partial<ChatStreamPayload>;
|
|
463
454
|
provider: string;
|
|
455
|
+
runtimeProvider: string;
|
|
464
456
|
signal?: AbortSignal;
|
|
465
457
|
}) => {
|
|
466
458
|
/**
|
|
@@ -471,7 +463,11 @@ class ChatService {
|
|
|
471
463
|
throw AgentRuntimeError.createError(ChatErrorType.InvalidAccessCode);
|
|
472
464
|
}
|
|
473
465
|
|
|
474
|
-
const agentRuntime = await initializeWithClientStore(
|
|
466
|
+
const agentRuntime = await initializeWithClientStore({
|
|
467
|
+
payload: params.payload,
|
|
468
|
+
provider: params.provider,
|
|
469
|
+
runtimeProvider: params.runtimeProvider,
|
|
470
|
+
});
|
|
475
471
|
const data = params.payload as ChatStreamPayload;
|
|
476
472
|
|
|
477
473
|
return agentRuntime.chat(data, { signal: params.signal });
|
package/src/services/models.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { getMessageError } from '@/utils/fetch';
|
|
|
8
8
|
|
|
9
9
|
import { API_ENDPOINTS } from './_url';
|
|
10
10
|
import { initializeWithClientStore } from './chat/clientModelRuntime';
|
|
11
|
+
import { resolveRuntimeProvider } from './chat/helper';
|
|
11
12
|
|
|
12
13
|
const isEnableFetchOnClient = (provider: string) => {
|
|
13
14
|
// TODO: remove this condition in V2.0
|
|
@@ -41,17 +42,22 @@ export class ModelsService {
|
|
|
41
42
|
headers: { 'Content-Type': 'application/json' },
|
|
42
43
|
provider,
|
|
43
44
|
});
|
|
45
|
+
|
|
46
|
+
const runtimeProvider = resolveRuntimeProvider(provider);
|
|
44
47
|
try {
|
|
45
48
|
/**
|
|
46
49
|
* Use browser agent runtime
|
|
47
50
|
*/
|
|
48
51
|
const enableFetchOnClient = isEnableFetchOnClient(provider);
|
|
49
52
|
if (enableFetchOnClient) {
|
|
50
|
-
const agentRuntime = await initializeWithClientStore(
|
|
53
|
+
const agentRuntime = await initializeWithClientStore({
|
|
54
|
+
provider,
|
|
55
|
+
runtimeProvider,
|
|
56
|
+
});
|
|
51
57
|
return agentRuntime.models();
|
|
52
58
|
}
|
|
53
59
|
|
|
54
|
-
const res = await fetch(API_ENDPOINTS.models(
|
|
60
|
+
const res = await fetch(API_ENDPOINTS.models(runtimeProvider), { headers });
|
|
55
61
|
if (!res.ok) return;
|
|
56
62
|
|
|
57
63
|
return res.json();
|
|
@@ -77,15 +83,19 @@ export class ModelsService {
|
|
|
77
83
|
provider,
|
|
78
84
|
});
|
|
79
85
|
|
|
86
|
+
const runtimeProvider = resolveRuntimeProvider(provider);
|
|
80
87
|
const enableFetchOnClient = isEnableFetchOnClient(provider);
|
|
81
88
|
|
|
82
89
|
console.log('enableFetchOnClient:', enableFetchOnClient);
|
|
83
90
|
let res: Response;
|
|
84
91
|
if (enableFetchOnClient) {
|
|
85
|
-
const agentRuntime = await initializeWithClientStore(
|
|
92
|
+
const agentRuntime = await initializeWithClientStore({
|
|
93
|
+
provider,
|
|
94
|
+
runtimeProvider,
|
|
95
|
+
});
|
|
86
96
|
res = (await agentRuntime.pullModel({ model }, { signal }))!;
|
|
87
97
|
} else {
|
|
88
|
-
res = await fetch(API_ENDPOINTS.modelPull(
|
|
98
|
+
res = await fetch(API_ENDPOINTS.modelPull(runtimeProvider), {
|
|
89
99
|
body: JSON.stringify({ model }),
|
|
90
100
|
headers,
|
|
91
101
|
method: 'POST',
|