@lobehub/lobehub 2.0.0-next.384 → 2.0.0-next.385
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 +25 -0
- package/changelog/v1.json +9 -0
- package/docs/self-hosting/advanced/knowledge-base.mdx +1 -1
- package/docs/self-hosting/advanced/knowledge-base.zh-CN.mdx +1 -1
- package/docs/self-hosting/migration/v2/breaking-changes.mdx +8 -0
- package/docs/self-hosting/migration/v2/breaking-changes.zh-CN.mdx +8 -0
- package/docs/self-hosting/server-database/docker-compose.mdx +1 -1
- package/docs/self-hosting/server-database/docker-compose.zh-CN.mdx +1 -1
- package/docs/self-hosting/server-database/docker.mdx +2 -8
- package/docs/self-hosting/server-database/docker.zh-CN.mdx +2 -9
- package/locales/en-US/error.json +10 -3
- package/locales/zh-CN/error.json +10 -3
- package/package.json +1 -1
- package/packages/database/src/models/topicShare.ts +9 -1
- package/packages/model-bank/src/modelProviders/anthropic.ts +1 -1
- package/packages/model-bank/src/modelProviders/google.ts +1 -1
- package/packages/model-bank/src/modelProviders/hunyuan.ts +1 -1
- package/packages/model-bank/src/modelProviders/minimax.ts +1 -1
- package/packages/model-bank/src/modelProviders/openai.ts +1 -1
- package/packages/model-bank/src/modelProviders/siliconcloud.ts +3 -2
- package/packages/model-bank/src/modelProviders/vertexai.ts +1 -1
- package/packages/model-bank/src/modelProviders/volcengine.ts +1 -1
- package/packages/model-bank/src/modelProviders/xai.ts +1 -1
- package/packages/model-runtime/src/types/chat.ts +14 -0
- package/src/app/[variants]/(main)/image/_layout/ConfigPanel/components/ModelSelect/ImageModelItem.tsx +31 -9
- package/src/app/[variants]/(main)/image/_layout/ConfigPanel/components/ModelSelect/index.tsx +9 -2
- package/src/app/[variants]/(main)/settings/provider/features/ProviderConfig/Checker.tsx +33 -4
- package/src/features/Conversation/Messages/Assistant/Extra/index.tsx +18 -12
- package/src/features/Conversation/Messages/User/Extra.tsx +5 -1
- package/src/features/IntegrationDetailModal/IntegrationDetailContent.tsx +11 -12
- package/src/features/SharePopover/index.tsx +44 -5
- package/src/layout/GlobalProvider/useUserStateRedirect.ts +7 -1
- package/src/locales/default/chat.ts +1 -0
- package/src/locales/default/error.ts +10 -3
- package/src/store/global/initialState.ts +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,31 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
## [Version 2.0.0-next.385](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.384...v2.0.0-next.385)
|
|
6
|
+
|
|
7
|
+
<sup>Released on **2026-01-26**</sup>
|
|
8
|
+
|
|
9
|
+
#### ✨ Features
|
|
10
|
+
|
|
11
|
+
- **misc**: Share page improvements and pg17 docs update.
|
|
12
|
+
|
|
13
|
+
<br/>
|
|
14
|
+
|
|
15
|
+
<details>
|
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
17
|
+
|
|
18
|
+
#### What's improved
|
|
19
|
+
|
|
20
|
+
- **misc**: Share page improvements and pg17 docs update, closes [#11850](https://github.com/lobehub/lobe-chat/issues/11850) ([5b953b1](https://github.com/lobehub/lobe-chat/commit/5b953b1))
|
|
21
|
+
|
|
22
|
+
</details>
|
|
23
|
+
|
|
24
|
+
<div align="right">
|
|
25
|
+
|
|
26
|
+
[](#readme-top)
|
|
27
|
+
|
|
28
|
+
</div>
|
|
29
|
+
|
|
5
30
|
## [Version 2.0.0-next.384](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.383...v2.0.0-next.384)
|
|
6
31
|
|
|
7
32
|
<sup>Released on **2026-01-26**</sup>
|
package/changelog/v1.json
CHANGED
|
@@ -27,7 +27,7 @@ PostgreSQL is a powerful open-source relational database system, and PGVector is
|
|
|
27
27
|
Deployment script example:
|
|
28
28
|
|
|
29
29
|
```
|
|
30
|
-
docker run -p 5432:5432 -d --name pg -e POSTGRES_PASSWORD=mysecretpassword pgvector/pgvector:
|
|
30
|
+
docker run -p 5432:5432 -d --name pg -e POSTGRES_PASSWORD=mysecretpassword pgvector/pgvector:pg17
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
- **Note**: Ensure sufficient resources for vector operations
|
|
@@ -25,7 +25,7 @@ PostgreSQL 是一个强大的开源关系型数据库系统,而 PGVector 是
|
|
|
25
25
|
示例部署脚本:
|
|
26
26
|
|
|
27
27
|
```
|
|
28
|
-
docker run -p 5432:5432 -d --name pg -e POSTGRES_PASSWORD=mysecretpassword pgvector/pgvector:
|
|
28
|
+
docker run -p 5432:5432 -d --name pg -e POSTGRES_PASSWORD=mysecretpassword pgvector/pgvector:pg17
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
- **注意事项**:确保分配足够的资源以处理向量操作
|
|
@@ -71,3 +71,11 @@ See the [Clerk Migration Guide](/docs/self-hosting/advanced/auth/clerk-to-better
|
|
|
71
71
|
LobeHub 2.0 only supports Server DB mode. Client DB (PGlite) is no longer supported. If you were using `NEXT_PUBLIC_SERVICE_MODE=client`, you need to migrate to Server DB deployment.
|
|
72
72
|
|
|
73
73
|
For deployment guides, see [Server Database Deployment](/docs/self-hosting/server-database).
|
|
74
|
+
|
|
75
|
+
## PostgreSQL Version Requirements
|
|
76
|
+
|
|
77
|
+
LobeHub 2.0 recommends using **PostgreSQL 17** or higher.
|
|
78
|
+
|
|
79
|
+
This is because LobeHub 2.0 uses the [pg\_search](https://github.com/paradedb/paradedb/tree/main/pg_search) extension for full-text search capabilities. If you use Serverless Postgres services like Neon, the pg\_search extension is only available on PostgreSQL 17.
|
|
80
|
+
|
|
81
|
+
If you self-host your database with Docker, we recommend using the `pgvector/pgvector:pg17` image.
|
|
@@ -69,3 +69,11 @@ LobeHub 2.0 仅支持 Better Auth 认证系统,不再支持 NextAuth 和 Clerk
|
|
|
69
69
|
LobeHub 2.0 仅支持 Server DB 模式,不再支持 Client DB (PGlite)。如果您之前使用 `NEXT_PUBLIC_SERVICE_MODE=client`,需要迁移到 Server DB 部署方式。
|
|
70
70
|
|
|
71
71
|
详细部署指南请参阅[服务端数据库部署](/docs/self-hosting/server-database)。
|
|
72
|
+
|
|
73
|
+
## PostgreSQL 版本要求
|
|
74
|
+
|
|
75
|
+
LobeHub 2.0 推荐使用 **PostgreSQL 17** 及以上版本。
|
|
76
|
+
|
|
77
|
+
这是因为 LobeHub 2.0 使用了 [pg\_search](https://github.com/paradedb/paradedb/tree/main/pg_search) 插件来提供全文搜索能力。如果您使用 Neon 等 Serverless Postgres 服务,pg\_search 插件仅在 PostgreSQL 17 上可用。
|
|
78
|
+
|
|
79
|
+
如果您使用 Docker 自建数据库,推荐使用 `pgvector/pgvector:pg17` 镜像。
|
|
@@ -28,12 +28,6 @@ tags:
|
|
|
28
28
|
Database](/docs/self-hosting/server-database) first.
|
|
29
29
|
</Callout>
|
|
30
30
|
|
|
31
|
-
<Callout type="warning">
|
|
32
|
-
Due to the inability to expose `NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY` using Docker environment variables, you cannot use Clerk as an authentication service when deploying LobeHub using Docker / Docker Compose.
|
|
33
|
-
|
|
34
|
-
If you do need Clerk as an authentication service, you might consider deploying using Vercel or building your own image.
|
|
35
|
-
</Callout>
|
|
36
|
-
|
|
37
31
|
## Deploying on a Linux Server
|
|
38
32
|
|
|
39
33
|
Here is the process for deploying the LobeHub server database version on a Linux server:
|
|
@@ -46,10 +40,10 @@ Here is the process for deploying the LobeHub server database version on a Linux
|
|
|
46
40
|
```sh
|
|
47
41
|
docker network create pg
|
|
48
42
|
|
|
49
|
-
docker run --name my-postgres --network pg -e POSTGRES_PASSWORD=mysecretpassword -p 5432:5432 -d pgvector/pgvector:
|
|
43
|
+
docker run --name my-postgres --network pg -e POSTGRES_PASSWORD=mysecretpassword -p 5432:5432 -d pgvector/pgvector:pg17
|
|
50
44
|
```
|
|
51
45
|
|
|
52
|
-
The above command will create a PG instance named `my-postgres` on the network `pg`, where `pgvector/pgvector:
|
|
46
|
+
The above command will create a PG instance named `my-postgres` on the network `pg`, where `pgvector/pgvector:pg17` is a Postgres 17 image with the pgvector plugin installed by default.
|
|
53
47
|
|
|
54
48
|
<Callout type="info">
|
|
55
49
|
The pgvector plugin provides vector search capabilities for Postgres, which is an important
|
|
@@ -26,13 +26,6 @@ tags:
|
|
|
26
26
|
存储服务](/zh/docs/self-hosting/advanced/s3/tencent-cloud)。
|
|
27
27
|
</Callout>
|
|
28
28
|
|
|
29
|
-
<Callout type="warning">
|
|
30
|
-
由于无法使用 Docker 环境变量暴露 `NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY`,使用 Docker / Docker Compose
|
|
31
|
-
部署 LobeHub 时,你不能使用 Clerk 作为登录鉴权服务。
|
|
32
|
-
|
|
33
|
-
如果你确实需要 Clerk 作为登录鉴权服务,你可以考虑使用 Vercel 部署或者自行构建镜像。
|
|
34
|
-
</Callout>
|
|
35
|
-
|
|
36
29
|
## 在 Linux 服务器上部署
|
|
37
30
|
|
|
38
31
|
以下是在 Linux 服务器上部署 LobeHub DB 版的流程:
|
|
@@ -45,10 +38,10 @@ tags:
|
|
|
45
38
|
```sh
|
|
46
39
|
docker network create pg
|
|
47
40
|
|
|
48
|
-
docker run --name my-postgres --network pg -e POSTGRES_PASSWORD=mysecretpassword -p 5432:5432 -d pgvector/pgvector:
|
|
41
|
+
docker run --name my-postgres --network pg -e POSTGRES_PASSWORD=mysecretpassword -p 5432:5432 -d pgvector/pgvector:pg17
|
|
49
42
|
```
|
|
50
43
|
|
|
51
|
-
上述指令会创建一个名为 `my-postgres`,并且网络为 `pg` 的 PG 实例,其中 `pgvector/pgvector:
|
|
44
|
+
上述指令会创建一个名为 `my-postgres`,并且网络为 `pg` 的 PG 实例,其中 `pgvector/pgvector:pg17` 是一个 Postgres 17 的镜像,且默认安装了 pgvector 插件。
|
|
52
45
|
|
|
53
46
|
<Callout type="info">
|
|
54
47
|
pgvector 插件为 Postgres 提供了向量搜索的能力,是 LobeHub 实现 RAG 的重要构件之一。
|
package/locales/en-US/error.json
CHANGED
|
@@ -9,11 +9,18 @@
|
|
|
9
9
|
"import.importConfigFile.title": "Import Failed",
|
|
10
10
|
"import.incompatible.description": "This file was exported from a higher version. Please try upgrading to the latest version and then re-importing.",
|
|
11
11
|
"import.incompatible.title": "Current application does not support importing this file",
|
|
12
|
+
"inviteCode.continue": "Continue",
|
|
12
13
|
"inviteCode.currentEmail": "Current account: {{email}}",
|
|
13
14
|
"inviteCode.desc": "An invite code is required to access LobeHub. Please enter a valid invite code to continue.",
|
|
14
|
-
"inviteCode.friends": "
|
|
15
|
-
"inviteCode.
|
|
16
|
-
"inviteCode.
|
|
15
|
+
"inviteCode.friends": "Ask a friend",
|
|
16
|
+
"inviteCode.joinUsOn": "Join us on",
|
|
17
|
+
"inviteCode.lookingForInvite": "Looking for an invite?",
|
|
18
|
+
"inviteCode.notYou": "Not you?",
|
|
19
|
+
"inviteCode.openingInStages": "is opening in stages.",
|
|
20
|
+
"inviteCode.placeholder": "Invite code or link",
|
|
21
|
+
"inviteCode.pleaseEnterCode": "Enter your invite code to continue.",
|
|
22
|
+
"inviteCode.switchAccount": "Switch account",
|
|
23
|
+
"inviteCode.title": "You're Almost In",
|
|
17
24
|
"loginRequired.desc": "You will be redirected to the login page shortly",
|
|
18
25
|
"loginRequired.title": "Please log in to use this feature",
|
|
19
26
|
"notFound.backHome": "Back to Home",
|
package/locales/zh-CN/error.json
CHANGED
|
@@ -9,11 +9,18 @@
|
|
|
9
9
|
"import.importConfigFile.title": "导入遇到了问题",
|
|
10
10
|
"import.incompatible.description": "该文件由更高版本导出。请升级到最新版后再导入",
|
|
11
11
|
"import.incompatible.title": "版本不兼容",
|
|
12
|
+
"inviteCode.continue": "继续",
|
|
12
13
|
"inviteCode.currentEmail": "当前账号:{{email}}",
|
|
13
14
|
"inviteCode.desc": "需要邀请码才能访问 LobeHub。请输入有效的邀请码以继续。",
|
|
14
|
-
"inviteCode.friends": "
|
|
15
|
-
"inviteCode.
|
|
16
|
-
"inviteCode.
|
|
15
|
+
"inviteCode.friends": "问问好友",
|
|
16
|
+
"inviteCode.joinUsOn": "关注我们",
|
|
17
|
+
"inviteCode.lookingForInvite": "需要邀请码?",
|
|
18
|
+
"inviteCode.notYou": "不是你?",
|
|
19
|
+
"inviteCode.openingInStages": "正在分阶段开放中。",
|
|
20
|
+
"inviteCode.placeholder": "输入邀请码或链接",
|
|
21
|
+
"inviteCode.pleaseEnterCode": "请输入邀请码以继续。",
|
|
22
|
+
"inviteCode.switchAccount": "切换账号",
|
|
23
|
+
"inviteCode.title": "即将完成",
|
|
17
24
|
"loginRequired.desc": "将为你跳转到登录页。登录后即可继续",
|
|
18
25
|
"loginRequired.title": "需要登录后继续",
|
|
19
26
|
"notFound.backHome": "返回首页",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobehub/lobehub",
|
|
3
|
-
"version": "2.0.0-next.
|
|
3
|
+
"version": "2.0.0-next.385",
|
|
4
4
|
"description": "LobeHub - an open-source,comprehensive AI Agent 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",
|
|
@@ -19,8 +19,9 @@ export class TopicShareModel {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
|
-
* Create
|
|
22
|
+
* Create or get existing share for a topic.
|
|
23
23
|
* Each topic can only have one share record (enforced by unique constraint).
|
|
24
|
+
* If record already exists, returns the existing one.
|
|
24
25
|
*/
|
|
25
26
|
create = async (topicId: string, visibility: ShareVisibility = 'private') => {
|
|
26
27
|
// First verify the topic belongs to the user
|
|
@@ -39,8 +40,14 @@ export class TopicShareModel {
|
|
|
39
40
|
userId: this.userId,
|
|
40
41
|
visibility,
|
|
41
42
|
})
|
|
43
|
+
.onConflictDoNothing({ target: topicShares.topicId })
|
|
42
44
|
.returning();
|
|
43
45
|
|
|
46
|
+
// If conflict occurred, return existing record
|
|
47
|
+
if (!result) {
|
|
48
|
+
return this.getByTopicId(topicId);
|
|
49
|
+
}
|
|
50
|
+
|
|
44
51
|
return result;
|
|
45
52
|
};
|
|
46
53
|
|
|
@@ -74,6 +81,7 @@ export class TopicShareModel {
|
|
|
74
81
|
.select({
|
|
75
82
|
id: topicShares.id,
|
|
76
83
|
topicId: topicShares.topicId,
|
|
84
|
+
userId: topicShares.userId,
|
|
77
85
|
visibility: topicShares.visibility,
|
|
78
86
|
})
|
|
79
87
|
.from(topicShares)
|
|
@@ -2,7 +2,7 @@ import { type ModelProviderCard } from '@/types/llm';
|
|
|
2
2
|
|
|
3
3
|
const Anthropic: ModelProviderCard = {
|
|
4
4
|
chatModels: [],
|
|
5
|
-
checkModel: 'claude-
|
|
5
|
+
checkModel: 'claude-opus-4-5-20251101',
|
|
6
6
|
description:
|
|
7
7
|
'Anthropic builds advanced language models like Claude 3.5 Sonnet, Claude 3 Sonnet, Claude 3 Opus, and Claude 3 Haiku, balancing intelligence, speed, and cost for workloads from enterprise to rapid-response use cases.',
|
|
8
8
|
enabled: true,
|
|
@@ -3,7 +3,7 @@ import { type ModelProviderCard } from '@/types/llm';
|
|
|
3
3
|
// ref: https://ai.google.dev/gemini-api/docs/models/gemini
|
|
4
4
|
const Google: ModelProviderCard = {
|
|
5
5
|
chatModels: [],
|
|
6
|
-
checkModel: 'gemini-
|
|
6
|
+
checkModel: 'gemini-3-flash-preview',
|
|
7
7
|
description:
|
|
8
8
|
"Google's Gemini family is its most advanced general-purpose AI, built by Google DeepMind for multimodal use across text, code, images, audio, and video. It scales from data centers to mobile devices with strong efficiency and reach.",
|
|
9
9
|
enabled: true,
|
|
@@ -3,7 +3,7 @@ import { type ModelProviderCard } from '@/types/llm';
|
|
|
3
3
|
// ref https://cloud.tencent.com/document/product/1729/104753
|
|
4
4
|
const Hunyuan: ModelProviderCard = {
|
|
5
5
|
chatModels: [],
|
|
6
|
-
checkModel: 'hunyuan-
|
|
6
|
+
checkModel: 'hunyuan-t1-latest',
|
|
7
7
|
description:
|
|
8
8
|
'A Tencent-developed LLM with strong Chinese writing, solid reasoning in complex contexts, and reliable task execution.',
|
|
9
9
|
disableBrowserRequest: true,
|
|
@@ -3,7 +3,7 @@ import { type ModelProviderCard } from '@/types/llm';
|
|
|
3
3
|
// ref: https://platform.minimaxi.com/document/Models
|
|
4
4
|
const Minimax: ModelProviderCard = {
|
|
5
5
|
chatModels: [],
|
|
6
|
-
checkModel: 'MiniMax-M2',
|
|
6
|
+
checkModel: 'MiniMax-M2.1',
|
|
7
7
|
description:
|
|
8
8
|
'Founded in 2021, MiniMax builds general-purpose AI with multimodal foundation models, including trillion-parameter MoE text models, speech models, and vision models, along with apps like Hailuo AI.',
|
|
9
9
|
id: 'minimax',
|
|
@@ -4,7 +4,7 @@ import { type ModelProviderCard } from '@/types/llm';
|
|
|
4
4
|
const OpenAI: ModelProviderCard = {
|
|
5
5
|
apiKeyUrl: 'https://platform.openai.com/api-keys?utm_source=lobehub',
|
|
6
6
|
chatModels: [],
|
|
7
|
-
checkModel: 'gpt-5
|
|
7
|
+
checkModel: 'gpt-5.2',
|
|
8
8
|
description:
|
|
9
9
|
'OpenAI is a leading AI research lab whose GPT models advanced natural language processing, delivering high performance and strong value across research, business, and innovation.',
|
|
10
10
|
enabled: true,
|
|
@@ -3,8 +3,9 @@ import { type ModelProviderCard } from '@/types/llm';
|
|
|
3
3
|
// ref: https://siliconflow.cn/zh-cn/pricing
|
|
4
4
|
const SiliconCloud: ModelProviderCard = {
|
|
5
5
|
chatModels: [],
|
|
6
|
-
checkModel: 'Pro/
|
|
7
|
-
description:
|
|
6
|
+
checkModel: 'Pro/zai-org/glm-4.7',
|
|
7
|
+
description:
|
|
8
|
+
'SiliconCloud is a cost-effective GenAI cloud service built on strong open-source base models.',
|
|
8
9
|
id: 'siliconcloud',
|
|
9
10
|
modelList: { showModelFetcher: true },
|
|
10
11
|
modelsUrl: 'https://siliconflow.cn/zh-cn/models',
|
|
@@ -3,7 +3,7 @@ import { type ModelProviderCard } from '@/types/llm';
|
|
|
3
3
|
// ref: https://ai.google.dev/gemini-api/docs/models/gemini
|
|
4
4
|
const VertexAI: ModelProviderCard = {
|
|
5
5
|
chatModels: [],
|
|
6
|
-
checkModel: 'gemini-
|
|
6
|
+
checkModel: 'gemini-3-flash-preview',
|
|
7
7
|
description:
|
|
8
8
|
"Google's Gemini family is its most advanced general-purpose AI, built by Google DeepMind for multimodal use across text, code, images, audio, and video. It scales from data centers to mobile devices, improving efficiency and deployment flexibility.",
|
|
9
9
|
id: 'vertexai',
|
|
@@ -3,7 +3,7 @@ import { type ModelProviderCard } from '@/types/llm';
|
|
|
3
3
|
// ref https://www.volcengine.com/docs/82379/1330310
|
|
4
4
|
const Doubao: ModelProviderCard = {
|
|
5
5
|
chatModels: [],
|
|
6
|
-
checkModel: 'doubao-seed-1
|
|
6
|
+
checkModel: 'doubao-seed-1.8',
|
|
7
7
|
description:
|
|
8
8
|
'ByteDance’s model service platform offers secure, feature-rich, cost-competitive model access plus end-to-end tooling for data, fine-tuning, inference, and evaluation.',
|
|
9
9
|
id: 'volcengine',
|
|
@@ -3,7 +3,7 @@ import { type ModelProviderCard } from '@/types/llm';
|
|
|
3
3
|
// ref: https://x.ai/about
|
|
4
4
|
const XAI: ModelProviderCard = {
|
|
5
5
|
chatModels: [],
|
|
6
|
-
checkModel: 'grok-
|
|
6
|
+
checkModel: 'grok-4-1-fast-non-reasoning',
|
|
7
7
|
description:
|
|
8
8
|
'xAI builds AI to accelerate scientific discovery, with a mission to deepen humanity’s understanding of the universe.',
|
|
9
9
|
id: 'xai',
|
|
@@ -90,6 +90,20 @@ export interface ChatStreamPayload {
|
|
|
90
90
|
* @title List of chat messages
|
|
91
91
|
*/
|
|
92
92
|
messages: OpenAIChatMessage[];
|
|
93
|
+
/**
|
|
94
|
+
* @title Custom text chunks for mock response
|
|
95
|
+
*/
|
|
96
|
+
mockChunks?: string[];
|
|
97
|
+
/**
|
|
98
|
+
* @title Delay in milliseconds between mock chunks
|
|
99
|
+
* @default 50
|
|
100
|
+
*/
|
|
101
|
+
mockDelayMs?: number;
|
|
102
|
+
/**
|
|
103
|
+
* @title Enable mock response for benchmark testing
|
|
104
|
+
* @description When true, returns a simulated SSE stream without calling real LLM API
|
|
105
|
+
*/
|
|
106
|
+
mockResponse?: boolean;
|
|
93
107
|
/**
|
|
94
108
|
* @title Model name
|
|
95
109
|
*/
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { BRANDING_PROVIDER } from '@lobechat/business-const';
|
|
2
|
+
import { CREDITS_PER_DOLLAR } from '@lobechat/const/currency';
|
|
1
3
|
import { ModelIcon } from '@lobehub/icons';
|
|
2
4
|
import { Flexbox, Popover, Text } from '@lobehub/ui';
|
|
3
5
|
import { createStaticStyles, cx } from 'antd-style';
|
|
@@ -7,6 +9,8 @@ import { memo, useMemo } from 'react';
|
|
|
7
9
|
|
|
8
10
|
import NewModelBadge from '@/components/ModelSelect/NewModelBadge';
|
|
9
11
|
import { useIsDark } from '@/hooks/useIsDark';
|
|
12
|
+
import { useServerConfigStore } from '@/store/serverConfig';
|
|
13
|
+
import { serverConfigSelectors } from '@/store/serverConfig/selectors';
|
|
10
14
|
|
|
11
15
|
const POPOVER_MAX_WIDTH = 320;
|
|
12
16
|
|
|
@@ -38,6 +42,10 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
|
38
42
|
}));
|
|
39
43
|
|
|
40
44
|
type ImageModelItemProps = AiModelForSelect & {
|
|
45
|
+
/**
|
|
46
|
+
* Provider ID for determining price display format
|
|
47
|
+
*/
|
|
48
|
+
providerId?: string;
|
|
41
49
|
/**
|
|
42
50
|
* Whether to show new model badge
|
|
43
51
|
* @default true
|
|
@@ -55,25 +63,39 @@ const ImageModelItem = memo<ImageModelItemProps>(
|
|
|
55
63
|
approximatePricePerImage,
|
|
56
64
|
description,
|
|
57
65
|
pricePerImage,
|
|
66
|
+
providerId,
|
|
58
67
|
showPopover = true,
|
|
59
68
|
showBadge = true,
|
|
60
69
|
...model
|
|
61
70
|
}) => {
|
|
62
71
|
const isDarkMode = useIsDark();
|
|
72
|
+
const enableBusinessFeatures = useServerConfigStore(
|
|
73
|
+
serverConfigSelectors.enableBusinessFeatures,
|
|
74
|
+
);
|
|
63
75
|
|
|
64
76
|
const priceLabel = useMemo(() => {
|
|
65
|
-
//
|
|
66
|
-
if (
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
77
|
+
// Show credits only for branding provider with business features enabled
|
|
78
|
+
if (enableBusinessFeatures && providerId === BRANDING_PROVIDER) {
|
|
79
|
+
if (typeof pricePerImage === 'number') {
|
|
80
|
+
const credits = pricePerImage * CREDITS_PER_DOLLAR;
|
|
81
|
+
return `${numeral(credits).format('0,0')} credits/张`;
|
|
82
|
+
}
|
|
83
|
+
if (typeof approximatePricePerImage === 'number') {
|
|
84
|
+
const credits = approximatePricePerImage * CREDITS_PER_DOLLAR;
|
|
85
|
+
return `~ ${numeral(credits).format('0,0')} credits/张`;
|
|
86
|
+
}
|
|
87
|
+
} else {
|
|
88
|
+
// Show USD price for open source version or non-branding providers
|
|
89
|
+
if (typeof pricePerImage === 'number') {
|
|
90
|
+
return `${numeral(pricePerImage).format('$0,0.00[000]')} / image`;
|
|
91
|
+
}
|
|
92
|
+
if (typeof approximatePricePerImage === 'number') {
|
|
93
|
+
return `~ ${numeral(approximatePricePerImage).format('$0,0.00[000]')} / image`;
|
|
94
|
+
}
|
|
73
95
|
}
|
|
74
96
|
|
|
75
97
|
return undefined;
|
|
76
|
-
}, [approximatePricePerImage, pricePerImage]);
|
|
98
|
+
}, [approximatePricePerImage, enableBusinessFeatures, pricePerImage, providerId]);
|
|
77
99
|
|
|
78
100
|
const popoverContent = useMemo(() => {
|
|
79
101
|
if (!description && !priceLabel) return null;
|
package/src/app/[variants]/(main)/image/_layout/ConfigPanel/components/ModelSelect/index.tsx
CHANGED
|
@@ -46,7 +46,7 @@ const ModelSelect = memo(() => {
|
|
|
46
46
|
const options = useMemo<SelectProps['options']>(() => {
|
|
47
47
|
const getImageModels = (provider: EnabledProviderWithModels) => {
|
|
48
48
|
const modelOptions = provider.children.map((model) => ({
|
|
49
|
-
label: <ImageModelItem {...model} />,
|
|
49
|
+
label: <ImageModelItem {...model} providerId={provider.id} />,
|
|
50
50
|
provider: provider.id,
|
|
51
51
|
value: `${provider.id}/${model.id}`,
|
|
52
52
|
}));
|
|
@@ -130,7 +130,14 @@ const ModelSelect = memo(() => {
|
|
|
130
130
|
|
|
131
131
|
if (!modelInfo) return props.label;
|
|
132
132
|
|
|
133
|
-
return
|
|
133
|
+
return (
|
|
134
|
+
<ImageModelItem
|
|
135
|
+
{...modelInfo}
|
|
136
|
+
providerId={modelInfo.providerId}
|
|
137
|
+
showBadge={false}
|
|
138
|
+
showPopover={false}
|
|
139
|
+
/>
|
|
140
|
+
);
|
|
134
141
|
};
|
|
135
142
|
|
|
136
143
|
return (
|
|
@@ -6,12 +6,12 @@ import { ModelIcon } from '@lobehub/icons';
|
|
|
6
6
|
import { Alert, Button, Flexbox, Highlighter, Icon, LobeSelect as Select } from '@lobehub/ui';
|
|
7
7
|
import { cssVar } from 'antd-style';
|
|
8
8
|
import { Loader2Icon } from 'lucide-react';
|
|
9
|
-
import { type ReactNode, memo, useEffect, useState } from 'react';
|
|
9
|
+
import { type ReactNode, memo, useEffect, useMemo, useState } from 'react';
|
|
10
10
|
import { useTranslation } from 'react-i18next';
|
|
11
11
|
|
|
12
12
|
import { useProviderName } from '@/hooks/useProviderName';
|
|
13
13
|
import { chatService } from '@/services/chat';
|
|
14
|
-
import {
|
|
14
|
+
import { aiProviderSelectors, useAiInfraStore } from '@/store/aiInfra';
|
|
15
15
|
|
|
16
16
|
const Error = memo<{ error: ChatMessageError }>(({ error }) => {
|
|
17
17
|
const { t } = useTranslation('error');
|
|
@@ -62,7 +62,36 @@ const Checker = memo<ConnectionCheckerProps>(
|
|
|
62
62
|
aiProviderSelectors.isProviderConfigUpdating(provider)(s),
|
|
63
63
|
s.updateAiProviderConfig,
|
|
64
64
|
]);
|
|
65
|
-
const
|
|
65
|
+
const aiProviderModelList = useAiInfraStore((s) => s.aiProviderModelList);
|
|
66
|
+
|
|
67
|
+
// Sort models for better UX:
|
|
68
|
+
// 1. checkModel first (provider's recommended test model)
|
|
69
|
+
// 2. enabled models (user is actively using)
|
|
70
|
+
// 3. by releasedAt descending (newer models first)
|
|
71
|
+
// 4. models without releasedAt last
|
|
72
|
+
const sortedModels = useMemo(() => {
|
|
73
|
+
const chatModels = aiProviderModelList.filter((m) => m.type === 'chat');
|
|
74
|
+
|
|
75
|
+
const sorted = [...chatModels].sort((a, b) => {
|
|
76
|
+
// checkModel always first
|
|
77
|
+
if (a.id === model) return -1;
|
|
78
|
+
if (b.id === model) return 1;
|
|
79
|
+
|
|
80
|
+
// enabled models come before disabled
|
|
81
|
+
if (a.enabled !== b.enabled) return a.enabled ? -1 : 1;
|
|
82
|
+
|
|
83
|
+
// sort by releasedAt descending, models without releasedAt go last
|
|
84
|
+
if (a.releasedAt && b.releasedAt) {
|
|
85
|
+
return new Date(b.releasedAt).getTime() - new Date(a.releasedAt).getTime();
|
|
86
|
+
}
|
|
87
|
+
if (a.releasedAt && !b.releasedAt) return -1;
|
|
88
|
+
if (!a.releasedAt && b.releasedAt) return 1;
|
|
89
|
+
|
|
90
|
+
return 0;
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
return sorted.map((m) => m.id);
|
|
94
|
+
}, [aiProviderModelList, model]);
|
|
66
95
|
|
|
67
96
|
const [loading, setLoading] = useState(false);
|
|
68
97
|
const [pass, setPass] = useState(false);
|
|
@@ -154,7 +183,7 @@ const Checker = memo<ConnectionCheckerProps>(
|
|
|
154
183
|
</Flexbox>
|
|
155
184
|
);
|
|
156
185
|
}}
|
|
157
|
-
options={
|
|
186
|
+
options={sortedModels.map((id) => ({ label: id, value: id }))}
|
|
158
187
|
style={{
|
|
159
188
|
flex: 1,
|
|
160
189
|
overflow: 'hidden',
|
|
@@ -3,6 +3,9 @@ import { type ModelPerformance, type ModelUsage } from '@lobechat/types';
|
|
|
3
3
|
import { Flexbox } from '@lobehub/ui';
|
|
4
4
|
import { memo } from 'react';
|
|
5
5
|
|
|
6
|
+
import { useUserStore } from '@/store/user';
|
|
7
|
+
import { authSelectors } from '@/store/user/slices/auth/selectors';
|
|
8
|
+
|
|
6
9
|
import { messageStateSelectors, useConversationStore } from '../../../store';
|
|
7
10
|
import ExtraContainer from '../../components/Extras/ExtraContainer';
|
|
8
11
|
import TTS from '../../components/Extras/TTS';
|
|
@@ -23,24 +26,27 @@ interface AssistantMessageExtraProps {
|
|
|
23
26
|
export const AssistantMessageExtra = memo<AssistantMessageExtraProps>(
|
|
24
27
|
({ extra, id, content, performance, usage, tools, provider, model }) => {
|
|
25
28
|
const loading = useConversationStore(messageStateSelectors.isMessageGenerating(id));
|
|
29
|
+
const isLogin = useUserStore(authSelectors.isLogin);
|
|
26
30
|
|
|
27
31
|
return (
|
|
28
32
|
<Flexbox gap={8} style={{ marginTop: !!tools?.length ? 8 : 4 }}>
|
|
29
33
|
{content !== LOADING_FLAT && model && (
|
|
30
34
|
<Usage model={model} performance={performance} provider={provider!} usage={usage} />
|
|
31
35
|
)}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
<
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
<
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
36
|
+
{isLogin && (
|
|
37
|
+
<>
|
|
38
|
+
{!!extra?.tts && (
|
|
39
|
+
<ExtraContainer>
|
|
40
|
+
<TTS content={content} id={id} loading={loading} {...extra?.tts} />
|
|
41
|
+
</ExtraContainer>
|
|
42
|
+
)}
|
|
43
|
+
{!!extra?.translate && (
|
|
44
|
+
<ExtraContainer>
|
|
45
|
+
<Translate id={id} loading={loading} {...extra?.translate} />
|
|
46
|
+
</ExtraContainer>
|
|
47
|
+
)}
|
|
48
|
+
</>
|
|
49
|
+
)}
|
|
44
50
|
</Flexbox>
|
|
45
51
|
);
|
|
46
52
|
},
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { Flexbox } from '@lobehub/ui';
|
|
2
2
|
import { memo } from 'react';
|
|
3
3
|
|
|
4
|
+
import { useUserStore } from '@/store/user';
|
|
5
|
+
import { authSelectors } from '@/store/user/slices/auth/selectors';
|
|
6
|
+
|
|
4
7
|
import { messageStateSelectors, useConversationStore } from '../../store';
|
|
5
8
|
import ExtraContainer from '../components/Extras/ExtraContainer';
|
|
6
9
|
import TTS from '../components/Extras/TTS';
|
|
@@ -14,11 +17,12 @@ interface UserMessageExtraProps {
|
|
|
14
17
|
|
|
15
18
|
export const UserMessageExtra = memo<UserMessageExtraProps>(({ extra, id, content }) => {
|
|
16
19
|
const loading = useConversationStore(messageStateSelectors.isMessageGenerating(id));
|
|
20
|
+
const isLogin = useUserStore(authSelectors.isLogin);
|
|
17
21
|
|
|
18
22
|
const showTranslate = !!extra?.translate;
|
|
19
23
|
const showTTS = !!extra?.tts;
|
|
20
24
|
|
|
21
|
-
const showExtra = showTranslate || showTTS;
|
|
25
|
+
const showExtra = isLogin && (showTranslate || showTTS);
|
|
22
26
|
|
|
23
27
|
if (!showExtra) return;
|
|
24
28
|
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
} from '@lobechat/const';
|
|
9
9
|
import { Flexbox, Icon, Image, Tag, Text, Typography, useModalContext } from '@lobehub/ui';
|
|
10
10
|
import { Button, Divider } from 'antd';
|
|
11
|
-
import {
|
|
11
|
+
import { createStaticStyles, cssVar } from 'antd-style';
|
|
12
12
|
import type { Klavis } from 'klavis';
|
|
13
13
|
import { ExternalLink, Loader2, SquareArrowOutUpRight } from 'lucide-react';
|
|
14
14
|
import { useEffect, useMemo, useRef } from 'react';
|
|
@@ -20,7 +20,7 @@ import { klavisStoreSelectors, lobehubSkillStoreSelectors } from '@/store/tool/s
|
|
|
20
20
|
import { KlavisServerStatus } from '@/store/tool/slices/klavisStore';
|
|
21
21
|
import { LobehubSkillStatus } from '@/store/tool/slices/lobehubSkillStore/types';
|
|
22
22
|
|
|
23
|
-
const
|
|
23
|
+
const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
24
24
|
authorLink: css`
|
|
25
25
|
cursor: pointer;
|
|
26
26
|
|
|
@@ -28,7 +28,7 @@ const useStyles = createStyles(({ css, token }) => ({
|
|
|
28
28
|
gap: 4px;
|
|
29
29
|
align-items: center;
|
|
30
30
|
|
|
31
|
-
color: ${
|
|
31
|
+
color: ${cssVar.colorPrimary};
|
|
32
32
|
|
|
33
33
|
&:hover {
|
|
34
34
|
text-decoration: underline;
|
|
@@ -41,7 +41,7 @@ const useStyles = createStyles(({ css, token }) => ({
|
|
|
41
41
|
`,
|
|
42
42
|
detailLabel: css`
|
|
43
43
|
font-size: 12px;
|
|
44
|
-
color: ${
|
|
44
|
+
color: ${cssVar.colorTextTertiary};
|
|
45
45
|
`,
|
|
46
46
|
header: css`
|
|
47
47
|
display: flex;
|
|
@@ -51,7 +51,7 @@ const useStyles = createStyles(({ css, token }) => ({
|
|
|
51
51
|
padding: 16px;
|
|
52
52
|
border-radius: 12px;
|
|
53
53
|
|
|
54
|
-
background: ${
|
|
54
|
+
background: ${cssVar.colorFillTertiary};
|
|
55
55
|
`,
|
|
56
56
|
icon: css`
|
|
57
57
|
display: flex;
|
|
@@ -63,25 +63,25 @@ const useStyles = createStyles(({ css, token }) => ({
|
|
|
63
63
|
height: 56px;
|
|
64
64
|
border-radius: 12px;
|
|
65
65
|
|
|
66
|
-
background: ${
|
|
66
|
+
background: ${cssVar.colorBgContainer};
|
|
67
67
|
`,
|
|
68
68
|
introduction: css`
|
|
69
69
|
font-size: 14px;
|
|
70
70
|
line-height: 1.8;
|
|
71
|
-
color: ${
|
|
71
|
+
color: ${cssVar.colorText};
|
|
72
72
|
`,
|
|
73
73
|
sectionTitle: css`
|
|
74
74
|
font-size: 14px;
|
|
75
75
|
font-weight: 600;
|
|
76
|
-
color: ${
|
|
76
|
+
color: ${cssVar.colorText};
|
|
77
77
|
`,
|
|
78
78
|
title: css`
|
|
79
79
|
font-size: 18px;
|
|
80
80
|
font-weight: 600;
|
|
81
|
-
color: ${
|
|
81
|
+
color: ${cssVar.colorText};
|
|
82
82
|
`,
|
|
83
83
|
toolTag: css`
|
|
84
|
-
font-family: ${
|
|
84
|
+
font-family: ${cssVar.fontFamilyCode};
|
|
85
85
|
font-size: 12px;
|
|
86
86
|
`,
|
|
87
87
|
toolsContainer: css`
|
|
@@ -92,7 +92,7 @@ const useStyles = createStyles(({ css, token }) => ({
|
|
|
92
92
|
trustWarning: css`
|
|
93
93
|
font-size: 12px;
|
|
94
94
|
line-height: 1.6;
|
|
95
|
-
color: ${
|
|
95
|
+
color: ${cssVar.colorTextTertiary};
|
|
96
96
|
`,
|
|
97
97
|
}));
|
|
98
98
|
|
|
@@ -109,7 +109,6 @@ export const IntegrationDetailContent = ({
|
|
|
109
109
|
identifier,
|
|
110
110
|
serverName,
|
|
111
111
|
}: IntegrationDetailContentProps) => {
|
|
112
|
-
const { styles } = useStyles();
|
|
113
112
|
const { t } = useTranslation(['plugin', 'setting']);
|
|
114
113
|
const { close } = useModalContext();
|
|
115
114
|
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
Button,
|
|
5
|
+
Checkbox,
|
|
5
6
|
Flexbox,
|
|
6
7
|
LobeSelect,
|
|
7
8
|
Popover,
|
|
@@ -20,6 +21,8 @@ import { useAppOrigin } from '@/hooks/useAppOrigin';
|
|
|
20
21
|
import { useIsMobile } from '@/hooks/useIsMobile';
|
|
21
22
|
import { topicService } from '@/services/topic';
|
|
22
23
|
import { useChatStore } from '@/store/chat';
|
|
24
|
+
import { useGlobalStore } from '@/store/global';
|
|
25
|
+
import { systemStatusSelectors } from '@/store/global/selectors';
|
|
23
26
|
|
|
24
27
|
import { styles } from './style';
|
|
25
28
|
|
|
@@ -38,6 +41,10 @@ const SharePopoverContent = memo<SharePopoverContentProps>(({ onOpenModal }) =>
|
|
|
38
41
|
const appOrigin = useAppOrigin();
|
|
39
42
|
|
|
40
43
|
const activeTopicId = useChatStore((s) => s.activeTopicId);
|
|
44
|
+
const [hideTopicSharePrivacyWarning, updateSystemStatus] = useGlobalStore((s) => [
|
|
45
|
+
systemStatusSelectors.systemStatus(s).hideTopicSharePrivacyWarning ?? false,
|
|
46
|
+
s.updateSystemStatus,
|
|
47
|
+
]);
|
|
41
48
|
|
|
42
49
|
const {
|
|
43
50
|
data: shareInfo,
|
|
@@ -79,13 +86,38 @@ const SharePopoverContent = memo<SharePopoverContentProps>(({ onOpenModal }) =>
|
|
|
79
86
|
|
|
80
87
|
const handleVisibilityChange = useCallback(
|
|
81
88
|
(visibility: Visibility) => {
|
|
82
|
-
// Show confirmation when changing from private to link
|
|
83
|
-
if (
|
|
89
|
+
// Show confirmation when changing from private to link (unless user has dismissed it)
|
|
90
|
+
if (
|
|
91
|
+
currentVisibility === 'private' &&
|
|
92
|
+
visibility === 'link' &&
|
|
93
|
+
!hideTopicSharePrivacyWarning
|
|
94
|
+
) {
|
|
95
|
+
let doNotShowAgain = false;
|
|
96
|
+
|
|
84
97
|
modal.confirm({
|
|
85
98
|
cancelText: t('cancel', { ns: 'common' }),
|
|
86
|
-
|
|
99
|
+
centered: true,
|
|
100
|
+
content: (
|
|
101
|
+
<div>
|
|
102
|
+
<p>{t('shareModal.popover.privacyWarning.content')}</p>
|
|
103
|
+
<div style={{ marginTop: 16 }}>
|
|
104
|
+
<Checkbox
|
|
105
|
+
onChange={(v) => {
|
|
106
|
+
doNotShowAgain = v;
|
|
107
|
+
}}
|
|
108
|
+
>
|
|
109
|
+
{t('shareModal.popover.privacyWarning.doNotShowAgain')}
|
|
110
|
+
</Checkbox>
|
|
111
|
+
</div>
|
|
112
|
+
</div>
|
|
113
|
+
),
|
|
87
114
|
okText: t('shareModal.popover.privacyWarning.confirm'),
|
|
88
|
-
onOk: () =>
|
|
115
|
+
onOk: () => {
|
|
116
|
+
if (doNotShowAgain) {
|
|
117
|
+
updateSystemStatus({ hideTopicSharePrivacyWarning: true });
|
|
118
|
+
}
|
|
119
|
+
updateVisibility(visibility);
|
|
120
|
+
},
|
|
89
121
|
title: t('shareModal.popover.privacyWarning.title'),
|
|
90
122
|
type: 'warning',
|
|
91
123
|
});
|
|
@@ -93,7 +125,14 @@ const SharePopoverContent = memo<SharePopoverContentProps>(({ onOpenModal }) =>
|
|
|
93
125
|
updateVisibility(visibility);
|
|
94
126
|
}
|
|
95
127
|
},
|
|
96
|
-
[
|
|
128
|
+
[
|
|
129
|
+
currentVisibility,
|
|
130
|
+
hideTopicSharePrivacyWarning,
|
|
131
|
+
modal,
|
|
132
|
+
t,
|
|
133
|
+
updateSystemStatus,
|
|
134
|
+
updateVisibility,
|
|
135
|
+
],
|
|
97
136
|
);
|
|
98
137
|
|
|
99
138
|
const handleCopyLink = useCallback(async () => {
|
|
@@ -70,7 +70,7 @@ export const useDesktopUserStateRedirect = () => {
|
|
|
70
70
|
|
|
71
71
|
export const useWebUserStateRedirect = () =>
|
|
72
72
|
useCallback((state: UserInitializationState) => {
|
|
73
|
-
const pathname = window.location
|
|
73
|
+
const { pathname } = window.location;
|
|
74
74
|
if (state.isInWaitList === true) {
|
|
75
75
|
redirectIfNotOn(pathname, '/waitlist');
|
|
76
76
|
return;
|
|
@@ -81,6 +81,12 @@ export const useWebUserStateRedirect = () =>
|
|
|
81
81
|
return;
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
+
// Redirect away from invite-code page if no longer required
|
|
85
|
+
if (pathname.startsWith('/invite-code')) {
|
|
86
|
+
window.location.href = '/';
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
84
90
|
if (!onboardingSelectors.needsOnboarding(state)) return;
|
|
85
91
|
|
|
86
92
|
redirectIfNotOn(pathname, '/onboarding');
|
|
@@ -326,6 +326,7 @@ export default {
|
|
|
326
326
|
'shareModal.popover.privacyWarning.confirm': 'I understand, continue',
|
|
327
327
|
'shareModal.popover.privacyWarning.content':
|
|
328
328
|
"Please make sure your conversation doesn't contain any personal or sensitive information. You are responsible for any content you choose to share and its consequences.",
|
|
329
|
+
'shareModal.popover.privacyWarning.doNotShowAgain': "Don't show this again",
|
|
329
330
|
'shareModal.popover.privacyWarning.title': 'Privacy Notice',
|
|
330
331
|
'shareModal.popover.title': 'Share Topic',
|
|
331
332
|
'shareModal.popover.visibility': 'Visibility',
|
|
@@ -12,12 +12,19 @@ export default {
|
|
|
12
12
|
'import.incompatible.description':
|
|
13
13
|
'This file was exported from a higher version. Please try upgrading to the latest version and then re-importing.',
|
|
14
14
|
'import.incompatible.title': 'Current application does not support importing this file',
|
|
15
|
+
'inviteCode.continue': 'Continue',
|
|
15
16
|
'inviteCode.currentEmail': 'Current account: {{email}}',
|
|
16
17
|
'inviteCode.desc':
|
|
17
18
|
'An invite code is required to access LobeHub. Please enter a valid invite code to continue.',
|
|
18
|
-
'inviteCode.friends': '
|
|
19
|
-
'inviteCode.
|
|
20
|
-
'inviteCode.
|
|
19
|
+
'inviteCode.friends': 'Ask a friend',
|
|
20
|
+
'inviteCode.joinUsOn': 'Join us on',
|
|
21
|
+
'inviteCode.lookingForInvite': 'Looking for an invite?',
|
|
22
|
+
'inviteCode.notYou': 'Not you?',
|
|
23
|
+
'inviteCode.openingInStages': 'is opening in stages.',
|
|
24
|
+
'inviteCode.placeholder': 'Invite code or link',
|
|
25
|
+
'inviteCode.pleaseEnterCode': 'Enter your invite code to continue.',
|
|
26
|
+
'inviteCode.switchAccount': 'Switch account',
|
|
27
|
+
'inviteCode.title': "You're Almost In",
|
|
21
28
|
'loginRequired.desc': 'You will be redirected to the login page shortly',
|
|
22
29
|
'loginRequired.title': 'Please log in to use this feature',
|
|
23
30
|
'notFound.backHome': 'Back to Home',
|
|
@@ -101,6 +101,7 @@ export interface SystemStatus {
|
|
|
101
101
|
hideGemini2_5FlashImagePreviewChineseWarning?: boolean;
|
|
102
102
|
hidePWAInstaller?: boolean;
|
|
103
103
|
hideThreadLimitAlert?: boolean;
|
|
104
|
+
hideTopicSharePrivacyWarning?: boolean;
|
|
104
105
|
imagePanelWidth: number;
|
|
105
106
|
imageTopicPanelWidth?: number;
|
|
106
107
|
/**
|
|
@@ -212,6 +213,7 @@ export const INITIAL_STATUS = {
|
|
|
212
213
|
hideGemini2_5FlashImagePreviewChineseWarning: false,
|
|
213
214
|
hidePWAInstaller: false,
|
|
214
215
|
hideThreadLimitAlert: false,
|
|
216
|
+
hideTopicSharePrivacyWarning: false,
|
|
215
217
|
imagePanelWidth: 320,
|
|
216
218
|
imageTopicPanelWidth: 80,
|
|
217
219
|
knowledgeBaseModalViewMode: 'list' as const,
|