@lobehub/chat 1.38.0 → 1.39.1

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 1.39.1](https://github.com/lobehub/lobe-chat/compare/v1.39.0...v1.39.1)
6
+
7
+ <sup>Released on **2024-12-24**</sup>
8
+
9
+ #### 🐛 Bug Fixes
10
+
11
+ - **misc**: Fix image input on pglite.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### What's fixed
19
+
20
+ - **misc**: Fix image input on pglite, closes [#5167](https://github.com/lobehub/lobe-chat/issues/5167) ([5c5b37d](https://github.com/lobehub/lobe-chat/commit/5c5b37d))
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 1.39.0](https://github.com/lobehub/lobe-chat/compare/v1.38.0...v1.39.0)
31
+
32
+ <sup>Released on **2024-12-23**</sup>
33
+
34
+ #### ✨ Features
35
+
36
+ - **misc**: Upgrade to next15 and react19.
37
+
38
+ <br/>
39
+
40
+ <details>
41
+ <summary><kbd>Improvements and Fixes</kbd></summary>
42
+
43
+ #### What's improved
44
+
45
+ - **misc**: Upgrade to next15 and react19, closes [#4450](https://github.com/lobehub/lobe-chat/issues/4450) ([07d7417](https://github.com/lobehub/lobe-chat/commit/07d7417))
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 1.38.0](https://github.com/lobehub/lobe-chat/compare/v1.37.2...v1.38.0)
6
56
 
7
57
  <sup>Released on **2024-12-23**</sup>
package/changelog/v1.json CHANGED
@@ -1,4 +1,22 @@
1
1
  [
2
+ {
3
+ "children": {
4
+ "fixes": [
5
+ "Fix image input on pglite."
6
+ ]
7
+ },
8
+ "date": "2024-12-24",
9
+ "version": "1.39.1"
10
+ },
11
+ {
12
+ "children": {
13
+ "features": [
14
+ "Upgrade to next15 and react19."
15
+ ]
16
+ },
17
+ "date": "2024-12-23",
18
+ "version": "1.39.0"
19
+ },
2
20
  {
3
21
  "children": {
4
22
  "features": [
@@ -1,6 +1,7 @@
1
1
  import analyzer from '@next/bundle-analyzer';
2
2
  import { withSentryConfig } from '@sentry/nextjs';
3
3
  import withSerwistInit from '@serwist/next';
4
+ import type { NextConfig } from 'next';
4
5
  import ReactComponentName from 'react-scan/react-component-name/webpack';
5
6
 
6
7
  const isProd = process.env.NODE_ENV === 'production';
@@ -13,8 +14,7 @@ const API_PROXY_ENDPOINT = process.env.API_PROXY_ENDPOINT || '';
13
14
 
14
15
  const basePath = process.env.NEXT_PUBLIC_BASE_PATH;
15
16
 
16
- /** @type {import('next').NextConfig} */
17
- const nextConfig = {
17
+ const nextConfig: NextConfig = {
18
18
  basePath,
19
19
  compress: isProd,
20
20
  experimental: {
@@ -27,7 +27,6 @@ const nextConfig = {
27
27
  'gpt-tokenizer',
28
28
  'chroma-js',
29
29
  ],
30
- serverComponentsExternalPackages: ['@electric-sql/pglite'],
31
30
  webVitalsAttribution: ['CLS', 'LCP'],
32
31
  },
33
32
 
@@ -107,7 +106,6 @@ const nextConfig = {
107
106
  },
108
107
  ];
109
108
  },
110
-
111
109
  output: buildWithDocker ? 'standalone' : undefined,
112
110
  reactStrictMode: true,
113
111
  redirects: async () => [
@@ -169,13 +167,14 @@ const nextConfig = {
169
167
  source: '/welcome',
170
168
  },
171
169
  ],
172
-
173
170
  rewrites: async () => [
174
171
  // due to google api not work correct in some countries
175
172
  // we need a proxy to bypass the restriction
176
173
  { destination: `${API_PROXY_ENDPOINT}/api/chat/google`, source: '/api/chat/google' },
177
174
  ],
178
175
 
176
+ serverExternalPackages: ['@electric-sql/pglite'],
177
+
179
178
  webpack(config) {
180
179
  config.experiments = {
181
180
  asyncWebAssembly: true,
@@ -206,7 +205,7 @@ const nextConfig = {
206
205
  },
207
206
  };
208
207
 
209
- const noWrapper = (config) => config;
208
+ const noWrapper = (config: NextConfig) => config;
210
209
 
211
210
  const withBundleAnalyzer = process.env.ANALYZE === 'true' ? analyzer() : noWrapper;
212
211
 
@@ -221,7 +220,7 @@ const withPWA = isProd
221
220
  const hasSentry = !!process.env.NEXT_PUBLIC_SENTRY_DSN;
222
221
  const withSentry =
223
222
  isProd && hasSentry
224
- ? (c) =>
223
+ ? (c: NextConfig) =>
225
224
  withSentryConfig(
226
225
  c,
227
226
  {
@@ -262,4 +261,4 @@ const withSentry =
262
261
  )
263
262
  : noWrapper;
264
263
 
265
- export default withBundleAnalyzer(withPWA(withSentry(nextConfig)));
264
+ export default withBundleAnalyzer(withPWA(withSentry(nextConfig) as NextConfig));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "1.38.0",
3
+ "version": "1.39.1",
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",
@@ -39,7 +39,7 @@
39
39
  "db:push-test": "NODE_ENV=test drizzle-kit push",
40
40
  "db:studio": "drizzle-kit studio",
41
41
  "db:z-pull": "drizzle-kit introspect",
42
- "dev": "next dev -p 3010",
42
+ "dev": "next dev --turbo -p 3010",
43
43
  "docs:i18n": "lobe-i18n md && npm run lint:mdx",
44
44
  "docs:seo": "lobe-seo && npm run lint:mdx",
45
45
  "i18n": "npm run workflow:i18n && lobe-i18n",
@@ -104,7 +104,7 @@
104
104
  "dependencies": {
105
105
  "@ant-design/icons": "^5.5.1",
106
106
  "@ant-design/pro-components": "^2.7.18",
107
- "@anthropic-ai/sdk": "^0.32.0",
107
+ "@anthropic-ai/sdk": "^0.33.0",
108
108
  "@auth/core": "^0.37.0",
109
109
  "@aws-sdk/client-bedrock-runtime": "^3.675.0",
110
110
  "@aws-sdk/client-s3": "^3.675.0",
@@ -130,7 +130,7 @@
130
130
  "@lobehub/tts": "^1.25.1",
131
131
  "@lobehub/ui": "^1.153.13",
132
132
  "@neondatabase/serverless": "^0.10.1",
133
- "@next/third-parties": "^14.2.15",
133
+ "@next/third-parties": "^15.0.0",
134
134
  "@react-spring/web": "^9.7.5",
135
135
  "@sentry/nextjs": "^7.119.2",
136
136
  "@serwist/next": "^9.0.9",
@@ -145,7 +145,7 @@
145
145
  "@vercel/speed-insights": "^1.0.12",
146
146
  "ahooks": "^3.8.1",
147
147
  "ai": "^3.4.16",
148
- "antd": "^5.21.4",
148
+ "antd": "^5.22.6",
149
149
  "antd-style": "^3.7.1",
150
150
  "brotli-wasm": "^3.0.1",
151
151
  "chroma-js": "^2.6.0",
@@ -175,7 +175,7 @@
175
175
  "mammoth": "^1.8.0",
176
176
  "modern-screenshot": "^4.4.39",
177
177
  "nanoid": "^5.0.7",
178
- "next": "14.2.8",
178
+ "next": "^15.1.2",
179
179
  "next-auth": "beta",
180
180
  "next-mdx-remote": "^4.4.1",
181
181
  "nextjs-toploader": "^3.7.15",
@@ -195,9 +195,9 @@
195
195
  "pwa-install-handler": "^2.6.1",
196
196
  "query-string": "^9.1.1",
197
197
  "random-words": "^2.0.1",
198
- "react": "^18.3.1",
198
+ "react": "^19.0.0",
199
199
  "react-confetti": "^6.1.0",
200
- "react-dom": "^18.3.1",
200
+ "react-dom": "^19.0.0",
201
201
  "react-fast-marquee": "^1.6.5",
202
202
  "react-hotkeys-hook": "^4.5.1",
203
203
  "react-i18next": "14.0.2",
@@ -244,8 +244,8 @@
244
244
  "@lobehub/i18n-cli": "^1.20.0",
245
245
  "@lobehub/lint": "^1.24.4",
246
246
  "@lobehub/seo-cli": "^1.4.2",
247
- "@next/bundle-analyzer": "^14.2.15",
248
- "@next/eslint-plugin-next": "^14.2.15",
247
+ "@next/bundle-analyzer": "^15.0.0",
248
+ "@next/eslint-plugin-next": "^15.0.0",
249
249
  "@peculiar/webcrypto": "^1.5.0",
250
250
  "@semantic-release/exec": "^6.0.3",
251
251
  "@testing-library/jest-dom": "^6.6.2",
@@ -48,7 +48,9 @@ export class MessageModel {
48
48
  // **************** Query *************** //
49
49
  query = async (
50
50
  { current = 0, pageSize = 1000, sessionId, topicId }: QueryMessageParams = {},
51
- options: { postProcessUrl?: (path: string | null) => Promise<string> } = {},
51
+ options: {
52
+ postProcessUrl?: (path: string | null, file: { fileType: string }) => Promise<string>;
53
+ } = {},
52
54
  ): Promise<MessageItem[]> => {
53
55
  const offset = current * pageSize;
54
56
 
@@ -130,7 +132,9 @@ export class MessageModel {
130
132
  const relatedFileList = await Promise.all(
131
133
  rawRelatedFileList.map(async (file) => ({
132
134
  ...file,
133
- url: options.postProcessUrl ? await options.postProcessUrl(file.url) : (file.url as string),
135
+ url: options.postProcessUrl
136
+ ? await options.postProcessUrl(file.url, file as any)
137
+ : (file.url as string),
134
138
  })),
135
139
  );
136
140
 
@@ -0,0 +1,20 @@
1
+ "use client";
2
+
3
+ import { useEffect } from "react";
4
+ import { unstableSetRender } from "antd";
5
+ import { createRoot } from "react-dom/client";
6
+
7
+ const AntdV5MonkeyPatch = () => {
8
+ useEffect(() => {
9
+ unstableSetRender((node, container) => {
10
+ const root = createRoot(container);
11
+ root.render(node);
12
+ return async () => {
13
+ root.unmount();
14
+ };
15
+ });
16
+ }, []);
17
+ return null;
18
+ };
19
+
20
+ export default AntdV5MonkeyPatch;
@@ -17,6 +17,7 @@ import { ServerConfigStoreProvider } from '@/store/serverConfig';
17
17
  import { getAntdLocale } from '@/utils/locale';
18
18
  import { isMobileDevice } from '@/utils/server/responsive';
19
19
 
20
+ import AntdV5MonkeyPatch from './AntdV5MonkeyPatch';
20
21
  import AppTheme from './AppTheme';
21
22
  import Debug from './Debug';
22
23
  import Locale from './Locale';
@@ -91,6 +92,7 @@ const GlobalLayout = async ({ children }: PropsWithChildren) => {
91
92
  <DebugUI />
92
93
  <Debug />
93
94
  </AppTheme>
95
+ <AntdV5MonkeyPatch />
94
96
  </Locale>
95
97
  </StyleRegistry>
96
98
  );
@@ -5,6 +5,7 @@ import { clientDB } from '@/database/client/db';
5
5
  import { MessageItem } from '@/database/schemas';
6
6
  import { MessageModel } from '@/database/server/models/message';
7
7
  import { BaseClientService } from '@/services/baseClientService';
8
+ import { clientS3Storage } from '@/services/file/ClientS3';
8
9
  import {
9
10
  ChatMessage,
10
11
  ChatMessageError,
@@ -34,10 +35,20 @@ export class ClientService extends BaseClientService implements IMessageService
34
35
  }
35
36
 
36
37
  async getMessages(sessionId: string, topicId?: string) {
37
- const data = await this.messageModel.query({
38
- sessionId: this.toDbSessionId(sessionId),
39
- topicId,
40
- });
38
+ const data = await this.messageModel.query(
39
+ {
40
+ sessionId: this.toDbSessionId(sessionId),
41
+ topicId,
42
+ },
43
+ {
44
+ postProcessUrl: async (url, file) => {
45
+ const hash = (url as string).replace('client-s3://', '');
46
+ const base64 = await this.getBase64ByFileHash(hash);
47
+
48
+ return `data:${file.fileType};base64,${base64}`;
49
+ },
50
+ },
51
+ );
41
52
 
42
53
  return data as unknown as ChatMessage[];
43
54
  }
@@ -115,4 +126,11 @@ export class ClientService extends BaseClientService implements IMessageService
115
126
  private toDbSessionId(sessionId: string | undefined) {
116
127
  return sessionId === INBOX_SESSION_ID ? undefined : sessionId;
117
128
  }
129
+
130
+ private async getBase64ByFileHash(hash: string) {
131
+ const fileItem = await clientS3Storage.getObject(hash);
132
+ if (!fileItem) throw new Error('file not found');
133
+
134
+ return Buffer.from(await fileItem.arrayBuffer()).toString('base64');
135
+ }
118
136
  }