@lobehub/chat 1.43.3 → 1.43.5

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.
Files changed (35) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/changelog/v1.json +18 -0
  3. package/next.config.ts +2 -8
  4. package/package.json +87 -88
  5. package/src/app/(main)/chat/features/Migration/Failed.tsx +4 -2
  6. package/src/app/(main)/discover/(detail)/assistant/[slug]/features/InfoSidebar/index.tsx +4 -5
  7. package/src/app/(main)/discover/(detail)/assistant/[slug]/page.tsx +1 -8
  8. package/src/app/(main)/discover/(detail)/model/[...slugs]/features/InfoSidebar/index.tsx +4 -5
  9. package/src/app/(main)/discover/(detail)/model/[...slugs]/page.tsx +1 -1
  10. package/src/app/(main)/discover/(detail)/plugin/[slug]/features/InfoSidebar/SuggestionItem.tsx +8 -6
  11. package/src/app/(main)/discover/(detail)/plugin/[slug]/features/InfoSidebar/index.tsx +4 -5
  12. package/src/app/(main)/discover/(detail)/plugin/[slug]/page.tsx +1 -1
  13. package/src/app/(main)/discover/(detail)/provider/[slug]/features/InfoSidebar/index.tsx +4 -5
  14. package/src/app/(main)/discover/(list)/assistants/features/Card.tsx +7 -6
  15. package/src/app/(main)/discover/(list)/models/features/Card.tsx +7 -5
  16. package/src/app/(main)/discover/(list)/plugins/features/Card.tsx +7 -6
  17. package/src/app/(main)/discover/(list)/providers/features/Card.tsx +7 -5
  18. package/src/app/(main)/discover/(list)/providers/features/List.tsx +5 -3
  19. package/src/app/(main)/discover/components/VirtuosoGridList/index.tsx +10 -14
  20. package/src/app/(main)/discover/features/ModelFeatureTags.tsx +12 -3
  21. package/src/app/(main)/settings/llm/components/ProviderModelList/ModelFetcher.tsx +1 -1
  22. package/src/app/(main)/settings/llm/components/ProviderModelList/Option.tsx +1 -1
  23. package/src/components/FileParsingStatus/EmbeddingStatus.tsx +7 -3
  24. package/src/components/FileParsingStatus/index.tsx +3 -3
  25. package/src/components/ModelSelect/index.tsx +8 -4
  26. package/src/components/TipGuide/index.tsx +6 -2
  27. package/src/features/ChatInput/ActionBar/Clear.tsx +3 -1
  28. package/src/features/ChatInput/ActionBar/Token/TokenTag.tsx +1 -1
  29. package/src/features/FileManager/FileList/FileListItem/index.tsx +3 -1
  30. package/src/features/User/DataStatistics.tsx +4 -20
  31. package/src/features/User/UserPanel/LangButton.tsx +5 -3
  32. package/src/features/User/UserPanel/ThemeButton.tsx +5 -3
  33. package/src/features/User/UserPanel/index.tsx +3 -1
  34. package/src/utils/format.test.ts +5 -3
  35. package/src/utils/format.ts +1 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,56 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ### [Version 1.43.5](https://github.com/lobehub/lobe-chat/compare/v1.43.4...v1.43.5)
