@lobehub/chat 0.115.1 → 0.115.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 +1 -1
- package/CHANGELOG.md +50 -0
- package/Dockerfile +1 -1
- package/README.md +6 -6
- package/README.zh-CN.md +6 -6
- package/docs/Deployment/Environment-Variable.md +2 -2
- package/docs/Deployment/Environment-Variable.zh-CN.md +2 -2
- package/next.config.mjs +0 -4
- package/package.json +1 -1
- package/src/app/api/config/route.ts +15 -0
- package/src/app/api/market/AgentMarket.ts +25 -0
- package/src/app/api/market/[id]/route.ts +6 -3
- package/src/app/api/market/route.ts +6 -3
- package/src/app/chat/features/SessionListContent/DefaultMode.tsx +2 -1
- package/src/app/chat/features/SessionListContent/List/Item/index.tsx +2 -1
- package/src/app/settings/agent/Agent.tsx +2 -1
- package/src/app/settings/common/Common.tsx +2 -1
- package/src/app/settings/llm/LLM/index.tsx +2 -1
- package/src/app/settings/tts/TTS/index.tsx +2 -1
- package/src/components/FileList/EditableFileList.tsx +1 -1
- package/src/components/FileList/index.tsx +3 -45
- package/src/components/FileList/style.ts +0 -23
- package/src/config/__tests__/client.test.ts +0 -23
- package/src/config/__tests__/server.test.ts +26 -1
- package/src/config/client.ts +4 -15
- package/src/config/server.ts +14 -1
- package/src/const/settings.ts +0 -3
- package/src/const/url.ts +1 -18
- package/src/features/AgentSetting/AgentConfig/index.tsx +2 -1
- package/src/features/AgentSetting/AgentMeta/index.tsx +2 -1
- package/src/features/AgentSetting/AgentTTS/index.tsx +3 -2
- package/src/features/ChatInput/ActionBar/ModelSwitch.tsx +2 -1
- package/src/features/Conversation/ChatList/Error/ApiKeyForm.tsx +2 -1
- package/src/features/Conversation/ChatList/Extras/TTS/index.tsx +3 -2
- package/src/features/Conversation/index.tsx +2 -1
- package/src/features/PluginDevModal/LocalForm.tsx +3 -2
- package/src/hooks/useSTT.ts +2 -1
- package/src/hooks/useTTS.ts +2 -1
- package/src/layout/GlobalLayout/StoreHydration.tsx +5 -0
- package/src/services/__tests__/chat.test.ts +1 -1
- package/src/services/__tests__/global.test.ts +49 -32
- package/src/services/_header.ts +2 -2
- package/src/services/_url.ts +1 -0
- package/src/services/config.ts +2 -1
- package/src/services/global.ts +9 -0
- package/src/services/market.ts +21 -0
- package/src/store/chat/initialState.ts +9 -47
- package/src/store/chat/selectors.ts +3 -0
- package/src/store/chat/{actions/enhance.test.ts → slices/enchance/action.test.ts} +2 -2
- package/src/store/chat/{actions/message.test.ts → slices/message/action.test.ts} +1 -1
- package/src/store/chat/{actions/message.ts → slices/message/action.ts} +2 -2
- package/src/store/chat/slices/message/initialState.ts +29 -0
- package/src/store/chat/{reducers/message.test.ts → slices/message/reducer.test.ts} +2 -2
- package/src/store/chat/{selectors/__tests__/chat.test.ts → slices/message/selectors.test.ts} +1 -1
- package/src/store/chat/{selectors/chat.ts → slices/message/selectors.ts} +2 -2
- package/src/store/chat/{actions/share.ts → slices/share/action.ts} +2 -2
- package/src/store/chat/slices/share/initialState.ts +7 -0
- package/src/store/chat/{actions/plugin.ts → slices/tool/action.ts} +1 -3
- package/src/store/chat/slices/tool/initialState.ts +7 -0
- package/src/store/chat/{actions/topic.test.ts → slices/topic/action.test.ts} +1 -1
- package/src/store/chat/{actions/topic.ts → slices/topic/action.ts} +2 -1
- package/src/store/chat/slices/topic/initialState.ts +23 -0
- package/src/store/chat/{selectors/__tests__/topic.test.ts → slices/topic/selectors.test.ts} +1 -1
- package/src/store/chat/{selectors/topic.ts → slices/topic/selectors.ts} +1 -1
- package/src/store/chat/store.ts +5 -5
- package/src/store/global/helpers.ts +1 -1
- package/src/store/global/index.ts +0 -1
- package/src/store/global/initialState.ts +6 -59
- package/src/store/global/selectors.ts +2 -2
- package/src/store/global/slices/{common.ts → common/action.ts} +12 -3
- package/src/store/global/slices/common/initialState.ts +55 -0
- package/src/store/global/{selectors/preference.ts → slices/common/selectors.ts} +1 -1
- package/src/store/global/{selectors/__snapshots__/settings.test.ts.snap → slices/settings/__snapshots__/selectors.test.ts.snap} +0 -1
- package/src/store/global/slices/{settings.ts → settings/action.ts} +12 -4
- package/src/store/global/slices/settings/initialState.ts +15 -0
- package/src/store/global/{selectors/settings.test.ts → slices/settings/selectors.test.ts} +9 -6
- package/src/store/global/{selectors/settings.ts → slices/settings/selectors.ts} +4 -4
- package/src/store/global/store.ts +4 -18
- package/src/store/market/action.ts +14 -10
- package/src/store/session/slices/agent/selectors.ts +2 -1
- package/src/store/session/slices/session/action.ts +2 -1
- package/src/tools/dalle/Render/ToolBar.tsx +2 -1
- package/src/types/settings.ts +4 -29
- package/src/components/FileList/FileGrid.tsx +0 -36
- package/src/services/agentMarket.ts +0 -21
- package/src/store/chat/selectors/index.ts +0 -3
- package/src/store/global/slices/agent.ts +0 -34
- /package/src/store/chat/{actions/enhance.ts → slices/enchance/action.ts} +0 -0
- /package/src/store/chat/{selectors/enchance.ts → slices/enchance/selectors.ts} +0 -0
- /package/src/store/chat/{reducers/message.ts → slices/message/reducer.ts} +0 -0
- /package/src/store/chat/{actions/plugin.test.ts → slices/tool/action.test.ts} +0 -0
package/.env.example
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
ACCESS_CODE=lobe66
|
|
3
3
|
|
|
4
4
|
# add your custom model name, multi model separate by comma. for example gpt-3.5-1106,gpt-4-1106
|
|
5
|
-
#
|
|
5
|
+
# CUSTOM_MODELS=model1,model2,model3
|
|
6
6
|
|
|
7
7
|
# ---- only choose one from OpenAI Service and Azure OpenAI Service ---- #
|
|
8
8
|
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,56 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
### [Version 0.115.3](https://github.com/lobehub/lobe-chat/compare/v0.115.2...v0.115.3)
|
|
6
|
+
|
|
7
|
+
<sup>Released on **2023-12-23**</sup>
|
|
8
|
+
|
|
9
|
+
#### ♻ Code Refactoring
|
|
10
|
+
|
|
11
|
+
- **misc**: Refactor and clean global store and chat store.
|
|
12
|
+
|
|
13
|
+
<br/>
|
|
14
|
+
|
|
15
|
+
<details>
|
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
17
|
+
|
|
18
|
+
#### Code refactoring
|
|
19
|
+
|
|
20
|
+
- **misc**: Refactor and clean global store and chat store, closes [#774](https://github.com/lobehub/lobe-chat/issues/774) ([6120042](https://github.com/lobehub/lobe-chat/commit/6120042))
|
|
21
|
+
|
|
22
|
+
</details>
|
|
23
|
+
|
|
24
|
+
<div align="right">
|
|
25
|
+
|
|
26
|
+
[](#readme-top)
|
|
27
|
+
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
### [Version 0.115.2](https://github.com/lobehub/lobe-chat/compare/v0.115.1...v0.115.2)
|
|
31
|
+
|
|
32
|
+
<sup>Released on **2023-12-23**</sup>
|
|
33
|
+
|
|
34
|
+
#### 🐛 Bug Fixes
|
|
35
|
+
|
|
36
|
+
- **misc**: Fix envs like `CUSTOM_MODELS` don't work with docker deployment.
|
|
37
|
+
|
|
38
|
+
<br/>
|
|
39
|
+
|
|
40
|
+
<details>
|
|
41
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
42
|
+
|
|
43
|
+
#### What's fixed
|
|
44
|
+
|
|
45
|
+
- **misc**: Fix envs like `CUSTOM_MODELS` don't work with docker deployment, closes [#773](https://github.com/lobehub/lobe-chat/issues/773) ([54dc18b](https://github.com/lobehub/lobe-chat/commit/54dc18b))
|
|
46
|
+
|
|
47
|
+
</details>
|
|
48
|
+
|
|
49
|
+
<div align="right">
|
|
50
|
+
|
|
51
|
+
[](#readme-top)
|
|
52
|
+
|
|
53
|
+
</div>
|
|
54
|
+
|
|
5
55
|
### [Version 0.115.1](https://github.com/lobehub/lobe-chat/compare/v0.115.0...v0.115.1)
|
|
6
56
|
|
|
7
57
|
<sup>Released on **2023-12-22**</sup>
|
package/Dockerfile
CHANGED
package/README.md
CHANGED
|
@@ -391,12 +391,12 @@ $ docker run -d -p 3210:3210 \
|
|
|
391
391
|
|
|
392
392
|
This project provides some additional configuration items set with environment variables:
|
|
393
393
|
|
|
394
|
-
| Environment Variable
|
|
395
|
-
|
|
|
396
|
-
| `OPENAI_API_KEY`
|
|
397
|
-
| `OPENAI_PROXY_URL`
|
|
398
|
-
| `
|
|
399
|
-
| `
|
|
394
|
+
| Environment Variable | Required | Description | Example |
|
|
395
|
+
| -------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
|
|
396
|
+
| `OPENAI_API_KEY` | Yes | This is the API key you apply on the OpenAI account page | `sk-xxxxxx...xxxxxx` |
|
|
397
|
+
| `OPENAI_PROXY_URL` | No | If you manually configure the OpenAI interface proxy, you can use this configuration item to override the default OpenAI API request base URL | `https://api.chatanywhere.cn/v1`<br/>The default value is<br/>`https://api.openai.com/v1` |
|
|
398
|
+
| `ACCESS_CODE` | No | Add a password to access this service; you can set a long password to avoid leaking. If this value contains a comma, it is a password array. | `awCTe)re_r74` or `rtrt_ewee3@09!` or `code1,code2,code3` |
|
|
399
|
+
| `CUSTOM_MODELS` | No | 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. | `qwen-7b-chat,+glm-6b,-gpt-3.5-turbo` |
|
|
400
400
|
|
|
401
401
|
> \[!NOTE]
|
|
402
402
|
>
|
package/README.zh-CN.md
CHANGED
|
@@ -363,12 +363,12 @@ $ docker run -d -p 3210:3210 \
|
|
|
363
363
|
|
|
364
364
|
本项目提供了一些额外的配置项,使用环境变量进行设置:
|
|
365
365
|
|
|
366
|
-
| 环境变量
|
|
367
|
-
|
|
|
368
|
-
| `OPENAI_API_KEY`
|
|
369
|
-
| `OPENAI_PROXY_URL`
|
|
370
|
-
| `
|
|
371
|
-
| `
|
|
366
|
+
| 环境变量 | 类型 | 描述 | 示例 |
|
|
367
|
+
| ------------------ | ---- | ----------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
|
|
368
|
+
| `OPENAI_API_KEY` | 必选 | 这是你在 OpenAI 账户页面申请的 API 密钥 | `sk-xxxxxx...xxxxxx` |
|
|
369
|
+
| `OPENAI_PROXY_URL` | 可选 | 如果你手动配置了 OpenAI 接口代理,可以使用此配置项来覆盖默认的 OpenAI API 请求基础 URL | `https://api.chatanywhere.cn/v1`<br/>默认值:<br/>`https://api.openai.com/v1` |
|
|
370
|
+
| `ACCESS_CODE` | 可选 | 添加访问此服务的密码,你可以设置一个长密码以防被爆破,该值用逗号分隔时为密码数组 | `awCTe)re_r74` or `rtrt_ewee3@09!` or `code1,code2,code3` |
|
|
371
|
+
| `CUSTOM_MODELS` | 可选 | 用来控制模型列表,使用 `+` 增加一个模型,使用 `-` 来隐藏一个模型,使用 `模型名=展示名` 来自定义模型的展示名,用英文逗号隔开。 | `qwen-7b-chat,+glm-6b,-gpt-3.5-turbo` |
|
|
372
372
|
|
|
373
373
|
> \[!NOTE]
|
|
374
374
|
>
|
|
@@ -6,7 +6,7 @@ LobeChat provides additional configuration options during deployment, which can
|
|
|
6
6
|
|
|
7
7
|
- [General Variables](#general-variables)
|
|
8
8
|
- [`ACCESS_CODE`](#access_code)
|
|
9
|
-
- [`
|
|
9
|
+
- [`CUSTOM_MODELS`](#custom_models)
|
|
10
10
|
- [OpenAI](#openai)
|
|
11
11
|
- [`OPENAI_API_KEY`](#openai_api_key)
|
|
12
12
|
- [`OPENAI_PROXY_URL`](#openai_proxy_url)
|
|
@@ -31,7 +31,7 @@ LobeChat provides additional configuration options during deployment, which can
|
|
|
31
31
|
- Default: `-`
|
|
32
32
|
- Example: `awCTe)re_r74` or `rtrt_ewee3@09!` or `code1,code2,code3`
|
|
33
33
|
|
|
34
|
-
### `
|
|
34
|
+
### `CUSTOM_MODELS`
|
|
35
35
|
|
|
36
36
|
- Type: Optional
|
|
37
37
|
- 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.
|
|
@@ -6,7 +6,7 @@ LobeChat 在部署时提供了一些额外的配置项,使用环境变量进
|
|
|
6
6
|
|
|
7
7
|
- [通用变量](#通用变量)
|
|
8
8
|
- [`ACCESS_CODE`](#access_code)
|
|
9
|
-
- [`
|
|
9
|
+
- [`CUSTOM_MODELS`](#custom_models)
|
|
10
10
|
- [OpenAI](#openai)
|
|
11
11
|
- [`OPENAI_API_KEY`](#openai_api_key)
|
|
12
12
|
- [`OPENAI_PROXY_URL`](#openai_proxy_url)
|
|
@@ -31,7 +31,7 @@ LobeChat 在部署时提供了一些额外的配置项,使用环境变量进
|
|
|
31
31
|
- 默认值:-
|
|
32
32
|
- 示例:`awCTe)re_r74` or `rtrt_ewee3@09!`
|
|
33
33
|
|
|
34
|
-
### `
|
|
34
|
+
### `CUSTOM_MODELS`
|
|
35
35
|
|
|
36
36
|
- 类型:可选
|
|
37
37
|
- 描述:用来控制模型列表,使用 `+` 增加一个模型,使用 `-` 来隐藏一个模型,使用 `模型名=展示名` 来自定义模型的展示名,用英文逗号隔开。
|
package/next.config.mjs
CHANGED
|
@@ -19,10 +19,6 @@ const withPWA = nextPWA({
|
|
|
19
19
|
/** @type {import('next').NextConfig} */
|
|
20
20
|
const nextConfig = {
|
|
21
21
|
compress: isProd,
|
|
22
|
-
env: {
|
|
23
|
-
AGENTS_INDEX_URL: process.env.AGENTS_INDEX_URL ?? '',
|
|
24
|
-
PLUGINS_INDEX_URL: process.env.PLUGINS_INDEX_URL ?? '',
|
|
25
|
-
},
|
|
26
22
|
experimental: {
|
|
27
23
|
forceSwcTransforms: true,
|
|
28
24
|
optimizePackageImports: [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobehub/chat",
|
|
3
|
-
"version": "0.115.
|
|
3
|
+
"version": "0.115.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",
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { getServerConfig } from '@/config/server';
|
|
2
|
+
import { GlobalServerConfig } from '@/types/settings';
|
|
3
|
+
|
|
4
|
+
export const runtime = 'edge';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* get Server config to client
|
|
8
|
+
*/
|
|
9
|
+
export const GET = async () => {
|
|
10
|
+
const { CUSTOM_MODELS } = getServerConfig();
|
|
11
|
+
|
|
12
|
+
const config: GlobalServerConfig = { customModelName: CUSTOM_MODELS };
|
|
13
|
+
|
|
14
|
+
return new Response(JSON.stringify(config));
|
|
15
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import urlJoin from 'url-join';
|
|
2
|
+
|
|
3
|
+
import { getServerConfig } from '@/config/server';
|
|
4
|
+
import { DEFAULT_LANG, checkLang } from '@/const/locale';
|
|
5
|
+
import { Locales } from '@/locales/resources';
|
|
6
|
+
|
|
7
|
+
export class AgentMarket {
|
|
8
|
+
private readonly baseUrl: string;
|
|
9
|
+
|
|
10
|
+
constructor(baseUrl?: string) {
|
|
11
|
+
this.baseUrl = baseUrl || getServerConfig().AGENTS_INDEX_URL;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
getAgentIndexUrl = (lang: Locales = DEFAULT_LANG) => {
|
|
15
|
+
if (checkLang(lang)) return this.baseUrl;
|
|
16
|
+
|
|
17
|
+
return urlJoin(this.baseUrl, `index.${lang}.json`);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
getAgentUrl = (identifier: string, lang: Locales = DEFAULT_LANG) => {
|
|
21
|
+
if (checkLang(lang)) return urlJoin(this.baseUrl, `${identifier}.json`);
|
|
22
|
+
|
|
23
|
+
return urlJoin(this.baseUrl, `${identifier}.${lang}.json`);
|
|
24
|
+
};
|
|
25
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { DEFAULT_LANG } from '@/const/locale';
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
import { AgentMarket } from '../AgentMarket';
|
|
3
4
|
|
|
4
5
|
export const runtime = 'edge';
|
|
5
6
|
|
|
@@ -8,11 +9,13 @@ export const GET = async (req: Request, { params }: { params: { id: string } })
|
|
|
8
9
|
|
|
9
10
|
const locale = searchParams.get('locale');
|
|
10
11
|
|
|
12
|
+
const market = new AgentMarket();
|
|
13
|
+
|
|
11
14
|
let res: Response;
|
|
12
15
|
|
|
13
|
-
res = await fetch(
|
|
16
|
+
res = await fetch(market.getAgentUrl(params.id, locale as any));
|
|
14
17
|
if (res.status === 404) {
|
|
15
|
-
res = await fetch(
|
|
18
|
+
res = await fetch(market.getAgentUrl(params.id, DEFAULT_LANG));
|
|
16
19
|
}
|
|
17
20
|
|
|
18
21
|
return res;
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import { DEFAULT_LANG } from '@/const/locale';
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
import { AgentMarket } from './AgentMarket';
|
|
3
4
|
|
|
4
5
|
export const runtime = 'edge';
|
|
5
6
|
|
|
6
7
|
export const GET = async (req: Request) => {
|
|
7
8
|
const locale = new URL(req.url).searchParams.get('locale');
|
|
8
9
|
|
|
10
|
+
const market = new AgentMarket();
|
|
11
|
+
|
|
9
12
|
let res: Response;
|
|
10
13
|
|
|
11
|
-
res = await fetch(
|
|
14
|
+
res = await fetch(market.getAgentIndexUrl(locale as any));
|
|
12
15
|
|
|
13
16
|
if (res.status === 404) {
|
|
14
|
-
res = await fetch(
|
|
17
|
+
res = await fetch(market.getAgentIndexUrl(DEFAULT_LANG));
|
|
15
18
|
}
|
|
16
19
|
|
|
17
20
|
return res;
|
|
@@ -3,7 +3,8 @@ import isEqual from 'fast-deep-equal';
|
|
|
3
3
|
import { memo } from 'react';
|
|
4
4
|
import { useTranslation } from 'react-i18next';
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import { useGlobalStore } from '@/store/global';
|
|
7
|
+
import { preferenceSelectors } from '@/store/global/selectors';
|
|
7
8
|
import { useSessionStore } from '@/store/session';
|
|
8
9
|
import { sessionSelectors } from '@/store/session/selectors';
|
|
9
10
|
|
|
@@ -5,7 +5,8 @@ import { Flexbox } from 'react-layout-kit';
|
|
|
5
5
|
import { shallow } from 'zustand/shallow';
|
|
6
6
|
|
|
7
7
|
import { useChatStore } from '@/store/chat';
|
|
8
|
-
import {
|
|
8
|
+
import { useGlobalStore } from '@/store/global';
|
|
9
|
+
import { settingsSelectors } from '@/store/global/selectors';
|
|
9
10
|
import { useSessionStore } from '@/store/session';
|
|
10
11
|
import { sessionHelpers } from '@/store/session/helpers';
|
|
11
12
|
import { agentSelectors, sessionSelectors } from '@/store/session/selectors';
|
|
@@ -2,9 +2,10 @@ import isEqual from 'fast-deep-equal';
|
|
|
2
2
|
import { memo } from 'react';
|
|
3
3
|
|
|
4
4
|
import AgentSetting from '@/features/AgentSetting';
|
|
5
|
-
import {
|
|
5
|
+
import { useGlobalStore } from '@/store/global';
|
|
6
6
|
import { useSwitchSideBarOnInit } from '@/store/global/hooks/useSwitchSettingsOnInit';
|
|
7
7
|
import { SettingsTabs } from '@/store/global/initialState';
|
|
8
|
+
import { settingsSelectors } from '@/store/global/selectors';
|
|
8
9
|
|
|
9
10
|
const Agent = memo(() => {
|
|
10
11
|
useSwitchSideBarOnInit(SettingsTabs.Agent);
|
|
@@ -12,7 +12,8 @@ import AvatarWithUpload from '@/features/AvatarWithUpload';
|
|
|
12
12
|
import { localeOptions } from '@/locales/options';
|
|
13
13
|
import { useChatStore } from '@/store/chat';
|
|
14
14
|
import { useFileStore } from '@/store/file';
|
|
15
|
-
import {
|
|
15
|
+
import { useGlobalStore } from '@/store/global';
|
|
16
|
+
import { settingsSelectors } from '@/store/global/selectors';
|
|
16
17
|
import { useSessionStore } from '@/store/session';
|
|
17
18
|
import { useToolStore } from '@/store/tool';
|
|
18
19
|
import { switchLang } from '@/utils/switchLang';
|
|
@@ -7,7 +7,8 @@ import { memo } from 'react';
|
|
|
7
7
|
import { useTranslation } from 'react-i18next';
|
|
8
8
|
|
|
9
9
|
import { FORM_STYLE } from '@/const/layoutTokens';
|
|
10
|
-
import {
|
|
10
|
+
import { useEffectAfterGlobalHydrated, useGlobalStore } from '@/store/global';
|
|
11
|
+
import { settingsSelectors } from '@/store/global/selectors';
|
|
11
12
|
|
|
12
13
|
import Checker from './Checker';
|
|
13
14
|
|
|
@@ -7,7 +7,8 @@ import { memo } from 'react';
|
|
|
7
7
|
import { useTranslation } from 'react-i18next';
|
|
8
8
|
|
|
9
9
|
import { FORM_STYLE } from '@/const/layoutTokens';
|
|
10
|
-
import {
|
|
10
|
+
import { useGlobalStore } from '@/store/global';
|
|
11
|
+
import { settingsSelectors } from '@/store/global/selectors';
|
|
11
12
|
|
|
12
13
|
import { opeanaiSTTOptions, opeanaiTTSOptions, sttOptions } from './options';
|
|
13
14
|
|
|
@@ -3,7 +3,7 @@ import { useResponsive } from 'antd-style';
|
|
|
3
3
|
import { memo } from 'react';
|
|
4
4
|
import { Flexbox } from 'react-layout-kit';
|
|
5
5
|
|
|
6
|
-
import ImageFileItem from '
|
|
6
|
+
import ImageFileItem from './ImageFileItem';
|
|
7
7
|
|
|
8
8
|
interface EditableFileListProps {
|
|
9
9
|
alwaysShowClose?: boolean;
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import { ImageGallery } from '@lobehub/ui';
|
|
2
|
-
import {
|
|
3
|
-
import { memo, useMemo } from 'react';
|
|
4
|
-
import { Flexbox } from 'react-layout-kit';
|
|
2
|
+
import { memo } from 'react';
|
|
5
3
|
|
|
6
|
-
import
|
|
4
|
+
import GalleyGrid from '@/components/GalleyGrid';
|
|
7
5
|
|
|
8
|
-
import FileGrid from './FileGrid';
|
|
9
6
|
import ImageFileItem from './ImageFileItem';
|
|
10
7
|
|
|
11
8
|
interface FileListProps {
|
|
@@ -13,48 +10,9 @@ interface FileListProps {
|
|
|
13
10
|
}
|
|
14
11
|
|
|
15
12
|
const FileList = memo<FileListProps>(({ items }) => {
|
|
16
|
-
const { mobile } = useResponsive();
|
|
17
|
-
|
|
18
|
-
const { firstRow, lastRow } = useMemo(() => {
|
|
19
|
-
if (items.length === 4) {
|
|
20
|
-
return {
|
|
21
|
-
firstRow: items.slice(0, 2),
|
|
22
|
-
lastRow: items.slice(2, 4),
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const firstCol = items.length % 3 === 0 ? 3 : items.length % 3;
|
|
27
|
-
|
|
28
|
-
return {
|
|
29
|
-
firstRow: items.slice(0, firstCol),
|
|
30
|
-
lastRow: items.slice(firstCol, items.length),
|
|
31
|
-
};
|
|
32
|
-
}, [items]);
|
|
33
|
-
|
|
34
|
-
const { gap, max } = useMemo(
|
|
35
|
-
() => ({
|
|
36
|
-
gap: mobile ? 4 : 6,
|
|
37
|
-
max: mobile ? MAX_SIZE_MOBILE : MAX_SIZE_DESKTOP,
|
|
38
|
-
}),
|
|
39
|
-
[mobile],
|
|
40
|
-
);
|
|
41
|
-
|
|
42
13
|
return (
|
|
43
14
|
<ImageGallery>
|
|
44
|
-
<
|
|
45
|
-
<FileGrid col={firstRow.length} gap={gap} max={max}>
|
|
46
|
-
{firstRow.map((i) => (
|
|
47
|
-
<ImageFileItem id={i} key={i} />
|
|
48
|
-
))}
|
|
49
|
-
</FileGrid>
|
|
50
|
-
{lastRow.length > 0 && (
|
|
51
|
-
<FileGrid col={lastRow.length > 2 ? 3 : lastRow.length} gap={gap} max={max}>
|
|
52
|
-
{lastRow.map((i) => (
|
|
53
|
-
<ImageFileItem id={i} key={i} />
|
|
54
|
-
))}
|
|
55
|
-
</FileGrid>
|
|
56
|
-
)}
|
|
57
|
-
</Flexbox>
|
|
15
|
+
<GalleyGrid items={items} renderItem={ImageFileItem} />
|
|
58
16
|
</ImageGallery>
|
|
59
17
|
);
|
|
60
18
|
});
|
|
@@ -1,24 +1 @@
|
|
|
1
|
-
import { createStyles } from 'antd-style';
|
|
2
|
-
|
|
3
1
|
export const MIN_IMAGE_SIZE = 64;
|
|
4
|
-
export const MAX_SIZE_DESKTOP = 640;
|
|
5
|
-
export const MAX_SIZE_MOBILE = 280;
|
|
6
|
-
export const useStyles = createStyles(
|
|
7
|
-
({ css }, { col, gap, max, min }: { col: number; gap: number; max: number; min: number }) => ({
|
|
8
|
-
container: css`
|
|
9
|
-
display: grid;
|
|
10
|
-
grid-gap: ${gap}px;
|
|
11
|
-
grid-template-columns: repeat(${col}, 1fr);
|
|
12
|
-
|
|
13
|
-
width: 100%;
|
|
14
|
-
max-width: ${max}px;
|
|
15
|
-
|
|
16
|
-
& > div {
|
|
17
|
-
width: 100%;
|
|
18
|
-
min-width: ${min}px;
|
|
19
|
-
min-height: ${min}px;
|
|
20
|
-
max-height: ${(max - gap * (col - 1)) / col}px;
|
|
21
|
-
}
|
|
22
|
-
`,
|
|
23
|
-
}),
|
|
24
|
-
);
|
|
@@ -9,29 +9,6 @@ vi.stubGlobal('process', {
|
|
|
9
9
|
});
|
|
10
10
|
|
|
11
11
|
describe('getClientConfig', () => {
|
|
12
|
-
it('should return default URLs when no environment variables are set', () => {
|
|
13
|
-
const config = getClientConfig();
|
|
14
|
-
expect(config.AGENTS_INDEX_URL).toBe('https://chat-agents.lobehub.com');
|
|
15
|
-
expect(config.PLUGINS_INDEX_URL).toBe('https://chat-plugins.lobehub.com');
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
it('should return custom URLs when environment variables are set', () => {
|
|
19
|
-
process.env.AGENTS_INDEX_URL = 'https://custom-agents-url.com';
|
|
20
|
-
process.env.PLUGINS_INDEX_URL = 'https://custom-plugins-url.com';
|
|
21
|
-
const config = getClientConfig();
|
|
22
|
-
expect(config.AGENTS_INDEX_URL).toBe('https://custom-agents-url.com');
|
|
23
|
-
expect(config.PLUGINS_INDEX_URL).toBe('https://custom-plugins-url.com');
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
it('should return default URLs when environment variables are empty string', () => {
|
|
27
|
-
process.env.AGENTS_INDEX_URL = '';
|
|
28
|
-
process.env.PLUGINS_INDEX_URL = '';
|
|
29
|
-
|
|
30
|
-
const config = getClientConfig();
|
|
31
|
-
expect(config.AGENTS_INDEX_URL).toBe('https://chat-agents.lobehub.com');
|
|
32
|
-
expect(config.PLUGINS_INDEX_URL).toBe('https://chat-plugins.lobehub.com');
|
|
33
|
-
});
|
|
34
|
-
|
|
35
12
|
it('should correctly reflect boolean values for analytics flags', () => {
|
|
36
13
|
process.env.NEXT_PUBLIC_ANALYTICS_VERCEL = '1';
|
|
37
14
|
process.env.NEXT_PUBLIC_VERCEL_DEBUG = '1';
|
|
@@ -21,7 +21,7 @@ describe('getServerConfig', () => {
|
|
|
21
21
|
global.process = undefined;
|
|
22
22
|
|
|
23
23
|
expect(() => getServerConfig()).toThrow(
|
|
24
|
-
'[Server Config] you are importing a
|
|
24
|
+
'[Server Config] you are importing a server-only module outside of server',
|
|
25
25
|
);
|
|
26
26
|
|
|
27
27
|
global.process = originalProcess; // Restore the original process object
|
|
@@ -55,4 +55,29 @@ describe('getServerConfig', () => {
|
|
|
55
55
|
const config = getServerConfig();
|
|
56
56
|
expect(config.IMGUR_CLIENT_ID).toBe('custom-client-id');
|
|
57
57
|
});
|
|
58
|
+
|
|
59
|
+
describe('index url', () => {
|
|
60
|
+
it('should return default URLs when no environment variables are set', () => {
|
|
61
|
+
const config = getServerConfig();
|
|
62
|
+
expect(config.AGENTS_INDEX_URL).toBe('https://chat-agents.lobehub.com');
|
|
63
|
+
expect(config.PLUGINS_INDEX_URL).toBe('https://chat-plugins.lobehub.com');
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('should return custom URLs when environment variables are set', () => {
|
|
67
|
+
process.env.AGENTS_INDEX_URL = 'https://custom-agents-url.com';
|
|
68
|
+
process.env.PLUGINS_INDEX_URL = 'https://custom-plugins-url.com';
|
|
69
|
+
const config = getServerConfig();
|
|
70
|
+
expect(config.AGENTS_INDEX_URL).toBe('https://custom-agents-url.com');
|
|
71
|
+
expect(config.PLUGINS_INDEX_URL).toBe('https://custom-plugins-url.com');
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('should return default URLs when environment variables are empty string', () => {
|
|
75
|
+
process.env.AGENTS_INDEX_URL = '';
|
|
76
|
+
process.env.PLUGINS_INDEX_URL = '';
|
|
77
|
+
|
|
78
|
+
const config = getServerConfig();
|
|
79
|
+
expect(config.AGENTS_INDEX_URL).toBe('https://chat-agents.lobehub.com');
|
|
80
|
+
expect(config.PLUGINS_INDEX_URL).toBe('https://chat-plugins.lobehub.com');
|
|
81
|
+
});
|
|
82
|
+
});
|
|
58
83
|
});
|
package/src/config/client.ts
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* the client config is only used in Vercel deployment
|
|
3
|
+
*/
|
|
4
|
+
|
|
1
5
|
/* eslint-disable sort-keys-fix/sort-keys-fix , typescript-sort-keys/interface */
|
|
2
6
|
|
|
3
7
|
declare global {
|
|
4
8
|
// eslint-disable-next-line @typescript-eslint/no-namespace
|
|
5
9
|
namespace NodeJS {
|
|
6
10
|
interface ProcessEnv {
|
|
7
|
-
AGENTS_INDEX_URL?: string;
|
|
8
|
-
PLUGINS_INDEX_URL?: string;
|
|
9
|
-
|
|
10
|
-
NEXT_PUBLIC_CUSTOM_MODELS?: string;
|
|
11
|
-
|
|
12
11
|
NEXT_PUBLIC_ANALYTICS_VERCEL?: string;
|
|
13
12
|
NEXT_PUBLIC_VERCEL_DEBUG?: string;
|
|
14
13
|
|
|
@@ -35,16 +34,6 @@ declare global {
|
|
|
35
34
|
}
|
|
36
35
|
|
|
37
36
|
export const getClientConfig = () => ({
|
|
38
|
-
AGENTS_INDEX_URL: !!process.env.AGENTS_INDEX_URL
|
|
39
|
-
? process.env.AGENTS_INDEX_URL
|
|
40
|
-
: 'https://chat-agents.lobehub.com',
|
|
41
|
-
PLUGINS_INDEX_URL: !!process.env.PLUGINS_INDEX_URL
|
|
42
|
-
? process.env.PLUGINS_INDEX_URL
|
|
43
|
-
: 'https://chat-plugins.lobehub.com',
|
|
44
|
-
|
|
45
|
-
// custom model names
|
|
46
|
-
CUSTOM_MODELS: process.env.NEXT_PUBLIC_CUSTOM_MODELS,
|
|
47
|
-
|
|
48
37
|
// Vercel Analytics
|
|
49
38
|
ANALYTICS_VERCEL: process.env.NEXT_PUBLIC_ANALYTICS_VERCEL === '1',
|
|
50
39
|
VERCEL_DEBUG: process.env.NEXT_PUBLIC_VERCEL_DEBUG === '1',
|
package/src/config/server.ts
CHANGED
|
@@ -5,6 +5,7 @@ declare global {
|
|
|
5
5
|
namespace NodeJS {
|
|
6
6
|
interface ProcessEnv {
|
|
7
7
|
ACCESS_CODE?: string;
|
|
8
|
+
CUSTOM_MODELS?: string;
|
|
8
9
|
|
|
9
10
|
OPENAI_API_KEY?: string;
|
|
10
11
|
OPENAI_PROXY_URL?: string;
|
|
@@ -14,6 +15,9 @@ declare global {
|
|
|
14
15
|
USE_AZURE_OPENAI?: string;
|
|
15
16
|
|
|
16
17
|
IMGUR_CLIENT_ID?: string;
|
|
18
|
+
|
|
19
|
+
AGENTS_INDEX_URL?: string;
|
|
20
|
+
PLUGINS_INDEX_URL?: string;
|
|
17
21
|
}
|
|
18
22
|
}
|
|
19
23
|
}
|
|
@@ -24,7 +28,7 @@ const DEFAULT_IMAGUR_CLIENT_ID = 'e415f320d6e24f9';
|
|
|
24
28
|
|
|
25
29
|
export const getServerConfig = () => {
|
|
26
30
|
if (typeof process === 'undefined') {
|
|
27
|
-
throw new Error('[Server Config] you are importing a
|
|
31
|
+
throw new Error('[Server Config] you are importing a server-only module outside of server');
|
|
28
32
|
}
|
|
29
33
|
|
|
30
34
|
// region format: iad1,sfo1
|
|
@@ -37,6 +41,7 @@ export const getServerConfig = () => {
|
|
|
37
41
|
|
|
38
42
|
return {
|
|
39
43
|
ACCESS_CODES,
|
|
44
|
+
CUSTOM_MODELS: process.env.CUSTOM_MODELS,
|
|
40
45
|
|
|
41
46
|
SHOW_ACCESS_CODE_CONFIG: !!ACCESS_CODES.length,
|
|
42
47
|
|
|
@@ -49,5 +54,13 @@ export const getServerConfig = () => {
|
|
|
49
54
|
USE_AZURE_OPENAI: process.env.USE_AZURE_OPENAI === '1',
|
|
50
55
|
|
|
51
56
|
IMGUR_CLIENT_ID: process.env.IMGUR_CLIENT_ID || DEFAULT_IMAGUR_CLIENT_ID,
|
|
57
|
+
|
|
58
|
+
AGENTS_INDEX_URL: !!process.env.AGENTS_INDEX_URL
|
|
59
|
+
? process.env.AGENTS_INDEX_URL
|
|
60
|
+
: 'https://chat-agents.lobehub.com',
|
|
61
|
+
|
|
62
|
+
PLUGINS_INDEX_URL: !!process.env.PLUGINS_INDEX_URL
|
|
63
|
+
? process.env.PLUGINS_INDEX_URL
|
|
64
|
+
: 'https://chat-plugins.lobehub.com',
|
|
52
65
|
};
|
|
53
66
|
};
|
package/src/const/settings.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { getClientConfig } from '@/config/client';
|
|
2
1
|
import { DEFAULT_OPENAI_MODEL_LIST } from '@/const/llm';
|
|
3
2
|
import { DEFAULT_AGENT_META } from '@/const/meta';
|
|
4
3
|
import { LobeAgentConfig, LobeAgentTTSConfig } from '@/types/agent';
|
|
@@ -52,8 +51,6 @@ export const DEFAULT_AGENT_CONFIG: LobeAgentConfig = {
|
|
|
52
51
|
export const DEFAULT_LLM_CONFIG: GlobalLLMConfig = {
|
|
53
52
|
openAI: {
|
|
54
53
|
OPENAI_API_KEY: '',
|
|
55
|
-
// support user custom model names with env var
|
|
56
|
-
customModelName: getClientConfig().CUSTOM_MODELS,
|
|
57
54
|
models: DEFAULT_OPENAI_MODEL_LIST,
|
|
58
55
|
},
|
|
59
56
|
};
|