@lobehub/chat 1.136.13 → 1.137.0
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/.cursor/rules/add-setting-env.mdc +175 -0
- package/.cursor/rules/db-migrations.mdc +25 -0
- package/.env.example +7 -0
- package/CHANGELOG.md +25 -0
- package/changelog/v1.json +9 -0
- package/docs/development/database-schema.dbml +1 -0
- package/docs/self-hosting/advanced/feature-flags.mdx +25 -15
- package/docs/self-hosting/advanced/feature-flags.zh-CN.mdx +25 -15
- package/docs/self-hosting/environment-variables/basic.mdx +12 -0
- package/docs/self-hosting/environment-variables/basic.zh-CN.mdx +12 -0
- package/locales/ar/setting.json +8 -0
- package/locales/bg-BG/setting.json +8 -0
- package/locales/de-DE/setting.json +8 -0
- package/locales/en-US/setting.json +8 -0
- package/locales/es-ES/setting.json +8 -0
- package/locales/fa-IR/setting.json +8 -0
- package/locales/fr-FR/setting.json +8 -0
- package/locales/it-IT/setting.json +8 -0
- package/locales/ja-JP/setting.json +8 -0
- package/locales/ko-KR/setting.json +8 -0
- package/locales/nl-NL/setting.json +8 -0
- package/locales/pl-PL/setting.json +8 -0
- package/locales/pt-BR/setting.json +8 -0
- package/locales/ru-RU/setting.json +8 -0
- package/locales/tr-TR/setting.json +8 -0
- package/locales/vi-VN/setting.json +8 -0
- package/locales/zh-CN/setting.json +8 -0
- package/locales/zh-TW/setting.json +8 -0
- package/package.json +1 -1
- package/packages/const/src/settings/image.ts +8 -0
- package/packages/const/src/settings/index.ts +3 -0
- package/packages/context-engine/src/__tests__/pipeline.test.ts +485 -0
- package/packages/context-engine/src/base/__tests__/BaseProcessor.test.ts +381 -0
- package/packages/context-engine/src/base/__tests__/BaseProvider.test.ts +392 -0
- package/packages/context-engine/src/processors/__tests__/MessageCleanup.test.ts +346 -0
- package/packages/context-engine/src/processors/__tests__/ToolCall.test.ts +552 -0
- package/packages/database/migrations/0038_add_image_user_settings.sql +1 -0
- package/packages/database/migrations/meta/0038_snapshot.json +7580 -0
- package/packages/database/migrations/meta/_journal.json +7 -0
- package/packages/database/src/core/migrations.json +6 -0
- package/packages/database/src/models/user.ts +3 -1
- package/packages/database/src/schemas/user.ts +1 -0
- package/packages/file-loaders/src/loaders/docx/index.test.ts +0 -1
- package/packages/file-loaders/src/loaders/excel/__snapshots__/index.test.ts.snap +30 -0
- package/packages/file-loaders/src/loaders/excel/index.test.ts +8 -0
- package/packages/file-loaders/src/loaders/pptx/index.test.ts +25 -0
- package/packages/file-loaders/src/utils/parser-utils.test.ts +155 -0
- package/packages/file-loaders/vitest.config.mts +8 -0
- package/packages/types/src/serverConfig.ts +7 -1
- package/packages/types/src/user/settings/image.ts +3 -0
- package/packages/types/src/user/settings/index.ts +3 -0
- package/src/app/[variants]/(main)/settings/_layout/SettingsContent.tsx +3 -0
- package/src/app/[variants]/(main)/settings/hooks/useCategory.tsx +8 -3
- package/src/app/[variants]/(main)/settings/image/index.tsx +74 -0
- package/src/components/FormInput/FormSliderWithInput.tsx +40 -0
- package/src/components/FormInput/index.ts +1 -0
- package/src/envs/image.ts +27 -0
- package/src/hooks/useFetchAiImageConfig.ts +12 -17
- package/src/locales/default/setting.ts +8 -0
- package/src/server/globalConfig/index.ts +5 -0
- package/src/store/global/initialState.ts +1 -0
- package/src/store/image/slices/generationConfig/action.test.ts +17 -0
- package/src/store/image/slices/generationConfig/action.ts +18 -21
- package/src/store/image/slices/generationConfig/initialState.ts +3 -2
- package/src/store/user/slices/common/action.ts +1 -0
- package/src/store/user/slices/settings/selectors/settings.ts +3 -0
|
@@ -3,10 +3,12 @@ import { isDesktop } from '@/const/version';
|
|
|
3
3
|
import { appEnv, getAppConfig } from '@/envs/app';
|
|
4
4
|
import { authEnv } from '@/envs/auth';
|
|
5
5
|
import { fileEnv } from '@/envs/file';
|
|
6
|
+
import { imageEnv } from '@/envs/image';
|
|
6
7
|
import { knowledgeEnv } from '@/envs/knowledge';
|
|
7
8
|
import { langfuseEnv } from '@/envs/langfuse';
|
|
8
9
|
import { parseSystemAgent } from '@/server/globalConfig/parseSystemAgent';
|
|
9
10
|
import { GlobalServerConfig } from '@/types/serverConfig';
|
|
11
|
+
import { cleanObject } from '@/utils/object';
|
|
10
12
|
|
|
11
13
|
import { genServerLLMConfig } from './_deprecated';
|
|
12
14
|
import { genServerAiProvidersConfig } from './genServerAiProviderConfig';
|
|
@@ -61,6 +63,9 @@ export const getServerGlobalConfig = async () => {
|
|
|
61
63
|
enabledAccessCode: ACCESS_CODES?.length > 0,
|
|
62
64
|
|
|
63
65
|
enabledOAuthSSO: enableNextAuth,
|
|
66
|
+
image: cleanObject({
|
|
67
|
+
defaultImageNum: imageEnv.AI_IMAGE_DEFAULT_IMAGE_NUM,
|
|
68
|
+
}),
|
|
64
69
|
/**
|
|
65
70
|
* @deprecated
|
|
66
71
|
*/
|
|
@@ -6,6 +6,18 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
|
6
6
|
|
|
7
7
|
import { useImageStore } from '@/store/image';
|
|
8
8
|
|
|
9
|
+
const { currentImageSettingsMock } = vi.hoisted(() => ({
|
|
10
|
+
currentImageSettingsMock: vi.fn(() => ({
|
|
11
|
+
defaultImageNum: 4,
|
|
12
|
+
})),
|
|
13
|
+
}));
|
|
14
|
+
|
|
15
|
+
vi.mock('@/store/user/slices/settings/selectors', () => ({
|
|
16
|
+
settingsSelectors: {
|
|
17
|
+
currentImageSettings: currentImageSettingsMock,
|
|
18
|
+
},
|
|
19
|
+
}));
|
|
20
|
+
|
|
9
21
|
// Test fixtures
|
|
10
22
|
const customModelSchema: ModelParamsSchema = {
|
|
11
23
|
prompt: { default: '' },
|
|
@@ -74,6 +86,7 @@ const initialTestState = {
|
|
|
74
86
|
|
|
75
87
|
beforeEach(() => {
|
|
76
88
|
vi.clearAllMocks();
|
|
89
|
+
currentImageSettingsMock.mockReturnValue({ defaultImageNum: 4 });
|
|
77
90
|
useImageStore.setState(initialTestState);
|
|
78
91
|
});
|
|
79
92
|
|
|
@@ -483,6 +496,7 @@ describe('GenerationConfigAction', () => {
|
|
|
483
496
|
});
|
|
484
497
|
|
|
485
498
|
it('should initialize with remembered model when user is logged in', () => {
|
|
499
|
+
currentImageSettingsMock.mockReturnValueOnce({ defaultImageNum: 6 });
|
|
486
500
|
const { result } = renderHook(() => useImageStore());
|
|
487
501
|
|
|
488
502
|
useImageStore.setState({
|
|
@@ -499,6 +513,7 @@ describe('GenerationConfigAction', () => {
|
|
|
499
513
|
expect(result.current.provider).toBe('fal');
|
|
500
514
|
expect(result.current.parameters).toEqual(fluxSchnellDefaultValues);
|
|
501
515
|
expect(result.current.isInit).toBe(true);
|
|
516
|
+
expect(result.current.imageNum).toBe(6);
|
|
502
517
|
});
|
|
503
518
|
|
|
504
519
|
it('should handle initialization without remembered preferences', () => {
|
|
@@ -511,6 +526,7 @@ describe('GenerationConfigAction', () => {
|
|
|
511
526
|
});
|
|
512
527
|
|
|
513
528
|
expect(result.current.isInit).toBe(true);
|
|
529
|
+
expect(result.current.imageNum).toBe(4);
|
|
514
530
|
});
|
|
515
531
|
|
|
516
532
|
it('should handle initialization errors gracefully', () => {
|
|
@@ -523,6 +539,7 @@ describe('GenerationConfigAction', () => {
|
|
|
523
539
|
});
|
|
524
540
|
|
|
525
541
|
expect(result.current.isInit).toBe(true);
|
|
542
|
+
expect(result.current.imageNum).toBe(4);
|
|
526
543
|
});
|
|
527
544
|
});
|
|
528
545
|
});
|
|
@@ -12,6 +12,7 @@ import { aiProviderSelectors, getAiInfraStoreState } from '@/store/aiInfra';
|
|
|
12
12
|
import { useGlobalStore } from '@/store/global';
|
|
13
13
|
import { useUserStore } from '@/store/user';
|
|
14
14
|
import { authSelectors } from '@/store/user/selectors';
|
|
15
|
+
import { settingsSelectors } from '@/store/user/slices/settings/selectors';
|
|
15
16
|
|
|
16
17
|
import type { ImageStore } from '../../store';
|
|
17
18
|
import { calculateInitialAspectRatio } from '../../utils/aspectRatio';
|
|
@@ -40,6 +41,7 @@ export interface GenerationConfigAction {
|
|
|
40
41
|
setAspectRatio(aspectRatio: string): void;
|
|
41
42
|
|
|
42
43
|
// 初始化相关方法
|
|
44
|
+
_initializeDefaultImageConfig(): void;
|
|
43
45
|
initializeImageConfig(
|
|
44
46
|
isLogin?: boolean,
|
|
45
47
|
lastSelectedImageModel?: string,
|
|
@@ -327,46 +329,41 @@ export const createGenerationConfigSlice: StateCreator<
|
|
|
327
329
|
set((state) => ({ parameters: { ...state.parameters, seed } }), false, `reuseSeed/${seed}`);
|
|
328
330
|
},
|
|
329
331
|
|
|
332
|
+
_initializeDefaultImageConfig: () => {
|
|
333
|
+
const { defaultImageNum } = settingsSelectors.currentImageSettings(useUserStore.getState());
|
|
334
|
+
set({ imageNum: defaultImageNum, isInit: true }, false, 'initializeImageConfig/default');
|
|
335
|
+
},
|
|
336
|
+
|
|
330
337
|
initializeImageConfig: (isLogin, lastSelectedImageModel, lastSelectedImageProvider) => {
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
let actualLastSelectedImageModel = lastSelectedImageModel;
|
|
334
|
-
let actualLastSelectedImageProvider = lastSelectedImageProvider;
|
|
335
|
-
|
|
336
|
-
if (typeof isLogin === 'undefined') {
|
|
337
|
-
const globalStatus = useGlobalStore.getState().status;
|
|
338
|
-
actualIsLogin = authSelectors.isLogin(useUserStore.getState());
|
|
339
|
-
actualLastSelectedImageModel = globalStatus.lastSelectedImageModel;
|
|
340
|
-
actualLastSelectedImageProvider = globalStatus.lastSelectedImageProvider;
|
|
341
|
-
}
|
|
338
|
+
const { _initializeDefaultImageConfig } = get();
|
|
339
|
+
const { defaultImageNum } = settingsSelectors.currentImageSettings(useUserStore.getState());
|
|
342
340
|
|
|
343
|
-
if (
|
|
341
|
+
if (isLogin && lastSelectedImageModel && lastSelectedImageProvider) {
|
|
344
342
|
try {
|
|
345
343
|
const { defaultValues, parametersSchema, initialActiveRatio } = prepareModelConfigState(
|
|
346
|
-
|
|
347
|
-
|
|
344
|
+
lastSelectedImageModel,
|
|
345
|
+
lastSelectedImageProvider,
|
|
348
346
|
);
|
|
349
347
|
|
|
350
348
|
set(
|
|
351
349
|
{
|
|
352
|
-
model:
|
|
353
|
-
provider:
|
|
350
|
+
model: lastSelectedImageModel,
|
|
351
|
+
provider: lastSelectedImageProvider,
|
|
354
352
|
parameters: defaultValues,
|
|
355
353
|
parametersSchema,
|
|
356
354
|
isAspectRatioLocked: false,
|
|
357
355
|
activeAspectRatio: initialActiveRatio,
|
|
356
|
+
imageNum: defaultImageNum,
|
|
358
357
|
isInit: true,
|
|
359
358
|
},
|
|
360
359
|
false,
|
|
361
|
-
`initializeImageConfig/${
|
|
360
|
+
`initializeImageConfig/${lastSelectedImageModel}/${lastSelectedImageProvider}`,
|
|
362
361
|
);
|
|
363
362
|
} catch {
|
|
364
|
-
|
|
365
|
-
set({ isInit: true }, false, 'initializeImageConfig/fallback');
|
|
363
|
+
_initializeDefaultImageConfig();
|
|
366
364
|
}
|
|
367
365
|
} else {
|
|
368
|
-
|
|
369
|
-
set({ isInit: true }, false, 'initializeImageConfig/default');
|
|
366
|
+
_initializeDefaultImageConfig();
|
|
370
367
|
}
|
|
371
368
|
},
|
|
372
369
|
});
|
|
@@ -7,9 +7,10 @@ import {
|
|
|
7
7
|
gptImage1ParamsSchema,
|
|
8
8
|
} from 'model-bank';
|
|
9
9
|
|
|
10
|
+
import { DEFAULT_IMAGE_CONFIG } from '@/const/settings';
|
|
11
|
+
|
|
10
12
|
export const DEFAULT_AI_IMAGE_PROVIDER = ModelProvider.OpenAI;
|
|
11
13
|
export const DEFAULT_AI_IMAGE_MODEL = 'gpt-image-1';
|
|
12
|
-
export const DEFAULT_IMAGE_NUM = 4;
|
|
13
14
|
|
|
14
15
|
export interface GenerationConfigState {
|
|
15
16
|
parameters: RuntimeImageGenParams;
|
|
@@ -34,7 +35,7 @@ export const DEFAULT_IMAGE_GENERATION_PARAMETERS: RuntimeImageGenParams =
|
|
|
34
35
|
export const initialGenerationConfigState: GenerationConfigState = {
|
|
35
36
|
model: DEFAULT_AI_IMAGE_MODEL,
|
|
36
37
|
provider: DEFAULT_AI_IMAGE_PROVIDER,
|
|
37
|
-
imageNum:
|
|
38
|
+
imageNum: DEFAULT_IMAGE_CONFIG.defaultImageNum,
|
|
38
39
|
parameters: DEFAULT_IMAGE_GENERATION_PARAMETERS,
|
|
39
40
|
parametersSchema: gptImage1ParamsSchema,
|
|
40
41
|
isAspectRatioLocked: false,
|
|
@@ -78,6 +78,7 @@ export const createCommonSlice: StateCreator<
|
|
|
78
78
|
// merge settings
|
|
79
79
|
const serverSettings: PartialDeep<UserSettings> = {
|
|
80
80
|
defaultAgent: serverConfig.defaultAgent,
|
|
81
|
+
image: serverConfig.image,
|
|
81
82
|
languageModel: serverConfig.languageModel,
|
|
82
83
|
systemAgent: serverConfig.systemAgent,
|
|
83
84
|
};
|
|
@@ -25,6 +25,8 @@ export const currentLLMSettings = (s: UserStore): UserModelProviderConfig =>
|
|
|
25
25
|
export const getProviderConfigById = (provider: string) => (s: UserStore) =>
|
|
26
26
|
currentLLMSettings(s)[provider as GlobalLLMProviderKey] as ProviderConfig | undefined;
|
|
27
27
|
|
|
28
|
+
const currentImageSettings = (s: UserStore) => currentSettings(s).image;
|
|
29
|
+
|
|
28
30
|
const currentTTS = (s: UserStore) => merge(DEFAULT_TTS_CONFIG, currentSettings(s).tts);
|
|
29
31
|
|
|
30
32
|
const defaultAgent = (s: UserStore) => merge(DEFAULT_AGENT, currentSettings(s).defaultAgent);
|
|
@@ -44,6 +46,7 @@ const getHotkeyById = (id: HotkeyId) => (s: UserStore) =>
|
|
|
44
46
|
merge(DEFAULT_HOTKEY_CONFIG, currentSettings(s).hotkey)[id];
|
|
45
47
|
|
|
46
48
|
export const settingsSelectors = {
|
|
49
|
+
currentImageSettings,
|
|
47
50
|
currentSettings,
|
|
48
51
|
currentSystemAgent,
|
|
49
52
|
currentTTS,
|