@lobehub/chat 1.106.1 โ†’ 1.106.3

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 CHANGED
@@ -2,6 +2,65 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ### [Version 1.106.3](https://github.com/lobehub/lobe-chat/compare/v1.106.2...v1.106.3)
6
+
7
+ <sup>Released on **2025-07-29**</sup>
8
+
9
+ #### ๐Ÿ› Bug Fixes
10
+
11
+ - **misc**: Moonshot assistant messages must not be empty.
12
+
13
+ #### ๐Ÿ’„ Styles
14
+
15
+ - **misc**: Add volcengine kimi-k2 model, Add Zhipu GLM-4.5 models.
16
+
17
+ <br/>
18
+
19
+ <details>
20
+ <summary><kbd>Improvements and Fixes</kbd></summary>
21
+
22
+ #### What's fixed
23
+
24
+ - **misc**: Moonshot assistant messages must not be empty, closes [#8419](https://github.com/lobehub/lobe-chat/issues/8419) ([a796495](https://github.com/lobehub/lobe-chat/commit/a796495))
25
+
26
+ #### Styles
27
+
28
+ - **misc**: Add volcengine kimi-k2 model, closes [#8591](https://github.com/lobehub/lobe-chat/issues/8591) ([9630167](https://github.com/lobehub/lobe-chat/commit/9630167))
29
+ - **misc**: Add Zhipu GLM-4.5 models, closes [#8590](https://github.com/lobehub/lobe-chat/issues/8590) ([4f4620c](https://github.com/lobehub/lobe-chat/commit/4f4620c))
30
+
31
+ </details>
32
+
33
+ <div align="right">
34
+
35
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
36
+
37
+ </div>
38
+
39
+ ### [Version 1.106.2](https://github.com/lobehub/lobe-chat/compare/v1.106.1...v1.106.2)
40
+
41
+ <sup>Released on **2025-07-29**</sup>
42
+
43
+ #### ๐Ÿ› Bug Fixes
44
+
45
+ - **misc**: Fix desktop auth redirect url error.
46
+
47
+ <br/>
48
+
49
+ <details>
50
+ <summary><kbd>Improvements and Fixes</kbd></summary>
51
+
52
+ #### What's fixed
53
+
54
+ - **misc**: Fix desktop auth redirect url error, closes [#8597](https://github.com/lobehub/lobe-chat/issues/8597) ([0ed7368](https://github.com/lobehub/lobe-chat/commit/0ed7368))
55
+
56
+ </details>
57
+
58
+ <div align="right">
59
+
60
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
61
+
62
+ </div>
63
+
5
64
  ### [Version 1.106.1](https://github.com/lobehub/lobe-chat/compare/v1.106.0...v1.106.1)
6
65
 
7
66
  <sup>Released on **2025-07-29**</sup>
package/changelog/v1.json CHANGED
@@ -1,4 +1,25 @@
1
1
  [
2
+ {
3
+ "children": {
4
+ "fixes": [
5
+ "Moonshot assistant messages must not be empty."
6
+ ],
7
+ "improvements": [
8
+ "Add volcengine kimi-k2 model, Add Zhipu GLM-4.5 models."
9
+ ]
10
+ },
11
+ "date": "2025-07-29",
12
+ "version": "1.106.3"
13
+ },
14
+ {
15
+ "children": {
16
+ "fixes": [
17
+ "Fix desktop auth redirect url error."
18
+ ]
19
+ },
20
+ "date": "2025-07-29",
21
+ "version": "1.106.2"
22
+ },
2
23
  {
3
24
  "children": {
4
25
  "improvements": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "1.106.1",
3
+ "version": "1.106.3",
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",
@@ -257,7 +257,7 @@
257
257
  "semver": "^7.7.2",
258
258
  "sharp": "^0.34.3",
259
259
  "shiki": "^3.8.1",
260
- "stripe": "^16.12.0",
260
+ "stripe": "^17.7.0",
261
261
  "superjson": "^2.2.2",
262
262
  "svix": "^1.69.0",
263
263
  "swr": "^2.3.4",
@@ -3,9 +3,50 @@ import { NextRequest, NextResponse, after } from 'next/server';
3
3
 
4
4
  import { OAuthHandoffModel } from '@/database/models/oauthHandoff';
5
5
  import { serverDB } from '@/database/server';
6
+ import { correctOIDCUrl } from '@/utils/server/correctOIDCUrl';
6
7
 
7
8
  const log = debug('lobe-oidc:callback:desktop');
8
9
 
10
+ const errorPathname = '/oauth/callback/error';
11
+
12
+ /**
13
+ * ๅฎ‰ๅ…จๅœฐๆž„ๅปบ้‡ๅฎšๅ‘URL
14
+ */
15
+ const buildRedirectUrl = (req: NextRequest, pathname: string): URL => {
16
+ const forwardedHost = req.headers.get('x-forwarded-host');
17
+ const requestHost = req.headers.get('host');
18
+ const forwardedProto =
19
+ req.headers.get('x-forwarded-proto') || req.headers.get('x-forwarded-protocol');
20
+
21
+ // ็กฎๅฎšๅฎž้™…็š„ไธปๆœบๅ๏ผŒๆไพ›ๅŽๅค‡ๅ€ผ
22
+ const actualHost = forwardedHost || requestHost;
23
+ const actualProto = forwardedProto || 'https';
24
+
25
+ log(
26
+ 'Building redirect URL - host: %s, proto: %s, pathname: %s',
27
+ actualHost,
28
+ actualProto,
29
+ pathname,
30
+ );
31
+
32
+ // ๅฆ‚ๆžœไธปๆœบๅไป็„ถๆ— ๆ•ˆ๏ผŒไฝฟ็”จreq.nextUrlไฝœไธบๅŽๅค‡
33
+ if (!actualHost) {
34
+ log('Warning: Invalid host detected, using req.nextUrl as fallback');
35
+ const fallbackUrl = req.nextUrl.clone();
36
+ fallbackUrl.pathname = pathname;
37
+ return fallbackUrl;
38
+ }
39
+
40
+ try {
41
+ return new URL(`${actualProto}://${actualHost}${pathname}`);
42
+ } catch (error) {
43
+ log('Error constructing URL, using req.nextUrl as fallback: %O', error);
44
+ const fallbackUrl = req.nextUrl.clone();
45
+ fallbackUrl.pathname = pathname;
46
+ return fallbackUrl;
47
+ }
48
+ };
49
+
9
50
  export const GET = async (req: NextRequest) => {
10
51
  try {
11
52
  const searchParams = req.nextUrl.searchParams;
@@ -14,9 +55,11 @@ export const GET = async (req: NextRequest) => {
14
55
 
15
56
  if (!code || !state || typeof code !== 'string' || typeof state !== 'string') {
16
57
  log('Missing code or state in form data');
17
- const errorUrl = req.nextUrl.clone();
18
- errorUrl.pathname = '/oauth/callback/error';
58
+
59
+ const errorUrl = buildRedirectUrl(req, errorPathname);
19
60
  errorUrl.searchParams.set('reason', 'invalid_request');
61
+
62
+ log('Redirecting to error URL: %s', errorUrl.toString());
20
63
  return NextResponse.redirect(errorUrl);
21
64
  }
22
65
 
@@ -31,9 +74,16 @@ export const GET = async (req: NextRequest) => {
31
74
  await authHandoffModel.create({ client, id, payload });
32
75
  log('Handoff record created successfully for id: %s', id);
33
76
 
34
- // Redirect to a generic success page. The desktop app will poll for the result.
35
- const successUrl = req.nextUrl.clone();
36
- successUrl.pathname = '/oauth/callback/success';
77
+ const successUrl = buildRedirectUrl(req, '/oauth/callback/success');
78
+
79
+ // ๆทปๅŠ ่ฐƒ่ฏ•ๆ—ฅๅฟ—
80
+ log('Request host header: %s', req.headers.get('host'));
81
+ log('Request x-forwarded-host: %s', req.headers.get('x-forwarded-host'));
82
+ log('Request x-forwarded-proto: %s', req.headers.get('x-forwarded-proto'));
83
+ log('Constructed success URL: %s', successUrl.toString());
84
+
85
+ const correctedUrl = correctOIDCUrl(req, successUrl);
86
+ log('Final redirect URL: %s', correctedUrl.toString());
37
87
 
38
88
  // cleanup expired
39
89
  after(async () => {
@@ -42,17 +92,18 @@ export const GET = async (req: NextRequest) => {
42
92
  log('Cleaned up %d expired handoff records', cleanedCount);
43
93
  });
44
94
 
45
- return NextResponse.redirect(successUrl);
95
+ return NextResponse.redirect(correctedUrl);
46
96
  } catch (error) {
47
97
  log('Error in OIDC callback: %O', error);
48
- const errorUrl = req.nextUrl.clone();
49
- errorUrl.pathname = '/oauth/callback/error';
98
+
99
+ const errorUrl = buildRedirectUrl(req, errorPathname);
50
100
  errorUrl.searchParams.set('reason', 'internal_error');
51
101
 
52
102
  if (error instanceof Error) {
53
103
  errorUrl.searchParams.set('errorMessage', error.message);
54
104
  }
55
105
 
106
+ log('Redirecting to error URL: %s', errorUrl.toString());
56
107
  return NextResponse.redirect(errorUrl);
57
108
  }
58
109
  };
@@ -3,6 +3,7 @@ import { NextRequest, NextResponse } from 'next/server';
3
3
 
4
4
  import { OIDCService } from '@/server/services/oidc';
5
5
  import { getUserAuth } from '@/utils/server/auth';
6
+ import { correctOIDCUrl } from '@/utils/server/correctOIDCUrl';
6
7
 
7
8
  const log = debug('lobe-oidc:consent');
8
9
 
@@ -113,19 +114,15 @@ export async function POST(request: NextRequest) {
113
114
  const internalRedirectUrlString = await oidcService.getInteractionResult(uid, result);
114
115
  log('OIDC Provider internal redirect URL string: %s', internalRedirectUrlString);
115
116
 
116
- // // Construct the handoff URL
117
- // const handoffUrl = new URL('/oauth/handoff', request.nextUrl.origin);
118
- // // Set the original redirect URL as the 'target' query parameter (URL encoded)
119
- // handoffUrl.searchParams.set('target', internalRedirectUrlString);
120
- //
121
- // log('Redirecting to handoff page: %s', handoffUrl.toString());
122
- // // Redirect to the handoff page
123
- // return NextResponse.redirect(handoffUrl.toString(), {
124
- // headers: request.headers, // Keep original headers if necessary
125
- // status: 303,
126
- // });
127
-
128
- return NextResponse.redirect(internalRedirectUrlString, {
117
+ let finalRedirectUrl;
118
+ try {
119
+ finalRedirectUrl = correctOIDCUrl(request, new URL(internalRedirectUrlString));
120
+ } catch {
121
+ finalRedirectUrl = new URL(internalRedirectUrlString);
122
+ log('Warning: Could not parse redirect URL, using as-is: %s', internalRedirectUrlString);
123
+ }
124
+
125
+ return NextResponse.redirect(finalRedirectUrl, {
129
126
  headers: request.headers,
130
127
  status: 303,
131
128
  });
@@ -131,53 +131,6 @@ const googleChatModels: AIChatModelCard[] = [
131
131
  },
132
132
  type: 'chat',
133
133
  },
134
- {
135
- abilities: {
136
- functionCall: true,
137
- reasoning: true,
138
- search: true,
139
- vision: true,
140
- },
141
- contextWindowTokens: 1_048_576 + 65_536,
142
- description: 'Gemini 2.5 Flash Preview ๆ˜ฏ Google ๆ€งไปทๆฏ”ๆœ€้ซ˜็š„ๆจกๅž‹๏ผŒๆไพ›ๅ…จ้ข็š„ๅŠŸ่ƒฝใ€‚',
143
- displayName: 'Gemini 2.5 Flash Preview 04-17',
144
- id: 'gemini-2.5-flash-preview-04-17',
145
- maxOutput: 65_536,
146
- pricing: {
147
- cachedInput: 0.0375,
148
- input: 0.15,
149
- output: 3.5, // Thinking
150
- },
151
- releasedAt: '2025-04-17',
152
- settings: {
153
- extendParams: ['thinkingBudget'],
154
- searchImpl: 'params',
155
- searchProvider: 'google',
156
- },
157
- type: 'chat',
158
- },
159
- {
160
- abilities: {
161
- functionCall: true,
162
- reasoning: true,
163
- search: true,
164
- vision: true,
165
- },
166
- contextWindowTokens: 1_048_576 + 65_536,
167
- description: 'Gemini 2.5 Flash Preview ๆ˜ฏ Google ๆ€งไปทๆฏ”ๆœ€้ซ˜็š„ๆจกๅž‹๏ผŒๆไพ›ๅ…จ้ข็š„ๅŠŸ่ƒฝใ€‚',
168
- displayName: 'Gemini 2.5 Flash Preview 04-17 for cursor testing',
169
- id: 'gemini-2.5-flash-preview-04-17-thinking',
170
- maxOutput: 65_536,
171
- pricing: {
172
- input: 0.15,
173
- output: 3.5,
174
- },
175
- settings: {
176
- searchImpl: 'params',
177
- searchProvider: 'google',
178
- },
179
- type: 'chat',
180
- },
181
134
  {
182
135
  abilities: {
183
136
  functionCall: true,
@@ -188,7 +141,6 @@ const googleChatModels: AIChatModelCard[] = [
188
141
  contextWindowTokens: 1_048_576 + 65_536,
189
142
  description: 'Gemini 2.5 Flash-Lite ๆ˜ฏ Google ๆœ€ๅฐใ€ๆ€งไปทๆฏ”ๆœ€้ซ˜็š„ๆจกๅž‹๏ผŒไธ“ไธบๅคง่ง„ๆจกไฝฟ็”จ่€Œ่ฎพ่ฎกใ€‚',
190
143
  displayName: 'Gemini 2.5 Flash-Lite',
191
- enabled: true,
192
144
  id: 'gemini-2.5-flash-lite',
193
145
  maxOutput: 65_536,
194
146
  pricing: {
@@ -33,6 +33,7 @@ const groqChatModels: AIChatModelCard[] = [
33
33
  displayName: 'Kimi K2 Instruct',
34
34
  enabled: true,
35
35
  id: 'moonshotai/kimi-k2-instruct',
36
+ maxOutput: 16_384,
36
37
  pricing: {
37
38
  input: 1,
38
39
  output: 3,
@@ -53,6 +54,9 @@ const groqChatModels: AIChatModelCard[] = [
53
54
  type: 'chat',
54
55
  },
55
56
  {
57
+ abilities: {
58
+ functionCall: true,
59
+ },
56
60
  contextWindowTokens: 131_072,
57
61
  displayName: 'Llama 4 Maverick (17Bx128E)',
58
62
  enabled: true,
@@ -44,6 +44,28 @@ const hunyuanChatModels: AIChatModelCard[] = [
44
44
  },
45
45
  type: 'chat',
46
46
  },
47
+ {
48
+ abilities: {
49
+ reasoning: true,
50
+ search: true,
51
+ },
52
+ contextWindowTokens: 92_000,
53
+ description:
54
+ 'ๅคงๅน…ๆๅ‡้ซ˜้šพๅบฆๆ•ฐๅญฆใ€้€ป่พ‘ๅ’Œไปฃ็ ่ƒฝๅŠ›๏ผŒไผ˜ๅŒ–ๆจกๅž‹่พ“ๅ‡บ็จณๅฎšๆ€ง๏ผŒๆๅ‡ๆจกๅž‹้•ฟๆ–‡่ƒฝๅŠ›ใ€‚',
55
+ displayName: 'Hunyuan T1 20250711',
56
+ id: 'hunyuan-t1-20250711',
57
+ maxOutput: 64_000,
58
+ pricing: {
59
+ currency: 'CNY',
60
+ input: 1,
61
+ output: 4,
62
+ },
63
+ releasedAt: '2025-07-11',
64
+ settings: {
65
+ searchImpl: 'params',
66
+ },
67
+ type: 'chat',
68
+ },
47
69
  {
48
70
  abilities: {
49
71
  reasoning: true,
@@ -5,7 +5,6 @@ const moonshotChatModels: AIChatModelCard[] = [
5
5
  {
6
6
  abilities: {
7
7
  functionCall: true,
8
- search: true,
9
8
  },
10
9
  contextWindowTokens: 131_072,
11
10
  description:
@@ -20,15 +19,11 @@ const moonshotChatModels: AIChatModelCard[] = [
20
19
  output: 16,
21
20
  },
22
21
  releasedAt: '2025-07-11',
23
- settings: {
24
- searchImpl: 'params',
25
- },
26
22
  type: 'chat',
27
23
  },
28
24
  {
29
25
  abilities: {
30
26
  functionCall: true,
31
- search: true,
32
27
  vision: true,
33
28
  },
34
29
  contextWindowTokens: 131_072,
@@ -44,9 +39,6 @@ const moonshotChatModels: AIChatModelCard[] = [
44
39
  output: 30,
45
40
  },
46
41
  releasedAt: '2025-02-17',
47
- settings: {
48
- searchImpl: 'params',
49
- },
50
42
  type: 'chat',
51
43
  },
52
44
  {
@@ -71,7 +63,6 @@ const moonshotChatModels: AIChatModelCard[] = [
71
63
  {
72
64
  abilities: {
73
65
  functionCall: true,
74
- search: true,
75
66
  },
76
67
  contextWindowTokens: 131_072,
77
68
  description: 'Moonshot V1 Auto ๅฏไปฅๆ นๆฎๅฝ“ๅ‰ไธŠไธ‹ๆ–‡ๅ ็”จ็š„ Tokens ๆ•ฐ้‡ๆฅ้€‰ๆ‹ฉๅˆ้€‚็š„ๆจกๅž‹',
@@ -82,15 +73,11 @@ const moonshotChatModels: AIChatModelCard[] = [
82
73
  input: 10, // 128k ไธŠไธ‹ๆ–‡ๆ—ถ
83
74
  output: 30,
84
75
  },
85
- settings: {
86
- searchImpl: 'params',
87
- },
88
76
  type: 'chat',
89
77
  },
90
78
  {
91
79
  abilities: {
92
80
  functionCall: true,
93
- search: true,
94
81
  },
95
82
  contextWindowTokens: 8192,
96
83
  description:
@@ -102,15 +89,11 @@ const moonshotChatModels: AIChatModelCard[] = [
102
89
  input: 2,
103
90
  output: 10,
104
91
  },
105
- settings: {
106
- searchImpl: 'params',
107
- },
108
92
  type: 'chat',
109
93
  },
110
94
  {
111
95
  abilities: {
112
96
  functionCall: true,
113
- search: true,
114
97
  },
115
98
  contextWindowTokens: 32_768,
116
99
  description:
@@ -122,15 +105,11 @@ const moonshotChatModels: AIChatModelCard[] = [
122
105
  input: 5,
123
106
  output: 20,
124
107
  },
125
- settings: {
126
- searchImpl: 'params',
127
- },
128
108
  type: 'chat',
129
109
  },
130
110
  {
131
111
  abilities: {
132
112
  functionCall: true,
133
- search: true,
134
113
  },
135
114
  contextWindowTokens: 131_072,
136
115
  description:
@@ -142,15 +121,11 @@ const moonshotChatModels: AIChatModelCard[] = [
142
121
  input: 10,
143
122
  output: 30,
144
123
  },
145
- settings: {
146
- searchImpl: 'params',
147
- },
148
124
  type: 'chat',
149
125
  },
150
126
  {
151
127
  abilities: {
152
128
  functionCall: true,
153
- search: true,
154
129
  vision: true,
155
130
  },
156
131
  contextWindowTokens: 8192,
@@ -164,15 +139,11 @@ const moonshotChatModels: AIChatModelCard[] = [
164
139
  output: 10,
165
140
  },
166
141
  releasedAt: '2025-01-14',
167
- settings: {
168
- searchImpl: 'params',
169
- },
170
142
  type: 'chat',
171
143
  },
172
144
  {
173
145
  abilities: {
174
146
  functionCall: true,
175
- search: true,
176
147
  vision: true,
177
148
  },
178
149
  contextWindowTokens: 32_768,
@@ -186,15 +157,11 @@ const moonshotChatModels: AIChatModelCard[] = [
186
157
  output: 20,
187
158
  },
188
159
  releasedAt: '2025-01-14',
189
- settings: {
190
- searchImpl: 'params',
191
- },
192
160
  type: 'chat',
193
161
  },
194
162
  {
195
163
  abilities: {
196
164
  functionCall: true,
197
- search: true,
198
165
  vision: true,
199
166
  },
200
167
  contextWindowTokens: 131_072,
@@ -208,9 +175,6 @@ const moonshotChatModels: AIChatModelCard[] = [
208
175
  output: 30,
209
176
  },
210
177
  releasedAt: '2025-01-14',
211
- settings: {
212
- searchImpl: 'params',
213
- },
214
178
  type: 'chat',
215
179
  },
216
180
  ];