@lobehub/chat 0.123.2 → 0.123.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/.env.example CHANGED
@@ -40,13 +40,13 @@ OPENAI_API_KEY=sk-xxxxxxxxx
40
40
  #ZHIPU_API_KEY=xxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxx
41
41
 
42
42
  ########################################
43
- ############ Google AI Service ##########
43
+ ########### Google AI Service ##########
44
44
  ########################################
45
45
 
46
- #GOOGLE_API_KEY=xxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxx
46
+ #GOOGLE_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
47
47
 
48
48
  ########################################
49
- ############ AWS Bedrock Service ##########
49
+ ######### AWS Bedrock Service ##########
50
50
  ########################################
51
51
 
52
52
  #AWS_REGION=us-east-1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,31 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ### [Version 0.123.3](https://github.com/lobehub/lobe-chat/compare/v0.123.2...v0.123.3)
6
+
7
+ <sup>Released on **2024-02-06**</sup>
8
+
9
+ #### 🐛 Bug Fixes
10
+
11
+ - **misc**: Fix non-https `crypto.subtile` missing error.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### What's fixed
19
+
20
+ - **misc**: Fix non-https `crypto.subtile` missing error, closes [#1238](https://github.com/lobehub/lobe-chat/issues/1238) ([1750d0b](https://github.com/lobehub/lobe-chat/commit/1750d0b))
21
+
22
+ </details>
23
+
24
+ <div align="right">
25
+
26
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
27
+
28
+ </div>
29
+
5
30
  ### [Version 0.123.2](https://github.com/lobehub/lobe-chat/compare/v0.123.1...v0.123.2)
6
31
 
7
32
  <sup>Released on **2024-02-06**</sup>
package/Dockerfile CHANGED
@@ -73,6 +73,6 @@ ENV AZURE_API_VERSION ""
73
73
  ENV GOOGLE_API_KEY ""
74
74
 
75
75
  # Zhipu
76
- ENV Zhipu_API_KEY ""
76
+ ENV ZHIPU_API_KEY ""
77
77
 
78
78
  CMD ["node", "server.js"]
package/README.md CHANGED
@@ -225,14 +225,12 @@ Our marketplace is not just a showcase platform but also a collaborative space.
225
225
 
226
226
  <!-- AGENT LIST -->
227
227
 
228
- | Recent Submits | Description |
229
- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
230
- | [Database Expert](https://chat-preview.lobehub.com/market?agent=dba)<br/><sup>By **[xuzhen1994](https://github.com/xuzhen1994)** on **2024-02-03**</sup> | Role: Database Expert |
231
- | Expertise: Possesses professional knowledge in the field of databases. Understands the working principles, advantages and disadvantages, applicable scenarios, and best practices of relational databases such as MySQL, PostgreSQL, Oracle, etc. Also familiar with the characteristics and usage scenarios of non-relational databases like MongoDB, Cassandra, Redis, as well as the advantages and applicable situations of columnar databases such as ClickHouse, Vertica, etc. Additionally, has knowledge of distributed database systems like Doris, HBase, CockroachDB, including their principles and applications. | |
232
- | Responsibilities: Provides professional advice on database design paradigms, index optimization, query performance tuning, data security, backup and recovery, and advanced topics such as database cluster deployment, disaster recovery design, and data migration.<br/>`database` `dba` `mysql` `clickhouse` `doris` `mongo-db` `oracle` | |
233
- | [Presentation Wizard](https://chat-preview.lobehub.com/market?agent=word)<br/><sup>By **[MYSeaIT](https://github.com/MYSeaIT)** on **2024-02-03**</sup> | App Presentation Maker Bot for Word: Assists in creating impressive and professional app presentations in Microsoft Word.<br/>`app-presentation` `microsoft-word` `bot` `assistance` `template` |
234
- | [SagePathfinder](https://chat-preview.lobehub.com/market?agent=sage-pathfinder)<br/><sup>By **[Ajasra](https://github.com/Ajasra)** on **2024-01-31**</sup> | Expert in personal growth coaching with a focus on stoicism, deep reflection, and strategic questioning.<br/>`personal-growth` `coaching` `reflection` `goal-setting` `well-being` |
235
- | [Variable Naming Master](https://chat-preview.lobehub.com/market?agent=variable-naming-assistant)<br/><sup>By **[undefinedZNN](https://github.com/undefinedZNN)** on **2024-01-31**</sup> | Master the art of programming variable naming, providing multiple suggestions and explaining their usage scenarios.<br/>`variable-naming` `programming` `suggestions` |
228
+ | Recent Submits | Description |
229
+ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
230
+ | [Database Expert](https://chat-preview.lobehub.com/market?agent=dba)<br/><sup>By **[xuzhen1994](https://github.com/xuzhen1994)** on **2024-02-03**</sup> | Provides professional advice on database design paradigms, index optimization, query performance tuning, data security, backup and recovery.<br/>`database` `dba` `mysql` `clickhouse` `doris` `mongo-db` `oracle` |
231
+ | [Presentation Wizard](https://chat-preview.lobehub.com/market?agent=word)<br/><sup>By **[MYSeaIT](https://github.com/MYSeaIT)** on **2024-02-03**</sup> | App Presentation Maker Bot for Word: Assists in creating impressive and professional app presentations in Microsoft Word.<br/>`app-presentation` `microsoft-word` `bot` `assistance` `template` |
232
+ | [SagePathfinder](https://chat-preview.lobehub.com/market?agent=sage-pathfinder)<br/><sup>By **[Ajasra](https://github.com/Ajasra)** on **2024-01-31**</sup> | Expert in personal growth coaching with a focus on stoicism, deep reflection, and strategic questioning.<br/>`personal-growth` `coaching` `reflection` `goal-setting` `well-being` |
233
+ | [Variable Naming Master](https://chat-preview.lobehub.com/market?agent=variable-naming-assistant)<br/><sup>By **[undefinedZNN](https://github.com/undefinedZNN)** on **2024-01-31**</sup> | Master the art of programming variable naming, providing multiple suggestions and explaining their usage scenarios.<br/>`variable-naming` `programming` `suggestions` |
236
234
 
237
235
  > 📊 Total agents: [<kbd>**149**</kbd> ](https://github.com/lobehub/lobe-chat-agents)
238
236
 
package/README.zh-CN.md CHANGED
@@ -205,14 +205,12 @@ LobeChat 的插件生态系统是其核心功能的重要扩展,它极大地
205
205
 
206
206
  <!-- AGENT LIST -->
207
207
 
208
- | 最近新增 | 助手说明 |
209
- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
210
- | [数据库专家](https://chat-preview.lobehub.com/market?agent=dba)<br/><sup>By **[xuzhen1994](https://github.com/xuzhen1994)** on **2024-02-03**</sup> | 角色:数据库专家 |
211
- | 专长:具备数据库方面的专业知识。关系型数据库,比如 MySQL、PostgreSQL、Oracle 等的工作原理、优缺点、适用场景以及最佳实践。非关系型数据库,比如 MongoDB、Cassandra、Redis 等的特点和使用场景。列式数据库,例如 ClickHouse、Vertica 等的优势和适用情况。分布式数据库系统,例如 Doris、HBase、CockroachDB 等的原理和应用等。 | |
212
- | 职责:提供关于数据库设计范式、索引优化、查询性能调优、数据安全、备份与恢复等方面的专业建议。另外还有对于数据库集群部署、容灾设计、数据迁移等高级主题的指导。<br/>`数据库` `dba` `mysql` `clickhouse` `doris` `mongo-db` `oracle` | |
213
- | [演示向导](https://chat-preview.lobehub.com/market?agent=word)<br/><sup>By **[MYSeaIT](https://github.com/MYSeaIT)** on **2024-02-03**</sup> | Word 应用演示制作机器人:帮助在 Microsoft Word 中创建令人印象深刻和专业的应用程序演示。<br/>`应用程序演示` `微软-word` `机器人` `辅助` `模板` |
214
- | [SagePathfinder](https://chat-preview.lobehub.com/market?agent=sage-pathfinder)<br/><sup>By **[Ajasra](https://github.com/Ajasra)** on **2024-01-31**</sup> | 专注于斯多葛主义、深度反思和战略性提问的个人成长教练专家。<br/>`个人成长` `教练` `反思` `目标设定` `幸福感` |
215
- | [变量命名大师](https://chat-preview.lobehub.com/market?agent=variable-naming-assistant)<br/><sup>By **[undefinedZNN](https://github.com/undefinedZNN)** on **2024-01-31**</sup> | 精通编程变量命名,提供多个建议并解释使用场景。<br/>`变量命名` `编程` `建议` |
208
+ | 最近新增 | 助手说明 |
209
+ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
210
+ | [数据库专家](https://chat-preview.lobehub.com/market?agent=dba)<br/><sup>By **[xuzhen1994](https://github.com/xuzhen1994)** on **2024-02-03**</sup> | 提供关于数据库设计范式、索引优化、查询性能调优、数据安全、备份与恢复等方面的专业建议<br/>`数据库` `dba` `mysql` `clickhouse` `doris` `mongo-db` `oracle` |
211
+ | [演示向导](https://chat-preview.lobehub.com/market?agent=word)<br/><sup>By **[MYSeaIT](https://github.com/MYSeaIT)** on **2024-02-03**</sup> | Word 应用演示制作机器人:帮助在 Microsoft Word 中创建令人印象深刻和专业的应用程序演示。<br/>`应用程序演示` `微软-word` `机器人` `辅助` `模板` |
212
+ | [SagePathfinder](https://chat-preview.lobehub.com/market?agent=sage-pathfinder)<br/><sup>By **[Ajasra](https://github.com/Ajasra)** on **2024-01-31**</sup> | 专注于斯多葛主义、深度反思和战略性提问的个人成长教练专家。<br/>`个人成长` `教练` `反思` `目标设定` `幸福感` |
213
+ | [变量命名大师](https://chat-preview.lobehub.com/market?agent=variable-naming-assistant)<br/><sup>By **[undefinedZNN](https://github.com/undefinedZNN)** on **2024-01-31**</sup> | 精通编程变量命名,提供多个建议并解释使用场景。<br/>`变量命名` `编程` `建议` |
216
214
 
217
215
  > 📊 Total agents: [<kbd>**149**</kbd> ](https://github.com/lobehub/lobe-chat-agents)
218
216
 
@@ -8,7 +8,6 @@ LobeChat provides additional configuration options during deployment, which can
8
8
  - [`ACCESS_CODE`](#access_code)
9
9
  - [Model Service Providers](#model-service-providers)
10
10
  - [OpenAI](#openai)
11
- - [`CUSTOM_MODELS`](#custom_models)
12
11
  - [Azure OpenAI](#azure-openai)
13
12
  - [Zhipu AI](#zhipu-ai)
14
13
  - [Google AI](#google-ai)
@@ -62,7 +61,7 @@ Related discussions:
62
61
  - [Reasons for errors when using third-party interfaces](https://github.com/lobehub/lobe-chat/discussions/734)
63
62
  - [No response when filling in the proxy server address for chatting](https://github.com/lobehub/lobe-chat/discussions/1065)
64
63
 
65
- ### `CUSTOM_MODELS`
64
+ #### `CUSTOM_MODELS`
66
65
 
67
66
  - Type: Optional
68
67
  - Description: Used to control the model list. Use `+` to add a model, `-` to hide a model, and `model_name=display_name` to customize the display name of a model, separated by commas.
@@ -71,6 +70,8 @@ Related discussions:
71
70
 
72
71
  The above example adds `qwen-7b-chat` and `glm-6b` to the model list, removes `gpt-3.5-turbo` from the list, and displays the model name `gpt-4-0125-preview` as `gpt-4-turbo`. If you want to disable all models first and then enable specific models, you can use `-all,+gpt-3.5-turbo`, which means only `gpt-3.5-turbo` will be enabled.
73
72
 
73
+ You can find all current model names in [modelProviders](https://github.com/lobehub/lobe-chat/tree/main/src/config/modelProviders).
74
+
74
75
  ### Azure OpenAI
75
76
 
76
77
  If you need to use Azure OpenAI to provide model services, you can refer to the [Deploy with Azure OpenAI](Deploy-with-Azure-OpenAI.zh-CN.md) section for detailed steps. Here are the environment variables related to Azure OpenAI.
@@ -8,7 +8,6 @@ LobeChat 在部署时提供了一些额外的配置项,使用环境变量进
8
8
  - [`ACCESS_CODE`](#access_code)
9
9
  - [模型服务商](#模型服务商)
10
10
  - [OpenAI](#openai)
11
- - [`CUSTOM_MODELS`](#custom_models)
12
11
  - [Azure OpenAI](#azure-openai)
13
12
  - [智谱 AI](#智谱-ai)
14
13
  - [Google AI](#google-ai)
@@ -62,7 +61,7 @@ LobeChat 在部署时提供了一些额外的配置项,使用环境变量进
62
61
  - [使用第三方接口报错的原因](https://github.com/lobehub/lobe-chat/discussions/734)
63
62
  - [代理服务器地址填了聊天没任何反应](https://github.com/lobehub/lobe-chat/discussions/1065)
64
63
 
65
- ### `CUSTOM_MODELS`
64
+ #### `CUSTOM_MODELS`
66
65
 
67
66
  - 类型:可选
68
67
  - 描述:用来控制模型列表,使用 `+` 增加一个模型,使用 `-` 来隐藏一个模型,使用 `模型名=展示名` 来自定义模型的展示名,用英文逗号隔开。
@@ -71,6 +70,8 @@ LobeChat 在部署时提供了一些额外的配置项,使用环境变量进
71
70
 
72
71
  上面示例表示增加 `qwen-7b-chat` 和 `glm-6b` 到模型列表,而从列表中删除 `gpt-3.5-turbo`,并将 `gpt-4-0125-preview` 模型名字展示为 `gpt-4-turbo`。如果你想先禁用所有模型,再启用指定模型,可以使用 `-all,+gpt-3.5-turbo`,则表示仅启用 `gpt-3.5-turbo`。
73
72
 
73
+ 你可以在 [modelProviders](https://github.com/lobehub/lobe-chat/tree/main/src/config/modelProviders) 查找到当前的所有模型名。
74
+
74
75
  ### Azure OpenAI
75
76
 
76
77
  如果你需要使用 Azure OpenAI 来提供模型服务,可以查阅 [使用 Azure OpenAI 部署](Deploy-with-Azure-OpenAI.zh-CN.md) 章节查看详细步骤,这里将列举和 Azure OpenAI 相关的环境变量。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "0.123.2",
3
+ "version": "0.123.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",
@@ -145,6 +145,7 @@
145
145
  "@lobehub/lint": "latest",
146
146
  "@next/bundle-analyzer": "^14",
147
147
  "@next/eslint-plugin-next": "^14",
148
+ "@peculiar/webcrypto": "^1.4.5",
148
149
  "@testing-library/jest-dom": "^6",
149
150
  "@testing-library/react": "^14",
150
151
  "@types/chroma-js": "^2",
@@ -40,11 +40,13 @@ export const POST = async (req: Request, { params }: { params: { provider: strin
40
40
  } catch (e) {
41
41
  // if catch the error, just return it
42
42
  const err = e as AgentInitErrorPayload;
43
-
44
- return createErrorResponse(err.errorType as ILobeAgentRuntimeErrorType, {
45
- error: err.error,
46
- provider: params.provider,
47
- });
43
+ return createErrorResponse(
44
+ (err.errorType || ChatErrorType.InternalServerError) as ILobeAgentRuntimeErrorType,
45
+ {
46
+ error: err.error || e,
47
+ provider: params.provider,
48
+ },
49
+ );
48
50
  }
49
51
 
50
52
  // ============ 2. create chat completion ============ //
@@ -1,11 +1,22 @@
1
1
  import { importJWK, jwtVerify } from 'jose';
2
2
 
3
3
  import { getServerConfig } from '@/config/server';
4
- import { JWTPayload, JWT_SECRET_KEY } from '@/const/auth';
4
+ import { JWTPayload, JWT_SECRET_KEY, NON_HTTP_PREFIX } from '@/const/auth';
5
5
  import { AgentRuntimeError } from '@/libs/agent-runtime';
6
6
  import { ChatErrorType } from '@/types/fetch';
7
7
 
8
- export const getJWTPayload = async (token: string) => {
8
+ export const getJWTPayload = async (token: string): Promise<JWTPayload> => {
9
+ //如果是 HTTP 协议发起的请求,直接解析 token
10
+ // 这是一个非常 hack 的解决方案,未来要找更好的解决方案来处理这个问题
11
+ // refs: https://github.com/lobehub/lobe-chat/pull/1238
12
+ if (token.startsWith(NON_HTTP_PREFIX)) {
13
+ const jwtParts = token.split('.');
14
+
15
+ const payload = jwtParts[1];
16
+
17
+ return JSON.parse(atob(payload));
18
+ }
19
+
9
20
  const encoder = new TextEncoder();
10
21
  const secretKey = await crypto.subtle.digest('SHA-256', encoder.encode(JWT_SECRET_KEY));
11
22
 
@@ -1,16 +1,13 @@
1
- import { consola } from 'consola';
2
-
3
1
  import { AgentRuntimeErrorType, ILobeAgentRuntimeErrorType } from '@/libs/agent-runtime';
4
- import { ChatErrorType, ErrorResponse, ErrorType } from '@/types/fetch';
2
+ import { ErrorResponse, ErrorType } from '@/types/fetch';
5
3
 
6
4
  const getStatus = (errorType: ILobeAgentRuntimeErrorType | ErrorType) => {
5
+ // InvalidAccessCode / InvalidAzureAPIKey / InvalidOpenAIAPIKey / InvalidZhipuAPIKey ....
6
+ if (errorType.toString().includes('Invalid')) return 401;
7
+
7
8
  switch (errorType) {
8
- case ChatErrorType.InvalidAccessCode:
9
- case AgentRuntimeErrorType.NoOpenAIAPIKey:
10
- case AgentRuntimeErrorType.InvalidAzureAPIKey:
11
- case AgentRuntimeErrorType.InvalidBedrockCredentials:
12
- case AgentRuntimeErrorType.InvalidZhipuAPIKey:
13
- case AgentRuntimeErrorType.InvalidGoogleAPIKey: {
9
+ // TODO: Need to refactor to Invalid OpenAI API Key
10
+ case AgentRuntimeErrorType.NoOpenAIAPIKey: {
14
11
  return 401;
15
12
  }
16
13
 
@@ -38,7 +35,8 @@ const getStatus = (errorType: ILobeAgentRuntimeErrorType | ErrorType) => {
38
35
  return 475;
39
36
  }
40
37
  }
41
- return errorType;
38
+
39
+ return errorType as number;
42
40
  };
43
41
 
44
42
  export const createErrorResponse = (
@@ -50,7 +48,7 @@ export const createErrorResponse = (
50
48
  const data: ErrorResponse = { body, errorType };
51
49
 
52
50
  if (typeof statusCode !== 'number' || statusCode < 200 || statusCode > 599) {
53
- consola.error(
51
+ console.error(
54
52
  `current StatusCode: \`${statusCode}\` .`,
55
53
  'Please go to `./src/app/api/errorResponse.ts` to defined the statusCode.',
56
54
  );
@@ -34,10 +34,13 @@ const ModelProviderIcon = memo<ModelProviderIconProps>(({ provider }) => {
34
34
  );
35
35
  }
36
36
 
37
- default:
38
37
  case ModelProvider.OpenAI: {
39
38
  return <OpenAI size={20} />;
40
39
  }
40
+
41
+ default: {
42
+ return null;
43
+ }
41
44
  }
42
45
  });
43
46
 
@@ -29,6 +29,7 @@ const OpenAI: ModelProviderCard = {
29
29
  tokens: 4096,
30
30
  },
31
31
  {
32
+ displayName: 'GPT-3.5 Turbo 16K',
32
33
  hidden: true,
33
34
  id: 'gpt-3.5-turbo-16k',
34
35
  tokens: 16_385,
@@ -65,12 +66,14 @@ const OpenAI: ModelProviderCard = {
65
66
  vision: true,
66
67
  },
67
68
  {
69
+ displayName: 'GPT-4 Turbo Preview (1106)',
68
70
  functionCall: true,
69
71
  hidden: true,
70
72
  id: 'gpt-4-1106-preview',
71
73
  tokens: 128_000,
72
74
  },
73
75
  {
76
+ displayName: 'GPT-4',
74
77
  functionCall: true,
75
78
  hidden: true,
76
79
  id: 'gpt-4',
package/src/const/auth.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export const LOBE_CHAT_AUTH_HEADER = 'X-lobe-chat-auth';
2
2
 
3
3
  export const JWT_SECRET_KEY = 'LobeHub · LobeChat';
4
+ export const NON_HTTP_PREFIX = 'http_nosafe';
4
5
 
5
6
  /* eslint-disable typescript-sort-keys/interface */
6
7
  export interface JWTPayload {
@@ -17,7 +17,7 @@ export const getErrorAlertConfig = (
17
17
  errorType?: IPluginErrorType | ILobeAgentRuntimeErrorType | ErrorType,
18
18
  ): AlertProps | undefined => {
19
19
  // OpenAIBizError / ZhipuBizError / GoogleBizError / ...
20
- if (typeof errorType === 'string' && errorType.includes('Biz'))
20
+ if (typeof errorType === 'string' && (errorType.includes('Biz') || errorType.includes('Invalid')))
21
21
  return {
22
22
  extraDefaultExpand: true,
23
23
  extraIsolate: true,
@@ -31,12 +31,7 @@ export const getErrorAlertConfig = (
31
31
  };
32
32
  }
33
33
 
34
- case PluginErrorType.PluginSettingsInvalid:
35
- case ChatErrorType.InvalidAccessCode:
36
- case AgentRuntimeErrorType.NoOpenAIAPIKey:
37
- case AgentRuntimeErrorType.InvalidBedrockCredentials:
38
- case AgentRuntimeErrorType.InvalidGoogleAPIKey:
39
- case AgentRuntimeErrorType.InvalidZhipuAPIKey: {
34
+ case ChatErrorType.InvalidAccessCode: {
40
35
  return {
41
36
  extraDefaultExpand: true,
42
37
  extraIsolate: true,
@@ -33,6 +33,7 @@ const Locale = memo<LocaleLayoutProps>(({ children, defaultLang }) => {
33
33
  const [lang, setLang] = useState(defaultLang);
34
34
 
35
35
  const { data: locale } = useSWR(['antd-locale', lang], ([, key]) => getAntdLocale(key), {
36
+ dedupingInterval: 0,
36
37
  revalidateOnFocus: false,
37
38
  });
38
39
 
@@ -1,16 +1,15 @@
1
1
  /* eslint-disable sort-keys-fix/sort-keys-fix */
2
-
3
2
  // ******* Runtime Biz Error ******* //
4
3
  export const AgentRuntimeErrorType = {
5
4
  AgentRuntimeError: 'AgentRuntimeError', // Agent Runtime 模块运行时错误
6
5
  LocationNotSupportError: 'LocationNotSupportError',
7
6
 
8
- OpenAIBizError: 'OpenAIBizError', // OpenAI 返回的业务错误
7
+ OpenAIBizError: 'OpenAIBizError',
9
8
 
10
9
  NoOpenAIAPIKey: 'NoOpenAIAPIKey',
11
10
 
12
11
  InvalidAzureAPIKey: 'InvalidAzureAPIKey',
13
- AzureBizError: 'AzureBizError', // Azure 返回的业务错误
12
+ AzureBizError: 'AzureBizError',
14
13
 
15
14
  InvalidZhipuAPIKey: 'InvalidZhipuAPIKey',
16
15
  ZhipuBizError: 'ZhipuBizError',
@@ -19,7 +18,7 @@ export const AgentRuntimeErrorType = {
19
18
  GoogleBizError: 'GoogleBizError',
20
19
 
21
20
  InvalidBedrockCredentials: 'InvalidBedrockCredentials',
22
- BedrockBizError: 'BedrockBizError', // Bedrock 返回的业务错误
21
+ BedrockBizError: 'BedrockBizError',
23
22
  } as const;
24
23
 
25
24
  export type ILobeAgentRuntimeErrorType =
@@ -1,34 +1,8 @@
1
- import { SignJWT, importJWK } from 'jose';
2
-
3
- import { JWTPayload, JWT_SECRET_KEY, LOBE_CHAT_AUTH_HEADER } from '@/const/auth';
1
+ import { JWTPayload, LOBE_CHAT_AUTH_HEADER } from '@/const/auth';
4
2
  import { ModelProvider } from '@/libs/agent-runtime';
5
3
  import { useGlobalStore } from '@/store/global';
6
4
  import { modelProviderSelectors, settingsSelectors } from '@/store/global/selectors';
7
-
8
- const createJWT = async (payload: JWTPayload) => {
9
- // 将AccessCode转换成适合作为密钥的格式,例如使用SHA-256进行哈希
10
- const encoder = new TextEncoder();
11
- const secretKey = await crypto.subtle.digest('SHA-256', encoder.encode(JWT_SECRET_KEY));
12
-
13
- // 将密钥导入为JWK格式
14
- const jwkSecretKey = await importJWK(
15
- {
16
- k: Buffer.from(secretKey).toString('base64'),
17
- kty: 'oct',
18
- },
19
- 'HS256',
20
- );
21
-
22
- // 获取当前时间戳
23
- const now = Math.floor(Date.now() / 1000);
24
-
25
- // 创建JWT
26
- return new SignJWT(payload as Record<string, any>)
27
- .setProtectedHeader({ alg: 'HS256' })
28
- .setIssuedAt(now) // 设置JWT的iat(签发时间)声明
29
- .setExpirationTime(now + 100) // 设置 JWT 的 exp(过期时间)为 100 s
30
- .sign(jwkSecretKey);
31
- };
5
+ import { createJWT } from '@/utils/jwt';
32
6
 
33
7
  const getProviderAuthPayload = (provider: string) => {
34
8
  switch (provider) {
@@ -81,7 +55,7 @@ const getProviderAuthPayload = (provider: string) => {
81
55
  const createAuthTokenWithPayload = async (payload = {}) => {
82
56
  const accessCode = settingsSelectors.password(useGlobalStore.getState());
83
57
 
84
- return await createJWT({ accessCode, ...payload });
58
+ return await createJWT<JWTPayload>({ accessCode, ...payload });
85
59
  };
86
60
 
87
61
  interface AuthParams {
@@ -21,6 +21,7 @@ exports[`modelProviderSelectors > CUSTOM_MODELS > custom deletion, addition, and
21
21
  {
22
22
  "displayName": "gpt-4-32k",
23
23
  "functionCall": true,
24
+ "hidden": undefined,
24
25
  "id": "gpt-4-0125-preview",
25
26
  "tokens": 128000,
26
27
  },
@@ -23,6 +23,62 @@ describe('modelProviderSelectors', () => {
23
23
  expect(result).toMatchSnapshot();
24
24
  });
25
25
 
26
+ it('should work correct with gpt-4', () => {
27
+ const s = merge(initialSettingsState, {
28
+ serverConfig: {
29
+ customModelName:
30
+ '-all,+gpt-3.5-turbo-1106,+gpt-3.5-turbo,+gpt-3.5-turbo-16k,+gpt-4,+gpt-4-32k,+gpt-4-1106-preview,+gpt-4-vision-preview',
31
+ },
32
+ }) as unknown as GlobalStore;
33
+
34
+ const result = modelProviderSelectors.modelSelectList(s).filter((r) => r.enabled);
35
+
36
+ expect(result[0].chatModels).toEqual([
37
+ {
38
+ displayName: 'GPT-3.5 Turbo (1106)',
39
+ functionCall: true,
40
+ id: 'gpt-3.5-turbo-1106',
41
+ tokens: 16385,
42
+ },
43
+ {
44
+ description: 'GPT 3.5 Turbo,适用于各种文本生成和理解任务',
45
+ displayName: 'GPT-3.5 Turbo',
46
+ functionCall: true,
47
+ id: 'gpt-3.5-turbo',
48
+ tokens: 4096,
49
+ },
50
+ {
51
+ displayName: 'GPT-3.5 Turbo 16K',
52
+ id: 'gpt-3.5-turbo-16k',
53
+ tokens: 16385,
54
+ },
55
+ {
56
+ displayName: 'GPT-4',
57
+ functionCall: true,
58
+ id: 'gpt-4',
59
+ tokens: 8192,
60
+ },
61
+ {
62
+ displayName: 'gpt-4-32k',
63
+ functionCall: true,
64
+ id: 'gpt-4-32k',
65
+ tokens: 32768,
66
+ },
67
+ {
68
+ displayName: 'GPT-4 Turbo Preview (1106)',
69
+ functionCall: true,
70
+ id: 'gpt-4-1106-preview',
71
+ tokens: 128000,
72
+ },
73
+ {
74
+ description: 'GPT-4 视觉预览版,支持视觉任务',
75
+ displayName: 'GPT-4 Turbo Vision (Preview)',
76
+ id: 'gpt-4-vision-preview',
77
+ tokens: 128000,
78
+ vision: true,
79
+ },
80
+ ]);
81
+ });
26
82
  it('duplicate naming model', () => {
27
83
  const s = merge(initialSettingsState, {
28
84
  serverConfig: {},
@@ -67,6 +123,7 @@ describe('modelProviderSelectors', () => {
67
123
  const result = modelProviderSelectors.modelSelectList(s).filter((r) => r.enabled);
68
124
 
69
125
  expect(result[0].chatModels.find((o) => o.id === 'gpt-4-1106-preview')).toEqual({
126
+ displayName: 'GPT-4 Turbo Preview (1106)',
70
127
  functionCall: true,
71
128
  id: 'gpt-4-1106-preview',
72
129
  tokens: 128000,
@@ -52,29 +52,31 @@ const processChatModels = (modelConfig: ReturnType<typeof parseModelString>): Ch
52
52
 
53
53
  return produce(chatModels, (draft) => {
54
54
  // 处理添加或替换逻辑
55
- for (const customModel of modelConfig.add) {
56
- // 首先尝试在 LOBE_DEFAULT_MODEL_LIST 中查找模型
57
- const defaultModel = LOBE_DEFAULT_MODEL_LIST.find((model) => model.id === customModel.id);
58
-
59
- // 如果在默认列表中找到了模型,则基于该模型进行更新
60
- if (defaultModel) {
61
- const model = draft.find((model) => model.id === customModel.id);
62
- // 如果当前 chatModels 中已有该模型,更新它
63
- if (model) {
64
- if (model.hidden) delete model.hidden;
65
- if (customModel.displayName) model.displayName = customModel.displayName;
55
+ for (const toAddModel of modelConfig.add) {
56
+ // first try to find the model in LOBE_DEFAULT_MODEL_LIST to confirm if it is a known model
57
+ const knownModel = LOBE_DEFAULT_MODEL_LIST.find((model) => model.id === toAddModel.id);
58
+
59
+ // if the model is known, update it based on the known model
60
+ if (knownModel) {
61
+ const modelInList = draft.find((model) => model.id === toAddModel.id);
62
+
63
+ // if the model is already in chatModels, update it
64
+ if (modelInList) {
65
+ if (modelInList.hidden) delete modelInList.hidden;
66
+ if (toAddModel.displayName) modelInList.displayName = toAddModel.displayName;
66
67
  } else {
67
- // 如果当前 chatModels 中没有该模型,添加它
68
+ // if the model is not in chatModels, add it
68
69
  draft.push({
69
- ...defaultModel,
70
- displayName: customModel.displayName || defaultModel.displayName,
70
+ ...knownModel,
71
+ displayName: toAddModel.displayName || knownModel.displayName || knownModel.id,
72
+ hidden: undefined,
71
73
  });
72
74
  }
73
75
  } else {
74
- // 如果在默认列表中未找到模型,作为新的自定义模型添加
76
+ // if the model is not in LOBE_DEFAULT_MODEL_LIST, add it as a new custom model
75
77
  draft.push({
76
- ...customModel,
77
- displayName: customModel.displayName || customModel.id,
78
+ ...toAddModel,
79
+ displayName: toAddModel.displayName || toAddModel.id,
78
80
  functionCall: true,
79
81
  isCustom: true,
80
82
  vision: true,
@@ -0,0 +1,26 @@
1
+ import { describe, expect, it } from 'vitest';
2
+
3
+ import { NON_HTTP_PREFIX } from '@/const/auth';
4
+
5
+ import { createJWT } from './jwt';
6
+
7
+ describe('createJWT', () => {
8
+ it('should create a JWT token', async () => {
9
+ const payload = { test: 'test' };
10
+ const token = await createJWT(payload);
11
+ expect(token).toBeTruthy();
12
+ });
13
+ it('should return a token with NON_HTTP_PREFIX when crypto.subtle does not exist', async () => {
14
+ const originalCryptoSubtle = crypto.subtle;
15
+ // @ts-ignore
16
+ crypto['subtle'] = undefined;
17
+
18
+ const payload = { test: 'test' };
19
+ const token = await createJWT(payload);
20
+
21
+ expect(token.startsWith(NON_HTTP_PREFIX)).toBeTruthy();
22
+
23
+ // @ts-ignore
24
+ crypto['subtle'] = originalCryptoSubtle;
25
+ });
26
+ });
@@ -0,0 +1,37 @@
1
+ import { SignJWT, importJWK } from 'jose';
2
+
3
+ import { JWT_SECRET_KEY, NON_HTTP_PREFIX } from '@/const/auth';
4
+
5
+ export const createJWT = async <T>(payload: T) => {
6
+ const now = Math.floor(Date.now() / 1000);
7
+ const duration = 100; // 100s
8
+
9
+ const encoder = new TextEncoder();
10
+
11
+ // fix the issue that crypto.subtle is not available in non-HTTPS environment
12
+ // refs: https://github.com/lobehub/lobe-chat/pull/1238
13
+ if (!crypto.subtle) {
14
+ const buffer = encoder.encode(JSON.stringify(payload));
15
+
16
+ return `${NON_HTTP_PREFIX}.${Buffer.from(buffer).toString('base64')}`;
17
+ }
18
+
19
+ // create a secret key
20
+ const secretKey = await crypto.subtle.digest('SHA-256', encoder.encode(JWT_SECRET_KEY));
21
+
22
+ // get the JWK from the secret key
23
+ const jwkSecretKey = await importJWK(
24
+ {
25
+ k: Buffer.from(secretKey).toString('base64'),
26
+ kty: 'oct',
27
+ },
28
+ 'HS256',
29
+ );
30
+
31
+ // 创建JWT
32
+ return new SignJWT(payload as Record<string, any>)
33
+ .setProtectedHeader({ alg: 'HS256' })
34
+ .setIssuedAt(now) // 设置JWT的iat(签发时间)声明
35
+ .setExpirationTime(now + duration) // 设置 JWT 的 exp(过期时间)为 100 s
36
+ .sign(jwkSecretKey);
37
+ };