@lobehub/chat 0.110.4 → 0.110.6

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,56 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ### [Version 0.110.6](https://github.com/lobehub/lobe-chat/compare/v0.110.5...v0.110.6)
6
+
7
+ <sup>Released on **2023-12-11**</sup>
8
+
9
+ #### 🐛 Bug Fixes
10
+
11
+ - **misc**: Sharp missing in docker production.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### What's fixed
19
+
20
+ - **misc**: Sharp missing in docker production, closes [#603](https://github.com/lobehub/lobe-chat/issues/603) ([d89b48d](https://github.com/lobehub/lobe-chat/commit/d89b48d))
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
+
30
+ ### [Version 0.110.5](https://github.com/lobehub/lobe-chat/compare/v0.110.4...v0.110.5)
31
+
32
+ <sup>Released on **2023-12-10**</sup>
33
+
34
+ #### 🐛 Bug Fixes
35
+
36
+ - **misc**: Fix setting plugin i18n.
37
+
38
+ <br/>
39
+
40
+ <details>
41
+ <summary><kbd>Improvements and Fixes</kbd></summary>
42
+
43
+ #### What's fixed
44
+
45
+ - **misc**: Fix setting plugin i18n, closes [#606](https://github.com/lobehub/lobe-chat/issues/606) ([4e18ebf](https://github.com/lobehub/lobe-chat/commit/4e18ebf))
46
+
47
+ </details>
48
+
49
+ <div align="right">
50
+
51
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
52
+
53
+ </div>
54
+
5
55
  ### [Version 0.110.4](https://github.com/lobehub/lobe-chat/compare/v0.110.3...v0.110.4)
6
56
 
7
57
  <sup>Released on **2023-12-08**</sup>
package/Dockerfile CHANGED
@@ -1,5 +1,15 @@
1
1
  FROM node:20-slim AS base
2
2
 
3
+ ## Sharp dependencies, copy all the files for production
4
+ FROM base AS sharp
5
+ ENV PNPM_HOME="/pnpm"
6
+ ENV PATH="$PNPM_HOME:$PATH"
7
+ RUN corepack enable
8
+
9
+ WORKDIR /app
10
+
11
+ RUN pnpm add sharp
12
+
3
13
  ## Install dependencies only when needed
4
14
  FROM base AS builder
5
15
  ENV PNPM_HOME="/pnpm"
@@ -14,9 +24,6 @@ COPY package.json ./
14
24
  # RUN npm config set registry https://registry.npmmirror.com/
15
25
  RUN pnpm i
16
26
 
17
- # https://nextjs.org/docs/messages/sharp-missing-in-production
18
- ENV NEXT_SHARP_PATH /app/node_modules/sharp
19
-
20
27
  COPY . .
21
28
  RUN pnpm run build:docker # run build standalone for docker version
22
29
 
@@ -39,6 +46,7 @@ RUN chown nextjs:nodejs .next
39
46
  # https://nextjs.org/docs/advanced-features/output-file-tracing
40
47
  COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
41
48
  COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
49
+ COPY --from=sharp --chown=nextjs:nodejs /app/node_modules/.pnpm ./node_modules/.pnpm
42
50
 
43
51
  USER nextjs
44
52
 
@@ -42,6 +42,10 @@ $ docker run -d -p 3210:3210 \
42
42
  > - The password set in the official Docker image is `lobe66` by default. Replace it with your own password to improve security.
43
43
  > - For a complete list of environment variables supported by LobeChat, please refer to the [Environment Variables](https://github.com/lobehub/lobe-chat/wiki/Environment-Variable.zh-CN) section.
44
44
 
45
+ > \[!WARNING]
46
+ >
47
+ > If the architecture of your **deployed server differs from the container architecture**, you may need to perform cross-compilation for **Sharp**. For further details, please refer to the documentation on [Sharp Cross-platform](https://sharp.pixelplumbing.com/install#cross-platform).
48
+
45
49
  #### Use a proxy address
46
50
 
47
51
  If you need to use OpenAI service through a proxy, you can use the `OPENAI_PROXY_URL` environment variable to configure the proxy address:
@@ -42,6 +42,10 @@ $ docker run -d -p 3210:3210 \
42
42
  > - 官方 Docker 镜像中设定的密码默认为 `lobe66`,请将其替换为自己的密码以提升安全性
43
43
  > - LobeChat 支持的完整环境变量列表请参考 [环境变量](https://github.com/lobehub/lobe-chat/wiki/Environment-Variable.zh-CN) 部分
44
44
 
45
+ > \[!WARNING]
46
+ >
47
+ > 注意,当**部署架构与镜像的不一致时**,需要对 **Sharp** 进行交叉编译,详见 [Sharp 交叉编译](https://sharp.pixelplumbing.com/install#cross-platform)
48
+
45
49
  #### 使用代理地址
46
50
 
47
51
  如果你需要通过代理使用 OpenAI 服务,你可以使用 `OPENAI_PROXY_URL` 环境变量来配置代理地址:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "0.110.4",
3
+ "version": "0.110.6",
4
4
  "description": "An open-source, extensible (Function Calling), high-performance chatbot framework. It supports one-click free deployment of your private ChatGPT/LLM web application",
5
5
  "keywords": [
6
6
  "chatbot",
@@ -144,7 +144,7 @@
144
144
  "@types/ua-parser-js": "^0.7",
145
145
  "@types/uuid": "^9",
146
146
  "@umijs/lint": "^4",
147
- "@vitest/coverage-v8": "^1",
147
+ "@vitest/coverage-v8": "0.34.6",
148
148
  "commitlint": "^18",
149
149
  "consola": "^3",
150
150
  "dpdm": "^3",
@@ -162,7 +162,7 @@
162
162
  "stylelint": "^15",
163
163
  "ts-node": "^10",
164
164
  "typescript": "^5",
165
- "vitest": "^1"
165
+ "vitest": "0.34.6"
166
166
  },
167
167
  "publishConfig": {
168
168
  "access": "public",
@@ -27,7 +27,7 @@ const AgentPlugin = memo(() => {
27
27
  s.toggleAgentPlugin,
28
28
  ]);
29
29
 
30
- const installedPlugins = useToolStore(pluginSelectors.installedPlugins, isEqual);
30
+ const installedPlugins = useToolStore(pluginSelectors.installedPluginMetaList, isEqual);
31
31
  const useFetchInstalledPlugins = useToolStore((s) => s.useFetchInstalledPlugins);
32
32
 
33
33
  const { isLoading } = useFetchInstalledPlugins();
@@ -36,7 +36,7 @@ const AgentPlugin = memo(() => {
36
36
 
37
37
  // =========== Plugin List =========== //
38
38
 
39
- const list = installedPlugins.map(({ identifier, type, manifest: { meta } = {} }) => {
39
+ const list = installedPlugins.map(({ identifier, type, meta }) => {
40
40
  const isCustomPlugin = type === 'customPlugin';
41
41
 
42
42
  return {
@@ -7,7 +7,7 @@ import { pluginSelectors } from './selectors';
7
7
 
8
8
  const mockState = {
9
9
  ...initialState,
10
- pluginManifestLoading: {
10
+ pluginInstallLoading: {
11
11
  'plugin-1': false,
12
12
  'plugin-2': true,
13
13
  },
@@ -139,4 +139,73 @@ describe('pluginSelectors', () => {
139
139
  expect(result).toBe(true);
140
140
  });
141
141
  });
142
+
143
+ describe('isPluginInstalled', () => {
144
+ it('should return true if the plugin is installed', () => {
145
+ const result = pluginSelectors.isPluginInstalled('plugin-1')(mockState);
146
+ expect(result).toBe(true);
147
+ });
148
+
149
+ it('should return false if the plugin is not installed', () => {
150
+ const result = pluginSelectors.isPluginInstalled('non-installed-plugin')(mockState);
151
+ expect(result).toBe(false);
152
+ });
153
+ });
154
+
155
+ describe('getInstalledPluginById', () => {
156
+ it('should return the installed plugin by id', () => {
157
+ const result = pluginSelectors.getInstalledPluginById('plugin-1')(mockState);
158
+ expect(result).toEqual(mockState.installedPlugins[0]);
159
+ });
160
+
161
+ it('should return undefined if the plugin is not installed', () => {
162
+ const result = pluginSelectors.getInstalledPluginById('non-installed-plugin')(mockState);
163
+ expect(result).toBeUndefined();
164
+ });
165
+ });
166
+
167
+ describe('getPluginManifestLoadingStatus', () => {
168
+ it('should return "loading" if the plugin manifest is being loaded', () => {
169
+ const result = pluginSelectors.getPluginManifestLoadingStatus('plugin-2')(mockState);
170
+ expect(result).toBe('loading');
171
+ });
172
+
173
+ it('should return "error" if the plugin manifest is not found', () => {
174
+ const result =
175
+ pluginSelectors.getPluginManifestLoadingStatus('non-existing-plugin')(mockState);
176
+ expect(result).toBe('error');
177
+ });
178
+
179
+ it('should return "success" if the plugin manifest is loaded', () => {
180
+ const result = pluginSelectors.getPluginManifestLoadingStatus('plugin-1')(mockState);
181
+ expect(result).toBe('success');
182
+ });
183
+ });
184
+
185
+ describe('storeAndInstallPluginsIdList', () => {
186
+ it('should return a list of unique plugin identifiers from both installed and store lists', () => {
187
+ const result = pluginSelectors.storeAndInstallPluginsIdList(mockState);
188
+ expect(result).toEqual(['plugin-1', 'plugin-2']);
189
+ });
190
+ });
191
+
192
+ describe('installedPluginManifestList', () => {
193
+ it('should return a list of manifests for installed plugins', () => {
194
+ const result = pluginSelectors.installedPluginManifestList(mockState);
195
+ const expectedManifests = mockState.installedPlugins.map((p) => p.manifest);
196
+ expect(result).toEqual(expectedManifests);
197
+ });
198
+ });
199
+
200
+ describe('installedPluginMetaList', () => {
201
+ it('should return a list of meta information for installed plugins', () => {
202
+ const result = pluginSelectors.installedPluginMetaList(mockState);
203
+ const expectedMetaList = mockState.installedPlugins.map((p) => ({
204
+ identifier: p.identifier,
205
+ meta: pluginSelectors.getPluginMetaById(p.identifier)(mockState),
206
+ type: p.type,
207
+ }));
208
+ expect(result).toEqual(expectedMetaList);
209
+ });
210
+ });
142
211
  });
@@ -63,6 +63,7 @@ const installedPluginMetaList = (s: ToolStoreState) =>
63
63
  installedPlugins(s).map((p) => ({
64
64
  identifier: p.identifier,
65
65
  meta: getPluginMetaById(p.identifier)(s),
66
+ type: p.type,
66
67
  }));
67
68
 
68
69
  const isPluginHasUI = (id: string) => (s: ToolStoreState) => {