Compare commits

...

95 Commits

Author SHA1 Message Date
ONLY-yours b8b1ab6616 feat: add loading back 2025-11-17 17:20:03 +08:00
ONLY-yours 3891015a3d fix: test mobile 2025-11-17 16:33:16 +08:00
ONLY-yours 5babb7d826 fix: try to fixed 2025-11-17 16:11:20 +08:00
ONLY-yours a7504b696a test: test the loading error 2025-11-17 15:38:29 +08:00
ONLY-yours 9dc4308942 fix: add router ErrorBoundary 2025-11-17 15:16:37 +08:00
ONLY-yours 082117998d fix: fixed the test error 2025-11-17 11:42:26 +08:00
ONLY-yours 9a74d6c045 fix: fix the reload was loading page problem 2025-11-17 11:26:38 +08:00
ONLY-yours b1a4f24dc9 fix: mobile chat settings go back 2025-11-17 11:19:38 +08:00
ONLY-yours c47551775b fix: delete uesless code 2025-11-17 11:04:24 +08:00
ONLY-yours 2d83300795 fix: delete useless code 2025-11-17 10:51:20 +08:00
ONLY-yours 0915538da8 Merge remote-tracking branch 'origin/next' into refactor/changeAllToSpa 2025-11-17 10:35:43 +08:00
renovate[bot] b76e3c85b9 Update all non-major dependencies (#10177)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-17 09:56:56 +08:00
lobehubbot 29ce0225b2 📝 docs(bot): Auto sync agents & plugin to readme 2025-11-17 01:49:09 +00:00
semantic-release-bot 06878829c9 🔖 chore(release): v2.0.0-next.69 [skip ci]
## [Version&nbsp;2.0.0-next.69](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.68...v2.0.0-next.69)
<sup>Released on **2025-11-17**</sup>

#### ♻ Code Refactoring

- **misc**: Remove `language_model_settings` and remove isDeprecatedEdition.

<br/>

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

#### Code refactoring

* **misc**: Remove `language_model_settings` and remove isDeprecatedEdition, closes [#10264](https://github.com/lobehub/lobe-chat/issues/10264) ([ae613c7](https://github.com/lobehub/lobe-chat/commit/ae613c7))

</details>

<div align="right">

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

</div>
2025-11-17 01:47:59 +00:00
Arvin Xu ae613c7c35 ♻️ refactor: remove language_model_settings and remove isDeprecatedEdition (#10264) 2025-11-17 09:35:49 +08:00
lobehubbot 8184f9d097 📝 docs(bot): Auto sync agents & plugin to readme 2025-11-16 15:20:51 +00:00
semantic-release-bot 7fac37b983 🔖 chore(release): v2.0.0-next.68 [skip ci]
## [Version&nbsp;2.0.0-next.68](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.67...v2.0.0-next.68)
<sup>Released on **2025-11-16**</sup>

#### 🐛 Bug Fixes

- **misc**: The tool to fail execution on ollama when a message contains b….

<br/>

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

#### What's fixed

* **misc**: The tool to fail execution on ollama when a message contains b…, closes [#10259](https://github.com/lobehub/lobe-chat/issues/10259) ([1ad8080](https://github.com/lobehub/lobe-chat/commit/1ad8080))

</details>

<div align="right">

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

</div>
2025-11-16 15:19:33 +00:00
Arvin Xu d3570879da 🔨 chore: unpin eta (#10260) 2025-11-16 23:07:44 +08:00
Hypo 1ad80809cf 🐛 fix: the tool to fail execution on ollama when a message contains b… (#10259) 2025-11-16 23:06:33 +08:00
lobehubbot 2c97a9e920 📝 docs(bot): Auto sync agents & plugin to readme 2025-11-16 11:59:30 +00:00
semantic-release-bot 246cce28db 🔖 chore(release): v2.0.0-next.67 [skip ci]
## [Version&nbsp;2.0.0-next.67](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.66...v2.0.0-next.67)
<sup>Released on **2025-11-16**</sup>

#### ♻ Code Refactoring

- **misc**: Refactor to virtua.

<br/>

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

#### Code refactoring

* **misc**: Refactor to virtua, closes [#10151](https://github.com/lobehub/lobe-chat/issues/10151) ([9ffb689](https://github.com/lobehub/lobe-chat/commit/9ffb689))

</details>

<div align="right">

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

</div>
2025-11-16 11:58:19 +00:00
Arvin Xu 9ffb6891e4 ♻️ refactor: refactor to virtua (#10151)
* refactor to virtua

* try virtua

* 默认滚动到底部

* fix
2025-11-16 19:46:41 +08:00
lobehubbot 766ca942b3 📝 docs(bot): Auto sync agents & plugin to readme 2025-11-16 07:02:41 +00:00
semantic-release-bot 147975ae46 🔖 chore(release): v2.0.0-next.66 [skip ci]
## [Version&nbsp;2.0.0-next.66](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.65...v2.0.0-next.66)
<sup>Released on **2025-11-16**</sup>

####  Features

- **misc**: Support to collapse message.

<br/>

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

#### What's improved

* **misc**: Support to collapse message, closes [#10234](https://github.com/lobehub/lobe-chat/issues/10234) ([4cd6347](https://github.com/lobehub/lobe-chat/commit/4cd6347))

</details>

<div align="right">

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

</div>
2025-11-16 07:01:10 +00:00
renovate[bot] a6c3317192 Update dependency lucide-react to ^0.553.0 (#10250)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-16 14:48:08 +08:00
Arvin Xu 4cd6347d7e feat: support to collapse message (#10234)
*  feat: add message collapse functionality

- Add collapsed field to MessageMetadata type and schema
- Add isMessageCollapsed selector to check message collapse state
- Add toggleMessageCollapsed action with optimistic update
- Export getDisplayMessageById for internal use
- Collapse state persists to database via metadata field

* 💄 ui: add collapse UI for assistant messages

- Add collapse/expand action icons to action bar
- Add collapsed message style with 200px max height and gradient overlay
- Add collapse/expand translations (zh-CN)
- Integrate with toggleMessageCollapsed store action
- Show appropriate icon based on collapsed state

* support CollapsedMessage

* update

* improve test time

* refactor fixtures

* fix tests

* improve i18n
2025-11-16 14:46:27 +08:00
Shinji-Li cd7d955e3d 🔨 chore: change the market base url to online market.lobehub.com (#10247)
* fix: change the market base url to online market.lobehub.com

* feat: update the market callback layout
2025-11-16 12:14:27 +08:00
renovate[bot] 61901ddb07 Update dependency ollama to ^0.6.3 (#10244)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-16 11:34:45 +08:00
renovate[bot] 77ed938cfb Update dependency @vercel/otel to v2 (#9969)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-16 11:34:36 +08:00
renovate[bot] 4c3ac3bce7 Update dependency dayjs to >=1.11.19 (#10241)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-16 11:33:22 +08:00
renovate[bot] a142b3384f Update aws-sdk-js-v3 monorepo to ~3.932.0 (#10119)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-16 11:31:49 +08:00
renovate[bot] ee80f613df Update dependency nanoid to >=5.1.6 (#10243)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-16 11:24:48 +08:00
lobehubbot 7d05d0270c 📝 docs(bot): Auto sync agents & plugin to readme 2025-11-16 02:12:14 +00:00
semantic-release-bot acd5954f15 🔖 chore(release): v2.0.0-next.65 [skip ci]
## [Version&nbsp;2.0.0-next.65](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.64...v2.0.0-next.65)
<sup>Released on **2025-11-16**</sup>

#### 💄 Styles

- **misc**: Update i18n.

<br/>

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

#### Styles

* **misc**: Update i18n, closes [#10235](https://github.com/lobehub/lobe-chat/issues/10235) ([a52c9e5](https://github.com/lobehub/lobe-chat/commit/a52c9e5))

</details>

<div align="right">

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

</div>
2025-11-16 02:11:08 +00:00
LobeHub Bot a52c9e5f24 🤖 style: update i18n (#10235) 2025-11-16 09:58:21 +08:00
lobehubbot bcb998d767 📝 docs(bot): Auto sync agents & plugin to readme 2025-11-15 16:51:17 +00:00
semantic-release-bot c6410b29c5 🔖 chore(release): v2.0.0-next.64 [skip ci]
## [Version&nbsp;2.0.0-next.64](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.63...v2.0.0-next.64)
<sup>Released on **2025-11-15**</sup>

#### ♻ Code Refactoring

- **misc**: Refactor package types.

<br/>

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

#### Code refactoring

* **misc**: Refactor package types, closes [#10233](https://github.com/lobehub/lobe-chat/issues/10233) ([9872409](https://github.com/lobehub/lobe-chat/commit/9872409))

</details>

<div align="right">

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

</div>
2025-11-15 16:50:03 +00:00
Arvin Xu 9872409d98 ♻️ refactor: refactor package types (#10233)
* refactor packages types

* remove lite mode
2025-11-16 00:37:55 +08:00
lobehubbot 319a622778 📝 docs(bot): Auto sync agents & plugin to readme 2025-11-15 16:08:24 +00:00
ONLY-yours 53fc0642e0 feat: use more simple way to update session hydration 2025-11-15 19:31:05 +08:00
ONLY-yours a8c725abd5 Merge remote-tracking branch 'origin/next' into refactor/changeAllToSpa 2025-11-15 19:08:58 +08:00
ONLY-yours b8a7f6e9eb feat: update the useQueryParams throttleMs params 2025-11-15 19:05:17 +08:00
ONLY-yours bb594f87e2 fix: fixed the test 2025-11-14 23:44:57 +08:00
ONLY-yours b0ee9b434e fix: fixed the url & new url not path problem 2025-11-14 23:34:31 +08:00
ONLY-yours cf2c5a1d37 fix: fixed router link error 2025-11-14 17:15:09 +08:00
ONLY-yours 0511e43a48 fix: fixed usage router error 2025-11-14 17:09:21 +08:00
ONLY-yours 1f128f407f Merge remote-tracking branch 'origin/next' into refactor/changeAllToSpa 2025-11-14 16:58:34 +08:00
ONLY-yours f258a2e042 fix: fixed the desktop knowledge page router 2025-11-14 16:18:55 +08:00
ONLY-yours 7996e1c431 Merge remote-tracking branch 'origin/next' into refactor/changeAllToSpa 2025-11-14 16:07:47 +08:00
ONLY-yours 93dddfc2e5 feat: rollback some changes about layout 2025-11-14 15:58:50 +08:00
ONLY-yours 5e4186559b fix: fix useNav in discover page error problem 2025-11-14 15:42:16 +08:00
ONLY-yours 9bfd9bb4a5 Merge remote-tracking branch 'origin/next' into refactor/changeAllToSpa 2025-11-14 15:05:02 +08:00
ONLY-yours 9ca54135b5 feat: fix a lot router problem 2025-11-14 14:45:24 +08:00
ONLY-yours f162556607 fix: delete the changelog modal page 2025-11-14 10:24:31 +08:00
ONLY-yours 3292ed83f9 fix: fix mobile router goback fc 2025-11-13 20:24:28 +08:00
ONLY-yours 561a38f788 fix: delete useless code 2025-11-13 20:08:58 +08:00
ONLY-yours 71aaf0fac5 chore: update test.ts in TopActions.tsx 2025-11-13 19:11:33 +08:00
ONLY-yours 287601f8ec fix: close the loading in the layout loading 2025-11-13 19:06:37 +08:00
ONLY-yours b36f8781e6 feat: use starTransition to navigate url 2025-11-13 18:02:16 +08:00
ONLY-yours 705450a571 fix: add files back 2025-11-13 17:17:36 +08:00
ONLY-yours 5272c7373f fix: add files back 2025-11-13 17:14:49 +08:00
ONLY-yours fb24b6f1b7 fix: add nuqs back & useQueryState back in oath 2025-11-13 17:09:10 +08:00
ONLY-yours 2fd65fe8a3 fix: discover find more link error fixed 2025-11-13 17:02:52 +08:00
ONLY-yours 35d5a2c937 chore: add mobile me layout back 2025-11-13 16:59:23 +08:00
ONLY-yours 42f40d2717 feat: change the mobile me layout back 2025-11-13 16:41:53 +08:00
ONLY-yours ef8a644d8c feat: delete all nuqs 2025-11-13 16:25:59 +08:00
ONLY-yours 81c84348bc fix: change the changelog pages render 2025-11-13 15:25:48 +08:00
ONLY-yours 8d7a0467db fix: fix build problem 2025-11-13 14:18:08 +08:00
ONLY-yours e9522729c5 fix: fix hydrateFallback problem 2025-11-13 11:49:35 +08:00
ONLY-yours cf01894077 feat: change local params get use ReactRouter Outlet context 2025-11-13 11:03:12 +08:00
ONLY-yours b5d945b1fd fix: delete some layout tsx & update the ts 2025-11-12 17:16:26 +08:00
ONLY-yours cbee964582 feat: change NextJs Link useRouter useSearchParams change to react-router way 2025-11-12 17:01:31 +08:00
ONLY-yours 87a38ad0c4 feat: change the :slug to react-router loader to get 2025-11-12 16:27:34 +08:00
ONLY-yours f2d4745ad3 Merge remote-tracking branch 'origin/next' into refactor/changeAllToSpa 2025-11-12 15:00:36 +08:00
ONLY-yours 0167ac8e28 feat: change all routes to outer routes 2025-11-12 15:00:06 +08:00
ONLY-yours b480227fd0 feat: discover pages layout & pages routers get done 2025-11-12 11:56:20 +08:00
ONLY-yours 97ff98cada Merge remote-tracking branch 'origin/next' into refactor/changeAllToSpa 2025-11-11 23:17:32 +08:00
ONLY-yours 845d3ef58a feat: change all discover page to the spa 2025-11-11 23:16:57 +08:00
ONLY-yours 906917362f feat: /chat delete pages & layouts dir 2025-11-11 17:45:12 +08:00
ONLY-yours c69049d6da fix: refactor the memory router to browser router 2025-11-11 16:01:32 +08:00
ONLY-yours 4f7356ffab feat: change AppRouter to Desktop Router & mobile Router to dynamic import 2025-11-08 17:52:05 +08:00
ONLY-yours d20c82c115 fix: change the router judge by servers 2025-11-08 11:59:00 +08:00
ONLY-yours d617a6cd97 fix: slove ts problem 2025-11-07 23:34:43 +08:00
ONLY-yours 408391eeb6 fix: slove the router back 2025-11-07 23:14:47 +08:00
ONLY-yours 4a2e671f55 fix: fix the test 2025-11-07 22:53:49 +08:00
ONLY-yours 695a261df1 Merge remote-tracking branch 'origin/next' into refactor/changeAllToSpa 2025-11-07 22:35:37 +08:00
ONLY-yours 39b723eff4 feat: fix mobile agent settings page not work problem 2025-11-07 22:24:03 +08:00
ONLY-yours 68937d842c fix: delete useless code 2025-11-07 22:16:17 +08:00
ONLY-yours b66bc66260 feat: link replace to react-router-dom 2025-11-07 22:06:18 +08:00
ONLY-yours 4d06279abd feat: change some nextjs router to react-router-dom use 2025-11-07 21:56:03 +08:00
ONLY-yours 1a8d33fbf4 fix: change the goback & knowledge/base url 2025-11-07 21:22:56 +08:00
ONLY-yours 2c086373cc feat: use loading to dynamic loading 2025-11-07 21:09:52 +08:00
ONLY-yours c7d49258f8 feat: change /settings labs image profile changelog to spa mode 2025-11-07 20:34:06 +08:00
ONLY-yours 2280fd6ff9 feat: disable / to /chat rewrite 2025-11-07 18:02:55 +08:00
ONLY-yours 8eb901c401 feat: change the root path to react-router-dom to render spa 2025-11-07 18:01:56 +08:00
498 changed files with 4682 additions and 4396 deletions
+1
View File
@@ -21,6 +21,7 @@ jobs:
(github.event_name == 'pull_request_review' && github.event.sender.type != 'Bot') ||
(github.event_name == 'pull_request_review_comment' && github.event.sender.type != 'Bot')
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
contents: read
# update issues/comments
+150
View File
@@ -2,6 +2,156 @@
# Changelog
## [Version 2.0.0-next.69](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.68...v2.0.0-next.69)
<sup>Released on **2025-11-17**</sup>
#### ♻ Code Refactoring
- **misc**: Remove `language_model_settings` and remove isDeprecatedEdition.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### Code refactoring
- **misc**: Remove `language_model_settings` and remove isDeprecatedEdition, closes [#10264](https://github.com/lobehub/lobe-chat/issues/10264) ([ae613c7](https://github.com/lobehub/lobe-chat/commit/ae613c7))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.68](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.67...v2.0.0-next.68)
<sup>Released on **2025-11-16**</sup>
#### 🐛 Bug Fixes
- **misc**: The tool to fail execution on ollama when a message contains b….
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### What's fixed
- **misc**: The tool to fail execution on ollama when a message contains b…, closes [#10259](https://github.com/lobehub/lobe-chat/issues/10259) ([1ad8080](https://github.com/lobehub/lobe-chat/commit/1ad8080))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.67](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.66...v2.0.0-next.67)
<sup>Released on **2025-11-16**</sup>
#### ♻ Code Refactoring
- **misc**: Refactor to virtua.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### Code refactoring
- **misc**: Refactor to virtua, closes [#10151](https://github.com/lobehub/lobe-chat/issues/10151) ([9ffb689](https://github.com/lobehub/lobe-chat/commit/9ffb689))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.66](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.65...v2.0.0-next.66)
<sup>Released on **2025-11-16**</sup>
#### ✨ Features
- **misc**: Support to collapse message.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### What's improved
- **misc**: Support to collapse message, closes [#10234](https://github.com/lobehub/lobe-chat/issues/10234) ([4cd6347](https://github.com/lobehub/lobe-chat/commit/4cd6347))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.65](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.64...v2.0.0-next.65)
<sup>Released on **2025-11-16**</sup>
#### 💄 Styles
- **misc**: Update i18n.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### Styles
- **misc**: Update i18n, closes [#10235](https://github.com/lobehub/lobe-chat/issues/10235) ([a52c9e5](https://github.com/lobehub/lobe-chat/commit/a52c9e5))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.64](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.63...v2.0.0-next.64)
<sup>Released on **2025-11-15**</sup>
#### ♻ Code Refactoring
- **misc**: Refactor package types.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### Code refactoring
- **misc**: Refactor package types, closes [#10233](https://github.com/lobehub/lobe-chat/issues/10233) ([9872409](https://github.com/lobehub/lobe-chat/commit/9872409))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.63](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.62...v2.0.0-next.63)
<sup>Released on **2025-11-15**</sup>
-272
View File
@@ -1,272 +0,0 @@
## Set global build ENV
ARG NODEJS_VERSION="24"
## Base image for all building stages
FROM node:${NODEJS_VERSION}-slim AS base
ARG USE_CN_MIRROR
ENV DEBIAN_FRONTEND="noninteractive"
RUN \
# If you want to build docker in China, build with --build-arg USE_CN_MIRROR=true
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 \
# Add required package
&& apt update \
&& apt install ca-certificates proxychains-ng -qy \
# Prepare required package to distroless
&& mkdir -p /distroless/bin /distroless/etc /distroless/etc/ssl/certs /distroless/lib \
# Copy proxychains to distroless
&& 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 \
# Copy node to distroless
&& 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 \
# Copy CA certificates to distroless
&& cp /etc/ssl/certs/ca-certificates.crt /distroless/etc/ssl/certs/ca-certificates.crt \
# Cleanup temp files
&& rm -rf /tmp/* /var/lib/apt/lists/* /var/tmp/*
## Builder image, install all the dependencies and build the app
FROM base AS builder
ARG USE_CN_MIRROR
ARG NEXT_PUBLIC_BASE_PATH
ARG NEXT_PUBLIC_SENTRY_DSN
ARG NEXT_PUBLIC_ANALYTICS_POSTHOG
ARG NEXT_PUBLIC_POSTHOG_HOST
ARG NEXT_PUBLIC_POSTHOG_KEY
ARG NEXT_PUBLIC_ANALYTICS_UMAMI
ARG NEXT_PUBLIC_UMAMI_SCRIPT_URL
ARG NEXT_PUBLIC_UMAMI_WEBSITE_ID
ARG FEATURE_FLAGS
ENV NEXT_PUBLIC_CLIENT_DB="pglite"
ENV NEXT_PUBLIC_BASE_PATH="${NEXT_PUBLIC_BASE_PATH}" \
FEATURE_FLAGS="${FEATURE_FLAGS}"
# Sentry
ENV NEXT_PUBLIC_SENTRY_DSN="${NEXT_PUBLIC_SENTRY_DSN}" \
SENTRY_ORG="" \
SENTRY_PROJECT=""
ENV APP_URL="http://app.com"
# Posthog
ENV NEXT_PUBLIC_ANALYTICS_POSTHOG="${NEXT_PUBLIC_ANALYTICS_POSTHOG}" \
NEXT_PUBLIC_POSTHOG_HOST="${NEXT_PUBLIC_POSTHOG_HOST}" \
NEXT_PUBLIC_POSTHOG_KEY="${NEXT_PUBLIC_POSTHOG_KEY}"
# Umami
ENV NEXT_PUBLIC_ANALYTICS_UMAMI="${NEXT_PUBLIC_ANALYTICS_UMAMI}" \
NEXT_PUBLIC_UMAMI_SCRIPT_URL="${NEXT_PUBLIC_UMAMI_SCRIPT_URL}" \
NEXT_PUBLIC_UMAMI_WEBSITE_ID="${NEXT_PUBLIC_UMAMI_WEBSITE_ID}"
# Node
ENV NODE_OPTIONS="--max-old-space-size=6144"
WORKDIR /app
COPY package.json pnpm-workspace.yaml ./
COPY .npmrc ./
COPY packages ./packages
RUN \
# If you want to build docker in China, build with --build-arg USE_CN_MIRROR=true
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 \
# Set the registry for corepack
&& export COREPACK_NPM_REGISTRY=$(npm config get registry | sed 's/\/$//') \
# Update corepack to latest (nodejs/corepack#612)
&& npm i -g corepack@latest \
# Enable corepack
&& corepack enable \
# Use pnpm for corepack
&& corepack use $(sed -n 's/.*"packageManager": "\(.*\)".*/\1/p' package.json) \
# Install the dependencies
&& pnpm i
COPY . .
# run build standalone for docker version
RUN npm run build:docker
## Application image, copy all the files for production
FROM busybox:latest AS app
COPY --from=base /distroless/ /
# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder /app/.next/standalone /app/
# Copy server launcher
COPY --from=builder /app/scripts/serverLauncher/startServer.js /app/startServer.js
RUN \
# Add nextjs:nodejs to run the app
addgroup -S -g 1001 nodejs \
&& adduser -D -G nodejs -H -S -h /app -u 1001 nextjs \
# Set permission for nextjs:nodejs
&& chown -R nextjs:nodejs /app /etc/proxychains4.conf
## Production image, copy all the files and run next
FROM scratch
# Copy all the files from app, set the correct permission for prerender cache
COPY --from=app / /
ENV NODE_ENV="production" \
NODE_OPTIONS="--dns-result-order=ipv4first --use-openssl-ca" \
NODE_EXTRA_CA_CERTS="" \
NODE_TLS_REJECT_UNAUTHORIZED="" \
SSL_CERT_FILE="/etc/ssl/certs/ca-certificates.crt"
# Make the middleware rewrite through local as default
# refs: https://github.com/lobehub/lobe-chat/issues/5876
ENV MIDDLEWARE_REWRITE_THROUGH_LOCAL="1"
# set hostname to localhost
ENV HOSTNAME="0.0.0.0" \
PORT="3210"
# General Variables
ENV ACCESS_CODE="" \
API_KEY_SELECT_MODE="" \
DEFAULT_AGENT_CONFIG="" \
SYSTEM_AGENT="" \
FEATURE_FLAGS="" \
PROXY_URL="" \
ENABLE_AUTH_PROTECTION=""
# Model Variables
ENV \
# AI21
AI21_API_KEY="" AI21_MODEL_LIST="" \
# Ai360
AI360_API_KEY="" AI360_MODEL_LIST="" \
# AiHubMix
AIHUBMIX_API_KEY="" AIHUBMIX_MODEL_LIST="" \
# Anthropic
ANTHROPIC_API_KEY="" ANTHROPIC_MODEL_LIST="" ANTHROPIC_PROXY_URL="" \
# Amazon Bedrock
ENABLED_AWS_BEDROCK="" AWS_ACCESS_KEY_ID="" AWS_SECRET_ACCESS_KEY="" AWS_REGION="" AWS_BEDROCK_MODEL_LIST="" \
# Azure OpenAI
AZURE_API_KEY="" AZURE_API_VERSION="" AZURE_ENDPOINT="" AZURE_MODEL_LIST="" \
# Baichuan
BAICHUAN_API_KEY="" BAICHUAN_MODEL_LIST="" \
# Cloudflare
CLOUDFLARE_API_KEY="" CLOUDFLARE_BASE_URL_OR_ACCOUNT_ID="" CLOUDFLARE_MODEL_LIST="" \
# Cohere
COHERE_API_KEY="" COHERE_MODEL_LIST="" COHERE_PROXY_URL="" \
# ComfyUI
ENABLED_COMFYUI="" COMFYUI_BASE_URL="" COMFYUI_AUTH_TYPE="" \
COMFYUI_API_KEY="" COMFYUI_USERNAME="" COMFYUI_PASSWORD="" COMFYUI_CUSTOM_HEADERS="" \
# DeepSeek
DEEPSEEK_API_KEY="" DEEPSEEK_MODEL_LIST="" \
# Fireworks AI
FIREWORKSAI_API_KEY="" FIREWORKSAI_MODEL_LIST="" \
# Gitee AI
GITEE_AI_API_KEY="" GITEE_AI_MODEL_LIST="" \
# GitHub
GITHUB_TOKEN="" GITHUB_MODEL_LIST="" \
# Google
GOOGLE_API_KEY="" GOOGLE_MODEL_LIST="" GOOGLE_PROXY_URL="" \
# Groq
GROQ_API_KEY="" GROQ_MODEL_LIST="" GROQ_PROXY_URL="" \
# Higress
HIGRESS_API_KEY="" HIGRESS_MODEL_LIST="" HIGRESS_PROXY_URL="" \
# HuggingFace
HUGGINGFACE_API_KEY="" HUGGINGFACE_MODEL_LIST="" HUGGINGFACE_PROXY_URL="" \
# Hunyuan
HUNYUAN_API_KEY="" HUNYUAN_MODEL_LIST="" \
# InternLM
INTERNLM_API_KEY="" INTERNLM_MODEL_LIST="" \
# Jina
JINA_API_KEY="" JINA_MODEL_LIST="" JINA_PROXY_URL="" \
# Minimax
MINIMAX_API_KEY="" MINIMAX_MODEL_LIST="" \
# Mistral
MISTRAL_API_KEY="" MISTRAL_MODEL_LIST="" \
# ModelScope
MODELSCOPE_API_KEY="" MODELSCOPE_MODEL_LIST="" MODELSCOPE_PROXY_URL="" \
# Moonshot
MOONSHOT_API_KEY="" MOONSHOT_MODEL_LIST="" MOONSHOT_PROXY_URL="" \
# Nebius
NEBIUS_API_KEY="" NEBIUS_MODEL_LIST="" NEBIUS_PROXY_URL="" \
# NewAPI
NEWAPI_API_KEY="" NEWAPI_PROXY_URL="" \
# Novita
NOVITA_API_KEY="" NOVITA_MODEL_LIST="" \
# Nvidia NIM
NVIDIA_API_KEY="" NVIDIA_MODEL_LIST="" NVIDIA_PROXY_URL="" \
# Ollama
ENABLED_OLLAMA="" OLLAMA_MODEL_LIST="" OLLAMA_PROXY_URL="" \
# OpenAI
ENABLED_OPENAI="" OPENAI_API_KEY="" OPENAI_MODEL_LIST="" OPENAI_PROXY_URL="" \
# OpenRouter
OPENROUTER_API_KEY="" OPENROUTER_MODEL_LIST="" \
# Perplexity
PERPLEXITY_API_KEY="" PERPLEXITY_MODEL_LIST="" PERPLEXITY_PROXY_URL="" \
# Qiniu
QINIU_API_KEY="" QINIU_MODEL_LIST="" QINIU_PROXY_URL="" \
# Qwen
QWEN_API_KEY="" QWEN_MODEL_LIST="" QWEN_PROXY_URL="" \
# SambaNova
SAMBANOVA_API_KEY="" SAMBANOVA_MODEL_LIST="" \
# SenseNova
SENSENOVA_API_KEY="" SENSENOVA_MODEL_LIST="" \
# SiliconCloud
SILICONCLOUD_API_KEY="" SILICONCLOUD_MODEL_LIST="" SILICONCLOUD_PROXY_URL="" \
# Spark
SPARK_API_KEY="" SPARK_MODEL_LIST="" SPARK_PROXY_URL="" SPARK_SEARCH_MODE="" \
# Stepfun
STEPFUN_API_KEY="" STEPFUN_MODEL_LIST="" \
# Taichu
TAICHU_API_KEY="" TAICHU_MODEL_LIST="" \
# TogetherAI
TOGETHERAI_API_KEY="" TOGETHERAI_MODEL_LIST="" \
# Upstage
UPSTAGE_API_KEY="" UPSTAGE_MODEL_LIST="" \
# v0 (Vercel)
V0_API_KEY="" V0_MODEL_LIST="" \
# vLLM
VLLM_API_KEY="" VLLM_MODEL_LIST="" VLLM_PROXY_URL="" \
# Wenxin
WENXIN_API_KEY="" WENXIN_MODEL_LIST="" \
# xAI
XAI_API_KEY="" XAI_MODEL_LIST="" XAI_PROXY_URL="" \
# Xinference
XINFERENCE_API_KEY="" XINFERENCE_MODEL_LIST="" XINFERENCE_PROXY_URL="" \
# 01.AI
ZEROONE_API_KEY="" ZEROONE_MODEL_LIST="" \
# Zhipu
ZHIPU_API_KEY="" ZHIPU_MODEL_LIST="" \
# Tencent Cloud
TENCENT_CLOUD_API_KEY="" TENCENT_CLOUD_MODEL_LIST="" \
# Infini-AI
INFINIAI_API_KEY="" INFINIAI_MODEL_LIST="" \
# 302.AI
AI302_API_KEY="" AI302_MODEL_LIST="" \
# FAL
ENABLED_FAL="" FAL_API_KEY="" FAL_MODEL_LIST="" \
# BFL
BFL_API_KEY="" BFL_MODEL_LIST="" \
# Vercel AI Gateway
VERCELAIGATEWAY_API_KEY="" VERCELAIGATEWAY_MODEL_LIST=""
USER nextjs
EXPOSE 3210/tcp
ENTRYPOINT ["/bin/node"]
CMD ["/app/startServer.js"]
+18 -18
View File
@@ -32,33 +32,33 @@
"electron-updater": "^6.6.2",
"electron-window-state": "^5.0.3",
"fetch-socks": "^1.3.2",
"get-port-please": "^3.1.2",
"get-port-please": "^3.2.0",
"pdfjs-dist": "4.10.38"
},
"devDependencies": {
"@electron-toolkit/eslint-config-prettier": "^3.0.0",
"@electron-toolkit/eslint-config-ts": "^3.0.0",
"@electron-toolkit/preload": "^3.0.1",
"@electron-toolkit/eslint-config-ts": "^3.1.0",
"@electron-toolkit/preload": "^3.0.2",
"@electron-toolkit/tsconfig": "^2.0.0",
"@electron-toolkit/utils": "^4.0.0",
"@lobechat/electron-client-ipc": "workspace:*",
"@lobechat/electron-server-ipc": "workspace:*",
"@lobechat/file-loaders": "workspace:*",
"@lobehub/i18n-cli": "^1.20.3",
"@types/lodash": "^4.17.0",
"@lobehub/i18n-cli": "^1.25.1",
"@types/lodash": "^4.17.20",
"@types/resolve": "^1.20.6",
"@types/semver": "^7.7.0",
"@types/semver": "^7.7.1",
"@types/set-cookie-parser": "^2.4.10",
"@typescript/native-preview": "7.0.0-dev.20250711.1",
"consola": "^3.1.0",
"consola": "^3.4.2",
"cookie": "^1.0.2",
"electron": "^38.6.0",
"electron": "^38.7.0",
"electron-builder": "^26.0.12",
"electron-is": "^3.0.0",
"electron-log": "^5.3.3",
"electron-log": "^5.4.3",
"electron-store": "^8.2.0",
"electron-vite": "^3.0.0",
"execa": "^9.5.2",
"electron-vite": "^3.1.0",
"execa": "^9.6.0",
"fast-glob": "^3.3.3",
"fix-path": "^5.0.0",
"http-proxy-agent": "^7.0.2",
@@ -66,13 +66,13 @@
"just-diff": "^6.0.2",
"lodash": "^4.17.21",
"lodash-es": "^4.17.21",
"resolve": "^1.22.8",
"semver": "^7.5.4",
"set-cookie-parser": "^2.7.1",
"tsx": "^4.19.3",
"typescript": "^5.7.3",
"undici": "^7.9.0",
"vite": "^6.3.5",
"resolve": "^1.22.11",
"semver": "^7.7.3",
"set-cookie-parser": "^2.7.2",
"tsx": "^4.20.6",
"typescript": "^5.9.3",
"undici": "^7.16.0",
"vite": "^6.4.1",
"vitest": "^3.2.4"
},
"pnpm": {
+49
View File
@@ -1,4 +1,53 @@
[
{
"children": {
"improvements": ["Remove language_model_settings and remove isDeprecatedEdition."]
},
"date": "2025-11-17",
"version": "2.0.0-next.69"
},
{
"children": {
"fixes": ["The tool to fail execution on ollama when a message contains b…."]
},
"date": "2025-11-16",
"version": "2.0.0-next.68"
},
{
"children": {
"improvements": ["Refactor to virtua."]
},
"date": "2025-11-16",
"version": "2.0.0-next.67"
},
{
"children": {
"features": ["Support to collapse message."]
},
"date": "2025-11-16",
"version": "2.0.0-next.66"
},
{
"children": {
"improvements": ["Update i18n."]
},
"date": "2025-11-16",
"version": "2.0.0-next.65"
},
{
"children": {
"improvements": ["Refactor package types."]
},
"date": "2025-11-15",
"version": "2.0.0-next.64"
},
{
"children": {
"features": ["Show orphaned tool message and support delete tool message."]
},
"date": "2025-11-15",
"version": "2.0.0-next.63"
},
{
"children": {},
"date": "2025-11-15",
+2 -2
View File
@@ -17,8 +17,8 @@
"playwright": "^1.56.1"
},
"devDependencies": {
"@types/node": "^22.10.5",
"@types/node": "^22.19.1",
"tsx": "^4.20.6",
"typescript": "^5.7.3"
"typescript": "^5.9.3"
}
}
+3
View File
@@ -17,6 +17,7 @@
"availableAgents": "المساعدون المتاحون",
"backToBottom": "العودة إلى الأسفل",
"chatList": {
"expandMessage": "عرض الرسائل",
"longMessageDetail": "عرض التفاصيل"
},
"clearCurrentMessages": "مسح رسائل الجلسة الحالية",
@@ -173,9 +174,11 @@
"title": "الإشارة إلى الأعضاء"
},
"messageAction": {
"collapse": "إخفاء الرسائل",
"continueGeneration": "متابعة التوليد",
"delAndRegenerate": "حذف وإعادة الإنشاء",
"deleteDisabledByThreads": "يوجد موضوعات فرعية، لا يمكن الحذف",
"expand": "عرض الرسائل",
"regenerate": "إعادة الإنشاء"
},
"messages": {
+5
View File
@@ -253,6 +253,11 @@
},
"localSystem": {
"apiName": {
"editLocalFile": "تحرير الملف",
"getCommandOutput": "الحصول على مخرجات الأوامر",
"globLocalFiles": "البحث عن الملفات المطابقة",
"grepContent": "البحث في المحتوى",
"killCommand": "إيقاف تنفيذ الأمر",
"listLocalFiles": "عرض قائمة الملفات",
"moveLocalFiles": "نقل الملفات",
"readLocalFile": "قراءة محتوى الملف",
+3
View File
@@ -17,6 +17,7 @@
"availableAgents": "Налични асистенти",
"backToBottom": "Върни се в началото",
"chatList": {
"expandMessage": "Разгъни съобщението",
"longMessageDetail": "Вижте детайлите"
},
"clearCurrentMessages": "Изчисти съобщенията от текущата сесия",
@@ -173,9 +174,11 @@
"title": "Споменаване на членове"
},
"messageAction": {
"collapse": "Скрий съобщението",
"continueGeneration": "Продължи генерирането",
"delAndRegenerate": "Изтрий и прегенерирай",
"deleteDisabledByThreads": "Съществуват подтеми, не можете да изтриете.",
"expand": "Разгъни съобщението",
"regenerate": "Прегенерирай"
},
"messages": {
+5
View File
@@ -253,6 +253,11 @@
},
"localSystem": {
"apiName": {
"editLocalFile": "Редактиране на файл",
"getCommandOutput": "Получаване на изход от командата",
"globLocalFiles": "Търсене на съвпадащи файлове",
"grepContent": "Търсене на съдържание",
"killCommand": "Прекратяване на изпълнението на командата",
"listLocalFiles": "Преглед на списък с файлове",
"moveLocalFiles": "Преместване на файлове",
"readLocalFile": "Четене на съдържание на файл",
+3
View File
@@ -17,6 +17,7 @@
"availableAgents": "Verfügbare Assistenten",
"backToBottom": "Zurück zum Ende",
"chatList": {
"expandMessage": "Nachricht anzeigen",
"longMessageDetail": "Details anzeigen"
},
"clearCurrentMessages": "Aktuelle Nachrichten löschen",
@@ -173,9 +174,11 @@
"title": "Mitglieder erwähnen"
},
"messageAction": {
"collapse": "Nachricht ausblenden",
"continueGeneration": "Generierung fortsetzen",
"delAndRegenerate": "Löschen und neu generieren",
"deleteDisabledByThreads": "Es gibt Unterthemen, die Löschung ist nicht möglich.",
"expand": "Nachricht anzeigen",
"regenerate": "Neu generieren"
},
"messages": {
+5
View File
@@ -253,6 +253,11 @@
},
"localSystem": {
"apiName": {
"editLocalFile": "Datei bearbeiten",
"getCommandOutput": "Codeausgabe abrufen",
"globLocalFiles": "Dateien durchsuchen",
"grepContent": "Inhalt durchsuchen",
"killCommand": "Codeausführung beenden",
"listLocalFiles": "Dateiliste anzeigen",
"moveLocalFiles": "Dateien verschieben",
"readLocalFile": "Dateiinhalt lesen",
+3
View File
@@ -17,6 +17,7 @@
"availableAgents": "Available assistants",
"backToBottom": "Back to bottom",
"chatList": {
"expandMessage": "Expand Message",
"longMessageDetail": "View Details"
},
"clearCurrentMessages": "Clear current session messages",
@@ -173,9 +174,11 @@
"title": "Mention Members"
},
"messageAction": {
"collapse": "Collapse Message",
"continueGeneration": "Continue Generating",
"delAndRegenerate": "Delete and Regenerate",
"deleteDisabledByThreads": "There are subtopics, deletion is not allowed",
"expand": "Expand Message",
"regenerate": "Regenerate"
},
"messages": {
+3
View File
@@ -17,6 +17,7 @@
"availableAgents": "Agentes disponibles",
"backToBottom": "Volver al fondo",
"chatList": {
"expandMessage": "Expandir mensaje",
"longMessageDetail": "Ver detalles"
},
"clearCurrentMessages": "Borrar mensajes actuales",
@@ -173,9 +174,11 @@
"title": "Mencionar miembros"
},
"messageAction": {
"collapse": "Ocultar mensaje",
"continueGeneration": "Continuar generando",
"delAndRegenerate": "Eliminar y Regenerar",
"deleteDisabledByThreads": "Existen subtemas, no se puede eliminar",
"expand": "Expandir mensaje",
"regenerate": "Regenerar"
},
"messages": {
+5
View File
@@ -253,6 +253,11 @@
},
"localSystem": {
"apiName": {
"editLocalFile": "Editar archivo",
"getCommandOutput": "Obtener salida del código",
"globLocalFiles": "Buscar archivos coincidentes",
"grepContent": "Buscar contenido",
"killCommand": "Detener ejecución del código",
"listLocalFiles": "Ver lista de archivos",
"moveLocalFiles": "Mover archivos",
"readLocalFile": "Leer contenido del archivo",
+3
View File
@@ -17,6 +17,7 @@
"availableAgents": "دستیاران در دسترس",
"backToBottom": "بازگشت به پایین",
"chatList": {
"expandMessage": "گسترش پیام",
"longMessageDetail": "مشاهده جزئیات"
},
"clearCurrentMessages": "پاک کردن پیام‌های جلسه فعلی",
@@ -173,9 +174,11 @@
"title": "ذکر اعضا"
},
"messageAction": {
"collapse": "بستن پیام",
"continueGeneration": "ادامه تولید",
"delAndRegenerate": "حذف و بازتولید",
"deleteDisabledByThreads": "زیرموضوع وجود دارد، نمی‌توان حذف کرد",
"expand": "گسترش پیام",
"regenerate": "بازتولید"
},
"messages": {
+5
View File
@@ -253,6 +253,11 @@
},
"localSystem": {
"apiName": {
"editLocalFile": "ویرایش فایل",
"getCommandOutput": "دریافت خروجی کد",
"globLocalFiles": "جستجوی فایل‌ها با الگو",
"grepContent": "جستجوی محتوا",
"killCommand": "متوقف کردن اجرای کد",
"listLocalFiles": "مشاهده لیست فایل‌ها",
"moveLocalFiles": "جابجایی فایل‌ها",
"readLocalFile": "خواندن محتوای فایل",
+3
View File
@@ -17,6 +17,7 @@
"availableAgents": "Assistants disponibles",
"backToBottom": "Retour en bas",
"chatList": {
"expandMessage": "Développer le message",
"longMessageDetail": "Voir les détails"
},
"clearCurrentMessages": "Effacer les messages actuels",
@@ -173,9 +174,11 @@
"title": "Mentionner un membre"
},
"messageAction": {
"collapse": "Réduire le message",
"continueGeneration": "Continuer la génération",
"delAndRegenerate": "Supprimer et régénérer",
"deleteDisabledByThreads": "Il existe des sous-sujets, la suppression n'est pas possible.",
"expand": "Développer le message",
"regenerate": "Régénérer"
},
"messages": {
+5
View File
@@ -253,6 +253,11 @@
},
"localSystem": {
"apiName": {
"editLocalFile": "Modifier le fichier",
"getCommandOutput": "Obtenir la sortie du code",
"globLocalFiles": "Rechercher des fichiers correspondants",
"grepContent": "Rechercher dans le contenu",
"killCommand": "Arrêter l'exécution du code",
"listLocalFiles": "Voir la liste des fichiers",
"moveLocalFiles": "Déplacer les fichiers",
"readLocalFile": "Lire le contenu du fichier",
+3
View File
@@ -17,6 +17,7 @@
"availableAgents": "Assistenti disponibili",
"backToBottom": "Torna in fondo",
"chatList": {
"expandMessage": "Espandi messaggio",
"longMessageDetail": "Visualizza dettagli"
},
"clearCurrentMessages": "Cancella messaggi attuali",
@@ -173,9 +174,11 @@
"title": "Menziona membri"
},
"messageAction": {
"collapse": "Comprimi messaggio",
"continueGeneration": "Continua a generare",
"delAndRegenerate": "Elimina e rigenera",
"deleteDisabledByThreads": "Esistono sottoargomenti, non è possibile eliminare",
"expand": "Espandi messaggio",
"regenerate": "Rigenera"
},
"messages": {
+5
View File
@@ -253,6 +253,11 @@
},
"localSystem": {
"apiName": {
"editLocalFile": "Modifica file",
"getCommandOutput": "Ottieni output del codice",
"globLocalFiles": "Cerca file corrispondenti",
"grepContent": "Cerca contenuto",
"killCommand": "Termina esecuzione del codice",
"listLocalFiles": "Visualizza lista file",
"moveLocalFiles": "Sposta file",
"readLocalFile": "Leggi contenuto file",
+3
View File
@@ -17,6 +17,7 @@
"availableAgents": "利用可能なアシスタント",
"backToBottom": "現在に戻る",
"chatList": {
"expandMessage": "メッセージを展開",
"longMessageDetail": "詳細を見る"
},
"clearCurrentMessages": "現在の会話をクリア",
@@ -173,9 +174,11 @@
"title": "メンバーをメンション"
},
"messageAction": {
"collapse": "メッセージを折りたたむ",
"continueGeneration": "生成を続ける",
"delAndRegenerate": "削除して再生成",
"deleteDisabledByThreads": "サブトピックが存在するため、削除できません。",
"expand": "メッセージを展開",
"regenerate": "再生成"
},
"messages": {
+5
View File
@@ -253,6 +253,11 @@
},
"localSystem": {
"apiName": {
"editLocalFile": "ファイルを編集",
"getCommandOutput": "コード出力を取得",
"globLocalFiles": "ファイルを検索",
"grepContent": "内容を検索",
"killCommand": "コードの実行を停止",
"listLocalFiles": "ファイル一覧を表示",
"moveLocalFiles": "ファイルを移動",
"readLocalFile": "ファイル内容を読み込み",
+3
View File
@@ -17,6 +17,7 @@
"availableAgents": "사용 가능한 도우미",
"backToBottom": "하단으로 이동",
"chatList": {
"expandMessage": "메시지 펼치기",
"longMessageDetail": "자세히 보기"
},
"clearCurrentMessages": "현재 대화 지우기",
@@ -173,9 +174,11 @@
"title": "멤버 언급"
},
"messageAction": {
"collapse": "메시지 접기",
"continueGeneration": "계속 생성하기",
"delAndRegenerate": "삭제하고 다시 생성",
"deleteDisabledByThreads": "하위 주제가 존재하여 삭제할 수 없습니다.",
"expand": "메시지 펼치기",
"regenerate": "다시 생성"
},
"messages": {
+5
View File
@@ -253,6 +253,11 @@
},
"localSystem": {
"apiName": {
"editLocalFile": "파일 편집",
"getCommandOutput": "코드 출력 가져오기",
"globLocalFiles": "파일 검색",
"grepContent": "내용 검색",
"killCommand": "코드 실행 중지",
"listLocalFiles": "파일 목록 보기",
"moveLocalFiles": "파일 이동",
"readLocalFile": "파일 내용 읽기",
+3
View File
@@ -17,6 +17,7 @@
"availableAgents": "Beschikbare assistenten",
"backToBottom": "Terug naar onderen",
"chatList": {
"expandMessage": "Bericht uitvouwen",
"longMessageDetail": "Bekijk details"
},
"clearCurrentMessages": "Huidige berichten wissen",
@@ -173,9 +174,11 @@
"title": "Leden vermelden"
},
"messageAction": {
"collapse": "Bericht samenvouwen",
"continueGeneration": "Doorgaan met genereren",
"delAndRegenerate": "Verwijderen en opnieuw genereren",
"deleteDisabledByThreads": "Er zijn subonderwerpen, verwijderen is niet mogelijk.",
"expand": "Bericht uitvouwen",
"regenerate": "Opnieuw genereren"
},
"messages": {
+5
View File
@@ -253,6 +253,11 @@
},
"localSystem": {
"apiName": {
"editLocalFile": "Bestand bewerken",
"getCommandOutput": "Code-uitvoer ophalen",
"globLocalFiles": "Bestanden zoeken",
"grepContent": "Inhoud doorzoeken",
"killCommand": "Code-uitvoering beëindigen",
"listLocalFiles": "Bestandslijst bekijken",
"moveLocalFiles": "Bestanden verplaatsen",
"readLocalFile": "Bestandsinhoud lezen",
+3
View File
@@ -17,6 +17,7 @@
"availableAgents": "Dostępni asystenci",
"backToBottom": "Przewiń na dół",
"chatList": {
"expandMessage": "Rozwiń wiadomość",
"longMessageDetail": "Zobacz szczegóły"
},
"clearCurrentMessages": "Wyczyść bieżącą rozmowę",
@@ -173,9 +174,11 @@
"title": "Wzmianka o członkach"
},
"messageAction": {
"collapse": "Zwiń wiadomość",
"continueGeneration": "Kontynuuj generowanie",
"delAndRegenerate": "Usuń i wygeneruj ponownie",
"deleteDisabledByThreads": "Istnieją podwątki, nie można usunąć",
"expand": "Rozwiń wiadomość",
"regenerate": "Wygeneruj ponownie"
},
"messages": {
+5
View File
@@ -253,6 +253,11 @@
},
"localSystem": {
"apiName": {
"editLocalFile": "Edytuj plik",
"getCommandOutput": "Pobierz wynik polecenia",
"globLocalFiles": "Wyszukaj pasujące pliki",
"grepContent": "Przeszukaj zawartość",
"killCommand": "Zatrzymaj wykonywanie polecenia",
"listLocalFiles": "Wyświetl listę plików",
"moveLocalFiles": "Przenieś pliki",
"readLocalFile": "Odczytaj zawartość pliku",
+3
View File
@@ -17,6 +17,7 @@
"availableAgents": "Assistentes disponíveis",
"backToBottom": "Voltar para o início",
"chatList": {
"expandMessage": "Expandir mensagem",
"longMessageDetail": "Ver detalhes"
},
"clearCurrentMessages": "Limpar mensagens atuais",
@@ -173,9 +174,11 @@
"title": "Mencionar membros"
},
"messageAction": {
"collapse": "Recolher mensagem",
"continueGeneration": "Continuar gerando",
"delAndRegenerate": "Excluir e Regenerar",
"deleteDisabledByThreads": "Existem subtópicos, não é possível deletar.",
"expand": "Expandir mensagem",
"regenerate": "Regenerar"
},
"messages": {
+5
View File
@@ -253,6 +253,11 @@
},
"localSystem": {
"apiName": {
"editLocalFile": "Editar arquivo",
"getCommandOutput": "Obter saída do código",
"globLocalFiles": "Buscar arquivos correspondentes",
"grepContent": "Procurar conteúdo",
"killCommand": "Encerrar execução do código",
"listLocalFiles": "Ver lista de arquivos",
"moveLocalFiles": "Mover arquivos",
"readLocalFile": "Ler conteúdo do arquivo",
+3
View File
@@ -17,6 +17,7 @@
"availableAgents": "Доступные помощники",
"backToBottom": "Вернуться вниз",
"chatList": {
"expandMessage": "Развернуть сообщение",
"longMessageDetail": "Посмотреть детали"
},
"clearCurrentMessages": "Очистить текущий разговор",
@@ -173,9 +174,11 @@
"title": "Упомянуть участника"
},
"messageAction": {
"collapse": "Свернуть сообщение",
"continueGeneration": "Продолжить генерацию",
"delAndRegenerate": "Удалить и пересоздать",
"deleteDisabledByThreads": "Существуют подтемы, удаление невозможно",
"expand": "Развернуть сообщение",
"regenerate": "Пересоздать"
},
"messages": {
+5
View File
@@ -253,6 +253,11 @@
},
"localSystem": {
"apiName": {
"editLocalFile": "Редактировать файл",
"getCommandOutput": "Получить вывод команды",
"globLocalFiles": "Поиск файлов по шаблону",
"grepContent": "Поиск по содержимому",
"killCommand": "Прервать выполнение команды",
"listLocalFiles": "Просмотр списка файлов",
"moveLocalFiles": "Перемещение файлов",
"readLocalFile": "Чтение содержимого файла",
+3
View File
@@ -17,6 +17,7 @@
"availableAgents": "Kullanılabilir asistanlar",
"backToBottom": "En alta git",
"chatList": {
"expandMessage": "Mesajı Genişlet",
"longMessageDetail": "Detayları görüntüle"
},
"clearCurrentMessages": "Mevcut oturum mesajlarını temizle",
@@ -173,9 +174,11 @@
"title": "Üyeleri Etiketle"
},
"messageAction": {
"collapse": "Mesajı Daralt",
"continueGeneration": "Oluşturmaya devam et",
"delAndRegenerate": "Sil ve Yeniden Oluştur",
"deleteDisabledByThreads": "Alt konular mevcut, silinemez",
"expand": "Mesajı Genişlet",
"regenerate": "Yeniden Oluştur"
},
"messages": {
+5
View File
@@ -253,6 +253,11 @@
},
"localSystem": {
"apiName": {
"editLocalFile": "Dosyayı Düzenle",
"getCommandOutput": "Komut Çıktısını Al",
"globLocalFiles": "Dosyaları Ara",
"grepContent": "İçeriği Ara",
"killCommand": "Komut Yürütmesini Durdur",
"listLocalFiles": "Dosya listesini görüntüle",
"moveLocalFiles": "Dosya taşı",
"readLocalFile": "Dosya içeriğini oku",
+3
View File
@@ -17,6 +17,7 @@
"availableAgents": "Trợ lý có sẵn",
"backToBottom": "Quay về dưới cùng",
"chatList": {
"expandMessage": "Mở rộng tin nhắn",
"longMessageDetail": "Xem chi tiết"
},
"clearCurrentMessages": "Xóa tin nhắn hiện tại",
@@ -173,9 +174,11 @@
"title": "Nhắc đến thành viên"
},
"messageAction": {
"collapse": "Thu gọn tin nhắn",
"continueGeneration": "Tiếp tục tạo",
"delAndRegenerate": "Xóa và tạo lại",
"deleteDisabledByThreads": "Có chủ đề con, không thể xóa",
"expand": "Mở rộng tin nhắn",
"regenerate": "Tạo lại"
},
"messages": {
+5
View File
@@ -253,6 +253,11 @@
},
"localSystem": {
"apiName": {
"editLocalFile": "Chỉnh sửa tệp",
"getCommandOutput": "Lấy đầu ra mã lệnh",
"globLocalFiles": "Tìm kiếm tệp",
"grepContent": "Tìm kiếm nội dung",
"killCommand": "Dừng thực thi mã",
"listLocalFiles": "Xem danh sách tệp",
"moveLocalFiles": "Di chuyển tệp",
"readLocalFile": "Đọc nội dung tệp",
+3
View File
@@ -17,6 +17,7 @@
"availableAgents": "可用助手",
"backToBottom": "跳转至当前",
"chatList": {
"expandMessage": "展开消息",
"longMessageDetail": "查看详情"
},
"clearCurrentMessages": "清空当前会话消息",
@@ -173,9 +174,11 @@
"title": "提及成员"
},
"messageAction": {
"collapse": "收起消息",
"continueGeneration": "继续生成",
"delAndRegenerate": "删除并重新生成",
"deleteDisabledByThreads": "存在子话题,不能删除",
"expand": "展开消息",
"regenerate": "重新生成"
},
"messages": {
+2 -2
View File
@@ -253,6 +253,7 @@
},
"localSystem": {
"apiName": {
"editLocalFile": "编辑文件",
"getCommandOutput": "获取代码输出",
"globLocalFiles": "匹配搜索文件",
"grepContent": "搜索内容",
@@ -263,8 +264,7 @@
"renameLocalFile": "重命名",
"runCommand": "执行代码",
"searchLocalFiles": "搜索文件",
"writeLocalFile": "写入文件",
"editLocalFile": "编辑文件"
"writeLocalFile": "写入文件"
},
"title": "本地系统"
},
+3
View File
@@ -17,6 +17,7 @@
"availableAgents": "可用助理",
"backToBottom": "返回底部",
"chatList": {
"expandMessage": "展開訊息",
"longMessageDetail": "查看詳情"
},
"clearCurrentMessages": "清空當前對話",
@@ -173,9 +174,11 @@
"title": "提及成員"
},
"messageAction": {
"collapse": "收起訊息",
"continueGeneration": "繼續生成",
"delAndRegenerate": "刪除並重新生成",
"deleteDisabledByThreads": "存在子話題,無法刪除",
"expand": "展開訊息",
"regenerate": "重新生成"
},
"messages": {
+5
View File
@@ -253,6 +253,11 @@
},
"localSystem": {
"apiName": {
"editLocalFile": "編輯檔案",
"getCommandOutput": "取得程式輸出",
"globLocalFiles": "匹配搜尋檔案",
"grepContent": "搜尋內容",
"killCommand": "終止程式執行",
"listLocalFiles": "查看檔案列表",
"moveLocalFiles": "移動檔案",
"readLocalFile": "讀取檔案內容",
+5 -5
View File
@@ -249,11 +249,11 @@ const nextConfig: NextConfig = {
// permanent: true,
// source: '/settings',
// },
{
destination: '/chat',
permanent: false,
source: '/',
},
// {
// destination: '/chat',
// permanent: false,
// source: '/',
// },
{
destination: '/chat',
permanent: true,
+23 -29
View File
@@ -1,6 +1,6 @@
{
"name": "@lobehub/lobehub",
"version": "2.0.0-next.63",
"version": "2.0.0-next.69",
"description": "LobeHub - an open-source,comprehensive AI Agent framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
"keywords": [
"framework",
@@ -75,7 +75,6 @@
"release": "semantic-release",
"self-hosting:docker": "docker build -t lobehub:local .",
"self-hosting:docker-cn": "docker build -t lobehub-local --build-arg USE_CN_MIRROR=true .",
"self-hosting:docker-cn@lite": "docker build -t lobehub-lite-local -f Dockerfile.lite --build-arg USE_CN_MIRROR=true .",
"start": "next start -p 3210",
"stylelint": "stylelint \"src/**/*.{js,jsx,ts,tsx}\" --fix",
"test": "npm run test-app && npm run test-server",
@@ -123,30 +122,27 @@
"eslint --fix"
]
},
"overrides": {
"eta": "4.0.1"
},
"dependencies": {
"@ant-design/icons": "^5.6.1",
"@ant-design/pro-components": "^2.8.10",
"@anthropic-ai/sdk": "^0.67.1",
"@auth/core": "^0.40.0",
"@aws-sdk/client-s3": "~3.893.0",
"@aws-sdk/s3-request-presigner": "~3.893.0",
"@aws-sdk/client-s3": "~3.932.0",
"@aws-sdk/s3-request-presigner": "~3.932.0",
"@azure-rest/ai-inference": "1.0.0-beta.5",
"@azure/core-auth": "^1.10.1",
"@cfworker/json-schema": "^4.1.1",
"@clerk/localizations": "^3.27.2",
"@clerk/nextjs": "^6.35.0",
"@clerk/themes": "^2.4.35",
"@clerk/localizations": "^3.28.0",
"@clerk/nextjs": "^6.35.1",
"@clerk/themes": "^2.4.36",
"@codesandbox/sandpack-react": "^2.20.0",
"@cyntler/react-doc-viewer": "^1.17.1",
"@electric-sql/pglite": "0.2.17",
"@emotion/react": "^11.14.0",
"@fal-ai/client": "^1.7.2",
"@formkit/auto-animate": "^0.9.0",
"@google/genai": "^1.29.0",
"@huggingface/inference": "^4.13.2",
"@google/genai": "^1.29.1",
"@huggingface/inference": "^4.13.3",
"@icons-pack/react-simple-icons": "^13.8.0",
"@khmyznikov/pwa-install": "0.3.9",
"@langchain/community": "^0.3.57",
@@ -169,14 +165,14 @@
"@lobehub/charts": "^2.1.2",
"@lobehub/chat-plugin-sdk": "^1.32.4",
"@lobehub/chat-plugins-gateway": "^1.9.0",
"@lobehub/editor": "^1.22.0",
"@lobehub/editor": "^1.23.1",
"@lobehub/icons": "^2.43.1",
"@lobehub/market-sdk": "^0.23.0",
"@lobehub/tts": "^2.0.1",
"@lobehub/ui": "^2.13.8",
"@lobehub/ui": "^2.16.2",
"@modelcontextprotocol/sdk": "^1.22.0",
"@neondatabase/serverless": "^1.0.2",
"@next/third-parties": "^16.0.1",
"@next/third-parties": "^16.0.3",
"@opentelemetry/exporter-jaeger": "^2.2.0",
"@opentelemetry/winston-transport": "^0.18.0",
"@react-pdf/renderer": "^4.3.1",
@@ -184,14 +180,14 @@
"@saintno/comfyui-sdk": "^0.2.49",
"@serwist/next": "^9.2.1",
"@t3-oss/env-nextjs": "^0.13.8",
"@tanstack/react-query": "^5.90.7",
"@tanstack/react-query": "^5.90.10",
"@trpc/client": "^11.7.1",
"@trpc/next": "^11.7.1",
"@trpc/react-query": "^11.7.1",
"@trpc/server": "^11.7.1",
"@vercel/analytics": "^1.5.0",
"@vercel/edge-config": "^1.4.3",
"@vercel/functions": "^3.3.0",
"@vercel/functions": "^3.3.2",
"@vercel/speed-insights": "^1.2.0",
"@virtuoso.dev/masonry": "^1.3.5",
"@xterm/xterm": "^5.5.0",
@@ -226,7 +222,7 @@
"langfuse": "^3.38.6",
"langfuse-core": "^3.38.6",
"lodash-es": "^4.17.21",
"lucide-react": "^0.548.0",
"lucide-react": "^0.553.0",
"mammoth": "^1.11.0",
"markdown-to-txt": "^2.0.1",
"marked": "^16.4.2",
@@ -234,7 +230,7 @@
"model-bank": "workspace:*",
"modern-screenshot": "^4.6.6",
"nanoid": "^5.1.6",
"next": "^16.0.1",
"next": "^16.0.3",
"next-auth": "5.0.0-beta.30",
"next-mdx-remote": "^5.0.0",
"nextjs-toploader": "^3.9.17",
@@ -243,7 +239,7 @@
"nuqs": "^2.7.3",
"officeparser": "5.1.1",
"oidc-provider": "^9.5.2",
"ollama": "^0.6.2",
"ollama": "^0.6.3",
"openai": "^4.104.0",
"openapi-fetch": "^0.14.1",
"partial-json": "^0.1.7",
@@ -266,19 +262,19 @@
"react-fast-marquee": "^1.6.5",
"react-hotkeys-hook": "^5.2.1",
"react-i18next": "^15.7.4",
"react-layout-kit": "^2.0.0",
"react-layout-kit": "^2.0.1",
"react-lazy-load": "^4.0.1",
"react-pdf": "^9.2.1",
"react-responsive": "^10.0.1",
"react-rnd": "^10.5.2",
"react-router-dom": "^7.9.5",
"react-router-dom": "^7.9.6",
"react-scan": "^0.4.3",
"react-virtuoso": "^4.14.1",
"react-wrap-balancer": "^1.1.1",
"remark": "^15.0.1",
"remark-gfm": "^4.0.1",
"remark-html": "^16.0.1",
"resolve-accept-language": "^3.1.13",
"resolve-accept-language": "^3.1.14",
"rtl-detect": "^1.1.2",
"semver": "^7.7.3",
"sharp": "^0.34.5",
@@ -296,6 +292,7 @@
"url-join": "^5.0.0",
"use-merge-value": "^1.2.0",
"uuid": "^11.1.0",
"virtua": "^0.47.0",
"word-extractor": "^1.0.4",
"ws": "^8.18.3",
"yaml": "^2.8.1",
@@ -312,7 +309,7 @@
"@lobehub/lint": "^1.26.2",
"@lobehub/market-types": "^1.11.4",
"@lobehub/seo-cli": "^1.7.0",
"@next/bundle-analyzer": "^16.0.1",
"@next/bundle-analyzer": "^16.0.3",
"@next/eslint-plugin-next": "^15.5.6",
"@peculiar/webcrypto": "^1.5.0",
"@playwright/test": "^1.56.1",
@@ -398,9 +395,6 @@
"pnpm": {
"onlyBuiltDependencies": [
"@vercel/speed-insights"
],
"overrides": {
"eta": "4.0.1"
}
]
}
}
}
+1 -1
View File
@@ -10,6 +10,6 @@
},
"dependencies": {},
"devDependencies": {
"openai": "^4.0.0"
"openai": "^4.104.0"
}
}
+2 -1
View File
@@ -1,6 +1,7 @@
/* eslint-disable sort-keys-fix/sort-keys-fix, typescript-sort-keys/interface */
import { ChatToolPayload } from '@lobechat/types';
import type { AgentState, ToolsCalling } from './state';
import { ChatToolPayload } from '@/types/message';
export interface AgentEventInit {
type: 'init';
+1 -1
View File
@@ -9,7 +9,7 @@
"main": "./src/index.ts",
"dependencies": {
"model-bank": "workspace:*",
"query-string": "^9.2.2",
"query-string": "^9.3.1",
"url-join": "^5.0.0"
}
}
-5
View File
@@ -4,13 +4,8 @@ import { BRANDING_NAME, ORG_NAME } from './branding';
export const CURRENT_VERSION = pkg.version;
export const isServerMode = true;
export const isUsePgliteDB = false;
export const isDesktop = process.env.NEXT_PUBLIC_IS_DESKTOP_APP === '1';
export const isDeprecatedEdition = false;
// @ts-ignore
export const isCustomBranding = BRANDING_NAME !== 'LobeHub';
// @ts-ignore
+2 -2
View File
@@ -21,8 +21,8 @@
"@lobechat/prompts": "workspace:*",
"@lobechat/types": "workspace:*",
"@lobechat/utils": "workspace:*",
"debug": "^4.3.4",
"immer": "^10.0.3",
"debug": "^4.4.3",
"immer": "^10.2.0",
"lodash-es": "^4.17.21",
"ts-md5": "^2.0.1"
},
@@ -1,17 +1,15 @@
import type { Message, ParseResult } from '../../types';
// Input fixtures
import assistantChainWithFollowupInput from './inputs/assistant-chain-with-followup.json';
import assistantWithToolsInput from './inputs/assistant-with-tools.json';
import { assistantGroup as assistantGroupInputs } from './inputs/assistantGroup';
import { branch as branchInputs } from './inputs/branch';
import { compare as compareInputs } from './inputs/compare';
import complexScenarioInput from './inputs/complex-scenario.json';
import linearConversationInput from './inputs/linear-conversation.json';
// Output fixtures
import assistantChainWithFollowupOutput from './outputs/assistant-chain-with-followup.json';
import assistantWithToolsOutput from './outputs/assistant-with-tools.json';
import { assistantGroup as assistantGroupOutputs } from './outputs/assistantGroup';
import { branch as branchOutputs } from './outputs/branch';
import { compare as compareOutputs } from './outputs/compare';
import complexScenarioOutput from './outputs/complex-scenario.json';
import linearConversationOutput from './outputs/linear-conversation.json';
/**
@@ -28,10 +26,9 @@ export interface SerializedParseResult {
*/
export const inputs = {
assistantChainWithFollowup: assistantChainWithFollowupInput as Message[],
assistantWithTools: assistantWithToolsInput as Message[],
assistantGroup: assistantGroupInputs,
branch: branchInputs,
compare: compareInputs,
complexScenario: complexScenarioInput as Message[],
linearConversation: linearConversationInput as Message[],
};
@@ -40,9 +37,8 @@ export const inputs = {
*/
export const outputs = {
assistantChainWithFollowup: assistantChainWithFollowupOutput as unknown as SerializedParseResult,
assistantWithTools: assistantWithToolsOutput as unknown as SerializedParseResult,
assistantGroup: assistantGroupOutputs,
branch: branchOutputs,
compare: compareOutputs,
complexScenario: complexScenarioOutput as unknown as SerializedParseResult,
linearConversation: linearConversationOutput as unknown as SerializedParseResult,
};
@@ -97,7 +97,8 @@
"tps": 48,
"ttft": 178,
"duration": 875,
"latency": 1053
"latency": 1053,
"collapsed": true
}
},
{
@@ -0,0 +1,8 @@
import type { Message } from '../../../../types';
import assistantWithTools from './assistant-with-tools.json';
import toolsWithBranches from './tools-with-branches.json';
export const assistantGroup = {
assistantWithTools: assistantWithTools as Message[],
toolsWithBranches: toolsWithBranches as Message[],
};
@@ -1,14 +1,12 @@
import type { Message } from '../../../types';
import assistantWithTools from './assistant-with-tools.json';
import { assistantGroup } from './assistantGroup';
import { branch } from './branch';
import { compare } from './compare';
import complexScenario from './complex-scenario.json';
import linearConversation from './linear-conversation.json';
export const inputs = {
assistantWithTools: assistantWithTools as Message[],
assistantGroup,
branch,
compare,
complexScenario: complexScenario as Message[],
linearConversation: linearConversation as Message[],
};
@@ -9,18 +9,12 @@
{
"id": "msg-102",
"type": "message",
"tools": [
"msg-103",
"msg-104"
]
"tools": ["msg-103", "msg-104"]
},
{
"id": "msg-105",
"type": "message",
"tools": [
"msg-106",
"msg-107"
]
"tools": ["msg-106", "msg-107"]
},
{
"id": "msg-108",
@@ -98,6 +92,9 @@
"totalInputTokens": 28,
"totalOutputTokens": 45,
"totalTokens": 73
},
"metadata": {
"collapsed": true
}
},
{
@@ -178,6 +175,9 @@
"totalOutputTokens": 199,
"totalTokens": 628,
"cost": 0.0018839999999999998
},
"metadata": {
"collapsed": true
}
}
],
@@ -0,0 +1,8 @@
import type { SerializedParseResult } from '../..';
import assistantWithTools from './assistant-with-tools.json';
import toolsWithBranches from './tools-with-branches.json';
export const assistantGroup = {
assistantWithTools: assistantWithTools as unknown as SerializedParseResult,
toolsWithBranches: toolsWithBranches as unknown as SerializedParseResult,
};
@@ -22,9 +22,9 @@ describe('parse', () => {
describe('Tool Usage', () => {
it('should parse assistant with tools correctly', () => {
const result = parse(inputs.assistantWithTools);
const result = parse(inputs.assistantGroup.assistantWithTools);
expect(serializeParseResult(result)).toEqual(outputs.assistantWithTools);
expect(serializeParseResult(result)).toEqual(outputs.assistantGroup.assistantWithTools);
});
it('should include follow-up messages after assistant chain', () => {
@@ -99,11 +99,11 @@ describe('parse', () => {
});
});
describe('Complex Scenarios', () => {
it('should handle complex mixed scenarios correctly', () => {
const result = parse(inputs.complexScenario);
describe('Assistant Group Scenarios', () => {
it('should handle tools with assistant branches correctly', () => {
const result = parse(inputs.assistantGroup.toolsWithBranches);
expect(serializeParseResult(result)).toEqual(outputs.complexScenario);
expect(serializeParseResult(result)).toEqual(outputs.assistantGroup.toolsWithBranches);
});
});
+45 -1
View File
@@ -40,9 +40,53 @@ export function parse(messages: Message[], messageGroups?: MessageGroupMetadata[
const flatList = transformer.flatten(messages);
// Convert messageMap from Map to plain object for serialization
// Clean up metadata for assistant messages with tools
const messageMapObj: Record<string, Message> = {};
const usagePerformanceFields = new Set([
'acceptedPredictionTokens',
'cost',
'duration',
'inputAudioTokens',
'inputCacheMissTokens',
'inputCachedTokens',
'inputCitationTokens',
'inputImageTokens',
'inputTextTokens',
'inputWriteCacheTokens',
'latency',
'outputAudioTokens',
'outputImageTokens',
'outputReasoningTokens',
'outputTextTokens',
'rejectedPredictionTokens',
'totalInputTokens',
'totalOutputTokens',
'totalTokens',
'tps',
'ttft',
]);
helperMaps.messageMap.forEach((message, id) => {
messageMapObj[id] = message;
// For assistant messages with tools, clean metadata to keep only usage/performance fields
if (
message.role === 'assistant' &&
message.tools &&
message.tools.length > 0 &&
message.metadata
) {
const cleanedMetadata: Record<string, any> = {};
Object.entries(message.metadata).forEach(([key, value]) => {
if (usagePerformanceFields.has(key)) {
cleanedMetadata[key] = value;
}
});
messageMapObj[id] = {
...message,
metadata: Object.keys(cleanedMetadata).length > 0 ? cleanedMetadata : undefined,
};
} else {
messageMapObj[id] = message;
}
});
return {
@@ -445,6 +445,40 @@ export class FlatListBuilder {
const msgUsage = assistant.usage || metaUsage;
const msgPerformance = assistant.performance || metaPerformance;
// Extract non-usage/performance metadata fields
const otherMetadata: Record<string, any> = {};
if (assistant.metadata) {
const usagePerformanceFields = new Set([
'acceptedPredictionTokens',
'cost',
'duration',
'inputAudioTokens',
'inputCacheMissTokens',
'inputCachedTokens',
'inputCitationTokens',
'inputImageTokens',
'inputTextTokens',
'inputWriteCacheTokens',
'latency',
'outputAudioTokens',
'outputImageTokens',
'outputReasoningTokens',
'outputTextTokens',
'rejectedPredictionTokens',
'totalInputTokens',
'totalOutputTokens',
'totalTokens',
'tps',
'ttft',
]);
Object.entries(assistant.metadata).forEach(([key, value]) => {
if (!usagePerformanceFields.has(key)) {
otherMetadata[key] = value;
}
});
}
const childBlock: AssistantContentBlock = {
content: assistant.content || '',
id: assistant.id,
@@ -457,12 +491,37 @@ export class FlatListBuilder {
if (assistant.reasoning) childBlock.reasoning = assistant.reasoning;
if (toolsWithResults.length > 0) childBlock.tools = toolsWithResults;
if (msgUsage) childBlock.usage = msgUsage;
if (Object.keys(otherMetadata).length > 0) {
childBlock.metadata = otherMetadata;
}
children.push(childBlock);
}
const aggregated = this.messageTransformer.aggregateMetadata(children);
// Collect all non-usage/performance metadata from all children
const groupMetadata: Record<string, any> = {};
children.forEach((child) => {
if ((child as any).metadata) {
Object.assign(groupMetadata, (child as any).metadata);
}
});
// If there's group-level metadata, apply it to first child and remove from others
if (Object.keys(groupMetadata).length > 0 && children.length > 0) {
// Ensure first child has the group metadata
if (!(children[0] as any).metadata) {
(children[0] as any).metadata = {};
}
Object.assign((children[0] as any).metadata, groupMetadata);
// Remove metadata from subsequent children (keep only in first child)
for (let i = 1; i < children.length; i++) {
delete (children[i] as any).metadata;
}
}
const result: Message = {
...firstAssistant,
children,
@@ -480,6 +539,11 @@ export class FlatListBuilder {
if (aggregated.performance) result.performance = aggregated.performance;
if (aggregated.usage) result.usage = aggregated.usage;
// Add group-level metadata if it exists
if (Object.keys(groupMetadata).length > 0) {
result.metadata = groupMetadata;
}
return result;
}
@@ -1,7 +1,6 @@
import type { AssistantContentBlock } from '@lobechat/types';
import { describe, expect, it } from 'vitest';
import type { AssistantContentBlock } from '@/types/index';
import type { Message } from '../../types';
import { MessageTransformer } from '../MessageTransformer';
+2 -2
View File
@@ -23,9 +23,9 @@
},
"peerDependencies": {
"@electric-sql/pglite": "^0.2.17",
"dayjs": ">=1.11.18",
"dayjs": ">=1.11.19",
"drizzle-orm": ">=0.44.7",
"nanoid": ">=5.1.5",
"nanoid": ">=5.1.6",
"pg": ">=8.16.3"
}
}
+1 -2
View File
@@ -1,7 +1,6 @@
import { ClientDBLoadingProgress, DatabaseLoadingState } from '@lobechat/types';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { ClientDBLoadingProgress, DatabaseLoadingState } from '@/types/clientDB';
import { DatabaseManager } from './db';
// Mock 所有外部依赖
+6 -6
View File
@@ -1,13 +1,13 @@
import {
type ClientDBLoadingProgress,
DatabaseLoadingState,
type MigrationSQL,
type MigrationTableItem,
} from '@lobechat/types';
import { sql } from 'drizzle-orm';
import { PgliteDatabase, drizzle } from 'drizzle-orm/pglite';
import { Md5 } from 'ts-md5';
import {
ClientDBLoadingProgress,
DatabaseLoadingState,
MigrationSQL,
MigrationTableItem,
} from '@/types/clientDB';
import { sleep } from '@/utils/sleep';
import migrations from '../core/migrations.json';
+1 -1
View File
@@ -1,11 +1,11 @@
import { PGlite } from '@electric-sql/pglite';
import { vector } from '@electric-sql/pglite/vector';
import type { MigrationTableItem } from '@lobechat/types';
import { drizzle as pgliteDrizzle } from 'drizzle-orm/pglite';
import fs from 'node:fs';
import { Md5 } from 'ts-md5';
import { electronIpcClient } from '@/server/modules/ElectronIPCClient';
import { MigrationTableItem } from '@/types/clientDB';
import { DrizzleMigrationModel } from '../models/drizzleMigration';
import * as schema from '../schemas';
@@ -1,9 +1,8 @@
// @vitest-environment node
import { AsyncTaskStatus, AsyncTaskType } from '@lobechat/types';
import { eq } from 'drizzle-orm';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { AsyncTaskStatus, AsyncTaskType } from '@/types/asyncTask';
import { asyncTasks, users } from '../../schemas';
import { LobeChatDatabase } from '../../type';
import { ASYNC_TASK_TIMEOUT, AsyncTaskModel } from '../asyncTask';
@@ -287,6 +287,44 @@ describe('ChunkModel', () => {
expect(result[1].index).toBe(1);
expect(result[2].index).toBe(2);
});
it('should handle chunks with null metadata and return undefined pageNumber', async () => {
const fileId = '1';
const [chunk] = await serverDB
.insert(chunks)
.values([{ text: 'Chunk with null metadata', userId, index: 0, metadata: null }])
.returning();
await serverDB.insert(fileChunks).values([{ fileId, chunkId: chunk.id, userId }]);
const result = await chunkModel.findByFileId(fileId, 0);
expect(result).toHaveLength(1);
expect(result[0].metadata).toBeNull();
expect(result[0].pageNumber).toBeUndefined();
});
it('should handle chunks with metadata containing pageNumber', async () => {
const fileId = '1';
const [chunk] = await serverDB
.insert(chunks)
.values([
{
text: 'Chunk with pageNumber',
userId,
index: 0,
metadata: { pageNumber: 5 } as any,
},
])
.returning();
await serverDB.insert(fileChunks).values([{ fileId, chunkId: chunk.id, userId }]);
const result = await chunkModel.findByFileId(fileId, 0);
expect(result).toHaveLength(1);
expect(result[0].pageNumber).toBe(5);
});
});
describe('getChunksTextByFileId', () => {
@@ -1,9 +1,8 @@
// @vitest-environment node
import { FilesTabs, SortType } from '@lobechat/types';
import { eq, inArray } from 'drizzle-orm';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { FilesTabs, SortType } from '@/types/files';
import {
chunks,
embeddings,
@@ -1,10 +1,9 @@
// @vitest-environment node
import { AsyncTaskStatus, ImageGenerationAsset } from '@lobechat/types';
import { FileSource } from '@lobechat/types';
import { eq } from 'drizzle-orm';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { FileSource } from '@/types/files';
import {
NewGeneration,
asyncTasks,
@@ -1,10 +1,9 @@
// @vitest-environment node
import { GenerationConfig } from '@lobechat/types';
import { AsyncTaskStatus } from '@lobechat/types';
import { eq } from 'drizzle-orm';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { AsyncTaskStatus } from '@/types/asyncTask';
import {
NewGenerationBatch,
generationBatches,
+7 -7
View File
@@ -1,15 +1,15 @@
import { and, asc, desc, eq } from 'drizzle-orm';
import { isEmpty } from 'lodash-es';
import { ModelProvider } from 'model-bank';
import { DEFAULT_MODEL_PROVIDER_LIST } from '@/config/modelProviders';
import {
import type {
AiProviderDetailItem,
AiProviderListItem,
AiProviderRuntimeConfig,
CreateAiProviderParams,
UpdateAiProviderConfigParams,
} from '@/types/aiProvider';
} from '@lobechat/types';
import { and, asc, desc, eq } from 'drizzle-orm';
import { isEmpty } from 'lodash-es';
import { ModelProvider } from 'model-bank';
import { DEFAULT_MODEL_PROVIDER_LIST } from '@/config/modelProviders';
import { merge } from '@/utils/merge';
import { AiProviderSelectItem, aiModels, aiProviders } from '../schemas';
@@ -1,14 +1,14 @@
import type {
AiProviderDetailItem,
AiProviderListItem,
AiProviderRuntimeConfig,
EnabledProvider,
} from '@lobechat/types';
import { AiProviderModelListItem, EnabledAiModel } from 'model-bank';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { DEFAULT_MODEL_PROVIDER_LIST } from '@/config/modelProviders';
import { clientDB, initializeDB } from '@/database/client/db';
import {
AiProviderDetailItem,
AiProviderListItem,
AiProviderRuntimeConfig,
EnabledProvider,
} from '@/types/aiProvider';
import { AiInfraRepos } from './index';
@@ -1,3 +1,10 @@
import type {
AiProviderDetailItem,
AiProviderListItem,
AiProviderRuntimeState,
EnabledProvider,
ProviderConfig,
} from '@lobechat/types';
import { isEmpty } from 'lodash-es';
import {
AIChatModelCard,
@@ -8,13 +15,6 @@ import {
import pMap from 'p-map';
import { DEFAULT_MODEL_PROVIDER_LIST } from '@/config/modelProviders';
import {
AiProviderDetailItem,
AiProviderListItem,
AiProviderRuntimeState,
EnabledProvider,
} from '@/types/aiProvider';
import { ProviderConfig } from '@/types/user/settings';
import { merge, mergeArrayById } from '@/utils/merge';
import { AiModelModel } from '../../models/aiModel';
@@ -1,8 +1,7 @@
import type { ImportPgDataStructure } from '@lobechat/types';
import { eq, inArray } from 'drizzle-orm';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { ImportPgDataStructure } from '@/types/export';
import { getTestDB } from '../../../models/__tests__/_util';
import * as Schema from '../../../schemas';
import { DataImporterRepos } from '../index';
@@ -1,4 +1,5 @@
// @vitest-environment node
import type { ImporterEntryData } from '@lobechat/types';
import { eq, inArray } from 'drizzle-orm';
import { beforeEach, describe, expect, it, vi } from 'vitest';
@@ -12,7 +13,6 @@ import {
topics,
users,
} from '@/database/schemas';
import { ImporterEntryData } from '@/types/importer';
import { DeprecatedDataImporterRepos as DataImporterRepos } from '../index';
import mockImportData from './fixtures/messages.json';
@@ -1,6 +1,6 @@
import type { ImporterEntryData } from '@lobechat/types';
import { and, eq, inArray, sql } from 'drizzle-orm';
import { ImporterEntryData } from '@/types/importer';
import { sanitizeUTF8 } from '@/utils/sanitizeUTF8';
import {
@@ -1,7 +1,6 @@
import type { ImportPgDataStructure, ImportResultData, ImporterEntryData } from '@lobechat/types';
import { and, eq, inArray } from 'drizzle-orm';
import { ImportPgDataStructure } from '@/types/export';
import { ImportResultData, ImporterEntryData } from '@/types/importer';
import { uuid } from '@/utils/uuid';
import * as EXPORT_TABLES from '../../schemas';
@@ -1,12 +1,11 @@
import { sql } from 'drizzle-orm';
import pMap from 'p-map';
import {
import type {
FilterCondition,
PaginationParams,
TableBasicInfo,
TableColumnInfo,
} from '@/types/tableViewer';
} from '@lobechat/types';
import { sql } from 'drizzle-orm';
import pMap from 'p-map';
import { LobeChatDatabase } from '../../type';
+1 -2
View File
@@ -1,4 +1,5 @@
/* eslint-disable sort-keys-fix/sort-keys-fix */
import type { LobeAgentChatConfig, LobeAgentTTSConfig } from '@lobechat/types';
import {
boolean,
index,
@@ -11,8 +12,6 @@ import {
} from 'drizzle-orm/pg-core';
import { createInsertSchema } from 'drizzle-zod';
import { LobeAgentChatConfig, LobeAgentTTSConfig } from '@/types/agent';
import { idGenerator, randomSlug } from '../utils/idGenerator';
import { timestamps } from './_helpers';
import { files, knowledgeBases } from './file';
+1 -2
View File
@@ -1,9 +1,8 @@
/* eslint-disable sort-keys-fix/sort-keys-fix */
import type { AiProviderConfig, AiProviderSettings } from '@lobechat/types';
import { boolean, integer, jsonb, pgTable, primaryKey, text, varchar } from 'drizzle-orm/pg-core';
import { AiModelSettings } from 'model-bank';
import { AiProviderConfig, AiProviderSettings } from '@/types/aiProvider';
import { timestamps } from './_helpers';
import { users } from './user';
+1 -2
View File
@@ -1,4 +1,5 @@
/* eslint-disable sort-keys-fix/sort-keys-fix */
import type { LobeDocumentPage } from '@lobechat/types';
import {
index,
integer,
@@ -12,8 +13,6 @@ import {
} from 'drizzle-orm/pg-core';
import { createInsertSchema } from 'drizzle-zod';
import { LobeDocumentPage } from '@/types/document';
import { idGenerator } from '../utils/idGenerator';
import { createdAt, timestamps } from './_helpers';
import { files } from './file';
+1 -2
View File
@@ -1,4 +1,5 @@
/* eslint-disable sort-keys-fix/sort-keys-fix */
import { FileSource } from '@lobechat/types';
import {
boolean,
index,
@@ -13,8 +14,6 @@ import {
} from 'drizzle-orm/pg-core';
import { createInsertSchema } from 'drizzle-zod';
import { FileSource } from '@/types/files';
import { idGenerator } from '../utils/idGenerator';
import { accessedAt, createdAt, timestamps } from './_helpers';
import { asyncTasks } from './asyncTask';
+1 -2
View File
@@ -1,9 +1,8 @@
/* eslint-disable sort-keys-fix/sort-keys-fix */
import type { ChatTopicMetadata } from '@lobechat/types';
import { boolean, index, jsonb, pgTable, primaryKey, text, uniqueIndex } from 'drizzle-orm/pg-core';
import { createInsertSchema } from 'drizzle-zod';
import { ChatTopicMetadata } from '@/types/topic';
import { idGenerator } from '../utils/idGenerator';
import { createdAt, timestamps, timestamptz } from './_helpers';
import { chatGroups } from './chatGroup';
+1 -1
View File
@@ -1,9 +1,9 @@
/* eslint-disable sort-keys-fix/sort-keys-fix */
import type { CustomPluginParams } from '@lobechat/types';
import { LobeChatPluginManifest } from '@lobehub/chat-plugin-sdk';
import { boolean, jsonb, pgTable, primaryKey, text } from 'drizzle-orm/pg-core';
import { DEFAULT_PREFERENCE } from '@/const/user';
import { CustomPluginParams } from '@/types/tool/plugin';
import { timestamps, timestamptz } from './_helpers';
@@ -1,3 +1,4 @@
import type { UserGuide, UserPreference } from '@lobechat/types';
import { TRPCError } from '@trpc/server';
import dayjs from 'dayjs';
import { count, eq } from 'drizzle-orm';
@@ -5,7 +6,6 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { INBOX_SESSION_ID } from '@/const/session';
import { KeyVaultsGateKeeper } from '@/server/modules/KeyVaultsEncrypt';
import { UserGuide, UserPreference } from '@/types/user';
import { getTestDBInstance } from '../../../core/dbForTest';
import { SessionModel } from '../../../models/session';
+1 -1
View File
@@ -5,6 +5,6 @@
"main": "src/index.ts",
"types": "src/index.ts",
"peerDependencies": {
"react": "^19"
"react": "^19.2.0"
}
}
+2 -2
View File
@@ -9,9 +9,9 @@
"test:coverage": "vitest --coverage --silent='passed-only'"
},
"dependencies": {
"debug": "^4.3.4"
"debug": "^4.4.3"
},
"devDependencies": {
"@types/debug": "^4.1.7"
"@types/debug": "^4.1.12"
}
}
+1 -1
View File
@@ -24,6 +24,6 @@
"@lobechat/model-runtime": "workspace:*",
"@lobechat/types": "workspace:*",
"@lobechat/utils": "workspace:*",
"i18next": "^24.2.1"
"i18next": "^24.2.3"
}
}
+3 -3
View File
@@ -28,8 +28,8 @@
"@napi-rs/canvas": "^0.1.70",
"@xmldom/xmldom": "^0.9.8",
"concat-stream": "^2.0.0",
"debug": "^4.3.4",
"mammoth": "^1.8.0",
"debug": "^4.4.3",
"mammoth": "^1.11.0",
"officeparser": "5.1.1",
"pdfjs-dist": "4.10.38",
"word-extractor": "^1.0.4",
@@ -39,7 +39,7 @@
"devDependencies": {
"@types/concat-stream": "^2.0.3",
"@types/yauzl": "^2.10.3",
"typescript": "^5"
"typescript": "^5.9.3"
},
"peerDependencies": {
"typescript": ">=5"
+2 -2
View File
@@ -13,9 +13,9 @@
"ora": "^9.0.0"
},
"devDependencies": {
"tsx": "^4.19.2"
"tsx": "^4.20.6"
},
"peerDependencies": {
"zod": "^3"
"zod": "^3.25.76"
}
}
+3 -3
View File
@@ -12,12 +12,12 @@
"test:update": "vitest -u"
},
"dependencies": {
"@aws-sdk/client-bedrock-runtime": "^3.862.0",
"@huggingface/inference": "^4.11.3",
"@aws-sdk/client-bedrock-runtime": "^3.932.0",
"@huggingface/inference": "^4.13.3",
"@lobechat/const": "workspace:*",
"@lobechat/types": "workspace:*",
"@lobechat/utils": "workspace:*",
"debug": "^4.4.1",
"debug": "^4.4.3",
"model-bank": "workspace:*",
"openai": "^4.104.0"
}
@@ -235,6 +235,73 @@ describe('OllamaStream', () => {
expect(onToolCall).toHaveBeenCalledTimes(1);
expect(onCompletionMock).toHaveBeenCalledTimes(1);
});
it('tools use with a done', async () => {
vi.spyOn(uuidModule, 'nanoid').mockReturnValueOnce('1').mockReturnValueOnce('abcd1234');
const mockOllamaStream = new ReadableStream<ChatResponse>({
start(controller) {
controller.enqueue({
model: 'qwen2.5',
created_at: new Date('2024-12-01T03:34:55.166692Z'),
message: {
role: 'assistant',
content: '',
tool_calls: [
{
function: {
name: 'realtime-weather____fetchCurrentWeather',
arguments: { city: '杭州' },
},
},
],
},
done_reason: 'stop',
done: true,
total_duration: 1122415333,
load_duration: 26178333,
prompt_eval_count: 221,
prompt_eval_duration: 507000000,
eval_count: 26,
eval_duration: 583000000,
} as unknown as ChatResponse);
controller.close();
},
});
const onStartMock = vi.fn();
const onTextMock = vi.fn();
const onToolCall = vi.fn();
const onCompletionMock = vi.fn();
const protocolStream = OllamaStream(mockOllamaStream, {
onStart: onStartMock,
onText: onTextMock,
onCompletion: onCompletionMock,
onToolsCalling: onToolCall,
});
const decoder = new TextDecoder();
const chunks = [];
// @ts-ignore
for await (const chunk of protocolStream) {
chunks.push(decoder.decode(chunk, { stream: true }));
}
expect(chunks).toEqual(
[
'id: chat_1',
'event: tool_calls',
`data: [{"function":{"arguments":"{\\"city\\":\\"杭州\\"}","name":"realtime-weather____fetchCurrentWeather"},"id":"realtime-weather____fetchCurrentWeather_0_abcd1234","index":0,"type":"function"}]\n`,
].map((i) => `${i}\n`),
);
expect(onTextMock).toHaveBeenCalledTimes(0);
expect(onStartMock).toHaveBeenCalledTimes(1);
expect(onToolCall).toHaveBeenCalledTimes(1);
expect(onCompletionMock).toHaveBeenCalledTimes(1);
});
});
it('should handle empty stream', async () => {
@@ -11,11 +11,6 @@ import {
} from './protocol';
const transformOllamaStream = (chunk: ChatResponse, stack: StreamContext): StreamProtocolChunk => {
// maybe need another structure to add support for multiple choices
if (chunk.done && !chunk.message.content) {
return { data: 'finished', id: stack.id, type: 'stop' };
}
if (chunk.message.thinking) {
return { data: chunk.message.thinking, id: stack.id, type: 'reasoning' };
}
@@ -36,6 +31,11 @@ const transformOllamaStream = (chunk: ChatResponse, stack: StreamContext): Strea
};
}
// maybe need another structure to add support for multiple choices
if (chunk.done && !chunk.message.content) {
return { data: 'finished', id: stack.id, type: 'stop' };
}
// 判断是否有 <think> 或 </think> 标签,更新 thinkingInContent 状态
if (chunk.message.content.includes('<think>')) {
stack.thinkingInContent = true;
@@ -1,6 +1,5 @@
import { GenerateContentResponse } from '@google/genai';
import { GroundingSearch } from '@/types/search';
import { GroundingSearch } from '@lobechat/types';
import { nanoid } from '../../utils/uuid';
import { convertGoogleAIUsage } from '../usageConverters/google-ai';
@@ -1,9 +1,8 @@
// @vitest-environment node
import type { ComfyUIKeyVault } from '@lobechat/types';
import { createBasicAuthCredentials } from '@lobechat/utils';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import type { ComfyUIKeyVault } from '@/types/index';
import type { CreateImagePayload } from '../../../types/image';
import { LobeComfyUI } from '../index';
@@ -1,7 +1,6 @@
import type { ComfyUIKeyVault } from '@lobechat/types';
import { createBasicAuthCredentials } from '@lobechat/utils';
import type { ComfyUIKeyVault } from '@/types/index';
export interface BasicCredentials {
password: string;
type: 'basic';
@@ -1,14 +1,9 @@
import type { ComfyUIKeyVault } from '@lobechat/types';
import { createBasicAuthCredentials } from '@lobechat/utils';
import debug from 'debug';
import type { ComfyUIKeyVault } from '@/types/index';
import { LobeRuntimeAI } from '../../core/BaseAI';
import {
AuthenticatedImageRuntime,
CreateImagePayload,
CreateImageResponse,
} from '../../types/image';
import { AuthenticatedImageRuntime, CreateImagePayload, CreateImageResponse } from '../../types';
import { parseComfyUIErrorMessage } from '../../utils/comfyuiErrorParser';
import { AgentRuntimeError } from '../../utils/createError';
+5 -5
View File
@@ -15,11 +15,11 @@
"@opentelemetry/instrumentation": "^0.207.0",
"@opentelemetry/instrumentation-http": "^0.207.0",
"@opentelemetry/instrumentation-pg": "^0.60.0",
"@opentelemetry/resources": "^2.0.1",
"@opentelemetry/sdk-metrics": "^2.0.1",
"@opentelemetry/resources": "^2.2.0",
"@opentelemetry/sdk-metrics": "^2.2.0",
"@opentelemetry/sdk-node": "^0.207.0",
"@opentelemetry/sdk-trace-node": "^2.0.1",
"@opentelemetry/semantic-conventions": "^1.36.0",
"@vercel/otel": "^1.13.0"
"@opentelemetry/sdk-trace-node": "^2.2.0",
"@opentelemetry/semantic-conventions": "^1.38.0",
"@vercel/otel": "^2.1.0"
}
}
+1 -1
View File
@@ -23,6 +23,6 @@
},
"devDependencies": {
"promptfoo": "^0.118.17",
"tsx": "^4.20.4"
"tsx": "^4.20.6"
}
}
+1 -1
View File
@@ -16,7 +16,7 @@
},
"dependencies": {
"node-fetch": "^3.3.2",
"request-filtering-agent": "^3"
"request-filtering-agent": "^3.0.2"
},
"devDependencies": {
"vitest": "^3.2.4"
+1 -1
View File
@@ -1,6 +1,6 @@
import { z } from 'zod';
import { AsyncTaskStatus } from '@/types/asyncTask';
import type { AsyncTaskStatus } from '../asyncTask';
export interface FileListItem {
chunkCount: number | null;

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