@lobehub/chat 1.103.1 → 1.103.2
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 +35 -0
- package/apps/desktop/build/icon-beta.ico +0 -0
- package/apps/desktop/build/icon-dev.ico +0 -0
- package/apps/desktop/build/icon-nightly.ico +0 -0
- package/apps/desktop/build/icon.ico +0 -0
- package/apps/desktop/electron.vite.config.ts +4 -2
- package/apps/desktop/package.json +1 -0
- package/apps/desktop/src/main/appBrowsers.ts +2 -2
- package/apps/desktop/src/main/const/env.ts +5 -4
- package/apps/desktop/src/main/const/store.ts +1 -0
- package/apps/desktop/src/main/const/theme.ts +11 -0
- package/apps/desktop/src/main/controllers/BrowserWindowsCtr.ts +1 -1
- package/apps/desktop/src/main/controllers/NotificationCtr.ts +2 -4
- package/apps/desktop/src/main/controllers/SystemCtr.ts +4 -0
- package/apps/desktop/src/main/controllers/TrayMenuCtr.ts +5 -5
- package/apps/desktop/src/main/controllers/index.ts +1 -1
- package/apps/desktop/src/main/core/App.ts +9 -10
- package/apps/desktop/src/main/core/{Browser.ts → browser/Browser.ts} +129 -88
- package/apps/desktop/src/main/core/{BrowserManager.ts → browser/BrowserManager.ts} +13 -3
- package/apps/desktop/src/main/core/{StaticFileServerManager.ts → infrastructure/StaticFileServerManager.ts} +13 -7
- package/apps/desktop/src/main/core/{StoreManager.ts → infrastructure/StoreManager.ts} +1 -1
- package/apps/desktop/src/main/core/{UpdaterManager.ts → infrastructure/UpdaterManager.ts} +1 -1
- package/apps/desktop/src/main/core/{MenuManager.ts → ui/MenuManager.ts} +2 -2
- package/apps/desktop/src/main/core/{ShortcutManager.ts → ui/ShortcutManager.ts} +7 -1
- package/apps/desktop/src/main/core/{Tray.ts → ui/Tray.ts} +61 -59
- package/apps/desktop/src/main/core/{TrayManager.ts → ui/TrayManager.ts} +5 -5
- package/apps/desktop/src/main/shortcuts/config.ts +2 -2
- package/apps/desktop/src/main/types/store.ts +1 -0
- package/changelog/v1.json +12 -0
- package/docs/development/basic/add-new-image-model.mdx +162 -0
- package/docs/development/basic/add-new-image-model.zh-CN.mdx +162 -0
- package/docs/usage/providers/fal.mdx +1 -1
- package/docs/usage/providers/fal.zh-CN.mdx +1 -1
- package/package.json +66 -66
- package/src/app/[variants]/(main)/chat/(workspace)/_layout/Desktop/Portal.tsx +3 -1
- package/src/app/[variants]/(main)/chat/(workspace)/features/AgentSettings/index.tsx +4 -2
- package/src/app/[variants]/(main)/image/@menu/components/SeedNumberInput/index.tsx +1 -1
- package/src/app/[variants]/(main)/image/features/GenerationFeed/BatchItem.tsx +39 -3
- package/src/app/[variants]/(main)/image/features/GenerationFeed/ReferenceImages.tsx +122 -0
- package/src/config/aiModels/fal.ts +31 -7
- package/src/config/aiModels/openai.ts +10 -1
- package/src/features/ElectronTitlebar/WinControl/index.tsx +85 -90
- package/src/features/ElectronTitlebar/hooks/useWatchThemeUpdate.ts +10 -5
- package/src/features/ImageTopicPanel/index.tsx +0 -1
- package/src/features/PluginDevModal/index.tsx +3 -1
- package/src/features/User/__tests__/UserAvatar.test.tsx +5 -4
- package/src/libs/model-runtime/fal/index.ts +1 -1
- package/src/libs/model-runtime/types/image.ts +1 -1
- package/src/libs/model-runtime/utils/openaiCompatibleFactory/index.ts +1 -1
- package/src/libs/model-runtime/utils/response.ts +2 -0
- package/src/libs/model-runtime/utils/streams/google-ai.test.ts +46 -0
- package/src/libs/model-runtime/utils/streams/google-ai.ts +4 -4
- package/src/libs/model-runtime/utils/streams/vertex-ai.ts +6 -8
- package/src/libs/standard-parameters/{meta-schema.test.ts → index.test.ts} +1 -1
- package/src/libs/standard-parameters/index.ts +152 -1
- package/src/server/ld.test.ts +4 -3
- package/src/server/routers/async/image.ts +1 -1
- package/src/services/__tests__/chat.test.ts +3 -4
- package/src/store/chat/slices/message/selectors.test.ts +2 -3
- package/src/store/chat/slices/plugin/action.test.ts +2 -1
- package/src/store/image/slices/generationConfig/action.test.ts +2 -2
- package/src/store/image/slices/generationConfig/action.ts +1 -1
- package/src/store/image/slices/generationConfig/hooks.test.ts +2 -2
- package/src/store/image/slices/generationConfig/hooks.ts +1 -4
- package/src/store/image/slices/generationConfig/initialState.ts +2 -2
- package/src/store/image/slices/generationConfig/selectors.test.ts +2 -2
- package/src/store/image/slices/generationConfig/selectors.ts +1 -1
- package/src/store/user/slices/auth/selectors.test.ts +3 -2
- package/src/types/generation/index.ts +1 -0
- package/docs/development/basic/add-new-ai-image-model.mdx +0 -36
- package/docs/development/basic/add-new-ai-image-model.zh-CN.mdx +0 -0
- package/src/config/paramsSchemas/fal/flux-kontext-dev.ts +0 -8
- package/src/config/paramsSchemas/fal/flux-pro-kontext.ts +0 -11
- package/src/config/paramsSchemas/fal/flux-schnell.ts +0 -9
- package/src/config/paramsSchemas/fal/imagen4.ts +0 -10
- package/src/config/paramsSchemas/openai/gpt-image-1.ts +0 -10
- package/src/libs/standard-parameters/meta-schema.ts +0 -147
- /package/apps/desktop/src/main/core/{I18nManager.ts → infrastructure/I18nManager.ts} +0 -0
- /package/apps/desktop/src/main/core/{IoCContainer.ts → infrastructure/IoCContainer.ts} +0 -0
@@ -1 +1,152 @@
|
|
1
|
-
|
1
|
+
import type { Simplify } from 'type-fest';
|
2
|
+
import { z } from 'zod';
|
3
|
+
|
4
|
+
export const MAX_SEED = 2 ** 31 - 1;
|
5
|
+
|
6
|
+
// 定义顶层的元规范 - 平铺结构
|
7
|
+
export const ModelParamsMetaSchema = z.object({
|
8
|
+
aspectRatio: z
|
9
|
+
.object({
|
10
|
+
default: z.string(),
|
11
|
+
description: z.string().optional(),
|
12
|
+
enum: z.array(z.string()),
|
13
|
+
type: z.literal('string').optional(),
|
14
|
+
})
|
15
|
+
.optional(),
|
16
|
+
|
17
|
+
cfg: z
|
18
|
+
.object({
|
19
|
+
default: z.number(),
|
20
|
+
description: z.string().optional(),
|
21
|
+
max: z.number(),
|
22
|
+
min: z.number(),
|
23
|
+
step: z.number(),
|
24
|
+
type: z.literal('number').optional(),
|
25
|
+
})
|
26
|
+
.optional(),
|
27
|
+
|
28
|
+
height: z
|
29
|
+
.object({
|
30
|
+
default: z.number(),
|
31
|
+
description: z.string().optional(),
|
32
|
+
max: z.number(),
|
33
|
+
min: z.number(),
|
34
|
+
step: z.number().optional().default(1),
|
35
|
+
type: z.literal('number').optional(),
|
36
|
+
})
|
37
|
+
.optional(),
|
38
|
+
|
39
|
+
imageUrl: z
|
40
|
+
.object({
|
41
|
+
default: z.string().nullable().optional(),
|
42
|
+
description: z.string().optional(),
|
43
|
+
type: z.tuple([z.literal('string'), z.literal('null')]).optional(),
|
44
|
+
})
|
45
|
+
.optional(),
|
46
|
+
|
47
|
+
imageUrls: z
|
48
|
+
.object({
|
49
|
+
default: z.array(z.string()),
|
50
|
+
description: z.string().optional(),
|
51
|
+
type: z.literal('array').optional(),
|
52
|
+
})
|
53
|
+
.optional(),
|
54
|
+
|
55
|
+
/**
|
56
|
+
* Prompt 是唯一一个每个模型都有的参数
|
57
|
+
*/
|
58
|
+
prompt: z.object({
|
59
|
+
default: z.string().optional().default(''),
|
60
|
+
description: z.string().optional(),
|
61
|
+
type: z.literal('string').optional(),
|
62
|
+
}),
|
63
|
+
|
64
|
+
seed: z
|
65
|
+
.object({
|
66
|
+
default: z.number().nullable().default(null),
|
67
|
+
description: z.string().optional(),
|
68
|
+
max: z.number().optional().default(MAX_SEED),
|
69
|
+
min: z.number().optional().default(0),
|
70
|
+
type: z.tuple([z.literal('number'), z.literal('null')]).optional(),
|
71
|
+
})
|
72
|
+
.optional(),
|
73
|
+
|
74
|
+
size: z
|
75
|
+
.object({
|
76
|
+
default: z.string(),
|
77
|
+
description: z.string().optional(),
|
78
|
+
enum: z.array(z.string()),
|
79
|
+
type: z.literal('string').optional(),
|
80
|
+
})
|
81
|
+
.optional(),
|
82
|
+
|
83
|
+
steps: z
|
84
|
+
.object({
|
85
|
+
default: z.number(),
|
86
|
+
description: z.string().optional(),
|
87
|
+
max: z.number(),
|
88
|
+
min: z.number(),
|
89
|
+
step: z.number().optional().default(1),
|
90
|
+
type: z.literal('number').optional(),
|
91
|
+
})
|
92
|
+
.optional(),
|
93
|
+
|
94
|
+
width: z
|
95
|
+
.object({
|
96
|
+
default: z.number(),
|
97
|
+
description: z.string().optional(),
|
98
|
+
max: z.number(),
|
99
|
+
min: z.number(),
|
100
|
+
step: z.number().optional().default(1),
|
101
|
+
type: z.literal('number').optional(),
|
102
|
+
})
|
103
|
+
.optional(),
|
104
|
+
});
|
105
|
+
// 导出推断出的类型,供定义对象使用
|
106
|
+
export type ModelParamsSchema = z.input<typeof ModelParamsMetaSchema>;
|
107
|
+
export type ModelParamsOutputSchema = z.output<typeof ModelParamsMetaSchema>;
|
108
|
+
export type ModelParamsKeys = Simplify<keyof ModelParamsOutputSchema>;
|
109
|
+
|
110
|
+
type TypeMapping<T> = T extends 'string'
|
111
|
+
? string
|
112
|
+
: T extends 'number'
|
113
|
+
? number
|
114
|
+
: T extends ['number', 'null']
|
115
|
+
? number | null
|
116
|
+
: T extends ['string', 'null']
|
117
|
+
? string | null
|
118
|
+
: T extends 'string'
|
119
|
+
? string
|
120
|
+
: T extends 'boolean'
|
121
|
+
? boolean
|
122
|
+
: never;
|
123
|
+
type TypeType<K extends ModelParamsKeys> = NonNullable<ModelParamsOutputSchema[K]>['type'];
|
124
|
+
type DefaultType<K extends ModelParamsKeys> = NonNullable<ModelParamsOutputSchema[K]>['default'];
|
125
|
+
type _StandardImageGenerationParameters<P extends ModelParamsKeys = ModelParamsKeys> = {
|
126
|
+
[key in P]: NonNullable<TypeType<key>> extends 'array'
|
127
|
+
? DefaultType<key>
|
128
|
+
: TypeMapping<TypeType<key>>;
|
129
|
+
};
|
130
|
+
|
131
|
+
export type RuntimeImageGenParams = Pick<_StandardImageGenerationParameters, 'prompt'> &
|
132
|
+
Partial<Omit<_StandardImageGenerationParameters, 'prompt'>>;
|
133
|
+
export type RuntimeImageGenParamsKeys = keyof RuntimeImageGenParams;
|
134
|
+
export type RuntimeImageGenParamsValue = RuntimeImageGenParams[RuntimeImageGenParamsKeys];
|
135
|
+
|
136
|
+
// 验证函数
|
137
|
+
export function validateModelParamsSchema(paramsSchema: unknown): ModelParamsOutputSchema {
|
138
|
+
return ModelParamsMetaSchema.parse(paramsSchema);
|
139
|
+
}
|
140
|
+
|
141
|
+
/**
|
142
|
+
* 从参数定义对象提取默认值
|
143
|
+
*/
|
144
|
+
export function extractDefaultValues(paramsSchema: ModelParamsSchema) {
|
145
|
+
// 部分默认值从 ModelParamsMetaSchema 中获取
|
146
|
+
const schemaWithDefault = ModelParamsMetaSchema.parse(paramsSchema);
|
147
|
+
return Object.fromEntries(
|
148
|
+
Object.entries(schemaWithDefault).map(([key, value]) => {
|
149
|
+
return [key, value.default];
|
150
|
+
}),
|
151
|
+
) as RuntimeImageGenParams;
|
152
|
+
}
|
package/src/server/ld.test.ts
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
// @vitest-environment node
|
2
2
|
import { describe, expect, it } from 'vitest';
|
3
3
|
|
4
|
+
import { BRANDING_NAME } from '@/const/branding';
|
4
5
|
import { DEFAULT_LANG } from '@/const/locale';
|
5
6
|
|
6
7
|
import { AUTHOR_LIST, Ld } from './ld';
|
@@ -57,7 +58,7 @@ describe('Ld', () => {
|
|
57
58
|
});
|
58
59
|
|
59
60
|
expect(webpage['@type']).toBe('WebPage');
|
60
|
-
expect(webpage.name).toBe(
|
61
|
+
expect(webpage.name).toBe(`Test Page · ${BRANDING_NAME}`);
|
61
62
|
expect(webpage.description).toBe('Test Description');
|
62
63
|
});
|
63
64
|
});
|
@@ -79,7 +80,7 @@ describe('Ld', () => {
|
|
79
80
|
const website = ld.genWebSite();
|
80
81
|
|
81
82
|
expect(website['@type']).toBe('WebSite');
|
82
|
-
expect(website.name).toBe(
|
83
|
+
expect(website.name).toBe(BRANDING_NAME);
|
83
84
|
});
|
84
85
|
});
|
85
86
|
|
@@ -95,7 +96,7 @@ describe('Ld', () => {
|
|
95
96
|
});
|
96
97
|
|
97
98
|
expect(article['@type']).toBe('Article');
|
98
|
-
expect(article.headline).toBe(
|
99
|
+
expect(article.headline).toBe(`Test Article · ${BRANDING_NAME}`);
|
99
100
|
expect(article.author['@type']).toBe('Person');
|
100
101
|
});
|
101
102
|
});
|
@@ -5,7 +5,7 @@ import { ASYNC_TASK_TIMEOUT, AsyncTaskModel } from '@/database/models/asyncTask'
|
|
5
5
|
import { FileModel } from '@/database/models/file';
|
6
6
|
import { GenerationModel } from '@/database/models/generation';
|
7
7
|
import { AgentRuntimeErrorType } from '@/libs/model-runtime/error';
|
8
|
-
import { RuntimeImageGenParams } from '@/libs/standard-parameters/
|
8
|
+
import { RuntimeImageGenParams } from '@/libs/standard-parameters/index';
|
9
9
|
import { asyncAuthedProcedure, asyncRouter as router } from '@/libs/trpc/async';
|
10
10
|
import { initAgentRuntimeWithUserPayload } from '@/server/modules/AgentRuntime';
|
11
11
|
import { GenerationService } from '@/server/services/generation';
|
@@ -4,6 +4,7 @@ import { merge } from 'lodash-es';
|
|
4
4
|
import OpenAI from 'openai';
|
5
5
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
6
6
|
|
7
|
+
import { DEFAULT_USER_AVATAR } from '@/const/meta';
|
7
8
|
import { DEFAULT_AGENT_CONFIG } from '@/const/settings';
|
8
9
|
import {
|
9
10
|
LobeAnthropicAI,
|
@@ -31,8 +32,6 @@ import { aiModelSelectors } from '@/store/aiInfra';
|
|
31
32
|
import { useToolStore } from '@/store/tool';
|
32
33
|
import { toolSelectors } from '@/store/tool/selectors';
|
33
34
|
import { UserStore } from '@/store/user';
|
34
|
-
import { useUserStore } from '@/store/user';
|
35
|
-
import { modelConfigSelectors } from '@/store/user/selectors';
|
36
35
|
import { UserSettingsState, initialSettingsState } from '@/store/user/slices/settings/initialState';
|
37
36
|
import { DalleManifest } from '@/tools/dalle';
|
38
37
|
import { WebBrowsingManifest } from '@/tools/web-browsing';
|
@@ -671,7 +670,7 @@ describe('ChatService', () => {
|
|
671
670
|
updatedAt: 1702723964330,
|
672
671
|
extra: {},
|
673
672
|
meta: {
|
674
|
-
avatar:
|
673
|
+
avatar: DEFAULT_USER_AVATAR,
|
675
674
|
},
|
676
675
|
},
|
677
676
|
] as ChatMessage[];
|
@@ -913,7 +912,7 @@ describe('ChatService', () => {
|
|
913
912
|
updatedAt: 1702723964330,
|
914
913
|
extra: {},
|
915
914
|
meta: {
|
916
|
-
avatar:
|
915
|
+
avatar: DEFAULT_USER_AVATAR,
|
917
916
|
},
|
918
917
|
},
|
919
918
|
] as ChatMessage[];
|
@@ -10,7 +10,6 @@ import { messageMapKey } from '@/store/chat/utils/messageMapKey';
|
|
10
10
|
import { createServerConfigStore } from '@/store/serverConfig/store';
|
11
11
|
import { LobeAgentConfig } from '@/types/agent';
|
12
12
|
import { ChatMessage } from '@/types/message';
|
13
|
-
import { MetaData } from '@/types/meta';
|
14
13
|
import { merge } from '@/utils/merge';
|
15
14
|
|
16
15
|
import { chatSelectors } from './selectors';
|
@@ -91,7 +90,7 @@ const mockedChats = [
|
|
91
90
|
content: 'Function Message',
|
92
91
|
role: 'tool',
|
93
92
|
meta: {
|
94
|
-
avatar:
|
93
|
+
avatar: DEFAULT_INBOX_AVATAR,
|
95
94
|
backgroundColor: 'rgba(0,0,0,0)',
|
96
95
|
description: 'inbox.desc',
|
97
96
|
title: 'inbox.title',
|
@@ -234,7 +233,7 @@ describe('chatSelectors', () => {
|
|
234
233
|
content: 'Function Message',
|
235
234
|
role: 'tool',
|
236
235
|
meta: {
|
237
|
-
avatar:
|
236
|
+
avatar: DEFAULT_INBOX_AVATAR,
|
238
237
|
backgroundColor: 'rgba(0,0,0,0)',
|
239
238
|
description: 'inbox.desc',
|
240
239
|
title: 'inbox.title',
|
@@ -2,6 +2,7 @@ import { act, renderHook } from '@testing-library/react';
|
|
2
2
|
import { Mock, afterEach, describe, expect, it, vi } from 'vitest';
|
3
3
|
|
4
4
|
import { LOADING_FLAT } from '@/const/message';
|
5
|
+
import { DEFAULT_INBOX_AVATAR } from '@/const/meta';
|
5
6
|
import { PLUGIN_SCHEMA_API_MD5_PREFIX, PLUGIN_SCHEMA_SEPARATOR } from '@/const/plugin';
|
6
7
|
import { chatService } from '@/services/chat';
|
7
8
|
import { messageService } from '@/services/message';
|
@@ -66,7 +67,7 @@ describe('ChatPluginAction', () => {
|
|
66
67
|
{
|
67
68
|
...toolMessage,
|
68
69
|
meta: {
|
69
|
-
avatar:
|
70
|
+
avatar: DEFAULT_INBOX_AVATAR,
|
70
71
|
backgroundColor: 'rgba(0,0,0,0)',
|
71
72
|
description: undefined,
|
72
73
|
title: undefined,
|
@@ -1,12 +1,12 @@
|
|
1
1
|
import { act, renderHook } from '@testing-library/react';
|
2
2
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
3
3
|
|
4
|
-
import { fluxSchnellParamsSchema } from '@/config/
|
4
|
+
import { fluxSchnellParamsSchema } from '@/config/aiModels/fal';
|
5
5
|
import {
|
6
6
|
ModelParamsSchema,
|
7
7
|
RuntimeImageGenParams,
|
8
8
|
extractDefaultValues,
|
9
|
-
} from '@/libs/standard-parameters/
|
9
|
+
} from '@/libs/standard-parameters/index';
|
10
10
|
import { useImageStore } from '@/store/image';
|
11
11
|
import { AIImageModelCard } from '@/types/aiModel';
|
12
12
|
|
@@ -6,7 +6,7 @@ import {
|
|
6
6
|
RuntimeImageGenParamsKeys,
|
7
7
|
RuntimeImageGenParamsValue,
|
8
8
|
extractDefaultValues,
|
9
|
-
} from '@/libs/standard-parameters/
|
9
|
+
} from '@/libs/standard-parameters/index';
|
10
10
|
import { aiProviderSelectors, getAiInfraStoreState } from '@/store/aiInfra';
|
11
11
|
import { AIImageModelCard } from '@/types/aiModel';
|
12
12
|
|
@@ -1,8 +1,8 @@
|
|
1
1
|
import { act, renderHook } from '@testing-library/react';
|
2
2
|
import { describe, expect, it, vi } from 'vitest';
|
3
3
|
|
4
|
-
import { fluxSchnellParamsSchema } from '@/config/
|
5
|
-
import { ModelParamsSchema, RuntimeImageGenParams } from '@/libs/standard-parameters/
|
4
|
+
import { fluxSchnellParamsSchema } from '@/config/aiModels/fal';
|
5
|
+
import { ModelParamsSchema, RuntimeImageGenParams } from '@/libs/standard-parameters/index';
|
6
6
|
import { useImageStore } from '@/store/image';
|
7
7
|
import { AIImageModelCard } from '@/types/aiModel';
|
8
8
|
|
@@ -1,10 +1,7 @@
|
|
1
1
|
import { useCallback, useMemo } from 'react';
|
2
2
|
|
3
3
|
import { DEFAULT_ASPECT_RATIO, PRESET_ASPECT_RATIOS } from '@/const/image';
|
4
|
-
import {
|
5
|
-
RuntimeImageGenParams,
|
6
|
-
RuntimeImageGenParamsKeys,
|
7
|
-
} from '@/libs/standard-parameters/meta-schema';
|
4
|
+
import { RuntimeImageGenParams, RuntimeImageGenParamsKeys } from '@/libs/standard-parameters/index';
|
8
5
|
|
9
6
|
import { useImageStore } from '../../store';
|
10
7
|
import { imageGenerationConfigSelectors } from './selectors';
|
@@ -1,11 +1,11 @@
|
|
1
1
|
/* eslint-disable sort-keys-fix/sort-keys-fix, typescript-sort-keys/interface */
|
2
|
-
import { gptImage1ParamsSchema } from '@/config/
|
2
|
+
import { gptImage1ParamsSchema } from '@/config/aiModels/openai';
|
3
3
|
import { ModelProvider } from '@/libs/model-runtime/types/type';
|
4
4
|
import {
|
5
5
|
ModelParamsSchema,
|
6
6
|
RuntimeImageGenParams,
|
7
7
|
extractDefaultValues,
|
8
|
-
} from '@/libs/standard-parameters/
|
8
|
+
} from '@/libs/standard-parameters/index';
|
9
9
|
|
10
10
|
export const DEFAULT_AI_IMAGE_PROVIDER = ModelProvider.OpenAI;
|
11
11
|
export const DEFAULT_AI_IMAGE_MODEL = 'gpt-image-1';
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import { describe, expect, it, vi } from 'vitest';
|
2
2
|
|
3
|
-
import { gptImage1ParamsSchema } from '@/config/
|
4
|
-
import { ModelParamsSchema, RuntimeImageGenParams } from '@/libs/standard-parameters/
|
3
|
+
import { gptImage1ParamsSchema } from '@/config/aiModels/openai';
|
4
|
+
import { ModelParamsSchema, RuntimeImageGenParams } from '@/libs/standard-parameters/index';
|
5
5
|
import { ImageStore } from '@/store/image';
|
6
6
|
import { initialState } from '@/store/image/initialState';
|
7
7
|
import { AIImageModelCard } from '@/types/aiModel';
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import { t } from 'i18next';
|
2
2
|
import { afterEach, describe, expect, it, vi } from 'vitest';
|
3
3
|
|
4
|
+
import { BRANDING_NAME } from '@/const/branding';
|
4
5
|
import { UserStore } from '@/store/user';
|
5
6
|
|
6
7
|
import { authSelectors, userProfileSelectors } from './selectors';
|
@@ -44,7 +45,7 @@ describe('userProfileSelectors', () => {
|
|
44
45
|
enableAuth: () => false,
|
45
46
|
} as unknown as UserStore;
|
46
47
|
|
47
|
-
expect(userProfileSelectors.displayUserName(store)).toBe(
|
48
|
+
expect(userProfileSelectors.displayUserName(store)).toBe(BRANDING_NAME);
|
48
49
|
});
|
49
50
|
|
50
51
|
it('should return user username when auth is disabled and is desktop', () => {
|
@@ -202,7 +203,7 @@ describe('userProfileSelectors', () => {
|
|
202
203
|
enableAuth: () => false,
|
203
204
|
} as unknown as UserStore;
|
204
205
|
|
205
|
-
expect(userProfileSelectors.username(store)).toBe(
|
206
|
+
expect(userProfileSelectors.username(store)).toBe(BRANDING_NAME);
|
206
207
|
});
|
207
208
|
|
208
209
|
it('should return user username when auth is disabled and is desktop', () => {
|
@@ -1,36 +0,0 @@
|
|
1
|
-
# 添加新的 AI 图像模型
|
2
|
-
|
3
|
-
## 兼容 openai 请求格式的模型
|
4
|
-
|
5
|
-
指的是可以使用 openai SDK 进行请求,并且请求参数和和返回值和 dall-e 以及 gpt-image-x 系列一致。
|
6
|
-
|
7
|
-
以智谱的 CogView-4 为例,它是一个兼容 openai 请求格式的模型,可以按照以下步骤添加:
|
8
|
-
|
9
|
-
1. 在对应的 ai models 文件 `src/config/aiModels/zhipu.ts` 中,添加模型配置,例如:
|
10
|
-
|
11
|
-
```ts
|
12
|
-
const zhipuImageModels: AIImageModelCard[] = [
|
13
|
-
// 添加模型配置
|
14
|
-
// https://bigmodel.cn/dev/howuse/image-generation-model/cogview-4
|
15
|
-
{
|
16
|
-
description:
|
17
|
-
'CogView-4 是智谱首个支持生成汉字的开源文生图模型,在语义理解、图像生成质量、中英文字生成能力等方面全面提升,支持任意长度的中英双语输入,能够生成在给定范围内的任意分辨率图像。',
|
18
|
-
displayName: 'CogView-4',
|
19
|
-
enabled: true,
|
20
|
-
id: 'cogview-4',
|
21
|
-
parameters: {
|
22
|
-
prompt: {
|
23
|
-
default: '',
|
24
|
-
},
|
25
|
-
size: {
|
26
|
-
default: '1024x1024',
|
27
|
-
enum: ['1024x1024', '768x1344', '864x1152', '1344x768', '1152x864', '1440x720', '720x1440'],
|
28
|
-
},
|
29
|
-
},
|
30
|
-
releasedAt: '2025-03-04',
|
31
|
-
type: 'image',
|
32
|
-
},
|
33
|
-
];
|
34
|
-
```
|
35
|
-
|
36
|
-
2. 执行下 `npx i18n` 命令,更新模型描述的翻译文件
|
File without changes
|
@@ -1,8 +0,0 @@
|
|
1
|
-
import { type ModelParamsSchema } from '@/libs/standard-parameters/meta-schema';
|
2
|
-
|
3
|
-
export const fluxKontextDevParamsSchema: ModelParamsSchema = {
|
4
|
-
imageUrl: { default: null },
|
5
|
-
prompt: { default: '' },
|
6
|
-
seed: { default: null },
|
7
|
-
steps: { default: 28, max: 50, min: 10 },
|
8
|
-
};
|
@@ -1,11 +0,0 @@
|
|
1
|
-
import { type ModelParamsSchema } from '@/libs/standard-parameters/meta-schema';
|
2
|
-
|
3
|
-
export const fluxProKontextParamsSchema: ModelParamsSchema = {
|
4
|
-
aspectRatio: {
|
5
|
-
default: '1:1',
|
6
|
-
enum: ['21:9', '16:9', '4:3', '3:2', '1:1', '2:3', '3:4', '9:16', '9:21'],
|
7
|
-
},
|
8
|
-
imageUrl: { default: null },
|
9
|
-
prompt: { default: '' },
|
10
|
-
seed: { default: null },
|
11
|
-
};
|
@@ -1,9 +0,0 @@
|
|
1
|
-
import { type ModelParamsSchema } from '@/libs/standard-parameters/meta-schema';
|
2
|
-
|
3
|
-
export const fluxSchnellParamsSchema: ModelParamsSchema = {
|
4
|
-
height: { default: 1024, max: 1536, min: 512, step: 1 },
|
5
|
-
prompt: { default: '' },
|
6
|
-
seed: { default: null },
|
7
|
-
steps: { default: 4, max: 12, min: 1 },
|
8
|
-
width: { default: 1024, max: 1536, min: 512, step: 1 },
|
9
|
-
};
|
@@ -1,10 +0,0 @@
|
|
1
|
-
import { type ModelParamsSchema } from '@/libs/standard-parameters/meta-schema';
|
2
|
-
|
3
|
-
export const imagen4ParamsSchema: ModelParamsSchema = {
|
4
|
-
aspectRatio: {
|
5
|
-
default: '1:1',
|
6
|
-
enum: ['1:1', '16:9', '9:16', '3:4', '4:3'],
|
7
|
-
},
|
8
|
-
prompt: { default: '' },
|
9
|
-
seed: { default: null },
|
10
|
-
};
|
@@ -1,10 +0,0 @@
|
|
1
|
-
import { type ModelParamsSchema } from '@/libs/standard-parameters/meta-schema';
|
2
|
-
|
3
|
-
export const gptImage1ParamsSchema: ModelParamsSchema = {
|
4
|
-
imageUrls: { default: [] },
|
5
|
-
prompt: { default: '' },
|
6
|
-
size: {
|
7
|
-
default: 'auto',
|
8
|
-
enum: ['auto', '1024x1024', '1536x1024', '1024x1536'],
|
9
|
-
},
|
10
|
-
};
|
@@ -1,147 +0,0 @@
|
|
1
|
-
import type { Simplify } from 'type-fest';
|
2
|
-
import { z } from 'zod';
|
3
|
-
|
4
|
-
export const MAX_SEED = 2 ** 31 - 1;
|
5
|
-
|
6
|
-
// 定义顶层的元规范 - 平铺结构
|
7
|
-
export const ModelParamsMetaSchema = z.object({
|
8
|
-
aspectRatio: z
|
9
|
-
.object({
|
10
|
-
default: z.string(),
|
11
|
-
description: z.string().optional(),
|
12
|
-
enum: z.array(z.string()),
|
13
|
-
type: z.literal('string').optional(),
|
14
|
-
})
|
15
|
-
.optional(),
|
16
|
-
|
17
|
-
cfg: z
|
18
|
-
.object({
|
19
|
-
default: z.number(),
|
20
|
-
description: z.string().optional(),
|
21
|
-
max: z.number(),
|
22
|
-
min: z.number(),
|
23
|
-
step: z.number(),
|
24
|
-
type: z.literal('number').optional(),
|
25
|
-
})
|
26
|
-
.optional(),
|
27
|
-
|
28
|
-
height: z
|
29
|
-
.object({
|
30
|
-
default: z.number(),
|
31
|
-
description: z.string().optional(),
|
32
|
-
max: z.number(),
|
33
|
-
min: z.number(),
|
34
|
-
step: z.number().optional().default(1),
|
35
|
-
type: z.literal('number').optional(),
|
36
|
-
})
|
37
|
-
.optional(),
|
38
|
-
|
39
|
-
imageUrl: z
|
40
|
-
.object({
|
41
|
-
default: z.string().nullable().optional(),
|
42
|
-
description: z.string().optional(),
|
43
|
-
type: z.tuple([z.literal('string'), z.literal('null')]).optional(),
|
44
|
-
})
|
45
|
-
.optional(),
|
46
|
-
|
47
|
-
imageUrls: z
|
48
|
-
.object({
|
49
|
-
default: z.array(z.string()),
|
50
|
-
description: z.string().optional(),
|
51
|
-
type: z.literal('array').optional(),
|
52
|
-
})
|
53
|
-
.optional(),
|
54
|
-
/**
|
55
|
-
* Prompt 是唯一一个每个模型都有的参数
|
56
|
-
*/
|
57
|
-
prompt: z.object({
|
58
|
-
default: z.string().optional().default(''),
|
59
|
-
description: z.string().optional(),
|
60
|
-
type: z.literal('string').optional(),
|
61
|
-
}),
|
62
|
-
seed: z
|
63
|
-
.object({
|
64
|
-
default: z.number().nullable().default(null),
|
65
|
-
description: z.string().optional(),
|
66
|
-
max: z.number().optional().default(MAX_SEED),
|
67
|
-
min: z.number().optional().default(0),
|
68
|
-
type: z.tuple([z.literal('number'), z.literal('null')]).optional(),
|
69
|
-
})
|
70
|
-
.optional(),
|
71
|
-
size: z
|
72
|
-
.object({
|
73
|
-
default: z.string(),
|
74
|
-
description: z.string().optional(),
|
75
|
-
enum: z.array(z.string()),
|
76
|
-
type: z.literal('string').optional(),
|
77
|
-
})
|
78
|
-
.optional(),
|
79
|
-
steps: z
|
80
|
-
.object({
|
81
|
-
default: z.number(),
|
82
|
-
description: z.string().optional(),
|
83
|
-
max: z.number(),
|
84
|
-
min: z.number(),
|
85
|
-
step: z.number().optional().default(1),
|
86
|
-
type: z.literal('number').optional(),
|
87
|
-
})
|
88
|
-
.optional(),
|
89
|
-
width: z
|
90
|
-
.object({
|
91
|
-
default: z.number(),
|
92
|
-
description: z.string().optional(),
|
93
|
-
max: z.number(),
|
94
|
-
min: z.number(),
|
95
|
-
step: z.number().optional().default(1),
|
96
|
-
type: z.literal('number').optional(),
|
97
|
-
})
|
98
|
-
.optional(),
|
99
|
-
});
|
100
|
-
// 导出推断出的类型,供定义对象使用
|
101
|
-
export type ModelParamsSchema = z.input<typeof ModelParamsMetaSchema>;
|
102
|
-
export type ModelParamsOutputSchema = z.output<typeof ModelParamsMetaSchema>;
|
103
|
-
export type ModelParamsKeys = Simplify<keyof ModelParamsOutputSchema>;
|
104
|
-
|
105
|
-
type TypeMapping<T> = T extends 'string'
|
106
|
-
? string
|
107
|
-
: T extends 'number'
|
108
|
-
? number
|
109
|
-
: T extends ['number', 'null']
|
110
|
-
? number | null
|
111
|
-
: T extends ['string', 'null']
|
112
|
-
? string | null
|
113
|
-
: T extends 'string'
|
114
|
-
? string
|
115
|
-
: T extends 'boolean'
|
116
|
-
? boolean
|
117
|
-
: never;
|
118
|
-
type TypeType<K extends ModelParamsKeys> = NonNullable<ModelParamsOutputSchema[K]>['type'];
|
119
|
-
type DefaultType<K extends ModelParamsKeys> = NonNullable<ModelParamsOutputSchema[K]>['default'];
|
120
|
-
type _StandardImageGenerationParameters<P extends ModelParamsKeys = ModelParamsKeys> = {
|
121
|
-
[key in P]: NonNullable<TypeType<key>> extends 'array'
|
122
|
-
? DefaultType<key>
|
123
|
-
: TypeMapping<TypeType<key>>;
|
124
|
-
};
|
125
|
-
|
126
|
-
export type RuntimeImageGenParams = Pick<_StandardImageGenerationParameters, 'prompt'> &
|
127
|
-
Partial<Omit<_StandardImageGenerationParameters, 'prompt'>>;
|
128
|
-
export type RuntimeImageGenParamsKeys = keyof RuntimeImageGenParams;
|
129
|
-
export type RuntimeImageGenParamsValue = RuntimeImageGenParams[RuntimeImageGenParamsKeys];
|
130
|
-
|
131
|
-
// 验证函数
|
132
|
-
export function validateModelParamsSchema(paramsSchema: unknown): ModelParamsOutputSchema {
|
133
|
-
return ModelParamsMetaSchema.parse(paramsSchema);
|
134
|
-
}
|
135
|
-
|
136
|
-
/**
|
137
|
-
* 从参数定义对象提取默认值
|
138
|
-
*/
|
139
|
-
export function extractDefaultValues(paramsSchema: ModelParamsSchema) {
|
140
|
-
// 部分默认值从 ModelParamsMetaSchema 中获取
|
141
|
-
const schemaWithDefault = ModelParamsMetaSchema.parse(paramsSchema);
|
142
|
-
return Object.fromEntries(
|
143
|
-
Object.entries(schemaWithDefault).map(([key, value]) => {
|
144
|
-
return [key, value.default];
|
145
|
-
}),
|
146
|
-
) as RuntimeImageGenParams;
|
147
|
-
}
|
File without changes
|
File without changes
|