Compare commits

...

68 Commits

Author SHA1 Message Date
semantic-release-bot 0c855e44fc 🔖 chore(release): v2.1.14 [skip ci]
### [Version 2.1.14](https://github.com/lobehub/lobe-chat/compare/v2.1.13...v2.1.14)
<sup>Released on **2026-02-04**</sup>

#### 🐛 Bug Fixes

- **misc**: Fix cannot uncompressed messages.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### What's fixed

* **misc**: Fix cannot uncompressed messages, closes [#12086](https://github.com/lobehub/lobe-chat/issues/12086) ([ccfaec2](https://github.com/lobehub/lobe-chat/commit/ccfaec2))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-02-04 05:37:35 +00:00
LobeHub Bot e18b7a92c7 🌐 chore: translate non-English comments to English in desktop menus (#12056)
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-04 13:21:24 +08:00
Arvin Xu 3f1fd102c5 👷 build: fix db index (#12090)
* build index

* update
2026-02-04 13:16:56 +08:00
Arvin Xu ccfaec2fdb 🐛 fix: fix cannot uncompressed messages (#12086)
* support uncompressed
* fix open new
2026-02-04 12:25:28 +08:00
lobehubbot 8aba59bffd 📝 docs(bot): Auto sync agents & plugin to readme 2026-02-03 06:54:24 +00:00
semantic-release-bot 13e0652c59 🔖 chore(release): v2.1.13 [skip ci]
### [Version&nbsp;2.1.13](https://github.com/lobehub/lobe-chat/compare/v2.1.12...v2.1.13)
<sup>Released on **2026-02-03**</sup>

#### 🐛 Bug Fixes

- **docker**: Add librt.so.1 to fix PDF parsing.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### What's fixed

* **docker**: Add librt.so.1 to fix PDF parsing, closes [#12039](https://github.com/lobehub/lobe-chat/issues/12039) ([4a6be92](https://github.com/lobehub/lobe-chat/commit/4a6be92))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-02-03 06:52:58 +00:00
Ruxiao Yin 4a6be92604 🐛 fix(docker): add librt.so.1 to fix PDF parsing (#12039) 2026-02-03 14:34:36 +08:00
lobehubbot c576a13a43 📝 docs(bot): Auto sync agents & plugin to readme 2026-02-03 03:04:51 +00:00
semantic-release-bot 63a0464a83 🔖 chore(release): v2.1.12 [skip ci]
### [Version&nbsp;2.1.12](https://github.com/lobehub/lobe-chat/compare/v2.1.11...v2.1.12)
<sup>Released on **2026-02-03**</sup>

#### 🐛 Bug Fixes

- **changelog**: Normalize versionRange to valid semver.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### What's fixed

* **changelog**: Normalize versionRange to valid semver, closes [#12049](https://github.com/lobehub/lobe-chat/issues/12049) ([74b9bd0](https://github.com/lobehub/lobe-chat/commit/74b9bd0))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-02-03 03:03:19 +00:00
LobeHub Bot b1c6bdb192 🌐 chore: translate non-English comments to English in server/utils (#12042)
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-03 10:45:26 +08:00
Kingsword 74b9bd0bed 🐛 fix(changelog): normalize versionRange to valid semver (#12049) 2026-02-03 10:45:03 +08:00
Arvin Xu 6977c570e6 🔨 chore: improve electron build workflow (#12054)
* improve workflow

* update
2026-02-03 10:44:26 +08:00
BrandonStudio 4efe60e9f7 🔨 chore: Remove unexpected file (#12045) 2026-02-02 15:29:39 +08:00
lobehubbot 336d10663c 📝 docs(bot): Auto sync agents & plugin to readme 2026-02-02 06:36:27 +00:00
semantic-release-bot 5f21aaf048 🔖 chore(release): v2.1.11 [skip ci]
### [Version&nbsp;2.1.11](https://github.com/lobehub/lobe-chat/compare/v2.1.10...v2.1.11)
<sup>Released on **2026-02-02**</sup>

#### 🐛 Bug Fixes

- **misc**: Hide password features when AUTH_DISABLE_EMAIL_PASSWORD is set.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### What's fixed

* **misc**: Hide password features when AUTH_DISABLE_EMAIL_PASSWORD is set, closes [#12023](https://github.com/lobehub/lobe-chat/issues/12023) ([e2fd28e](https://github.com/lobehub/lobe-chat/commit/e2fd28e))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-02-02 06:35:01 +00:00
YuTengjing e2fd28eece 🐛 fix: hide password features when AUTH_DISABLE_EMAIL_PASSWORD is set (#12023) 2026-02-02 14:17:10 +08:00
lobehubbot a6a1fecae0 📝 docs(bot): Auto sync agents & plugin to readme 2026-02-02 05:54:53 +00:00
semantic-release-bot fdee6b9aac 🔖 chore(release): v2.1.10 [skip ci]
### [Version&nbsp;2.1.10](https://github.com/lobehub/lobe-chat/compare/v2.1.9...v2.1.10)
<sup>Released on **2026-02-02**</sup>

#### 🐛 Bug Fixes

- **auth**: Revert authority URL and tenant ID for Microsoft authentication..

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### What's fixed

* **auth**: Revert authority URL and tenant ID for Microsoft authentication., closes [#11930](https://github.com/lobehub/lobe-chat/issues/11930) ([98f93ef](https://github.com/lobehub/lobe-chat/commit/98f93ef))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-02-02 05:53:33 +00:00
BrandonStudio 98f93ef2f0 🐛 fix(auth): revert authority URL and tenant ID for Microsoft authentication. (#11930)
🔧 feat(auth): revert authority URL and tenant ID for Microsoft authentication
2026-02-02 13:35:54 +08:00
lobehubbot df7e2800a7 📝 docs(bot): Auto sync agents & plugin to readme 2026-02-02 03:48:44 +00:00
semantic-release-bot 4aac694364 🔖 chore(release): v2.1.9 [skip ci]
### [Version&nbsp;2.1.9](https://github.com/lobehub/lobe-chat/compare/v2.1.8...v2.1.9)
<sup>Released on **2026-02-02**</sup>

#### 🐛 Bug Fixes

- **misc**: Use oauth2.link for generic OIDC provider account linking.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### What's fixed

* **misc**: Use oauth2.link for generic OIDC provider account linking, closes [#12024](https://github.com/lobehub/lobe-chat/issues/12024) ([c7a06a4](https://github.com/lobehub/lobe-chat/commit/c7a06a4))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-02-02 03:47:20 +00:00
YuTengjing c7a06a4b62 🐛 fix: use oauth2.link for generic OIDC provider account linking (#12024) 2026-02-02 11:29:35 +08:00
lobehubbot 2f21c15172 📝 docs(bot): Auto sync agents & plugin to readme 2026-02-01 10:12:44 +00:00
semantic-release-bot de0ce799c7 🔖 chore(release): v2.1.8 [skip ci]
### [Version&nbsp;2.1.8](https://github.com/lobehub/lobe-chat/compare/v2.1.7...v2.1.8)
<sup>Released on **2026-02-01**</sup>

#### 💄 Styles

- **misc**: Improve tasks display.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### Styles

* **misc**: Improve tasks display, closes [#12032](https://github.com/lobehub/lobe-chat/issues/12032) ([3423ad1](https://github.com/lobehub/lobe-chat/commit/3423ad1))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-02-01 10:11:21 +00:00
Arvin Xu 3423ad1b15 💄 style: improve tasks display (#12032)
improve tasks
2026-02-01 17:53:21 +08:00
LobeHub Bot 5db07efe6b 🌐 chore: translate non-English comments to English in src/hooks (#12028)
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-01 17:40:45 +08:00
lobehubbot f5d67a7385 📝 docs(bot): Auto sync agents & plugin to readme 2026-02-01 06:30:03 +00:00
semantic-release-bot 99d4c02b9d 🔖 chore(release): v2.1.7 [skip ci]
### [Version&nbsp;2.1.7](https://github.com/lobehub/lobe-chat/compare/v2.1.6...v2.1.7)
<sup>Released on **2026-02-01**</sup>

#### 🐛 Bug Fixes

- **misc**: Add missing description parameter docs in Notebook system prompt.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### What's fixed

* **misc**: Add missing description parameter docs in Notebook system prompt, closes [#12015](https://github.com/lobehub/lobe-chat/issues/12015) [#11391](https://github.com/lobehub/lobe-chat/issues/11391) ([182030f](https://github.com/lobehub/lobe-chat/commit/182030f))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-02-01 06:28:33 +00:00
Arvin Xu 182030f404 🐛 fix: add missing description parameter docs in Notebook system prompt (#12015)
The createDocument API requires a 'description' parameter, but the system prompt
didn't mention it. This caused models (especially Gemini) to omit the description
field when calling createDocument, resulting in validation errors.

Added <api_parameters> section to clearly document all required and optional
parameters for each Notebook API.

closes #11391
2026-02-01 14:09:52 +08:00
lobehubbot da87df9533 📝 docs(bot): Auto sync agents & plugin to readme 2026-02-01 04:32:26 +00:00
semantic-release-bot 710d92d9f6 🔖 chore(release): v2.1.6 [skip ci]
### [Version&nbsp;2.1.6](https://github.com/lobehub/lobe-chat/compare/v2.1.5...v2.1.6)
<sup>Released on **2026-02-01**</sup>

#### 💄 Styles

- **misc**: Improve local-system tool implement.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### Styles

* **misc**: Improve local-system tool implement, closes [#12022](https://github.com/lobehub/lobe-chat/issues/12022) ([5e203b8](https://github.com/lobehub/lobe-chat/commit/5e203b8))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-02-01 04:31:04 +00:00
Arvin Xu 5e203b868c 💄 style: improve local-system tool implement (#12022)
* improve local system ability

* fix build

* improve tools title render

* fix tools

* update

* try to fix lint

* update

* refactor the LocalFileCtr.ts result

* refactor the exector result
2026-02-01 12:13:27 +08:00
lobehubbot 6e4ad89c82 📝 docs(bot): Auto sync agents & plugin to readme 2026-01-31 17:01:11 +00:00
semantic-release-bot 73daa2513f 🔖 chore(release): v2.1.5 [skip ci]
### [Version&nbsp;2.1.5](https://github.com/lobehub/lobe-chat/compare/v2.1.4...v2.1.5)
<sup>Released on **2026-01-31**</sup>

#### 🐛 Bug Fixes

- **misc**: Slove the group member agents cant set skills problem.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### What's fixed

* **misc**: Slove the group member agents cant set skills problem, closes [#12021](https://github.com/lobehub/lobe-chat/issues/12021) ([2302940](https://github.com/lobehub/lobe-chat/commit/2302940))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-01-31 16:59:50 +00:00
Shinji-Li 2302940079 🐛 fix: slove the group member agents cant set skills problem (#12021)
fix: slove the group member agents cant set skills problem
2026-02-01 00:42:21 +08:00
lobehubbot 9c653e0053 📝 docs(bot): Auto sync agents & plugin to readme 2026-01-31 15:02:40 +00:00
semantic-release-bot 53c9cda9e8 🔖 chore(release): v2.1.4 [skip ci]
### [Version&nbsp;2.1.4](https://github.com/lobehub/lobe-chat/compare/v2.1.3...v2.1.4)
<sup>Released on **2026-01-31**</sup>

#### 🐛 Bug Fixes

- **stream**: Update event handling to use 'text' instead of 'content_part' in gemini 2.5 models.

#### 💄 Styles

- **misc**: Update i18n, Update Kimi K2.5 & Qwen3 Max Thinking models.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### What's fixed

* **stream**: Update event handling to use 'text' instead of 'content_part' in gemini 2.5 models, closes [#11235](https://github.com/lobehub/lobe-chat/issues/11235) ([a76a630](https://github.com/lobehub/lobe-chat/commit/a76a630))

#### Styles

* **misc**: Update i18n, closes [#11920](https://github.com/lobehub/lobe-chat/issues/11920) ([1a590a0](https://github.com/lobehub/lobe-chat/commit/1a590a0))
* **misc**: Update Kimi K2.5 & Qwen3 Max Thinking models, closes [#11925](https://github.com/lobehub/lobe-chat/issues/11925) ([6f9e010](https://github.com/lobehub/lobe-chat/commit/6f9e010))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-01-31 15:00:54 +00:00
sxjeru 6f9e01047b 💄 style: Update Kimi K2.5 & Qwen3 Max Thinking models (#11925)
* 🔨 feat(models): add new AI models and update pricing strategies

* 🐛 fix(models): remove deprecated Gemini 2.0 Flash Exp model from googleChatModels

* 🔨 fix(moonshot): update Kimi K2.5 model parameters and enhance payload handling

*  feat: 添加新的聊天模型 Kimi-K2.5 和 PaddleOCR-VL 1.5 到 siliconcloud

* Update packages/model-bank/src/aiModels/qwen.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

*  feat: 添加 Kimi K2.5 模型,更新 Qwen 模型的思维预算处理

*  feat: 添加 forceImageBase64 选项以支持强制将图像 URL 转换为 Base64

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-31 22:43:28 +08:00
sxjeru a76a630f28 🐛 fix(stream): update event handling to use 'text' instead of 'content_part' in gemini 2.5 models (#11235)
🐛 fix(stream): update event handling to use 'text' instead of 'content_part' in Google AI stream
2026-01-31 22:43:18 +08:00
Arvin Xu 338df4baf9 📝 docs: Update src directory structure to be more comprehensive (#12016)
* update e2e test

* 📝 docs: Update src directory structure to be more comprehensive

- Add missing directories: business, const, envs, helpers, tools
- Add missing root files: auth.ts, instrumentation.ts, instrumentation.node.ts, proxy.ts
- Update descriptions to be more accurate
- Sync changes across English and Chinese documentation

Fixes #9521
2026-01-31 22:42:30 +08:00
LobeHub Bot 1a590a065c 🤖 style: update i18n (#11920)
💄 style: update i18n

Co-authored-by: canisminor1990 <17870709+canisminor1990@users.noreply.github.com>
2026-01-31 20:34:06 +08:00
Arvin Xu 4a87b31246 📝 docs: improve docs (#12013)
Update docs
2026-01-31 19:46:44 +08:00
lobehubbot 83842b45b3 📝 docs(bot): Auto sync agents & plugin to readme 2026-01-31 10:44:46 +00:00
semantic-release-bot 87e3dad58a 🔖 chore(release): v2.1.3 [skip ci]
### [Version&nbsp;2.1.3](https://github.com/lobehub/lobe-chat/compare/v2.1.2...v2.1.3)
<sup>Released on **2026-01-31**</sup>

#### 🐛 Bug Fixes

- **auth**: Add AUTH_DISABLE_EMAIL_PASSWORD env to enable SSO-only mode.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### What's fixed

* **auth**: Add AUTH_DISABLE_EMAIL_PASSWORD env to enable SSO-only mode, closes [#12009](https://github.com/lobehub/lobe-chat/issues/12009) ([f3210a3](https://github.com/lobehub/lobe-chat/commit/f3210a3))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-01-31 10:43:14 +00:00
YuTengjing f3210a3f57 🐛 fix(auth): add AUTH_DISABLE_EMAIL_PASSWORD env to enable SSO-only mode (#12009) 2026-01-31 18:25:22 +08:00
Innei 8b8159eb01 🔧 chore: upgrade macOS ARM64 runner from macos-14 to macos-15 (#12006) 2026-01-31 13:12:12 +08:00
LobeHub Bot 5086a126a7 🌐 chore: translate non-English comments to English in src/store (#12001)
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-31 11:02:23 +08:00
lobehubbot a82a4bda34 📝 docs(bot): Auto sync agents & plugin to readme 2026-01-30 17:09:25 +00:00
semantic-release-bot 71b2ecd94b 🔖 chore(release): v2.1.2 [skip ci]
### [Version&nbsp;2.1.2](https://github.com/lobehub/lobe-chat/compare/v2.1.1...v2.1.2)
<sup>Released on **2026-01-30**</sup>

#### 🐛 Bug Fixes

- **misc**: Fix feishu sso provider.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### What's fixed

* **misc**: Fix feishu sso provider, closes [#11970](https://github.com/lobehub/lobe-chat/issues/11970) ([ffd9fff](https://github.com/lobehub/lobe-chat/commit/ffd9fff))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-01-30 17:07:53 +00:00
Arvin Xu ffd9fff091 🐛 fix: fix feishu sso provider (#11970) 2026-01-31 00:50:11 +08:00
LobeHub Bot 67c4bafd3f 🌐 chore: translate non-English comments to English in desktop controllers (#11978) 2026-01-31 00:49:38 +08:00
Arvin Xu 7496511917 📝 docs: improve self-hosting documents (#11994)
* update document

* update documents

* update auth

* move

* update database

* move auth

* move auth

* update
2026-01-30 20:50:05 +08:00
lobehubbot 15e89f2eee 📝 docs(bot): Auto sync agents & plugin to readme 2026-01-30 10:39:04 +00:00
semantic-release-bot 1421e991d8 🔖 chore(release): v2.1.1 [skip ci]
### [Version&nbsp;2.1.1](https://github.com/lobehub/lobe-chat/compare/v2.1.0...v2.1.1)
<sup>Released on **2026-01-30**</sup>

#### 🐛 Bug Fixes

- **misc**: Correct desktop download URL path.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### What's fixed

* **misc**: Correct desktop download URL path, closes [#11990](https://github.com/lobehub/lobe-chat/issues/11990) ([e46df98](https://github.com/lobehub/lobe-chat/commit/e46df98))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-01-30 10:37:18 +00:00
Arvin Xu f17acd7f7e ♻️ chore(docker-compose): refactor docker compose (#11989)
* improve message content

* ♻️ refactor(docker-compose): 创建精简版 deploy 配置

- 新建 docker-compose/deploy 目录,包含最小化部署配置
- 仅保留核心服务:postgresql、redis、rustfs、searxng、lobe
- 移除 Casdoor 认证服务相关配置
- 移除可观测性服务(Grafana/Prometheus/Tempo/otel-collector)
- 使用 paradedb/paradedb:latest 镜像(支持 pgvector + pg_search)
- 更新 setup.sh 指向新的 deploy 目录
- 清理 .env 示例文件中的 Casdoor 相关配置

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* update document

* update content

* update content

* improve env

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 18:15:43 +08:00
Innei e46df98907 🐛 fix: correct desktop download URL path (#11990)
Fixed the download URL path from '/download' to '/downloads' to match the actual official site path.
2026-01-30 17:53:09 +08:00
lobehubbot 2c791d749d 📝 docs(bot): Auto sync agents & plugin to readme 2026-01-30 05:57:38 +00:00
semantic-release-bot 4e982cf89f 🔖 chore(release): v2.1.0 [skip ci]
## [Version&nbsp;2.1.0](https://github.com/lobehub/lobe-chat/compare/v2.0.13...v2.1.0)
<sup>Released on **2026-01-30**</sup>

####  Features

- **misc**: Refactor cron job UI and use runtime enableBusinessFeatures flag.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### What's improved

* **misc**: Refactor cron job UI and use runtime enableBusinessFeatures flag, closes [#11975](https://github.com/lobehub/lobe-chat/issues/11975) ([104a19a](https://github.com/lobehub/lobe-chat/commit/104a19a))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-01-30 05:56:16 +00:00
Innei 104a19a8a4 feat: refactor cron job UI and use runtime enableBusinessFeatures flag (#11975)
- Replace compile-time ENABLE_BUSINESS_FEATURES constant with runtime
  serverConfigSelectors.enableBusinessFeatures for cron module
- Redesign CronJobScheduleConfig with FormGroup pattern matching Settings UI
- Update CronJobHeader with simplified layout (28px title, Switch only)
- Convert all cron feature components to use createStaticStyles with cssVar
- Add i18n keys for cron job form labels

LOBE-4540
2026-01-30 13:38:34 +08:00
lobehubbot c5a1791e32 📝 docs(bot): Auto sync agents & plugin to readme 2026-01-29 17:23:20 +00:00
semantic-release-bot 9a1a81680f 🔖 chore(release): v2.0.13 [skip ci]
### [Version&nbsp;2.0.13](https://github.com/lobehub/lobe-chat/compare/v2.0.12...v2.0.13)
<sup>Released on **2026-01-29**</sup>

#### 💄 Styles

- **misc**: Fix usage table display issues.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### Styles

* **misc**: Fix usage table display issues, closes [#10108](https://github.com/lobehub/lobe-chat/issues/10108) ([4bd82c3](https://github.com/lobehub/lobe-chat/commit/4bd82c3))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-01-29 17:21:49 +00:00
Rylan Cai 4bd82c397a 💄 style: fix usage table display issues (#10108)
* wip: use stack bar chart

* 💄 style: update labels

* 🐛 fix: should not include INF vales

* ♻️ refactor: improve codes

* 💄 style: improve label format

* 💄 style: improve label format
2026-01-30 01:05:02 +08:00
lobehubbot 891837b792 📝 docs(bot): Auto sync agents & plugin to readme 2026-01-29 17:01:44 +00:00
semantic-release-bot a4c1d4b687 🔖 chore(release): v2.0.12 [skip ci]
### [Version&nbsp;2.0.12](https://github.com/lobehub/lobe-chat/compare/v2.0.11...v2.0.12)
<sup>Released on **2026-01-29**</sup>

#### 🐛 Bug Fixes

- **misc**: Group publish to market should set local group market identifer.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### What's fixed

* **misc**: Group publish to market should set local group market identifer, closes [#11965](https://github.com/lobehub/lobe-chat/issues/11965) ([0bda4d9](https://github.com/lobehub/lobe-chat/commit/0bda4d9))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-01-29 17:00:18 +00:00
Shinji-Li 0bda4d9845 🐛 fix: group publish to market should set local group market identifer (#11965)
* fix: when use group in market the supervisor plugins lost

* fix: slove the group pubilsh but not set the market id into group
2026-01-29 22:30:14 +08:00
lobehubbot 7abc5142e0 📝 docs(bot): Auto sync agents & plugin to readme 2026-01-29 14:03:28 +00:00
semantic-release-bot 1b9caa92a5 🔖 chore(release): v2.0.11 [skip ci]
### [Version&nbsp;2.0.11](https://github.com/lobehub/lobe-chat/compare/v2.0.10...v2.0.11)
<sup>Released on **2026-01-29**</sup>

#### 💄 Styles

- **misc**: Fix group task render.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### Styles

* **misc**: Fix group task render, closes [#11952](https://github.com/lobehub/lobe-chat/issues/11952) ([b8ef02e](https://github.com/lobehub/lobe-chat/commit/b8ef02e))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-01-29 14:02:07 +00:00
Arvin Xu b8ef02e647 💄 style: fix group task render (#11952)
* improve task messages render

* improve task messages render

* refactor agent task

* fix tests

* improved ui now

* fix

* fix supervisor issue

* add more tests

* fix agent tasks issue

* update i18n

* update createdAt

* fix tests and update dockerfile

* fix max length

* fix max length
2026-01-29 21:44:32 +08:00
488 changed files with 24045 additions and 5745 deletions
+5 -4
View File
@@ -5,10 +5,11 @@ You are a support assistant for LobeChat authentication migration issues. Your j
**IMPORTANT**: The official documentation website is `https://lobehub.com`. When providing documentation links, always use `https://lobehub.com/docs/...` format. Never use `lobechat.com` - that domain is incorrect.
Examples of correct documentation URLs:
- `https://lobehub.com/docs/self-hosting/advanced/auth/nextauth-to-betterauth`
- `https://lobehub.com/docs/self-hosting/advanced/auth/clerk-to-betterauth`
- `https://lobehub.com/docs/self-hosting/advanced/auth`
- `https://lobehub.com/docs/self-hosting/advanced/auth/providers/casdoor`
- `https://lobehub.com/docs/self-hosting/migration/v2/auth/nextauth-to-betterauth`
- `https://lobehub.com/docs/self-hosting/migration/v2/auth/clerk-to-betterauth`
- `https://lobehub.com/docs/self-hosting/auth`
- `https://lobehub.com/docs/self-hosting/auth/providers/casdoor`
## Target Issues
+4 -6
View File
@@ -1,6 +1,3 @@
# add a access code to lock your lobe-chat application, you can set a long password to avoid leaking. If this value contains a comma, it is a password array.
# ACCESS_CODE=lobe66
# Specify your API Key selection method, currently supporting `random` and `turn`.
# API_KEY_SELECT_MODE=random
@@ -265,9 +262,6 @@ OPENAI_API_KEY=sk-xxxxxxxxx
# Bucket request endpoint
# S3_ENDPOINT=https://xxxxxxxxxxxxxxxxxxxxxxxxxxxxx.r2.cloudflarestorage.com
# Public access domain for the bucket
# S3_PUBLIC_DOMAIN=https://s3-for-lobechat.your-domain.com
# Bucket region, such as us-west-1, generally not needed to add
# but some service providers may require configuration
# S3_REGION=us-west-1
@@ -295,6 +289,10 @@ OPENAI_API_KEY=sk-xxxxxxxxx
# Leave empty to allow all emails
# AUTH_ALLOWED_EMAILS=example.com,admin@other.com
# Disable email/password authentication (SSO-only mode)
# Set to '1' to disable email/password sign-in and registration, only allowing SSO login
# AUTH_DISABLE_EMAIL_PASSWORD=0
# Google OAuth Configuration (for Better-Auth)
# Get credentials from: https://console.cloud.google.com/apis/credentials
# Authorized redirect URIs:
-3
View File
@@ -85,9 +85,6 @@ S3_ENDPOINT=http://localhost:${MINIO_PORT}
# S3 bucket name for storing files
S3_BUCKET=${MINIO_LOBE_BUCKET}
# Public domain for S3 file access
S3_PUBLIC_DOMAIN=http://localhost:${MINIO_PORT}
# Enable path-style S3 requests (required for MinIO)
S3_ENABLE_PATH_STYLE=1
@@ -24,6 +24,17 @@ runs:
shell: bash
run: pnpm install --node-linker=hoisted
# 移除国内 electron 镜像配置,GitHub Actions 使用官方源更快
- name: Remove China electron mirror from .npmrc
shell: bash
run: |
NPMRC_FILE="./apps/desktop/.npmrc"
if [ -f "$NPMRC_FILE" ]; then
sed -i.bak '/^electron_mirror=/d; /^electron_builder_binaries_mirror=/d' "$NPMRC_FILE"
rm -f "${NPMRC_FILE}.bak"
echo "✅ Removed electron mirror config from .npmrc"
fi
- name: Install deps on Desktop
shell: bash
run: npm run install-isolated --prefix=./apps/desktop
@@ -70,12 +70,12 @@ jobs:
```
2. Read the latest migration documentation based on the issue:
- If issue #11757 (NextAuth): `cat docs/self-hosting/advanced/auth/nextauth-to-betterauth.mdx`
- If issue #11707 (Clerk): `cat docs/self-hosting/advanced/auth/clerk-to-betterauth.mdx`
- If issue #11757 (NextAuth): `cat docs/self-hosting/migration/v2/auth/nextauth-to-betterauth.mdx`
- If issue #11707 (Clerk): `cat docs/self-hosting/migration/v2/auth/clerk-to-betterauth.mdx`
3. Read additional reference files:
- Main auth documentation: `cat docs/self-hosting/advanced/auth.mdx`
- Migration internals: `cat docs/self-hosting/advanced/auth/migration-internals.mdx`
- Main auth documentation: `cat docs/self-hosting/auth.mdx`
- Migration internals: `cat docs/self-hosting/migration/v2/auth/migration-internals.mdx`
- Deprecated env vars checker: `cat scripts/_shared/checkDeprecatedAuth.js`
4. Analyze the user's comment and determine:
+11
View File
@@ -109,6 +109,17 @@ jobs:
- name: Install dependencies
run: pnpm install --node-linker=hoisted
# 移除国内 electron 镜像配置,GitHub Actions 使用官方源更快
- name: Remove China electron mirror from .npmrc
shell: bash
run: |
NPMRC_FILE="./apps/desktop/.npmrc"
if [ -f "$NPMRC_FILE" ]; then
sed -i.bak '/^electron_mirror=/d; /^electron_builder_binaries_mirror=/d' "$NPMRC_FILE"
rm -f "${NPMRC_FILE}.bak"
echo "✅ Removed electron mirror config from .npmrc"
fi
- name: Install deps on Desktop
run: npm run install-isolated --prefix=./apps/desktop
+1 -1
View File
@@ -148,7 +148,7 @@ jobs:
# 使用 GitHub Hosted Runner
if [[ "${{ github.event_name }}" != "workflow_dispatch" ]] || [[ "${{ inputs.build_mac }}" == "true" ]]; then
echo "Using GitHub-Hosted Runner for macOS ARM64"
arm_entry='{"os": "macos-14", "name": "macos-arm64"}'
arm_entry='{"os": "macos-15", "name": "macos-arm64"}'
static_matrix=$(echo "$static_matrix" | jq -c --argjson entry "$arm_entry" '. + [$entry]')
fi
+459
View File
@@ -2,6 +2,465 @@
# Changelog
### [Version 2.1.14](https://github.com/lobehub/lobe-chat/compare/v2.1.13...v2.1.14)
<sup>Released on **2026-02-04**</sup>
#### 🐛 Bug Fixes
- **misc**: Fix cannot uncompressed messages.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### What's fixed
- **misc**: Fix cannot uncompressed messages, closes [#12086](https://github.com/lobehub/lobe-chat/issues/12086) ([ccfaec2](https://github.com/lobehub/lobe-chat/commit/ccfaec2))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
### [Version 2.1.13](https://github.com/lobehub/lobe-chat/compare/v2.1.12...v2.1.13)
<sup>Released on **2026-02-03**</sup>
#### 🐛 Bug Fixes
- **docker**: Add librt.so.1 to fix PDF parsing.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### What's fixed
- **docker**: Add librt.so.1 to fix PDF parsing, closes [#12039](https://github.com/lobehub/lobe-chat/issues/12039) ([4a6be92](https://github.com/lobehub/lobe-chat/commit/4a6be92))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
### [Version 2.1.12](https://github.com/lobehub/lobe-chat/compare/v2.1.11...v2.1.12)
<sup>Released on **2026-02-03**</sup>
#### 🐛 Bug Fixes
- **changelog**: Normalize versionRange to valid semver.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### What's fixed
- **changelog**: Normalize versionRange to valid semver, closes [#12049](https://github.com/lobehub/lobe-chat/issues/12049) ([74b9bd0](https://github.com/lobehub/lobe-chat/commit/74b9bd0))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
### [Version 2.1.11](https://github.com/lobehub/lobe-chat/compare/v2.1.10...v2.1.11)
<sup>Released on **2026-02-02**</sup>
#### 🐛 Bug Fixes
- **misc**: Hide password features when AUTH_DISABLE_EMAIL_PASSWORD is set.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### What's fixed
- **misc**: Hide password features when AUTH_DISABLE_EMAIL_PASSWORD is set, closes [#12023](https://github.com/lobehub/lobe-chat/issues/12023) ([e2fd28e](https://github.com/lobehub/lobe-chat/commit/e2fd28e))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
### [Version 2.1.10](https://github.com/lobehub/lobe-chat/compare/v2.1.9...v2.1.10)
<sup>Released on **2026-02-02**</sup>
#### 🐛 Bug Fixes
- **auth**: Revert authority URL and tenant ID for Microsoft authentication..
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### What's fixed
- **auth**: Revert authority URL and tenant ID for Microsoft authentication., closes [#11930](https://github.com/lobehub/lobe-chat/issues/11930) ([98f93ef](https://github.com/lobehub/lobe-chat/commit/98f93ef))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
### [Version 2.1.9](https://github.com/lobehub/lobe-chat/compare/v2.1.8...v2.1.9)
<sup>Released on **2026-02-02**</sup>
#### 🐛 Bug Fixes
- **misc**: Use oauth2.link for generic OIDC provider account linking.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### What's fixed
- **misc**: Use oauth2.link for generic OIDC provider account linking, closes [#12024](https://github.com/lobehub/lobe-chat/issues/12024) ([c7a06a4](https://github.com/lobehub/lobe-chat/commit/c7a06a4))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
### [Version 2.1.8](https://github.com/lobehub/lobe-chat/compare/v2.1.7...v2.1.8)
<sup>Released on **2026-02-01**</sup>
#### 💄 Styles
- **misc**: Improve tasks display.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### Styles
- **misc**: Improve tasks display, closes [#12032](https://github.com/lobehub/lobe-chat/issues/12032) ([3423ad1](https://github.com/lobehub/lobe-chat/commit/3423ad1))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
### [Version 2.1.7](https://github.com/lobehub/lobe-chat/compare/v2.1.6...v2.1.7)
<sup>Released on **2026-02-01**</sup>
#### 🐛 Bug Fixes
- **misc**: Add missing description parameter docs in Notebook system prompt.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### What's fixed
- **misc**: Add missing description parameter docs in Notebook system prompt, closes [#12015](https://github.com/lobehub/lobe-chat/issues/12015) [#11391](https://github.com/lobehub/lobe-chat/issues/11391) ([182030f](https://github.com/lobehub/lobe-chat/commit/182030f))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
### [Version 2.1.6](https://github.com/lobehub/lobe-chat/compare/v2.1.5...v2.1.6)
<sup>Released on **2026-02-01**</sup>
#### 💄 Styles
- **misc**: Improve local-system tool implement.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### Styles
- **misc**: Improve local-system tool implement, closes [#12022](https://github.com/lobehub/lobe-chat/issues/12022) ([5e203b8](https://github.com/lobehub/lobe-chat/commit/5e203b8))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
### [Version 2.1.5](https://github.com/lobehub/lobe-chat/compare/v2.1.4...v2.1.5)
<sup>Released on **2026-01-31**</sup>
#### 🐛 Bug Fixes
- **misc**: Slove the group member agents cant set skills problem.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### What's fixed
- **misc**: Slove the group member agents cant set skills problem, closes [#12021](https://github.com/lobehub/lobe-chat/issues/12021) ([2302940](https://github.com/lobehub/lobe-chat/commit/2302940))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
### [Version 2.1.4](https://github.com/lobehub/lobe-chat/compare/v2.1.3...v2.1.4)
<sup>Released on **2026-01-31**</sup>
#### 🐛 Bug Fixes
- **stream**: Update event handling to use 'text' instead of 'content_part' in gemini 2.5 models.
#### 💄 Styles
- **misc**: Update i18n, Update Kimi K2.5 & Qwen3 Max Thinking models.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### What's fixed
- **stream**: Update event handling to use 'text' instead of 'content_part' in gemini 2.5 models, closes [#11235](https://github.com/lobehub/lobe-chat/issues/11235) ([a76a630](https://github.com/lobehub/lobe-chat/commit/a76a630))
#### Styles
- **misc**: Update i18n, closes [#11920](https://github.com/lobehub/lobe-chat/issues/11920) ([1a590a0](https://github.com/lobehub/lobe-chat/commit/1a590a0))
- **misc**: Update Kimi K2.5 & Qwen3 Max Thinking models, closes [#11925](https://github.com/lobehub/lobe-chat/issues/11925) ([6f9e010](https://github.com/lobehub/lobe-chat/commit/6f9e010))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
### [Version 2.1.3](https://github.com/lobehub/lobe-chat/compare/v2.1.2...v2.1.3)
<sup>Released on **2026-01-31**</sup>
#### 🐛 Bug Fixes
- **auth**: Add AUTH_DISABLE_EMAIL_PASSWORD env to enable SSO-only mode.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### What's fixed
- **auth**: Add AUTH_DISABLE_EMAIL_PASSWORD env to enable SSO-only mode, closes [#12009](https://github.com/lobehub/lobe-chat/issues/12009) ([f3210a3](https://github.com/lobehub/lobe-chat/commit/f3210a3))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
### [Version 2.1.2](https://github.com/lobehub/lobe-chat/compare/v2.1.1...v2.1.2)
<sup>Released on **2026-01-30**</sup>
#### 🐛 Bug Fixes
- **misc**: Fix feishu sso provider.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### What's fixed
- **misc**: Fix feishu sso provider, closes [#11970](https://github.com/lobehub/lobe-chat/issues/11970) ([ffd9fff](https://github.com/lobehub/lobe-chat/commit/ffd9fff))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
### [Version 2.1.1](https://github.com/lobehub/lobe-chat/compare/v2.1.0...v2.1.1)
<sup>Released on **2026-01-30**</sup>
#### 🐛 Bug Fixes
- **misc**: Correct desktop download URL path.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### What's fixed
- **misc**: Correct desktop download URL path, closes [#11990](https://github.com/lobehub/lobe-chat/issues/11990) ([e46df98](https://github.com/lobehub/lobe-chat/commit/e46df98))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.1.0](https://github.com/lobehub/lobe-chat/compare/v2.0.13...v2.1.0)
<sup>Released on **2026-01-30**</sup>
#### ✨ Features
- **misc**: Refactor cron job UI and use runtime enableBusinessFeatures flag.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### What's improved
- **misc**: Refactor cron job UI and use runtime enableBusinessFeatures flag, closes [#11975](https://github.com/lobehub/lobe-chat/issues/11975) ([104a19a](https://github.com/lobehub/lobe-chat/commit/104a19a))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
### [Version 2.0.13](https://github.com/lobehub/lobe-chat/compare/v2.0.12...v2.0.13)
<sup>Released on **2026-01-29**</sup>
#### 💄 Styles
- **misc**: Fix usage table display issues.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### Styles
- **misc**: Fix usage table display issues, closes [#10108](https://github.com/lobehub/lobe-chat/issues/10108) ([4bd82c3](https://github.com/lobehub/lobe-chat/commit/4bd82c3))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
### [Version 2.0.12](https://github.com/lobehub/lobe-chat/compare/v2.0.11...v2.0.12)
<sup>Released on **2026-01-29**</sup>
#### 🐛 Bug Fixes
- **misc**: Group publish to market should set local group market identifer.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### What's fixed
- **misc**: Group publish to market should set local group market identifer, closes [#11965](https://github.com/lobehub/lobe-chat/issues/11965) ([0bda4d9](https://github.com/lobehub/lobe-chat/commit/0bda4d9))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
### [Version 2.0.11](https://github.com/lobehub/lobe-chat/compare/v2.0.10...v2.0.11)
<sup>Released on **2026-01-29**</sup>
#### 💄 Styles
- **misc**: Fix group task render.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### Styles
- **misc**: Fix group task render, closes [#11952](https://github.com/lobehub/lobe-chat/issues/11952) ([b8ef02e](https://github.com/lobehub/lobe-chat/commit/b8ef02e))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
### [Version 2.0.10](https://github.com/lobehub/lobe-chat/compare/v2.0.9...v2.0.10)
<sup>Released on **2026-01-29**</sup>
+54 -57
View File
@@ -8,24 +8,23 @@ ARG USE_CN_MIRROR
ENV DEBIAN_FRONTEND="noninteractive"
RUN <<'EOF'
set -e
if [ "${USE_CN_MIRROR:-false}" = "true" ]; then
sed -i "s/deb.debian.org/mirrors.ustc.edu.cn/g" "/etc/apt/sources.list.d/debian.sources"
fi
apt update
apt install ca-certificates proxychains-ng -qy
mkdir -p /distroless/bin /distroless/etc /distroless/etc/ssl/certs /distroless/lib
cp /usr/lib/$(arch)-linux-gnu/libproxychains.so.4 /distroless/lib/libproxychains.so.4
cp /usr/lib/$(arch)-linux-gnu/libdl.so.2 /distroless/lib/libdl.so.2
cp /usr/bin/proxychains4 /distroless/bin/proxychains
cp /etc/proxychains4.conf /distroless/etc/proxychains4.conf
cp /usr/lib/$(arch)-linux-gnu/libstdc++.so.6 /distroless/lib/libstdc++.so.6
cp /usr/lib/$(arch)-linux-gnu/libgcc_s.so.1 /distroless/lib/libgcc_s.so.1
cp /usr/local/bin/node /distroless/bin/node
cp /etc/ssl/certs/ca-certificates.crt /distroless/etc/ssl/certs/ca-certificates.crt
rm -rf /tmp/* /var/lib/apt/lists/* /var/tmp/*
EOF
RUN set -e && \
if [ "${USE_CN_MIRROR:-false}" = "true" ]; then \
sed -i "s/deb.debian.org/mirrors.ustc.edu.cn/g" "/etc/apt/sources.list.d/debian.sources"; \
fi && \
apt update && \
apt install ca-certificates proxychains-ng -qy && \
mkdir -p /distroless/bin /distroless/etc /distroless/etc/ssl/certs /distroless/lib && \
cp /usr/lib/$(arch)-linux-gnu/libproxychains.so.4 /distroless/lib/libproxychains.so.4 && \
cp /usr/lib/$(arch)-linux-gnu/libdl.so.2 /distroless/lib/libdl.so.2 && \
cp /usr/bin/proxychains4 /distroless/bin/proxychains && \
cp /etc/proxychains4.conf /distroless/etc/proxychains4.conf && \
cp /usr/lib/$(arch)-linux-gnu/libstdc++.so.6 /distroless/lib/libstdc++.so.6 && \
cp /usr/lib/$(arch)-linux-gnu/libgcc_s.so.1 /distroless/lib/libgcc_s.so.1 && \
cp /usr/lib/$(arch)-linux-gnu/librt.so.1 /distroless/lib/librt.so.1 && \
cp /usr/local/bin/node /distroless/bin/node && \
cp /etc/ssl/certs/ca-certificates.crt /distroless/etc/ssl/certs/ca-certificates.crt && \
rm -rf /tmp/* /var/lib/apt/lists/* /var/tmp/*
## Builder image, install all the dependencies and build the app
FROM base AS builder
@@ -77,23 +76,21 @@ COPY patches ./patches
# bring in desktop workspace manifest so pnpm can resolve it
COPY apps/desktop/src/main/package.json ./apps/desktop/src/main/package.json
RUN <<'EOF'
set -e
if [ "${USE_CN_MIRROR:-false}" = "true" ]; then
export SENTRYCLI_CDNURL="https://npmmirror.com/mirrors/sentry-cli"
npm config set registry "https://registry.npmmirror.com/"
echo 'canvas_binary_host_mirror=https://npmmirror.com/mirrors/canvas' >> .npmrc
fi
export COREPACK_NPM_REGISTRY=$(npm config get registry | sed 's/\/$//')
npm i -g corepack@latest
corepack enable
corepack use $(sed -n 's/.*"packageManager": "\(.*\)".*/\1/p' package.json)
pnpm i
mkdir -p /deps
cd /deps
pnpm init
pnpm add pg drizzle-orm
EOF
RUN set -e && \
if [ "${USE_CN_MIRROR:-false}" = "true" ]; then \
export SENTRYCLI_CDNURL="https://npmmirror.com/mirrors/sentry-cli"; \
npm config set registry "https://registry.npmmirror.com/"; \
echo 'canvas_binary_host_mirror=https://npmmirror.com/mirrors/canvas' >> .npmrc; \
fi && \
export COREPACK_NPM_REGISTRY=$(npm config get registry | sed 's/\/$//') && \
npm i -g corepack@latest && \
corepack enable && \
corepack use $(sed -n 's/.*"packageManager": "\(.*\)".*/\1/p' package.json) && \
pnpm i && \
mkdir -p /deps && \
cd /deps && \
pnpm init && \
pnpm add pg drizzle-orm
COPY . .
@@ -101,17 +98,15 @@ COPY . .
RUN npm run build:docker
# Prepare desktop export assets for Electron packaging (if generated)
RUN <<'EOF'
set -e
if [ -d "/app/out" ]; then
mkdir -p /app/apps/desktop/dist/next
cp -a /app/out/. /app/apps/desktop/dist/next/
echo "✅ Copied Next export output into /app/apps/desktop/dist/next"
else
echo "️ No Next export output found at /app/out, creating empty directory"
mkdir -p /app/apps/desktop/dist/next
fi
EOF
RUN set -e && \
if [ -d "/app/out" ]; then \
mkdir -p /app/apps/desktop/dist/next && \
cp -a /app/out/. /app/apps/desktop/dist/next/ && \
echo "Copied Next export output into /app/apps/desktop/dist/next"; \
else \
echo "No Next export output found at /app/out, creating empty directory" && \
mkdir -p /app/apps/desktop/dist/next; \
fi
## Application image, copy all the files for production
FROM busybox:latest AS app
@@ -138,12 +133,10 @@ COPY --from=builder /deps/node_modules/drizzle-orm /app/node_modules/drizzle-orm
COPY --from=builder /app/scripts/serverLauncher/startServer.js /app/startServer.js
COPY --from=builder /app/scripts/_shared /app/scripts/_shared
RUN <<'EOF'
set -e
addgroup -S -g 1001 nodejs
adduser -D -G nodejs -H -S -h /app -u 1001 nextjs
chown -R nextjs:nodejs /app /etc/proxychains4.conf
EOF
RUN set -e && \
addgroup -S -g 1001 nodejs && \
adduser -D -G nodejs -H -S -h /app -u 1001 nextjs && \
chown -R nextjs:nodejs /app /etc/proxychains4.conf
## Production image, copy all the files and run next
FROM scratch
@@ -166,14 +159,12 @@ ENV HOSTNAME="0.0.0.0" \
PORT="3210"
# General Variables
ENV ACCESS_CODE="" \
APP_URL="" \
ENV APP_URL="" \
API_KEY_SELECT_MODE="" \
DEFAULT_AGENT_CONFIG="" \
SYSTEM_AGENT="" \
FEATURE_FLAGS="" \
PROXY_URL="" \
ENABLE_AUTH_PROTECTION=""
PROXY_URL=""
# Database
ENV KEY_VAULTS_SECRET="" \
@@ -184,6 +175,10 @@ ENV KEY_VAULTS_SECRET="" \
ENV AUTH_SECRET="" \
AUTH_SSO_PROVIDERS="" \
AUTH_ALLOWED_EMAILS="" \
AUTH_TRUSTED_ORIGINS="" \
AUTH_DISABLE_EMAIL_PASSWORD="" \
AUTH_EMAIL_VERIFICATION="" \
AUTH_ENABLE_MAGIC_LINK="" \
# Google
AUTH_GOOGLE_ID="" \
AUTH_GOOGLE_SECRET="" \
@@ -192,7 +187,9 @@ ENV AUTH_SECRET="" \
AUTH_GITHUB_SECRET="" \
# Microsoft
AUTH_MICROSOFT_ID="" \
AUTH_MICROSOFT_SECRET=""
AUTH_MICROSOFT_SECRET="" \
AUTH_MICROSOFT_AUTHORITY_URL="" \
AUTH_MICROSOFT_TENANT_ID=""
# Redis
ENV REDIS_URL="" \
+3 -4
View File
@@ -37,7 +37,7 @@ Were building the worlds largest humanagent co-evolving network.
[![][share-mastodon-shield]][share-mastodon-link]
[![][share-linkedin-shield]][share-linkedin-link]
<sup>Agent teams that grow with you</sup>
<sup>Agent teammates that grow with you</sup>
[![][github-trending-shield]][github-trending-url]
@@ -581,7 +581,7 @@ LobeHub provides Self-Hosted Version with Vercel, Alibaba Cloud, and [Docker Ima
"If you want to deploy this service yourself on Vercel, Zeabur or Alibaba Cloud, you can follow these steps:
- Prepare your [OpenAI API Key](https://platform.openai.com/account/api-keys).
- Click the button below to start deployment: Log in directly with your GitHub account, and remember to fill in the `OPENAI_API_KEY`(required) and `ACCESS_CODE` (recommended) on the environment variable section.
- Click the button below to start deployment: Log in directly with your GitHub account, and remember to fill in the `OPENAI_API_KEY`(required) on the environment variable section.
- After deployment, you can start using it.
- Bind a custom domain (optional): The DNS of the domain assigned by Vercel is polluted in some areas; binding a custom domain can connect directly.
@@ -647,7 +647,6 @@ This project provides some additional configuration items set with environment v
| -------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| `OPENAI_API_KEY` | Yes | This is the API key you apply on the OpenAI account page | `sk-xxxxxx...xxxxxx` |
| `OPENAI_PROXY_URL` | No | If you manually configure the OpenAI interface proxy, you can use this configuration item to override the default OpenAI API request base URL | `https://api.chatanywhere.cn` or `https://aihubmix.com/v1` <br/>The default value is<br/>`https://api.openai.com/v1` |
| `ACCESS_CODE` | No | Add a password to access this service; you can set a long password to avoid leaking. If this value contains a comma, it is a password array. | `awCTe)re_r74` or `rtrt_ewee3@09!` or `code1,code2,code3` |
| `OPENAI_MODEL_LIST` | No | Used to control the model list. Use `+` to add a model, `-` to hide a model, and `model_name=display_name` to customize the display name of a model, separated by commas. | `qwen-7b-chat,+glm-6b,-gpt-3.5-turbo` |
> \[!NOTE]
@@ -829,7 +828,7 @@ This project is [LobeHub Community License](./LICENSE) licensed.
[codespaces-link]: https://codespaces.new/lobehub/lobe-chat
[codespaces-shield]: https://github.com/codespaces/badge.svg
[deploy-button-image]: https://vercel.com/button
[deploy-link]: https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Flobehub%2Flobe-chat&env=OPENAI_API_KEY,ACCESS_CODE&envDescription=Find%20your%20OpenAI%20API%20Key%20by%20click%20the%20right%20Learn%20More%20button.%20%7C%20Access%20Code%20can%20protect%20your%20website&envLink=https%3A%2F%2Fplatform.openai.com%2Faccount%2Fapi-keys&project-name=lobe-chat&repository-name=lobe-chat
[deploy-link]: https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Flobehub%2Flobe-chat&env=OPENAI_API_KEY&envDescription=Find%20your%20OpenAI%20API%20Key%20by%20click%20the%20right%20Learn%20More%20button.&envLink=https%3A%2F%2Fplatform.openai.com%2Faccount%2Fapi-keys&project-name=lobe-chat&repository-name=lobe-chat
[deploy-on-alibaba-cloud-button-image]: https://service-info-public.oss-cn-hangzhou.aliyuncs.com/computenest-en.svg
[deploy-on-alibaba-cloud-link]: https://computenest.console.aliyun.com/service/instance/create/default?type=user&ServiceName=LobeHub%E7%A4%BE%E5%8C%BA%E7%89%88
[deploy-on-repocloud-button-image]: https://d16t0pc4846x52.cloudfront.net/deploylobe.svg
+3 -4
View File
@@ -35,7 +35,7 @@ LobeHub 是一个工作与生活空间,用于发现、构建并与会随着您
[![][share-weibo-shield]][share-weibo-link]
[![][share-mastodon-shield]][share-mastodon-link]
<sup>Agent teams that grow with you</sup>
<sup>Agent teammates that grow with you</sup>
[![][github-trending-shield]][github-trending-url]
[![][github-hello-shield]][github-hello-url]
@@ -555,7 +555,7 @@ LobeHub 提供了 Vercel 的 自托管版本 和 [Docker 镜像][docker-release-
如果想在 Vercel 、 Zeabur 或 阿里云 上部署该服务,可以按照以下步骤进行操作:
- 准备好你的 [OpenAI API Key](https://platform.openai.com/account/api-keys) 。
- 点击下方按钮开始部署: 直接使用 GitHub 账号登录即可,记得在环境变量页填入 `OPENAI_API_KEY` (必填) and `ACCESS_CODE`(推荐)
- 点击下方按钮开始部署: 直接使用 GitHub 账号登录即可,记得在环境变量页填入 `OPENAI_API_KEY` (必填);
- 部署完毕后,即可开始使用;
- 绑定自定义域名(可选):Vercel 分配的域名 DNS 在某些区域被污染了,绑定自定义域名即可直连。目前 Zeabur 提供的域名还未被污染,大多数地区都可以直连。
@@ -621,7 +621,6 @@ docker compose up -d
| ------------------- | ---- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| `OPENAI_API_KEY` | 必选 | 这是你在 OpenAI 账户页面申请的 API 密钥 | `sk-xxxxxx...xxxxxx` |
| `OPENAI_PROXY_URL` | 可选 | 如果你手动配置了 OpenAI 接口代理,可以使用此配置项来覆盖默认的 OpenAI API 请求基础 URL | `https://api.chatanywhere.cn``https://aihubmix.com/v1`<br/>默认值:<br/>`https://api.openai.com/v1` |
| `ACCESS_CODE` | 可选 | 添加访问此服务的密码,你可以设置一个长密码以防被爆破,该值用逗号分隔时为密码数组 | `awCTe)re_r74` or `rtrt_ewee3@09!` or `code1,code2,code3` |
| `OPENAI_MODEL_LIST` | 可选 | 用来控制模型列表,使用 `+` 增加一个模型,使用 `-` 来隐藏一个模型,使用 `模型名=展示名` 来自定义模型的展示名,用英文逗号隔开。 | `qwen-7b-chat,+glm-6b,-gpt-3.5-turbo` |
> \[!NOTE]
@@ -843,7 +842,7 @@ This project is [LobeHub Community License](./LICENSE) licensed.
[codespaces-link]: https://codespaces.new/lobehub/lobe-chat
[codespaces-shield]: https://github.com/codespaces/badge.svg
[deploy-button-image]: https://vercel.com/button
[deploy-link]: https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Flobehub%2Flobe-chat&env=OPENAI_API_KEY,ACCESS_CODE&envDescription=Find%20your%20OpenAI%20API%20Key%20by%20click%20the%20right%20Learn%20More%20button.%20%7C%20Access%20Code%20can%20protect%20your%20website&envLink=https%3A%2F%2Fplatform.openai.com%2Faccount%2Fapi-keys&project-name=lobe-chat&repository-name=lobe-chat
[deploy-link]: https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Flobehub%2Flobe-chat&env=OPENAI_API_KEY&envDescription=Find%20your%20OpenAI%20API%20Key%20by%20click%20the%20right%20Learn%20More%20button.&envLink=https%3A%2F%2Fplatform.openai.com%2Faccount%2Fapi-keys&project-name=lobe-chat&repository-name=lobe-chat
[deploy-on-alibaba-cloud-button-image]: https://service-info-public.oss-cn-hangzhou.aliyuncs.com/computenest-en.svg
[deploy-on-alibaba-cloud-link]: https://computenest.console.aliyun.com/service/instance/create/default?type=user&ServiceName=LobeHub%E7%A4%BE%E5%8C%BA%E7%89%88
[deploy-on-sealos-button-image]: https://raw.githubusercontent.com/labring-actions/templates/main/Deploy-on-Sealos.svg
+4 -4
View File
@@ -12,11 +12,11 @@
"main": "./dist/main/index.js",
"scripts": {
"build": "electron-vite build",
"build-local": "npm run build && electron-builder --dir --config electron-builder.mjs --c.mac.notarize=false -c.mac.identity=null --c.asar=false",
"build:linux": "npm run build && electron-builder --linux --config electron-builder.mjs --publish never",
"build:mac": "npm run build && electron-builder --mac --config electron-builder.mjs --publish never",
"build:mac:local": "npm run build && UPDATE_CHANNEL=nightly electron-builder --mac --config electron-builder.mjs --publish never",
"build:win": "npm run build && electron-builder --win --config electron-builder.mjs --publish never",
"build-local": "npm run build && electron-builder --dir --config electron-builder.mjs --c.mac.notarize=false -c.mac.identity=null --c.asar=false",
"dev": "electron-vite dev",
"dev:static": "cross-env DESKTOP_RENDERER_STATIC=1 npm run electron:dev",
"electron:dev": "electron-vite dev",
@@ -47,9 +47,6 @@
"get-port-please": "^3.2.0",
"superjson": "^2.2.6"
},
"optionalDependencies": {
"node-mac-permissions": "^2.5.0"
},
"devDependencies": {
"@electron-toolkit/eslint-config-prettier": "^3.0.0",
"@electron-toolkit/eslint-config-ts": "^3.1.0",
@@ -103,6 +100,9 @@
"vitest": "^3.2.4",
"zod": "^3.25.76"
},
"optionalDependencies": {
"node-mac-permissions": "^2.5.0"
},
"pnpm": {
"onlyBuiltDependencies": [
"@napi-rs/canvas",
@@ -218,8 +218,13 @@ export default class LocalFileCtr extends ControllerModule {
}
@IpcMethod()
async listLocalFiles({ path: dirPath }: ListLocalFileParams): Promise<FileResult[]> {
logger.debug('Listing directory contents:', { dirPath });
async listLocalFiles({
path: dirPath,
sortBy = 'modifiedTime',
sortOrder = 'desc',
limit = 100,
}: ListLocalFileParams): Promise<{ files: FileResult[]; totalCount: number }> {
logger.debug('Listing directory contents:', { dirPath, limit, sortBy, sortOrder });
const results: FileResult[] = [];
try {
@@ -256,22 +261,51 @@ export default class LocalFileCtr extends ControllerModule {
}
}
// Sort entries: folders first, then by name
// Sort entries based on sortBy and sortOrder
results.sort((a, b) => {
if (a.isDirectory !== b.isDirectory) {
return a.isDirectory ? -1 : 1; // Directories first
let comparison = 0;
switch (sortBy) {
case 'name': {
comparison = (a.name || '').localeCompare(b.name || '');
break;
}
case 'modifiedTime': {
comparison = a.modifiedTime.getTime() - b.modifiedTime.getTime();
break;
}
case 'createdTime': {
comparison = a.createdTime.getTime() - b.createdTime.getTime();
break;
}
case 'size': {
comparison = a.size - b.size;
break;
}
default: {
comparison = a.modifiedTime.getTime() - b.modifiedTime.getTime();
}
}
// Add null/undefined checks for robustness if needed, though names should exist
return (a.name || '').localeCompare(b.name || ''); // Then sort by name
return sortOrder === 'desc' ? -comparison : comparison;
});
logger.debug('Directory listing successful', { dirPath, resultCount: results.length });
return results;
const totalCount = results.length;
// Apply limit
const limitedResults = results.slice(0, limit);
logger.debug('Directory listing successful', {
dirPath,
resultCount: limitedResults.length,
totalCount,
});
return { files: limitedResults, totalCount };
} catch (error) {
logger.error(`Failed to list directory ${dirPath}:`, error);
// Rethrow or return an empty array/error object depending on desired behavior
// For now, returning empty array on error listing directory itself
return [];
// For now, returning empty result on error listing directory itself
return { files: [], totalCount: 0 };
}
}
@@ -59,14 +59,14 @@ interface McpInstallParams {
*/
export default class McpInstallController extends ControllerModule {
/**
* 处理 MCP 插件安装请求
* @param parsedData 解析后的协议数据
* @returns 是否处理成功
* Handle MCP plugin installation request
* @param parsedData Parsed protocol data
* @returns Whether processing succeeded
*/
@protocolHandler('install')
public async handleInstallRequest(parsedData: McpInstallParams): Promise<boolean> {
try {
// 从参数中提取必需字段
// Extract required fields from parameters
const { id, schema: schemaParam, marketId } = parsedData;
if (!id) {
@@ -76,11 +76,11 @@ export default class McpInstallController extends ControllerModule {
return false;
}
// 映射协议来源
// Map protocol source
const isOfficialMarket = marketId === 'lobehub';
// 对于官方市场,schema 是可选的;对于第三方市场,schema 是必需的
// For official marketplace, schema is optional; for third-party marketplace, schema is required
if (!isOfficialMarket && !schemaParam) {
logger.warn(`🔧 [McpInstall] Schema is required for third-party marketplace:`, {
marketId,
@@ -90,7 +90,7 @@ export default class McpInstallController extends ControllerModule {
let mcpSchema: McpSchema | undefined;
// 如果提供了 schema 参数,则解析和验证
// If schema parameter is provided, parse and validate
if (schemaParam) {
try {
mcpSchema = JSON.parse(schemaParam);
@@ -104,7 +104,7 @@ export default class McpInstallController extends ControllerModule {
return false;
}
// 验证 identifier 与 id 参数匹配
// Verify identifier matches id parameter
if (mcpSchema.identifier !== id) {
logger.error(`🔧 [McpInstall] Schema identifier does not match URL id parameter:`, {
schemaId: mcpSchema.identifier,
@@ -122,7 +122,7 @@ export default class McpInstallController extends ControllerModule {
pluginVersion: mcpSchema?.version || 'Unknown',
});
// 广播安装请求到前端
// Broadcast installation request to frontend
const installRequest = {
marketId,
pluginId: id,
@@ -136,7 +136,7 @@ export default class McpInstallController extends ControllerModule {
pluginName: installRequest.schema?.name || 'Unknown',
});
// 通过应用实例广播到前端
// Broadcast to frontend via app instance
if (this.app?.browserManager) {
this.app.browserManager.broadcastToWindow('app', 'mcpInstallRequest', installRequest);
logger.debug(`🔧 [McpInstall] Install request broadcasted successfully`);
@@ -88,7 +88,7 @@ export default class NetworkProxyCtr extends ControllerModule {
}
/**
* 测试代理连接
* Test proxy connection
*/
@IpcMethod()
async testProxyConnection(url: string): Promise<{ message?: string; success: boolean }> {
@@ -108,7 +108,7 @@ export default class NetworkProxyCtr extends ControllerModule {
}
/**
* 测试指定代理配置
* Test specified proxy configuration
*/
@IpcMethod()
async testProxyConfig({
@@ -131,17 +131,17 @@ export default class NetworkProxyCtr extends ControllerModule {
}
/**
* 应用初始代理设置
* Apply initial proxy settings
*/
async beforeAppReady(): Promise<void> {
try {
// 获取存储的代理设置
// Get stored proxy settings
const networkProxy = this.app.storeManager.get(
'networkProxy',
defaultProxySettings,
) as NetworkProxySettings;
// 验证配置
// Validate configuration
const validation = ProxyConfigValidator.validate(networkProxy);
if (!validation.isValid) {
logger.warn('Invalid stored proxy configuration, using defaults:', validation.errors);
@@ -158,7 +158,7 @@ export default class NetworkProxyCtr extends ControllerModule {
});
} catch (error) {
logger.error('Failed to apply initial proxy settings:', error);
// 出错时使用默认设置
// Use default settings on error
try {
await ProxyDispatcherManager.applyProxySettings(defaultProxySettings);
logger.info('Fallback to default proxy settings');
@@ -162,7 +162,7 @@ export default class RemoteServerSyncCtr extends ControllerModule {
});
});
// 5. 监听请求本身的错误(如 DNS 解析失败)
// 5. Listen for request errors (e.g., DNS resolution failure)
clientReq.on('error', (error) => {
logger.error(`${logPrefix} Error forwarding request:`, error);
if (sender.isDestroyed()) return;
@@ -196,7 +196,7 @@ export default class RemoteServerSyncCtr extends ControllerModule {
delete requestHeaders['connection']; // Often causes issues
// delete requestHeaders['content-length']; // Let node handle it based on body
// 读取代理配置
// Read proxy configuration
const proxyConfig = this.app.storeManager.get('networkProxy', defaultProxySettings);
let agent;
@@ -20,8 +20,8 @@ vi.mock('@/utils/logger', () => ({
// Mock file-loaders
vi.mock('@lobechat/file-loaders', () => ({
SYSTEM_FILES_TO_IGNORE: ['.DS_Store', 'Thumbs.db'],
loadFile: vi.fn(),
SYSTEM_FILES_TO_IGNORE: ['.DS_Store', 'Thumbs.db', '$RECYCLE.BIN'],
}));
// Mock electron
@@ -553,6 +553,514 @@ describe('LocalFileCtr', () => {
});
});
describe('listLocalFiles', () => {
it('should list directory contents successfully', async () => {
vi.mocked(mockFsPromises.readdir).mockResolvedValue(['file1.txt', 'file2.txt', 'folder1']);
vi.mocked(mockFsPromises.stat).mockImplementation(async (filePath) => {
const name = (filePath as string).split('/').pop();
if (name === 'folder1') {
return {
isDirectory: () => true,
birthtime: new Date('2024-01-01'),
mtime: new Date('2024-01-15'),
atime: new Date('2024-01-20'),
size: 4096,
} as any;
}
return {
isDirectory: () => false,
birthtime: new Date('2024-01-02'),
mtime: new Date('2024-01-10'),
atime: new Date('2024-01-18'),
size: 1024,
} as any;
});
const result = await localFileCtr.listLocalFiles({ path: '/test' });
expect(result.files).toHaveLength(3);
expect(result.totalCount).toBe(3);
expect(mockFsPromises.readdir).toHaveBeenCalledWith('/test');
});
it('should filter out system files like .DS_Store and Thumbs.db', async () => {
vi.mocked(mockFsPromises.readdir).mockResolvedValue([
'file1.txt',
'.DS_Store',
'Thumbs.db',
'folder1',
]);
vi.mocked(mockFsPromises.stat).mockImplementation(async (filePath) => {
const name = (filePath as string).split('/').pop();
if (name === 'folder1') {
return {
isDirectory: () => true,
birthtime: new Date('2024-01-01'),
mtime: new Date('2024-01-15'),
atime: new Date('2024-01-20'),
size: 4096,
} as any;
}
return {
isDirectory: () => false,
birthtime: new Date('2024-01-02'),
mtime: new Date('2024-01-10'),
atime: new Date('2024-01-18'),
size: 1024,
} as any;
});
const result = await localFileCtr.listLocalFiles({ path: '/test' });
// Should only contain file1.txt and folder1, not .DS_Store or Thumbs.db
expect(result.files).toHaveLength(2);
expect(result.totalCount).toBe(2);
expect(result.files.map((r) => r.name)).not.toContain('.DS_Store');
expect(result.files.map((r) => r.name)).not.toContain('Thumbs.db');
expect(result.files.map((r) => r.name)).toContain('folder1');
expect(result.files.map((r) => r.name)).toContain('file1.txt');
});
it('should filter out $RECYCLE.BIN system folder', async () => {
vi.mocked(mockFsPromises.readdir).mockResolvedValue(['file1.txt', '$RECYCLE.BIN', 'folder1']);
vi.mocked(mockFsPromises.stat).mockImplementation(async (filePath) => {
const name = (filePath as string).split('/').pop();
const isDir = name === 'folder1' || name === '$RECYCLE.BIN';
return {
isDirectory: () => isDir,
birthtime: new Date('2024-01-01'),
mtime: new Date('2024-01-15'),
atime: new Date('2024-01-20'),
size: isDir ? 4096 : 1024,
} as any;
});
const result = await localFileCtr.listLocalFiles({ path: '/test' });
// Should not contain $RECYCLE.BIN
expect(result.files).toHaveLength(2);
expect(result.totalCount).toBe(2);
expect(result.files.map((r) => r.name)).not.toContain('$RECYCLE.BIN');
});
it('should sort by name ascending when specified', async () => {
vi.mocked(mockFsPromises.readdir).mockResolvedValue(['zebra.txt', 'alpha.txt', 'apple.txt']);
vi.mocked(mockFsPromises.stat).mockResolvedValue({
isDirectory: () => false,
birthtime: new Date('2024-01-01'),
mtime: new Date('2024-01-15'),
atime: new Date('2024-01-20'),
size: 1024,
} as any);
const result = await localFileCtr.listLocalFiles({
path: '/test',
sortBy: 'name',
sortOrder: 'asc',
});
expect(result.files.map((r) => r.name)).toEqual(['alpha.txt', 'apple.txt', 'zebra.txt']);
});
it('should sort by modifiedTime descending by default', async () => {
vi.mocked(mockFsPromises.readdir).mockResolvedValue(['old.txt', 'new.txt', 'mid.txt']);
vi.mocked(mockFsPromises.stat).mockImplementation(async (filePath) => {
const name = (filePath as string).split('/').pop();
const dates: Record<string, Date> = {
'new.txt': new Date('2024-01-20'),
'mid.txt': new Date('2024-01-15'),
'old.txt': new Date('2024-01-01'),
};
return {
isDirectory: () => false,
birthtime: new Date('2024-01-01'),
mtime: dates[name!] || new Date('2024-01-01'),
atime: new Date('2024-01-20'),
size: 1024,
} as any;
});
const result = await localFileCtr.listLocalFiles({ path: '/test' });
// Default sort: modifiedTime descending (newest first)
expect(result.files.map((r) => r.name)).toEqual(['new.txt', 'mid.txt', 'old.txt']);
});
it('should sort by size ascending when specified', async () => {
vi.mocked(mockFsPromises.readdir).mockResolvedValue(['large.txt', 'small.txt', 'medium.txt']);
vi.mocked(mockFsPromises.stat).mockImplementation(async (filePath) => {
const name = (filePath as string).split('/').pop();
const sizes: Record<string, number> = {
'large.txt': 10000,
'medium.txt': 5000,
'small.txt': 1000,
};
return {
isDirectory: () => false,
birthtime: new Date('2024-01-01'),
mtime: new Date('2024-01-15'),
atime: new Date('2024-01-20'),
size: sizes[name!] || 1024,
} as any;
});
const result = await localFileCtr.listLocalFiles({
path: '/test',
sortBy: 'size',
sortOrder: 'asc',
});
expect(result.files.map((r) => r.name)).toEqual(['small.txt', 'medium.txt', 'large.txt']);
});
it('should apply limit parameter', async () => {
vi.mocked(mockFsPromises.readdir).mockResolvedValue([
'file1.txt',
'file2.txt',
'file3.txt',
'file4.txt',
'file5.txt',
]);
vi.mocked(mockFsPromises.stat).mockResolvedValue({
isDirectory: () => false,
birthtime: new Date('2024-01-01'),
mtime: new Date('2024-01-15'),
atime: new Date('2024-01-20'),
size: 1024,
} as any);
const result = await localFileCtr.listLocalFiles({
path: '/test',
limit: 3,
});
expect(result.files).toHaveLength(3);
expect(result.totalCount).toBe(5); // Total is 5, but limited to 3
});
it('should use default limit of 100', async () => {
// Create 150 files
const files = Array.from({ length: 150 }, (_, i) => `file${i}.txt`);
vi.mocked(mockFsPromises.readdir).mockResolvedValue(files);
vi.mocked(mockFsPromises.stat).mockResolvedValue({
isDirectory: () => false,
birthtime: new Date('2024-01-01'),
mtime: new Date('2024-01-15'),
atime: new Date('2024-01-20'),
size: 1024,
} as any);
const result = await localFileCtr.listLocalFiles({ path: '/test' });
expect(result.files).toHaveLength(100);
expect(result.totalCount).toBe(150); // Total is 150, but limited to 100
});
it('should sort by createdTime ascending when specified', async () => {
vi.mocked(mockFsPromises.readdir).mockResolvedValue([
'newest.txt',
'oldest.txt',
'middle.txt',
]);
vi.mocked(mockFsPromises.stat).mockImplementation(async (filePath) => {
const name = (filePath as string).split('/').pop();
const dates: Record<string, Date> = {
'newest.txt': new Date('2024-03-01'),
'middle.txt': new Date('2024-02-01'),
'oldest.txt': new Date('2024-01-01'),
};
return {
isDirectory: () => false,
birthtime: dates[name!] || new Date('2024-01-01'),
mtime: new Date('2024-01-15'),
atime: new Date('2024-01-20'),
size: 1024,
} as any;
});
const result = await localFileCtr.listLocalFiles({
path: '/test',
sortBy: 'createdTime',
sortOrder: 'asc',
});
expect(result.files.map((r) => r.name)).toEqual(['oldest.txt', 'middle.txt', 'newest.txt']);
});
it('should sort by createdTime descending when specified', async () => {
vi.mocked(mockFsPromises.readdir).mockResolvedValue([
'newest.txt',
'oldest.txt',
'middle.txt',
]);
vi.mocked(mockFsPromises.stat).mockImplementation(async (filePath) => {
const name = (filePath as string).split('/').pop();
const dates: Record<string, Date> = {
'newest.txt': new Date('2024-03-01'),
'middle.txt': new Date('2024-02-01'),
'oldest.txt': new Date('2024-01-01'),
};
return {
isDirectory: () => false,
birthtime: dates[name!] || new Date('2024-01-01'),
mtime: new Date('2024-01-15'),
atime: new Date('2024-01-20'),
size: 1024,
} as any;
});
const result = await localFileCtr.listLocalFiles({
path: '/test',
sortBy: 'createdTime',
sortOrder: 'desc',
});
expect(result.files.map((r) => r.name)).toEqual(['newest.txt', 'middle.txt', 'oldest.txt']);
});
it('should sort by name descending when specified', async () => {
vi.mocked(mockFsPromises.readdir).mockResolvedValue(['alpha.txt', 'zebra.txt', 'middle.txt']);
vi.mocked(mockFsPromises.stat).mockResolvedValue({
isDirectory: () => false,
birthtime: new Date('2024-01-01'),
mtime: new Date('2024-01-15'),
atime: new Date('2024-01-20'),
size: 1024,
} as any);
const result = await localFileCtr.listLocalFiles({
path: '/test',
sortBy: 'name',
sortOrder: 'desc',
});
expect(result.files.map((r) => r.name)).toEqual(['zebra.txt', 'middle.txt', 'alpha.txt']);
});
it('should sort by size descending when specified', async () => {
vi.mocked(mockFsPromises.readdir).mockResolvedValue(['small.txt', 'large.txt', 'medium.txt']);
vi.mocked(mockFsPromises.stat).mockImplementation(async (filePath) => {
const name = (filePath as string).split('/').pop();
const sizes: Record<string, number> = {
'large.txt': 10000,
'medium.txt': 5000,
'small.txt': 1000,
};
return {
isDirectory: () => false,
birthtime: new Date('2024-01-01'),
mtime: new Date('2024-01-15'),
atime: new Date('2024-01-20'),
size: sizes[name!] || 1024,
} as any;
});
const result = await localFileCtr.listLocalFiles({
path: '/test',
sortBy: 'size',
sortOrder: 'desc',
});
expect(result.files.map((r) => r.name)).toEqual(['large.txt', 'medium.txt', 'small.txt']);
});
it('should sort by modifiedTime ascending when specified', async () => {
vi.mocked(mockFsPromises.readdir).mockResolvedValue(['old.txt', 'new.txt', 'mid.txt']);
vi.mocked(mockFsPromises.stat).mockImplementation(async (filePath) => {
const name = (filePath as string).split('/').pop();
const dates: Record<string, Date> = {
'new.txt': new Date('2024-01-20'),
'mid.txt': new Date('2024-01-15'),
'old.txt': new Date('2024-01-01'),
};
return {
isDirectory: () => false,
birthtime: new Date('2024-01-01'),
mtime: dates[name!] || new Date('2024-01-01'),
atime: new Date('2024-01-20'),
size: 1024,
} as any;
});
const result = await localFileCtr.listLocalFiles({
path: '/test',
sortBy: 'modifiedTime',
sortOrder: 'asc',
});
expect(result.files.map((r) => r.name)).toEqual(['old.txt', 'mid.txt', 'new.txt']);
});
it('should handle empty directory with sort options', async () => {
vi.mocked(mockFsPromises.readdir).mockResolvedValue([]);
const result = await localFileCtr.listLocalFiles({
path: '/empty',
sortBy: 'name',
sortOrder: 'asc',
});
expect(result.files).toEqual([]);
expect(result.totalCount).toBe(0);
});
it('should apply limit after sorting', async () => {
vi.mocked(mockFsPromises.readdir).mockResolvedValue([
'file1.txt',
'file2.txt',
'file3.txt',
'file4.txt',
'file5.txt',
]);
vi.mocked(mockFsPromises.stat).mockImplementation(async (filePath) => {
const name = (filePath as string).split('/').pop();
const dates: Record<string, Date> = {
'file1.txt': new Date('2024-01-01'),
'file2.txt': new Date('2024-01-02'),
'file3.txt': new Date('2024-01-03'),
'file4.txt': new Date('2024-01-04'),
'file5.txt': new Date('2024-01-05'),
};
return {
isDirectory: () => false,
birthtime: new Date('2024-01-01'),
mtime: dates[name!] || new Date('2024-01-01'),
atime: new Date('2024-01-20'),
size: 1024,
} as any;
});
// Sort by modifiedTime desc (default) and limit to 3
const result = await localFileCtr.listLocalFiles({
path: '/test',
limit: 3,
});
// Should get the 3 newest files
expect(result.files).toHaveLength(3);
expect(result.totalCount).toBe(5); // Total is 5, but limited to 3
expect(result.files.map((r) => r.name)).toEqual(['file5.txt', 'file4.txt', 'file3.txt']);
});
it('should handle limit larger than file count', async () => {
vi.mocked(mockFsPromises.readdir).mockResolvedValue(['file1.txt', 'file2.txt']);
vi.mocked(mockFsPromises.stat).mockResolvedValue({
isDirectory: () => false,
birthtime: new Date('2024-01-01'),
mtime: new Date('2024-01-15'),
atime: new Date('2024-01-20'),
size: 1024,
} as any);
const result = await localFileCtr.listLocalFiles({
path: '/test',
limit: 1000,
});
expect(result.files).toHaveLength(2);
expect(result.totalCount).toBe(2);
});
it('should return file metadata including size, times and type', async () => {
const createdTime = new Date('2024-01-01');
const modifiedTime = new Date('2024-01-15');
const accessTime = new Date('2024-01-20');
vi.mocked(mockFsPromises.readdir).mockResolvedValue(['document.pdf']);
vi.mocked(mockFsPromises.stat).mockResolvedValue({
isDirectory: () => false,
birthtime: createdTime,
mtime: modifiedTime,
atime: accessTime,
size: 2048,
} as any);
const result = await localFileCtr.listLocalFiles({ path: '/test' });
expect(result.files).toHaveLength(1);
expect(result.totalCount).toBe(1);
expect(result.files[0]).toEqual({
name: 'document.pdf',
path: '/test/document.pdf',
isDirectory: false,
size: 2048,
type: 'pdf',
createdTime,
modifiedTime,
lastAccessTime: accessTime,
});
});
it('should return empty result when directory read fails', async () => {
vi.mocked(mockFsPromises.readdir).mockRejectedValue(new Error('Permission denied'));
const result = await localFileCtr.listLocalFiles({ path: '/protected' });
expect(result.files).toEqual([]);
expect(result.totalCount).toBe(0);
});
it('should skip files that cannot be stat', async () => {
vi.mocked(mockFsPromises.readdir).mockResolvedValue(['good.txt', 'bad.txt']);
vi.mocked(mockFsPromises.stat).mockImplementation(async (filePath) => {
if ((filePath as string).includes('bad.txt')) {
throw new Error('Cannot stat file');
}
return {
isDirectory: () => false,
birthtime: new Date('2024-01-01'),
mtime: new Date('2024-01-15'),
atime: new Date('2024-01-20'),
size: 1024,
} as any;
});
const result = await localFileCtr.listLocalFiles({ path: '/test' });
// Should only contain good.txt, bad.txt should be skipped
expect(result.files).toHaveLength(1);
expect(result.totalCount).toBe(1);
expect(result.files[0].name).toBe('good.txt');
});
it('should handle directory type correctly', async () => {
vi.mocked(mockFsPromises.readdir).mockResolvedValue(['my_folder']);
vi.mocked(mockFsPromises.stat).mockResolvedValue({
isDirectory: () => true,
birthtime: new Date('2024-01-01'),
mtime: new Date('2024-01-15'),
atime: new Date('2024-01-20'),
size: 4096,
} as any);
const result = await localFileCtr.listLocalFiles({ path: '/test' });
expect(result.files).toHaveLength(1);
expect(result.totalCount).toBe(1);
expect(result.files[0].isDirectory).toBe(true);
expect(result.files[0].type).toBe('directory');
});
it('should handle files without extension', async () => {
vi.mocked(mockFsPromises.readdir).mockResolvedValue(['Makefile', 'README']);
vi.mocked(mockFsPromises.stat).mockResolvedValue({
isDirectory: () => false,
birthtime: new Date('2024-01-01'),
mtime: new Date('2024-01-15'),
atime: new Date('2024-01-20'),
size: 512,
} as any);
const result = await localFileCtr.listLocalFiles({ path: '/test' });
expect(result.files).toHaveLength(2);
expect(result.totalCount).toBe(2);
// Files without extension should have empty type
expect(result.files[0].type).toBe('');
expect(result.files[1].type).toBe('');
});
});
describe('handleGrepContent', () => {
it('should search content in a single file', async () => {
vi.mocked(mockFsPromises.stat).mockResolvedValue({
+1 -1
View File
@@ -45,7 +45,7 @@ export class LinuxMenu extends BaseMenuPlatform implements IMenuPlatform {
this.buildAndSetAppMenu(options);
}
// --- 私有方法:定义菜单模板和逻辑 ---
// --- Private methods: define menu templates and logic ---
private getAppMenuTemplate(options?: MenuOptions): MenuItemConstructorOptions[] {
const showDev = isDev || options?.showDevItems;
+8 -8
View File
@@ -48,23 +48,23 @@ export class MacOSMenu extends BaseMenuPlatform implements IMenuPlatform {
}
refresh(options?: MenuOptions): void {
// 重建Application menu
// Rebuild Application menu
this.buildAndSetAppMenu(options);
// 如果托盘菜单存在,也重建它(如果需要动态更新)
// If tray menu exists, rebuild it as well (if dynamic update is needed)
// this.trayMenu = this.buildTrayMenu();
// 需要考虑如何更新现有托盘图标的菜单
// Need to consider how to update the menu for existing tray icons
}
// --- 私有方法:定义菜单模板和逻辑 ---
// --- Private methods: define menu templates and logic ---
private getAppMenuTemplate(options?: MenuOptions): MenuItemConstructorOptions[] {
const appName = app.getName();
const showDev = isDev || options?.showDevItems;
// 创建命名空间翻译函数
// Create namespaced translation function
const t = this.app.i18n.ns('menu');
// 添加调试日志
// console.log('[MacOSMenu] 菜单渲染, i18n实例:', !!this.app.i18n);
// Add debug logging
// console.log('[MacOSMenu] Menu rendering, i18n instance:', !!this.app.i18n);
const template: MenuItemConstructorOptions[] = [
{
@@ -324,7 +324,7 @@ export class MacOSMenu extends BaseMenuPlatform implements IMenuPlatform {
},
{
click: () => {
// @ts-expect-error cache 目录好像暂时不在类型定义里
// @ts-expect-error cache directory seems to be temporarily missing from type definitions
const cachePath = app.getPath('cache');
const updaterCachePath = path.join(cachePath, `${app.getName()}-updater`);
+1 -1
View File
@@ -43,7 +43,7 @@ export class WindowsMenu extends BaseMenuPlatform implements IMenuPlatform {
refresh(options?: MenuOptions): void {
this.buildAndSetAppMenu(options);
// 如果有必要更新托盘菜单,可以在这里添加逻辑
// If it's necessary to update tray menu, logic can be added here
}
private getAppMenuTemplate(options?: MenuOptions): MenuItemConstructorOptions[] {
+111
View File
@@ -1,4 +1,115 @@
[
{
"children": {},
"date": "2026-02-03",
"version": "2.1.13"
},
{
"children": {},
"date": "2026-02-03",
"version": "2.1.12"
},
{
"children": {
"fixes": ["Hide password features when AUTH_DISABLE_EMAIL_PASSWORD is set."]
},
"date": "2026-02-02",
"version": "2.1.11"
},
{
"children": {},
"date": "2026-02-02",
"version": "2.1.10"
},
{
"children": {
"fixes": ["Use oauth2.link for generic OIDC provider account linking."]
},
"date": "2026-02-02",
"version": "2.1.9"
},
{
"children": {
"improvements": ["Improve tasks display."]
},
"date": "2026-02-01",
"version": "2.1.8"
},
{
"children": {
"fixes": ["Add missing description parameter docs in Notebook system prompt."]
},
"date": "2026-02-01",
"version": "2.1.7"
},
{
"children": {
"improvements": ["Improve local-system tool implement."]
},
"date": "2026-02-01",
"version": "2.1.6"
},
{
"children": {
"fixes": ["Slove the group member agents cant set skills problem."]
},
"date": "2026-01-31",
"version": "2.1.5"
},
{
"children": {
"improvements": ["Update i18n, Update Kimi K2.5 & Qwen3 Max Thinking models."]
},
"date": "2026-01-31",
"version": "2.1.4"
},
{
"children": {},
"date": "2026-01-31",
"version": "2.1.3"
},
{
"children": {
"fixes": ["Fix feishu sso provider."]
},
"date": "2026-01-30",
"version": "2.1.2"
},
{
"children": {
"fixes": ["Correct desktop download URL path."]
},
"date": "2026-01-30",
"version": "2.1.1"
},
{
"children": {
"features": ["Refactor cron job UI and use runtime enableBusinessFeatures flag."]
},
"date": "2026-01-30",
"version": "2.1.0"
},
{
"children": {
"improvements": ["Fix usage table display issues."]
},
"date": "2026-01-29",
"version": "2.0.13"
},
{
"children": {
"fixes": ["Group publish to market should set local group market identifer."]
},
"date": "2026-01-29",
"version": "2.0.12"
},
{
"children": {
"improvements": ["Fix group task render."]
},
"date": "2026-01-29",
"version": "2.0.11"
},
{
"children": {
"fixes": ["Add ExtendParamsTypeSchema for enhanced model settings."]
-50
View File
@@ -1,50 +0,0 @@
## chore(i18n): Adjust Latin language locales for terminology consistency
This comprehensive update ensures all Latin language locales (de-DE, fr-FR, es-ES, it-IT, pt-BR, nl-NL, pl-PL) follow the microcopy style guide's terminology requirements.
### Changes Made
**Total: 557 changes across 7 Latin locales**
#### Primary Terminology Updates
1. **"Plugin" → "Skill"**
- Fixed terminology inconsistency across all Latin languages
- UI elements now consistently use "Skill" instead of localized equivalents
- Includes both singular and plural forms: `plugin/Skill`, `plugins/Skills`
2. **"LobeChat" → "LobeHub"**
- Updated brand name references to current branding
3. **"Agent" Terminology Consistency**
- French: Fixed inconsistent "Assistant" → "Agent" usage in UI elements
- Ensured consistent terminology across all languages
#### Per-Locale Breakdown
- **de-DE (German)**: 267 changes
- **fr-FR (French)**: 94 changes (including 7 Agent→Assistant fixes)
- **es-ES (Spanish)**: 39 changes
- **it-IT (Italian)**: 59 changes (including 18 plugin→skill fixes)
- **pt-BR (Portuguese)**: 58 changes
- **nl-NL (Dutch)**: 62 changes
- **pl-PL (Polish)**: 28 changes
#### Files Modified
- All 37 locale JSON files for each language (259 total files)
- Includes: auth.json, chat.json, common.json, discover.json, plugin.json, setting.json, etc.
#### Key Improvements
1. **Fixed Terminology**: Following microcopy guide's fixed terminology rules
2. **Brand Consistency**: Changed all brand references to "LobeHub"
3. **Natural Localization**: Maintained natural language patterns while ensuring consistency
4. **User Experience**: Improved consistency across all Latin language interfaces
### Scripts Created
Two utility scripts for future locale maintenance:
- `scripts/adjust-latin-locales.py` - For common.json specific adjustments
- `scripts/adjust-latin-locales-full.py` - For comprehensive adjustments across all files
### Review Notes
- All changes maintain backward compatibility
- No breaking changes to functionality
- JSON files validated and remain syntactically correct
- Changes reviewed against English base for consistency
+37
View File
@@ -0,0 +1,37 @@
# Proxy, if you need it
# HTTP_PROXY=http://localhost:7890
# HTTPS_PROXY=http://localhost:7890
# Allowed email addresses for login, separated by commas
# When set, only emails in the list can log in, other users cannot log in
# Leave empty to allow all users to register
# AUTH_ALLOWED_EMAILS=user1@example.com,user2@example.com
# Disable user registration (SSO-only mode)
# When set to 1, users cannot register via email/password, only SSO login is allowed
# AUTH_DISABLE_EMAIL_PASSWORD=1
# ===========================
# ====== Preset config ======
# ===========================
# if no special requirements, no need to change
LOBE_PORT=3210
RUSTFS_PORT=9000
APP_URL=http://localhost:3210
# INTERNAL_APP_URL is optional, used for server-to-server calls
# to bypass CDN/proxy. If not set, defaults to APP_URL.
# Example: INTERNAL_APP_URL=http://localhost:3210
# Postgres related, which are the necessary environment variables for DB
LOBE_DB_NAME=lobechat
POSTGRES_PASSWORD=uWNZugjBqixf8dxC
# RUSTFS S3 configuration
RUSTFS_ACCESS_KEY=admin
RUSTFS_SECRET_KEY=YOUR_RUSTFS_PASSWORD
# Configure the bucket information of RUSTFS
S3_ENDPOINT=http://localhost:9000
RUSTFS_LOBE_BUCKET=lobe
JWKS_KEY={"keys":[{"d":"PVoFyqyrGstB8wU52S7gqqQQdZLtin_thcEM0nrNtqp9U-NlKLlhgEcWp5t89ycgvhsAzmrRbezGj4JBTr3jn7eWdwQpPJNYiipnsgeJn0pwsB0H2dMqtavxinoPVXkMTOuGHMTFhhyguFBw2JbIL0PTQUcUlXjv40OoJpYHZeggSxgfV-TuxjwW8Ll4-n84M5IOi6A53RvioE-Hm1iyIc2XLBCfyOu-SbAQYi8HzrA64kCxobAB0peLQMiAzfZmwPKiGOhnhKrAlYmG02qFnbUYiJu_-AXwsAyGv9S9i6dwK7QXaGGWYyis8LlPpd_JmPrBnrWomwDlI045NUMWZQ","dp":"OSXI2NBBZl2r0Dpf4-1z44A_jC5lOyXtJhXQYnSXy5eIuxTJcEtkUYagGEwnREO4Q3t-4J-lT_6Y71M1ZlgKG1upwfw1O4aE3vGpHOik9iZYYCjA8fe5uBfOpX1ELmOtHNoHRhMtyjuPxSFXLlSp3bgcF1f3F40ClukdvXCx0Mc","dq":"m6hNdfj-F8E_7nUlX2nG95OffkFrhHTo67ML9aPgpvFwBlzg-hk5LwtxMfUzngqWF78TMl0JDm7vS1bz0xlWqXqu8pFPoTUnUoWgYfvuyHLBwR5TgccQkfoKbkSMzYNy8VJPXZeyIjVXsW98tZvj-NZF-M9Pke_EWJm-jjXCu_8","e":"AQAB","kty":"RSA","n":"piffosMS0HOSgsSr_zQkXYaQt1kOCD73VR0b2XJD6UdQCKPbnBOzTIuA_xowX61QVsl5pCZLTw8ERC3r2Nlxj5Rp_H6RuOT7ioUqlbnxSGnfuAn8dFupY3A-sf9HVDOvtJdlS-nO9yA4wWU-A50zZ1Mf0pPZlUZE6dUQfsJFi5yXaNAybyk3U4VpMO_SXAilWEHVhiO0F0ccpJMCkT47AeXmYH9MlWwIGcay0UiAsdrs8J-q1arZ7Mbq0oxHmUXJG0vwRvAL8KnCEi8cJ3e2kKCRcr-BQCujsHUyUl6f_ATwSVuTHdAR1IzIcW37v27h3WQK_v0ffQM1NstamDX5vQ","p":"4myVm2M5cZGvVXsOmWUTUG87VC1GlQcL5tmMNSGSpQCL8yWZ1vANkmCxSMptrKB4dU9DAB3On6_oMhW1pJ3uYNGSW49BcmJoLkiWKeg5zWFnKPQNuThQmY1sCCubtKhBQgaYUr7TVzN9smrDV3zCu9MlRl-XPwnEmWaDII3g-f8","q":"u9v4IOEsb4l2Y3eWKE2bwJh5fJRR4vivaYA7U-1-OpvDwB3A48Rey9IL1ucXqE5G1Du8BtijPm5oSAar5uzrjtg1bZ9gevif6DnBGaIRE7LnSrUsTPfZwzntJ1rTaGiVe_pAdnTKXXaH6DxygXxH4wvGgA44V3TTfBXQUcjzdEM","qi":"lDBnSPKkRnYqQvbqVD1LxzqBPEeqEA3GyCqMj6fIZNgoEaBSLi0TSsUyGZ5mahX3KO35vKAZa5jvGjhvUGUiXycq8KvRZdeGK45vJdwZT2TiXiDwo9IQgJcbFMpxaB9DhjX2x0yqxgUY5ca75jLqbMuKBKBN0PVqIr9jlHkR8_s","use":"sig","kid":"6823046760c5d460","alg":"RS256"}]}
+34
View File
@@ -0,0 +1,34 @@
# Proxy,如果你需要的话(比如你使用 GitHub 作为鉴权服务提供商)
# HTTP_PROXY=http://localhost:7890
# HTTPS_PROXY=http://localhost:7890
# 允许登录的邮箱地址,用英文逗号分隔
# 设置后只有列表中的邮箱可以登录,其他用户可以注册但无法登录
# 留空则允许所有用户注册登录
# AUTH_ALLOWED_EMAILS=user1@example.com,user2@example.com
# 禁用用户注册(仅允许 SSO 登录)
# 设置为 1 后,用户无法通过邮箱密码注册,只能通过 SSO 登录
# AUTH_DISABLE_EMAIL_PASSWORD=1
# ===================
# ===== 预设配置 =====
# ===================
# 如没有特殊需要不用更改
LOBE_PORT=3210
RUSTFS_PORT=9000
APP_URL=http://localhost:3210
# Postgres 相关,也即 DB 必须的环境变量
LOBE_DB_NAME=lobehub
POSTGRES_PASSWORD=uWNZugjBqixf8dxC
# RustFS S3 配置
RUSTFS_ACCESS_KEY=admin
RUSTFS_SECRET_KEY=YOUR_RUSTFS_PASSWORD
# 在下方配置 rustfs 中添加的桶
S3_ENDPOINT=http://localhost:9000
RUSTFS_LOBE_BUCKET=lobe
JWKS_KEY={"keys":[{"d":"PVoFyqyrGstB8wU52S7gqqQQdZLtin_thcEM0nrNtqp9U-NlKLlhgEcWp5t89ycgvhsAzmrRbezGj4JBTr3jn7eWdwQpPJNYiipnsgeJn0pwsB0H2dMqtavxinoPVXkMTOuGHMTFhhyguFBw2JbIL0PTQUcUlXjv40OoJpYHZeggSxgfV-TuxjwW8Ll4-n84M5IOi6A53RvioE-Hm1iyIc2XLBCfyOu-SbAQYi8HzrA64kCxobAB0peLQMiAzfZmwPKiGOhnhKrAlYmG02qFnbUYiJu_-AXwsAyGv9S9i6dwK7QXaGGWYyis8LlPpd_JmPrBnrWomwDlI045NUMWZQ","dp":"OSXI2NBBZl2r0Dpf4-1z44A_jC5lOyXtJhXQYnSXy5eIuxTJcEtkUYagGEwnREO4Q3t-4J-lT_6Y71M1ZlgKG1upwfw1O4aE3vGpHOik9iZYYCjA8fe5uBfOpX1ELmOtHNoHRhMtyjuPxSFXLlSp3bgcF1f3F40ClukdvXCx0Mc","dq":"m6hNdfj-F8E_7nUlX2nG95OffkFrhHTo67ML9aPgpvFwBlzg-hk5LwtxMfUzngqWF78TMl0JDm7vS1bz0xlWqXqu8pFPoTUnUoWgYfvuyHLBwR5TgccQkfoKbkSMzYNy8VJPXZeyIjVXsW98tZvj-NZF-M9Pke_EWJm-jjXCu_8","e":"AQAB","kty":"RSA","n":"piffosMS0HOSgsSr_zQkXYaQt1kOCD73VR0b2XJD6UdQCKPbnBOzTIuA_xowX61QVsl5pCZLTw8ERC3r2Nlxj5Rp_H6RuOT7ioUqlbnxSGnfuAn8dFupY3A-sf9HVDOvtJdlS-nO9yA4wWU-A50zZ1Mf0pPZlUZE6dUQfsJFi5yXaNAybyk3U4VpMO_SXAilWEHVhiO0F0ccpJMCkT47AeXmYH9MlWwIGcay0UiAsdrs8J-q1arZ7Mbq0oxHmUXJG0vwRvAL8KnCEi8cJ3e2kKCRcr-BQCujsHUyUl6f_ATwSVuTHdAR1IzIcW37v27h3WQK_v0ffQM1NstamDX5vQ","p":"4myVm2M5cZGvVXsOmWUTUG87VC1GlQcL5tmMNSGSpQCL8yWZ1vANkmCxSMptrKB4dU9DAB3On6_oMhW1pJ3uYNGSW49BcmJoLkiWKeg5zWFnKPQNuThQmY1sCCubtKhBQgaYUr7TVzN9smrDV3zCu9MlRl-XPwnEmWaDII3g-f8","q":"u9v4IOEsb4l2Y3eWKE2bwJh5fJRR4vivaYA7U-1-OpvDwB3A48Rey9IL1ucXqE5G1Du8BtijPm5oSAar5uzrjtg1bZ9gevif6DnBGaIRE7LnSrUsTPfZwzntJ1rTaGiVe_pAdnTKXXaH6DxygXxH4wvGgA44V3TTfBXQUcjzdEM","qi":"lDBnSPKkRnYqQvbqVD1LxzqBPEeqEA3GyCqMj6fIZNgoEaBSLi0TSsUyGZ5mahX3KO35vKAZa5jvGjhvUGUiXycq8KvRZdeGK45vJdwZT2TiXiDwo9IQgJcbFMpxaB9DhjX2x0yqxgUY5ca75jLqbMuKBKBN0PVqIr9jlHkR8_s","use":"sig","kid":"6823046760c5d460","alg":"RS256"}]}
+18
View File
@@ -0,0 +1,18 @@
{
"ID": "",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": ["*"]
},
"Action": ["s3:GetObject"],
"NotAction": [],
"Resource": ["arn:aws:s3:::lobe/*"],
"NotResource": [],
"Condition": {}
}
],
"Version": "2012-10-17"
}
+148
View File
@@ -0,0 +1,148 @@
name: lobehub
services:
network-service:
image: alpine
container_name: lobe-network
restart: always
ports:
- '${RUSTFS_PORT}:9000' # RustFS API
- '9001:9001' # RustFS Console
- '${LOBE_PORT}:3210' # LobeChat
command: tail -f /dev/null
networks:
- lobe-network
postgresql:
image: paradedb/paradedb:latest-pg17
container_name: lobe-postgres
ports:
- '5432:5432'
volumes:
- './data:/var/lib/postgresql/data'
environment:
- 'POSTGRES_DB=${LOBE_DB_NAME}'
- 'POSTGRES_PASSWORD=${POSTGRES_PASSWORD}'
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U postgres']
interval: 5s
timeout: 5s
retries: 5
restart: always
networks:
- lobe-network
redis:
image: redis:7-alpine
container_name: lobe-redis
ports:
- '6379:6379'
command: redis-server --save 60 1000 --appendonly yes
volumes:
- 'redis_data:/data'
healthcheck:
test: ['CMD', 'redis-cli', 'ping']
interval: 5s
timeout: 3s
retries: 5
restart: always
networks:
- lobe-network
rustfs:
image: rustfs/rustfs:latest
container_name: lobe-rustfs
network_mode: 'service:network-service'
environment:
- RUSTFS_CONSOLE_ENABLE=true
- RUSTFS_ACCESS_KEY=${RUSTFS_ACCESS_KEY}
- RUSTFS_SECRET_KEY=${RUSTFS_SECRET_KEY}
volumes:
- rustfs-data:/data
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://localhost:9000/health >/dev/null 2>&1 || exit 1"]
interval: 5s
timeout: 3s
retries: 30
command: ["--access-key","${RUSTFS_ACCESS_KEY}","--secret-key","${RUSTFS_SECRET_KEY}","/data"]
rustfs-init:
image: minio/mc:latest
container_name: lobe-rustfs-init
depends_on:
rustfs:
condition: service_healthy
volumes:
- ./bucket.config.json:/bucket.config.json:ro
entrypoint: /bin/sh
command: -c '
set -eux;
echo "S3_ACCESS_KEY=${RUSTFS_ACCESS_KEY}, S3_SECRET_KEY=${RUSTFS_SECRET_KEY}";
mc --version;
mc alias set rustfs "http://network-service:9000" "${RUSTFS_ACCESS_KEY}" "${RUSTFS_SECRET_KEY}";
mc ls rustfs || true;
mc mb "rustfs/lobe" --ignore-existing;
mc admin info rustfs || true;
mc anonymous set-json "/bucket.config.json" "rustfs/lobe";
'
restart: "no"
networks:
- lobe-network
searxng:
image: searxng/searxng
container_name: lobe-searxng
volumes:
- './searxng-settings.yml:/etc/searxng/settings.yml'
environment:
- 'SEARXNG_SETTINGS_FILE=/etc/searxng/settings.yml'
restart: always
networks:
- lobe-network
env_file:
- .env
lobe:
image: lobehub/lobehub
container_name: lobehub
network_mode: 'service:network-service'
depends_on:
postgresql:
condition: service_healthy
network-service:
condition: service_started
rustfs:
condition: service_healthy
rustfs-init:
condition: service_completed_successfully
redis:
condition: service_healthy
environment:
- 'KEY_VAULTS_SECRET=Kix2wcUONd4CX51E/ZPAd36BqM4wzJgKjPtz2sGztqQ='
- 'AUTH_SECRET=NX2kaPE923dt6BL2U8e9oSre5RfoT7hg'
- 'DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgresql:5432/${LOBE_DB_NAME}'
- 'S3_BUCKET=${RUSTFS_LOBE_BUCKET}'
- 'S3_ENABLE_PATH_STYLE=1'
- 'S3_ACCESS_KEY=${RUSTFS_ACCESS_KEY}'
- 'S3_ACCESS_KEY_ID=${RUSTFS_ACCESS_KEY}'
- 'S3_SECRET_ACCESS_KEY=${RUSTFS_SECRET_KEY}'
- 'LLM_VISION_IMAGE_USE_BASE64=1'
- 'S3_SET_ACL=0'
- 'SEARXNG_URL=http://searxng:8080'
- 'REDIS_URL=redis://redis:6379'
- 'REDIS_PREFIX=lobechat'
- 'REDIS_TLS=0'
env_file:
- .env
restart: always
volumes:
data:
driver: local
redis_data:
driver: local
rustfs-data:
driver: local
networks:
lobe-network:
driver: bridge
File diff suppressed because it is too large Load Diff
-1
View File
@@ -37,7 +37,6 @@ RUSTFS_ACCESS_KEY=admin
RUSTFS_SECRET_KEY=YOUR_RUSTFS_PASSWORD
# Configure the bucket information of RUSTFS
S3_PUBLIC_DOMAIN=http://localhost:9000
S3_ENDPOINT=http://localhost:9000
RUSTFS_LOBE_BUCKET=lobe
-1
View File
@@ -34,7 +34,6 @@ RUSTFS_ACCESS_KEY=admin
RUSTFS_SECRET_KEY=YOUR_RUSTFS_PASSWORD
# 在下方配置 rustfs 中添加的桶
S3_PUBLIC_DOMAIN=http://localhost:9000
S3_ENDPOINT=http://localhost:9000
RUSTFS_LOBE_BUCKET=lobe
@@ -34,7 +34,6 @@ MINIO_ROOT_USER=admin
MINIO_ROOT_PASSWORD=YOUR_MINIO_PASSWORD
# Configure the bucket information of MinIO
S3_PUBLIC_DOMAIN=http://localhost:9000
S3_ENDPOINT=http://localhost:9000
MINIO_LOBE_BUCKET=lobe
@@ -34,7 +34,6 @@ MINIO_ROOT_USER=admin
MINIO_ROOT_PASSWORD=YOUR_MINIO_PASSWORD
# 在下方配置 minio 中添加的桶
S3_PUBLIC_DOMAIN=http://localhost:9000
S3_ENDPOINT=http://localhost:9000
MINIO_LOBE_BUCKET=lobe
@@ -103,7 +103,6 @@ services:
- 'DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgresql:5432/${LOBE_DB_NAME}'
- 'S3_ENDPOINT=http://localhost:${MINIO_PORT}'
- 'S3_BUCKET=${MINIO_LOBE_BUCKET}'
- 'S3_PUBLIC_DOMAIN=http://localhost:${MINIO_PORT}'
- 'S3_ENABLE_PATH_STYLE=1'
- 'REDIS_URL=redis://redis:6379'
- 'REDIS_PREFIX=lobechat'
+2 -3
View File
@@ -12,7 +12,7 @@ DATABASE_URL=postgresql://postgres:uWNZugjBqixf8dxC@postgresql:5432/lobechat
AUTH_SECRET=NX2kaPE923dt6BL2U8e9oSre5RfoT7hg
AUTH_SSO_PROVIDERS=zitadel
# ZiTADEL provider configuration
# Please refer tohttps://lobehub.com/zh/docs/self-hosting/advanced/auth/providers/zitadel
# Please refer to: https://lobehub.com/docs/self-hosting/auth/providers/zitadel
AUTH_ZITADEL_ID=285945938244075523
AUTH_ZITADEL_SECRET=hkbtzHLaCEIeHeFThym14UcydpmQiEB5JtAX08HSqSoJxhAlVVkyovTuNUZ5TNrT
AUTH_ZITADEL_ISSUER=http://localhost:8080
@@ -21,8 +21,7 @@ AUTH_ZITADEL_ISSUER=http://localhost:8080
S3_ACCESS_KEY_ID=
S3_SECRET_ACCESS_KEY=
S3_ENDPOINT=http://localhost:9000
S3_BUCKET=lobe
S3_PUBLIC_DOMAIN=http://localhost:9000
S3_BUCKET=lobe
S3_ENABLE_PATH_STYLE=1
LLM_VISION_IMAGE_USE_BASE64=1
@@ -11,7 +11,7 @@ DATABASE_URL=postgresql://postgres:uWNZugjBqixf8dxC@postgresql:5432/lobechat
AUTH_SECRET=NX2kaPE923dt6BL2U8e9oSre5RfoT7hg
AUTH_SSO_PROVIDERS=zitadel
# ZiTADEL 鉴权服务提供商部分
# 请参考:https://lobehub.com/zh/docs/self-hosting/advanced/auth/next-auth/zitadel
# 请参考:https://lobehub.com/zh/docs/self-hosting/auth/providers/zitadel
AUTH_ZITADEL_ID=285945938244075523
AUTH_ZITADEL_SECRET=hkbtzHLaCEIeHeFThym14UcydpmQiEB5JtAX08HSqSoJxhAlVVkyovTuNUZ5TNrT
AUTH_ZITADEL_ISSUER=http://localhost:8080
@@ -20,8 +20,7 @@ AUTH_ZITADEL_ISSUER=http://localhost:8080
S3_ACCESS_KEY_ID=
S3_SECRET_ACCESS_KEY=
S3_ENDPOINT=http://localhost:9000
S3_BUCKET=lobe
S3_PUBLIC_DOMAIN=http://localhost:9000
S3_BUCKET=lobe
S3_ENABLE_PATH_STYLE=1
LLM_VISION_IMAGE_USE_BASE64=1
@@ -34,7 +34,6 @@ MINIO_ROOT_USER=admin
MINIO_ROOT_PASSWORD=YOUR_MINIO_PASSWORD
# Configure the bucket information of MinIO
S3_PUBLIC_DOMAIN=http://localhost:9000
S3_ENDPOINT=http://localhost:9000
MINIO_LOBE_BUCKET=lobe
@@ -34,7 +34,6 @@ MINIO_ROOT_USER=admin
MINIO_ROOT_PASSWORD=YOUR_MINIO_PASSWORD
# 在下方配置 minio 中添加的桶
S3_PUBLIC_DOMAIN=http://localhost:9000
S3_ENDPOINT=http://localhost:9000
MINIO_LOBE_BUCKET=lobe
+1 -3
View File
@@ -12,7 +12,7 @@ DATABASE_URL=postgresql://postgres:uWNZugjBqixf8dxC@postgresql:5432/lobe
# Authentication related environment variables
# Supports Auth0, Azure AD, GitHub, Authentik, Zitadel, Logto, etc.
# For supported providers, see: https://lobehub.com/docs/self-hosting/advanced/auth
# For supported providers, see: https://lobehub.com/docs/self-hosting/auth
# If you have ACCESS_CODE, please remove it. We use Better Auth as the sole authentication source
# Required: Auth secret key. Generate with: openssl rand -base64 32
AUTH_SECRET=NX2kaPE923dt6BL2U8e9oSre5RfoT7hg
@@ -38,8 +38,6 @@ S3_SECRET_ACCESS_KEY=YOUR_S3_SECRET_ACCESS_KEY
S3_ENDPOINT=https://lobe-s3-api.example.com
# Required: S3 Bucket (invalid until manually created in MinIO UI)
S3_BUCKET=lobe
# Required: S3 Public Domain for client access to unstructured data
S3_PUBLIC_DOMAIN=https://lobe-s3-api.example.com
# Optional: S3 Enable Path Style
# Use 0 for mainstream S3 cloud providers; use 1 for self-hosted MinIO
# See: https://lobehub.com/docs/self-hosting/advanced/s3#s-3-enable-path-style
@@ -11,7 +11,7 @@ DATABASE_URL=postgresql://postgres:uWNZugjBqixf8dxC@postgresql:5432/lobe
# 鉴权服务必需的环境变量
# 可以使用 Auth0、Azure AD、GitHub、Authentik、Zitadel、Logto 等,如有其他接入诉求欢迎提 PR
# 目前支持的鉴权服务提供商请参考:https://lobehub.com/zh/docs/self-hosting/advanced/auth
# 目前支持的鉴权服务提供商请参考:https://lobehub.com/zh/docs/self-hosting/auth
# 如果你有 ACCESS_CODE,请务必清空,我们以 Better Auth 作为唯一鉴权来源
# 必填,用于鉴权的密钥,可以使用 openssl rand -base64 32 生成
AUTH_SECRET=NX2kaPE923dt6BL2U8e9oSre5RfoT7hg
@@ -38,8 +38,6 @@ S3_SECRET_ACCESS_KEY=YOUR_S3_SECRET_ACCESS_KEY
S3_ENDPOINT=https://lobe-s3-api.example.com
# 必填,S3 的 Bucket,直到在 MinIO UI 中手动创建之前都是无效的
S3_BUCKET=lobe
# 必填,S3 的 Public Domain,用于客户端通过公开连接访问非结构化数据
S3_PUBLIC_DOMAIN=https://lobe-s3-api.example.com
# 选填,S3 的 Enable Path Style
# 对于主流 S3 Cloud 服务商,一般填 0 即可;对于自部署的 MinIO,请填 1
# 请参考:https://lobehub.com/zh/docs/self-hosting/advanced/s3#s-3-enable-path-style
@@ -17,7 +17,7 @@ AUTH_SECRET=NX2kaPE923dt6BL2U8e9oSre5RfoT7hg
AUTH_SSO_PROVIDERS=zitadel
# ZiTADEL provider configuration
# Please refer tohttps://lobehub.com/zh/docs/self-hosting/advanced/auth/providers/zitadel
# Please refer to: https://lobehub.com/docs/self-hosting/auth/providers/zitadel
AUTH_ZITADEL_ID=285934220675723622
AUTH_ZITADEL_SECRET=pe7Nh3lopXkZkfqh5YEDYI2xsbIz08eZKqInOUZxssd3refRia518Apbv3DZ
AUTH_ZITADEL_ISSUER=https://zitadel.example.com
@@ -35,8 +35,6 @@ S3_SECRET_ACCESS_KEY=YOUR_S3_SECRET_ACCESS_KEY
S3_ENDPOINT=https://lobe-s3-api.example.com
# Required: S3 Bucket (invalid until manually created in MinIO UI)
S3_BUCKET=lobe
# Required: S3 Public Domain for client access to unstructured data
S3_PUBLIC_DOMAIN=https://lobe-s3-api.example.com
# Optional: S3 Enable Path Style
# Use 0 for mainstream S3 cloud providers; use 1 for self-hosted MinIO
# See: https://lobehub.com/docs/self-hosting/advanced/s3#s-3-enable-path-style
@@ -16,7 +16,7 @@ AUTH_SECRET=NX2kaPE923dt6BL2U8e9oSre5RfoT7hg
AUTH_SSO_PROVIDERS=zitadel
# ZiTADEL 鉴权服务提供商部分
# 请参考:https://lobehub.com/zh/docs/self-hosting/advanced/auth/next-auth/zitadel
# 请参考:https://lobehub.com/zh/docs/self-hosting/auth/providers/zitadel
AUTH_ZITADEL_ID=285934220675723622
AUTH_ZITADEL_SECRET=pe7Nh3lopXkZkfqh5YEDYI2xsbIz08eZKqInOUZxssd3refRia518Apbv3DZ
AUTH_ZITADEL_ISSUER=https://zitadel.example.com
@@ -31,8 +31,6 @@ S3_SECRET_ACCESS_KEY=YOUR_S3_SECRET_ACCESS_KEY
S3_ENDPOINT=https://lobe-s3-api.example.com
# 必填,S3 的 Bucket,直到在 MinIO UI 中手动创建之前都是无效的
S3_BUCKET=lobe
# 必填,S3 的 Public Domain,用于客户端通过公开连接访问非结构化数据
S3_PUBLIC_DOMAIN=https://lobe-s3-api.example.com
# 选填,S3 的 Enable Path Style
# 对于主流 S3 Cloud 服务商,一般填 0 即可;对于自部署的 MinIO,请填 1
# 请参考:https://lobehub.com/zh/docs/self-hosting/advanced/s3#s-3-enable-path-style
+53 -90
View File
@@ -230,6 +230,20 @@ show_message() {
;;
esac
;;
tips_disable_registration)
case $LANGUAGE in
zh_CN)
echo "如需限制用户注册,可在 .env 中配置:"
echo " - 使用 SSO 登录时,设置 AUTH_DISABLE_EMAIL_PASSWORD=1 可禁用邮箱密码注册"
echo " - 使用邮箱密码登录时,设置 AUTH_ALLOWED_EMAILS=user1@example.com,user2@example.com 可限制允许登录的邮箱"
;;
*)
echo "To restrict user registration, configure in .env:"
echo " - For SSO login: set AUTH_DISABLE_EMAIL_PASSWORD=1 to disable email/password registration"
echo " - For email/password login: set AUTH_ALLOWED_EMAILS=user1@example.com,user2@example.com to allow specific emails"
;;
esac
;;
tips_show_documentation)
case $LANGUAGE in
zh_CN)
@@ -263,10 +277,10 @@ show_message() {
tips_allow_ports)
case $LANGUAGE in
zh_CN)
echo "请确保服务器以下端口未被占用且能被访问:3210, 9000, 9001, 8000"
echo "请确保服务器以下端口未被占用且能被访问:3210, 9000, 9001"
;;
*)
echo "Please make sure the following ports on the server are not occupied and can be accessed: 3210, 9000, 9001, 8000"
echo "Please make sure the following ports on the server are not occupied and can be accessed: 3210, 9000, 9001"
;;
esac
;;
@@ -315,12 +329,10 @@ show_message() {
tips_init_database_failed)
case $LANGUAGE in
zh_CN)
echo "无法初始化数据库,为了避免你的数据重复初始化,请在首次成功启动时运行以下指令清空 Casdoor 初始配置文件:"
echo "echo '{}' > init_data.json"
echo "无法初始化数据库"
;;
*)
echo "Failed to initialize the database. To avoid your data being initialized repeatedly, run the following command to unmount the initial configuration file of Casdoor when you first start successfully:"
echo "echo '{}' > init_data.json"
echo "Failed to initialize the database."
;;
esac
;;
@@ -338,7 +350,7 @@ show_message() {
case $LANGUAGE in
zh_CN)
echo "请选择部署模式:"
echo "(0) 域名模式(访问时无需指明端口),需要使用反向代理服务 LobeHub, RustFS, Casdoor ,并分别分配一个域名;"
echo "(0) 域名模式(访问时无需指明端口),需要使用反向代理服务 LobeHub, RustFS,并分别分配一个域名;"
echo "(1) 端口模式(访问时需要指明端口,如使用IP访问,或域名+端口访问),需要放开指定端口;"
echo "(2) 本地模式(仅供本地测试使用)"
echo "如果你对这些内容疑惑,可以先选择使用本地模式进行部署,稍后根据文档指引再进行修改。"
@@ -346,7 +358,7 @@ show_message() {
;;
*)
echo "Please select the deployment mode:"
echo "(0) Domain mode (no need to specify the port when accessing), you need to use the reverse proxy service LobeHub, RustFS, Casdoor, and assign a domain name respectively;"
echo "(0) Domain mode (no need to specify the port when accessing), you need to use the reverse proxy service LobeHub, RustFS, and assign a domain name respectively;"
echo "(1) Port mode (need to specify the port when accessing, such as using IP access, or domain name + port access), you need to open the specified port;"
echo "(2) Local mode (for local testing only)"
echo "If you are confused about these contents, you can choose to deploy in local mode first, and then modify according to the document guide later."
@@ -408,31 +420,33 @@ download_file() {
}
print_centered() {
# Define colors
declare -A colors
colors=(
[black]="\e[30m"
[red]="\e[31m"
[green]="\e[32m"
[yellow]="\e[33m"
[blue]="\e[34m"
[magenta]="\e[35m"
[cyan]="\e[36m"
[white]="\e[37m"
[reset]="\e[0m"
)
local text="$1" # Get input texts
local color="${2:-reset}" # Get color, default to reset
local term_width=$(tput cols) # Get terminal width
local text_length=${#text} # Get text length
local padding=$(((term_width - text_length) / 2)) # Get padding
# Check if the color is valid
if [[ -z "${colors[$color]}" ]]; then
echo "Invalid color specified. Available colors: ${!colors[@]}"
return 1
fi
# Get color code (compatible with bash 3.x)
local color_code=""
local reset_code="\e[0m"
case "$color" in
black) color_code="\e[30m" ;;
red) color_code="\e[31m" ;;
green) color_code="\e[32m" ;;
yellow) color_code="\e[33m" ;;
blue) color_code="\e[34m" ;;
magenta) color_code="\e[35m" ;;
cyan) color_code="\e[36m" ;;
white) color_code="\e[37m" ;;
reset) color_code="\e[0m" ;;
*)
echo "Invalid color specified. Available colors: black red green yellow blue magenta cyan white reset"
return 1
;;
esac
# Print the text with padding
printf "%*s${colors[$color]}%s${colors[reset]}\n" $padding "" "$text"
printf "%*s${color_code}%s${reset_code}\n" $padding "" "$text"
}
# Usage:
@@ -469,10 +483,9 @@ ask() {
# == Variables ==
# ===============
# File list
SUB_DIR="docker-compose/local"
SUB_DIR="docker-compose/deploy"
FILES=(
"$SUB_DIR/docker-compose.yml"
"$SUB_DIR/init_data.json"
"$SUB_DIR/searxng-settings.yml"
"$SUB_DIR/bucket.config.json"
)
@@ -481,10 +494,7 @@ ENV_EXAMPLES=(
"$SUB_DIR/.env.example"
)
# Default values
CASDOOR_PASSWORD="pswd123"
CASDOOR_SECRET="CASDOOR_SECRET"
RUSTFS_SECRET_KEY="YOUR_RUSTFS_PASSWORD"
CASDOOR_HOST="localhost:8000"
RUSTFS_HOST="localhost:9000"
PROTOCOL="http"
@@ -514,9 +524,8 @@ section_download_files(){
fi
download_file "$SOURCE_URL/${FILES[0]}" "docker-compose.yml"
download_file "$SOURCE_URL/${FILES[1]}" "init_data.json"
download_file "$SOURCE_URL/${FILES[2]}" "searxng-settings.yml"
download_file "$SOURCE_URL/${FILES[3]}" "bucket.config.json"
download_file "$SOURCE_URL/${FILES[1]}" "searxng-settings.yml"
download_file "$SOURCE_URL/${FILES[2]}" "bucket.config.json"
# Download .env.example with the specified language
if [ "$LANGUAGE" = "zh_CN" ]; then
download_file "$SOURCE_URL/${ENV_EXAMPLES[0]}" ".env"
@@ -576,15 +585,10 @@ section_configurate_host() {
echo "LobeHub" $(show_message "ask_domain" "example.com")
ask "(example.com)"
LOBE_HOST="$ask_result"
# If user use domain mode, ask for the domain of RustFS and Casdoor
# If user use domain mode, ask for the domain of RustFS
echo "RustFS S3 API" $(show_message "ask_domain" "s3.example.com")
ask "(s3.example.com)"
RUSTFS_HOST="$ask_result"
echo "Casdoor API" $(show_message "ask_domain" "auth.example.com")
ask "(auth.example.com)"
CASDOOR_HOST="$ask_result"
# Setup callback url for Casdoor
sed "${SED_INPLACE_ARGS[@]}" "s/"example.com"/${LOBE_HOST}/" init_data.json
;;
1)
DEPLOY_MODE="ip"
@@ -595,23 +599,16 @@ section_configurate_host() {
# If user use ip mode, append the port to the host
LOBE_HOST="${HOST}:3210"
RUSTFS_HOST="${HOST}:9000"
CASDOOR_HOST="${HOST}:8000"
# Setup callback url for Casdoor
sed "${SED_INPLACE_ARGS[@]}" "s/"localhost:3210"/${LOBE_HOST}/" init_data.json
;;
*)
echo "Invalid deploy mode: $ask_result"
exit 1
;;
esac
# lobe host
sed "${SED_INPLACE_ARGS[@]}" "s#^APP_URL=.*#APP_URL=$PROTOCOL://$LOBE_HOST#" .env
# auth related
sed "${SED_INPLACE_ARGS[@]}" "s#^AUTH_CASDOOR_ISSUER=.*#AUTH_CASDOOR_ISSUER=$PROTOCOL://$CASDOOR_HOST#" .env
sed "${SED_INPLACE_ARGS[@]}" "s#^origin=.*#origin=$PROTOCOL://$CASDOOR_HOST#" .env
# s3 related
sed "${SED_INPLACE_ARGS[@]}" "s#^S3_PUBLIC_DOMAIN=.*#S3_PUBLIC_DOMAIN=$PROTOCOL://$RUSTFS_HOST#" .env
sed "${SED_INPLACE_ARGS[@]}" "s#^S3_ENDPOINT=.*#S3_ENDPOINT=$PROTOCOL://$RUSTFS_HOST#" .env
@@ -664,37 +661,7 @@ section_regenerate_secrets() {
exit 1
fi
echo $(show_message "security_secrect_regenerate")
# Generate CASDOOR_SECRET
CASDOOR_SECRET=$(generate_key 32)
if [ $? -ne 0 ]; then
echo $(show_message "security_secrect_regenerate_failed") "CASDOOR_SECRET"
else
# Search and replace the value of CASDOOR_SECRET in .env
sed "${SED_INPLACE_ARGS[@]}" "s#^AUTH_CASDOOR_SECRET=.*#AUTH_CASDOOR_SECRET=${CASDOOR_SECRET}#" .env
if [ $? -ne 0 ]; then
echo $(show_message "security_secrect_regenerate_failed") "AUTH_CASDOOR_SECRET in \`.env\`"
fi
# replace `clientSecrect` in init_data.json
sed "${SED_INPLACE_ARGS[@]}" "s#dbf205949d704de81b0b5b3603174e23fbecc354#${CASDOOR_SECRET}#" init_data.json
if [ $? -ne 0 ]; then
echo $(show_message "security_secrect_regenerate_failed") "AUTH_CASDOOR_SECRET in \`init_data.json\`"
fi
fi
# Generate Casdoor User
CASDOOR_USER="admin"
CASDOOR_PASSWORD=$(generate_key 10)
if [ $? -ne 0 ]; then
echo $(show_message "security_secrect_regenerate_failed") "CASDOOR_PASSWORD"
CASDOOR_PASSWORD="pswd123"
else
# replace `password` in init_data.json
sed "${SED_INPLACE_ARGS[@]}" "s/"pswd123"/${CASDOOR_PASSWORD}/" init_data.json
if [ $? -ne 0 ]; then
echo $(show_message "security_secrect_regenerate_failed") "CASDOOR_PASSWORD in \`init_data.json\`"
fi
fi
# Generate RUSTFS S3 User Password
RUSTFS_SECRET_KEY=$(generate_key 8)
if [ $? -ne 0 ]; then
@@ -735,13 +702,10 @@ section_init_database() {
fi
docker compose pull
docker compose up --detach postgresql casdoor
docker compose up --detach postgresql
# hopefully enough time for even the slower systems
sleep 15
docker compose stop
# Init finished, remove init mount
echo '{}' > init_data.json
}
show_message "ask_init_database"
@@ -759,16 +723,14 @@ fi
section_display_configurated_report() {
# Display configuration reports
echo $(show_message "security_secrect_regenerate_report")
echo -e "LobeHub: \n - URL: $PROTOCOL://$LOBE_HOST \n - Username: user \n - Password: ${CASDOOR_PASSWORD} "
echo -e "Casdoor: \n - URL: $PROTOCOL://$CASDOOR_HOST \n - Username: admin \n - Password: ${CASDOOR_PASSWORD}\n"
echo -e "LobeHub: \n - URL: $PROTOCOL://$LOBE_HOST"
echo -e "RustFS: \n - URL: $PROTOCOL://$RUSTFS_HOST \n - Username: admin\n - Password: ${RUSTFS_SECRET_KEY}\n"
# if user run in domain mode, diplay reverse proxy configuration
if [[ "$DEPLOY_MODE" == "domain" ]]; then
echo $(show_message "tips_add_reverse_proxy")
printf "\n%s\t->\t%s\n" "$LOBE_HOST" "127.0.0.1:3210"
printf "%s\t->\t%s\n" "$CASDOOR_HOST" "127.0.0.1:8000"
printf "%s\t->\t%s\n" "$RUSTFS_HOST" "127.0.0.1:9000"
fi
@@ -777,7 +739,8 @@ section_display_configurated_report() {
printf "\n%s\n\n" "$(show_message "tips_run_command")"
print_centered "docker compose up --no-attach searxng" "green"
printf "\n%s\n" "$(show_message "tips_if_run_normally")"
printf "\n%s\n\n" "$(show_message "tips_regen_jwks")"
printf "\n%s\n" "$(show_message "tips_regen_jwks")"
printf "\n%s\n\n" "$(show_message "tips_disable_registration")"
print_centered "docker compose up -d --no-attach searxng" "green"
printf "\n%s\n" "$(show_message "tips_if_want_searxng_logs")"
print_centered "docker compose logs -f searxng" "white"
+1 -1
View File
@@ -9,7 +9,7 @@ tags:
# Seamless DeepSeek R1 Integration, Unlock a New Chain-of-Thought Experience
LobeChat completed its largest AI ecosystem expansion ever in February, delivering a more powerful and flexible AI chat experience.
LobeHub completed its largest AI ecosystem expansion ever in February, delivering a more powerful and flexible AI chat experience.
## 🌟 Major Updates
@@ -9,7 +9,7 @@ tags:
# 完美集成 DeepSeek R1 ,开启思维链新体验
LobeChat 在二月完成了史上最大规模的 AI 生态扩展,带来更强大、更灵活的 AI 对话体验。
LobeHub 在二月完成了史上最大规模的 AI 生态扩展,带来更强大、更灵活的 AI 对话体验。
## 🌟 重大更新
+1 -1
View File
@@ -9,7 +9,7 @@ tags:
# Seamless DeepSeek R1 Integration, Unlock a New Chain-of-Thought Experience
In March, LobeChat continued to refine the user experience—adding practical features like customizable hotkeys and data export, while further expanding the AI provider ecosystem.
In March, LobeHub continued to refine the user experience—adding practical features like customizable hotkeys and data export, while further expanding the AI provider ecosystem.
## 🌟 Key Updates
+1 -1
View File
@@ -9,7 +9,7 @@ tags:
# 完美集成 DeepSeek R1 ,开启思维链新体验
LobeChat 在三月持续优化用户体验,新增快捷键自定义、数据导出等实用功能,并扩展 AI 服务商生态。
LobeHub 在三月持续优化用户体验,新增快捷键自定义、数据导出等实用功能,并扩展 AI 服务商生态。
## 🌟 重要更新
+2 -2
View File
@@ -1,6 +1,6 @@
---
title: Brand-New Design Style and Desktop App Release ✨
description: LobeChat officially launches the desktop app, delivering a more modern and smoother experience.
description: LobeHub officially launches the desktop app, delivering a more modern and smoother experience.
tags:
- Desktop App
- LobeHub
@@ -9,7 +9,7 @@ tags:
# Brand-New Design Style and Desktop App Release ✨
In April, LobeChat shipped a major visual upgrade with the brand-new Lobe UI v2 design system, and officially released the desktop app—bringing a more modern and fluid experience.
In April, LobeHub shipped a major visual upgrade with the brand-new Lobe UI v2 design system, and officially released the desktop app—bringing a more modern and fluid experience.
## 🌟 Major Updates
@@ -1,6 +1,6 @@
---
title: 全新设计风格与桌面端发布 ✨
description: LobeChat 正式发布桌面端应用,带来更现代、更流畅的使用体验
description: LobeHub 正式发布桌面端应用,带来更现代、更流畅的使用体验
tags:
- 桌面端
- LobeHub
@@ -9,7 +9,7 @@ tags:
# 全新设计风格与桌面端发布 ✨
LobeChat 在四月完成重大视觉升级,推出全新 Lobe UI v2 设计系统,并正式发布桌面端应用,带来更现代、更流畅的使用体验。
LobeHub 在四月完成重大视觉升级,推出全新 Lobe UI v2 设计系统,并正式发布桌面端应用,带来更现代、更流畅的使用体验。
## 🌟 重大更新
+1 -1
View File
@@ -9,7 +9,7 @@ tags:
# Prompt Variables and Claude 4 Reasoning Model Support 🚀
From May to June, LobeChat continued to refine core capabilities—introducing a prompt-variables system, adding support for Claude 4 reasoning models, and expanding search and crawling across multiple AI providers.
From May to June, LobeHub continued to refine core capabilities—introducing a prompt-variables system, adding support for Claude 4 reasoning models, and expanding search and crawling across multiple AI providers.
## 🌟 Key Updates
+1 -1
View File
@@ -9,7 +9,7 @@ tags:
# 提示词变量与 Claude 4 推理模型支持 🚀
LobeChat 在五月至六月持续优化核心功能,新增提示词变量系统、支持 Claude 4 推理模型,并扩展多个 AI 服务商的搜索与推理能力。
LobeHub 在五月至六月持续优化核心功能,新增提示词变量系统、支持 Claude 4 推理模型,并扩展多个 AI 服务商的搜索与推理能力。
## 🌟 主要更新
+1 -1
View File
@@ -9,7 +9,7 @@ tags:
# MCP Marketplace and Search Provider Expansion 🔍
From June to July, LobeChat launched the MCP plugin marketplace, added support for multiple search providers, and integrated Amazon Cognito and Google SSO—continuing to improve both user experience and the developer ecosystem.
From June to July, LobeHub launched the MCP plugin marketplace, added support for multiple search providers, and integrated Amazon Cognito and Google SSO—continuing to improve both user experience and the developer ecosystem.
## 🌟 Major Updates
@@ -9,7 +9,7 @@ tags:
# MCP 市场与搜索服务商扩展 🔍
LobeChat 在六月至七月推出 MCP 插件市场,新增多个搜索服务商支持,并集成 Amazon Cognito 与 Google SSO 认证,持续优化用户体验与开发者生态。
LobeHub 在六月至七月推出 MCP 插件市场,新增多个搜索服务商支持,并集成 Amazon Cognito 与 Google SSO 认证,持续优化用户体验与开发者生态。
## 🌟 重大更新
@@ -9,7 +9,7 @@ tags:
# AI Image Generation and Desktop Enhancements 🎨
From July to August, LobeChat introduced AI image generation, added support for multiple providers, and continued improving the desktop experience and authentication system.
From July to August, LobeHub introduced AI image generation, added support for multiple providers, and continued improving the desktop experience and authentication system.
## 🌟 Major Updates
@@ -9,7 +9,7 @@ tags:
# AI 图像生成与桌面端增强 🎨
LobeChat 在七月至八月推出 AI 图像生成功能,新增多个服务商支持,并持续优化桌面端体验与认证系统。
LobeHub 在七月至八月推出 AI 图像生成功能,新增多个服务商支持,并持续优化桌面端体验与认证系统。
## 🌟 重大更新
+1 -1
View File
@@ -9,7 +9,7 @@ tags:
# Gemini Image Generation and Non-Streaming Mode Support 🎨
From August to September, LobeChat added Gemini 2.5 Flash Image generation, introduced non-streaming response mode support, and expanded provider and model support across the ecosystem.
From August to September, LobeHub added Gemini 2.5 Flash Image generation, introduced non-streaming response mode support, and expanded provider and model support across the ecosystem.
## 🌟 Major Updates
+1 -1
View File
@@ -9,7 +9,7 @@ tags:
# Gemini 图像生成与非流式模式支持 🎨
LobeChat 在八月至九月新增 Gemini 2.5 Flash Image 图像生成能力,支持非流式响应模式,并扩展多个 AI 服务商与模型支持。
LobeHub 在八月至九月新增 Gemini 2.5 Flash Image 图像生成能力,支持非流式响应模式,并扩展多个 AI 服务商与模型支持。
## 🌟 重大更新
+1 -1
View File
@@ -9,7 +9,7 @@ tags:
# Claude Sonnet 4.5 and Built-in Python Plugin 🐍
From September to October, LobeChat added support for Claude Sonnet 4.5, introduced a built-in Python plugin, and improved chat list navigation and rich text editing.
From September to October, LobeHub added support for Claude Sonnet 4.5, introduced a built-in Python plugin, and improved chat list navigation and rich text editing.
## 🌟 Key Updates
+1 -1
View File
@@ -9,7 +9,7 @@ tags:
# Claude Sonnet 4.5 与内置 Python 插件 🐍
LobeChat 在九月至十月新增 Claude Sonnet 4.5 模型支持,推出内置 Python 插件,并优化聊天列表导航与富文本编辑体验。
LobeHub 在九月至十月新增 Claude Sonnet 4.5 模型支持,推出内置 Python 插件,并优化聊天列表导航与富文本编辑体验。
## 🌟 主要更新
+1 -1
View File
@@ -9,7 +9,7 @@ tags:
# ComfyUI Integration and Knowledge Base Improvements ⭐
From October to November, LobeChat integrated ComfyUI workflows, added support for multiple AI providers and models, and continued to improve the knowledge base and overall user experience.
From October to November, LobeHub integrated ComfyUI workflows, added support for multiple AI providers and models, and continued to improve the knowledge base and overall user experience.
## 🌟 Key Updates
+1 -1
View File
@@ -9,7 +9,7 @@ tags:
# ComfyUI 集成与知识库优化 ⭐
LobeChat 在十月至十一月集成 ComfyUI 工作流,新增多个 AI 服务商与模型支持,并持续优化知识库与用户体验。
LobeHub 在十月至十一月集成 ComfyUI 工作流,新增多个 AI 服务商与模型支持,并持续优化知识库与用户体验。
## 🌟 重要更新
+1 -1
View File
@@ -10,7 +10,7 @@ tags:
# MCP Cloud Endpoints and Model Library Expansion 🔌
In November, LobeChat continued to improve model support and user experience by adding multiple AI providers and enhancing knowledge base capabilities.
In November, LobeHub continued to improve model support and user experience by adding multiple AI providers and enhancing knowledge base capabilities.
## 🌟 Key Updates
+1 -1
View File
@@ -10,7 +10,7 @@ tags:
# MCP 云端点与模型库扩展 🔌
LobeChat 在十一月持续优化模型支持与用户体验,新增多个 AI 服务商,并改进知识库功能。
LobeHub 在十一月持续优化模型支持与用户体验,新增多个 AI 服务商,并改进知识库功能。
## 🌟 重要更新
+1 -1
View File
@@ -6,7 +6,7 @@
"image": "/blog/assets7f3b38c1d76cceb91edb29d6b1eb60db.webp",
"id": "2025-12-20-mcp",
"date": "2025-12-20",
"versionRange": ["1.142.8", "1.143"]
"versionRange": ["1.142.8", "1.143.0"]
},
{
"image": "/blog/assets3a7f0b29839603336e39e923b423409b.webp",
@@ -114,7 +114,7 @@ AUTH_OKTA_ISSUER: process.env.AUTH_OKTA_ISSUER,
### Step 4: Update Documentation (Optional)
Add provider documentation in `docs/self-hosting/advanced/auth.mdx` and `docs/self-hosting/advanced/auth.zh-CN.mdx`.
Add provider documentation in `docs/self-hosting/auth.mdx` and `docs/self-hosting/auth.zh-CN.mdx`.
## Adding a Built-in Provider
@@ -12,7 +12,7 @@ tags:
LobeHub 使用 [Auth.js v5](https://authjs.dev/) 作为外部身份验证服务。Auth.js 是一个开源的身份验证库,它提供了一种简单的方式来实现身份验证和授权功能。本文档将介绍如何使用 Auth.js 来实现新的身份验证方式。
LobeChat 使用 [Better Auth](https://www.better-auth.com) 作为身份验证服务。本文档介绍如何添加新的 SSO 身份验证提供商。
LobeHub 使用 [Better Auth](https://www.better-auth.com) 作为身份验证服务。本文档介绍如何添加新的 SSO 身份验证提供商。
为了在 LobeHub 中添加新的身份验证提供者(例如添加 Okta),你需要完成以下步骤:
@@ -115,7 +115,7 @@ AUTH_OKTA_ISSUER: process.env.AUTH_OKTA_ISSUER,
### 步骤 4: 更新文档(可选)
在 `docs/self-hosting/advanced/auth.mdx` 和 `docs/self-hosting/advanced/auth.zh-CN.mdx` 中添加提供商文档。
在 `docs/self-hosting/auth.mdx` 和 `docs/self-hosting/auth.zh-CN.mdx` 中添加提供商文档。
## 添加内置提供商
@@ -11,7 +11,7 @@ tags:
# Adding New Image Models
> Learn more about the AI image generation modal design in the [AI Image Generation Modal Design Discussion](https://github.com/lobehub/lobe-chat/discussions/7442)
> Learn more about the AI image generation modal design in the [AI Image Generation Modal Design Discussion](https://github.com/lobehub/lobehub/discussions/7442)
## Parameter Standardization
@@ -65,7 +65,7 @@ For image generation models that are not compatible with OpenAI format, you need
### Method 1: Using OpenAI Compatible Factory
Most Providers use `openaiCompatibleFactory` for OpenAI compatibility. You can pass in a custom `createImage` function (reference [PR #8534](https://github.com/lobehub/lobe-chat/pull/8534)).
Most Providers use `openaiCompatibleFactory` for OpenAI compatibility. You can pass in a custom `createImage` function (reference [PR #8534](https://github.com/lobehub/lobehub/pull/8534)).
**Implementation Steps**:
@@ -124,7 +124,7 @@ export const LobeProviderAI = openaiCompatibleFactory({
### Method 2: Direct Implementation in Provider Class
If your Provider has an independent class implementation, you can directly add the `createImage` method in the class (reference [PR #8503](https://github.com/lobehub/lobe-chat/pull/8503)).
If your Provider has an independent class implementation, you can directly add the `createImage` method in the class (reference [PR #8503](https://github.com/lobehub/lobehub/pull/8503)).
**Implementation Steps**:
@@ -9,7 +9,7 @@ tags:
# 添加新的图像模型
> 了解更多关于 AI 绘画模态的设计,请参考 [AI 绘画模态设计讨论](https://github.com/lobehub/lobe-chat/discussions/7442)
> 了解更多关于 AI 绘画模态的设计,请参考 [AI 绘画模态设计讨论](https://github.com/lobehub/lobehub/discussions/7442)
## 参数标准化
@@ -63,7 +63,7 @@ const zhipuImageModels: AIImageModelCard[] = [
### 方式一:使用 OpenAI Compatible Factory
大部分 Provider 都使用 `openaiCompatibleFactory` 来兼容 OpenAI,可以通过传入自定义的 `createImage` 函数(参考 [PR #8534](https://github.com/lobehub/lobe-chat/pull/8534))。
大部分 Provider 都使用 `openaiCompatibleFactory` 来兼容 OpenAI,可以通过传入自定义的 `createImage` 函数(参考 [PR #8534](https://github.com/lobehub/lobehub/pull/8534))。
**实现步骤**
@@ -122,7 +122,7 @@ export const LobeProviderAI = openaiCompatibleFactory({
### 方式二:在 Provider 类中直接实现
如果你的 Provider 有独立的类实现,可以直接在类中添加 `createImage` 方法(参考 [PR #8503](https://github.com/lobehub/lobe-chat/pull/8503))。
如果你的 Provider 有独立的类实现,可以直接在类中添加 `createImage` 方法(参考 [PR #8503](https://github.com/lobehub/lobehub/pull/8503))。
**实现步骤**
+10 -10
View File
@@ -1,18 +1,18 @@
---
title: Lobe Chat API Client-Server Interaction Logic
title: LobeHub API Client-Server Interaction Logic
description: >-
Explore the client-server interaction logic of Lobe Chat API, including event
Explore the client-server interaction logic of LobeHub API, including event
sequences.
tags:
- Lobe Chat API
- LobeHub API
- Client-Server Interaction
- Event Sequences
- API Logic
---
# Lobe Chat API Client-Server Interaction Logic
# LobeHub API Client-Server Interaction Logic
This document explains the implementation logic of Lobe Chat API in client-server interactions, including event sequences and core components involved.
This document explains the implementation logic of LobeHub API in client-server interactions, including event sequences and core components involved.
## Interaction Sequence Diagram
@@ -201,7 +201,7 @@ sequenceDiagram
## AgentRuntime Overview
AgentRuntime is a core abstraction layer in Lobe Chat that encapsulates a unified interface for interacting with different AI model providers. Its main responsibilities and features include:
AgentRuntime is a core abstraction layer in LobeHub that encapsulates a unified interface for interacting with different AI model providers. Its main responsibilities and features include:
1. **Unified Abstraction Layer**: AgentRuntime provides a unified interface that hides the implementation details and differences between various AI provider APIs (such as OpenAI, Anthropic, Bedrock, etc.).
@@ -244,7 +244,7 @@ AgentRuntime is a core abstraction layer in Lobe Chat that encapsulates a unifie
**Adapter Implementation Examples**:
1. **OpenRouter Adapter**: OpenRouter is a unified API that allows access to AI models from multiple providers. Lobe Chat implements support for OpenRouter through an adapter:
1. **OpenRouter Adapter**: OpenRouter is a unified API that allows access to AI models from multiple providers. LobeHub implements support for OpenRouter through an adapter:
```ts
// OpenRouter adapter implementation
@@ -258,7 +258,7 @@ AgentRuntime is a core abstraction layer in Lobe Chat that encapsulates a unifie
apiKey: options.apiKey,
baseURL: OPENROUTER_BASE_URL,
defaultHeaders: {
'HTTP-Referer': 'https://github.com/lobehub/lobe-chat',
'HTTP-Referer': 'https://github.com/lobehub/lobehub',
'X-Title': 'LobeHub',
},
});
@@ -267,7 +267,7 @@ AgentRuntime is a core abstraction layer in Lobe Chat that encapsulates a unifie
// Implement chat functionality
async chat(payload: ChatCompletionCreateParamsBase, options?: RequestOptions) {
// Convert Lobe Chat request format to OpenRouter format
// Convert LobeHub request format to OpenRouter format
// Handle model mapping, message format, etc.
return this.client.chat.completions.create(
{
@@ -282,7 +282,7 @@ AgentRuntime is a core abstraction layer in Lobe Chat that encapsulates a unifie
}
```
2. **Google Gemini Adapter**: Gemini is Google's large language model. Lobe Chat supports Gemini series models through a dedicated adapter:
2. **Google Gemini Adapter**: Gemini is Google's large language model. LobeHub supports Gemini series models through a dedicated adapter:
```ts
import { GoogleGenerativeAI } from '@google/generative-ai';
+10 -10
View File
@@ -1,16 +1,16 @@
---
title: Lobe Chat API 前后端交互逻辑
description: 深入了解 Lobe Chat API 的前后端交互实现逻辑和核心组件。
title: LobeHub API 前后端交互逻辑
description: 深入了解 LobeHub API 的前后端交互实现逻辑和核心组件。
tags:
- Lobe Chat API
- LobeHub API
- 前后端交互
- 事件序列
- 核心组件
---
# Lobe Chat API 前后端交互逻辑
# LobeHub API 前后端交互逻辑
本文档说明了 Lobe Chat API 在前后端交互中的实现逻辑,包括事件序列和涉及的核心组件。
本文档说明了 LobeHub API 在前后端交互中的实现逻辑,包括事件序列和涉及的核心组件。
## 交互时序图
@@ -199,7 +199,7 @@ sequenceDiagram
## AgentRuntime 说明
AgentRuntime 是 Lobe Chat 中的一个核心抽象层,它封装了与不同 AI 模型提供商交互的统一接口。其主要职责和特点包括:
AgentRuntime 是 LobeHub 中的一个核心抽象层,它封装了与不同 AI 模型提供商交互的统一接口。其主要职责和特点包括:
1. **统一抽象层**AgentRuntime 提供了一个统一的接口,隐藏了不同 AI 提供商 API 的实现细节差异(如 OpenAI、Anthropic、Bedrock 等)。
@@ -242,7 +242,7 @@ AgentRuntime 是 Lobe Chat 中的一个核心抽象层,它封装了与不同 A
**适配器实现示例**
1. **OpenRouter 适配器**OpenRouter 是一个统一 API,可以通过它访问多个模型提供商的 AI 模型。Lobe Chat 通过适配器实现对 OpenRouter 的支持:
1. **OpenRouter 适配器**OpenRouter 是一个统一 API,可以通过它访问多个模型提供商的 AI 模型。LobeHub 通过适配器实现对 OpenRouter 的支持:
```ts
// OpenRouter 适配器实现
@@ -256,7 +256,7 @@ AgentRuntime 是 Lobe Chat 中的一个核心抽象层,它封装了与不同 A
apiKey: options.apiKey,
baseURL: OPENROUTER_BASE_URL,
defaultHeaders: {
'HTTP-Referer': 'https://github.com/lobehub/lobe-chat',
'HTTP-Referer': 'https://github.com/lobehub/lobehub',
'X-Title': 'LobeHub',
},
});
@@ -265,7 +265,7 @@ AgentRuntime 是 Lobe Chat 中的一个核心抽象层,它封装了与不同 A
// 实现聊天功能
async chat(payload: ChatCompletionCreateParamsBase, options?: RequestOptions) {
// 将 Lobe Chat 的请求格式转换为 OpenRouter 格式
// 将 LobeHub 的请求格式转换为 OpenRouter 格式
// 处理模型映射、消息格式等
return this.client.chat.completions.create(
{
@@ -280,7 +280,7 @@ AgentRuntime 是 Lobe Chat 中的一个核心抽象层,它封装了与不同 A
}
```
2. **Google Gemini 适配器**Gemini 是 Google 的大语言模型,Lobe Chat 通过专门的适配器支持 Gemini 系列模型:
2. **Google Gemini 适配器**Gemini 是 Google 的大语言模型,LobeHub 通过专门的适配器支持 Gemini 系列模型:
```ts
import { GoogleGenerativeAI } from '@google/generative-ai';
@@ -13,11 +13,11 @@ tags:
This document aims to guide developers on how to develop a complete feature in LobeHub.
We will use [RFC 021 - Custom Assistant Opening Guidance](https://github.com/lobehub/lobe-chat/discussions/891) as an example to illustrate the complete implementation process.
We will use [RFC 021 - Custom Assistant Opening Guidance](https://github.com/lobehub/lobehub/discussions/891) as an example to illustrate the complete implementation process.
## 1. Update Schema
lobe-chat uses a postgres database, with the browser-side local database using [pglite](https://pglite.dev/) (wasm version of postgres). The project also uses [drizzle](https://orm.drizzle.team/) ORM to operate the database.
lobehub uses a postgres database, with the browser-side local database using [pglite](https://pglite.dev/) (wasm version of postgres). The project also uses [drizzle](https://orm.drizzle.team/) ORM to operate the database.
Compared to the old solution where the browser side used indexDB, having both the browser side and server side use postgres has the advantage that the model layer code can be completely reused.
@@ -160,7 +160,7 @@ Foreseeably, the frontend will add two inputs, calling updateSessionConfig upon
### Data Flow Store Implementation
lobe-chat uses [zustand](https://zustand.docs.pmnd.rs/getting-started/introduction) as the global state management framework. For detailed practices on state management, you can refer to [📘 State Management Best Practices](/docs/development/state-management/state-management-intro).
lobehub uses [zustand](https://zustand.docs.pmnd.rs/getting-started/introduction) as the global state management framework. For detailed practices on state management, you can refer to [📘 State Management Best Practices](/docs/development/state-management/state-management-intro).
There are two stores related to the agent:
@@ -254,7 +254,7 @@ We're adding a new category of settings this time. In `src/features/AgentSetting
- [@ant-design/icons](https://ant.design/components/icon-cn) and [lucide](https://lucide.dev/icons/): icon libraries
- [react-i18next](https://github.com/i18next/react-i18next) and [lobe-i18n](https://github.com/lobehub/lobe-cli-toolbox/tree/master/packages/lobe-i18n): i18n framework and multi-language automatic translation tool
lobe-chat is an internationalized project, so newly added text needs to update the default `locale` file: `src/locales/default/setting.ts`.
lobehub is an internationalized project, so newly added text needs to update the default `locale` file: `src/locales/default/setting.ts`.
Let's take the subcomponent `OpeningQuestion.tsx` as an example. Component implementation:
@@ -12,11 +12,11 @@ tags:
本文档旨在指导开发者了解如何在 LobeHub 中开发一块完整的功能需求。
我们将以 [RFC 021 - 自定义助手开场引导](https://github.com/lobehub/lobe-chat/discussions/891) 为例,阐述完整的实现流程。
我们将以 [RFC 021 - 自定义助手开场引导](https://github.com/lobehub/lobehub/discussions/891) 为例,阐述完整的实现流程。
## 一、更新 schema
lobe-chat 使用 postgres 数据库,浏览器端本地数据库使用 [pglite](https://pglite.dev/)wasm 版本 postgres)。项目还使用了 [drizzle](https://orm.drizzle.team/) ORM 用来操作数据库。
lobehub 使用 postgres 数据库,浏览器端本地数据库使用 [pglite](https://pglite.dev/)wasm 版本 postgres)。项目还使用了 [drizzle](https://orm.drizzle.team/) ORM 用来操作数据库。
相比旧方案浏览器端使用 indexDB 来说,浏览器端和 server 端都使用 postgres 好处在于 model 层代码可以完全复用。
@@ -159,7 +159,7 @@ export const sessionRouter = router({
### 数据流 store 实现
lobe-chat 使用 [zustand](https://zustand.docs.pmnd.rs/getting-started/introduction) 作为全局状态管理框架,对于状态管理的详细实践介绍,可以查阅 [📘 状态管理最佳实践](/zh/docs/development/state-management/state-management-intro)。
lobehub 使用 [zustand](https://zustand.docs.pmnd.rs/getting-started/introduction) 作为全局状态管理框架,对于状态管理的详细实践介绍,可以查阅 [📘 状态管理最佳实践](/zh/docs/development/state-management/state-management-intro)。
和 agent 相关的 store 有两个:
@@ -253,7 +253,7 @@ export const agentSelectors = {
- [@ant-design/icons](https://ant.design/components/icon-cn) 和 [lucide](https://lucide.dev/icons/): 图标库
- [react-i18next](https://github.com/i18next/react-i18next) 和 [lobe-i18n](https://github.com/lobehub/lobe-cli-toolbox/tree/master/packages/lobe-i18n) i18n 框架和多语言自动翻译工具
lobe-chat 是个国际化项目,新加的文案需要更新默认的 `locale` 文件: `src/locales/default/setting.ts` 。
lobehub 是个国际化项目,新加的文案需要更新默认的 `locale` 文件: `src/locales/default/setting.ts` 。
我们以子组件 `OpeningQuestion.tsx` 为例,组件实现:
+23 -14
View File
@@ -17,20 +17,29 @@ The directory structure of LobeHub is as follows:
```bash
src
├── app # Next.js App Router implementation with route groups and API routes
├── components # Reusable UI components
├── config # Application configuration files, including client-side and server-side environment variables
├── features # Function modules related to business functions, such as agent settings, plugin development pop-ups, etc.
├── hooks # Custom utility hooks reused throughout the application
├── layout # Application layout components, such as navigation bars, sidebars, etc.
├── libs # Third-party integrations (analytics, OIDC, etc.)
├── locales # Internationalization language files
├── server # Server-side modules and services
├── services # Encapsulated backend service interfaces, such as HTTP requests
├── store # Zustand store for state management
├── styles # Global styles and CSS-in-JS configurations
├── types # TypeScript type definition files
── utils # Common utility functions
├── app # Next.js App Router implementation with route groups and API routes
├── business # Business logic modules (client and server)
├── components # Reusable UI components
├── config # Application configuration files, including client-side and server-side environment variables
├── const # Application constants and enums
├── envs # Environment variable definitions and validation (analytics, auth, llm, etc.)
├── features # Function modules related to business functions, such as agent settings, plugin development pop-ups, etc.
├── helpers # Utility helpers for tool engineering, placeholder parsing, etc.
├── hooks # Custom utility hooks reused throughout the application
├── layout # Application layout components, such as navigation bars, sidebars, etc.
├── libs # Third-party integrations (analytics, OIDC, etc.)
├── locales # Internationalization language files
├── server # Server-side modules and services
── services # Encapsulated backend service interfaces, such as HTTP requests
├── store # Zustand store for state management
├── styles # Global styles and CSS-in-JS configurations
├── tools # Built-in tools (artifacts, inspectors, interventions, etc.)
├── types # TypeScript type definition files
├── utils # Common utility functions
├── auth.ts # Authentication configuration (Better Auth)
├── instrumentation.ts # Application monitoring and telemetry setup
├── instrumentation.node.ts # Node.js-specific instrumentation
└── proxy.ts # Next.js middleware proxy configuration
```
## app
@@ -15,20 +15,29 @@ LobeHub 的文件夹目录架构如下:
```bash
src
├── app # Next.js App Router 实现,包含路由组和 API 路由
├── components # 可复用的 UI 组件
├── config # 应用的配置文件,包含客户端环境变量与服务端环境变量
├── features # 与业务功能相关的功能模块,如 Agent 设置、插件开发弹窗等
├── hooks # 应用复用自定义的工具 Hooks
├── layout # 应用的布局组件,如导航栏、侧边栏等
├── libs # 第三方集成(分析、OIDC 等)
├── locales # 国际化的语言文件
├── server # 服务端模块和服务
├── services # 封装的后端服务接口,如 HTTP 请求
├── store # 用于状态管理的 zustand store
├── styles # 全局样式和 CSS-in-JS 配置
├── types # TypeScript 的类型定义文件
── utils # 通用的工具函数
├── app # Next.js App Router 实现,包含路由组和 API 路由
├── business # 业务逻辑模块(客户端和服务端)
├── components # 可复用的 UI 组件
├── config # 应用的配置文件,包含客户端环境变量与服务端环境变量
├── const # 应用常量和枚举
├── envs # 环境变量定义和校验(分析、认证、LLM 等)
├── features # 与业务功能相关的功能模块,如 Agent 设置、插件开发弹窗等
├── helpers # 工具辅助函数,用于工具工程、占位符解析等
├── hooks # 全应用复用自定义的工具 Hooks
├── layout # 应用的布局组件,如导航栏、侧边栏等
├── libs # 第三方集成(分析、OIDC 等)
├── locales # 国际化的语言文件
├── server # 服务端模块和服务
── services # 封装的后端服务接口,如 HTTP 请求
├── store # 用于状态管理的 zustand store
├── styles # 全局样式和 CSS-in-JS 配置
├── tools # 内置工具(artifacts、inspectors、interventions 等)
├── types # TypeScript 的类型定义文件
├── utils # 通用的工具函数
├── auth.ts # 认证配置(Better Auth
├── instrumentation.ts # 应用监控和遥测设置
├── instrumentation.node.ts # Node.js 专用的 instrumentation
└── proxy.ts # Next.js 中间件代理配置
```
## app
+178 -16
View File
@@ -10,7 +10,8 @@ tags:
- PNPM
- Bun
- Git
- VSCode
- Docker
- PostgreSQL
---
# Environment Setup Guide
@@ -35,30 +36,83 @@ First, you need to install the following software:
- PNPM: We use PNPM as the preferred package manager. You can download and install it from the [PNPM official website](https://pnpm.io/installation).
- Bun: We use Bun as the npm scripts runner. You can download and install it from the [Bun official website](https://bun.com/docs/installation).
- Git: We use Git for version control. You can download and install it from the Git official website.
- Docker: Required for running PostgreSQL, MinIO, and other services. You can download and install it from the [Docker official website](https://www.docker.com/get-started).
- IDE: You can choose your preferred integrated development environment (IDE). We recommend using WebStorm/VSCode.
### VSCode Users
We recommend installing the extensions listed in [.vscode/extensions.json](https://github.com/lobehub/lobe-chat/blob/main/.vscode/extensions.json) for the best development experience.
We recommend installing the extensions listed in [.vscode/extensions.json](https://github.com/lobehub/lobehub/blob/main/.vscode/extensions.json) for the best development experience.
### Project Setup
After installing the above software, you can start setting up the LobeHub project.
1. **Get the code**: First, you need to clone the LobeHub codebase from GitHub. Run the following command in the terminal:
#### 1. Get the Code
First, you need to clone the LobeHub codebase from GitHub. Run the following command in the terminal:
```bash
git clone https://github.com/lobehub/lobe-chat.git
git clone https://github.com/lobehub/lobehub.git
cd lobehub
```
2. **Install dependencies**: Then, navigate to the project directory and use PNPM to install the project's dependencies:
#### 2. Install Dependencies
Use PNPM to install the project's dependencies:
```bash
cd lobe-chat
pnpm i
```
3. **Start the development server**: After installing the dependencies, you can start the development server:
#### 3. Configure Environment
Copy the example environment file to create your Docker Compose configuration:
```bash
cp docker-compose/local/.env.example docker-compose/local/.env
```
Edit `docker-compose/local/.env` as needed for your development setup. This file contains all necessary environment variables for the Docker services and configures:
- **Database**: PostgreSQL with connection string
- **Authentication**: Better Auth with Casdoor SSO
- **Storage**: MinIO S3-compatible storage
- **Search**: SearXNG search engine
#### 4. Start Docker Services
Start all required services using Docker Compose:
```bash
docker-compose -f docker-compose.development.yml up -d
```
This will start the following services:
- PostgreSQL database (port 5432)
- MinIO storage (port 9000)
- Casdoor authentication (port 8000)
- SearXNG search (port 8080)
You can check all Docker services are running by running:
```bash
docker-compose -f docker-compose.development.yml ps
```
#### 5. Run Database Migrations
Execute the database migration script to create all necessary tables:
```bash
pnpm db:migrate
```
You should see: `✅ database migration pass.`
#### 6. Start Development Server
Launch the LobeHub development server:
```bash
bun run dev
@@ -68,19 +122,127 @@ Now, you can open `http://localhost:3010` in your browser, and you should see th
![](https://github-production-user-asset-6210df.s3.amazonaws.com/28616219/274655364-414bc31e-8511-47a3-af17-209b530effc7.png)
## Working with Server-Side Features
## Image Generation Development
The basic setup above uses LobeHub's client-side database mode. If you need to work with server-side features such as:
When working with image generation features (text-to-image, image-to-image), the Docker Compose setup already includes all necessary storage services for handling generated images and user uploads.
- Database persistence
- File uploads and storage
- Image generation
- Multi-user authentication
- Advanced server-side integrations
### Image Generation Configuration
Please refer to the [Work with Server-Side Database](/docs/development/basic/work-with-server-side-database) guide for complete setup instructions.
The existing Docker Compose configuration already includes MinIO storage service and all necessary environment variables in `docker-compose/local/.env.example`. No additional setup is required.
### Image Generation Architecture
The image generation feature requires:
- **PostgreSQL**: Stores metadata about generated images
- **MinIO/S3**: Stores the actual image files
### Storage Configuration
The `docker-compose/local/.env.example` file includes all necessary S3 environment variables:
```bash
# S3 Storage Configuration (MinIO for local development)
S3_ACCESS_KEY_ID=${MINIO_ROOT_USER}
S3_SECRET_ACCESS_KEY=${MINIO_ROOT_PASSWORD}
S3_ENDPOINT=http://localhost:${MINIO_PORT}
S3_BUCKET=${MINIO_LOBE_BUCKET}
S3_ENABLE_PATH_STYLE=1 # Required for MinIO
S3_SET_ACL=0 # MinIO compatibility
```
### File Storage Structure
Generated images and user uploads are organized in the MinIO bucket:
```
lobe/ # S3 Bucket (MINIO_LOBE_BUCKET)
├── generated/ # Generated images
│ └── {userId}/
│ └── {sessionId}/
│ └── {imageId}.png
└── uploads/ # User uploads for image-to-image
└── {userId}/
└── {fileId}.{ext}
```
### Development Workflow for Images
When developing image generation features, generated images will be:
1. Created by the AI model
2. Uploaded to S3/MinIO via presigned URLs
3. Metadata stored in PostgreSQL
4. Served via the public S3 URL
Example code for testing image upload:
```typescript
// Example: Upload generated image
const uploadUrl = await trpc.upload.createPresignedUrl.mutate({
filename: 'generated-image.png',
contentType: 'image/png',
});
// Upload to S3
await fetch(uploadUrl, {
method: 'PUT',
body: imageBlob,
headers: { 'Content-Type': 'image/png' },
});
```
### Service URLs
When running with Docker Compose development setup:
- **PostgreSQL**: `postgres://postgres@localhost:5432/LobeHub`
- **MinIO API**: `http://localhost:9000`
- **MinIO Console**: `http://localhost:9001` (admin/CHANGE\_THIS\_PASSWORD\_IN\_PRODUCTION)
- **Application**: `http://localhost:3010`
## Troubleshooting
### Reset Services
If you encounter issues, you can reset the entire stack:
```bash
# Stop and remove all containers
docker-compose -f docker-compose.development.yml down
# Remove volumes (this will delete all data)
docker-compose -f docker-compose.development.yml down -v
# Start fresh
docker-compose -f docker-compose.development.yml up -d
pnpm db:migrate
```
### Port Conflicts
If ports are already in use:
```bash
# Check what's using the ports
lsof -i :5432 # PostgreSQL
lsof -i :9000 # MinIO API
lsof -i :9001 # MinIO Console
```
### Database Migrations
The setup script runs migrations automatically. If you need to run them manually:
```bash
pnpm db:migrate
```
Note: In development mode with `pnpm dev:desktop`, migrations also run automatically on startup.
---
During the development process, if you encounter any issues with environment setup or have any questions about LobeHub development, feel free to ask us at any time. We look forward to seeing your contributions!
[codespaces-link]: https://codespaces.new/lobehub/lobe-chat
[codespaces-link]: https://codespaces.new/lobehub/lobehub
[codespaces-shield]: https://github.com/codespaces/badge.svg
@@ -7,6 +7,8 @@ tags:
- Node.js
- PNPM
- Git
- Docker
- PostgreSQL
---
# 环境设置指南
@@ -29,32 +31,85 @@ tags:
- Node.jsLobeHub 是基于 Node.js 构建的,因此你需要安装 Node.js。我们建议安装最新的稳定版。
- PNPM:我们使用 PNPM 作为管理器。你可以从 [pnpm 的官方网站](https://pnpm.io/installation) 上下载并安装。
- Bun:我们使用 Bun 作为 npm scripts runner, 你可以从 [Bun 的官方网站](https://bun.com/docs/installation) 上下载并安装。
- Bun:我们使用 Bun 作为 npm scripts runner你可以从 [Bun 的官方网站](https://bun.com/docs/installation) 上下载并安装。
- Git:我们使用 Git 进行版本控制。你可以从 Git 的官方网站上下载并安装。
- Docker:用于运行 PostgreSQL、MinIO 等服务。你可以从 [Docker 官方网站](https://www.docker.com/get-started) 下载并安装。
- IDE:你可以选择你喜欢的集成开发环境(IDE),我们推荐使用 WebStorm/VSCode。
### VSCode 用户
推荐安装 [.vscode/extensions.json](https://github.com/lobehub/lobe-chat/blob/main/.vscode/extensions.json) 中推荐安装的扩展获得最佳开发体验。
推荐安装 [.vscode/extensions.json](https://github.com/lobehub/lobehub/blob/main/.vscode/extensions.json) 中推荐安装的扩展获得最佳开发体验。
### 项目设置
完成上述软件的安装后,你可以开始设置 LobeHub 项目了。
1. **获取代码**:首先,你需要从 GitHub 上克隆 LobeHub 的代码库。在终端中运行以下命令:
#### 1. 获取代码
首先,你需要从 GitHub 上克隆 LobeHub 的代码库。在终端中运行以下命令:
```bash
git clone https://github.com/lobehub/lobe-chat.git
git clone https://github.com/lobehub/lobehub.git
cd lobehub
```
2. **安装依赖**:然后,进入项目目录,并使用 `pnpm` 安装项目的依赖包:
#### 2. 安装依赖
使用 PNPM 安装项目的依赖包:
```bash
cd lobe-chat
pnpm i
```
3. **启动开发服务器**:安装完依赖后,你可以启动开发服务器:
#### 3. 配置环境
复制示例环境文件来创建你的 Docker Compose 配置:
```bash
cp docker-compose/local/.env.example docker-compose/local/.env
```
根据需要编辑 `docker-compose/local/.env` 文件以适应你的开发设置。此文件包含 Docker 服务所需的所有环境变量,配置了:
- **数据库**:带连接字符串的 PostgreSQL
- **身份验证**:带 Casdoor SSO 的 Better Auth
- **存储**MinIO S3 兼容存储
- **搜索**SearXNG 搜索引擎
#### 4. 启动 Docker 服务
使用 Docker Compose 启动所有必需的服务:
```bash
docker-compose -f docker-compose.development.yml up -d
```
这将启动以下服务:
- PostgreSQL 数据库(端口 5432
- MinIO 存储(端口 9000
- Casdoor 身份验证(端口 8000
- SearXNG 搜索(端口 8080
可以通过运行以下命令检查所有 Docker 服务运行状态:
```bash
docker-compose -f docker-compose.development.yml ps
```
#### 5. 运行数据库迁移
执行数据库迁移脚本以创建所有必要的表:
```bash
pnpm db:migrate
```
预期输出:`✅ database migration pass.`
#### 6. 启动开发服务器
启动 LobeHub 开发服务器:
```bash
bun run dev
@@ -64,19 +119,127 @@ bun run dev
![Chat Page](https://hub-apac-1.lobeobjects.space/docs/fc7b157a3bc016bc97719065f80c555c.png)
## 使用服务端功能
## 图像生成开发
上述基础设置使用 LobeHub 的客户端数据库模式。如果你需要开发服务端功能,如:
在开发图像生成功能(文生图、图生图)时,Docker Compose 配置已经包含了处理生成图像和用户上传所需的所有存储服务。
- 数据库持久化
- 文件上传和存储
- 图像生成
- 多用户身份验证
- 高级服务端集成
### 图像生成配置
请参考[使用服务端数据库](/docs/development/basic/work-with-server-side-database)指南获得完整的设置说明
现有的 Docker Compose 配置已经包含了 MinIO 存储服务以及 `docker-compose/local/.env.example` 中的所有必要环境变量。无需额外配置
### 图像生成架构
图像生成功能需要:
- **PostgreSQL**:存储生成图像的元数据
- **MinIO/S3**:存储实际的图像文件
### 存储配置
`docker-compose/local/.env.example` 文件包含所有必要的 S3 环境变量:
```bash
# S3 存储配置(本地开发使用 MinIO)
S3_ACCESS_KEY_ID=${MINIO_ROOT_USER}
S3_SECRET_ACCESS_KEY=${MINIO_ROOT_PASSWORD}
S3_ENDPOINT=http://localhost:${MINIO_PORT}
S3_BUCKET=${MINIO_LOBE_BUCKET}
S3_ENABLE_PATH_STYLE=1 # MinIO 必需
S3_SET_ACL=0 # MinIO 兼容性
```
### 文件存储结构
生成的图像和用户上传在 MinIO 存储桶中按以下方式组织:
```
lobe/ # S3 存储桶 (MINIO_LOBE_BUCKET)
├── generated/ # 生成的图像
│ └── {userId}/
│ └── {sessionId}/
│ └── {imageId}.png
└── uploads/ # 用户上传的图像处理文件
└── {userId}/
└── {fileId}.{ext}
```
### 图像开发工作流
在开发图像生成功能时,生成的图像将:
1. 由 AI 模型创建
2. 通过预签名 URL 上传到 S3/MinIO
3. 元数据存储在 PostgreSQL 中
4. 通过公共 S3 URL 提供服务
测试图像上传的示例代码:
```typescript
// 示例:上传生成的图像
const uploadUrl = await trpc.upload.createPresignedUrl.mutate({
filename: 'generated-image.png',
contentType: 'image/png',
});
// 上传到 S3
await fetch(uploadUrl, {
method: 'PUT',
body: imageBlob,
headers: { 'Content-Type': 'image/png' },
});
```
### 服务地址
运行 Docker Compose 开发环境时:
- **PostgreSQL**`postgres://postgres@localhost:5432/LobeHub`
- **MinIO API**`http://localhost:9000`
- **MinIO 控制台**`http://localhost:9001` (admin/CHANGE\_THIS\_PASSWORD\_IN\_PRODUCTION)
- **应用程序**`http://localhost:3010`
## 故障排除
### 重置服务
如遇到问题,可以重置整个服务堆栈:
```bash
# 停止并删除所有容器
docker-compose -f docker-compose.development.yml down
# 删除卷(这将删除所有数据)
docker-compose -f docker-compose.development.yml down -v
# 重新启动
docker-compose -f docker-compose.development.yml up -d
pnpm db:migrate
```
### 端口冲突
如果端口已被占用:
```bash
# 检查端口使用情况
lsof -i :5432 # PostgreSQL
lsof -i :9000 # MinIO API
lsof -i :9001 # MinIO 控制台
```
### 数据库迁移
配置脚本会自动运行迁移。如需手动运行:
```bash
pnpm db:migrate
```
注意:在使用 `pnpm dev:desktop` 的开发模式下,迁移也会在启动时自动运行。
---
在开发过程中,如果你在环境设置上遇到任何问题,或者有任何关于 LobeHub 开发的问题,欢迎随时向我们提问。我们期待看到你的贡献!
[codespaces-link]: https://codespaces.new/lobehub/lobe-chat
[codespaces-link]: https://codespaces.new/lobehub/lobehub
[codespaces-shield]: https://github.com/codespaces/badge.svg
@@ -1,196 +0,0 @@
---
title: Work with Server-Side Database
description: Learn how to set up a server-side database for LobeHub with Docker.
tags:
- LobeHub
- Server-Side Database
- Docker
- PostgreSQL
- MinIO
---
# Work with Server-Side Database
LobeHub provides a battery-included experience with its client-side database.
While some features you really care about is only available at a server-side development.
In order to work with the aspect of server-side database,
you can setup all the prerequisites by following the [Deploying Server-Side Database](https://lobehub.com/docs/self-hosting/server-database) story.
But here is the easier approach that can reduce your pain.
## Quick Setup
### Environment Configuration
First, copy the example environment file to create your Docker Compose configuration:
```bash
cp docker-compose/local/.env.example docker-compose/local/.env
```
Edit `docker-compose/local/.env` as needed for your development setup. This file contains all necessary environment variables for the Docker services and configures:
- **Database**: PostgreSQL with connection string
- **Authentication**: NextAuth with Casdoor SSO
- **Storage**: MinIO S3-compatible storage
- **Search**: SearXNG search engine
### Start Docker Services
Start all required services using Docker Compose:
```bash
docker-compose -f docker-compose.development.yml up -d
```
This will start the following services:
- PostgreSQL database (port 5432)
- MinIO storage (port 9000)
- Casdoor authentication (port 8000)
- SearXNG search (port 8080)
### Run Database Migrations
Execute the database migration script to create all necessary tables:
```bash
pnpm db:migrate
```
You should see: `✅ database migration pass.`
### Start Development Server
Launch the LobeHub development server:
```bash
pnpm dev
```
The server will start on `http://localhost:3010`
And you can check all Docker services are running by running:
```bash
docker-compose -f docker-compose.development.yml ps
```
## Image Generation Development
When working with image generation features (text-to-image, image-to-image), the Docker Compose setup already includes all necessary storage services for handling generated images and user uploads.
### Image Generation Configuration
The existing Docker Compose configuration already includes MinIO storage service and all necessary environment variables in `docker-compose/local/.env.example`. No additional setup is required.
### Image Generation Architecture
The image generation feature requires:
- **PostgreSQL**: Stores metadata about generated images
- **MinIO/S3**: Stores the actual image files
### Storage Configuration
The `docker-compose/local/.env.example` file includes all necessary S3 environment variables:
```bash
# S3 Storage Configuration (MinIO for local development)
S3_ACCESS_KEY_ID=${MINIO_ROOT_USER}
S3_SECRET_ACCESS_KEY=${MINIO_ROOT_PASSWORD}
S3_ENDPOINT=http://localhost:${MINIO_PORT}
S3_BUCKET=${MINIO_LOBE_BUCKET}
S3_PUBLIC_DOMAIN=http://localhost:${MINIO_PORT}
S3_ENABLE_PATH_STYLE=1 # Required for MinIO
S3_SET_ACL=0 # MinIO compatibility
```
### File Storage Structure
Generated images and user uploads are organized in the MinIO bucket:
```
lobe/ # S3 Bucket (MINIO_LOBE_BUCKET)
├── generated/ # Generated images
│ └── {userId}/
│ └── {sessionId}/
│ └── {imageId}.png
└── uploads/ # User uploads for image-to-image
└── {userId}/
└── {fileId}.{ext}
```
### Development Workflow for Images
When developing image generation features, generated images will be:
1. Created by the AI model
2. Uploaded to S3/MinIO via presigned URLs
3. Metadata stored in PostgreSQL
4. Served via the public S3 URL
Example code for testing image upload:
```typescript
// Example: Upload generated image
const uploadUrl = await trpc.upload.createPresignedUrl.mutate({
filename: 'generated-image.png',
contentType: 'image/png',
});
// Upload to S3
await fetch(uploadUrl, {
method: 'PUT',
body: imageBlob,
headers: { 'Content-Type': 'image/png' },
});
```
### Service URLs
When running with Docker Compose development setup:
- **PostgreSQL**: `postgres://postgres@localhost:5432/LobeHub`
- **MinIO API**: `http://localhost:9000`
- **MinIO Console**: `http://localhost:9001` (admin/CHANGE\_THIS\_PASSWORD\_IN\_PRODUCTION)
- **Application**: `http://localhost:3010`
### Reset Services
If you encounter issues, you can reset the entire stack:
```bash
# Stop and remove all containers
docker-compose -f docker-compose.development.yml down
# Remove volumes (this will delete all data)
docker-compose -f docker-compose.development.yml down -v
# Start fresh
docker-compose -f docker-compose.development.yml up -d
pnpm db:migrate
```
### Troubleshooting
#### Port Conflicts
If ports are already in use:
```bash
# Check what's using the ports
lsof -i :5432 # PostgreSQL
lsof -i :9000 # MinIO API
lsof -i :9001 # MinIO Console
```
#### Database Migrations
The setup script runs migrations automatically. If you need to run them manually:
```bash
pnpm db:migrate
```
Note: In development mode with `pnpm dev:desktop`, migrations also run automatically on startup.
@@ -1,196 +0,0 @@
---
title: 使用服务端数据库
description: 快速设置 LobeHub 服务端数据库,支持 Docker 和图像生成。
tags:
- 服务端数据库
- LobeHub
- Docker
- 图像生成
- PostgreSQL
---
# 使用服务端数据库
LobeHub 提供了内置的客户端数据库体验。
但某些重要功能仅在服务端开发中可用。
为了使用服务端数据库功能,
需要参考 [部署服务端数据库](https://lobehub.com/docs/self-hosting/server-database) 的说明来配置所有前置条件。
本文档提供了一个更简化的配置方法,能够在本地开发时快速启动简化的服务端环境。
## 快速设置
### 环境配置
首先,复制示例环境文件来创建你的 Docker Compose 配置:
```bash
cp docker-compose/local/.env.example docker-compose/local/.env
```
根据需要编辑 `docker-compose/local/.env` 文件以适应你的开发设置。此文件包含 Docker 服务所需的所有环境变量,配置了:
- **数据库**: 带连接字符串的 PostgreSQL
- **身份验证**: 带 Casdoor SSO 的 NextAuth
- **存储**: MinIO S3 兼容存储
- **搜索**: SearXNG 搜索引擎
### 启动 Docker 服务
使用 Docker Compose 启动所有必需的服务:
```bash
docker-compose -f docker-compose.development.yml up -d
```
这将启动以下服务:
- PostgreSQL 数据库(端口 5432
- MinIO 存储(端口 9000
- Casdoor 身份验证(端口 8000
- SearXNG 搜索(端口 8080
### 运行数据库迁移
执行数据库迁移脚本以创建所有必要的表:
```bash
pnpm db:migrate
```
预期输出:`✅ database migration pass.`
### 启动开发服务器
启动 LobeHub 开发服务器:
```bash
pnpm dev
```
服务器将在 `http://localhost:3010` 上启动
可以通过运行以下命令检查所有 Docker 服务运行状态:
```bash
docker-compose -f docker-compose.development.yml ps
```
## 图像生成开发
在开发图像生成功能(文生图、图生图)时,Docker Compose 配置已经包含了处理生成图像和用户上传所需的所有存储服务。
### 图像生成配置
现有的 Docker Compose 配置已经包含了 MinIO 存储服务以及 `docker-compose/local/.env.example` 中的所有必要环境变量。无需额外配置。
### 图像生成架构
图像生成功能需要:
- **PostgreSQL**:存储生成图像的元数据
- **MinIO/S3**:存储实际的图像文件
### 存储配置
`docker-compose/local/.env.example` 文件包含所有必要的 S3 环境变量:
```bash
# S3 存储配置(本地开发使用 MinIO)
S3_ACCESS_KEY_ID=${MINIO_ROOT_USER}
S3_SECRET_ACCESS_KEY=${MINIO_ROOT_PASSWORD}
S3_ENDPOINT=http://localhost:${MINIO_PORT}
S3_BUCKET=${MINIO_LOBE_BUCKET}
S3_PUBLIC_DOMAIN=http://localhost:${MINIO_PORT}
S3_ENABLE_PATH_STYLE=1 # MinIO 必需
S3_SET_ACL=0 # MinIO 兼容性
```
### 文件存储结构
生成的图像和用户上传在 MinIO 存储桶中按以下方式组织:
```
lobe/ # S3 存储桶 (MINIO_LOBE_BUCKET)
├── generated/ # 生成的图像
│ └── {userId}/
│ └── {sessionId}/
│ └── {imageId}.png
└── uploads/ # 用户上传的图像处理文件
└── {userId}/
└── {fileId}.{ext}
```
### 图像开发工作流
在开发图像生成功能时,生成的图像将:
1. 由 AI 模型创建
2. 通过预签名 URL 上传到 S3/MinIO
3. 元数据存储在 PostgreSQL 中
4. 通过公共 S3 URL 提供服务
测试图像上传的示例代码:
```typescript
// 示例:上传生成的图像
const uploadUrl = await trpc.upload.createPresignedUrl.mutate({
filename: 'generated-image.png',
contentType: 'image/png',
});
// 上传到 S3
await fetch(uploadUrl, {
method: 'PUT',
body: imageBlob,
headers: { 'Content-Type': 'image/png' },
});
```
### 服务地址
运行 Docker Compose 开发环境时:
- **PostgreSQL**`postgres://postgres@localhost:5432/LobeHub`
- **MinIO API**`http://localhost:9000`
- **MinIO 控制台**`http://localhost:9001` (admin/CHANGE\_THIS\_PASSWORD\_IN\_PRODUCTION)
- **应用程序**`http://localhost:3010`
### 重置服务
如遇到问题,可以重置整个服务堆栈:
```bash
# 停止并删除所有容器
docker-compose -f docker-compose.development.yml down
# 删除卷(这将删除所有数据)
docker-compose -f docker-compose.development.yml down -v
# 重新启动
docker-compose -f docker-compose.development.yml up -d
pnpm db:migrate
```
### 故障排除
#### 端口冲突
如果端口已被占用:
```bash
# 检查端口使用情况
lsof -i :5432 # PostgreSQL
lsof -i :9000 # MinIO API
lsof -i :9001 # MinIO 控制台
```
#### 数据库迁移
配置脚本会自动运行迁移。如需手动运行:
```bash
pnpm db:migrate
```
注意:在使用 `pnpm dev:desktop` 的开发模式下,迁移也会在启动时自动运行。
+1
View File
@@ -643,6 +643,7 @@ table messages {
thread_id [name: 'messages_thread_id_idx']
agent_id [name: 'messages_agent_id_idx']
group_id [name: 'messages_group_id_idx']
message_group_id [name: 'messages_message_group_id_idx']
}
}
@@ -54,7 +54,7 @@ This will utilize the `lobe-i18n` tool to process the language files.
Once you have completed the above steps, you need to submit your changes and create a Pull Request.
Ensure that you follow LobeHub's contribution guidelines and provide a necessary description to explain your changes. For example, refer to a similar previous Pull Request [#759](https://github.com/lobehub/lobe-chat/pull/759).
Ensure that you follow LobeHub's contribution guidelines and provide a necessary description to explain your changes. For example, refer to a similar previous Pull Request [#759](https://github.com/lobehub/lobehub/pull/759).
### Additional Information
@@ -54,7 +54,7 @@ npm run i18n
一旦你完成了上述步骤,你需要提交你的更改并创建一个 Pull Request。
请确保你遵循了 LobeHub 的贡献指南,并提供必要的描述来说明你的更改。例如,参考之前的类似 Pull Request [#759](https://github.com/lobehub/lobe-chat/pull/759)。
请确保你遵循了 LobeHub 的贡献指南,并提供必要的描述来说明你的更改。例如,参考之前的类似 Pull Request [#759](https://github.com/lobehub/lobehub/pull/759)。
### 附加信息
@@ -114,11 +114,11 @@ In this example, we demonstrate how to use `i18next` and related plugins to init
We have already supported a variety of languages globally through the following efforts:
- [✨ feat: adding Arabic Language Support #1049](https://github.com/lobehub/lobe-chat/pull/1049)
- [🌐 style: Add Vietnamese files and add the vi-VN option in the General Settings #860](https://github.com/lobehub/lobe-chat/pull/860)
- [🌐 style: support it-IT nl-NL and pl-PL locales #759](https://github.com/lobehub/lobe-chat/pull/759)
- [🌐 feat(locale): Add fr-FR (#637) #645](https://github.com/lobehub/lobe-chat/pull/645)
- [🌐 Add russian localy #137](https://github.com/lobehub/lobe-chat/pull/137)
- [✨ feat: adding Arabic Language Support #1049](https://github.com/lobehub/lobehub/pull/1049)
- [🌐 style: Add Vietnamese files and add the vi-VN option in the General Settings #860](https://github.com/lobehub/lobehub/pull/860)
- [🌐 style: support it-IT nl-NL and pl-PL locales #759](https://github.com/lobehub/lobehub/pull/759)
- [🌐 feat(locale): Add fr-FR (#637) #645](https://github.com/lobehub/lobehub/pull/645)
- [🌐 Add russian localy #137](https://github.com/lobehub/lobehub/pull/137)
To add support for new languages, please refer to the detailed steps in the [New Locale Addition Guide](add-new-locale).
@@ -111,11 +111,11 @@ const createI18nInstance = (lang) => {
我们通过以下工作,已经支持了全球多种语言:
- [✨ feat: adding Arabic Language Support #1049](https://github.com/lobehub/lobe-chat/pull/1049)
- [🌐 style: Add Vietnamese files and add the vi-VN option in the General Settings #860](https://github.com/lobehub/lobe-chat/pull/860)
- [🌐 style: support it-IT nl-NL and pl-PL locales #759](https://github.com/lobehub/lobe-chat/pull/759)
- [🌐 feat(locale): Add fr-FR (#637) #645](https://github.com/lobehub/lobe-chat/pull/645)
- [🌐 Add russian localy #137](https://github.com/lobehub/lobe-chat/pull/137)
- [✨ feat: adding Arabic Language Support #1049](https://github.com/lobehub/lobehub/pull/1049)
- [🌐 style: Add Vietnamese files and add the vi-VN option in the General Settings #860](https://github.com/lobehub/lobehub/pull/860)
- [🌐 style: support it-IT nl-NL and pl-PL locales #759](https://github.com/lobehub/lobehub/pull/759)
- [🌐 feat(locale): Add fr-FR (#637) #645](https://github.com/lobehub/lobehub/pull/645)
- [🌐 Add russian localy #137](https://github.com/lobehub/lobehub/pull/137)
要添加新的语种支持, 详细步骤请参考:[新语种添加指南](/zh/docs/development/internationalization/add-new-locale)。
+8 -8
View File
@@ -29,11 +29,11 @@ tags:
| ![][discover-desktop] | ![][discover-mobile] |
| [⚡️ Lighthouse Report][discover-desktop-report] | [⚡️ Lighthouse Report][discover-mobile-report] |
[chat-desktop]: https://raw.githubusercontent.com/lobehub/lobe-chat/lighthouse/lighthouse/chat/desktop/pagespeed.svg
[chat-desktop-report]: https://lobehub.github.io/lobe-chat/lighthouse/chat/desktop/LobeHub_com_chat.html
[chat-mobile]: https://raw.githubusercontent.com/lobehub/lobe-chat/lighthouse/lighthouse/chat/mobile/pagespeed.svg
[chat-mobile-report]: https://lobehub.github.io/lobe-chat/lighthouse/chat/mobile/LobeHub_com_chat.html
[discover-desktop]: https://raw.githubusercontent.com/lobehub/lobe-chat/lighthouse/lighthouse/discover/desktop/pagespeed.svg
[discover-desktop-report]: https://lobehub.github.io/lobe-chat/lighthouse/discover/desktop/LobeHub_com_discover.html
[discover-mobile]: https://raw.githubusercontent.com/lobehub/lobe-chat/lighthouse/lighthouse/discover/mobile/pagespeed.svg
[discover-mobile-report]: https://lobehub.github.io/lobe-chat/lighthouse/discover/mobile/LobeHub_com_discover.html
[chat-desktop]: https://raw.githubusercontent.com/lobehub/lobehub/lighthouse/lighthouse/chat/desktop/pagespeed.svg
[chat-desktop-report]: https://lobehub.github.io/lobehub/lighthouse/chat/desktop/LobeHub_com_chat.html
[chat-mobile]: https://raw.githubusercontent.com/lobehub/lobehub/lighthouse/lighthouse/chat/mobile/pagespeed.svg
[chat-mobile-report]: https://lobehub.github.io/lobehub/lighthouse/chat/mobile/LobeHub_com_chat.html
[discover-desktop]: https://raw.githubusercontent.com/lobehub/lobehub/lighthouse/lighthouse/discover/desktop/pagespeed.svg
[discover-desktop-report]: https://lobehub.github.io/lobehub/lighthouse/discover/desktop/LobeHub_com_discover.html
[discover-mobile]: https://raw.githubusercontent.com/lobehub/lobehub/lighthouse/lighthouse/discover/mobile/pagespeed.svg
[discover-mobile-report]: https://lobehub.github.io/lobehub/lighthouse/discover/mobile/LobeHub_com_discover.html
+8 -8
View File
@@ -30,11 +30,11 @@ tags:
| ![][discover-desktop] | ![][discover-mobile] |
| [⚡️ Lighthouse Report][discover-desktop-report] | [⚡️ Lighthouse Report][discover-mobile-report] |
[chat-desktop]: https://raw.githubusercontent.com/lobehub/lobe-chat/lighthouse/lighthouse/chat/desktop/pagespeed.svg
[chat-desktop-report]: https://lobehub.github.io/lobe-chat/lighthouse/chat/desktop/LobeHub_com_chat.html
[chat-mobile]: https://raw.githubusercontent.com/lobehub/lobe-chat/lighthouse/lighthouse/chat/mobile/pagespeed.svg
[chat-mobile-report]: https://lobehub.github.io/lobe-chat/lighthouse/chat/mobile/LobeHub_com_chat.html
[discover-desktop]: https://raw.githubusercontent.com/lobehub/lobe-chat/lighthouse/lighthouse/discover/desktop/pagespeed.svg
[discover-desktop-report]: https://lobehub.github.io/lobe-chat/lighthouse/discover/desktop/LobeHub_com_discover.html
[discover-mobile]: https://raw.githubusercontent.com/lobehub/lobe-chat/lighthouse/lighthouse/discover/mobile/pagespeed.svg
[discover-mobile-report]: https://lobehub.github.io/lobe-chat/lighthouse/discover/mobile/LobeHub_com_discover.html
[chat-desktop]: https://raw.githubusercontent.com/lobehub/lobehub/lighthouse/lighthouse/chat/desktop/pagespeed.svg
[chat-desktop-report]: https://lobehub.github.io/lobehub/lighthouse/chat/desktop/LobeHub_com_chat.html
[chat-mobile]: https://raw.githubusercontent.com/lobehub/lobehub/lighthouse/lighthouse/chat/mobile/pagespeed.svg
[chat-mobile-report]: https://lobehub.github.io/lobehub/lighthouse/chat/mobile/LobeHub_com_chat.html
[discover-desktop]: https://raw.githubusercontent.com/lobehub/lobehub/lighthouse/lighthouse/discover/desktop/pagespeed.svg
[discover-desktop-report]: https://lobehub.github.io/lobehub/lighthouse/discover/desktop/LobeHub_com_discover.html
[discover-mobile]: https://raw.githubusercontent.com/lobehub/lobehub/lighthouse/lighthouse/discover/mobile/pagespeed.svg
[discover-mobile-report]: https://lobehub.github.io/lobehub/lighthouse/discover/mobile/LobeHub_com_discover.html
+22 -15
View File
@@ -34,18 +34,25 @@ The folder directory structure of LobeHub is as follows:
```bash
src
├── app # Code related to the main logic and state management of the application
├── components # Reusable UI components
├── config # Application configuration files, including client and server environment variables
├── const # Used to define constants, such as action types, route names, etc.
├── features # Business-related feature modules, such as Agent settings, plugin development pop-ups, etc.
├── hooks # Custom utility Hooks reusable across the application
├── layout # Application layout components, such as navigation bars, sidebars, etc.
├── locales # Language files for internationalization
├── services # Encapsulated backend service interfaces, such as HTTP requests
├── store # Zustand store for state management
├── types # TypeScript type definition files
── utils # General utility functions
├── app # Next.js App Router implementation with route groups and API routes
├── business # Business logic modules (client and server)
├── components # Reusable UI components
├── config # Application configuration files, including client and server environment variables
├── const # Application constants and enums
├── envs # Environment variable definitions and validation (analytics, auth, llm, etc.)
├── features # Business-related feature modules, such as Agent settings, plugin development pop-ups, etc.
├── helpers # Utility helpers for tool engineering, placeholder parsing, etc.
├── hooks # Custom utility Hooks reusable across the application
├── layout # Application layout components, such as navigation bars, sidebars, etc.
├── libs # Third-party integrations (analytics, OIDC, etc.)
── locales # Language files for internationalization
├── server # Server-side modules and services
├── services # Encapsulated backend service interfaces, such as HTTP requests
├── store # Zustand store for state management
├── styles # Global styles and CSS-in-JS configurations
├── tools # Built-in tools (artifacts, inspectors, interventions, etc.)
├── types # TypeScript type definition files
└── utils # General utility functions
```
For a detailed introduction to the directory structure, see: [Folder Directory Structure](/docs/development/basic/folder-structure)
@@ -59,13 +66,13 @@ We recommend using WebStorm as your integrated development environment (IDE).
1. **Get the code**: Clone the LobeHub code repository locally:
```bash
git clone https://github.com/lobehub/lobe-chat.git
git clone https://github.com/lobehub/lobehub.git
```
2. **Install dependencies**: Enter the project directory and install the required dependencies:
```bash
cd lobe-chat
cd lobehub
# If you use Bun
bun install
# If you use PNPM
@@ -110,6 +117,6 @@ For a detailed guide on internationalization implementation, please refer to [In
To support developers in better understanding and using the technology stack of LobeHub, we provide a comprehensive list of resources and references — [LobeHub Resources and References](/docs/development/basic/resources) - Visit our maintained list of resources, including tutorials, articles, and other useful links.
We encourage developers to utilize these resources to deepen their learning and enhance their skills, join community discussions through [LobeHub GitHub Discussions](https://github.com/lobehub/lobe-chat/discussions) or [Discord](https://discord.com/invite/AYFPHvv2jT), ask questions, or share your experiences.
We encourage developers to utilize these resources to deepen their learning and enhance their skills, join community discussions through [LobeHub GitHub Discussions](https://github.com/lobehub/lobehub/discussions) or [Discord](https://discord.com/invite/AYFPHvv2jT), ask questions, or share your experiences.
If you have any questions or need further assistance, please do not hesitate to contact us through the above channels.
+22 -15
View File
@@ -32,18 +32,25 @@ LobeHub 的文件夹目录架构如下:
```bash
src
├── app # 应用主要逻辑和状态管理相关的代码
├── components # 可复用的 UI 组件
├── config # 应用的配置文件,包含客户端环境变量与服务端环境变量
├── const # 用于定义常量,如 action 类型、路由名等
├── features # 与业务功能相关的功能模块,如 Agent 设置、插件开发弹窗等
├── hooks # 全应用复用自定义的工具 Hooks
├── layout # 应用的布局组件,如导航栏、侧边栏
├── locales # 国际化的语言文件
├── services # 封装的后端服务接口,如 HTTP 请求
├── store # 用于状态管理的 zustand store
├── types # TypeScript 的类型定义文件
── utils # 通用的工具函数
├── app # Next.js App Router 实现,包含路由组和 API 路由
├── business # 业务逻辑模块(客户端和服务端)
├── components # 可复用的 UI 组件
├── config # 应用的配置文件,包含客户端环境变量与服务端环境变量
├── const # 应用常量和枚举
├── envs # 环境变量定义和校验(分析、认证、LLM 等)
├── features # 与业务功能相关的功能模块,如 Agent 设置、插件开发弹窗
├── helpers # 工具辅助函数,用于工具工程、占位符解析等
├── hooks # 全应用复用自定义的工具 Hooks
├── layout # 应用的布局组件,如导航栏、侧边栏等
├── libs # 第三方集成(分析、OIDC 等)
── locales # 国际化的语言文件
├── server # 服务端模块和服务
├── services # 封装的后端服务接口,如 HTTP 请求
├── store # 用于状态管理的 zustand store
├── styles # 全局样式和 CSS-in-JS 配置
├── tools # 内置工具(artifacts、inspectors、interventions 等)
├── types # TypeScript 的类型定义文件
└── utils # 通用的工具函数
```
有关目录架构的详细介绍,详见: [文件夹目录架构](/zh/docs/development/basic/folder-structure)
@@ -57,13 +64,13 @@ src
1. **获取代码**:克隆 LobeHub 的代码库到本地:
```bash
git clone https://github.com/lobehub/lobe-chat.git
git clone https://github.com/lobehub/lobehub.git
```
2. **安装依赖**:进入项目目录,并安装所需依赖:
```bash
cd lobe-chat
cd lobehub
# 如果你使用 Bun
bun install
# 如果你使用 PNPM
@@ -108,6 +115,6 @@ LobeHub 采用 `i18next` 和 `lobe-i18n` 实现多语言支持,确保用户全
为了支持开发者更好地理解和使用 LobeHub 的技术栈,我们提供了一份详尽的资源与参考列表 —— [LobeHub 资源与参考](/zh/docs/development/basic/resources) - 访问我们维护的资源列表,包括教程、文章和其他有用的链接。
我们鼓励开发者利用这些资源深入学习和提升技能,通过 [LobeHub GitHub Discussions](https://github.com/lobehub/lobe-chat/discussions) 或者 [Discord](https://discord.com/invite/AYFPHvv2jT) 加入社区讨论,提出问题或分享你的经验。
我们鼓励开发者利用这些资源深入学习和提升技能,通过 [LobeHub GitHub Discussions](https://github.com/lobehub/lobehub/discussions) 或者 [Discord](https://discord.com/invite/AYFPHvv2jT) 加入社区讨论,提出问题或分享你的经验。
如果你有任何疑问,或者需要进一步的帮助,请不要犹豫,请通过上述渠道与我们联系。
@@ -1,87 +0,0 @@
---
title: Configuring Casdoor Authentication for LobeChat
description: >-
Learn how to configure Casdoor SSO for LobeChat, including creating an
application and setting up environment variables.
tags:
- Casdoor
- Authentication
- LobeChat
- Single Sign-On
- OIDC
---
# Configuring Casdoor Authentication
[Casdoor](https://casdoor.org/) is an open-source Identity Access Management (IAM) platform with web UI for SSO.
<Steps>
### Create Application in Casdoor
1. Log in to your Casdoor admin console
2. Go to **Applications** and click **Add**
3. Configure the application:
- Name: `LobeChat`
- Organization: Select your organization
- Redirect URLs: Add your callback URL
<Callout type={'info'}>
**Callback URL Format**: `https://your-domain.com/api/auth/callback/casdoor`
</Callout>
4. Save and note down the **Client ID** and **Client Secret**
### Get Issuer URL
The issuer URL is your Casdoor server URL, typically: `https://your-casdoor-domain`
### Configure Environment Variables
When deploying LobeChat, you need to configure the following environment variables:
| Environment Variable | Type | Description |
| ------------------------ | -------- | ----------------------------------------------------------------------------- |
| `AUTH_SECRET` | Required | Key used to encrypt session tokens. Generate using: `openssl rand -base64 32` |
| `AUTH_SSO_PROVIDERS` | Required | SSO provider for LobeChat. Use `casdoor` for Casdoor |
| `AUTH_CASDOOR_ID` | Required | Client ID from Casdoor application |
| `AUTH_CASDOOR_SECRET` | Required | Client Secret from Casdoor application |
| `AUTH_CASDOOR_ISSUER` | Required | Casdoor server URL (e.g., `https://your-casdoor-domain`) |
| `CASDOOR_WEBHOOK_SECRET` | Optional | Secret key for validating Webhook requests from Casdoor |
<Callout type={'tip'}>
Go to [📘 Environment Variables](/docs/self-hosting/environment-variables/auth#casdoor) for detailed information on these variables.
</Callout>
### Configure Webhook (Optional)
> Available in Casdoor `>=1.843.0`.
Configure Casdoor [Webhook](https://www.casdoor.org/docs/webhooks/overview#setting-up-a-webhook) to sync user data updates to LobeChat.
**Synced data fields**:
- Avatar (`avatar`)
- Email (`email`)
- Display name (`displayName`)
**Configuration steps**:
1. Go to **Admin Tools** -> **Webhooks** and create a Webhook
2. Fill in the following fields:
- URL: `https://your-domain.com/api/webhooks/casdoor`
- Method: `POST`
- Content Type: `application/json`
- Headers: `casdoor-secret`: `your-webhook-secret`
- Events: `update-user`
3. Generate a secret at [generate-secret.vercel.app/10](https://generate-secret.vercel.app/10)
4. Set the secret in the `CASDOOR_WEBHOOK_SECRET` environment variable
</Steps>
<Callout type={'info'}>
After successful deployment, users will be able to authenticate with Casdoor and use LobeChat.
</Callout>
## Related Resources
- [Casdoor Documentation](https://casdoor.org/docs/overview)
- [Casdoor Application Configuration](https://casdoor.org/docs/application/config)
@@ -1,83 +0,0 @@
---
title: 在 LobeChat 中配置 Casdoor 身份验证
description: 学习如何在 LobeChat 中配置 Casdoor SSO,包括创建应用和设置环境变量。
tags:
- Casdoor
- 身份验证
- LobeChat
- 单点登录
- OIDC
---
# 配置 Casdoor 身份验证
[Casdoor](https://casdoor.org/) 是一个开源的身份访问管理 (IAM) 平台,提供 Web UI 支持单点登录。
<Steps>
### 在 Casdoor 中创建应用
1. 登录 Casdoor 管理控制台
2. 前往 **Applications**,点击 **Add**
3. 配置应用:
- Name: `LobeChat`
- Organization: 选择你的组织
- Redirect URLs: 添加回调 URL
<Callout type={'info'}>
**回调 URL 格式**: `https://your-domain.com/api/auth/callback/casdoor`
</Callout>
4. 保存并记下 **Client ID** 和 **Client Secret**
### 获取 Issuer URL
Issuer URL 是 Casdoor 服务器 URL,通常为:`https://your-casdoor-domain`
### 配置环境变量
在部署 LobeChat 时,你需要配置以下环境变量:
| 环境变量 | 类型 | 描述 |
| ------------------------ | -- | ------------------------------------------------- |
| `AUTH_SECRET` | 必选 | 用于加密会话令牌的密钥。使用以下命令生成:`openssl rand -base64 32` |
| `AUTH_SSO_PROVIDERS` | 必选 | SSO 提供商。使用 Casdoor 请填写 `casdoor` |
| `AUTH_CASDOOR_ID` | 必选 | Casdoor 应用的 Client ID |
| `AUTH_CASDOOR_SECRET` | 必选 | Casdoor 应用的 Client Secret |
| `AUTH_CASDOOR_ISSUER` | 必选 | Casdoor 服务器 URL(例如 `https://your-casdoor-domain` |
| `CASDOOR_WEBHOOK_SECRET` | 可选 | 用于验证 Casdoor 发送的 Webhook 请求是否合法的密钥 |
<Callout type={'tip'}>
前往 [📘 环境变量](/zh/docs/self-hosting/environment-variables/auth#casdoor) 可查阅相关变量详情。
</Callout>
### 配置 Webhook(可选)
> 在 Casdoor `>=1.843.0` 上可用。
配置 Casdoor 的 [Webhook](https://www.casdoor.org/docs/webhooks/overview#setting-up-a-webhook) 以便在用户信息更新时同步到 LobeChat。
**同步的数据字段**
- 头像 (`avatar`)
- 邮箱 (`email`)
- 显示名称 (`displayName`)
**配置步骤**
1. 前往 `管理工具` -> `Webhooks`,创建一个 Webhook
2. 填写以下字段:
- 链接:`https://your-domain.com/api/webhooks/casdoor`
- 方法:`POST`
- 内容类型:`application/json`
- 协议头:`casdoor-secret`: `你的Webhook密钥`
- 事件:`update-user`
3. 密钥可前往 [generate-secret.vercel.app/10](https://generate-secret.vercel.app/10) 生成
4. 将密钥填写到环境变量 `CASDOOR_WEBHOOK_SECRET`
</Steps>
<Callout type={'info'}>部署成功后,用户将可以通过 Casdoor 身份认证并使用 LobeChat。</Callout>
## 相关资源
- [Casdoor 文档](https://casdoor.org/docs/overview)
- [Casdoor 应用配置](https://casdoor.org/docs/application/config)
+1 -1
View File
@@ -57,4 +57,4 @@ You can achieve various feature combinations using the above configuration synta
| `commercial_hide_github` | Hides GitHub-related links in settings footer (requires commercial license). | Disabled |
| `commercial_hide_docs` | Hides documentation and help menu including changelog, docs, and feedback (requires commercial license). | Disabled |
You can always check the [featureFlags](https://github.com/lobehub/lobe-chat/blob/main/src/config/featureFlags/schema.ts) to get the latest list of feature flags.
You can always check the [featureFlags](https://github.com/lobehub/lobehub/blob/main/src/config/featureFlags/schema.ts) to get the latest list of feature flags.
@@ -53,4 +53,4 @@ tags:
| `commercial_hide_github` | 隐藏设置页面底部的 GitHub 相关链接(需要商业授权)。 | 关闭 |
| `commercial_hide_docs` | 隐藏文档和帮助菜单,包括更新日志、文档和反馈(需要商业授权)。 | 关闭 |
你可以随时检查 [featureFlags](https://github.com/lobehub/lobe-chat/blob/main/src/config/featureFlags/schema.ts) 以获取最新的特性标志列表。
你可以随时检查 [featureFlags](https://github.com/lobehub/lobehub/blob/main/src/config/featureFlags/schema.ts) 以获取最新的特性标志列表。
@@ -22,12 +22,12 @@ LobeHub supports file upload and knowledge base management. This feature relies
PostgreSQL is a powerful open-source relational database system, and PGVector is its extension for vector operations.
- **Purpose**: Store structured data and vector indexes
- **Deployment Tip**: Use official Docker image for quick deployment
- **Deployment Tip**: Use the ParadeDB Docker image for quick deployment with pgvector and pg\_search plugins
Deployment script example:
```
docker run -p 5432:5432 -d --name pg -e POSTGRES_PASSWORD=mysecretpassword pgvector/pgvector:pg17
docker run -p 5432:5432 -d --name pg -e POSTGRES_PASSWORD=mysecretpassword paradedb/paradedb:latest-pg17
```
- **Note**: Ensure sufficient resources for vector operations
@@ -20,12 +20,12 @@ LobeHub 支持文件上传 / 知识库管理。该功能依赖于以下核心技
PostgreSQL 是一个强大的开源关系型数据库系统,而 PGVector 是其扩展,为向量操作提供支持。
- **用途**:存储结构化数据和向量索引
- **部署建议**:使用官方 Docker 镜像可以快速部署 PostgreSQL 和 PGVector
- **部署建议**:使用 ParadeDB Docker 镜像可以快速部署包含 pgvector 和 pg\_search 插件的 PostgreSQL
示例部署脚本:
```
docker run -p 5432:5432 -d --name pg -e POSTGRES_PASSWORD=mysecretpassword pgvector/pgvector:pg17
docker run -p 5432:5432 -d --name pg -e POSTGRES_PASSWORD=mysecretpassword paradedb/paradedb:latest-pg17
```
- **注意事项**:确保分配足够的资源以处理向量操作
+1 -1
View File
@@ -191,7 +191,7 @@ This URL should point to a functional SearXNG instance. You can choose to self-h
You can find publicly available SearXNG instances in the [SearXNG instance list](https://searx.space/). Choose an instance that is fast and reliable, and then configure its URL in LobeHub.
> Note that the `searxng` you use must have `json` output enabled; otherwise, the `lobe-chat` call will result in an error. If self-hosting, find the `searxng` configuration file and add `json` as shown below.
> Note that the `searxng` you use must have `json` output enabled; otherwise, the `lobehub` call will result in an error. If self-hosting, find the `searxng` configuration file and add `json` as shown below.
```bash
$ vi searxng/settings.yml
@@ -186,7 +186,7 @@ SEARXNG_URL=https://searxng-instance.com
您可以在 [SearXNG 实例列表](https://searx.space/) 中找到公开可用的 SearXNG 实例。选择一个响应速度快、可靠性高的实例,然后将其 URL 配置到 LobeHub 中。
> 注意,使用的 `searxng` 必须开启 `json` 输出,否则 `lobe-chat` 调用会报错。如果是自托管,类似下面这样,找到 `searxng` 的配置文件,追加 `json` 即可。
> 注意,使用的 `searxng` 必须开启 `json` 输出,否则 `lobehub` 调用会报错。如果是自托管,类似下面这样,找到 `searxng` 的配置文件,追加 `json` 即可。
```bash
$ vi searxng/settings.yml
+6 -6
View File
@@ -1,6 +1,6 @@
---
title: Configure Redis Cache Service
description: Learn how to configure Redis cache service to optimize LobeChat performance and session management.
description: Learn how to configure Redis cache service to optimize LobeHub performance and session management.
tags:
- Redis
- Cache
@@ -10,17 +10,17 @@ tags:
# Configure Redis Cache Service
LobeChat uses Redis as a high-performance cache and session storage service to optimize system performance and manage user authentication state.
LobeHub uses Redis as a high-performance cache and session storage service to optimize system performance and manage user authentication state.
<Callout type={'info'}>
LobeChat uses the standard Redis protocol (via ioredis library), supporting any Redis
LobeHub uses the standard Redis protocol (via ioredis library), supporting any Redis
protocol-compatible service, including official Redis, self-hosted Redis, and cloud provider Redis
services (such as AWS ElastiCache, Alibaba Cloud Redis, etc.).
</Callout>
## Use Cases
Redis is used in LobeChat for the following scenarios:
Redis is used in LobeHub for the following scenarios:
### Authentication Session Storage
@@ -57,7 +57,7 @@ Caches Agent configuration data to reduce database queries and improve response
### `REDIS_PREFIX`
The prefix for Redis keys, used to isolate LobeChat data in a shared Redis instance.
The prefix for Redis keys, used to isolate LobeHub data in a shared Redis instance.
- Default: `lobechat`
- Example: `REDIS_PREFIX=my-lobechat`
@@ -119,7 +119,7 @@ REDIS_PREFIX=lobechat
## Notes
<Callout type={'warning'}>
Redis is an optional service. If `REDIS_URL` is not configured, LobeChat will still function
Redis is an optional service. If `REDIS_URL` is not configured, LobeHub will still function
normally, but will lose the caching and session management optimizations mentioned above.
</Callout>
+6 -6
View File
@@ -1,6 +1,6 @@
---
title: 配置 Redis 缓存服务
description: 了解如何配置 Redis 缓存服务以优化 LobeChat 的性能和会话管理。
description: 了解如何配置 Redis 缓存服务以优化 LobeHub 的性能和会话管理。
tags:
- Redis
- 缓存
@@ -10,17 +10,17 @@ tags:
# 配置 Redis 缓存服务
LobeChat 使用 Redis 作为高性能缓存和会话存储服务,用于优化系统性能和管理用户认证状态。
LobeHub 使用 Redis 作为高性能缓存和会话存储服务,用于优化系统性能和管理用户认证状态。
<Callout type={'info'}>
LobeChat 使用标准 Redis 协议(通过 ioredis 库),支持任何兼容 Redis 协议的服务,包括 Redis
LobeHub 使用标准 Redis 协议(通过 ioredis 库),支持任何兼容 Redis 协议的服务,包括 Redis
官方服务、自部署 Redis、以及云服务商提供的 Redis 服务(如 AWS ElastiCache、阿里云 Redis
等)。
</Callout>
## 使用场景
Redis 在 LobeChat 中主要用于以下场景:
Redis 在 LobeHub 中主要用于以下场景:
### 认证会话存储
@@ -57,7 +57,7 @@ Redis 在 LobeChat 中主要用于以下场景:
### `REDIS_PREFIX`
Redis 键的前缀,用于在共享 Redis 实例中隔离 LobeChat 的数据。
Redis 键的前缀,用于在共享 Redis 实例中隔离 LobeHub 的数据。
- 默认值:`lobechat`
- 示例:`REDIS_PREFIX=my-lobechat`
@@ -118,7 +118,7 @@ REDIS_PREFIX=lobechat
## 注意事项
<Callout type={'warning'}>
Redis 是可选服务。如果不配置 `REDIS_URL`LobeChat 仍然可以正常运行,但会失去上述缓存和会话管理的优化功能。
Redis 是可选服务。如果不配置 `REDIS_URL`LobeHub 仍然可以正常运行,但会失去上述缓存和会话管理的优化功能。
</Callout>
- **内存管理**:Redis 是内存数据库,请确保服务器有足够的内存
+3 -3
View File
@@ -1,6 +1,6 @@
---
title: Configuring Upstash Redis Service
description: Step-by-step guide to configure Upstash Redis for LobeChat cache and session storage.
description: Step-by-step guide to configure Upstash Redis for LobeHub cache and session storage.
tags:
- Upstash
- Redis
@@ -10,7 +10,7 @@ tags:
# Configuring Upstash Redis Service
[Upstash](https://upstash.com/) is a serverless Redis service that provides a free tier and pay-as-you-go pricing, making it ideal for LobeChat deployments.
[Upstash](https://upstash.com/) is a serverless Redis service that provides a free tier and pay-as-you-go pricing, making it ideal for LobeHub deployments.
## Configuration Steps
@@ -37,7 +37,7 @@ tags:
```
<Callout type={'info'}>
Upstash uses `rediss://` (with double 's') for TLS connections. LobeChat supports this format automatically.
Upstash uses `rediss://` (with double 's') for TLS connections. LobeHub supports this format automatically.
</Callout>
</Steps>
@@ -1,6 +1,6 @@
---
title: 配置 Upstash Redis 服务
description: 详细指南:如何配置 Upstash Redis 用于 LobeChat 的缓存和会话存储。
description: 详细指南:如何配置 Upstash Redis 用于 LobeHub 的缓存和会话存储。
tags:
- Upstash
- Redis
@@ -10,7 +10,7 @@ tags:
# 配置 Upstash Redis 服务
[Upstash](https://upstash.com/) 是一个 Serverless Redis 服务,提供免费额度和按量付费模式,非常适合 LobeChat 部署使用。
[Upstash](https://upstash.com/) 是一个 Serverless Redis 服务,提供免费额度和按量付费模式,非常适合 LobeHub 部署使用。
## 配置步骤
@@ -37,7 +37,7 @@ tags:
```
<Callout type={'info'}>
Upstash 使用 `rediss://`(双 's')表示 TLS 连接,LobeChat 自动支持此格式。
Upstash 使用 `rediss://`(双's')表示 TLS 连接,LobeHub 自动支持此格式。
</Callout>
</Steps>
-9
View File
@@ -50,15 +50,6 @@ The best practice in this area is to use a file storage service (S3) to store im
Whether to set the ACL to `public-read` when uploading files. This option is enabled by default. If the service provider does not support setting individual ACLs for files (i.e., all files inherit the ACL of the storage bucket), enabling this option may cause request errors. Set `S3_SET_ACL` to `0` to disable it.
### `S3_PUBLIC_DOMAIN`
The public access domain of the storage bucket, used to access files in the storage bucket. This address needs to be **publicly readable**. The reason is that when OpenAI's gpt-4o and other vision models recognize images, OpenAI will try to download this image link on their servers. Therefore, this link must be publicly accessible. If it is a private link, OpenAI will not be able to access the image and thus will not be able to recognize the image content properly.
<Callout type={'warning'}>
Additionally, since this access domain is often a separate URL, it needs to be configured to allow
cross-origin access to the site. Otherwise, cross-origin issues will occur in the browser.
</Callout>
### `S3_ENABLE_PATH_STYLE`
Whether to enable the `path-style` access mode of S3. This option is disabled by default. If your S3 service provider uses `path-style`, set `S3_ENABLE_PATH_STYLE` to `1` to enable it.
-8
View File
@@ -46,14 +46,6 @@ LobeHub 在 [很早以前](https://x.com/lobehub/status/1724289575672291782) 就
是否在上传文件时设置 ACL 为 `public-read`。该选项默认启用。如果服务商不支持为文件设置单独的 ACL(即所有文件继承存储桶的 ACL),启用此选项可能会导致请求错误,将 `S3_SET_ACL` 设置为 `0` 即可关闭。
### `S3_PUBLIC_DOMAIN`
存储桶对外的访问域名,用于访问存储桶中的文件,这个地址需要**允许互联网可读**。 原因是 OpenAI 的 gpt-4o 等视觉模型识别图片时,OpenAI 会尝试在他们的服务器中下载这个图片链接,因此这个链接必须是公开可访问的,如果是私有的链接,OpenAI 将无法访问到这个图片,进而无法正常识别到图片内容。
<Callout type={'warning'}>
此外,由于该访问域名往往是一个独立的网址,因此需要配置允许站点的跨域访问,否则会在浏览器中出现跨域问题。
</Callout>
### `S3_ENABLE_PATH_STYLE`
是否启用 S3 的 `path-style` 访问模式。此选项默认禁用。如果您的 S3 服务提供商使用 `path-style`,请将 `S3_ENABLE_PATH_STYLE` 设置为 `1` 以启用它。
@@ -39,8 +39,6 @@ We need to configure an S3 storage service in the server-side database to store
S3_BUCKET=LobeHub
# Request endpoint of the bucket (note that the path in this link includes the bucket name, which must be removed, or use the link provided on the page for applying S3 API token)
S3_ENDPOINT=https://0b33a03b5c993fd2f453379dc36558e5.r2.cloudflarestorage.com
# Access domain of the bucket
S3_PUBLIC_DOMAIN=https://s3-for-LobeHub.your-domain.com
```
<Callout type={'warning'}>
@@ -118,9 +116,6 @@ S3_SECRET_ACCESS_KEY=55af75d8eb6b99f189f6a35f855336ea62cd9c4751a5cf4337c53c1d3f4
S3_BUCKET=LobeHub
# Bucket Request Endpoint
S3_ENDPOINT=https://0b33a03b5c993fd2f453379dc36558e5.r2.cloudflarestorage.com
# Public Access Domain for the Bucket
S3_PUBLIC_DOMAIN=https://s3-dev.your-domain.com
# Bucket Region, such as us-west-1. Generally not required, but some service providers may need it.
# S3_REGION=us-west-1
```

Some files were not shown because too many files have changed in this diff Show More