@lobehub/chat 1.88.0 → 1.88.1
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 +33 -0
- package/changelog/v1.json +12 -0
- package/package.json +1 -1
- package/src/config/aiModels/google.ts +2 -2
- package/src/libs/model-runtime/google/index.ts +9 -0
- package/src/libs/model-runtime/utils/streams/google-ai.ts +9 -0
- package/src/store/user/slices/auth/selectors.test.ts +39 -2
- package/src/store/user/slices/auth/selectors.ts +15 -3
package/CHANGELOG.md
CHANGED
@@ -2,6 +2,39 @@
|
|
2
2
|
|
3
3
|
# Changelog
|
4
4
|
|
5
|
+
### [Version 1.88.1](https://github.com/lobehub/lobe-chat/compare/v1.88.0...v1.88.1)
|
6
|
+
|
7
|
+
<sup>Released on **2025-05-24**</sup>
|
8
|
+
|
9
|
+
#### 🐛 Bug Fixes
|
10
|
+
|
11
|
+
- **misc**: User nickName & username selector in desktop.
|
12
|
+
|
13
|
+
#### 💄 Styles
|
14
|
+
|
15
|
+
- **misc**: Support Gemini 2.5 thought reasoning.
|
16
|
+
|
17
|
+
<br/>
|
18
|
+
|
19
|
+
<details>
|
20
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
21
|
+
|
22
|
+
#### What's fixed
|
23
|
+
|
24
|
+
- **misc**: User nickName & username selector in desktop, closes [#7899](https://github.com/lobehub/lobe-chat/issues/7899) ([bf51746](https://github.com/lobehub/lobe-chat/commit/bf51746))
|
25
|
+
|
26
|
+
#### Styles
|
27
|
+
|
28
|
+
- **misc**: Support Gemini 2.5 thought reasoning, closes [#7686](https://github.com/lobehub/lobe-chat/issues/7686) ([f34c4de](https://github.com/lobehub/lobe-chat/commit/f34c4de))
|
29
|
+
|
30
|
+
</details>
|
31
|
+
|
32
|
+
<div align="right">
|
33
|
+
|
34
|
+
[](#readme-top)
|
35
|
+
|
36
|
+
</div>
|
37
|
+
|
5
38
|
## [Version 1.88.0](https://github.com/lobehub/lobe-chat/compare/v1.87.9...v1.88.0)
|
6
39
|
|
7
40
|
<sup>Released on **2025-05-23**</sup>
|
package/changelog/v1.json
CHANGED
@@ -1,4 +1,16 @@
|
|
1
1
|
[
|
2
|
+
{
|
3
|
+
"children": {
|
4
|
+
"fixes": [
|
5
|
+
"User nickName & username selector in desktop."
|
6
|
+
],
|
7
|
+
"improvements": [
|
8
|
+
"Support Gemini 2.5 thought reasoning."
|
9
|
+
]
|
10
|
+
},
|
11
|
+
"date": "2025-05-24",
|
12
|
+
"version": "1.88.1"
|
13
|
+
},
|
2
14
|
{
|
3
15
|
"children": {
|
4
16
|
"features": [
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@lobehub/chat",
|
3
|
-
"version": "1.88.
|
3
|
+
"version": "1.88.1",
|
4
4
|
"description": "Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
|
5
5
|
"keywords": [
|
6
6
|
"framework",
|
@@ -285,7 +285,7 @@ const googleChatModels: AIChatModelCard[] = [
|
|
285
285
|
contextWindowTokens: 2_008_192,
|
286
286
|
description:
|
287
287
|
'Gemini 1.5 Pro 002 是最新的生产就绪模型,提供更高质量的输出,特别在数学、长上下文和视觉任务方面有显著提升。',
|
288
|
-
displayName: 'Gemini 1.5 Pro 002',
|
288
|
+
displayName: 'Gemini 1.5 Pro 002 (Paid)',
|
289
289
|
id: 'gemini-1.5-pro-002', // Deprecated on 2025-09-24
|
290
290
|
maxOutput: 8192,
|
291
291
|
pricing: {
|
@@ -303,7 +303,7 @@ const googleChatModels: AIChatModelCard[] = [
|
|
303
303
|
},
|
304
304
|
contextWindowTokens: 2_008_192,
|
305
305
|
description: 'Gemini 1.5 Pro 001 是可扩展的多模态AI解决方案,支持广泛的复杂任务。',
|
306
|
-
displayName: 'Gemini 1.5 Pro 001',
|
306
|
+
displayName: 'Gemini 1.5 Pro 001 (Paid)',
|
307
307
|
id: 'gemini-1.5-pro-001', // Deprecated on 2025-05-27
|
308
308
|
maxOutput: 8192,
|
309
309
|
pricing: {
|
@@ -82,6 +82,10 @@ interface LobeGoogleAIParams {
|
|
82
82
|
isVertexAi?: boolean;
|
83
83
|
}
|
84
84
|
|
85
|
+
interface GoogleAIThinkingConfig {
|
86
|
+
includeThoughts?: boolean;
|
87
|
+
}
|
88
|
+
|
85
89
|
export class LobeGoogleAI implements LobeRuntimeAI {
|
86
90
|
private client: GoogleGenerativeAI;
|
87
91
|
private isVertexAi: boolean;
|
@@ -106,6 +110,10 @@ export class LobeGoogleAI implements LobeRuntimeAI {
|
|
106
110
|
const payload = this.buildPayload(rawPayload);
|
107
111
|
const model = payload.model;
|
108
112
|
|
113
|
+
const thinkingConfig: GoogleAIThinkingConfig = {
|
114
|
+
includeThoughts: true,
|
115
|
+
};
|
116
|
+
|
109
117
|
const contents = await this.buildGoogleMessages(payload.messages);
|
110
118
|
|
111
119
|
const inputStartAt = Date.now();
|
@@ -117,6 +125,7 @@ export class LobeGoogleAI implements LobeRuntimeAI {
|
|
117
125
|
// @ts-expect-error - Google SDK 0.24.0 doesn't have this property for now with
|
118
126
|
response_modalities: modelsWithModalities.has(model) ? ['Text', 'Image'] : undefined,
|
119
127
|
temperature: payload.temperature,
|
128
|
+
thinkingConfig,
|
120
129
|
topP: payload.top_p,
|
121
130
|
},
|
122
131
|
model,
|
@@ -76,6 +76,15 @@ const transformGoogleGenerativeAIStream = (
|
|
76
76
|
const text = chunk.text?.();
|
77
77
|
|
78
78
|
if (candidate) {
|
79
|
+
// 首先检查是否为 reasoning 内容 (thought: true)
|
80
|
+
if (Array.isArray(candidate.content.parts) && candidate.content.parts.length > 0) {
|
81
|
+
for (const part of candidate.content.parts) {
|
82
|
+
if (part && part.text && (part as any).thought === true) {
|
83
|
+
return { data: part.text, id: context.id, type: 'reasoning' };
|
84
|
+
}
|
85
|
+
}
|
86
|
+
}
|
87
|
+
|
79
88
|
// return the grounding
|
80
89
|
if (candidate.groundingMetadata) {
|
81
90
|
const { webSearchQueries, groundingChunks } = candidate.groundingMetadata;
|
@@ -11,6 +11,7 @@ vi.mock('i18next', () => ({
|
|
11
11
|
|
12
12
|
// 定义一个变量来存储 enableAuth 的值
|
13
13
|
let enableAuth = true;
|
14
|
+
let isDesktop = false;
|
14
15
|
|
15
16
|
// 模拟 @/const/auth 模块
|
16
17
|
vi.mock('@/const/auth', () => ({
|
@@ -19,14 +20,23 @@ vi.mock('@/const/auth', () => ({
|
|
19
20
|
},
|
20
21
|
}));
|
21
22
|
|
23
|
+
// 模拟 @/const/version 模块
|
24
|
+
vi.mock('@/const/version', () => ({
|
25
|
+
get isDesktop() {
|
26
|
+
return isDesktop;
|
27
|
+
},
|
28
|
+
}));
|
29
|
+
|
22
30
|
afterEach(() => {
|
23
31
|
enableAuth = true;
|
32
|
+
isDesktop = false;
|
24
33
|
});
|
25
34
|
|
26
35
|
describe('userProfileSelectors', () => {
|
27
36
|
describe('nickName', () => {
|
28
|
-
it('should return default nickname when auth is disabled', () => {
|
37
|
+
it('should return default nickname when auth is disabled and not desktop', () => {
|
29
38
|
enableAuth = false;
|
39
|
+
isDesktop = false;
|
30
40
|
|
31
41
|
const store: UserStore = {
|
32
42
|
isSignedIn: false,
|
@@ -38,6 +48,19 @@ describe('userProfileSelectors', () => {
|
|
38
48
|
expect(t).toHaveBeenCalledWith('userPanel.defaultNickname', { ns: 'common' });
|
39
49
|
});
|
40
50
|
|
51
|
+
it('should return user fullName when auth is disabled and is desktop', () => {
|
52
|
+
enableAuth = false;
|
53
|
+
isDesktop = true;
|
54
|
+
|
55
|
+
const store: UserStore = {
|
56
|
+
isSignedIn: false,
|
57
|
+
user: { fullName: 'John Doe' },
|
58
|
+
enableAuth: () => false,
|
59
|
+
} as unknown as UserStore;
|
60
|
+
|
61
|
+
expect(userProfileSelectors.nickName(store)).toBe('John Doe');
|
62
|
+
});
|
63
|
+
|
41
64
|
it('should return user fullName when signed in', () => {
|
42
65
|
enableAuth = true;
|
43
66
|
|
@@ -75,8 +98,9 @@ describe('userProfileSelectors', () => {
|
|
75
98
|
});
|
76
99
|
|
77
100
|
describe('username', () => {
|
78
|
-
it('should return default username when auth is disabled', () => {
|
101
|
+
it('should return default username when auth is disabled and not desktop', () => {
|
79
102
|
enableAuth = false;
|
103
|
+
isDesktop = false;
|
80
104
|
|
81
105
|
const store: UserStore = {
|
82
106
|
isSignedIn: false,
|
@@ -87,6 +111,19 @@ describe('userProfileSelectors', () => {
|
|
87
111
|
expect(userProfileSelectors.username(store)).toBe('LobeChat');
|
88
112
|
});
|
89
113
|
|
114
|
+
it('should return user username when auth is disabled and is desktop', () => {
|
115
|
+
enableAuth = false;
|
116
|
+
isDesktop = true;
|
117
|
+
|
118
|
+
const store: UserStore = {
|
119
|
+
isSignedIn: false,
|
120
|
+
user: { username: 'johndoe' },
|
121
|
+
enableAuth: () => false,
|
122
|
+
} as unknown as UserStore;
|
123
|
+
|
124
|
+
expect(userProfileSelectors.username(store)).toBe('johndoe');
|
125
|
+
});
|
126
|
+
|
90
127
|
it('should return user username when signed in', () => {
|
91
128
|
const store: UserStore = {
|
92
129
|
isSignedIn: true,
|
@@ -4,19 +4,31 @@ import { enableAuth, enableClerk, enableNextAuth } from '@/const/auth';
|
|
4
4
|
import { BRANDING_NAME } from '@/const/branding';
|
5
5
|
import { UserStore } from '@/store/user';
|
6
6
|
import { LobeUser } from '@/types/user';
|
7
|
+
import { isDesktop } from '@/const/version';
|
7
8
|
|
8
9
|
const DEFAULT_USERNAME = BRANDING_NAME;
|
9
10
|
|
10
11
|
const nickName = (s: UserStore) => {
|
11
|
-
|
12
|
+
const defaultNickName = s.user?.fullName || s.user?.username;
|
13
|
+
if (!enableAuth) {
|
14
|
+
if (isDesktop) {
|
15
|
+
return defaultNickName;
|
16
|
+
}
|
17
|
+
return t('userPanel.defaultNickname', { ns: 'common' });
|
18
|
+
}
|
12
19
|
|
13
|
-
if (s.isSignedIn) return
|
20
|
+
if (s.isSignedIn) return defaultNickName;
|
14
21
|
|
15
22
|
return t('userPanel.anonymousNickName', { ns: 'common' });
|
16
23
|
};
|
17
24
|
|
18
25
|
const username = (s: UserStore) => {
|
19
|
-
if (!enableAuth)
|
26
|
+
if (!enableAuth) {
|
27
|
+
if (isDesktop) {
|
28
|
+
return s.user?.username;
|
29
|
+
}
|
30
|
+
return DEFAULT_USERNAME;
|
31
|
+
}
|
20
32
|
|
21
33
|
if (s.isSignedIn) return s.user?.username;
|
22
34
|
|