@lobehub/lobehub 2.0.0-next.231 → 2.0.0-next.233
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/.github/workflows/bundle-analyzer.yml +1 -1
- package/.github/workflows/e2e.yml +67 -52
- package/.github/workflows/manual-build-desktop.yml +5 -5
- package/.github/workflows/pr-build-desktop.yml +4 -4
- package/.github/workflows/pr-build-docker.yml +2 -2
- package/.github/workflows/release-desktop-beta.yml +4 -4
- package/.github/workflows/release-docker.yml +2 -2
- package/.github/workflows/test.yml +44 -7
- package/CHANGELOG.md +50 -0
- package/changelog/v1.json +14 -0
- package/docs/self-hosting/environment-variables/auth.mdx +7 -0
- package/docs/self-hosting/environment-variables/auth.zh-CN.mdx +7 -0
- package/package.json +1 -1
- package/packages/business/config/src/llm.ts +6 -1
- package/packages/const/src/settings/image.ts +1 -1
- package/packages/model-bank/src/aiModels/azure.ts +2 -2
- package/packages/model-bank/src/aiModels/google.ts +1 -0
- package/packages/model-bank/src/aiModels/lobehub.ts +33 -13
- package/packages/model-bank/src/aiModels/openai.ts +21 -4
- package/packages/model-runtime/src/core/openaiCompatibleFactory/createImage.ts +4 -1
- package/packages/model-runtime/src/providers/openai/__snapshots__/index.test.ts.snap +1 -1
- package/packages/ssrf-safe-fetch/index.test.ts +5 -34
- package/packages/ssrf-safe-fetch/index.ts +12 -2
- package/src/app/[variants]/(main)/image/_layout/ConfigPanel/components/MultiImagesUpload/index.tsx +3 -3
- package/src/app/[variants]/(main)/image/features/GenerationFeed/index.tsx +3 -10
- package/src/app/[variants]/(main)/image/index.tsx +1 -1
- package/src/components/Loading/BrandTextLoading/index.module.css +81 -0
- package/src/components/Loading/BrandTextLoading/index.tsx +24 -17
- package/src/envs/auth.ts +15 -0
- package/src/hooks/useFetchAiImageConfig.ts +54 -10
- package/src/libs/redis/manager.ts +63 -0
- package/src/libs/trpc/utils/internalJwt.ts +2 -2
- package/src/server/services/agent/index.test.ts +15 -8
- package/src/server/services/agent/index.ts +11 -4
- package/src/store/image/slices/generationConfig/initialState.ts +5 -5
- package/src/store/image/slices/generationConfig/selectors.test.ts +11 -4
- package/vitest.config.mts +10 -6
|
@@ -3,17 +3,20 @@ import { DEFAULT_AGENT_CONFIG } from '@lobechat/const';
|
|
|
3
3
|
import { type LobeChatDatabase } from '@lobechat/database';
|
|
4
4
|
import { type AgentItem, type LobeAgentConfig } from '@lobechat/types';
|
|
5
5
|
import { cleanObject, merge } from '@lobechat/utils';
|
|
6
|
+
import debug from 'debug';
|
|
6
7
|
import type { PartialDeep } from 'type-fest';
|
|
7
8
|
|
|
8
9
|
import { AgentModel } from '@/database/models/agent';
|
|
9
10
|
import { SessionModel } from '@/database/models/session';
|
|
10
11
|
import { UserModel } from '@/database/models/user';
|
|
11
12
|
import { getRedisConfig } from '@/envs/redis';
|
|
12
|
-
import { RedisKeyNamespace, RedisKeys,
|
|
13
|
+
import { RedisKeyNamespace, RedisKeys, initializeRedisWithPrefix, isRedisEnabled } from '@/libs/redis';
|
|
13
14
|
import { getServerDefaultAgentConfig } from '@/server/globalConfig';
|
|
14
15
|
|
|
15
16
|
import { type UpdateAgentResult } from './type';
|
|
16
17
|
|
|
18
|
+
const log = debug('lobe-agent:service');
|
|
19
|
+
|
|
17
20
|
interface AgentWelcomeData {
|
|
18
21
|
openQuestions: string[];
|
|
19
22
|
welcomeMessage: string;
|
|
@@ -113,7 +116,10 @@ export class AgentService {
|
|
|
113
116
|
*/
|
|
114
117
|
private async getAgentWelcomeFromRedis(agentId: string): Promise<AgentWelcomeData | null> {
|
|
115
118
|
try {
|
|
116
|
-
const
|
|
119
|
+
const redisConfig = getRedisConfig();
|
|
120
|
+
if (!isRedisEnabled(redisConfig)) return null;
|
|
121
|
+
|
|
122
|
+
const redis = await initializeRedisWithPrefix(redisConfig, RedisKeyNamespace.AI_GENERATION);
|
|
117
123
|
if (!redis) return null;
|
|
118
124
|
|
|
119
125
|
const key = RedisKeys.aiGeneration.agentWelcome(agentId);
|
|
@@ -121,8 +127,9 @@ export class AgentService {
|
|
|
121
127
|
if (!value) return null;
|
|
122
128
|
|
|
123
129
|
return JSON.parse(value) as AgentWelcomeData;
|
|
124
|
-
} catch {
|
|
125
|
-
//
|
|
130
|
+
} catch (error) {
|
|
131
|
+
// Log error for observability but don't break agent retrieval
|
|
132
|
+
log('Failed to get agent welcome from Redis for agent %s: %O', agentId, error);
|
|
126
133
|
return null;
|
|
127
134
|
}
|
|
128
135
|
}
|
|
@@ -4,13 +4,13 @@ import {
|
|
|
4
4
|
ModelProvider,
|
|
5
5
|
type RuntimeImageGenParams,
|
|
6
6
|
extractDefaultValues,
|
|
7
|
-
gptImage1ParamsSchema,
|
|
8
7
|
} from 'model-bank';
|
|
8
|
+
import { nanoBananaProParameters } from 'model-bank/google';
|
|
9
9
|
|
|
10
10
|
import { DEFAULT_IMAGE_CONFIG } from '@/const/settings';
|
|
11
11
|
|
|
12
|
-
export const DEFAULT_AI_IMAGE_PROVIDER = ModelProvider.
|
|
13
|
-
export const DEFAULT_AI_IMAGE_MODEL = '
|
|
12
|
+
export const DEFAULT_AI_IMAGE_PROVIDER = ModelProvider.Google;
|
|
13
|
+
export const DEFAULT_AI_IMAGE_MODEL = 'gemini-3-pro-image-preview:image';
|
|
14
14
|
|
|
15
15
|
export interface GenerationConfigState {
|
|
16
16
|
parameters: RuntimeImageGenParams;
|
|
@@ -30,14 +30,14 @@ export interface GenerationConfigState {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
export const DEFAULT_IMAGE_GENERATION_PARAMETERS: RuntimeImageGenParams =
|
|
33
|
-
extractDefaultValues(
|
|
33
|
+
extractDefaultValues(nanoBananaProParameters);
|
|
34
34
|
|
|
35
35
|
export const initialGenerationConfigState: GenerationConfigState = {
|
|
36
36
|
model: DEFAULT_AI_IMAGE_MODEL,
|
|
37
37
|
provider: DEFAULT_AI_IMAGE_PROVIDER,
|
|
38
38
|
imageNum: DEFAULT_IMAGE_CONFIG.defaultImageNum,
|
|
39
39
|
parameters: DEFAULT_IMAGE_GENERATION_PARAMETERS,
|
|
40
|
-
parametersSchema:
|
|
40
|
+
parametersSchema: nanoBananaProParameters,
|
|
41
41
|
isAspectRatioLocked: false,
|
|
42
42
|
activeAspectRatio: null,
|
|
43
43
|
isInit: false,
|
|
@@ -6,6 +6,7 @@ import { ImageStore } from '@/store/image';
|
|
|
6
6
|
import { initialState } from '@/store/image/initialState';
|
|
7
7
|
import { merge } from '@/utils/merge';
|
|
8
8
|
|
|
9
|
+
import { DEFAULT_AI_IMAGE_MODEL, DEFAULT_AI_IMAGE_PROVIDER } from './initialState';
|
|
9
10
|
import { imageGenerationConfigSelectors } from './selectors';
|
|
10
11
|
|
|
11
12
|
// Mock external dependencies
|
|
@@ -57,7 +58,7 @@ describe('imageGenerationConfigSelectors', () => {
|
|
|
57
58
|
|
|
58
59
|
it('should return the default model from initial state', () => {
|
|
59
60
|
const result = imageGenerationConfigSelectors.model(initialStore);
|
|
60
|
-
expect(result).toBe(
|
|
61
|
+
expect(result).toBe(DEFAULT_AI_IMAGE_MODEL);
|
|
61
62
|
});
|
|
62
63
|
});
|
|
63
64
|
|
|
@@ -70,7 +71,7 @@ describe('imageGenerationConfigSelectors', () => {
|
|
|
70
71
|
|
|
71
72
|
it('should return the default provider from initial state', () => {
|
|
72
73
|
const result = imageGenerationConfigSelectors.provider(initialStore);
|
|
73
|
-
expect(result).toBe(
|
|
74
|
+
expect(result).toBe(DEFAULT_AI_IMAGE_PROVIDER);
|
|
74
75
|
});
|
|
75
76
|
});
|
|
76
77
|
|
|
@@ -98,7 +99,10 @@ describe('imageGenerationConfigSelectors', () => {
|
|
|
98
99
|
it('should return the current parameters', () => {
|
|
99
100
|
const state = merge(initialStore, { parameters: testParameters });
|
|
100
101
|
const result = imageGenerationConfigSelectors.parameters(state);
|
|
101
|
-
|
|
102
|
+
// merge does deep merge, so result contains both default and test values
|
|
103
|
+
expect(result.prompt).toBe(testParameters.prompt);
|
|
104
|
+
expect(result.size).toBe(testParameters.size);
|
|
105
|
+
expect(result.imageUrls).toEqual(testParameters.imageUrls);
|
|
102
106
|
});
|
|
103
107
|
|
|
104
108
|
it('should return the default parameters from initial state', () => {
|
|
@@ -120,7 +124,10 @@ describe('imageGenerationConfigSelectors', () => {
|
|
|
120
124
|
it('should return the current parametersSchema', () => {
|
|
121
125
|
const state = merge(initialStore, { parametersSchema: testModelSchema });
|
|
122
126
|
const result = imageGenerationConfigSelectors.parametersSchema(state);
|
|
123
|
-
|
|
127
|
+
// merge does deep merge, so result contains both default and test values
|
|
128
|
+
expect(result.prompt).toEqual(testModelSchema.prompt);
|
|
129
|
+
expect(result.size).toEqual(testModelSchema.size);
|
|
130
|
+
expect(result.imageUrls).toEqual(testModelSchema.imageUrls);
|
|
124
131
|
});
|
|
125
132
|
|
|
126
133
|
it('should return default parametersSchema when not explicitly overridden', () => {
|
package/vitest.config.mts
CHANGED
|
@@ -2,6 +2,10 @@ import { dirname, join, resolve } from 'node:path';
|
|
|
2
2
|
import { coverageConfigDefaults, defineConfig } from 'vitest/config';
|
|
3
3
|
|
|
4
4
|
export default defineConfig({
|
|
5
|
+
optimizeDeps: {
|
|
6
|
+
exclude: ['crypto', 'util', 'tty'],
|
|
7
|
+
include: ['@lobehub/tts'],
|
|
8
|
+
},
|
|
5
9
|
plugins: [
|
|
6
10
|
/**
|
|
7
11
|
* @lobehub/fluent-emoji@4.0.0 ships `es/FluentEmoji/style.js` but its `es/FluentEmoji/index.js`
|
|
@@ -27,16 +31,13 @@ export default defineConfig({
|
|
|
27
31
|
id.endsWith('/FluentEmoji/style/index.js') ||
|
|
28
32
|
id.endsWith('/FluentEmoji/style/index.js?');
|
|
29
33
|
|
|
30
|
-
if (isFluentEmojiEntry && isMissingStyleIndex)
|
|
34
|
+
if (isFluentEmojiEntry && isMissingStyleIndex)
|
|
35
|
+
return resolve(dirname(importer), 'style.js');
|
|
31
36
|
|
|
32
37
|
return null;
|
|
33
38
|
},
|
|
34
39
|
},
|
|
35
40
|
],
|
|
36
|
-
optimizeDeps: {
|
|
37
|
-
exclude: ['crypto', 'util', 'tty'],
|
|
38
|
-
include: ['@lobehub/tts'],
|
|
39
|
-
},
|
|
40
41
|
test: {
|
|
41
42
|
alias: {
|
|
42
43
|
/* eslint-disable sort-keys-fix/sort-keys-fix */
|
|
@@ -77,11 +78,14 @@ export default defineConfig({
|
|
|
77
78
|
environment: 'happy-dom',
|
|
78
79
|
exclude: [
|
|
79
80
|
'**/node_modules/**',
|
|
81
|
+
'**/.*/**',
|
|
80
82
|
'**/dist/**',
|
|
81
83
|
'**/build/**',
|
|
82
84
|
'**/tmp/**',
|
|
83
85
|
'**/temp/**',
|
|
84
|
-
'
|
|
86
|
+
'**/docs/**',
|
|
87
|
+
'**/locales/**',
|
|
88
|
+
'**/public/**',
|
|
85
89
|
'**/apps/desktop/**',
|
|
86
90
|
'**/apps/mobile/**',
|
|
87
91
|
'**/packages/**',
|