@lobehub/lobehub 2.0.0-next.67 → 2.0.0-next.69
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 +50 -0
- package/changelog/v1.json +18 -0
- package/package.json +2 -8
- package/packages/const/src/version.ts +0 -5
- package/packages/database/src/models/__tests__/chunk.test.ts +38 -0
- package/packages/model-runtime/src/core/streams/ollama.test.ts +67 -0
- package/packages/model-runtime/src/core/streams/ollama.ts +5 -5
- package/src/app/(backend)/api/webhooks/clerk/route.ts +1 -2
- package/src/app/[variants]/(main)/(mobile)/me/(home)/__tests__/useCategory.test.tsx +0 -20
- package/src/app/[variants]/(main)/(mobile)/me/(home)/features/useCategory.tsx +4 -33
- package/src/app/[variants]/(main)/(mobile)/me/profile/features/Category.tsx +18 -23
- package/src/app/[variants]/(main)/(mobile)/me/settings/features/useCategory.tsx +5 -15
- package/src/app/[variants]/(main)/discover/(detail)/provider/[...slugs]/features/Sidebar/ActionButton/ProviderConfig.tsx +4 -11
- package/src/app/[variants]/(main)/image/@menu/features/ConfigPanel/components/ModelSelect/index.tsx +12 -27
- package/src/app/[variants]/(main)/image/layout.tsx +0 -4
- package/src/app/[variants]/(main)/profile/hooks/useCategory.tsx +10 -13
- package/src/app/[variants]/(main)/profile/stats/features/ShareButton/Preview.tsx +2 -14
- package/src/app/[variants]/(main)/settings/_layout/Desktop/index.tsx +2 -3
- package/src/app/[variants]/(main)/settings/_layout/SettingsContent.tsx +1 -12
- package/src/app/[variants]/(main)/settings/_layout/type.ts +0 -1
- package/src/app/[variants]/(main)/settings/hooks/useCategory.tsx +8 -16
- package/src/app/[variants]/(main)/settings/page.tsx +3 -7
- package/src/app/[variants]/(main)/settings/provider/features/ProviderConfig/index.tsx +2 -4
- package/src/app/[variants]/(main)/settings/storage/index.tsx +1 -9
- package/src/app/[variants]/(main)/settings/system-agent/index.tsx +1 -2
- package/src/components/InvalidAPIKey/APIKeyForm/useApiKey.ts +0 -12
- package/src/config/featureFlags/schema.test.ts +1 -3
- package/src/config/featureFlags/schema.ts +0 -3
- package/src/features/ChatInput/ActionBar/Knowledge/index.tsx +2 -3
- package/src/features/ChatInput/ActionBar/Search/index.tsx +5 -7
- package/src/features/ChatInput/ActionBar/Upload/index.tsx +1 -3
- package/src/features/Conversation/Messages/Assistant/index.tsx +1 -1
- package/src/features/Conversation/components/ShareMessageModal/index.tsx +3 -8
- package/src/features/DevPanel/PostgresViewer/usePgTable.ts +3 -11
- package/src/features/ModelSwitchPanel/index.tsx +9 -24
- package/src/features/ShareModal/index.tsx +7 -13
- package/src/features/User/UserPanel/PanelContent.tsx +6 -8
- package/src/hooks/useCheckPluginsIsInstalled.ts +1 -4
- package/src/hooks/useFetchGroups.ts +1 -4
- package/src/hooks/useFetchInstalledPlugins.ts +1 -4
- package/src/hooks/useFetchMessages.ts +1 -4
- package/src/hooks/useFetchSessions.ts +1 -4
- package/src/hooks/useFetchThreads.ts +1 -5
- package/src/hooks/useFetchTopics.ts +1 -4
- package/src/hooks/useInterceptingRoutes.test.ts +0 -19
- package/src/hooks/useInterceptingRoutes.ts +1 -7
- package/src/layout/GlobalProvider/StoreInitialization.tsx +2 -4
- package/src/services/_auth.ts +2 -11
- package/src/services/_header.ts +2 -10
- package/src/services/chat/chat.test.ts +53 -10
- package/src/services/chat/clientModelRuntime.test.ts +108 -172
- package/src/services/chat/contextEngineering.ts +2 -2
- package/src/services/config.ts +2 -2
- package/src/store/aiInfra/slices/aiProvider/action.ts +3 -4
- package/src/store/chat/slices/thread/action.ts +2 -2
- package/src/store/global/selectors/systemStatus.test.ts +0 -98
- package/src/store/global/selectors/systemStatus.ts +0 -30
- package/src/store/serverConfig/selectors.test.ts +2 -2
- package/src/store/serverConfig/store.test.ts +0 -1
- package/src/app/[variants]/(main)/settings/storage/IndexedDBStorage.tsx +0 -55
- package/src/features/ChatInput/ActionBar/Upload/ClientMode.tsx +0 -62
|
@@ -18,14 +18,10 @@ import {
|
|
|
18
18
|
LobeZhipuAI,
|
|
19
19
|
ModelRuntime,
|
|
20
20
|
} from '@lobechat/model-runtime';
|
|
21
|
-
import { merge } from 'lodash-es';
|
|
22
21
|
import { ModelProvider } from 'model-bank';
|
|
23
22
|
import OpenAI from 'openai';
|
|
24
23
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
25
24
|
|
|
26
|
-
import { UserStore } from '@/store/user';
|
|
27
|
-
import { UserSettingsState, initialSettingsState } from '@/store/user/slices/settings/initialState';
|
|
28
|
-
|
|
29
25
|
import { initializeWithClientStore } from './clientModelRuntime';
|
|
30
26
|
|
|
31
27
|
// Mocking external dependencies
|
|
@@ -62,21 +58,35 @@ vi.mock('@lobechat/model-runtime', async (importOriginal) => {
|
|
|
62
58
|
};
|
|
63
59
|
});
|
|
64
60
|
|
|
65
|
-
|
|
61
|
+
// Mock version constants
|
|
62
|
+
vi.mock('@/const/version', () => ({
|
|
63
|
+
isServerMode: false,
|
|
64
|
+
isDeprecatedEdition: true,
|
|
65
|
+
isDesktop: false,
|
|
66
|
+
}));
|
|
67
|
+
|
|
68
|
+
// Helper function to mock aiInfra store with provider keyVaults
|
|
69
|
+
const mockProviderKeyVaults = async (provider: string, keyVaults: any) => {
|
|
70
|
+
const { useAiInfraStore } = await import('@/store/aiInfra');
|
|
71
|
+
// @ts-ignore
|
|
72
|
+
useAiInfraStore.setState((state) => ({
|
|
73
|
+
aiProviderRuntimeConfig: {
|
|
74
|
+
...state.aiProviderRuntimeConfig,
|
|
75
|
+
[provider]: {
|
|
76
|
+
keyVaults,
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
}));
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
afterEach(async () => {
|
|
66
83
|
vi.restoreAllMocks();
|
|
84
|
+
// Clean up store state
|
|
85
|
+
const { useAiInfraStore } = await import('@/store/aiInfra');
|
|
86
|
+
useAiInfraStore.setState({ aiProviderRuntimeConfig: {} } as any);
|
|
67
87
|
});
|
|
68
88
|
|
|
69
89
|
beforeEach(async () => {
|
|
70
|
-
// 清除所有模块的缓存
|
|
71
|
-
vi.resetModules();
|
|
72
|
-
|
|
73
|
-
// 默认设置 isServerMode 为 false
|
|
74
|
-
vi.mock('@/const/version', () => ({
|
|
75
|
-
isServerMode: false,
|
|
76
|
-
isDeprecatedEdition: true,
|
|
77
|
-
isDesktop: false,
|
|
78
|
-
}));
|
|
79
|
-
|
|
80
90
|
// Reset all mocks
|
|
81
91
|
vi.clearAllMocks();
|
|
82
92
|
|
|
@@ -97,17 +107,11 @@ describe('ModelRuntimeOnClient', () => {
|
|
|
97
107
|
describe('initializeWithClientStore', () => {
|
|
98
108
|
describe('should initialize with options correctly', () => {
|
|
99
109
|
it('OpenAI provider: with apikey and endpoint', async () => {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
apiKey: 'user-openai-key',
|
|
106
|
-
baseURL: 'user-openai-endpoint',
|
|
107
|
-
},
|
|
108
|
-
},
|
|
109
|
-
},
|
|
110
|
-
} as UserSettingsState) as unknown as UserStore;
|
|
110
|
+
await mockProviderKeyVaults(ModelProvider.OpenAI, {
|
|
111
|
+
apiKey: 'user-openai-key',
|
|
112
|
+
baseURL: 'user-openai-endpoint',
|
|
113
|
+
});
|
|
114
|
+
|
|
111
115
|
const runtime = await initializeWithClientStore({
|
|
112
116
|
payload: {},
|
|
113
117
|
provider: ModelProvider.OpenAI,
|
|
@@ -118,17 +122,11 @@ describe('ModelRuntimeOnClient', () => {
|
|
|
118
122
|
});
|
|
119
123
|
|
|
120
124
|
it('Azure provider: with apiKey, apiVersion, endpoint', async () => {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
endpoint: 'user-azure-endpoint',
|
|
127
|
-
apiVersion: '2024-06-01',
|
|
128
|
-
},
|
|
129
|
-
},
|
|
130
|
-
},
|
|
131
|
-
} as UserSettingsState) as unknown as UserStore;
|
|
125
|
+
await mockProviderKeyVaults(ModelProvider.Azure, {
|
|
126
|
+
apiKey: 'user-azure-key',
|
|
127
|
+
endpoint: 'user-azure-endpoint',
|
|
128
|
+
apiVersion: '2024-06-01',
|
|
129
|
+
});
|
|
132
130
|
|
|
133
131
|
const runtime = await initializeWithClientStore({
|
|
134
132
|
payload: {},
|
|
@@ -139,15 +137,10 @@ describe('ModelRuntimeOnClient', () => {
|
|
|
139
137
|
});
|
|
140
138
|
|
|
141
139
|
it('Google provider: with apiKey', async () => {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
apiKey: 'user-google-key',
|
|
147
|
-
},
|
|
148
|
-
},
|
|
149
|
-
},
|
|
150
|
-
} as UserSettingsState) as unknown as UserStore;
|
|
140
|
+
await mockProviderKeyVaults(ModelProvider.Google, {
|
|
141
|
+
apiKey: 'user-google-key',
|
|
142
|
+
});
|
|
143
|
+
|
|
151
144
|
const runtime = await initializeWithClientStore({
|
|
152
145
|
payload: {},
|
|
153
146
|
provider: ModelProvider.Google,
|
|
@@ -157,15 +150,10 @@ describe('ModelRuntimeOnClient', () => {
|
|
|
157
150
|
});
|
|
158
151
|
|
|
159
152
|
it('Moonshot AI provider: with apiKey', async () => {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
apiKey: 'user-moonshot-key',
|
|
165
|
-
},
|
|
166
|
-
},
|
|
167
|
-
},
|
|
168
|
-
} as UserSettingsState) as unknown as UserStore;
|
|
153
|
+
await mockProviderKeyVaults(ModelProvider.Moonshot, {
|
|
154
|
+
apiKey: 'user-moonshot-key',
|
|
155
|
+
});
|
|
156
|
+
|
|
169
157
|
const runtime = await initializeWithClientStore({
|
|
170
158
|
payload: {},
|
|
171
159
|
provider: ModelProvider.Moonshot,
|
|
@@ -175,17 +163,12 @@ describe('ModelRuntimeOnClient', () => {
|
|
|
175
163
|
});
|
|
176
164
|
|
|
177
165
|
it('Bedrock provider: with accessKeyId, region, secretAccessKey', async () => {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
secretAccessKey: 'user-bedrock-secret',
|
|
185
|
-
},
|
|
186
|
-
},
|
|
187
|
-
},
|
|
188
|
-
} as UserSettingsState) as unknown as UserStore;
|
|
166
|
+
await mockProviderKeyVaults(ModelProvider.Bedrock, {
|
|
167
|
+
accessKeyId: 'user-bedrock-access-key',
|
|
168
|
+
region: 'user-bedrock-region',
|
|
169
|
+
secretAccessKey: 'user-bedrock-secret',
|
|
170
|
+
});
|
|
171
|
+
|
|
189
172
|
const runtime = await initializeWithClientStore({
|
|
190
173
|
payload: {},
|
|
191
174
|
provider: ModelProvider.Bedrock,
|
|
@@ -195,15 +178,10 @@ describe('ModelRuntimeOnClient', () => {
|
|
|
195
178
|
});
|
|
196
179
|
|
|
197
180
|
it('Ollama provider: with endpoint', async () => {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
baseURL: 'http://127.0.0.1:1234',
|
|
203
|
-
},
|
|
204
|
-
},
|
|
205
|
-
},
|
|
206
|
-
} as UserSettingsState) as unknown as UserStore;
|
|
181
|
+
await mockProviderKeyVaults(ModelProvider.Ollama, {
|
|
182
|
+
baseURL: 'http://127.0.0.1:1234',
|
|
183
|
+
});
|
|
184
|
+
|
|
207
185
|
const runtime = await initializeWithClientStore({
|
|
208
186
|
payload: {},
|
|
209
187
|
provider: ModelProvider.Ollama,
|
|
@@ -213,15 +191,10 @@ describe('ModelRuntimeOnClient', () => {
|
|
|
213
191
|
});
|
|
214
192
|
|
|
215
193
|
it('Perplexity provider: with apiKey', async () => {
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
apiKey: 'user-perplexity-key',
|
|
221
|
-
},
|
|
222
|
-
},
|
|
223
|
-
},
|
|
224
|
-
} as UserSettingsState) as unknown as UserStore;
|
|
194
|
+
await mockProviderKeyVaults(ModelProvider.Perplexity, {
|
|
195
|
+
apiKey: 'user-perplexity-key',
|
|
196
|
+
});
|
|
197
|
+
|
|
225
198
|
const runtime = await initializeWithClientStore({
|
|
226
199
|
payload: {},
|
|
227
200
|
provider: ModelProvider.Perplexity,
|
|
@@ -231,15 +204,10 @@ describe('ModelRuntimeOnClient', () => {
|
|
|
231
204
|
});
|
|
232
205
|
|
|
233
206
|
it('Anthropic provider: with apiKey', async () => {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
apiKey: 'user-anthropic-key',
|
|
239
|
-
},
|
|
240
|
-
},
|
|
241
|
-
},
|
|
242
|
-
} as UserSettingsState) as unknown as UserStore;
|
|
207
|
+
await mockProviderKeyVaults(ModelProvider.Anthropic, {
|
|
208
|
+
apiKey: 'user-anthropic-key',
|
|
209
|
+
});
|
|
210
|
+
|
|
243
211
|
const runtime = await initializeWithClientStore({
|
|
244
212
|
payload: {},
|
|
245
213
|
provider: ModelProvider.Anthropic,
|
|
@@ -249,15 +217,10 @@ describe('ModelRuntimeOnClient', () => {
|
|
|
249
217
|
});
|
|
250
218
|
|
|
251
219
|
it('Mistral provider: with apiKey', async () => {
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
apiKey: 'user-mistral-key',
|
|
257
|
-
},
|
|
258
|
-
},
|
|
259
|
-
},
|
|
260
|
-
} as UserSettingsState) as unknown as UserStore;
|
|
220
|
+
await mockProviderKeyVaults(ModelProvider.Mistral, {
|
|
221
|
+
apiKey: 'user-mistral-key',
|
|
222
|
+
});
|
|
223
|
+
|
|
261
224
|
const runtime = await initializeWithClientStore({
|
|
262
225
|
payload: {},
|
|
263
226
|
provider: ModelProvider.Mistral,
|
|
@@ -267,15 +230,10 @@ describe('ModelRuntimeOnClient', () => {
|
|
|
267
230
|
});
|
|
268
231
|
|
|
269
232
|
it('OpenRouter provider: with apiKey', async () => {
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
apiKey: 'user-openrouter-key',
|
|
275
|
-
},
|
|
276
|
-
},
|
|
277
|
-
},
|
|
278
|
-
} as UserSettingsState) as unknown as UserStore;
|
|
233
|
+
await mockProviderKeyVaults(ModelProvider.OpenRouter, {
|
|
234
|
+
apiKey: 'user-openrouter-key',
|
|
235
|
+
});
|
|
236
|
+
|
|
279
237
|
const runtime = await initializeWithClientStore({
|
|
280
238
|
payload: {},
|
|
281
239
|
provider: ModelProvider.OpenRouter,
|
|
@@ -285,15 +243,10 @@ describe('ModelRuntimeOnClient', () => {
|
|
|
285
243
|
});
|
|
286
244
|
|
|
287
245
|
it('TogetherAI provider: with apiKey', async () => {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
apiKey: 'user-togetherai-key',
|
|
293
|
-
},
|
|
294
|
-
},
|
|
295
|
-
},
|
|
296
|
-
} as UserSettingsState) as unknown as UserStore;
|
|
246
|
+
await mockProviderKeyVaults(ModelProvider.TogetherAI, {
|
|
247
|
+
apiKey: 'user-togetherai-key',
|
|
248
|
+
});
|
|
249
|
+
|
|
297
250
|
const runtime = await initializeWithClientStore({
|
|
298
251
|
payload: {},
|
|
299
252
|
provider: ModelProvider.TogetherAI,
|
|
@@ -303,15 +256,10 @@ describe('ModelRuntimeOnClient', () => {
|
|
|
303
256
|
});
|
|
304
257
|
|
|
305
258
|
it('ZeroOneAI provider: with apiKey', async () => {
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
apiKey: 'user-zeroone-key',
|
|
311
|
-
},
|
|
312
|
-
},
|
|
313
|
-
},
|
|
314
|
-
} as UserSettingsState) as unknown as UserStore;
|
|
259
|
+
await mockProviderKeyVaults(ModelProvider.ZeroOne, {
|
|
260
|
+
apiKey: 'user-zeroone-key',
|
|
261
|
+
});
|
|
262
|
+
|
|
315
263
|
const runtime = await initializeWithClientStore({
|
|
316
264
|
payload: {},
|
|
317
265
|
provider: ModelProvider.ZeroOne,
|
|
@@ -321,16 +269,11 @@ describe('ModelRuntimeOnClient', () => {
|
|
|
321
269
|
});
|
|
322
270
|
|
|
323
271
|
it('Groq provider: with apiKey,endpoint', async () => {
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
baseURL: 'user-groq-endpoint',
|
|
330
|
-
},
|
|
331
|
-
},
|
|
332
|
-
},
|
|
333
|
-
} as UserSettingsState) as unknown as UserStore;
|
|
272
|
+
await mockProviderKeyVaults(ModelProvider.Groq, {
|
|
273
|
+
apiKey: 'user-groq-key',
|
|
274
|
+
baseURL: 'user-groq-endpoint',
|
|
275
|
+
});
|
|
276
|
+
|
|
334
277
|
const runtime = await initializeWithClientStore({
|
|
335
278
|
payload: {},
|
|
336
279
|
provider: ModelProvider.Groq,
|
|
@@ -344,15 +287,10 @@ describe('ModelRuntimeOnClient', () => {
|
|
|
344
287
|
});
|
|
345
288
|
|
|
346
289
|
it('DeepSeek provider: with apiKey', async () => {
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
apiKey: 'user-deepseek-key',
|
|
352
|
-
},
|
|
353
|
-
},
|
|
354
|
-
},
|
|
355
|
-
} as UserSettingsState) as unknown as UserStore;
|
|
290
|
+
await mockProviderKeyVaults(ModelProvider.DeepSeek, {
|
|
291
|
+
apiKey: 'user-deepseek-key',
|
|
292
|
+
});
|
|
293
|
+
|
|
356
294
|
const runtime = await initializeWithClientStore({
|
|
357
295
|
payload: {},
|
|
358
296
|
provider: ModelProvider.DeepSeek,
|
|
@@ -362,15 +300,10 @@ describe('ModelRuntimeOnClient', () => {
|
|
|
362
300
|
});
|
|
363
301
|
|
|
364
302
|
it('Qwen provider: with apiKey', async () => {
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
apiKey: 'user-qwen-key',
|
|
370
|
-
},
|
|
371
|
-
},
|
|
372
|
-
},
|
|
373
|
-
} as UserSettingsState) as unknown as UserStore;
|
|
303
|
+
await mockProviderKeyVaults(ModelProvider.Qwen, {
|
|
304
|
+
apiKey: 'user-qwen-key',
|
|
305
|
+
});
|
|
306
|
+
|
|
374
307
|
const runtime = await initializeWithClientStore({
|
|
375
308
|
payload: {},
|
|
376
309
|
provider: ModelProvider.Qwen,
|
|
@@ -384,16 +317,23 @@ describe('ModelRuntimeOnClient', () => {
|
|
|
384
317
|
* similar cases in server side
|
|
385
318
|
*/
|
|
386
319
|
it('Unknown provider: with apiKey', async () => {
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
320
|
+
const { useAiInfraStore } = await import('@/store/aiInfra');
|
|
321
|
+
// @ts-ignore
|
|
322
|
+
useAiInfraStore.setState((state) => ({
|
|
323
|
+
aiProviderRuntimeConfig: {
|
|
324
|
+
...state.aiProviderRuntimeConfig,
|
|
325
|
+
unknown: {
|
|
326
|
+
keyVaults: {
|
|
391
327
|
apiKey: 'user-unknown-key',
|
|
392
|
-
|
|
328
|
+
baseURL: 'user-unknown-endpoint',
|
|
329
|
+
},
|
|
330
|
+
settings: {
|
|
331
|
+
sdkType: 'openai',
|
|
393
332
|
},
|
|
394
333
|
},
|
|
395
334
|
},
|
|
396
|
-
}
|
|
335
|
+
}));
|
|
336
|
+
|
|
397
337
|
const runtime = await initializeWithClientStore({
|
|
398
338
|
payload: {},
|
|
399
339
|
provider: 'unknown' as ModelProvider,
|
|
@@ -415,15 +355,11 @@ describe('ModelRuntimeOnClient', () => {
|
|
|
415
355
|
'eyJhbGciOiJIUzI1NiIsInNpZ25fdHlwZSI6IlNJR04iLCJ0eXAiOiJKV1QifQ.eyJhcGlfa2V5IjoiemhpcHUiLCJleHAiOjE3MTU5MTc2NzMsImlhdCI6MTcxMzMyNTY3M30.gt8o-hUDvJFPJLYcH4EhrT1LAmTXI8YnybHeQjpD9oM',
|
|
416
356
|
),
|
|
417
357
|
}));
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
},
|
|
424
|
-
},
|
|
425
|
-
},
|
|
426
|
-
} as UserSettingsState) as unknown as UserStore;
|
|
358
|
+
|
|
359
|
+
await mockProviderKeyVaults(ModelProvider.ZhiPu, {
|
|
360
|
+
apiKey: 'zhipu.user-key',
|
|
361
|
+
});
|
|
362
|
+
|
|
427
363
|
const runtime = await initializeWithClientStore({
|
|
428
364
|
payload: {},
|
|
429
365
|
provider: ModelProvider.ZhiPu,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isDesktop
|
|
1
|
+
import { isDesktop } from '@lobechat/const';
|
|
2
2
|
import {
|
|
3
3
|
ContextEngine,
|
|
4
4
|
GroupMessageFlattenProcessor,
|
|
@@ -88,7 +88,7 @@ export const contextEngineering = async ({
|
|
|
88
88
|
|
|
89
89
|
// 8.5 Message content processing
|
|
90
90
|
new MessageContentProcessor({
|
|
91
|
-
fileContext: { enabled:
|
|
91
|
+
fileContext: { enabled: true, includeFileUrl: !isDesktop },
|
|
92
92
|
isCanUseVideo,
|
|
93
93
|
isCanUseVision,
|
|
94
94
|
model,
|
package/src/services/config.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BRANDING_NAME
|
|
1
|
+
import { BRANDING_NAME } from '@lobechat/const';
|
|
2
2
|
import { downloadFile, exportJSONFile } from '@lobechat/utils/client';
|
|
3
3
|
import dayjs from 'dayjs';
|
|
4
4
|
|
|
@@ -19,7 +19,7 @@ class ConfigService {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
// or export to file with the data
|
|
22
|
-
const result = await this.createDataStructure(data,
|
|
22
|
+
const result = await this.createDataStructure(data, 'postgres');
|
|
23
23
|
|
|
24
24
|
exportJSONFile(result, filename);
|
|
25
25
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isDesktop } from '@lobechat/const';
|
|
2
2
|
import { getModelPropertyWithFallback, resolveImageSinglePrice } from '@lobechat/model-runtime';
|
|
3
3
|
import { uniqBy } from 'lodash-es';
|
|
4
4
|
import {
|
|
@@ -319,8 +319,7 @@ export const createAiProviderSlice: StateCreator<
|
|
|
319
319
|
const isAuthLoaded = authSelectors.isLoaded(useUserStore.getState());
|
|
320
320
|
// Only fetch when auth is loaded and login status is explicitly defined (true or false)
|
|
321
321
|
// Prevents unnecessary requests when login state is null/undefined
|
|
322
|
-
const shouldFetch =
|
|
323
|
-
isAuthLoaded && !isDeprecatedEdition && isLogin !== null && isLogin !== undefined;
|
|
322
|
+
const shouldFetch = isAuthLoaded && isLogin !== null && isLogin !== undefined;
|
|
324
323
|
return useClientDataSWR<AiProviderRuntimeStateWithBuiltinModels | undefined>(
|
|
325
324
|
shouldFetch ? [AiProviderSwrKey.fetchAiProviderRuntimeState, isLogin] : null,
|
|
326
325
|
async ([, isLogin]) => {
|
|
@@ -381,7 +380,7 @@ export const createAiProviderSlice: StateCreator<
|
|
|
381
380
|
};
|
|
382
381
|
},
|
|
383
382
|
{
|
|
384
|
-
focusThrottleInterval: isDesktop
|
|
383
|
+
focusThrottleInterval: isDesktop ? 100 : undefined,
|
|
385
384
|
onSuccess: (data) => {
|
|
386
385
|
if (!data) return;
|
|
387
386
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint-disable sort-keys-fix/sort-keys-fix, typescript-sort-keys/interface */
|
|
2
2
|
// Disable the auto sort key eslint rule to make the code more logic and readable
|
|
3
|
-
import { LOADING_FLAT, THREAD_DRAFT_ID
|
|
3
|
+
import { LOADING_FLAT, THREAD_DRAFT_ID } from '@lobechat/const';
|
|
4
4
|
import { chainSummaryTitle } from '@lobechat/prompts';
|
|
5
5
|
import {
|
|
6
6
|
CreateMessageParams,
|
|
@@ -222,7 +222,7 @@ export const chatThreadMessage: StateCreator<
|
|
|
222
222
|
|
|
223
223
|
useFetchThreads: (enable, topicId) =>
|
|
224
224
|
useClientDataSWR<ThreadItem[]>(
|
|
225
|
-
enable && !!topicId
|
|
225
|
+
enable && !!topicId ? [SWR_USE_FETCH_THREADS, topicId] : null,
|
|
226
226
|
async ([, topicId]: [string, string]) => threadService.getThreads(topicId),
|
|
227
227
|
{
|
|
228
228
|
onSuccess: (threads) => {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { describe, expect, it, vi } from 'vitest';
|
|
2
2
|
|
|
3
|
-
import { DatabaseLoadingState } from '@/types/clientDB';
|
|
4
3
|
import { merge } from '@/utils/merge';
|
|
5
4
|
|
|
6
5
|
import { GlobalState, INITIAL_STATUS, initialState } from '../initialState';
|
|
@@ -108,101 +107,4 @@ describe('systemStatusSelectors', () => {
|
|
|
108
107
|
expect(systemStatusSelectors.themeMode(s)).toBe('auto');
|
|
109
108
|
});
|
|
110
109
|
});
|
|
111
|
-
|
|
112
|
-
describe('pglite status selectors', () => {
|
|
113
|
-
describe('isPgliteNotEnabled', () => {
|
|
114
|
-
it('should return true when conditions are met', () => {
|
|
115
|
-
const s: GlobalState = {
|
|
116
|
-
...initialState,
|
|
117
|
-
isStatusInit: true,
|
|
118
|
-
status: {
|
|
119
|
-
...initialState.status,
|
|
120
|
-
isEnablePglite: false,
|
|
121
|
-
},
|
|
122
|
-
};
|
|
123
|
-
expect(systemStatusSelectors.isPgliteNotEnabled(s)).toBe(true);
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
it('should return false when isStatusInit is false', () => {
|
|
127
|
-
const s: GlobalState = {
|
|
128
|
-
...initialState,
|
|
129
|
-
isStatusInit: false,
|
|
130
|
-
status: {
|
|
131
|
-
...initialState.status,
|
|
132
|
-
isEnablePglite: false,
|
|
133
|
-
},
|
|
134
|
-
};
|
|
135
|
-
expect(systemStatusSelectors.isPgliteNotEnabled(s)).toBe(false);
|
|
136
|
-
});
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
describe('isPgliteNotInited', () => {
|
|
140
|
-
it('should return true when pglite is enabled but not ready', () => {
|
|
141
|
-
const s: GlobalState = {
|
|
142
|
-
...initialState,
|
|
143
|
-
isStatusInit: true,
|
|
144
|
-
status: {
|
|
145
|
-
...initialState.status,
|
|
146
|
-
isEnablePglite: true,
|
|
147
|
-
},
|
|
148
|
-
initClientDBStage: DatabaseLoadingState.Initializing,
|
|
149
|
-
};
|
|
150
|
-
expect(systemStatusSelectors.isPgliteNotInited(s)).toBe(true);
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
it('should return false when pglite is ready', () => {
|
|
154
|
-
const s: GlobalState = {
|
|
155
|
-
...initialState,
|
|
156
|
-
isStatusInit: true,
|
|
157
|
-
status: {
|
|
158
|
-
...initialState.status,
|
|
159
|
-
isEnablePglite: true,
|
|
160
|
-
},
|
|
161
|
-
initClientDBStage: DatabaseLoadingState.Ready,
|
|
162
|
-
};
|
|
163
|
-
expect(systemStatusSelectors.isPgliteNotInited(s)).toBe(false);
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
it('should return false when pglite is not enabled', () => {
|
|
167
|
-
const s: GlobalState = {
|
|
168
|
-
...initialState,
|
|
169
|
-
isStatusInit: true,
|
|
170
|
-
status: {
|
|
171
|
-
...initialState.status,
|
|
172
|
-
isEnablePglite: false,
|
|
173
|
-
},
|
|
174
|
-
initClientDBStage: DatabaseLoadingState.Initializing,
|
|
175
|
-
};
|
|
176
|
-
expect(systemStatusSelectors.isPgliteNotInited(s)).toBe(false);
|
|
177
|
-
});
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
describe('isPgliteInited', () => {
|
|
181
|
-
it('should return true when pglite is enabled and ready', () => {
|
|
182
|
-
const s: GlobalState = {
|
|
183
|
-
...initialState,
|
|
184
|
-
isStatusInit: true,
|
|
185
|
-
status: {
|
|
186
|
-
...initialState.status,
|
|
187
|
-
isEnablePglite: true,
|
|
188
|
-
},
|
|
189
|
-
initClientDBStage: DatabaseLoadingState.Ready,
|
|
190
|
-
};
|
|
191
|
-
expect(systemStatusSelectors.isPgliteInited(s)).toBe(true);
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
it('should return false when not ready', () => {
|
|
195
|
-
const s: GlobalState = {
|
|
196
|
-
...initialState,
|
|
197
|
-
isStatusInit: true,
|
|
198
|
-
status: {
|
|
199
|
-
...initialState.status,
|
|
200
|
-
isEnablePglite: true,
|
|
201
|
-
},
|
|
202
|
-
initClientDBStage: DatabaseLoadingState.Initializing,
|
|
203
|
-
};
|
|
204
|
-
expect(systemStatusSelectors.isPgliteInited(s)).toBe(false);
|
|
205
|
-
});
|
|
206
|
-
});
|
|
207
|
-
});
|
|
208
110
|
});
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import { isServerMode, isUsePgliteDB } from '@/const/version';
|
|
2
|
-
import { DatabaseLoadingState } from '@/types/clientDB';
|
|
3
|
-
|
|
4
1
|
import { GlobalState, INITIAL_STATUS } from '../initialState';
|
|
5
2
|
|
|
6
3
|
export const systemStatus = (s: GlobalState) => s.status;
|
|
@@ -32,29 +29,6 @@ const wideScreen = (s: GlobalState) => !s.status.noWideScreen;
|
|
|
32
29
|
const chatInputHeight = (s: GlobalState) => s.status.chatInputHeight || 64;
|
|
33
30
|
const expandInputActionbar = (s: GlobalState) => s.status.expandInputActionbar;
|
|
34
31
|
const isStatusInit = (s: GlobalState) => !!s.isStatusInit;
|
|
35
|
-
const isPgliteNotEnabled = (s: GlobalState) =>
|
|
36
|
-
isUsePgliteDB && !isServerMode && isStatusInit(s) && !s.status.isEnablePglite;
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* 当且仅当 client db 模式,且 pglite 未初始化完成时返回 true
|
|
40
|
-
*/
|
|
41
|
-
const isPgliteNotInited = (s: GlobalState) =>
|
|
42
|
-
isUsePgliteDB &&
|
|
43
|
-
isStatusInit(s) &&
|
|
44
|
-
s.status.isEnablePglite &&
|
|
45
|
-
s.initClientDBStage !== DatabaseLoadingState.Ready;
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* 当且仅当 client db 模式,且 pglite 初始化完成时返回 true
|
|
49
|
-
*/
|
|
50
|
-
const isPgliteInited = (s: GlobalState): boolean =>
|
|
51
|
-
(isStatusInit(s) &&
|
|
52
|
-
s.status.isEnablePglite &&
|
|
53
|
-
s.initClientDBStage === DatabaseLoadingState.Ready) ||
|
|
54
|
-
false;
|
|
55
|
-
|
|
56
|
-
// 这个变量控制 clientdb 是否完成初始化,正常来说,只有 pgliteDB 模式下,才会存在变化,其他时候都是 true
|
|
57
|
-
const isDBInited = (s: GlobalState): boolean => (isUsePgliteDB ? isPgliteInited(s) : true);
|
|
58
32
|
|
|
59
33
|
const getAgentSystemRoleExpanded =
|
|
60
34
|
(agentId: string) =>
|
|
@@ -80,10 +54,6 @@ export const systemStatusSelectors = {
|
|
|
80
54
|
imagePanelWidth,
|
|
81
55
|
imageTopicPanelWidth,
|
|
82
56
|
inZenMode,
|
|
83
|
-
isDBInited,
|
|
84
|
-
isPgliteInited,
|
|
85
|
-
isPgliteNotEnabled,
|
|
86
|
-
isPgliteNotInited,
|
|
87
57
|
isShowCredit,
|
|
88
58
|
isStatusInit,
|
|
89
59
|
language,
|
|
@@ -11,7 +11,7 @@ describe('featureFlagsSelectors', () => {
|
|
|
11
11
|
featureFlags: {
|
|
12
12
|
...mapFeatureFlagsEnvToState(DEFAULT_FEATURE_FLAGS),
|
|
13
13
|
isAgentEditable: false,
|
|
14
|
-
|
|
14
|
+
showProvider: true,
|
|
15
15
|
showMarket: true,
|
|
16
16
|
showAiImage: true,
|
|
17
17
|
},
|
|
@@ -20,7 +20,7 @@ describe('featureFlagsSelectors', () => {
|
|
|
20
20
|
const result = featureFlagsSelectors(store.getState());
|
|
21
21
|
|
|
22
22
|
expect(result.isAgentEditable).toBe(false);
|
|
23
|
-
expect(result.
|
|
23
|
+
expect(result.showProvider).toBe(true);
|
|
24
24
|
expect(result.showMarket).toBe(true);
|
|
25
25
|
expect(result.showAiImage).toBe(true);
|
|
26
26
|
});
|
|
@@ -21,7 +21,6 @@ describe('createServerConfigStore', () => {
|
|
|
21
21
|
it('should initialize store with default state', () => {
|
|
22
22
|
const store = createServerConfigStore();
|
|
23
23
|
|
|
24
|
-
expect(store.getState().featureFlags).toHaveProperty('showLLM');
|
|
25
24
|
expect(store.getState().featureFlags).toHaveProperty('enablePlugins');
|
|
26
25
|
expect(store.getState()).toMatchObject({
|
|
27
26
|
serverConfig: { telemetry: {}, aiProvider: {} },
|