6
+
7
+ <sup>Released on **2025-01-07**</sup>
8
+
9
+ #### 💄 Styles
10
+
11
+ - **misc**: Fix style warning in antd 5.23.0 and some error logs.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### Styles
19
+
20
+ - **misc**: Fix style warning in antd 5.23.0 and some error logs, closes [#5319](https://github.com/lobehub/lobe-chat/issues/5319) ([4fcf5d6](https://github.com/lobehub/lobe-chat/commit/4fcf5d6))
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.43.4](https://github.com/lobehub/lobe-chat/compare/v1.43.3...v1.43.4)
31
+
32
+ <sup>Released on **2025-01-06**</sup>
33
+
34
+ #### 🐛 Bug Fixes
35
+
36
+ - **misc**: Fix format short number.
37
+
38
+ <br/>
39
+
40
+ <details>
41
+ <summary><kbd>Improvements and Fixes</kbd></summary>
42
+
43
+ #### What's fixed
44
+
45
+ - **misc**: Fix format short number, closes [#5294](https://github.com/lobehub/lobe-chat/issues/5294) ([d8a29ec](https://github.com/lobehub/lobe-chat/commit/d8a29ec))
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.43.3](https://github.com/lobehub/lobe-chat/compare/v1.43.2...v1.43.3)
6
56
 
7
57
  <sup>Released on **2025-01-04**</sup>
package/changelog/v1.json CHANGED
@@ -1,4 +1,22 @@
1
1
  [
2
+ {
3
+ "children": {
4
+ "improvements": [
5
+ "Fix style warning in antd 5.23.0 and some error logs."
6
+ ]
7
+ },
8
+ "date": "2025-01-07",
9
+ "version": "1.43.5"
10
+ },
11
+ {
12
+ "children": {
13
+ "fixes": [
14
+ "Fix format short number."
15
+ ]
16
+ },
17
+ "date": "2025-01-06",
18
+ "version": "1.43.4"
19
+ },
2
20
  {
3
21
  "children": {
4
22
  "improvements": [
package/next.config.ts CHANGED
@@ -10,7 +10,6 @@ const enableReactScan = !!process.env.REACT_SCAN_MONITOR_API_KEY;
10
10
  const isUsePglite = process.env.NEXT_PUBLIC_CLIENT_DB === 'pglite';
11
11
 
12
12
  // if you need to proxy the api endpoint to remote server
13
- const API_PROXY_ENDPOINT = process.env.API_PROXY_ENDPOINT || '';
14
13
 
15
14
  const basePath = process.env.NEXT_PUBLIC_BASE_PATH;
16
15
 
@@ -28,7 +27,6 @@ const nextConfig: NextConfig = {
28
27
  ],
29
28
  webVitalsAttribution: ['CLS', 'LCP'],
30
29
  },
31
-
32
30
  async headers() {
33
31
  return [
34
32
  {
@@ -166,13 +164,9 @@ const nextConfig: NextConfig = {
166
164
  source: '/welcome',
167
165
  },
168
166
  ],
169
- rewrites: async () => [
170
- // due to google api not work correct in some countries
171
- // we need a proxy to bypass the restriction
172
- { destination: `${API_PROXY_ENDPOINT}/api/chat/google`, source: '/api/chat/google' },
173
- ],
167
+ serverExternalPackages: ['@electric-sql/pglite', 'shiki/wasm', 'sharp'],
174
168
 
175
- serverExternalPackages: ['@electric-sql/pglite'],
169
+ transpilePackages: ['pdfjs-dist', 'mermaid'],
176
170
 
177
171
  webpack(config) {
178
172
  config.experiments = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "1.43.3",
3
+ "version": "1.43.5",
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",
@@ -103,80 +103,80 @@
103
103
  ]
104
104
  },
105
105
  "dependencies": {
106
- "@ant-design/icons": "^5.5.1",
107
- "@ant-design/pro-components": "^2.7.18",
108
- "@anthropic-ai/sdk": "^0.33.0",
109
- "@auth/core": "^0.37.0",
110
- "@aws-sdk/client-bedrock-runtime": "^3.675.0",
111
- "@aws-sdk/client-s3": "^3.675.0",
112
- "@aws-sdk/s3-request-presigner": "^3.675.0",
106
+ "@ant-design/icons": "^5.5.2",
107
+ "@ant-design/pro-components": "^2.8.3",
108
+ "@anthropic-ai/sdk": "^0.33.1",
109
+ "@auth/core": "^0.37.4",
110
+ "@aws-sdk/client-bedrock-runtime": "^3.723.0",
111
+ "@aws-sdk/client-s3": "^3.723.0",
112
+ "@aws-sdk/s3-request-presigner": "^3.723.0",
113
113
  "@azure/core-rest-pipeline": "1.16.0",
114
114
  "@azure/openai": "1.0.0-beta.12",
115
115
  "@baiducloud/qianfan": "^0.1.9",
116
- "@cfworker/json-schema": "^4.0.0",
117
- "@clerk/localizations": "^3.3.0",
116
+ "@cfworker/json-schema": "^4.1.0",
117
+ "@clerk/localizations": "^3.9.5",
118
118
  "@clerk/nextjs": "^6.9.6",
119
- "@clerk/themes": "^2.1.37",
120
- "@codesandbox/sandpack-react": "^2.19.9",
119
+ "@clerk/themes": "^2.2.3",
120
+ "@codesandbox/sandpack-react": "^2.19.10",
121
121
  "@cyntler/react-doc-viewer": "^1.17.0",
122
122
  "@electric-sql/pglite": "0.2.13",
123
123
  "@google/generative-ai": "^0.21.0",
124
124
  "@huggingface/inference": "^2.8.1",
125
125
  "@icons-pack/react-simple-icons": "9.6.0",
126
126
  "@khmyznikov/pwa-install": "^0.3.9",
127
- "@langchain/community": "^0.3.0",
128
- "@lobehub/charts": "^1.9.12",
127
+ "@langchain/community": "^0.3.22",
128
+ "@lobehub/charts": "^1.11.0",
129
129
  "@lobehub/chat-plugin-sdk": "^1.32.4",
130
130
  "@lobehub/chat-plugins-gateway": "^1.9.0",
131
- "@lobehub/icons": "^1.56.0",
132
- "@lobehub/tts": "^1.25.1",
133
- "@lobehub/ui": "^1.156.3",
134
- "@neondatabase/serverless": "^0.10.1",
135
- "@next/third-parties": "^15.0.0",
131
+ "@lobehub/icons": "^1.61.1",
132
+ "@lobehub/tts": "^1.27.0",
133
+ "@lobehub/ui": "^1.161.0",
134
+ "@neondatabase/serverless": "^0.10.4",
135
+ "@next/third-parties": "^15.1.3",
136
136
  "@react-spring/web": "^9.7.5",
137
- "@sentry/nextjs": "^7.119.2",
138
- "@serwist/next": "^9.0.9",
137
+ "@sentry/nextjs": "^7.120.2",
138
+ "@serwist/next": "^9.0.11",
139
139
  "@t3-oss/env-nextjs": "^0.11.1",
140
- "@tanstack/react-query": "^5.59.15",
140
+ "@tanstack/react-query": "^5.62.16",
141
141
  "@trpc/client": "next",
142
142
  "@trpc/next": "next",
143
143
  "@trpc/react-query": "next",
144
144
  "@trpc/server": "next",
145
- "@vercel/analytics": "^1.3.1",
146
- "@vercel/edge-config": "^1.3.0",
147
- "@vercel/speed-insights": "^1.0.12",
148
- "ahooks": "^3.8.1",
149
- "ai": "^3.4.16",
150
- "antd": "^5.22.6",
145
+ "@vercel/analytics": "^1.4.1",
146
+ "@vercel/edge-config": "^1.4.0",
147
+ "@vercel/speed-insights": "^1.1.0",
148
+ "ahooks": "^3.8.4",
149
+ "ai": "^3.4.33",
150
+ "antd": "^5.23.0",
151
151
  "antd-style": "^3.7.1",
152
152
  "brotli-wasm": "^3.0.1",
153
153
  "chroma-js": "^3.1.2",
154
154
  "dayjs": "^1.11.13",
155
- "debug": "^4.3.7",
155
+ "debug": "^4.4.0",
156
156
  "dexie": "^3.2.7",
157
157
  "diff": "^5.2.0",
158
- "drizzle-orm": "^0.38.0",
158
+ "drizzle-orm": "^0.38.3",
159
159
  "drizzle-zod": "^0.5.1",
160
160
  "fast-deep-equal": "^3.1.3",
161
161
  "file-type": "^19.6.0",
162
- "framer-motion": "^11.11.9",
163
- "gpt-tokenizer": "^2.5.0",
164
- "i18next": "^23.16.1",
165
- "i18next-browser-languagedetector": "^7.2.1",
162
+ "framer-motion": "^11.16.0",
163
+ "gpt-tokenizer": "^2.8.1",
164
+ "i18next": "^23.16.8",
165
+ "i18next-browser-languagedetector": "^7.2.2",
166
166
  "i18next-resources-to-backend": "^1.2.1",
167
167
  "idb-keyval": "^6.2.1",
168
168
  "immer": "^10.1.1",
169
- "jose": "^5.9.4",
169
+ "jose": "^5.9.6",
170
170
  "js-sha256": "^0.11.0",
171
171
  "jsonl-parse-stringify": "^1.0.3",
172
- "langchain": "^0.3.2",
172
+ "langchain": "^0.3.10",
173
173
  "langfuse": "3.29.1",
174
174
  "langfuse-core": "3.29.1",
175
175
  "lodash-es": "^4.17.21",
176
176
  "lucide-react": "latest",
177
- "mammoth": "^1.8.0",
178
- "modern-screenshot": "^4.4.39",
179
- "nanoid": "^5.0.7",
177
+ "mammoth": "^1.9.0",
178
+ "modern-screenshot": "^4.5.5",
179
+ "nanoid": "^5.0.9",
180
180
  "next": "^15.1.3",
181
181
  "next-auth": "beta",
182
182
  "next-mdx-remote": "^4.4.1",
@@ -184,104 +184,103 @@
184
184
  "numeral": "^2.0.6",
185
185
  "nuqs": "^1.20.0",
186
186
  "officeparser": "^4.2.0",
187
- "ollama": "^0.5.10",
188
- "openai": "^4.68.1",
187
+ "ollama": "^0.5.11",
188
+ "openai": "^4.77.3",
189
189
  "openapi-fetch": "^0.9.8",
190
190
  "partial-json": "^0.1.7",
191
191
  "pdf-parse": "^1.1.1",
192
192
  "pdfjs-dist": "4.8.69",
193
- "pg": "^8.13.0",
194
- "pino": "^9.5.0",
193
+ "pg": "^8.13.1",
194
+ "pino": "^9.6.0",
195
195
  "plaiceholder": "^3.0.0",
196
196
  "polished": "^4.3.1",
197
- "posthog-js": "^1.174.2",
198
- "pwa-install-handler": "^2.6.1",
197
+ "posthog-js": "^1.204.0",
198
+ "pwa-install-handler": "^2.6.2",
199
199
  "query-string": "^9.1.1",
200
200
  "random-words": "^2.0.1",
201
201
  "react": "^19.0.0",
202
- "react-confetti": "^6.1.0",
202
+ "react-confetti": "^6.2.2",
203
203
  "react-dom": "^19.0.0",
204
204
  "react-fast-marquee": "^1.6.5",
205
- "react-hotkeys-hook": "^4.5.1",
205
+ "react-hotkeys-hook": "^4.6.1",
206
206
  "react-i18next": "14.0.2",
207
- "react-layout-kit": "^1.9.0",
207
+ "react-layout-kit": "^1.9.1",
208
208
  "react-lazy-load": "^4.0.1",
209
209
  "react-pdf": "^9.2.1",
210
210
  "react-scan": "^0.0.51",
211
- "react-virtuoso": "^4.12.0",
211
+ "react-virtuoso": "^4.12.3",
212
212
  "react-wrap-balancer": "^1.1.1",
213
213
  "remark": "^14.0.3",
214
214
  "remark-gfm": "^3.0.1",
215
215
  "remark-html": "^15.0.2",
216
216
  "request-filtering-agent": "^2.0.1",
217
- "resolve-accept-language": "^3.1.8",
217
+ "resolve-accept-language": "^3.1.10",
218
218
  "rtl-detect": "^1.1.2",
219
219
  "semver": "^7.6.3",
220
220
  "sharp": "^0.33.5",
221
- "shiki": "^1.22.0",
222
221
  "stripe": "^15.12.0",
223
- "superjson": "^2.2.1",
224
- "svix": "^1.37.0",
225
- "swr": "^2.2.5",
222
+ "superjson": "^2.2.2",
223
+ "svix": "^1.45.1",
224
+ "swr": "^2.3.0",
226
225
  "systemjs": "^6.15.1",
227
226
  "ts-md5": "^1.3.1",
228
- "ua-parser-js": "^1.0.39",
229
- "unstructured-client": "^0.18.1",
227
+ "ua-parser-js": "^1.0.40",
228
+ "unstructured-client": "^0.18.2",
230
229
  "url-join": "^5.0.0",
231
230
  "use-merge-value": "^1.2.0",
232
231
  "utility-types": "^3.11.0",
233
- "uuid": "^11.0.0",
232
+ "uuid": "^11.0.4",
234
233
  "ws": "^8.18.0",
235
234
  "y-protocols": "^1.0.6",
236
235
  "y-webrtc": "^10.3.0",
237
- "yaml": "^2.6.0",
238
- "yjs": "^13.6.20",
239
- "zod": "^3.23.8",
236
+ "yaml": "^2.7.0",
237
+ "yjs": "^13.6.21",
238
+ "zod": "^3.24.1",
240
239
  "zustand": "5.0.1",
241
240
  "zustand-utils": "^1.3.2"
242
241
  },
243
242
  "devDependencies": {
244
- "@commitlint/cli": "^19.5.0",
243
+ "@commitlint/cli": "^19.6.1",
245
244
  "@edge-runtime/vm": "^5.0.0",
246
- "@huggingface/tasks": "^0.12.22",
245
+ "@huggingface/tasks": "^0.12.30",
247
246
  "@lobehub/i18n-cli": "^1.20.3",
248
247
  "@lobehub/lint": "^1.24.4",
249
- "@lobehub/seo-cli": "^1.4.2",
250
- "@next/bundle-analyzer": "^15.0.0",
251
- "@next/eslint-plugin-next": "^15.0.0",
248
+ "@lobehub/seo-cli": "^1.4.3",
249
+ "@next/bundle-analyzer": "^15.1.3",
250
+ "@next/eslint-plugin-next": "^15.1.3",
252
251
  "@peculiar/webcrypto": "^1.5.0",
253
252
  "@semantic-release/exec": "^6.0.3",
254
- "@testing-library/jest-dom": "^6.6.2",
255
- "@testing-library/react": "^16.0.1",
256
- "@types/chroma-js": "^2.4.4",
253
+ "@testing-library/jest-dom": "^6.6.3",
254
+ "@testing-library/react": "^16.1.0",
255
+ "@types/chroma-js": "^2.4.5",
257
256
  "@types/crypto-js": "^4.2.2",
258
257
  "@types/debug": "^4.1.12",
259
258
  "@types/diff": "^6.0.0",
260
259
  "@types/fs-extra": "^11.0.4",
261
260
  "@types/ip": "^1.1.3",
262
261
  "@types/json-schema": "^7.0.15",
263
- "@types/lodash": "^4.17.12",
262
+ "@types/lodash": "^4.17.14",
264
263
  "@types/lodash-es": "^4.17.12",
265
- "@types/node": "^20.16.13",
264
+ "@types/node": "^20.17.12",
266
265
  "@types/numeral": "^2.0.5",
267
266
  "@types/pg": "^8.11.10",
268
267
  "@types/react": "18.3.13",
269
- "@types/react-dom": "^19.0.0",
268
+ "@types/react-dom": "^19.0.2",
270
269
  "@types/rtl-detect": "^1.0.3",
271
270
  "@types/semver": "^7.5.8",
272
271
  "@types/systemjs": "^6.15.1",
273
272
  "@types/ua-parser-js": "^0.7.39",
274
273
  "@types/unist": "^3.0.3",
275
274
  "@types/uuid": "^10.0.0",
276
- "@types/ws": "^8.5.12",
275
+ "@types/ws": "^8.5.13",
277
276
  "@vitest/coverage-v8": "~1.2.2",
278
277
  "ajv-keywords": "^5.1.0",
279
- "commitlint": "^19.5.0",
280
- "consola": "^3.2.3",
278
+ "commitlint": "^19.6.1",
279
+ "consola": "^3.3.3",
281
280
  "crypto-js": "^4.2.0",
282
- "dotenv": "^16.4.5",
283
- "dpdm-fast": "^1.0.4",
284
- "drizzle-kit": "^0.30.0",
281
+ "dotenv": "^16.4.7",
282
+ "dpdm-fast": "^1.0.7",
283
+ "drizzle-kit": "^0.30.1",
285
284
  "eslint": "^8.57.1",
286
285
  "eslint-plugin-mdx": "^2.3.4",
287
286
  "eslint-plugin-unused-imports": "4.0.1",
@@ -289,29 +288,29 @@
289
288
  "fs-extra": "^11.2.0",
290
289
  "glob": "^11.0.0",
291
290
  "gray-matter": "^4.0.3",
292
- "happy-dom": "^15.7.4",
293
- "husky": "^9.1.6",
291
+ "happy-dom": "^15.11.7",
292
+ "husky": "^9.1.7",
294
293
  "just-diff": "^6.0.2",
295
- "lint-staged": "^15.2.10",
294
+ "lint-staged": "^15.3.0",
296
295
  "lodash": "^4.17.21",
297
- "markdown-table": "^3.0.3",
296
+ "markdown-table": "^3.0.4",
298
297
  "markdown-to-txt": "^2.0.1",
299
- "mime": "^4.0.4",
298
+ "mime": "^4.0.6",
300
299
  "node-fetch": "^3.3.2",
301
300
  "node-gyp": "^11.0.0",
302
301
  "openapi-typescript": "^6.7.6",
303
- "p-map": "^7.0.2",
304
- "prettier": "^3.3.3",
302
+ "p-map": "^7.0.3",
303
+ "prettier": "^3.4.2",
305
304
  "remark-cli": "^11.0.0",
306
305
  "remark-parse": "^10.0.2",
307
306
  "semantic-release": "^21.1.2",
308
- "serwist": "^9.0.9",
307
+ "serwist": "^9.0.11",
309
308
  "stylelint": "^15.11.0",
310
- "tsx": "^4.19.1",
311
- "typescript": "^5.6.3",
309
+ "tsx": "^4.19.2",
310
+ "typescript": "^5.7.2",
312
311
  "unified": "^11.0.5",
313
312
  "unist-util-visit": "^5.0.0",
314
- "vite": "^5.4.9",
313
+ "vite": "^5.4.11",
315
314
  "vitest": "~1.2.2",
316
315
  "vitest-canvas-mock": "^0.3.3"
317
316
  },
@@ -70,8 +70,10 @@ const Failed = memo<FailedProps>(({ error, state, setUpgradeStatus, setError, up
70
70
  type: 'primary',
71
71
  }}
72
72
  onConfirm={clearLocal}
73
- overlayInnerStyle={{ background: lighten(0.03, theme.colorBgElevated) }}
74
- overlayStyle={{ width: 340 }}
73
+ styles={{
74
+ body: { background: lighten(0.03, theme.colorBgElevated) },
75
+ root: { width: 340 },
76
+ }}
75
77
  title={t('dbV1.clear.confirm')}
76
78
  >
77
79
  <Button size={'large'}>{t('dbV1.action.clearDB')}</Button>
@@ -4,7 +4,7 @@ import { Skeleton } from 'antd';
4
4
  import Link from 'next/link';
5
5
  import { memo } from 'react';
6
6
  import { useTranslation } from 'react-i18next';
7
- import { Flexbox, FlexboxProps } from 'react-layout-kit';
7
+ import { Flexbox } from 'react-layout-kit';
8
8
  import urlJoin from 'url-join';
9
9
 
10
10
  import { DiscoverAssistantItem, DiscoverPlugintem } from '@/types/discover';
@@ -13,18 +13,17 @@ import Block from '../../../../features/Block';
13
13
  import SuggestionItem from './SuggestionItem';
14
14
  import ToolItem from './ToolItem';
15
15
 
16
- interface InfoSidebarProps extends FlexboxProps {
16
+ interface InfoSidebarProps {
17
17
  data: DiscoverAssistantItem;
18
18
  identifier: string;
19
- mobile?: boolean;
20
19
  pluginData?: DiscoverPlugintem[];
21
20
  }
22
21
 
23
- const InfoSidebar = memo<InfoSidebarProps>(({ pluginData, data, ...rest }) => {
22
+ const InfoSidebar = memo<InfoSidebarProps>(({ pluginData, data }) => {
24
23
  const { t } = useTranslation('discover');
25
24
 
26
25
  return (
27
- <Flexbox gap={48} style={{ position: 'relative' }} width={'100%'} {...rest}>
26
+ <Flexbox gap={48} style={{ position: 'relative' }} width={'100%'}>
28
27
  {pluginData && pluginData?.length > 0 && (
29
28
  <Block gap={12} title={t('assistants.plugins')}>
30
29
  {pluginData.map((item) => (
@@ -99,14 +99,7 @@ const Page = async (props: DiscoverPageProps) => {
99
99
  actions={<Actions data={data} identifier={identifier} />}
100
100
  header={<Header data={data} identifier={identifier} mobile={mobile} />}
101
101
  mobile={mobile}
102
- sidebar={
103
- <InfoSidebar
104
- data={data}
105
- identifier={identifier}
106
- mobile={mobile}
107
- pluginData={pluginData}
108
- />
109
- }
102
+ sidebar={<InfoSidebar data={data} identifier={identifier} pluginData={pluginData} />}
110
103
  /* ↓ cloud slot ↓ */
111
104
 
112
105
  /* ↑ cloud slot ↑ */
@@ -4,7 +4,7 @@ import { Skeleton } from 'antd';
4
4
  import Link from 'next/link';
5
5
  import { memo } from 'react';
6
6
  import { useTranslation } from 'react-i18next';
7
- import { Flexbox, FlexboxProps } from 'react-layout-kit';
7
+ import { Flexbox } from 'react-layout-kit';
8
8
  import urlJoin from 'url-join';
9
9
 
10
10
  import { DiscoverModelItem } from '@/types/discover';
@@ -12,17 +12,16 @@ import { DiscoverModelItem } from '@/types/discover';
12
12
  import Block from '../../../../features/Block';
13
13
  import SuggestionItem from './SuggestionItem';
14
14
 
15
- interface InfoSidebarProps extends FlexboxProps {
15
+ interface InfoSidebarProps {
16
16
  data: DiscoverModelItem;
17
17
  identifier: string;
18
- mobile?: boolean;
19
18
  }
20
19
 
21
- const InfoSidebar = memo<InfoSidebarProps>(({ data, ...rest }) => {
20
+ const InfoSidebar = memo<InfoSidebarProps>(({ data }) => {
22
21
  const { t } = useTranslation('discover');
23
22
 
24
23
  return (
25
- <Flexbox gap={48} style={{ position: 'relative' }} width={'100%'} {...rest}>
24
+ <Flexbox gap={48} style={{ position: 'relative' }} width={'100%'}>
26
25
  <Block
27
26
  gap={24}
28
27
  more={t('models.more')}
@@ -105,7 +105,7 @@ const Page = async (props: Props) => {
105
105
  actions={<Actions data={data} identifier={identifier} providerData={providerData} />}
106
106
  header={<Header data={data} identifier={identifier} mobile={mobile} />}
107
107
  mobile={mobile}
108
- sidebar={<InfoSidebar data={data} identifier={identifier} mobile={mobile} />}
108
+ sidebar={<InfoSidebar data={data} identifier={identifier} />}
109
109
  /* ↓ cloud slot ↓ */
110
110
 
111
111
  /* ↑ cloud slot ↑ */
@@ -1,8 +1,8 @@
1
1
  import { Avatar } from '@lobehub/ui';
2
2
  import { Typography } from 'antd';
3
3
  import { createStyles } from 'antd-style';
4
- import { memo } from 'react';
5
- import { Flexbox, FlexboxProps } from 'react-layout-kit';
4
+ import { CSSProperties, memo } from 'react';
5
+ import { Flexbox } from 'react-layout-kit';
6
6
 
7
7
  import { DiscoverPlugintem } from '@/types/discover';
8
8
 
@@ -30,16 +30,18 @@ const useStyles = createStyles(({ css, token, isDarkMode }) => ({
30
30
  }));
31
31
 
32
32
  export interface SuggestionItemProps
33
- extends Omit<DiscoverPlugintem, 'suggestions' | 'socialData' | 'category' | 'manifest'>,
34
- FlexboxProps {}
33
+ extends Omit<DiscoverPlugintem, 'suggestions' | 'socialData' | 'category' | 'manifest'> {
34
+ className?: string;
35
+ style?: CSSProperties;
36
+ }
35
37
 
36
- const SuggestionItem = memo<SuggestionItemProps>(({ className, meta, identifier, ...rest }) => {
38
+ const SuggestionItem = memo<SuggestionItemProps>(({ className, meta, identifier, style }) => {
37
39
  const { avatar, title, description } = meta;
38
40
 
39
41
  const { cx, styles, theme } = useStyles();
40
42
 
41
43
  return (
42
- <Flexbox className={cx(styles.container, className)} gap={12} key={identifier} {...rest}>
44
+ <Flexbox className={cx(styles.container, className)} gap={12} key={identifier} style={style}>
43
45
  <Flexbox align={'center'} gap={12} horizontal width={'100%'}>
44
46
  <Avatar
45
47
  alt={title}
@@ -4,7 +4,7 @@ import { Skeleton } from 'antd';
4
4
  import Link from 'next/link';
5
5
  import { memo } from 'react';
6
6
  import { useTranslation } from 'react-i18next';
7
- import { Flexbox, FlexboxProps } from 'react-layout-kit';
7
+ import { Flexbox } from 'react-layout-kit';
8
8
  import urlJoin from 'url-join';
9
9
 
10
10
  import { DiscoverPlugintem } from '@/types/discover';
@@ -12,17 +12,16 @@ import { DiscoverPlugintem } from '@/types/discover';
12
12
  import Block from '../../../../features/Block';
13
13
  import SuggestionItem from './SuggestionItem';
14
14
 
15
- interface InfoSidebarProps extends FlexboxProps {
15
+ interface InfoSidebarProps {
16
16
  data: DiscoverPlugintem;
17
17
  identifier: string;
18
- mobile?: boolean;
19
18
  }
20
19
 
21
- const InfoSidebar = memo<InfoSidebarProps>(({ data, ...rest }) => {
20
+ const InfoSidebar = memo<InfoSidebarProps>(({ data }) => {
22
21
  const { t } = useTranslation('discover');
23
22
 
24
23
  return (
25
- <Flexbox gap={48} style={{ position: 'relative' }} width={'100%'} {...rest}>
24
+ <Flexbox gap={48} style={{ position: 'relative' }} width={'100%'}>
26
25
  <Block
27
26
  gap={24}
28
27
  more={t('assistants.more')}
@@ -91,7 +91,7 @@ const Page = async (props: DiscoverPageProps) => {
91
91
  actions={<Actions data={data} identifier={identifier} />}
92
92
  header={<Header data={data} identifier={identifier} mobile={mobile} />}
93
93
  mobile={mobile}
94
- sidebar={<InfoSidebar data={data} identifier={identifier} mobile={mobile} />}
94
+ sidebar={<InfoSidebar data={data} identifier={identifier} />}
95
95
  /* ↓ cloud slot ↓ */
96
96
 
97
97
  /* ↑ cloud slot ↑ */
@@ -4,7 +4,7 @@ import { Skeleton } from 'antd';
4
4
  import Link from 'next/link';
5
5
  import { memo } from 'react';
6
6
  import { useTranslation } from 'react-i18next';
7
- import { Flexbox, FlexboxProps } from 'react-layout-kit';
7
+ import { Flexbox } from 'react-layout-kit';
8
8
  import urlJoin from 'url-join';
9
9
 
10
10
  import { DiscoverProviderItem } from '@/types/discover';
@@ -12,17 +12,16 @@ import { DiscoverProviderItem } from '@/types/discover';
12
12
  import Block from '../../../../features/Block';
13
13
  import SuggestionItem from './SuggestionItem';
14
14
 
15
- interface InfoSidebarProps extends FlexboxProps {
15
+ interface InfoSidebarProps {
16
16
  data: DiscoverProviderItem;
17
17
  identifier: string;
18
- mobile?: boolean;
19
18
  }
20
19
 
21
- const InfoSidebar = memo<InfoSidebarProps>(({ data, ...rest }) => {
20
+ const InfoSidebar = memo<InfoSidebarProps>(({ data }) => {
22
21
  const { t } = useTranslation('discover');
23
22
 
24
23
  return (
25
- <Flexbox gap={48} style={{ position: 'relative' }} width={'100%'} {...rest}>
24
+ <Flexbox gap={48} style={{ position: 'relative' }} width={'100%'}>
26
25
  <Block
27
26
  gap={24}
28
27
  more={t('providers.more')}
@@ -4,8 +4,8 @@ import { createStyles } from 'antd-style';
4
4
  import { startCase } from 'lodash-es';
5
5
  import dynamic from 'next/dynamic';
6
6
  import qs from 'query-string';
7
- import { memo } from 'react';
8
- import { Center, Flexbox, FlexboxProps } from 'react-layout-kit';
7
+ import { CSSProperties, memo } from 'react';
8
+ import { Center, Flexbox } from 'react-layout-kit';
9
9
  import urlJoin from 'url-join';
10
10
 
11
11
  import { DiscoverAssistantItem } from '@/types/discover';
@@ -62,14 +62,15 @@ const useStyles = createStyles(({ css, token, isDarkMode }) => ({
62
62
  }));
63
63
 
64
64
  export interface AssistantCardProps
65
- extends Omit<DiscoverAssistantItem, 'suggestions' | 'socialData' | 'config'>,
66
- Omit<FlexboxProps, 'children'> {
65
+ extends Omit<DiscoverAssistantItem, 'suggestions' | 'socialData' | 'config'> {
66
+ className?: string;
67
67
  showCategory?: boolean;
68
+ style?: CSSProperties;
68
69
  variant?: 'default' | 'compact';
69
70
  }
70
71
 
71
72
  const AssistantCard = memo<AssistantCardProps>(
72
- ({ showCategory, className, meta, createdAt, author, variant, ...rest }) => {
73
+ ({ showCategory, className, meta, createdAt, author, variant, style }) => {
73
74
  const { avatar, title, description, tags = [], category } = meta;
74
75
  const { cx, styles, theme } = useStyles();
75
76
  const categoryItem = useCategoryItem(category, 12);
@@ -88,7 +89,7 @@ const AssistantCard = memo<AssistantCardProps>(
88
89
  );
89
90
 
90
91
  return (
91
- <Flexbox className={cx(styles.container, className)} gap={24} {...rest}>
92
+ <Flexbox className={cx(styles.container, className)} gap={24} style={style}>
92
93
  {!isCompact && <CardBanner avatar={avatar} />}
93
94
  <Flexbox gap={12} padding={16}>
94
95
  <Flexbox
@@ -1,9 +1,9 @@
1
1
  import { ModelIcon } from '@lobehub/icons';
2
2
  import { Typography } from 'antd';
3
3
  import { createStyles } from 'antd-style';
4
- import { memo } from 'react';
4
+ import { CSSProperties, memo } from 'react';
5
5
  import { useTranslation } from 'react-i18next';
6
- import { Flexbox, FlexboxProps } from 'react-layout-kit';
6
+ import { Flexbox } from 'react-layout-kit';
7
7
 
8
8
  import { DiscoverModelItem } from '@/types/discover';
9
9
 
@@ -67,17 +67,19 @@ const useStyles = createStyles(({ css, token, isDarkMode }) => ({
67
67
  `,
68
68
  }));
69
69
 
70
- export interface ModelCardProps extends DiscoverModelItem, FlexboxProps {
70
+ export interface ModelCardProps extends DiscoverModelItem {
71
+ className?: string;
71
72
  showCategory?: boolean;
73
+ style?: CSSProperties;
72
74
  }
73
75
 
74
- const ModelCard = memo<ModelCardProps>(({ className, meta, identifier, ...rest }) => {
76
+ const ModelCard = memo<ModelCardProps>(({ className, meta, identifier, style }) => {
75
77
  const { description, title, functionCall, vision, contextWindowTokens } = meta;
76
78
  const { t } = useTranslation('models');
77
79
  const { cx, styles } = useStyles();
78
80
 
79
81
  return (
80
- <Flexbox className={cx(styles.container, className)} gap={24} key={identifier} {...rest}>
82
+ <Flexbox className={cx(styles.container, className)} gap={24} key={identifier} style={style}>
81
83
  <Flexbox
82
84
  gap={12}
83
85
  padding={16}
@@ -4,8 +4,8 @@ import { createStyles } from 'antd-style';
4
4
  import { startCase } from 'lodash-es';
5
5
  import dynamic from 'next/dynamic';
6
6
  import qs from 'query-string';
7
- import { memo } from 'react';
8
- import { Center, Flexbox, FlexboxProps } from 'react-layout-kit';
7
+ import { CSSProperties, memo } from 'react';
8
+ import { Center, Flexbox } from 'react-layout-kit';
9
9
  import urlJoin from 'url-join';
10
10
 
11
11
  import { DiscoverPlugintem } from '@/types/discover';
@@ -64,21 +64,22 @@ const useStyles = createStyles(({ css, token, isDarkMode }) => ({
64
64
  }));
65
65
 
66
66
  interface PluginCardProps
67
- extends Omit<DiscoverPlugintem, 'manifest' | 'suggestions' | 'socialData'>,
68
- Omit<FlexboxProps, 'children'> {
67
+ extends Omit<DiscoverPlugintem, 'manifest' | 'suggestions' | 'socialData'> {
68
+ className?: string;
69
69
  showCategory?: boolean;
70
+ style?: CSSProperties;
70
71
  variant?: 'default' | 'compact';
71
72
  }
72
73
 
73
74
  const PluginCard = memo<PluginCardProps>(
74
- ({ className, showCategory, meta, createdAt, author, variant, ...rest }) => {
75
+ ({ className, showCategory, meta, createdAt, author, variant, style }) => {
75
76
  const { avatar, title, description, tags = [], category } = meta;
76
77
  const categoryItem = useCategoryItem(category, 12);
77
78
  const { cx, styles, theme } = useStyles();
78
79
  const isCompact = variant === 'compact';
79
80
 
80
81
  return (
81
- <Flexbox className={cx(styles.container, className)} gap={24} {...rest}>
82
+ <Flexbox className={cx(styles.container, className)} gap={24} style={style}>
82
83
  {!isCompact && <CardBanner avatar={avatar} />}
83
84
  <Flexbox className={styles.inner} gap={12}>
84
85
  <Flexbox align={'flex-end'} gap={16} horizontal justify={'space-between'} width={'100%'}>
@@ -3,9 +3,9 @@ import { Tag } from '@lobehub/ui';
3
3
  import { Skeleton, Typography } from 'antd';
4
4
  import { createStyles } from 'antd-style';
5
5
  import dynamic from 'next/dynamic';
6
- import { memo } from 'react';
6
+ import { CSSProperties, memo } from 'react';
7
7
  import { useTranslation } from 'react-i18next';
8
- import { Flexbox, FlexboxProps } from 'react-layout-kit';
8
+ import { Flexbox } from 'react-layout-kit';
9
9
  import urlJoin from 'url-join';
10
10
 
11
11
  import { DiscoverProviderItem } from '@/types/discover';
@@ -69,17 +69,19 @@ const useStyles = createStyles(({ css, token, isDarkMode }) => ({
69
69
  `,
70
70
  }));
71
71
 
72
- export interface ProviderCardProps extends DiscoverProviderItem, FlexboxProps {
72
+ export interface ProviderCardProps extends DiscoverProviderItem {
73
+ className?: string;
73
74
  mobile?: boolean;
75
+ style?: CSSProperties;
74
76
  }
75
77
 
76
- const ProviderCard = memo<ProviderCardProps>(({ models, className, meta, identifier, ...rest }) => {
78
+ const ProviderCard = memo<ProviderCardProps>(({ models, className, meta, identifier, style }) => {
77
79
  const { description } = meta;
78
80
  const { t } = useTranslation(['discover', 'providers']);
79
81
  const { cx, styles, theme } = useStyles();
80
82
 
81
83
  return (
82
- <Flexbox className={cx(styles.container, className)} gap={24} {...rest}>
84
+ <Flexbox className={cx(styles.container, className)} gap={24} style={style}>
83
85
  <Flexbox gap={12} padding={16} width={'100%'}>
84
86
  <ProviderCombine
85
87
  provider={identifier}
@@ -10,7 +10,7 @@ import { DiscoverProviderItem } from '@/types/discover';
10
10
 
11
11
  import SearchResultCount from '../../../components/SearchResultCount';
12
12
  import Title from '../../../components/Title';
13
- import { VirtuosoList } from '../../../components/VirtuosoGridList';
13
+ import VirtuosoGridList from '../../../components/VirtuosoGridList';
14
14
  import Card from './Card';
15
15
 
16
16
  export interface ListProps {
@@ -27,7 +27,7 @@ const List = memo<ListProps>(({ searchKeywords, items = [], mobile }) => {
27
27
  return (
28
28
  <>
29
29
  <SearchResultCount count={items.length} keyword={searchKeywords} />
30
- <VirtuosoList
30
+ <VirtuosoGridList
31
31
  data={items}
32
32
  initialItemCount={6}
33
33
  itemContent={(_, item) => (
@@ -35,6 +35,7 @@ const List = memo<ListProps>(({ searchKeywords, items = [], mobile }) => {
35
35
  <Card {...item} mobile={mobile} style={{ minHeight: 'unset' }} />
36
36
  </Link>
37
37
  )}
38
+ rows={2}
38
39
  style={{
39
40
  minHeight: '75vh',
40
41
  }}
@@ -46,7 +47,7 @@ const List = memo<ListProps>(({ searchKeywords, items = [], mobile }) => {
46
47
  return (
47
48
  <>
48
49
  <Title tag={items.length}>{t('providers.list')}</Title>
49
- <VirtuosoList
50
+ <VirtuosoGridList
50
51
  data={items}
51
52
  initialItemCount={6}
52
53
  itemContent={(_, item) => (
@@ -54,6 +55,7 @@ const List = memo<ListProps>(({ searchKeywords, items = [], mobile }) => {
54
55
  <Card {...item} mobile={mobile} style={{ minHeight: 'unset' }} />
55
56
  </Link>
56
57
  )}
58
+ rows={2}
57
59
  style={{
58
60
  minHeight: '75vh',
59
61
  }}
@@ -1,24 +1,16 @@
1
- import { Grid, GridProps } from '@lobehub/ui';
2
- import { forwardRef, memo } from 'react';
3
- import { Flexbox, FlexboxProps } from 'react-layout-kit';
1
+ import { Grid } from '@lobehub/ui';
2
+ import { memo } from 'react';
3
+ import { Flexbox } from 'react-layout-kit';
4
4
  import { VirtuosoGrid, VirtuosoGridProps } from 'react-virtuoso';
5
5
 
6
6
  import { useScrollParent } from './useScrollParent';
7
7
 
8
- const GridList = forwardRef<HTMLDivElement, GridProps>((props, ref) => (
9
- <Grid gap={16} maxItemWidth={280} ref={ref} rows={4} {...props} />
10
- ));
11
-
12
- const List = forwardRef<HTMLDivElement, FlexboxProps>((props, ref) => (
13
- <Flexbox gap={16} ref={ref} {...props} />
14
- ));
15
-
16
8
  export const VirtuosoList = memo<VirtuosoGridProps<any, any>>(({ data, ...rest }) => {
17
9
  const scrollParent = useScrollParent();
18
10
  const initialItemCount = data && data?.length >= 8 ? 8 : data?.length;
19
11
  return (
20
12
  <VirtuosoGrid
21
- components={{ List: List }}
13
+ components={{ List: (props, ref) => <Flexbox gap={16} ref={ref} {...props} /> }}
22
14
  customScrollParent={scrollParent}
23
15
  data={data}
24
16
  initialItemCount={initialItemCount}
@@ -29,7 +21,7 @@ export const VirtuosoList = memo<VirtuosoGridProps<any, any>>(({ data, ...rest }
29
21
  });
30
22
 
31
23
  const VirtuosoGridList = memo<VirtuosoGridProps<any, any>>(
32
- ({ data, initialItemCount, ...rest }) => {
24
+ ({ data, initialItemCount, rows = 4, ...rest }) => {
33
25
  const scrollParent = useScrollParent();
34
26
  const count = data && data?.length >= 8 ? 8 : data?.length;
35
27
  const maxInitialItemCount =
@@ -38,7 +30,11 @@ const VirtuosoGridList = memo<VirtuosoGridProps<any, any>>(
38
30
  : initialItemCount;
39
31
  return (
40
32
  <VirtuosoGrid
41
- components={{ List: GridList }}
33
+ components={{
34
+ List: (props, ref) => (
35
+ <Grid gap={16} maxItemWidth={280} ref={ref} rows={rows} {...props} />
36
+ ),
37
+ }}
42
38
  customScrollParent={scrollParent}
43
39
  data={data}
44
40
  initialItemCount={maxInitialItemCount || count}
@@ -37,7 +37,12 @@ const ModelFeatureTags = memo<TagsProps>(({ children, tokens, vision, functionCa
37
37
  return (
38
38
  <Flexbox align={'center'} gap={4} horizontal wrap={'wrap'} {...rest}>
39
39
  {tokens && (
40
- <Tooltip overlayStyle={{ pointerEvents: 'none' }} title={t('models.contentLength')}>
40
+ <Tooltip
41
+ styles={{
42
+ root: { pointerEvents: 'none' },
43
+ }}
44
+ title={t('models.contentLength')}
45
+ >
41
46
  <Tag bordered={false} className={styles.token} style={{ flex: 'none', margin: 0 }}>
42
47
  {formatTokenNumber(tokens)}
43
48
  </Tag>
@@ -45,7 +50,9 @@ const ModelFeatureTags = memo<TagsProps>(({ children, tokens, vision, functionCa
45
50
  )}
46
51
  {vision && (
47
52
  <Tooltip
48
- overlayStyle={{ pointerEvents: 'none' }}
53
+ styles={{
54
+ root: { pointerEvents: 'none' },
55
+ }}
49
56
  title={t('ModelSelect.featureTag.vision', { ns: 'components' })}
50
57
  >
51
58
  <Tag
@@ -58,7 +65,9 @@ const ModelFeatureTags = memo<TagsProps>(({ children, tokens, vision, functionCa
58
65
  )}
59
66
  {functionCall && (
60
67
  <Tooltip
61
- overlayStyle={{ maxWidth: 'unset', pointerEvents: 'none' }}
68
+ styles={{
69
+ root: { maxWidth: 'unset', pointerEvents: 'none' },
70
+ }}
62
71
  title={t('ModelSelect.featureTag.functionCall', { ns: 'components' })}
63
72
  >
64
73
  <Tag
@@ -76,7 +76,7 @@ const ModelFetcher = memo<ModelFetcherProps>(({ provider }) => {
76
76
  )}
77
77
  </div>
78
78
  <Tooltip
79
- overlayStyle={{ pointerEvents: 'none' }}
79
+ styles={{ root: { pointerEvents: 'none' } }}
80
80
  title={
81
81
  latestFetchTime
82
82
  ? t('llm.fetcher.latestTime', {
@@ -51,9 +51,9 @@ const OptionRender = memo<OptionRenderProps>(({ displayName, id, provider, isAzu
51
51
  </Flexbox>
52
52
  {removed && (
53
53
  <Tooltip
54
- overlayStyle={{ maxWidth: 300 }}
55
54
  placement={'top'}
56
55
  style={{ pointerEvents: 'none' }}
56
+ styles={{ root: { maxWidth: 300 } }}
57
57
  title={t('ModelSelect.removed')}
58
58
  >
59
59
  <ActionIcon icon={Recycle} style={{ color: theme.colorWarning }} />
@@ -37,7 +37,9 @@ const EmbeddingStatus = memo<EmbeddingStatusProps>(
37
37
  return (
38
38
  <Flexbox horizontal>
39
39
  <Tooltip
40
- overlayStyle={{ pointerEvents: 'none' }}
40
+ styles={{
41
+ root: { pointerEvents: 'none' },
42
+ }}
41
43
  title={t('FileParsingStatus.chunks.embeddingStatus.processing')}
42
44
  >
43
45
  <Tag
@@ -57,7 +59,9 @@ const EmbeddingStatus = memo<EmbeddingStatusProps>(
57
59
  case AsyncTaskStatus.Error: {
58
60
  return (
59
61
  <Tooltip
60
- overlayStyle={{ maxWidth: 340, pointerEvents: 'none' }}
62
+ styles={{
63
+ root: { maxWidth: 340, pointerEvents: 'none' },
64
+ }}
61
65
  title={
62
66
  <Flexbox gap={4}>
63
67
  {t('FileParsingStatus.chunks.embeddingStatus.errorResult')}
@@ -91,7 +95,7 @@ const EmbeddingStatus = memo<EmbeddingStatusProps>(
91
95
  return (
92
96
  <Flexbox horizontal>
93
97
  <Tooltip
94
- overlayStyle={{ pointerEvents: 'none' }}
98
+ styles={{ root: { pointerEvents: 'none' } }}
95
99
  title={t('FileParsingStatus.chunks.embeddingStatus.success')}
96
100
  >
97
101
  <Tag
@@ -54,7 +54,7 @@ const FileParsingStatus = memo<FileParsingStatusProps>(
54
54
  case AsyncTaskStatus.Processing: {
55
55
  return (
56
56
  <Tooltip
57
- overlayStyle={{ pointerEvents: 'none' }}
57
+ styles={{ root: { pointerEvents: 'none' } }}
58
58
  title={t('FileParsingStatus.chunks.status.processingTip')}
59
59
  >
60
60
  <Tag
@@ -73,7 +73,7 @@ const FileParsingStatus = memo<FileParsingStatusProps>(
73
73
  case AsyncTaskStatus.Error: {
74
74
  return (
75
75
  <Tooltip
76
- overlayStyle={{ maxWidth: 340, pointerEvents: 'none' }}
76
+ styles={{ root: { maxWidth: 340, pointerEvents: 'none' } }}
77
77
  title={
78
78
  <Flexbox gap={4}>
79
79
  {t('FileParsingStatus.chunks.status.errorResult')}
@@ -109,7 +109,7 @@ const FileParsingStatus = memo<FileParsingStatusProps>(
109
109
  return (
110
110
  <Flexbox horizontal>
111
111
  <Tooltip
112
- overlayStyle={{ pointerEvents: 'none' }}
112
+ styles={{ root: { pointerEvents: 'none' } }}
113
113
  title={t('FileParsingStatus.chunks.embeddingStatus.empty')}
114
114
  >
115
115
  <Tag
@@ -74,8 +74,8 @@ export const ModelInfoTags = memo<ModelInfoTagsProps>(
74
74
  <Flexbox direction={directionReverse ? 'horizontal-reverse' : 'horizontal'} gap={4}>
75
75
  {model.files && (
76
76
  <Tooltip
77
- overlayStyle={{ pointerEvents: 'none' }}
78
77
  placement={placement}
78
+ styles={{ root: { pointerEvents: 'none' } }}
79
79
  title={t('ModelSelect.featureTag.file')}
80
80
  >
81
81
  <div className={cx(styles.tag, styles.tagGreen)} style={{ cursor: 'pointer' }} title="">
@@ -85,8 +85,8 @@ export const ModelInfoTags = memo<ModelInfoTagsProps>(
85
85
  )}
86
86
  {model.vision && (
87
87
  <Tooltip
88
- overlayStyle={{ pointerEvents: 'none' }}
89
88
  placement={placement}
89
+ styles={{ root: { pointerEvents: 'none' } }}
90
90
  title={t('ModelSelect.featureTag.vision')}
91
91
  >
92
92
  <div className={cx(styles.tag, styles.tagGreen)} style={{ cursor: 'pointer' }} title="">
@@ -96,8 +96,10 @@ export const ModelInfoTags = memo<ModelInfoTagsProps>(
96
96
  )}
97
97
  {model.functionCall && (
98
98
  <Tooltip
99
- overlayStyle={{ maxWidth: 'unset', pointerEvents: 'none' }}
100
99
  placement={placement}
100
+ styles={{
101
+ root: { maxWidth: 'unset', pointerEvents: 'none' },
102
+ }}
101
103
  title={t('ModelSelect.featureTag.functionCall')}
102
104
  >
103
105
  <div className={cx(styles.tag, styles.tagBlue)} style={{ cursor: 'pointer' }} title="">
@@ -107,8 +109,10 @@ export const ModelInfoTags = memo<ModelInfoTagsProps>(
107
109
  )}
108
110
  {typeof model.contextWindowTokens === 'number' && (
109
111
  <Tooltip
110
- overlayStyle={{ maxWidth: 'unset', pointerEvents: 'none' }}
111
112
  placement={placement}
113
+ styles={{
114
+ root: { maxWidth: 'unset', pointerEvents: 'none' },
115
+ }}
112
116
  title={t('ModelSelect.featureTag.tokens', {
113
117
  tokens:
114
118
  model.contextWindowTokens === 0
@@ -116,6 +116,9 @@ const TipGuide: FC<TipGuideProps> = ({
116
116
  >
117
117
  <Popover
118
118
  arrow={{ pointAtCenter: true }}
119
+ classNames={{
120
+ root: cx(className, styles.overlay),
121
+ }}
119
122
  color={'blue'}
120
123
  content={
121
124
  <Flexbox gap={24} horizontal style={{ userSelect: 'none' }}>
@@ -131,9 +134,10 @@ const TipGuide: FC<TipGuideProps> = ({
131
134
  </Flexbox>
132
135
  }
133
136
  open={open}
134
- overlayClassName={cx(className, styles.overlay)}
135
- overlayStyle={{ maxWidth, zIndex: 1000, ...style }}
136
137
  placement={placement}
138
+ styles={{
139
+ root: { maxWidth, zIndex: 1000, ...style },
140
+ }}
137
141
  trigger="hover"
138
142
  >
139
143
  {children}
@@ -40,8 +40,10 @@ const Clear = memo(() => {
40
40
  >
41
41
  <ActionIcon
42
42
  icon={Eraser}
43
- overlayStyle={{ maxWidth: 'none' }}
44
43
  placement={'bottom'}
44
+ styles={{
45
+ root: { maxWidth: 'none' },
46
+ }}
45
47
  title={actionTitle}
46
48
  />
47
49
  </Popconfirm>
@@ -75,7 +75,7 @@ const Token = memo<TokenTagProps>(({ total: messageString }) => {
75
75
  <Flexbox align={'center'} gap={4} horizontal justify={'space-between'} width={'100%'}>
76
76
  <div style={{ color: theme.colorTextDescription }}>{t('tokenDetails.title')}</div>
77
77
  <Tooltip
78
- overlayStyle={{ maxWidth: 'unset', pointerEvents: 'none' }}
78
+ styles={{ root: { maxWidth: 'unset', pointerEvents: 'none' } }}
79
79
  title={t('ModelSelect.featureTag.tokens', {
80
80
  ns: 'components',
81
81
  tokens: numeral(maxTokens).format('0,0'),
@@ -162,7 +162,9 @@ const FileRenderItem = memo<FileRenderItemProps>(
162
162
  {isCreatingFileParseTask || isNull(chunkingStatus) || !chunkingStatus ? (
163
163
  <div className={isCreatingFileParseTask ? undefined : styles.hover}>
164
164
  <Tooltip
165
- overlayStyle={{ pointerEvents: 'none' }}
165
+ styles={{
166
+ root: { pointerEvents: 'none' },
167
+ }}
166
168
  title={t(
167
169
  isSupportedForChunking
168
170
  ? 'FileManager.actions.chunkingTooltip'
@@ -3,7 +3,7 @@
3
3
  import { Icon, Tooltip } from '@lobehub/ui';
4
4
  import { Badge } from 'antd';
5
5
  import { createStyles } from 'antd-style';
6
- import { isNumber, isUndefined } from 'lodash-es';
6
+ import { isUndefined } from 'lodash-es';
7
7
  import { LoaderCircle } from 'lucide-react';
8
8
  import { memo, useMemo } from 'react';
9
9
  import { useTranslation } from 'react-i18next';
@@ -14,6 +14,7 @@ import { messageService } from '@/services/message';
14
14
  import { sessionService } from '@/services/session';
15
15
  import { topicService } from '@/services/topic';
16
16
  import { useServerConfigStore } from '@/store/serverConfig';
17
+ import { formatShortenNumber } from '@/utils/format';
17
18
  import { today } from '@/utils/time';
18
19
 
19
20
  const useStyles = createStyles(({ css, token }) => ({
@@ -42,23 +43,6 @@ const useStyles = createStyles(({ css, token }) => ({
42
43
  `,
43
44
  }));
44
45
 
45
- const formatNumber = (num: any) => {
46
- if (!isNumber(num)) return num;
47
- // 使用Intl.NumberFormat来添加千分号
48
- const formattedWithComma = new Intl.NumberFormat('en-US').format(num);
49
-
50
- // 格式化为 K 或 M
51
- if (num >= 10_000_000) {
52
- return (num / 1_000_000).toFixed(1) + 'M';
53
- } else if (num >= 10_000) {
54
- return (num / 1000).toFixed(1) + 'K';
55
- } else if (num === 0) {
56
- return 0;
57
- } else {
58
- return formattedWithComma;
59
- }
60
- };
61
-
62
46
  const DataStatistics = memo<Omit<FlexboxProps, 'children'>>(({ style, ...rest }) => {
63
47
  const mobile = useServerConfigStore((s) => s.isMobile);
64
48
  // sessions
@@ -128,7 +112,7 @@ const DataStatistics = memo<Omit<FlexboxProps, 'children'>>(({ style, ...rest })
128
112
  key={item.key}
129
113
  >
130
114
  <Flexbox gap={2}>
131
- <div className={styles.count}>{formatNumber(item.count)}</div>
115
+ <div className={styles.count}>{formatShortenNumber(item.count)}</div>
132
116
  <div className={styles.title}>{item.title}</div>
133
117
  </Flexbox>
134
118
  {showBadge && (
@@ -150,7 +134,7 @@ const DataStatistics = memo<Omit<FlexboxProps, 'children'>>(({ style, ...rest })
150
134
  return (
151
135
  <Flexbox className={styles.card} flex={1} gap={2} key={item.key}>
152
136
  <Flexbox horizontal>
153
- <div className={styles.count}>{formatNumber(item.count)}</div>
137
+ <div className={styles.count}>{formatShortenNumber(item.count)}</div>
154
138
  </Flexbox>
155
139
  <div className={styles.title}>{item.title}</div>
156
140
  </Flexbox>
@@ -39,10 +39,12 @@ const LangButton = memo<{ placement?: PopoverProps['placement'] }>(({ placement
39
39
  <Popover
40
40
  arrow={false}
41
41
  content={<Menu items={items} selectable selectedKeys={[language]} />}
42
- overlayInnerStyle={{
43
- padding: 0,
44
- }}
45
42
  placement={placement}
43
+ styles={{
44
+ body: {
45
+ padding: 0,
46
+ },
47
+ }}
46
48
  trigger={['click', 'hover']}
47
49
  >
48
50
  <ActionIcon
@@ -52,10 +52,12 @@ const ThemeButton = memo<{ placement?: PopoverProps['placement'] }>(({ placement
52
52
  <Popover
53
53
  arrow={false}
54
54
  content={<Menu items={items} selectable selectedKeys={[themeMode]} />}
55
- overlayInnerStyle={{
56
- padding: 0,
57
- }}
58
55
  placement={placement}
56
+ styles={{
57
+ body: {
58
+ padding: 0,
59
+ },
60
+ }}
59
61
  trigger={['click', 'hover']}
60
62
  >
61
63
  <ActionIcon
@@ -27,9 +27,11 @@ const UserPanel = memo<PropsWithChildren>(({ children }) => {
27
27
  content={<PanelContent closePopover={() => setOpen(false)} />}
28
28
  onOpenChange={setOpen}
29
29
  open={open}
30
- overlayInnerStyle={{ padding: 0 }}
31
30
  placement={'topRight'}
32
31
  rootClassName={styles.popover}
32
+ styles={{
33
+ body: { padding: 0 },
34
+ }}
33
35
  trigger={['click']}
34
36
  >
35
37
  {children}
@@ -16,7 +16,6 @@ import {
16
16
  formatTokenNumber,
17
17
  } from './format';
18
18
 
19
- // 保留你已经编写的测试用例
20
19
  describe('format', () => {
21
20
  describe('formatSize', () => {
22
21
  it('should format bytes to KB correctly', () => {
@@ -128,10 +127,13 @@ describe('format', () => {
128
127
  expect(formatShortenNumber(9999)).toBe('9,999');
129
128
  });
130
129
 
131
- it('should format numbers between 10,000 and 9,999,999 correctly', () => {
130
+ it('should format numbers between 10,000 and 999,999 correctly', () => {
132
131
  expect(formatShortenNumber(10000)).toBe('10.0K');
133
132
  expect(formatShortenNumber(123456)).toBe('123.5K');
134
- expect(formatShortenNumber(9999999)).toBe('10000.0K');
133
+ expect(formatShortenNumber(998000)).toBe('998.0K');
134
+ expect(formatShortenNumber(999999)).toBe('1000.0K');
135
+ expect(formatShortenNumber(1000000)).toBe('1.0M');
136
+ expect(formatShortenNumber(9999999)).toBe('10.0M');
135
137
  });
136
138
 
137
139
  it('should format numbers 10,000,000 and above correctly', () => {
@@ -69,7 +69,7 @@ export const formatShortenNumber = (num: any) => {
69
69
  const formattedWithComma = new Intl.NumberFormat('en-US').format(num);
70
70
 
71
71
  // 格式化为 K 或 M
72
- if (num >= 10_000_000) {
72
+ if (num >= 1_000_000) {
73
73
  return (num / 1_000_000).toFixed(1) + 'M';
74
74
  } else if (num >= 10_000) {
75
75
  return (num / 1000).toFixed(1) + 'K';