@lobehub/chat 1.16.9 → 1.16.10

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.

Potentially problematic release.


This version of @lobehub/chat might be problematic. Click here for more details.

package/CHANGELOG.md CHANGED
@@ -2,6 +2,39 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ### [Version 1.16.10](https://github.com/lobehub/lobe-chat/compare/v1.16.9...v1.16.10)
6
+
7
+ <sup>Released on **2024-09-12**</sup>
8
+
9
+ #### ♻ Code Refactoring
10
+
11
+ - **misc**: Support Environment Variable Inference For NextAuth.
12
+
13
+ #### 🐛 Bug Fixes
14
+
15
+ - **misc**: Qwen model param error.
16
+
17
+ <br/>
18
+
19
+ <details>
20
+ <summary><kbd>Improvements and Fixes</kbd></summary>
21
+
22
+ #### Code refactoring
23
+
24
+ - **misc**: Support Environment Variable Inference For NextAuth, closes [#3701](https://github.com/lobehub/lobe-chat/issues/3701) ([b956755](https://github.com/lobehub/lobe-chat/commit/b956755))
25
+
26
+ #### What's fixed
27
+
28
+ - **misc**: Qwen model param error, closes [#3902](https://github.com/lobehub/lobe-chat/issues/3902) ([c9f00e5](https://github.com/lobehub/lobe-chat/commit/c9f00e5))
29
+
30
+ </details>
31
+
32
+ <div align="right">
33
+
34
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
35
+
36
+ </div>
37
+
5
38
  ### [Version 1.16.9](https://github.com/lobehub/lobe-chat/compare/v1.16.8...v1.16.9)
6
39
 
7
40
  <sup>Released on **2024-09-12**</sup>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "1.16.9",
3
+ "version": "1.16.10",
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",
@@ -102,7 +102,7 @@
102
102
  "@ant-design/icons": "^5.4.0",
103
103
  "@ant-design/pro-components": "^2.7.10",
104
104
  "@anthropic-ai/sdk": "^0.27.0",
105
- "@auth/core": "0.28.0",
105
+ "@auth/core": "^0.34.2",
106
106
  "@aws-sdk/client-bedrock-runtime": "^3.637.0",
107
107
  "@aws-sdk/client-s3": "^3.637.0",
108
108
  "@aws-sdk/s3-request-presigner": "^3.637.0",
@@ -169,7 +169,7 @@
169
169
  "modern-screenshot": "^4.4.39",
170
170
  "nanoid": "^5.0.7",
171
171
  "next": "14.2.8",
172
- "next-auth": "5.0.0-beta.15",
172
+ "next-auth": "beta",
173
173
  "next-sitemap": "^4.2.3",
174
174
  "numeral": "^2.0.6",
175
175
  "nuqs": "^1.17.8",
@@ -0,0 +1,200 @@
1
+ // @vitest-environment node
2
+ import { beforeEach, describe, expect, it, vi } from 'vitest';
3
+
4
+ import { getAuthConfig } from '../auth';
5
+
6
+ // Stub the global process object to safely mock environment variables
7
+ vi.stubGlobal('process', {
8
+ ...process, // Preserve the original process object
9
+ env: { ...process.env }, // Clone the environment variables object for modification
10
+ });
11
+
12
+ const spyConsoleWarn = vi.spyOn(console, 'warn');
13
+
14
+ describe('getAuthConfig', () => {
15
+ beforeEach(() => {
16
+ // Clear all environment variables before each test
17
+ // @ts-expect-error
18
+ process.env = {};
19
+ });
20
+
21
+ // TODO(NextAuth ENVs Migration): Remove once nextauth envs migration time end
22
+ describe('should warn about deprecated environment variables', () => {
23
+ it('should warn about Auth0 deprecated environment variables', () => {
24
+ // Set all deprecated environment variables
25
+ process.env.AUTH0_CLIENT_ID = 'auth0_client_id';
26
+ process.env.AUTH0_CLIENT_SECRET = 'auth0_client_secret';
27
+ process.env.AUTH0_ISSUER = 'auth0_issuer';
28
+ // Call the function
29
+ getAuthConfig();
30
+
31
+ // Check that the spyConsoleWarn function was called for each deprecated environment variable
32
+ // Example: A warning meassage should incloud: `<Old Env> .* <New Env>`
33
+ // And the regex should match the warning message: `AUTH0_CLIENT_ID.*AUTH_AUTH0_ID`
34
+ expect(spyConsoleWarn).toHaveBeenCalledWith(
35
+ expect.stringMatching(/AUTH0_CLIENT_ID.*AUTH_AUTH0_ID/),
36
+ );
37
+ expect(spyConsoleWarn).toHaveBeenCalledWith(
38
+ expect.stringMatching(/AUTH0_CLIENT_SECRET.*AUTH_AUTH0_SECRET/),
39
+ );
40
+ expect(spyConsoleWarn).toHaveBeenCalledWith(
41
+ expect.stringMatching(/AUTH0_ISSUER.*AUTH_AUTH0_ISSUER/),
42
+ );
43
+ });
44
+ it('should warn about Authentik deprecated environment variables', () => {
45
+ // Set all deprecated environment variables
46
+ process.env.AUTHENTIK_CLIENT_ID = 'authentik_client_id';
47
+ process.env.AUTHENTIK_CLIENT_SECRET = 'authentik_client_secret';
48
+ process.env.AUTHENTIK_ISSUER = 'authentik_issuer';
49
+
50
+ // Call the function
51
+ getAuthConfig();
52
+
53
+ // Check that the spyConsoleWarn function was called for each deprecated environment variable
54
+ expect(spyConsoleWarn).toHaveBeenCalledWith(
55
+ expect.stringMatching(/AUTHENTIK_CLIENT_ID.*AUTH_AUTHENTIK_ID/),
56
+ );
57
+ expect(spyConsoleWarn).toHaveBeenCalledWith(
58
+ expect.stringMatching(/AUTHENTIK_CLIENT_SECRET.*AUTH_AUTHENTIK_SECRET/),
59
+ );
60
+ expect(spyConsoleWarn).toHaveBeenCalledWith(
61
+ expect.stringMatching(/AUTHENTIK_ISSUER.*AUTH_AUTHENTIK_ISSUER/),
62
+ );
63
+ });
64
+ it('should warn about Authelia deprecated environment variables', () => {
65
+ // Set all deprecated environment variables
66
+ process.env.AUTHELIA_CLIENT_ID = 'authelia_client_id';
67
+ process.env.AUTHELIA_CLIENT_SECRET = 'authelia_client_secret';
68
+ process.env.AUTHELIA_ISSUER = 'authelia_issuer';
69
+
70
+ // Call the function
71
+ getAuthConfig();
72
+
73
+ // Check that the spyConsoleWarn function was called for each deprecated environment variable
74
+ expect(spyConsoleWarn).toHaveBeenCalledWith(
75
+ expect.stringMatching(/AUTHELIA_CLIENT_ID.*AUTH_AUTHELIA_ID/),
76
+ );
77
+ expect(spyConsoleWarn).toHaveBeenCalledWith(
78
+ expect.stringMatching(/AUTHELIA_CLIENT_SECRET.*AUTH_AUTHELIA_SECRET/),
79
+ );
80
+ expect(spyConsoleWarn).toHaveBeenCalledWith(
81
+ expect.stringMatching(/AUTHELIA_ISSUER.*AUTH_AUTHELIA_ISSUER/),
82
+ );
83
+ });
84
+ it('should warn about AzureAD deprecated environment variables', () => {
85
+ // Set all deprecated environment variables
86
+ process.env.AZURE_AD_CLIENT_ID = 'azure_ad_client_id';
87
+ process.env.AZURE_AD_CLIENT_SECRET = 'azure_ad_client_secret';
88
+ process.env.AZURE_AD_TENANT_ID = 'azure_ad_tenant_id';
89
+
90
+ // Call the function
91
+ getAuthConfig();
92
+
93
+ // Check that the spyConsoleWarn function was called for each deprecated environment variable
94
+ expect(spyConsoleWarn).toHaveBeenCalledWith(
95
+ expect.stringMatching(/AZURE_AD_CLIENT_ID.*AUTH_AZURE_AD_ID/),
96
+ );
97
+ expect(spyConsoleWarn).toHaveBeenCalledWith(
98
+ expect.stringMatching(/AZURE_AD_CLIENT_SECRET.*AUTH_AZURE_AD_SECRET/),
99
+ );
100
+ expect(spyConsoleWarn).toHaveBeenCalledWith(
101
+ expect.stringMatching(/AZURE_AD_TENANT_ID.*AUTH_AZURE_AD_TENANT_ID/),
102
+ );
103
+ });
104
+ it('should warn about Cloudflare Zero Trust deprecated environment variables', () => {
105
+ // Set all deprecated environment variables
106
+ process.env.CLOUDFLARE_ZERO_TRUST_CLIENT_ID = 'cloudflare_zero_trust_client_id';
107
+ process.env.CLOUDFLARE_ZERO_TRUST_CLIENT_SECRET = 'cloudflare_zero_trust_client_secret';
108
+ process.env.CLOUDFLARE_ZERO_TRUST_ISSUER = 'cloudflare_zero_trust_issuer';
109
+
110
+ // Call the function
111
+ getAuthConfig();
112
+
113
+ // Check that the spyConsoleWarn function was called for each deprecated environment variable
114
+ expect(spyConsoleWarn).toHaveBeenCalledWith(
115
+ expect.stringMatching(/CLOUDFLARE_ZERO_TRUST_CLIENT_ID.*AUTH_CLOUDFLARE_ZERO_TRUST_ID/),
116
+ );
117
+ expect(spyConsoleWarn).toHaveBeenCalledWith(
118
+ expect.stringMatching(
119
+ /CLOUDFLARE_ZERO_TRUST_CLIENT_SECRET.*AUTH_CLOUDFLARE_ZERO_TRUST_SECRET/,
120
+ ),
121
+ );
122
+ expect(spyConsoleWarn).toHaveBeenCalledWith(
123
+ expect.stringMatching(/CLOUDFLARE_ZERO_TRUST_ISSUER.*AUTH_CLOUDFLARE_ZERO_TRUST_ISSUER/),
124
+ );
125
+ });
126
+ it('should warn about Generic OIDC deprecated environment variables', () => {
127
+ // Set all deprecated environment variables
128
+ process.env.GENERIC_OIDC_CLIENT_ID = 'generic_oidc_client_id';
129
+ process.env.GENERIC_OIDC_CLIENT_SECRET = 'generic_oidc_client_secret';
130
+ process.env.GENERIC_OIDC_ISSUER = 'generic_oidc_issuer';
131
+ // Call the function
132
+ getAuthConfig();
133
+
134
+ // Check that the spyConsoleWarn function was called for each deprecated environment variable
135
+ expect(spyConsoleWarn).toHaveBeenCalledWith(
136
+ expect.stringMatching(/GENERIC_OIDC_CLIENT_ID.*AUTH_GENERIC_OIDC_ID/),
137
+ );
138
+ expect(spyConsoleWarn).toHaveBeenCalledWith(
139
+ expect.stringMatching(/GENERIC_OIDC_CLIENT_SECRET.*AUTH_GENERIC_OIDC_SECRET/),
140
+ );
141
+ expect(spyConsoleWarn).toHaveBeenCalledWith(
142
+ expect.stringMatching(/GENERIC_OIDC_ISSUER.*AUTH_GENERIC_OIDC_ISSUER/),
143
+ );
144
+ });
145
+ it('should warn about GitHub deprecated environment variables', () => {
146
+ // Set all deprecated environment variables
147
+ process.env.GITHUB_CLIENT_ID = 'github_client_id';
148
+ process.env.GITHUB_CLIENT_SECRET = 'github_client_secret';
149
+ // Call the function
150
+ getAuthConfig();
151
+
152
+ // Check that the spyConsoleWarn function was called for each deprecated environment variable
153
+ expect(spyConsoleWarn).toHaveBeenCalledWith(
154
+ expect.stringMatching(/GITHUB_CLIENT_ID.*AUTH_GITHUB_ID/),
155
+ );
156
+ expect(spyConsoleWarn).toHaveBeenCalledWith(
157
+ expect.stringMatching(/GITHUB_CLIENT_SECRET.*AUTH_GITHUB_SECRET/),
158
+ );
159
+ });
160
+ it('should warn about Logto deprecated environment variables', () => {
161
+ // Set all deprecated environment variables
162
+ process.env.LOGTO_CLIENT_ID = 'logto_client_id';
163
+ process.env.LOGTO_CLIENT_SECRET = 'logto_client_secret';
164
+ process.env.LOGTO_ISSUER = 'logto_issuer';
165
+ // Call the function
166
+ getAuthConfig();
167
+
168
+ // Check that the spyConsoleWarn function was called for each deprecated environment variable
169
+ expect(spyConsoleWarn).toHaveBeenCalledWith(
170
+ expect.stringMatching(/LOGTO_CLIENT_ID.*AUTH_LOGTO_ID/),
171
+ );
172
+ expect(spyConsoleWarn).toHaveBeenCalledWith(
173
+ expect.stringMatching(/LOGTO_CLIENT_SECRET.*AUTH_LOGTO_SECRET/),
174
+ );
175
+ expect(spyConsoleWarn).toHaveBeenCalledWith(
176
+ expect.stringMatching(/LOGTO_ISSUER.*AUTH_LOGTO_ISSUER/),
177
+ );
178
+ });
179
+ it('should warn about Zitadel deprecated environment variables', () => {
180
+ // Set all deprecated environment variables
181
+ process.env.ZITADEL_CLIENT_ID = 'zitadel_client_id';
182
+ process.env.ZITADEL_CLIENT_SECRET = 'zitadel_client_secret';
183
+ process.env.ZITADEL_ISSUER = 'zitadel_issuer';
184
+ // Call the function
185
+ getAuthConfig();
186
+
187
+ // Check that the spyConsoleWarn function was called for each deprecated environment variable
188
+ expect(spyConsoleWarn).toHaveBeenCalledWith(
189
+ expect.stringMatching(/ZITADEL_CLIENT_ID.*AUTH_ZITADEL_ID/),
190
+ );
191
+ expect(spyConsoleWarn).toHaveBeenCalledWith(
192
+ expect.stringMatching(/ZITADEL_CLIENT_SECRET.*AUTH_ZITADEL_SECRET/),
193
+ );
194
+ expect(spyConsoleWarn).toHaveBeenCalledWith(
195
+ expect.stringMatching(/ZITADEL_ISSUER.*AUTH_ZITADEL_ISSUER/),
196
+ );
197
+ });
198
+ });
199
+ // Remove end
200
+ });
@@ -42,7 +42,102 @@ declare global {
42
42
  }
43
43
  }
44
44
 
45
+ // TODO(NextAuth ENVs Migration): Remove once nextauth envs migration time end
46
+ const removeTipsTemplate = (willBeRemoved: string, replaceOne: string) =>
47
+ `${willBeRemoved} will be removed in the future. Please set ${replaceOne} instead.`;
48
+ // End
49
+
45
50
  export const getAuthConfig = () => {
51
+ // TODO(NextAuth ENVs Migration): Remove once nextauth envs migration time end
52
+ if (process.env.AUTH0_CLIENT_ID) {
53
+ console.warn(removeTipsTemplate('AUTH0_CLIENT_ID', 'AUTH_AUTH0_ID'));
54
+ }
55
+ if (process.env.AUTH0_CLIENT_SECRET) {
56
+ console.warn(removeTipsTemplate('AUTH0_CLIENT_SECRET', 'AUTH_AUTH0_SECRET'));
57
+ }
58
+ if (process.env.AUTH0_ISSUER) {
59
+ console.warn(removeTipsTemplate('AUTH0_ISSUER', 'AUTH_AUTH0_ISSUER'));
60
+ }
61
+ if (process.env.AUTHENTIK_CLIENT_ID) {
62
+ console.warn(removeTipsTemplate('AUTHENTIK_CLIENT_ID', 'AUTH_AUTHENTIK_ID'));
63
+ }
64
+ if (process.env.AUTHENTIK_CLIENT_SECRET) {
65
+ console.warn(removeTipsTemplate('AUTHENTIK_CLIENT_SECRET', 'AUTH_AUTHENTIK_SECRET'));
66
+ }
67
+ if (process.env.AUTHENTIK_ISSUER) {
68
+ console.warn(removeTipsTemplate('AUTHENTIK_ISSUER', 'AUTH_AUTHENTIK_ISSUER'));
69
+ }
70
+ if (process.env.AUTHELIA_CLIENT_ID) {
71
+ console.warn(removeTipsTemplate('AUTHELIA_CLIENT_ID', 'AUTH_AUTHELIA_ID'));
72
+ }
73
+ if (process.env.AUTHELIA_CLIENT_SECRET) {
74
+ console.warn(removeTipsTemplate('AUTHELIA_CLIENT_SECRET', 'AUTH_AUTHELIA_SECRET'));
75
+ }
76
+ if (process.env.AUTHELIA_ISSUER) {
77
+ console.warn(removeTipsTemplate('AUTHELIA_ISSUER', 'AUTH_AUTHELIA_ISSUER'));
78
+ }
79
+ if (process.env.AZURE_AD_CLIENT_ID) {
80
+ console.warn(removeTipsTemplate('AZURE_AD_CLIENT_ID', 'AUTH_AZURE_AD_ID'));
81
+ }
82
+ if (process.env.AZURE_AD_CLIENT_SECRET) {
83
+ console.warn(removeTipsTemplate('AZURE_AD_CLIENT_SECRET', 'AUTH_AZURE_AD_SECRET'));
84
+ }
85
+ if (process.env.AZURE_AD_TENANT_ID) {
86
+ console.warn(removeTipsTemplate('AZURE_AD_TENANT_ID', 'AUTH_AZURE_AD_TENANT_ID'));
87
+ }
88
+ if (process.env.CLOUDFLARE_ZERO_TRUST_CLIENT_ID) {
89
+ console.warn(
90
+ removeTipsTemplate('CLOUDFLARE_ZERO_TRUST_CLIENT_ID', 'AUTH_CLOUDFLARE_ZERO_TRUST_ID'),
91
+ );
92
+ }
93
+ if (process.env.CLOUDFLARE_ZERO_TRUST_CLIENT_SECRET) {
94
+ console.warn(
95
+ removeTipsTemplate(
96
+ 'CLOUDFLARE_ZERO_TRUST_CLIENT_SECRET',
97
+ 'AUTH_CLOUDFLARE_ZERO_TRUST_SECRET',
98
+ ),
99
+ );
100
+ }
101
+ if (process.env.CLOUDFLARE_ZERO_TRUST_ISSUER) {
102
+ console.warn(
103
+ removeTipsTemplate('CLOUDFLARE_ZERO_TRUST_ISSUER', 'AUTH_CLOUDFLARE_ZERO_TRUST_ISSUER'),
104
+ );
105
+ }
106
+ if (process.env.GENERIC_OIDC_CLIENT_ID) {
107
+ console.warn(removeTipsTemplate('GENERIC_OIDC_CLIENT_ID', 'AUTH_GENERIC_OIDC_ID'));
108
+ }
109
+ if (process.env.GENERIC_OIDC_CLIENT_SECRET) {
110
+ console.warn(removeTipsTemplate('GENERIC_OIDC_CLIENT_SECRET', 'AUTH_GENERIC_OIDC_SECRET'));
111
+ }
112
+ if (process.env.GENERIC_OIDC_ISSUER) {
113
+ console.warn(removeTipsTemplate('GENERIC_OIDC_ISSUER', 'AUTH_GENERIC_OIDC_ISSUER'));
114
+ }
115
+ if (process.env.GITHUB_CLIENT_ID) {
116
+ console.warn(removeTipsTemplate('GITHUB_CLIENT_ID', 'AUTH_GITHUB_ID'));
117
+ }
118
+ if (process.env.GITHUB_CLIENT_SECRET) {
119
+ console.warn(removeTipsTemplate('GITHUB_CLIENT_SECRET', 'AUTH_GITHUB_SECRET'));
120
+ }
121
+ if (process.env.LOGTO_CLIENT_ID) {
122
+ console.warn(removeTipsTemplate('LOGTO_CLIENT_ID', 'AUTH_LOGTO_ID'));
123
+ }
124
+ if (process.env.LOGTO_CLIENT_SECRET) {
125
+ console.warn(removeTipsTemplate('LOGTO_CLIENT_SECRET', 'AUTH_LOGTO_SECRET'));
126
+ }
127
+ if (process.env.LOGTO_ISSUER) {
128
+ console.warn(removeTipsTemplate('LOGTO_ISSUER', 'AUTH_LOGTO_ISSUER'));
129
+ }
130
+ if (process.env.ZITADEL_CLIENT_ID) {
131
+ console.warn(removeTipsTemplate('ZITADEL_CLIENT_ID', 'AUTH_ZITADEL_ID'));
132
+ }
133
+ if (process.env.ZITADEL_CLIENT_SECRET) {
134
+ console.warn(removeTipsTemplate('ZITADEL_CLIENT_SECRET', 'AUTH_ZITADEL_SECRET'));
135
+ }
136
+ if (process.env.ZITADEL_ISSUER) {
137
+ console.warn(removeTipsTemplate('ZITADEL_ISSUER', 'AUTH_ZITADEL_ISSUER'));
138
+ }
139
+ // End
140
+
46
141
  return createEnv({
47
142
  client: {
48
143
  NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: z.string().optional(),
@@ -95,7 +190,7 @@ export const getAuthConfig = () => {
95
190
  GENERIC_OIDC_CLIENT_ID: z.string().optional(),
96
191
  GENERIC_OIDC_CLIENT_SECRET: z.string().optional(),
97
192
  GENERIC_OIDC_ISSUER: z.string().optional(),
98
-
193
+
99
194
  // ZITADEL
100
195
  ZITADEL_CLIENT_ID: z.string().optional(),
101
196
  ZITADEL_CLIENT_SECRET: z.string().optional(),
@@ -152,7 +247,7 @@ export const getAuthConfig = () => {
152
247
  GENERIC_OIDC_CLIENT_ID: process.env.GENERIC_OIDC_CLIENT_ID,
153
248
  GENERIC_OIDC_CLIENT_SECRET: process.env.GENERIC_OIDC_CLIENT_SECRET,
154
249
  GENERIC_OIDC_ISSUER: process.env.GENERIC_OIDC_ISSUER,
155
-
250
+
156
251
  // ZITADEL
157
252
  ZITADEL_CLIENT_ID: process.env.ZITADEL_CLIENT_ID,
158
253
  ZITADEL_CLIENT_SECRET: process.env.ZITADEL_CLIENT_SECRET,
@@ -161,13 +161,11 @@ describe('LobeQwenAI', () => {
161
161
  vi.spyOn(instance['client'].chat.completions, 'create').mockResolvedValue(
162
162
  new ReadableStream() as any,
163
163
  );
164
-
165
164
  await instance.chat({
166
165
  messages: [{ content: 'Hello', role: 'user' }],
167
166
  model: 'qwen-turbo',
168
167
  temperature: temp,
169
168
  });
170
-
171
169
  expect(instance['client'].chat.completions.create).toHaveBeenCalledWith(
172
170
  expect.objectContaining({
173
171
  messages: expect.any(Array),
@@ -183,13 +181,11 @@ describe('LobeQwenAI', () => {
183
181
  vi.spyOn(instance['client'].chat.completions, 'create').mockResolvedValue(
184
182
  new ReadableStream() as any,
185
183
  );
186
-
187
184
  await instance.chat({
188
185
  messages: [{ content: 'Hello', role: 'user' }],
189
186
  model: 'qwen-turbo',
190
187
  temperature: 1.5,
191
188
  });
192
-
193
189
  expect(instance['client'].chat.completions.create).toHaveBeenCalledWith(
194
190
  expect.objectContaining({
195
191
  messages: expect.any(Array),
@@ -199,6 +195,26 @@ describe('LobeQwenAI', () => {
199
195
  expect.any(Object),
200
196
  );
201
197
  });
198
+
199
+ it('should set temperature to Float', async () => {
200
+ const createMock = vi.fn().mockResolvedValue(new ReadableStream() as any);
201
+ vi.spyOn(instance['client'].chat.completions, 'create').mockImplementation(createMock);
202
+ await instance.chat({
203
+ messages: [{ content: 'Hello', role: 'user' }],
204
+ model: 'qwen-turbo',
205
+ temperature: 1,
206
+ });
207
+ expect(instance['client'].chat.completions.create).toHaveBeenCalledWith(
208
+ expect.objectContaining({
209
+ messages: expect.any(Array),
210
+ model: 'qwen-turbo',
211
+ temperature: expect.any(Number),
212
+ }),
213
+ expect.any(Object),
214
+ );
215
+ const callArgs = createMock.mock.calls[0][0];
216
+ expect(Number.isInteger(callArgs.temperature)).toBe(false); // Temperature is always not an integer
217
+ });
202
218
  });
203
219
 
204
220
  describe('Error', () => {
@@ -111,7 +111,7 @@ export class LobeQwenAI implements LobeRuntimeAI {
111
111
  temperature:
112
112
  temperature === 0 || temperature >= 2
113
113
  ? undefined
114
- : temperature,
114
+ : (temperature === 1 ? 0.999 : temperature), // 'temperature' must be Float
115
115
  top_p: top_p && top_p >= 1 ? 0.999 : top_p,
116
116
  };
117
117
 
@@ -1,4 +1,5 @@
1
1
  import type { NextAuthConfig } from 'next-auth';
2
+ import urlJoin from 'url-join';
2
3
 
3
4
  import { authEnv } from '@/config/auth';
4
5
 
@@ -40,6 +41,7 @@ export default {
40
41
  },
41
42
  },
42
43
  providers: initSSOProviders(),
44
+ redirectProxyUrl: process.env.APP_URL ? urlJoin(process.env.APP_URL, '/api/auth') : undefined,
43
45
  secret: authEnv.NEXT_AUTH_SECRET,
44
- trustHost: true,
46
+ trustHost: process.env?.AUTH_TRUST_HOST ? process.env.AUTH_TRUST_HOST === 'true' : true,
45
47
  } satisfies NextAuthConfig;
@@ -11,9 +11,11 @@ const provider = {
11
11
  // Specify auth scope, at least include 'openid email'
12
12
  // all scopes in Auth0 ref: https://auth0.com/docs/get-started/apis/scopes/openid-connect-scopes#standard-claims
13
13
  authorization: { params: { scope: 'openid email profile' } },
14
- clientId: authEnv.AUTH0_CLIENT_ID,
15
- clientSecret: authEnv.AUTH0_CLIENT_SECRET,
16
- issuer: authEnv.AUTH0_ISSUER,
14
+ // TODO(NextAuth ENVs Migration): Remove once nextauth envs migration time end
15
+ clientId: authEnv.AUTH0_CLIENT_ID ?? process.env.AUTH_AUTH0_ID,
16
+ clientSecret: authEnv.AUTH0_CLIENT_SECRET ?? process.env.AUTH_AUTH0_SECRET,
17
+ issuer: authEnv.AUTH0_ISSUER ?? process.env.AUTH_AUTH0_ISSUER,
18
+ // Remove End
17
19
  profile(profile) {
18
20
  return {
19
21
  email: profile.email,
@@ -6,11 +6,11 @@ import { CommonProviderConfig } from './sso.config';
6
6
 
7
7
  export type AutheliaProfile = {
8
8
  // The users display name
9
- email: string;
9
+ email: string;
10
10
  // The users email
11
- groups: string[];
11
+ groups: string[];
12
12
  // The username the user used to login with
13
- name: string;
13
+ name: string;
14
14
  preferred_username: string; // The users groups
15
15
  sub: string; // The users id
16
16
  };
@@ -21,10 +21,10 @@ const provider = {
21
21
  ...CommonProviderConfig,
22
22
  authorization: { params: { scope: 'openid email profile' } },
23
23
  checks: ['state', 'pkce'],
24
- clientId: authEnv.AUTHELIA_CLIENT_ID,
25
- clientSecret: authEnv.AUTHELIA_CLIENT_SECRET,
24
+ clientId: authEnv.AUTHELIA_CLIENT_ID ?? process.env.AUTH_AUTHELIA_ID,
25
+ clientSecret: authEnv.AUTHELIA_CLIENT_SECRET ?? process.env.AUTH_AUTHELIA_SECRET,
26
26
  id: 'authelia',
27
- issuer: authEnv.AUTHELIA_ISSUER,
27
+ issuer: authEnv.AUTHELIA_ISSUER ?? process.env.AUTH_AUTHELIA_ISSUER,
28
28
  name: 'Authelia',
29
29
  profile(profile) {
30
30
  return {
@@ -11,9 +11,11 @@ const provider = {
11
11
  // Specify auth scope, at least include 'openid email'
12
12
  // all scopes in Authentik ref: https://goauthentik.io/docs/providers/oauth2
13
13
  authorization: { params: { scope: 'openid email profile' } },
14
- clientId: authEnv.AUTHENTIK_CLIENT_ID,
15
- clientSecret: authEnv.AUTHENTIK_CLIENT_SECRET,
16
- issuer: authEnv.AUTHENTIK_ISSUER,
14
+ // TODO(NextAuth ENVs Migration): Remove once nextauth envs migration time end
15
+ clientId: authEnv.AUTHENTIK_CLIENT_ID ?? process.env.AUTH_AUTHENTIK_ID,
16
+ clientSecret: authEnv.AUTHENTIK_CLIENT_SECRET ?? process.env.AUTH_AUTHENTIK_SECRET,
17
+ issuer: authEnv.AUTHENTIK_ISSUER ?? process.env.AUTH_AUTHENTIK_ISSUER,
18
+ // Remove end
17
19
  // TODO(NextAuth): map unique user id to `providerAccountId` field
18
20
  // profile(profile) {
19
21
  // return {
@@ -11,9 +11,11 @@ const provider = {
11
11
  // Specify auth scope, at least include 'openid email'
12
12
  // all scopes in Azure AD ref: https://learn.microsoft.com/en-us/entra/identity-platform/scopes-oidc#openid-connect-scopes
13
13
  authorization: { params: { scope: 'openid email profile' } },
14
- clientId: authEnv.AZURE_AD_CLIENT_ID,
15
- clientSecret: authEnv.AZURE_AD_CLIENT_SECRET,
16
- tenantId: authEnv.AZURE_AD_TENANT_ID,
14
+ // TODO(NextAuth ENVs Migration): Remove once nextauth envs migration time end
15
+ clientId: authEnv.AZURE_AD_CLIENT_ID ?? process.env.AUTH_AZURE_AD_ID,
16
+ clientSecret: authEnv.AZURE_AD_CLIENT_SECRET ?? process.env.AUTH_AZURE_AD_SECRET,
17
+ tenantId: authEnv.AZURE_AD_TENANT_ID ?? process.env.AUTH_AZURE_AD_TENANT_ID,
18
+ // Remove end
17
19
  // TODO(NextAuth): map unique user id to `providerAccountId` field
18
20
  // profile(profile) {
19
21
  // return {
@@ -16,10 +16,11 @@ const provider = {
16
16
  ...CommonProviderConfig,
17
17
  authorization: { params: { scope: 'openid email profile' } },
18
18
  checks: ['state', 'pkce'],
19
- clientId: authEnv.CLOUDFLARE_ZERO_TRUST_CLIENT_ID,
20
- clientSecret: authEnv.CLOUDFLARE_ZERO_TRUST_CLIENT_SECRET,
19
+ clientId: authEnv.CLOUDFLARE_ZERO_TRUST_CLIENT_ID ?? process.env.AUTH_CLOUDFLARE_ZERO_TRUST_ID,
20
+ clientSecret:
21
+ authEnv.CLOUDFLARE_ZERO_TRUST_CLIENT_SECRET ?? process.env.AUTH_CLOUDFLARE_ZERO_TRUST_SECRET,
21
22
  id: 'cloudflare-zero-trust',
22
- issuer: authEnv.CLOUDFLARE_ZERO_TRUST_ISSUER,
23
+ issuer: authEnv.CLOUDFLARE_ZERO_TRUST_ISSUER ?? process.env.AUTH_CLOUDFLARE_ZERO_TRUST_ISSUER,
23
24
  name: 'Cloudflare Zero Trust',
24
25
  profile(profile) {
25
26
  return {
@@ -19,10 +19,10 @@ const provider = {
19
19
  ...CommonProviderConfig,
20
20
  authorization: { params: { scope: 'email openid profile' } },
21
21
  checks: ['state', 'pkce'],
22
- clientId: authEnv.GENERIC_OIDC_CLIENT_ID,
23
- clientSecret: authEnv.GENERIC_OIDC_CLIENT_SECRET,
22
+ clientId: authEnv.GENERIC_OIDC_CLIENT_ID ?? process.env.AUTH_GENERIC_OIDC_ID,
23
+ clientSecret: authEnv.GENERIC_OIDC_CLIENT_SECRET ?? process.env.AUTH_GENERIC_OIDC_SECRET,
24
24
  id: 'generic-oidc',
25
- issuer: authEnv.GENERIC_OIDC_ISSUER,
25
+ issuer: authEnv.GENERIC_OIDC_ISSUER ?? process.env.AUTH_GENERIC_OIDC_ISSUER,
26
26
  name: 'Generic OIDC',
27
27
  profile(profile) {
28
28
  return {
@@ -10,8 +10,10 @@ const provider = {
10
10
  ...CommonProviderConfig,
11
11
  // Specify auth scope, at least include 'openid email'
12
12
  authorization: { params: { scope: 'read:user user:email' } },
13
- clientId: authEnv.GITHUB_CLIENT_ID,
14
- clientSecret: authEnv.GITHUB_CLIENT_SECRET,
13
+ // TODO(NextAuth ENVs Migration): Remove once nextauth envs migration time end
14
+ clientId: authEnv.GITHUB_CLIENT_ID ?? process.env.AUTH_GITHUB_ID,
15
+ clientSecret: authEnv.GITHUB_CLIENT_SECRET ?? process.env.AUTH_GITHUB_SECRET,
16
+ // Remove end
15
17
  profile: (profile) => {
16
18
  return {
17
19
  email: profile.email,
@@ -41,9 +41,9 @@ const provider = {
41
41
  },
42
42
  // You can get the issuer value from the Logto Application Details page,
43
43
  // in the field "Issuer endpoint"
44
- clientId: authEnv.LOGTO_CLIENT_ID,
45
- clientSecret: authEnv.LOGTO_CLIENT_SECRET,
46
- issuer: authEnv.LOGTO_ISSUER,
44
+ clientId: authEnv.LOGTO_CLIENT_ID ?? process.env.AUTH_LOGTO_ID,
45
+ clientSecret: authEnv.LOGTO_CLIENT_SECRET ?? process.env.AUTH_LOGTO_SECRET,
46
+ issuer: authEnv.LOGTO_ISSUER ?? process.env.AUTH_LOGTO_ISSUER,
47
47
  }),
48
48
  };
49
49
 
@@ -7,9 +7,11 @@ const provider = {
7
7
  provider: Zitadel({
8
8
  // Available scopes in ZITADEL: https://zitadel.com/docs/apis/openidoauth/scopes
9
9
  authorization: { params: { scope: 'openid email profile' } },
10
- clientId: authEnv.ZITADEL_CLIENT_ID,
11
- clientSecret: authEnv.ZITADEL_CLIENT_SECRET,
12
- issuer: authEnv.ZITADEL_ISSUER,
10
+ // TODO(NextAuth ENVs Migration): Remove once nextauth envs migration time end
11
+ clientId: authEnv.ZITADEL_CLIENT_ID ?? process.env.AUTH_ZITADEL_ID,
12
+ clientSecret: authEnv.ZITADEL_CLIENT_SECRET ?? process.env.AUTH_ZITADEL_SECRET,
13
+ issuer: authEnv.ZITADEL_ISSUER ?? process.env.AUTH_ZITADEL_ISSUER,
14
+ // Remove end
13
15
  // TODO(NextAuth): map unique user id to `providerAccountId` field
14
16
  // profile(profile) {
15
17
  // return {