Compare commits

...

25 Commits

Author SHA1 Message Date
Arvin Xu 69dac2fc6e Merge branch 'main' into chore/try-react-compiler 2025-03-09 19:06:06 +08:00
Jonas Siewertsen 75c88425e0 📝 docs: Add NEXT_PUBLIC_ENABLE_NEXT_AUTH to clerk example (#6309) 2025-03-09 19:05:37 +08:00
samanhappy 30b2639c4b 💄 style(chat): auto send message from URL (#6497)
*  feat(chat): auto send message from URL

* introduce MessageFromUrl component
2025-03-09 19:01:59 +08:00
Rylan Cai 81867c413c 👷 chore: fix re-init in setup.sh (#6714) 2025-03-09 19:00:22 +08:00
Aloxaf f1ffc2c60c 💄 style: support openrouter claude 3.7 sonnet reasoning (#6806)
* feat: openrouter reasoning

* test: add test
2025-03-09 18:57:50 +08:00
gru-agent[bot] a9eadafd9f test: Add unit tests for the browserless function in the web crawler module (#6830)
Co-authored-by: gru-agent[bot] <185149714+gru-agent[bot]@users.noreply.github.com>
2025-03-09 18:11:24 +08:00
renovate[bot] 0e1146aa8d Update dependency lucide-react to ^0.479.0 (#6822)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-09 17:07:45 +08:00
lobehubbot 997ba159d2 📝 docs(bot): Auto sync agents & plugin to readme 2025-03-09 08:48:02 +00:00
semantic-release-bot ab8aa0a485 🔖 chore(release): v1.69.4 [skip ci]
### [Version&nbsp;1.69.4](https://github.com/lobehub/lobe-chat/compare/v1.69.3...v1.69.4)
<sup>Released on **2025-03-09**</sup>

#### 🐛 Bug Fixes

- **misc**: Fix mistral can not chat.

<br/>

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

#### What's fixed

* **misc**: Fix mistral can not chat, closes [#6828](https://github.com/lobehub/lobe-chat/issues/6828) ([00cba71](https://github.com/lobehub/lobe-chat/commit/00cba71))

</details>

<div align="right">

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

</div>
2025-03-09 08:46:55 +00:00
Arvin Xu 00cba71e27 🐛 fix: fix mistral can not chat (#6828)
* ♻️ refactor: refactor the implement

* fix mistral issue

* improve log

* refactor to the getXXXStoreState

* fix tests
2025-03-09 16:38:20 +08:00
renovate[bot] 86544a8455 Update dependency @google/generative-ai to ^0.24.0 (#6820)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-09 11:50:57 +08:00
lobehubbot f3c49cfd6a 📝 docs(bot): Auto sync agents & plugin to readme 2025-03-08 02:17:04 +00:00
semantic-release-bot b6eeba5850 🔖 chore(release): v1.69.3 [skip ci]
### [Version&nbsp;1.69.3](https://github.com/lobehub/lobe-chat/compare/v1.69.2...v1.69.3)
<sup>Released on **2025-03-08**</sup>

#### 💄 Styles

- **misc**: Add login ui for next-auth.

<br/>

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

#### Styles

* **misc**: Add login ui for next-auth, closes [#6434](https://github.com/lobehub/lobe-chat/issues/6434) ([541f275](https://github.com/lobehub/lobe-chat/commit/541f275))

</details>

<div align="right">

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

</div>
2025-03-08 02:16:01 +00:00
renovate[bot] 963f7889de Update dependency framer-motion to v12 (#5597) 2025-03-08 10:07:29 +08:00
Rylan Cai 541f27591a 💄 style: Add login ui for next-auth (#6434) 2025-03-08 10:02:51 +08:00
lobehubbot 3fb966cf37 📝 docs(bot): Auto sync agents & plugin to readme 2025-03-07 18:51:56 +00:00
semantic-release-bot 17d0a0fade 🔖 chore(release): v1.69.2 [skip ci]
### [Version&nbsp;1.69.2](https://github.com/lobehub/lobe-chat/compare/v1.69.1...v1.69.2)
<sup>Released on **2025-03-07**</sup>

#### ♻ Code Refactoring

- **misc**: Refactor the agent runtime implement.

<br/>

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

#### Code refactoring

* **misc**: Refactor the agent runtime implement, closes [#6784](https://github.com/lobehub/lobe-chat/issues/6784) ([14a9874](https://github.com/lobehub/lobe-chat/commit/14a9874))

</details>

<div align="right">

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

</div>
2025-03-07 18:50:55 +00:00
Arvin Xu 14a98748bb ♻️ refactor: refactor the agent runtime implement (#6784)
* bump

* add uniform runtime

* fix tests

* upgrade
2025-03-08 02:42:18 +08:00
lobehubbot 38c564337a 📝 docs(bot): Auto sync agents & plugin to readme 2025-03-07 17:27:40 +00:00
semantic-release-bot 2382a35810 🔖 chore(release): v1.69.1 [skip ci]
### [Version&nbsp;1.69.1](https://github.com/lobehub/lobe-chat/compare/v1.69.0...v1.69.1)
<sup>Released on **2025-03-07**</sup>

#### 💄 Styles

- **misc**: Add Qwen QwQ model.

<br/>

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

#### Styles

* **misc**: Add Qwen QwQ model, closes [#6783](https://github.com/lobehub/lobe-chat/issues/6783) ([3d3c2ce](https://github.com/lobehub/lobe-chat/commit/3d3c2ce))

</details>

<div align="right">

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

</div>
2025-03-07 17:26:30 +00:00
sxjeru 3d3c2ce72f 💄 style: Add Qwen QwQ model (#6783)
* Update groq.ts

* Update siliconcloud.ts

* Update novita.ts

* Update google.ts
2025-03-08 01:17:47 +08:00
lobehubbot 7f82512b54 📝 docs(bot): Auto sync agents & plugin to readme 2025-03-07 11:38:03 +00:00
Arvin Xu b30f55705f push 2025-02-20 03:19:08 +00:00
Arvin Xu fbe9ec0e48 Merge branch 'main' into chore/try-react-compiler 2025-02-20 11:13:12 +08:00
arvinxx e5b4b60c3d add config 2025-01-22 22:03:27 +08:00
76 changed files with 1328 additions and 290 deletions
+100
View File
@@ -2,6 +2,106 @@
# Changelog
### [Version 1.69.4](https://github.com/lobehub/lobe-chat/compare/v1.69.3...v1.69.4)
<sup>Released on **2025-03-09**</sup>
#### 🐛 Bug Fixes
- **misc**: Fix mistral can not chat.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### What's fixed
- **misc**: Fix mistral can not chat, closes [#6828](https://github.com/lobehub/lobe-chat/issues/6828) ([00cba71](https://github.com/lobehub/lobe-chat/commit/00cba71))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
### [Version 1.69.3](https://github.com/lobehub/lobe-chat/compare/v1.69.2...v1.69.3)
<sup>Released on **2025-03-08**</sup>
#### 💄 Styles
- **misc**: Add login ui for next-auth.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### Styles
- **misc**: Add login ui for next-auth, closes [#6434](https://github.com/lobehub/lobe-chat/issues/6434) ([541f275](https://github.com/lobehub/lobe-chat/commit/541f275))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
### [Version 1.69.2](https://github.com/lobehub/lobe-chat/compare/v1.69.1...v1.69.2)
<sup>Released on **2025-03-07**</sup>
#### ♻ Code Refactoring
- **misc**: Refactor the agent runtime implement.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### Code refactoring
- **misc**: Refactor the agent runtime implement, closes [#6784](https://github.com/lobehub/lobe-chat/issues/6784) ([14a9874](https://github.com/lobehub/lobe-chat/commit/14a9874))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
### [Version 1.69.1](https://github.com/lobehub/lobe-chat/compare/v1.69.0...v1.69.1)
<sup>Released on **2025-03-07**</sup>
#### 💄 Styles
- **misc**: Add Qwen QwQ model.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### Styles
- **misc**: Add Qwen QwQ model, closes [#6783](https://github.com/lobehub/lobe-chat/issues/6783) ([3d3c2ce](https://github.com/lobehub/lobe-chat/commit/3d3c2ce))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 1.69.0](https://github.com/lobehub/lobe-chat/compare/v1.68.11...v1.69.0)
<sup>Released on **2025-03-07**</sup>
+35
View File
@@ -1,4 +1,39 @@
[
{
"children": {
"fixes": ["Fix mistral can not chat."]
},
"date": "2025-03-09",
"version": "1.69.4"
},
{
"children": {
"improvements": ["Add login ui for next-auth."]
},
"date": "2025-03-08",
"version": "1.69.3"
},
{
"children": {
"improvements": ["Refactor the agent runtime implement."]
},
"date": "2025-03-07",
"version": "1.69.2"
},
{
"children": {
"improvements": ["Add Qwen QwQ model."]
},
"date": "2025-03-07",
"version": "1.69.1"
},
{
"children": {
"features": ["Support Anthropic Context Caching."]
},
"date": "2025-03-07",
"version": "1.69.0"
},
{
"children": {
"improvements": ["Add Gemini 2.0 Flash model variations, add QwQ models."]
+92 -1
View File
@@ -170,6 +170,16 @@ show_message() {
;;
esac
;;
tips_download_failed)
case $LANGUAGE in
zh_CN)
echo "$2 下载失败,请检查网络连接。"
;;
*)
echo "$2 Download failed, please check the network connection."
;;
esac
;;
tips_already_installed)
case $LANGUAGE in
zh_CN)
@@ -260,6 +270,30 @@ show_message() {
;;
esac
;;
tips_no_docker_permission)
case $LANGUAGE in
zh_CN)
echo "WARN: 看起来当前用户没有 Docker 权限。"
echo "使用 'sudo usermod -aG docker $USER' 为用户分配 Docker 权限(可能需要重新启动 shell)。"
;;
*)
echo "WARN: It look like the current user does not have Docker permissions."
echo "Use 'sudo usermod -aG docker $USER' to assign Docker permissions to the user (may require restarting shell)."
;;
esac
;;
tips_init_database_failed)
case $LANGUAGE in
zh_CN)
echo "无法初始化数据库,为了避免你的数据重复初始化,请在首次成功启动时运行以下指令清空 Casdoor 初始配置文件:"
echo "echo '{}' > init_data.json"
;;
*)
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"
;;
esac
;;
ask_regenerate_secrets)
case $LANGUAGE in
zh_CN)
@@ -320,12 +354,27 @@ show_message() {
;;
esac
;;
ask_init_database)
case $LANGUAGE in
zh_CN)
echo "是否初始化数据库?"
;;
*)
echo "Do you want to initialize the database?"
;;
esac
;;
esac
}
# Function to download files
download_file() {
wget -q --show-progress "$1" -O "$2"
wget --show-progress "$1" -O "$2"
# If run failed, exit
if [ $? -ne 0 ]; then
show_message "tips_download_failed" "$2"
exit 1
fi
}
print_centered() {
@@ -629,12 +678,54 @@ section_regenerate_secrets() {
fi
fi
}
show_message "ask_regenerate_secrets"
ask "(y/n)" "y"
if [[ "$ask_result" == "y" ]]; then
section_regenerate_secrets
fi
section_init_database() {
if ! command -v docker &> /dev/null ; then
echo "docker" $(show_message "tips_no_executable")
return 1
fi
if ! docker compose &> /dev/null ; then
echo "docker compose" $(show_message "tips_no_executable")
return 1
fi
# Check if user has permissions to run Docker by trying to get the status of Docker (docker status).
# If this fails, the user probably does not have permissions for Docker.
# ref: https://github.com/paperless-ngx/paperless-ngx/blob/89e5c08a1fe4ca0b7641ae8fbd5554502199ae40/install-paperless-ngx.sh#L64-L72
if ! docker stats --no-stream &> /dev/null ; then
echo $(show_message "tips_no_docker_permission")
return 1
fi
docker compose pull
docker compose up --detach postgresql casdoor
# 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"
ask "(y/n)" "y"
if [[ "$ask_result" == "y" ]]; then
# If return 1 means failed
section_init_database
if [ $? -ne 0 ]; then
echo $(show_message "tips_init_database_failed")
fi
else
show_message "tips_init_database_failed"
fi
section_display_configurated_report() {
# Display configuration reports
echo $(show_message "security_secrect_regenerate_report")
@@ -27,6 +27,7 @@ Go to [Clerk](https://clerk.com?utm_source=lobehub\&utm_medium=docs) to register
```shell
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_live_xxxxxxxxxxx
CLERK_SECRET_KEY=sk_live_xxxxxxxxxxxxxxxxxxxxxx
NEXT_PUBLIC_ENABLE_NEXT_AUTH=0
```
### Create and Configure Webhook in Clerk
+9
View File
@@ -245,6 +245,9 @@
"Qwen/QVQ-72B-Preview": {
"description": "QVQ-72B-Preview هو نموذج بحثي طورته فريق Qwen يركز على قدرات الاستدلال البصري، حيث يتمتع بميزة فريدة في فهم المشاهد المعقدة وحل المشكلات الرياضية المتعلقة بالرؤية."
},
"Qwen/QwQ-32B": {
"description": "QwQ هو نموذج استدلال من سلسلة Qwen. مقارنةً بالنماذج التقليدية المعتمدة على تحسين التعليمات، يتمتع QwQ بقدرة على التفكير والاستدلال، مما يتيح له تحقيق أداء معزز بشكل ملحوظ في المهام اللاحقة، خاصة في حل المشكلات الصعبة. QwQ-32B هو نموذج استدلال متوسط الحجم، قادر على تحقيق أداء تنافسي عند مقارنته بأحدث نماذج الاستدلال (مثل DeepSeek-R1، o1-mini). يستخدم هذا النموذج تقنيات مثل RoPE، SwiGLU، RMSNorm وAttention QKV bias، ويتميز بهيكل شبكة مكون من 64 طبقة و40 رأس انتباه Q (حيث KV في هيكل GQA هو 8)."
},
"Qwen/QwQ-32B-Preview": {
"description": "QwQ-32B-Preview هو أحدث نموذج بحث تجريبي من Qwen، يركز على تعزيز قدرات الاستدلال للذكاء الاصطناعي. من خلال استكشاف آليات معقدة مثل خلط اللغة والاستدلال التكراري، تشمل المزايا الرئيسية القدرة القوية على التحليل الاستدلالي، والقدرات الرياضية والبرمجية. في الوقت نفسه، هناك أيضًا مشكلات في تبديل اللغة، ودورات الاستدلال، واعتبارات الأمان، واختلافات في القدرات الأخرى."
},
@@ -1637,9 +1640,15 @@
"qwq": {
"description": "QwQ هو نموذج بحث تجريبي يركز على تحسين قدرات الاستدلال للذكاء الاصطناعي."
},
"qwq-32b": {
"description": "نموذج استدلال QwQ المدرب على نموذج Qwen2.5-32B، الذي يعزز بشكل كبير من قدرة الاستدلال للنموذج من خلال التعلم المعزز. تصل المؤشرات الأساسية للنموذج (AIME 24/25، LiveCodeBench) وبعض المؤشرات العامة (IFEval، LiveBench وغيرها) إلى مستوى DeepSeek-R1 الكامل، حيث تتجاوز جميع المؤشرات بشكل ملحوظ نموذج DeepSeek-R1-Distill-Qwen-32B المعتمد أيضًا على Qwen2.5-32B."
},
"qwq-32b-preview": {
"description": "نموذج QwQ هو نموذج بحث تجريبي تم تطويره بواسطة فريق Qwen، يركز على تعزيز قدرات الاستدلال للذكاء الاصطناعي."
},
"qwq-plus-latest": {
"description": "نموذج استدلال QwQ المدرب على نموذج Qwen2.5، الذي يعزز بشكل كبير من قدرة الاستدلال للنموذج من خلال التعلم المعزز. تصل المؤشرات الأساسية للنموذج (AIME 24/25، LiveCodeBench) وبعض المؤشرات العامة (IFEval، LiveBench وغيرها) إلى مستوى DeepSeek-R1 الكامل."
},
"r1-1776": {
"description": "R1-1776 هو إصدار من نموذج DeepSeek R1، تم تدريبه لاحقًا لتقديم معلومات حقائق غير خاضعة للرقابة وغير متحيزة."
},
+9
View File
@@ -245,6 +245,9 @@
"Qwen/QVQ-72B-Preview": {
"description": "QVQ-72B-Preview е изследователски модел, разработен от екипа на Qwen, който се фокусира върху визуалните способности за извеждане и притежава уникални предимства в разбирането на сложни сцени и решаването на визуално свързани математически проблеми."
},
"Qwen/QwQ-32B": {
"description": "QwQ е моделът за изводи от серията Qwen. В сравнение с традиционните модели за оптимизация на инструкции, QwQ притежава способности за разсъждение и извод, което позволява значително подобряване на производителността в задачи от по-ниско ниво, особено при решаване на трудни проблеми. QwQ-32B е среден модел за изводи, който постига конкурентоспособна производителност в сравнение с най-съвременните модели за изводи (като DeepSeek-R1, o1-mini). Този модел използва технологии като RoPE, SwiGLU, RMSNorm и Attention QKV bias, с 64 слоя в мрежовата структура и 40 Q внимание глави (в архитектурата GQA KV е 8)."
},
"Qwen/QwQ-32B-Preview": {
"description": "QwQ-32B-Preview е най-новият експериментален изследователски модел на Qwen, който се фокусира върху подобряване на AI разсъдъчните способности. Чрез изследване на сложни механизми като езикови смеси и рекурсивно разсъждение, основните предимства включват мощни аналитични способности, математически и програмистки умения. В същото време съществуват проблеми с езиковото превключване, цикли на разсъждение, съображения за безопасност и разлики в други способности."
},
@@ -1637,9 +1640,15 @@
"qwq": {
"description": "QwQ е експериментален изследователски модел, който се фокусира върху подобряване на AI разсъдъчните способности."
},
"qwq-32b": {
"description": "QwQ моделът за изводи, обучен на базата на модела Qwen2.5-32B, значително подобрява способностите си за изводи чрез усилено обучение. Основните показатели на модела, като математически код и други ключови индикатори (AIME 24/25, LiveCodeBench), както и някои общи индикатори (IFEval, LiveBench и др.), достигат нивото на DeepSeek-R1 в пълна версия, като всички показатели значително надвишават тези на DeepSeek-R1-Distill-Qwen-32B, също базиран на Qwen2.5-32B."
},
"qwq-32b-preview": {
"description": "QwQ моделът е експериментален изследователски модел, разработен от екипа на Qwen, който се фокусира върху подобряване на AI разсъдъчните способности."
},
"qwq-plus-latest": {
"description": "QwQ моделът за изводи, обучен на базата на модела Qwen2.5, значително подобрява способностите си за изводи чрез усилено обучение. Основните показатели на модела, като математически код и други ключови индикатори (AIME 24/25, LiveCodeBench), както и някои общи индикатори (IFEval, LiveBench и др.), достигат нивото на DeepSeek-R1 в пълна версия."
},
"r1-1776": {
"description": "R1-1776 е версия на модела DeepSeek R1, след обучението, която предоставя непроверена и безпристрастна фактическа информация."
},
+9
View File
@@ -245,6 +245,9 @@
"Qwen/QVQ-72B-Preview": {
"description": "QVQ-72B-Preview ist ein forschungsorientiertes Modell, das vom Qwen-Team entwickelt wurde und sich auf visuelle Inferenzfähigkeiten konzentriert. Es hat einzigartige Vorteile beim Verständnis komplexer Szenen und der Lösung visuell verwandter mathematischer Probleme."
},
"Qwen/QwQ-32B": {
"description": "QwQ ist das Inferenzmodell der Qwen-Serie. Im Vergleich zu traditionellen, anweisungsoptimierten Modellen verfügt QwQ über Denk- und Schlussfolgerungsfähigkeiten, die eine signifikante Leistungssteigerung bei nachgelagerten Aufgaben ermöglichen, insbesondere bei der Lösung schwieriger Probleme. QwQ-32B ist ein mittelgroßes Inferenzmodell, das im Vergleich zu den fortschrittlichsten Inferenzmodellen (wie DeepSeek-R1, o1-mini) wettbewerbsfähige Leistungen erzielt. Dieses Modell verwendet Technologien wie RoPE, SwiGLU, RMSNorm und Attention QKV Bias und hat eine Netzwerkstruktur mit 64 Schichten und 40 Q-Attention-Köpfen (im GQA-Architektur sind es 8 KV)."
},
"Qwen/QwQ-32B-Preview": {
"description": "QwQ-32B-Preview ist das neueste experimentelle Forschungsmodell von Qwen, das sich auf die Verbesserung der KI-Inferenzfähigkeiten konzentriert. Durch die Erforschung komplexer Mechanismen wie Sprachmischung und rekursive Inferenz bietet es Hauptvorteile wie starke Analysefähigkeiten, mathematische und Programmierfähigkeiten. Gleichzeitig gibt es Herausforderungen wie Sprachwechsel, Inferenzzyklen, Sicherheitsüberlegungen und Unterschiede in anderen Fähigkeiten."
},
@@ -1637,9 +1640,15 @@
"qwq": {
"description": "QwQ ist ein experimentelles Forschungsmodell, das sich auf die Verbesserung der KI-Inferenzfähigkeiten konzentriert."
},
"qwq-32b": {
"description": "Das QwQ-Inferenzmodell, das auf dem Qwen2.5-32B-Modell trainiert wurde, hat durch verstärktes Lernen die Inferenzfähigkeiten des Modells erheblich verbessert. Die Kernmetriken des Modells, wie mathematische Codes (AIME 24/25, LiveCodeBench) sowie einige allgemeine Metriken (IFEval, LiveBench usw.), erreichen das Niveau der DeepSeek-R1 Vollversion, wobei alle Metriken deutlich die ebenfalls auf Qwen2.5-32B basierende DeepSeek-R1-Distill-Qwen-32B übertreffen."
},
"qwq-32b-preview": {
"description": "Das QwQ-Modell ist ein experimentelles Forschungsmodell, das vom Qwen-Team entwickelt wurde und sich auf die Verbesserung der KI-Inferenzfähigkeiten konzentriert."
},
"qwq-plus-latest": {
"description": "Das QwQ-Inferenzmodell, das auf dem Qwen2.5-Modell trainiert wurde, hat durch verstärktes Lernen die Inferenzfähigkeiten des Modells erheblich verbessert. Die Kernmetriken des Modells, wie mathematische Codes (AIME 24/25, LiveCodeBench) sowie einige allgemeine Metriken (IFEval, LiveBench usw.), erreichen das Niveau der DeepSeek-R1 Vollversion."
},
"r1-1776": {
"description": "R1-1776 ist eine Version des DeepSeek R1 Modells, die nachtrainiert wurde, um unverfälschte, unvoreingenommene Fakteninformationen bereitzustellen."
},
+9
View File
@@ -245,6 +245,9 @@
"Qwen/QVQ-72B-Preview": {
"description": "QVQ-72B-Preview is a research-oriented model developed by the Qwen team, focusing on visual reasoning capabilities, with unique advantages in understanding complex scenes and solving visually related mathematical problems."
},
"Qwen/QwQ-32B": {
"description": "QwQ is the inference model of the Qwen series. Compared to traditional instruction-tuned models, QwQ possesses reasoning and cognitive abilities, achieving significantly enhanced performance in downstream tasks, especially in solving difficult problems. QwQ-32B is a medium-sized inference model that competes effectively against state-of-the-art inference models (such as DeepSeek-R1 and o1-mini). This model employs technologies such as RoPE, SwiGLU, RMSNorm, and Attention QKV bias, featuring a 64-layer network structure and 40 Q attention heads (with 8 KV heads in the GQA architecture)."
},
"Qwen/QwQ-32B-Preview": {
"description": "QwQ-32B-Preview is Qwen's latest experimental research model, focusing on enhancing AI reasoning capabilities. By exploring complex mechanisms such as language mixing and recursive reasoning, its main advantages include strong analytical reasoning, mathematical, and programming abilities. However, it also faces challenges such as language switching issues, reasoning loops, safety considerations, and differences in other capabilities."
},
@@ -1637,9 +1640,15 @@
"qwq": {
"description": "QwQ is an experimental research model focused on improving AI reasoning capabilities."
},
"qwq-32b": {
"description": "The QwQ inference model is trained based on the Qwen2.5-32B model, significantly enhancing its reasoning capabilities through reinforcement learning. The core metrics of the model, including mathematical code (AIME 24/25, LiveCodeBench) and some general metrics (IFEval, LiveBench, etc.), reach the level of the full version of DeepSeek-R1, with all metrics significantly surpassing those of DeepSeek-R1-Distill-Qwen-32B, which is also based on Qwen2.5-32B."
},
"qwq-32b-preview": {
"description": "The QwQ model is an experimental research model developed by the Qwen team, focusing on enhancing AI reasoning capabilities."
},
"qwq-plus-latest": {
"description": "The QwQ inference model is trained based on the Qwen2.5 model, significantly enhancing its reasoning capabilities through reinforcement learning. The core metrics of the model, including mathematical code (AIME 24/25, LiveCodeBench) and some general metrics (IFEval, LiveBench, etc.), reach the level of the full version of DeepSeek-R1."
},
"r1-1776": {
"description": "R1-1776 is a version of the DeepSeek R1 model, fine-tuned to provide unfiltered, unbiased factual information."
},
+9
View File
@@ -245,6 +245,9 @@
"Qwen/QVQ-72B-Preview": {
"description": "QVQ-72B-Preview es un modelo de investigación desarrollado por el equipo de Qwen, enfocado en la capacidad de razonamiento visual, que tiene ventajas únicas en la comprensión de escenas complejas y en la resolución de problemas matemáticos relacionados con la visión."
},
"Qwen/QwQ-32B": {
"description": "QwQ es el modelo de inferencia de la serie Qwen. A diferencia de los modelos tradicionales de ajuste por instrucciones, QwQ posee habilidades de pensamiento e inferencia, lo que le permite lograr un rendimiento significativamente mejorado en tareas posteriores, especialmente en la resolución de problemas difíciles. QwQ-32B es un modelo de inferencia de tamaño mediano que puede competir en rendimiento con los modelos de inferencia más avanzados (como DeepSeek-R1, o1-mini). Este modelo utiliza tecnologías como RoPE, SwiGLU, RMSNorm y sesgo de atención QKV, y cuenta con una estructura de red de 64 capas y 40 cabezas de atención Q (en la arquitectura GQA, KV es de 8)."
},
"Qwen/QwQ-32B-Preview": {
"description": "QwQ-32B-Preview es el último modelo de investigación experimental de Qwen, enfocado en mejorar la capacidad de razonamiento de la IA. A través de la exploración de mecanismos complejos como la mezcla de lenguajes y el razonamiento recursivo, sus principales ventajas incluyen una poderosa capacidad de análisis de razonamiento, así como habilidades matemáticas y de programación. Sin embargo, también presenta problemas de cambio de idioma, ciclos de razonamiento, consideraciones de seguridad y diferencias en otras capacidades."
},
@@ -1637,9 +1640,15 @@
"qwq": {
"description": "QwQ es un modelo de investigación experimental que se centra en mejorar la capacidad de razonamiento de la IA."
},
"qwq-32b": {
"description": "El modelo de inferencia QwQ, entrenado con el modelo Qwen2.5-32B, ha mejorado significativamente su capacidad de inferencia a través del aprendizaje por refuerzo. Los indicadores clave del modelo, como el código matemático y otros indicadores centrales (AIME 24/25, LiveCodeBench), así como algunos indicadores generales (IFEval, LiveBench, etc.), han alcanzado el nivel del modelo DeepSeek-R1 en su versión completa, superando notablemente a DeepSeek-R1-Distill-Qwen-32B, que también se basa en Qwen2.5-32B."
},
"qwq-32b-preview": {
"description": "El modelo QwQ es un modelo de investigación experimental desarrollado por el equipo de Qwen, enfocado en mejorar la capacidad de razonamiento de la IA."
},
"qwq-plus-latest": {
"description": "El modelo de inferencia QwQ, entrenado con el modelo Qwen2.5, ha mejorado significativamente su capacidad de inferencia a través del aprendizaje por refuerzo. Los indicadores clave del modelo, como el código matemático y otros indicadores centrales (AIME 24/25, LiveCodeBench), así como algunos indicadores generales (IFEval, LiveBench, etc.), han alcanzado el nivel del modelo DeepSeek-R1 en su versión completa."
},
"r1-1776": {
"description": "R1-1776 es una versión del modelo DeepSeek R1, que ha sido entrenada posteriormente para proporcionar información factual sin censura y sin sesgos."
},
+9
View File
@@ -245,6 +245,9 @@
"Qwen/QVQ-72B-Preview": {
"description": "QVQ-72B-Preview یک مدل تحقیقاتی است که توسط تیم Qwen توسعه یافته و بر روی توانایی‌های استنتاج بصری تمرکز دارد و در درک صحنه‌های پیچیده و حل مسائل ریاضی مرتبط با بصری دارای مزیت‌های منحصر به فردی است."
},
"Qwen/QwQ-32B": {
"description": "QwQ مدل استنتاجی از سری Qwen است. در مقایسه با مدل‌های سنتی بهینه‌سازی دستورالعمل، QwQ دارای توانایی تفکر و استنتاج است و می‌تواند در وظایف پایین‌دستی عملکرد قابل توجهی را به ویژه در حل مسائل دشوار ارائه دهد. QwQ-32B یک مدل استنتاجی متوسط است که می‌تواند در مقایسه با مدل‌های استنتاجی پیشرفته (مانند DeepSeek-R1، o1-mini) عملکرد رقابتی را به دست آورد. این مدل از تکنیک‌هایی مانند RoPE، SwiGLU، RMSNorm و Attention QKV bias استفاده می‌کند و دارای ساختار شبکه 64 لایه و 40 سر توجه Q (در معماری GQA، KV برابر با 8 است) می‌باشد."
},
"Qwen/QwQ-32B-Preview": {
"description": "QwQ-32B-Preview جدیدترین مدل تحقیقاتی تجربی Qwen است که بر بهبود توانایی استدلال AI تمرکز دارد. با کاوش در مکانیزم‌های پیچیده‌ای مانند ترکیب زبان و استدلال بازگشتی، مزایای اصلی شامل توانایی تحلیل استدلال قوی، توانایی ریاضی و برنامه‌نویسی است. در عین حال، مشکلاتی مانند تغییر زبان، حلقه‌های استدلال، ملاحظات ایمنی و تفاوت‌های دیگر در توانایی‌ها وجود دارد."
},
@@ -1637,9 +1640,15 @@
"qwq": {
"description": "QwQ یک مدل تحقیقاتی تجربی است که بر بهبود توانایی استدلال AI تمرکز دارد."
},
"qwq-32b": {
"description": "مدل استنتاج QwQ مبتنی بر مدل Qwen2.5-32B است که از طریق یادگیری تقویتی به طور قابل توجهی توانایی استنتاج مدل را افزایش داده است. شاخص‌های اصلی مدل مانند کد ریاضی (AIME 24/25، LiveCodeBench) و برخی از شاخص‌های عمومی (IFEval، LiveBench و غیره) به سطح DeepSeek-R1 نسخه کامل رسیده‌اند و تمامی شاخص‌ها به طور قابل توجهی از DeepSeek-R1-Distill-Qwen-32B که نیز مبتنی بر Qwen2.5-32B است، پیشی گرفته‌اند."
},
"qwq-32b-preview": {
"description": "مدل QwQ یک مدل تحقیقاتی تجربی است که توسط تیم Qwen توسعه یافته و بر تقویت توانایی استدلال AI تمرکز دارد."
},
"qwq-plus-latest": {
"description": "مدل استنتاج QwQ مبتنی بر مدل Qwen2.5 است که از طریق یادگیری تقویتی به طور قابل توجهی توانایی استنتاج مدل را افزایش داده است. شاخص‌های اصلی مدل مانند کد ریاضی (AIME 24/25، LiveCodeBench) و برخی از شاخص‌های عمومی (IFEval، LiveBench و غیره) به سطح DeepSeek-R1 نسخه کامل رسیده‌اند."
},
"r1-1776": {
"description": "R1-1776 نسخه‌ای از مدل DeepSeek R1 است که پس از آموزش مجدد، اطلاعات واقعی بدون سانسور و بدون تعصب را ارائه می‌دهد."
},
+9
View File
@@ -245,6 +245,9 @@
"Qwen/QVQ-72B-Preview": {
"description": "QVQ-72B-Preview est un modèle de recherche développé par l'équipe Qwen, axé sur les capacités de raisonnement visuel, qui possède des avantages uniques dans la compréhension de scènes complexes et la résolution de problèmes mathématiques liés à la vision."
},
"Qwen/QwQ-32B": {
"description": "QwQ est le modèle d'inférence de la série Qwen. Comparé aux modèles d'optimisation d'instructions traditionnels, QwQ possède des capacités de réflexion et de raisonnement, permettant d'obtenir des performances nettement améliorées dans les tâches en aval, en particulier pour résoudre des problèmes difficiles. QwQ-32B est un modèle d'inférence de taille moyenne, capable d'obtenir des performances compétitives par rapport aux modèles d'inférence les plus avancés (comme DeepSeek-R1, o1-mini). Ce modèle utilise des techniques telles que RoPE, SwiGLU, RMSNorm et Attention QKV bias, avec une architecture de réseau de 64 couches et 40 têtes d'attention Q (dans l'architecture GQA, KV est de 8)."
},
"Qwen/QwQ-32B-Preview": {
"description": "QwQ-32B-Preview est le dernier modèle de recherche expérimental de Qwen, axé sur l'amélioration des capacités de raisonnement de l'IA. En explorant des mécanismes complexes tels que le mélange de langues et le raisonnement récursif, ses principaux avantages incluent de puissantes capacités d'analyse de raisonnement, ainsi que des compétences en mathématiques et en programmation. Cependant, il existe également des problèmes de changement de langue, des cycles de raisonnement, des considérations de sécurité et des différences dans d'autres capacités."
},
@@ -1637,9 +1640,15 @@
"qwq": {
"description": "QwQ est un modèle de recherche expérimental, axé sur l'amélioration des capacités de raisonnement de l'IA."
},
"qwq-32b": {
"description": "Le modèle d'inférence QwQ, entraîné sur le modèle Qwen2.5-32B, a considérablement amélioré ses capacités d'inférence grâce à l'apprentissage par renforcement. Les indicateurs clés du modèle, tels que le code mathématique (AIME 24/25, LiveCodeBench) ainsi que certains indicateurs généraux (IFEval, LiveBench, etc.), atteignent le niveau de la version complète de DeepSeek-R1, avec des performances nettement supérieures à celles de DeepSeek-R1-Distill-Qwen-32B, également basé sur Qwen2.5-32B."
},
"qwq-32b-preview": {
"description": "Le modèle QwQ est un modèle de recherche expérimental développé par l'équipe Qwen, axé sur l'amélioration des capacités de raisonnement de l'IA."
},
"qwq-plus-latest": {
"description": "Le modèle d'inférence QwQ, entraîné sur le modèle Qwen2.5, a considérablement amélioré ses capacités d'inférence grâce à l'apprentissage par renforcement. Les indicateurs clés du modèle, tels que le code mathématique (AIME 24/25, LiveCodeBench) ainsi que certains indicateurs généraux (IFEval, LiveBench, etc.), atteignent le niveau de la version complète de DeepSeek-R1."
},
"r1-1776": {
"description": "R1-1776 est une version du modèle DeepSeek R1, après un entraînement supplémentaire, fournissant des informations factuelles non filtrées et impartiales."
},
+9
View File
@@ -245,6 +245,9 @@
"Qwen/QVQ-72B-Preview": {
"description": "QVQ-72B-Preview è un modello di ricerca sviluppato dal team Qwen, focalizzato sulle capacità di inferenza visiva, con vantaggi unici nella comprensione di scenari complessi e nella risoluzione di problemi matematici legati alla visione."
},
"Qwen/QwQ-32B": {
"description": "QwQ è il modello di inferenza della serie Qwen. Rispetto ai tradizionali modelli di ottimizzazione delle istruzioni, QwQ possiede capacità di pensiero e ragionamento, consentendo prestazioni significativamente migliorate nei compiti downstream, specialmente nella risoluzione di problemi complessi. QwQ-32B è un modello di inferenza di medie dimensioni, in grado di ottenere prestazioni competitive rispetto ai modelli di inferenza all'avanguardia (come DeepSeek-R1, o1-mini). Questo modello utilizza tecnologie come RoPE, SwiGLU, RMSNorm e Attention QKV bias, con una struttura di rete a 64 strati e 40 teste di attenzione Q (nel GQA, KV è 8)."
},
"Qwen/QwQ-32B-Preview": {
"description": "QwQ-32B-Preview è l'ultimo modello di ricerca sperimentale di Qwen, focalizzato sul miglioramento delle capacità di ragionamento dell'IA. Esplorando meccanismi complessi come la mescolanza linguistica e il ragionamento ricorsivo, i principali vantaggi includono potenti capacità di analisi del ragionamento, abilità matematiche e di programmazione. Tuttavia, ci sono anche problemi di cambio linguistico, cicli di ragionamento, considerazioni di sicurezza e differenze in altre capacità."
},
@@ -1637,9 +1640,15 @@
"qwq": {
"description": "QwQ è un modello di ricerca sperimentale, focalizzato sul miglioramento delle capacità di ragionamento dell'IA."
},
"qwq-32b": {
"description": "Il modello di inferenza QwQ, addestrato sul modello Qwen2.5-32B, ha notevolmente migliorato le capacità di inferenza del modello attraverso l'apprendimento rinforzato. I principali indicatori core (AIME 24/25, LiveCodeBench) e alcuni indicatori generali (IFEval, LiveBench, ecc.) raggiungono il livello della versione completa di DeepSeek-R1, con tutti gli indicatori che superano significativamente il DeepSeek-R1-Distill-Qwen-32B, anch'esso basato su Qwen2.5-32B."
},
"qwq-32b-preview": {
"description": "Il modello QwQ è un modello di ricerca sperimentale sviluppato dal team Qwen, focalizzato sul potenziamento delle capacità di ragionamento dell'IA."
},
"qwq-plus-latest": {
"description": "Il modello di inferenza QwQ, addestrato sul modello Qwen2.5, ha notevolmente migliorato le capacità di inferenza del modello attraverso l'apprendimento rinforzato. I principali indicatori core (AIME 24/25, LiveCodeBench) e alcuni indicatori generali (IFEval, LiveBench, ecc.) raggiungono il livello della versione completa di DeepSeek-R1."
},
"r1-1776": {
"description": "R1-1776 è una versione del modello DeepSeek R1, addestrata successivamente per fornire informazioni fattuali non verificate e prive di pregiudizi."
},
+9
View File
@@ -245,6 +245,9 @@
"Qwen/QVQ-72B-Preview": {
"description": "QVQ-72B-Previewは、Qwenチームによって開発された視覚推論能力に特化した研究モデルであり、複雑なシーン理解と視覚関連の数学問題を解決する上で独自の利点を持っています。"
},
"Qwen/QwQ-32B": {
"description": "QwQはQwenシリーズの推論モデルです。従来の指示調整モデルと比較して、QwQは思考と推論能力を備えており、特に困難な問題を解決する際に、下流タスクでのパフォーマンスを大幅に向上させることができます。QwQ-32Bは中型の推論モデルであり、最先端の推論モデル(DeepSeek-R1、o1-miniなど)との比較において競争力のあるパフォーマンスを発揮します。このモデルはRoPE、SwiGLU、RMSNorm、Attention QKVバイアスなどの技術を採用しており、64層のネットワーク構造と40のQアテンションヘッド(GQAアーキテクチャではKVは8個)を持っています。"
},
"Qwen/QwQ-32B-Preview": {
"description": "QwQ-32B-PreviewはQwenの最新の実験的研究モデルで、AIの推論能力を向上させることに特化しています。言語の混合、再帰的推論などの複雑なメカニズムを探求することで、主な利点は強力な推論分析能力、数学およびプログラミング能力です。同時に、言語切り替えの問題、推論のループ、安全性の考慮、その他の能力の違いも存在します。"
},
@@ -1637,9 +1640,15 @@
"qwq": {
"description": "QwQはAIの推論能力を向上させることに特化した実験的研究モデルです。"
},
"qwq-32b": {
"description": "Qwen2.5-32Bモデルに基づいて訓練されたQwQ推論モデルは、強化学習を通じてモデルの推論能力を大幅に向上させました。モデルの数学コードなどのコア指標(AIME 24/25、LiveCodeBench)および一部の一般的な指標(IFEval、LiveBenchなど)は、DeepSeek-R1のフルバージョンに達しており、すべての指標は同じくQwen2.5-32Bに基づくDeepSeek-R1-Distill-Qwen-32Bを大幅に上回っています。"
},
"qwq-32b-preview": {
"description": "QwQモデルはQwenチームによって開発された実験的な研究モデルで、AIの推論能力を強化することに焦点を当てています。"
},
"qwq-plus-latest": {
"description": "Qwen2.5モデルに基づいて訓練されたQwQ推論モデルは、強化学習を通じてモデルの推論能力を大幅に向上させました。モデルの数学コードなどのコア指標(AIME 24/25、LiveCodeBench)および一部の一般的な指標(IFEval、LiveBenchなど)は、DeepSeek-R1のフルバージョンに達しています。"
},
"r1-1776": {
"description": "R1-1776は、DeepSeek R1モデルの一つのバージョンで、後処理を経て、検閲されていない偏りのない事実情報を提供します。"
},
+9
View File
@@ -245,6 +245,9 @@
"Qwen/QVQ-72B-Preview": {
"description": "QVQ-72B-Preview는 Qwen 팀이 개발한 시각적 추론 능력에 중점을 둔 연구 모델로, 복잡한 장면 이해 및 시각 관련 수학 문제 해결에서 독특한 장점을 가지고 있습니다."
},
"Qwen/QwQ-32B": {
"description": "QwQ는 Qwen 시리즈의 추론 모델입니다. 전통적인 지시 조정 모델과 비교할 때, QwQ는 사고 및 추론 능력을 갖추고 있어 하위 작업에서 특히 어려운 문제를 해결하는 데 있어 성능이 크게 향상됩니다. QwQ-32B는 중형 추론 모델로, 최신 추론 모델(예: DeepSeek-R1, o1-mini)과 비교할 때 경쟁력 있는 성능을 발휘합니다. 이 모델은 RoPE, SwiGLU, RMSNorm 및 Attention QKV bias와 같은 기술을 사용하며, 64층 네트워크 구조와 40개의 Q 주의 헤드(GQA 구조에서 KV는 8개)를 가지고 있습니다."
},
"Qwen/QwQ-32B-Preview": {
"description": "QwQ-32B-Preview는 Qwen의 최신 실험적 연구 모델로, AI 추론 능력을 향상시키는 데 중점을 두고 있습니다. 언어 혼합, 재귀 추론 등 복잡한 메커니즘을 탐구하며, 주요 장점으로는 강력한 추론 분석 능력, 수학 및 프로그래밍 능력이 포함됩니다. 동시에 언어 전환 문제, 추론 루프, 안전성 고려 및 기타 능력 차이와 같은 문제도 존재합니다."
},
@@ -1637,9 +1640,15 @@
"qwq": {
"description": "QwQ는 AI 추론 능력을 향상시키는 데 중점을 둔 실험 연구 모델입니다."
},
"qwq-32b": {
"description": "Qwen2.5-32B 모델을 기반으로 훈련된 QwQ 추론 모델로, 강화 학습을 통해 모델의 추론 능력을 크게 향상시켰습니다. 모델의 수학 코드 등 핵심 지표(AIME 24/25, LiveCodeBench) 및 일부 일반 지표(IFEval, LiveBench 등)는 DeepSeek-R1 풀 버전 수준에 도달했으며, 모든 지표는 동일하게 Qwen2.5-32B를 기반으로 한 DeepSeek-R1-Distill-Qwen-32B를 크게 초과합니다."
},
"qwq-32b-preview": {
"description": "QwQ 모델은 Qwen 팀이 개발한 실험적 연구 모델로, AI 추론 능력을 향상시키는 데 중점을 두고 있습니다."
},
"qwq-plus-latest": {
"description": "Qwen2.5 모델을 기반으로 훈련된 QwQ 추론 모델로, 강화 학습을 통해 모델의 추론 능력을 크게 향상시켰습니다. 모델의 수학 코드 등 핵심 지표(AIME 24/25, LiveCodeBench) 및 일부 일반 지표(IFEval, LiveBench 등)는 DeepSeek-R1 풀 버전 수준에 도달했습니다."
},
"r1-1776": {
"description": "R1-1776은 DeepSeek R1 모델의 한 버전으로, 후속 훈련을 거쳐 검토되지 않은 편향 없는 사실 정보를 제공합니다."
},
+9
View File
@@ -245,6 +245,9 @@
"Qwen/QVQ-72B-Preview": {
"description": "QVQ-72B-Preview is een onderzoeksmodel ontwikkeld door het Qwen-team, dat zich richt op visuele redeneervaardigheden en unieke voordelen heeft in het begrijpen van complexe scènes en het oplossen van visueel gerelateerde wiskundige problemen."
},
"Qwen/QwQ-32B": {
"description": "QwQ is het inferentiemodel van de Qwen-serie. In vergelijking met traditionele instructie-geoptimaliseerde modellen beschikt QwQ over denk- en redeneervaardigheden, waardoor het in staat is om aanzienlijk verbeterde prestaties te leveren in downstream-taken, vooral bij het oplossen van moeilijke problemen. QwQ-32B is een middelgroot inferentiemodel dat concurrerende prestaties kan behalen in vergelijking met de meest geavanceerde inferentiemodellen (zoals DeepSeek-R1, o1-mini). Dit model maakt gebruik van technologieën zoals RoPE, SwiGLU, RMSNorm en Attention QKV bias, en heeft een netwerkstructuur van 64 lagen en 40 Q-aandachtshoofden (met KV van 8 in de GQA-architectuur)."
},
"Qwen/QwQ-32B-Preview": {
"description": "QwQ-32B-Preview is het nieuwste experimentele onderzoeksmodel van Qwen, gericht op het verbeteren van AI-redeneringscapaciteiten. Door het verkennen van complexe mechanismen zoals taalmixing en recursieve redenering, zijn de belangrijkste voordelen onder andere krachtige redeneringsanalyses, wiskundige en programmeervaardigheden. Tegelijkertijd zijn er ook problemen met taalwisseling, redeneringscycli, veiligheidskwesties en verschillen in andere capaciteiten."
},
@@ -1637,9 +1640,15 @@
"qwq": {
"description": "QwQ is een experimenteel onderzoeksmodel dat zich richt op het verbeteren van de AI-redeneringscapaciteiten."
},
"qwq-32b": {
"description": "De QwQ-inferentiemodel, getraind op het Qwen2.5-32B-model, heeft zijn inferentievermogen aanzienlijk verbeterd door middel van versterkend leren. De kernindicatoren van het model, zoals wiskundige code (AIME 24/25, LiveCodeBench) en enkele algemene indicatoren (IFEval, LiveBench, enz.), bereiken het niveau van de DeepSeek-R1 volwaardige versie, waarbij alle indicatoren aanzienlijk beter presteren dan de DeepSeek-R1-Distill-Qwen-32B, die ook op Qwen2.5-32B is gebaseerd."
},
"qwq-32b-preview": {
"description": "Het QwQ-model is een experimenteel onderzoeksmodel ontwikkeld door het Qwen-team, gericht op het verbeteren van de AI-redeneringscapaciteiten."
},
"qwq-plus-latest": {
"description": "De QwQ-inferentiemodel, getraind op het Qwen2.5-model, heeft zijn inferentievermogen aanzienlijk verbeterd door middel van versterkend leren. De kernindicatoren van het model, zoals wiskundige code (AIME 24/25, LiveCodeBench) en enkele algemene indicatoren (IFEval, LiveBench, enz.), bereiken het niveau van de DeepSeek-R1 volwaardige versie."
},
"r1-1776": {
"description": "R1-1776 is een versie van het DeepSeek R1-model, dat is bijgetraind om ongecensureerde, onpartijdige feitelijke informatie te bieden."
},
+9
View File
@@ -245,6 +245,9 @@
"Qwen/QVQ-72B-Preview": {
"description": "QVQ-72B-Preview to model badawczy opracowany przez zespół Qwen, skoncentrowany na zdolnościach wnioskowania wizualnego, który ma unikalne zalety w zrozumieniu złożonych scenariuszy i rozwiązywaniu wizualnie związanych problemów matematycznych."
},
"Qwen/QwQ-32B": {
"description": "QwQ jest modelem inferencyjnym z serii Qwen. W porównaniu do tradycyjnych modeli dostosowanych do instrukcji, QwQ posiada zdolności myślenia i wnioskowania, co pozwala na znaczące zwiększenie wydajności w zadaniach końcowych, szczególnie w rozwiązywaniu trudnych problemów. QwQ-32B to średniej wielkości model inferencyjny, który osiąga konkurencyjną wydajność w porównaniu z najnowocześniejszymi modelami inferencyjnymi, takimi jak DeepSeek-R1 i o1-mini. Model ten wykorzystuje technologie takie jak RoPE, SwiGLU, RMSNorm oraz Attention QKV bias, posiada 64-warstwową strukturę sieci i 40 głowic uwagi Q (w architekturze GQA KV wynosi 8)."
},
"Qwen/QwQ-32B-Preview": {
"description": "QwQ-32B-Preview to najnowszy eksperymentalny model badawczy Qwen, skoncentrowany na zwiększeniu zdolności wnioskowania AI. Poprzez eksplorację złożonych mechanizmów, takich jak mieszanie języków i wnioskowanie rekurencyjne, główne zalety obejmują silne zdolności analizy wnioskowania, matematyki i programowania. Jednocześnie występują problemy z przełączaniem języków, cyklami wnioskowania, kwestiami bezpieczeństwa oraz różnicami w innych zdolnościach."
},
@@ -1637,9 +1640,15 @@
"qwq": {
"description": "QwQ to eksperymentalny model badawczy, skoncentrowany na zwiększeniu zdolności wnioskowania AI."
},
"qwq-32b": {
"description": "Model inferency QwQ, oparty na modelu Qwen2.5-32B, został znacznie ulepszony dzięki uczeniu przez wzmocnienie, co zwiększa jego zdolności inferencyjne. Kluczowe wskaźniki modelu, takie jak matematyczny kod i inne (AIME 24/25, LiveCodeBench), oraz niektóre ogólne wskaźniki (IFEval, LiveBench itp.) osiągają poziom pełnej wersji DeepSeek-R1, a wszystkie wskaźniki znacznie przewyższają te, które są oparte na Qwen2.5-32B, w tym DeepSeek-R1-Distill-Qwen-32B."
},
"qwq-32b-preview": {
"description": "Model QwQ to eksperymentalny model badawczy opracowany przez zespół Qwen, skoncentrowany na zwiększeniu zdolności wnioskowania AI."
},
"qwq-plus-latest": {
"description": "Model inferency QwQ, oparty na modelu Qwen2.5, został znacznie ulepszony dzięki uczeniu przez wzmocnienie, co zwiększa jego zdolności inferencyjne. Kluczowe wskaźniki modelu, takie jak matematyczny kod i inne (AIME 24/25, LiveCodeBench), oraz niektóre ogólne wskaźniki (IFEval, LiveBench itp.) osiągają poziom pełnej wersji DeepSeek-R1."
},
"r1-1776": {
"description": "R1-1776 to wersja modelu DeepSeek R1, która została poddana dalszemu treningowi, aby dostarczać nieocenzurowane, bezstronne informacje faktograficzne."
},
+9
View File
@@ -245,6 +245,9 @@
"Qwen/QVQ-72B-Preview": {
"description": "QVQ-72B-Preview é um modelo de pesquisa desenvolvido pela equipe Qwen, focado em capacidades de raciocínio visual, apresentando vantagens únicas na compreensão de cenários complexos e na resolução de problemas matemáticos relacionados à visão."
},
"Qwen/QwQ-32B": {
"description": "QwQ é o modelo de inferência da série Qwen. Em comparação com modelos tradicionais de ajuste de instruções, o QwQ possui habilidades de raciocínio e inferência, permitindo um desempenho significativamente melhorado em tarefas de downstream, especialmente na resolução de problemas difíceis. O QwQ-32B é um modelo de inferência de médio porte, capaz de obter um desempenho competitivo em comparação com modelos de inferência de ponta, como DeepSeek-R1 e o1-mini. Este modelo utiliza tecnologias como RoPE, SwiGLU, RMSNorm e viés de atenção QKV, apresentando uma estrutura de rede de 64 camadas e 40 cabeças de atenção Q (sendo KV 8 no GQA)."
},
"Qwen/QwQ-32B-Preview": {
"description": "QwQ-32B-Preview é o mais recente modelo de pesquisa experimental da Qwen, focado em melhorar a capacidade de raciocínio da IA. Ao explorar mecanismos complexos como mistura de linguagem e raciocínio recursivo, suas principais vantagens incluem forte capacidade de análise de raciocínio, habilidades matemáticas e de programação. Ao mesmo tempo, existem questões de troca de linguagem, ciclos de raciocínio, considerações de segurança e diferenças em outras capacidades."
},
@@ -1637,9 +1640,15 @@
"qwq": {
"description": "QwQ é um modelo de pesquisa experimental, focado em melhorar a capacidade de raciocínio da IA."
},
"qwq-32b": {
"description": "Modelo de inferência QwQ treinado com base no modelo Qwen2.5-32B, que melhorou significativamente a capacidade de inferência do modelo através de aprendizado por reforço. Os indicadores principais do modelo, como código matemático (AIME 24/25, LiveCodeBench) e alguns indicadores gerais (IFEval, LiveBench, etc.), alcançaram o nível do DeepSeek-R1 versão completa, com todos os indicadores superando significativamente o DeepSeek-R1-Distill-Qwen-32B, que também é baseado no Qwen2.5-32B."
},
"qwq-32b-preview": {
"description": "O modelo QwQ é um modelo de pesquisa experimental desenvolvido pela equipe Qwen, focado em aprimorar a capacidade de raciocínio da IA."
},
"qwq-plus-latest": {
"description": "Modelo de inferência QwQ treinado com base no modelo Qwen2.5, que melhorou significativamente a capacidade de inferência do modelo através de aprendizado por reforço. Os indicadores principais do modelo, como código matemático (AIME 24/25, LiveCodeBench) e alguns indicadores gerais (IFEval, LiveBench, etc.), alcançaram o nível do DeepSeek-R1 versão completa."
},
"r1-1776": {
"description": "R1-1776 é uma versão do modelo DeepSeek R1, treinada posteriormente para fornecer informações factuais não filtradas e imparciais."
},
+9
View File
@@ -245,6 +245,9 @@
"Qwen/QVQ-72B-Preview": {
"description": "QVQ-72B-Preview — это исследовательская модель, разработанная командой Qwen, сосредоточенная на способностях визуального вывода, обладающая уникальными преимуществами в понимании сложных сцен и решении визуально связанных математических задач."
},
"Qwen/QwQ-32B": {
"description": "QwQ — это модель вывода из серии Qwen. В отличие от традиционных моделей, настроенных на инструкции, QwQ обладает способностями к мышлению и рассуждению, что позволяет значительно улучшить производительность в задачах нижнего уровня, особенно при решении сложных проблем. QwQ-32B — это средняя модель вывода, которая демонстрирует конкурентоспособные результаты в сравнении с самыми современными моделями вывода (такими как DeepSeek-R1, o1-mini). Эта модель использует технологии RoPE, SwiGLU, RMSNorm и Attention QKV bias, имеет 64-слойную архитектуру и 40 голов внимания Q (в архитектуре GQA KV составляет 8)."
},
"Qwen/QwQ-32B-Preview": {
"description": "QwQ-32B-Preview — это последняя экспериментальная исследовательская модель Qwen, сосредоточенная на повышении возможностей вывода ИИ. Исследуя сложные механизмы, такие как смешение языков и рекурсивные выводы, основные преимущества включают мощные аналитические способности, математические и программные навыки. В то же время существуют проблемы с переключением языков, циклом вывода, соображениями безопасности и различиями в других способностях."
},
@@ -1637,9 +1640,15 @@
"qwq": {
"description": "QwQ — это экспериментальная исследовательская модель, сосредоточенная на повышении возможностей вывода ИИ."
},
"qwq-32b": {
"description": "Модель вывода QwQ, обученная на модели Qwen2.5-32B, значительно улучшила свои способности вывода благодаря обучению с подкреплением. Основные показатели модели, такие как математический код и другие ключевые метрики (AIME 24/25, LiveCodeBench), а также некоторые общие показатели (IFEval, LiveBench и др.) достигли уровня DeepSeek-R1 в полной мере, при этом все показатели значительно превышают аналогичные показатели DeepSeek-R1-Distill-Qwen-32B, также основанной на Qwen2.5-32B."
},
"qwq-32b-preview": {
"description": "Модель QwQ — это экспериментальная исследовательская модель, разработанная командой Qwen, сосредоточенная на улучшении возможностей вывода ИИ."
},
"qwq-plus-latest": {
"description": "Модель вывода QwQ, обученная на модели Qwen2.5, значительно улучшила свои способности вывода благодаря обучению с подкреплением. Основные показатели модели, такие как математический код и другие ключевые метрики (AIME 24/25, LiveCodeBench), а также некоторые общие показатели (IFEval, LiveBench и др.) достигли уровня DeepSeek-R1 в полной мере."
},
"r1-1776": {
"description": "R1-1776 — это версия модели DeepSeek R1, прошедшая дообучение, которая предоставляет непроверенную, беспристрастную фактическую информацию."
},
+9
View File
@@ -245,6 +245,9 @@
"Qwen/QVQ-72B-Preview": {
"description": "QVQ-72B-Preview, Qwen ekibi tarafından geliştirilen ve görsel çıkarım yeteneklerine odaklanan bir araştırma modelidir. Karmaşık sahne anlayışı ve görsel ile ilgili matematiksel sorunları çözme konusundaki benzersiz avantajları ile dikkat çekmektedir."
},
"Qwen/QwQ-32B": {
"description": "QwQ, Qwen serisinin çıkarım modelidir. Geleneksel talimat ayarlama modellerine kıyasla, QwQ düşünme ve çıkarım yeteneğine sahiptir ve özellikle zor problemleri çözme konusunda önemli ölçüde artırılmış performans sergileyebilir. QwQ-32B, orta ölçekli bir çıkarım modelidir ve en son çıkarım modelleri (örneğin, DeepSeek-R1, o1-mini) ile karşılaştırıldığında rekabetçi bir performans elde edebilir. Bu model, RoPE, SwiGLU, RMSNorm ve Attention QKV bias gibi teknikleri kullanmakta olup, 64 katmanlı bir ağ yapısına ve 40 Q dikkat başlığına (GQA mimarisinde KV 8'dir) sahiptir."
},
"Qwen/QwQ-32B-Preview": {
"description": "QwQ-32B-Preview, Qwen'in en son deneysel araştırma modelidir ve AI akıl yürütme yeteneklerini artırmaya odaklanmaktadır. Dil karışımı, özyinelemeli akıl yürütme gibi karmaşık mekanizmaları keşfederek, güçlü akıl yürütme analizi, matematik ve programlama yetenekleri gibi ana avantajlar sunmaktadır. Bununla birlikte, dil geçiş sorunları, akıl yürütme döngüleri, güvenlik endişeleri ve diğer yetenek farklılıkları gibi zorluklar da bulunmaktadır."
},
@@ -1637,9 +1640,15 @@
"qwq": {
"description": "QwQ, AI akıl yürütme yeteneklerini artırmaya odaklanan deneysel bir araştırma modelidir."
},
"qwq-32b": {
"description": "Qwen2.5-32B modeli üzerine eğitilmiş QwQ çıkarım modeli, pekiştirmeli öğrenme ile modelin çıkarım yeteneğini önemli ölçüde artırmıştır. Modelin matematiksel kodları ve diğer temel göstergeleri (AIME 24/25, LiveCodeBench) ile bazı genel göstergeleri (IFEval, LiveBench vb.) DeepSeek-R1 tam sürüm seviyesine ulaşmıştır ve tüm göstergeler, yine Qwen2.5-32B tabanlı olan DeepSeek-R1-Distill-Qwen-32B'yi önemli ölçüde aşmaktadır."
},
"qwq-32b-preview": {
"description": "QwQ modeli, Qwen ekibi tarafından geliştirilen deneysel bir araştırma modelidir ve AI akıl yürütme yeteneklerini artırmaya odaklanmaktadır."
},
"qwq-plus-latest": {
"description": "Qwen2.5 modeli üzerine eğitilmiş QwQ çıkarım modeli, pekiştirmeli öğrenme ile modelin çıkarım yeteneğini önemli ölçüde artırmıştır. Modelin matematiksel kodları ve diğer temel göstergeleri (AIME 24/25, LiveCodeBench) ile bazı genel göstergeleri (IFEval, LiveBench vb.) DeepSeek-R1 tam sürüm seviyesine ulaşmıştır."
},
"r1-1776": {
"description": "R1-1776, DeepSeek R1 modelinin bir versiyonudur ve son eğitimle, sansürsüz, tarafsız gerçek bilgileri sunar."
},
+9
View File
@@ -245,6 +245,9 @@
"Qwen/QVQ-72B-Preview": {
"description": "QVQ-72B-Preview là một mô hình nghiên cứu do đội ngũ Qwen phát triển, tập trung vào khả năng suy diễn hình ảnh, có lợi thế độc đáo trong việc hiểu các cảnh phức tạp và giải quyết các vấn đề toán học liên quan đến hình ảnh."
},
"Qwen/QwQ-32B": {
"description": "QwQ là mô hình suy diễn của dòng Qwen. So với các mô hình tinh chỉnh theo chỉ dẫn truyền thống, QwQ có khả năng tư duy và suy diễn, có thể đạt được hiệu suất được cải thiện đáng kể trong các nhiệm vụ hạ nguồn, đặc biệt là trong việc giải quyết các vấn đề khó khăn. QwQ-32B là mô hình suy diễn trung bình, có thể đạt được hiệu suất cạnh tranh khi so sánh với các mô hình suy diễn tiên tiến nhất (như DeepSeek-R1, o1-mini). Mô hình này sử dụng các công nghệ như RoPE, SwiGLU, RMSNorm và Attention QKV bias, có cấu trúc mạng 64 lớp và 40 đầu chú ý Q (trong kiến trúc GQA, KV là 8)."
},
"Qwen/QwQ-32B-Preview": {
"description": "QwQ-32B-Preview là mô hình nghiên cứu thử nghiệm mới nhất của Qwen, tập trung vào việc nâng cao khả năng suy luận của AI. Thông qua việc khám phá các cơ chế phức tạp như trộn ngôn ngữ và suy luận đệ quy, những lợi thế chính bao gồm khả năng phân tích suy luận mạnh mẽ, khả năng toán học và lập trình. Tuy nhiên, cũng có những vấn đề về chuyển đổi ngôn ngữ, vòng lặp suy luận, các vấn đề an toàn và sự khác biệt về các khả năng khác."
},
@@ -1637,9 +1640,15 @@
"qwq": {
"description": "QwQ là một mô hình nghiên cứu thử nghiệm, tập trung vào việc nâng cao khả năng suy luận của AI."
},
"qwq-32b": {
"description": "Mô hình suy diễn QwQ được đào tạo dựa trên mô hình Qwen2.5-32B, đã được cải thiện đáng kể khả năng suy diễn của mô hình thông qua học tăng cường. Các chỉ số cốt lõi của mô hình như mã toán (AIME 24/25, LiveCodeBench) và một số chỉ số chung (IFEval, LiveBench, v.v.) đạt đến mức độ của phiên bản đầy đủ DeepSeek-R1, tất cả các chỉ số đều vượt trội so với DeepSeek-R1-Distill-Qwen-32B cũng dựa trên Qwen2.5-32B."
},
"qwq-32b-preview": {
"description": "Mô hình QwQ là một mô hình nghiên cứu thử nghiệm được phát triển bởi đội ngũ Qwen, tập trung vào việc nâng cao khả năng suy luận của AI."
},
"qwq-plus-latest": {
"description": "Mô hình suy diễn QwQ được đào tạo dựa trên mô hình Qwen2.5, đã được cải thiện đáng kể khả năng suy diễn của mô hình thông qua học tăng cường. Các chỉ số cốt lõi của mô hình như mã toán (AIME 24/25, LiveCodeBench) và một số chỉ số chung (IFEval, LiveBench, v.v.) đạt đến mức độ của phiên bản đầy đủ DeepSeek-R1."
},
"r1-1776": {
"description": "R1-1776 là một phiên bản của mô hình DeepSeek R1, đã được huấn luyện lại, cung cấp thông tin sự thật chưa được kiểm duyệt và không thiên lệch."
},
+9
View File
@@ -245,6 +245,9 @@
"Qwen/QVQ-72B-Preview": {
"description": "QVQ-72B-Preview 是由 Qwen 团队开发的专注于视觉推理能力的研究型模型,其在复杂场景理解和解决视觉相关的数学问题方面具有独特优势。"
},
"Qwen/QwQ-32B": {
"description": "QwQ 是 Qwen 系列的推理模型。与传统的指令调优模型相比,QwQ 具备思考和推理能力,能够在下游任务中实现显著增强的性能,尤其是在解决困难问题方面。QwQ-32B 是中型推理模型,能够在与最先进的推理模型(如 DeepSeek-R1、o1-mini)的对比中取得有竞争力的性能。该模型采用 RoPE、SwiGLU、RMSNorm 和 Attention QKV bias 等技术,具有 64 层网络结构和 40 个 Q 注意力头(GQA 架构中 KV 为 8 个)。"
},
"Qwen/QwQ-32B-Preview": {
"description": "Qwen QwQ 是由 Qwen 团队开发的实验研究模型,专注于提升AI推理能力。"
},
@@ -1637,9 +1640,15 @@
"qwq": {
"description": "QwQ 是一个实验研究模型,专注于提高 AI 推理能力。"
},
"qwq-32b": {
"description": "基于 Qwen2.5-32B 模型训练的 QwQ 推理模型,通过强化学习大幅度提升了模型推理能力。模型数学代码等核心指标(AIME 24/25、LiveCodeBench)以及部分通用指标(IFEval、LiveBench等)达到DeepSeek-R1 满血版水平,各指标均显著超过同样基于 Qwen2.5-32B 的 DeepSeek-R1-Distill-Qwen-32B。"
},
"qwq-32b-preview": {
"description": "QwQ模型是由 Qwen 团队开发的实验性研究模型,专注于增强 AI 推理能力。"
},
"qwq-plus-latest": {
"description": "基于 Qwen2.5 模型训练的 QwQ 推理模型,通过强化学习大幅度提升了模型推理能力。模型数学代码等核心指标(AIME 24/25、LiveCodeBench)以及部分通用指标(IFEval、LiveBench等)达到DeepSeek-R1 满血版水平。"
},
"r1-1776": {
"description": "R1-1776 是 DeepSeek R1 模型的一个版本,经过后训练,可提供未经审查、无偏见的事实信息。"
},
+9
View File
@@ -245,6 +245,9 @@
"Qwen/QVQ-72B-Preview": {
"description": "QVQ-72B-Preview 是由 Qwen 團隊開發的專注於視覺推理能力的研究型模型,其在複雜場景理解和解決視覺相關的數學問題方面具有獨特優勢。"
},
"Qwen/QwQ-32B": {
"description": "QwQ 是 Qwen 系列的推理模型。與傳統的指令調優模型相比,QwQ 具備思考和推理能力,能夠在下游任務中實現顯著增強的性能,尤其是在解決困難問題方面。QwQ-32B 是中型推理模型,能夠在與最先進的推理模型(如 DeepSeek-R1、o1-mini)的對比中取得有競爭力的性能。該模型採用 RoPE、SwiGLU、RMSNorm 和 Attention QKV bias 等技術,具有 64 層網絡結構和 40 個 Q 注意力頭(GQA 架構中 KV 為 8 個)。"
},
"Qwen/QwQ-32B-Preview": {
"description": "QwQ-32B-Preview是Qwen 最新的實驗性研究模型,專注於提升AI推理能力。通過探索語言混合、遞歸推理等複雜機制,主要優勢包括強大的推理分析能力、數學和編程能力。與此同時,也存在語言切換問題、推理循環、安全性考量、其他能力方面的差異。"
},
@@ -1637,9 +1640,15 @@
"qwq": {
"description": "QwQ 是一個實驗研究模型,專注於提高 AI 推理能力。"
},
"qwq-32b": {
"description": "基於 Qwen2.5-32B 模型訓練的 QwQ 推理模型,通過強化學習大幅度提升了模型推理能力。模型數學代碼等核心指標(AIME 24/25、LiveCodeBench)以及部分通用指標(IFEval、LiveBench等)達到 DeepSeek-R1 滿血版水平,各指標均顯著超過同樣基於 Qwen2.5-32B 的 DeepSeek-R1-Distill-Qwen-32B。"
},
"qwq-32b-preview": {
"description": "QwQ模型是由 Qwen 團隊開發的實驗性研究模型,專注於增強 AI 推理能力。"
},
"qwq-plus-latest": {
"description": "基於 Qwen2.5 模型訓練的 QwQ 推理模型,通過強化學習大幅度提升了模型推理能力。模型數學代碼等核心指標(AIME 24/25、LiveCodeBench)以及部分通用指標(IFEval、LiveBench等)達到 DeepSeek-R1 滿血版水平。"
},
"r1-1776": {
"description": "R1-1776 是 DeepSeek R1 模型的一個版本,經過後訓練,可提供未經審查、無偏見的事實資訊。"
},
+1
View File
@@ -25,6 +25,7 @@ const nextConfig: NextConfig = {
'@lobehub/ui',
'gpt-tokenizer',
],
reactCompiler: true,
webVitalsAttribution: ['CLS', 'LCP'],
webpackMemoryOptimizations: true,
},
+6 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@lobehub/chat",
"version": "1.69.0",
"version": "1.69.4",
"description": "Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
"keywords": [
"framework",
@@ -122,7 +122,7 @@
"@cyntler/react-doc-viewer": "^1.17.0",
"@electric-sql/pglite": "0.2.13",
"@google-cloud/vertexai": "^1.9.2",
"@google/generative-ai": "^0.22.0",
"@google/generative-ai": "^0.24.0",
"@huggingface/inference": "^2.8.1",
"@icons-pack/react-simple-icons": "9.6.0",
"@khmyznikov/pwa-install": "0.3.9",
@@ -133,7 +133,7 @@
"@lobehub/chat-plugins-gateway": "^1.9.0",
"@lobehub/icons": "^1.73.1",
"@lobehub/tts": "^1.28.0",
"@lobehub/ui": "^1.165.2",
"@lobehub/ui": "^1.165.5",
"@neondatabase/serverless": "^0.10.4",
"@next/third-parties": "^15.2.0",
"@react-spring/web": "^9.7.5",
@@ -165,7 +165,7 @@
"epub2": "^3.0.2",
"fast-deep-equal": "^3.1.3",
"file-type": "^20.0.0",
"framer-motion": "^11.16.0",
"framer-motion": "^12.0.0",
"gpt-tokenizer": "^2.8.1",
"html-to-text": "^9.0.5",
"i18next": "^24.2.1",
@@ -180,7 +180,7 @@
"langfuse": "3.29.1",
"langfuse-core": "3.29.1",
"lodash-es": "^4.17.21",
"lucide-react": "^0.477.0",
"lucide-react": "^0.479.0",
"mammoth": "^1.9.0",
"mdast-util-to-markdown": "^2.1.2",
"modern-screenshot": "^4.5.5",
@@ -286,6 +286,7 @@
"@types/ws": "^8.5.13",
"@vitest/coverage-v8": "~1.2.2",
"ajv-keywords": "^5.1.0",
"babel-plugin-react-compiler": "19.0.0-beta-21e868a-20250216",
"commitlint": "^19.6.1",
"consola": "^3.3.3",
"crypto-js": "^4.2.0",
+2 -1
View File
@@ -8,6 +8,7 @@
"@mozilla/readability": "^0.5.0",
"happy-dom": "^17.0.0",
"node-html-markdown": "^1.3.0",
"query-string": "^9.1.1"
"query-string": "^9.1.1",
"url-join": "^5"
}
}
@@ -0,0 +1,94 @@
import { describe, expect, it, vi } from 'vitest';
import { browserless } from '../browserless';
describe('browserless', () => {
it('should throw BrowserlessInitError when env vars not set', async () => {
const originalEnv = { ...process.env };
process.env = { ...originalEnv };
delete process.env.BROWSERLESS_URL;
delete process.env.BROWSERLESS_TOKEN;
await expect(browserless('https://example.com', { filterOptions: {} })).rejects.toThrow(
'`BROWSERLESS_URL` or `BROWSERLESS_TOKEN` are required',
);
process.env = originalEnv;
});
it('should return undefined on fetch error', async () => {
process.env.BROWSERLESS_TOKEN = 'test-token';
global.fetch = vi.fn().mockRejectedValue(new Error('Fetch error'));
const result = await browserless('https://example.com', { filterOptions: {} });
expect(result).toBeUndefined();
});
it('should return undefined when content is empty', async () => {
process.env.BROWSERLESS_TOKEN = 'test-token';
global.fetch = vi.fn().mockResolvedValue({
text: vi.fn().mockResolvedValue('<html></html>'),
} as any);
const result = await browserless('https://example.com', { filterOptions: {} });
expect(result).toBeUndefined();
});
it('should return undefined when title is "Just a moment..."', async () => {
process.env.BROWSERLESS_TOKEN = 'test-token';
global.fetch = vi.fn().mockResolvedValue({
text: vi.fn().mockResolvedValue('<html><title>Just a moment...</title></html>'),
} as any);
const result = await browserless('https://example.com', { filterOptions: {} });
expect(result).toBeUndefined();
});
it('should return crawl result on successful fetch', async () => {
process.env.BROWSERLESS_TOKEN = 'test-token';
global.fetch = vi.fn().mockResolvedValue({
text: vi.fn().mockResolvedValue(`
<html>
<head>
<title>Test Title</title>
<meta name="description" content="Test Description">
</head>
<body>
<h1>Test Content</h1>
</body>
</html>
`),
} as any);
const result = await browserless('https://example.com', { filterOptions: {} });
expect(result).toEqual({
content: expect.any(String),
contentType: 'text',
description: expect.any(String),
length: expect.any(Number),
siteName: null,
title: 'Test Title',
url: 'https://example.com',
});
});
it('should use correct URL when BROWSERLESS_URL is provided', async () => {
const customUrl = 'https://custom.browserless.io';
const originalEnv = { ...process.env };
process.env.BROWSERLESS_TOKEN = 'test-token';
process.env.BROWSERLESS_URL = customUrl;
global.fetch = vi.fn().mockImplementation((url) => {
expect(url).toContain(customUrl);
return Promise.resolve({
text: () => Promise.resolve('<html><title>Test</title></html>'),
});
});
await browserless('https://example.com', { filterOptions: {} });
expect(global.fetch).toHaveBeenCalled();
process.env = originalEnv;
});
});
@@ -1,4 +1,5 @@
import qs from 'query-string';
import urlJoin from 'url-join';
import { CrawlImpl, CrawlSuccessResult } from '../type';
import { htmlToMarkdown } from '../utils/htmlToMarkdown';
@@ -25,7 +26,7 @@ export const browserless: CrawlImpl = async (url, { filterOptions }) => {
try {
const res = await fetch(
qs.stringifyUrl({ query: { token: BROWSERLESS_TOKEN }, url: `${BASE_URL}/content` }),
qs.stringifyUrl({ query: { token: BROWSERLESS_TOKEN }, url: urlJoin(BASE_URL, '/content') }),
{
body: JSON.stringify(input),
headers: {
+6
View File
@@ -61,4 +61,10 @@ export const crawUrlRules: CrawlUrlRule[] = [
},
urlPattern: 'https://www.qiumiwu.com/standings/(.*)',
},
// mozilla use jina
{
impls: ['jina'],
urlPattern: 'https://developer.mozilla.org(.*)',
},
];
@@ -0,0 +1,161 @@
'use client';
import { LobeChat } from '@lobehub/ui/brand';
import { Button, Col, Flex, Row, Skeleton, Typography } from 'antd';
import { createStyles } from 'antd-style';
import { AuthError } from 'next-auth';
import { signIn } from 'next-auth/react';
import { useRouter, useSearchParams } from 'next/navigation';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
import BrandWatermark from '@/components/BrandWatermark';
import AuthIcons from '@/components/NextAuth/AuthIcons';
import { DOCUMENTS_REFER_URL, PRIVACY_URL, TERMS_URL } from '@/const/url';
import { useUserStore } from '@/store/user';
const { Title, Paragraph } = Typography;
const useStyles = createStyles(({ css, token }) => ({
button: css`
text-transform: capitalize;
`,
container: css`
min-width: 360px;
border: 1px solid ${token.colorBorder};
border-radius: ${token.borderRadiusLG}px;
background: ${token.colorBgContainer};
`,
contentCard: css`
padding-block: 2.5rem;
padding-inline: 2rem;
`,
description: css`
margin: 0;
color: ${token.colorTextSecondary};
`,
footer: css`
padding: 1rem;
border-block-start: 1px solid ${token.colorBorder};
border-radius: 0 0 8px 8px;
color: ${token.colorTextDescription};
background: ${token.colorBgElevated};
`,
text: css`
text-align: center;
`,
title: css`
margin: 0;
color: ${token.colorTextHeading};
`,
}));
const BtnListLoading = memo(() => {
return (
<Flex gap={'small'} vertical>
<Skeleton.Button active style={{ minWidth: 300 }} />
<Skeleton.Button active style={{ minWidth: 300 }} />
<Skeleton.Button active style={{ minWidth: 300 }} />
</Flex>
);
});
/**
* Follow the implementation from AuthJS official documentation,
* but using client components.
* ref: https://authjs.dev/guides/pages/signin
*/
export default memo(() => {
const { styles } = useStyles();
const { t } = useTranslation('clerk');
const router = useRouter();
const oAuthSSOProviders = useUserStore((s) => s.oAuthSSOProviders);
const searchParams = useSearchParams();
// Redirect back to the page url
const callbackUrl = searchParams.get('callbackUrl') ?? '';
const handleSignIn = async (provider: string) => {
try {
await signIn(provider, { redirectTo: callbackUrl });
} catch (error) {
// Signin can fail for a number of reasons, such as the user
// not existing, or the user not having the correct role.
// In some cases, you may want to redirect to a custom error
if (error instanceof AuthError) {
return router.push(`/next-auth/?error=${error.type}`);
}
// Otherwise if a redirects happens Next.js can handle it
// so you can just re-thrown the error and let Next.js handle it.
// Docs: https://nextjs.org/docs/app/api-reference/functions/redirect#server-component
throw error;
}
};
const footerBtns = [
{ href: DOCUMENTS_REFER_URL, id: 0, label: t('footerPageLink__help') },
{ href: PRIVACY_URL, id: 1, label: t('footerPageLink__privacy') },
{ href: TERMS_URL, id: 2, label: t('footerPageLink__terms') },
];
return (
<div className={styles.container}>
<div className={styles.contentCard}>
{/* Card Body */}
<Flex gap="large" vertical>
{/* Header */}
<div className={styles.text}>
<Title className={styles.title} level={4}>
<div>
<LobeChat size={48} />
</div>
{t('signIn.start.title', { applicationName: 'LobeChat' })}
</Title>
<Paragraph className={styles.description}>{t('signIn.start.subtitle')}</Paragraph>
</div>
{/* Content */}
<Flex gap="small" vertical>
{oAuthSSOProviders ? (
oAuthSSOProviders.map((provider) => (
<Button
className={styles.button}
icon={AuthIcons(provider, 16)}
key={provider}
onClick={() => handleSignIn(provider)}
>
{provider}
</Button>
))
) : (
<BtnListLoading />
)}
</Flex>
</Flex>
</div>
<div className={styles.footer}>
{/* Footer */}
<Row>
<Col span={12}>
<Flex justify="left" style={{ height: '100%' }}>
<BrandWatermark />
</Flex>
</Col>
<Col offset={4} span={8}>
<Flex justify="right">
{footerBtns.map((btn) => (
<Button key={btn.id} onClick={() => router.push(btn.href)} size="small" type="text">
{btn.label}
</Button>
))}
</Flex>
</Col>
</Row>
</div>
</div>
);
});
@@ -0,0 +1,11 @@
import { Suspense } from 'react';
import Loading from '@/components/Loading/BrandTextLoading';
import AuthSignInBox from './AuthSignInBox';
export default () => (
<Suspense fallback={<Loading />}>
<AuthSignInBox />
</Suspense>
);
@@ -0,0 +1,31 @@
'use client';
import { useSearchParams } from 'next/navigation';
import { useEffect } from 'react';
import { useSendMessage } from '@/features/ChatInput/useSend';
import { useChatStore } from '@/store/chat';
const MessageFromUrl = () => {
const updateInputMessage = useChatStore((s) => s.updateInputMessage);
const { send: sendMessage } = useSendMessage();
const searchParams = useSearchParams();
useEffect(() => {
const message = searchParams.get('message');
if (message) {
// Remove message from URL
const params = new URLSearchParams(searchParams.toString());
params.delete('message');
const newUrl = `${window.location.pathname}?${params.toString()}`;
window.history.replaceState({}, '', newUrl);
updateInputMessage(message);
sendMessage();
}
}, [searchParams, updateInputMessage, sendMessage]);
return null;
};
export default MessageFromUrl;
@@ -1,7 +1,7 @@
import { Button, Space } from 'antd';
import { createStyles } from 'antd-style';
import { rgba } from 'polished';
import { memo, useEffect, useState } from 'react';
import { Suspense, memo, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Flexbox } from 'react-layout-kit';
@@ -13,6 +13,7 @@ import { useChatStore } from '@/store/chat';
import { chatSelectors } from '@/store/chat/selectors';
import { isMacOS } from '@/utils/platform';
import MessageFromUrl from './MessageFromUrl';
import SendMore from './SendMore';
import ShortcutHint from './ShortcutHint';
@@ -67,49 +68,54 @@ const Footer = memo<FooterProps>(({ onExpandChange, expand }) => {
}, [setIsMac]);
return (
<Flexbox
align={'end'}
className={styles.overrideAntdIcon}
distribution={'space-between'}
flex={'none'}
gap={8}
horizontal
padding={'0 24px'}
>
<Flexbox align={'center'} gap={8} horizontal style={{ overflow: 'hidden' }}>
{expand && <LocalFiles />}
</Flexbox>
<Flexbox align={'center'} flex={'none'} gap={8} horizontal>
<ShortcutHint />
<SaveTopic />
<Flexbox style={{ minWidth: 92 }}>
{isAIGenerating ? (
<Button
className={styles.loadingButton}
icon={<StopLoadingIcon />}
onClick={stopGenerateMessage}
>
{t('input.stop')}
</Button>
) : (
<Space.Compact>
<>
<Suspense fallback={null}>
<MessageFromUrl />
</Suspense>
<Flexbox
align={'end'}
className={styles.overrideAntdIcon}
distribution={'space-between'}
flex={'none'}
gap={8}
horizontal
padding={'0 24px'}
>
<Flexbox align={'center'} gap={8} horizontal style={{ overflow: 'hidden' }}>
{expand && <LocalFiles />}
</Flexbox>
<Flexbox align={'center'} flex={'none'} gap={8} horizontal>
<ShortcutHint />
<SaveTopic />
<Flexbox style={{ minWidth: 92 }}>
{isAIGenerating ? (
<Button
disabled={!canSend}
loading={!canSend}
onClick={() => {
sendMessage();
onExpandChange?.(false);
}}
type={'primary'}
className={styles.loadingButton}
icon={<StopLoadingIcon />}
onClick={stopGenerateMessage}
>
{t('input.send')}
{t('input.stop')}
</Button>
<SendMore disabled={!canSend} isMac={isMac} />
</Space.Compact>
)}
) : (
<Space.Compact>
<Button
disabled={!canSend}
loading={!canSend}
onClick={() => {
sendMessage();
onExpandChange?.(false);
}}
type={'primary'}
>
{t('input.send')}
</Button>
<SendMore disabled={!canSend} isMac={isMac} />
</Space.Compact>
)}
</Flexbox>
</Flexbox>
</Flexbox>
</Flexbox>
</>
);
});
@@ -10,7 +10,7 @@ import { userService } from '@/services/user';
import { useUserStore } from '@/store/user';
import { userProfileSelectors } from '@/store/user/selectors';
import AuthIcons from './AuthIcons';
import AuthIcons from '@/components/NextAuth/AuthIcons';
const { Item } = List;
@@ -12,10 +12,6 @@ import {
} from '@lobehub/ui/icons';
import React from 'react';
const iconProps = {
size: 32,
};
const iconComponents: { [key: string]: React.ElementType } = {
'auth0': Auth0,
'authelia': Authelia.Color,
@@ -29,9 +25,15 @@ const iconComponents: { [key: string]: React.ElementType } = {
'zitadel': Zitadel.Color,
};
const AuthIcons = (id: string) => {
/**
* Get the auth icons component for the given id
* @param id
* @param size default is 36
* @returns
*/
const AuthIcons = (id: string, size = 36) => {
const IconComponent = iconComponents[id] || iconComponents.default;
return <IconComponent {...iconProps} />;
return <IconComponent size={size}/>;
};
export default AuthIcons;
-1
View File
@@ -118,7 +118,6 @@ const googleChatModels: AIChatModelCard[] = [
description:
'Gemini 2.0 Flash Thinking Exp 是 Google 的实验性多模态推理AI模型,能对复杂问题进行推理,拥有新的思维能力。',
displayName: 'Gemini 2.0 Flash Thinking Experimental',
enabled: true,
id: 'gemini-2.0-flash-thinking-exp',
maxOutput: 65_536,
pricing: {
+14
View File
@@ -4,6 +4,20 @@ import { AIChatModelCard } from '@/types/aiModel';
// https://console.groq.com/docs/models
const groqChatModels: AIChatModelCard[] = [
{
abilities: {
functionCall: true,
reasoning: true,
},
contextWindowTokens: 131_072,
displayName: 'Qwen QwQ 32B',
id: 'qwen-qwq-32b',
pricing: {
input: 0.29,
output: 0.39,
},
type: 'chat',
},
{
abilities: {
functionCall: true,
+36
View File
@@ -150,6 +150,29 @@ const novitaChatModels: AIChatModelCard[] = [
},
type: 'chat',
},
{
contextWindowTokens: 64_000,
displayName: 'Deepseek V3 Turbo',
id: 'deepseek/deepseek-v3-turbo',
pricing: {
input: 0.4,
output: 1.3,
},
type: 'chat',
},
{
abilities: {
reasoning: true,
},
contextWindowTokens: 64_000,
displayName: 'Deepseek R1 Turbo',
id: 'deepseek/deepseek-r1-turbo',
pricing: {
input: 0.7,
output: 2.5,
},
type: 'chat',
},
{
abilities: {
reasoning: true,
@@ -378,6 +401,19 @@ const novitaChatModels: AIChatModelCard[] = [
},
type: 'chat',
},
{
abilities: {
reasoning: true,
},
contextWindowTokens: 32_768,
displayName: 'QwQ 32B',
id: 'qwen/qwq-32b',
pricing: {
input: 0.18,
output: 0.2,
},
type: 'chat',
},
];
export const allModels = [...novitaChatModels];
+26 -1
View File
@@ -137,6 +137,31 @@ const openrouterChatModels: AIChatModelCard[] = [
releasedAt: '2024-06-20',
type: 'chat',
},
{
abilities: {
functionCall: true,
reasoning: true,
vision: true,
},
contextWindowTokens: 200_000,
description:
'Claude 3.7 Sonnet 是 Anthropic 迄今为止最智能的模型,也是市场上首个混合推理模型。Claude 3.7 Sonnet 可以产生近乎即时的响应或延长的逐步思考,用户可以清晰地看到这些过程。Sonnet 特别擅长编程、数据科学、视觉处理、代理任务。',
displayName: 'Claude 3.7 Sonnet',
enabled: true,
id: 'anthropic/claude-3.7-sonnet',
maxOutput: 8192,
pricing: {
cachedInput: 0.3,
input: 3,
output: 15,
writeCacheInput: 3.75,
},
releasedAt: '2025-02-24',
settings: {
extendParams: ['enableReasoning', 'reasoningBudgetToken'],
},
type: 'chat',
},
{
abilities: {
functionCall: true,
@@ -258,7 +283,7 @@ const openrouterChatModels: AIChatModelCard[] = [
id: 'deepseek/deepseek-r1:free',
releasedAt: '2025-01-20',
type: 'chat',
},
},
{
abilities: {
vision: true,
+18 -2
View File
@@ -226,9 +226,25 @@ const siliconcloudChatModels: AIChatModelCard[] = [
},
contextWindowTokens: 32_768,
description:
'QwQ-32B-Preview是Qwen 最新的实验性研究模型,专注于提升AI推理能力。通过探索语言混合、递归推理等复杂机制,主要优势包括强大的推理分析能力、数学和编程能力。与此同时,也存在语言切换问题、推理循环、安全性考虑、其他能力方面的差异。',
displayName: 'QwQ 32B Preview',
'QwQ 是 Qwen 系列的推理模型。与传统的指令调优模型相比,QwQ 具备思考和推理能力,能够在下游任务中实现显著增强的性能,尤其是在解决困难问题方面。QwQ-32B 是中型推理模型,能够在与最先进的推理模型(如 DeepSeek-R1、o1-mini)的对比中取得有竞争力的性能。该模型采用 RoPE、SwiGLU、RMSNorm 和 Attention QKV bias 等技术,具有 64 层网络结构和 40 个 Q 注意力头(GQA 架构中 KV 为 8 个)。',
displayName: 'QwQ 32B',
enabled: true,
id: 'Qwen/QwQ-32B',
pricing: {
currency: 'CNY',
input: 1,
output: 4,
},
type: 'chat',
},
{
abilities: {
reasoning: true,
},
contextWindowTokens: 32_768,
description:
'QwQ-32B-Preview 是 Qwen 最新的实验性研究模型,专注于提升AI推理能力。通过探索语言混合、递归推理等复杂机制,主要优势包括强大的推理分析能力、数学和编程能力。与此同时,也存在语言切换问题、推理循环、安全性考虑、其他能力方面的差异。',
displayName: 'QwQ 32B Preview',
id: 'Qwen/QwQ-32B-Preview',
pricing: {
currency: 'CNY',
@@ -112,12 +112,6 @@ const ModelCard = memo<ModelCardProps>(({ pricing, id, provider, displayName })
</Flexbox>
</Tooltip>
)}
<Tooltip title={t('messages.modelCard.pricing.inputTokens', { amount: inputPrice })}>
<Flexbox gap={2} horizontal>
<Icon icon={ArrowUpFromDot} />
{inputPrice}
</Flexbox>
</Tooltip>
{pricing?.writeCacheInput && (
<Tooltip
title={t('messages.modelCard.pricing.writeCacheInputTokens', {
@@ -130,6 +124,12 @@ const ModelCard = memo<ModelCardProps>(({ pricing, id, provider, displayName })
</Flexbox>
</Tooltip>
)}
<Tooltip title={t('messages.modelCard.pricing.inputTokens', { amount: inputPrice })}>
<Flexbox gap={2} horizontal>
<Icon icon={ArrowUpFromDot} />
{inputPrice}
</Flexbox>
</Tooltip>
<Tooltip title={t('messages.modelCard.pricing.outputTokens', { amount: outputPrice })}>
<Flexbox gap={2} horizontal>
<Icon icon={ArrowDownToDot} />
@@ -138,7 +138,7 @@ const TokenDetail = memo<TokenDetailProps>(({ usage, model, provider }) => {
</Flexbox>
)}
{outputDetails.length > 1 && (
<>
<Flexbox gap={4}>
<Flexbox
align={'center'}
gap={4}
@@ -146,12 +146,12 @@ const TokenDetail = memo<TokenDetailProps>(({ usage, model, provider }) => {
justify={'space-between'}
width={'100%'}
>
<div style={{ color: theme.colorTextDescription }}>
<div style={{ color: theme.colorTextDescription, fontSize: 12 }}>
{t('messages.tokenDetails.outputTitle')}
</div>
</Flexbox>
<TokenProgress data={outputDetails} showIcon />
</>
</Flexbox>
)}
<Flexbox>
<TokenProgress data={totalDetail} showIcon />
@@ -0,0 +1,114 @@
import { LobeRuntimeAI } from '../BaseAI';
import { LobeOpenAI } from '../openai';
import { providerRuntimeMap } from '../runtimeMap';
import {
ChatCompetitionOptions,
type ChatCompletionErrorPayload,
ChatStreamPayload,
EmbeddingsOptions,
EmbeddingsPayload,
TextToImagePayload,
TextToSpeechPayload,
} from '../types';
export interface RuntimeItem {
id: string;
models?: string[];
runtime: LobeRuntimeAI;
}
interface ProviderInitParams extends Record<string, any> {
accessKeyId?: string;
accessKeySecret?: string;
apiKey?: string;
apiVersion?: string;
baseURL?: string;
baseURLOrAccountID?: string;
dangerouslyAllowBrowser?: boolean;
region?: string;
sessionToken?: string;
}
interface ProviderInstance {
apiType: keyof typeof providerRuntimeMap;
models?: string[];
params: ProviderInitParams;
runtime?: typeof LobeOpenAI;
}
interface UniformRuntimeOptions {
chat?: {
handleError?: (error: any) => Omit<ChatCompletionErrorPayload, 'provider'> | undefined;
};
}
class UniformRuntime {
private _runtimes: RuntimeItem[];
private _options: UniformRuntimeOptions;
constructor(id: string, providers: ProviderInstance[], options: UniformRuntimeOptions) {
if (providers.length === 0) {
throw new Error('empty providers');
}
this._runtimes = providers.map((options) => {
const providerAI = options.runtime ?? providerRuntimeMap[options.apiType] ?? LobeOpenAI;
const runtime: LobeRuntimeAI = new providerAI({ ...options.params, id });
return { id: options.apiType, models: options.models, runtime };
});
this._options = options;
}
// 检查下是否能匹配到特定模型,否则默认使用第一个 runtime
getRuntimeByModel(model: string) {
const runtimeItem =
this._runtimes.find((runtime) => runtime.models && runtime.models.includes(model)) ||
this._runtimes[0];
return runtimeItem.runtime;
}
async chat(payload: ChatStreamPayload, options?: ChatCompetitionOptions) {
try {
const runtime = this.getRuntimeByModel(payload.model);
return await runtime.chat(payload, options);
} catch (e) {
if (this._options.chat?.handleError) {
const error = this._options.chat.handleError(e);
if (error) {
throw error;
}
}
throw e;
}
}
async textToImage(payload: TextToImagePayload) {
const runtime = this.getRuntimeByModel(payload.model);
return runtime.textToImage?.(payload);
}
async models() {
return this._runtimes[0].runtime.models?.();
}
async embeddings(payload: EmbeddingsPayload, options?: EmbeddingsOptions) {
const runtime = this.getRuntimeByModel(payload.model);
return runtime.embeddings?.(payload, options);
}
async textToSpeech(payload: TextToSpeechPayload, options?: EmbeddingsOptions) {
const runtime = this.getRuntimeByModel(payload.model);
return runtime.textToSpeech?.(payload, options);
}
}
export default UniformRuntime;
@@ -0,0 +1,15 @@
export const handleAnthropicError = (error: any) => {
let errorResult: any = error;
if (error.error) {
errorResult = error.error;
if ('error' in errorResult) {
errorResult = errorResult.error;
}
} else {
errorResult = { headers: error.headers, stack: error.stack, status: error.status };
}
return { errorResult };
};
+10 -1
View File
@@ -44,6 +44,15 @@ describe('LobeAnthropicAI', () => {
expect(instance).toBeInstanceOf(LobeAnthropicAI);
expect(instance.baseURL).toBe('https://api.anthropic.proxy');
});
it('should correctly initialize with different id', async () => {
const instance = new LobeAnthropicAI({
apiKey: 'test_api_key',
id: 'abc',
});
expect(instance).toBeInstanceOf(LobeAnthropicAI);
expect(instance['id']).toBe('abc');
});
});
describe('chat', () => {
@@ -347,7 +356,7 @@ describe('LobeAnthropicAI', () => {
// Assert
expect(e).toEqual({
endpoint: 'https://api.anthropic.com',
error: apiError,
error: apiError.error.error,
errorType: bizErrorType,
provider,
});
+58 -40
View File
@@ -2,18 +2,23 @@
import '@anthropic-ai/sdk/shims/web';
import Anthropic from '@anthropic-ai/sdk';
import { ClientOptions } from 'openai';
import type { ChatModelCard } from '@/types/llm';
import { LobeRuntimeAI } from '../BaseAI';
import { AgentRuntimeErrorType } from '../error';
import { ChatCompetitionOptions, ChatStreamPayload, ModelProvider } from '../types';
import {
ChatCompetitionOptions,
type ChatCompletionErrorPayload,
ChatStreamPayload,
ModelProvider,
} from '../types';
import { AgentRuntimeError } from '../utils/createError';
import { debugStream } from '../utils/debugStream';
import { desensitizeUrl } from '../utils/desensitizeUrl';
import { buildAnthropicMessages, buildAnthropicTools } from '../utils/anthropicHelpers';
import { StreamingResponse } from '../utils/response';
import { AnthropicStream } from '../utils/streams';
import type { ChatModelCard } from '@/types/llm';
import { handleAnthropicError } from './handleAnthropicError';
export interface AnthropicModelCard {
display_name: string;
@@ -22,18 +27,24 @@ export interface AnthropicModelCard {
const DEFAULT_BASE_URL = 'https://api.anthropic.com';
interface AnthropicAIParams extends ClientOptions {
id?: string;
}
export class LobeAnthropicAI implements LobeRuntimeAI {
private client: Anthropic;
baseURL: string;
apiKey?: string;
private id: string;
constructor({ apiKey, baseURL = DEFAULT_BASE_URL, ...res }: ClientOptions = {}) {
constructor({ apiKey, baseURL = DEFAULT_BASE_URL, id, ...res }: AnthropicAIParams = {}) {
if (!apiKey) throw AgentRuntimeError.createError(AgentRuntimeErrorType.InvalidProviderAPIKey);
this.client = new Anthropic({ apiKey, baseURL, ...res });
this.baseURL = this.client.baseURL;
this.apiKey = apiKey;
this.id = id || ModelProvider.Anthropic;
}
async chat(payload: ChatStreamPayload, options?: ChatCompetitionOptions) {
@@ -57,42 +68,7 @@ export class LobeAnthropicAI implements LobeRuntimeAI {
headers: options?.headers,
});
} catch (error) {
let desensitizedEndpoint = this.baseURL;
if (this.baseURL !== DEFAULT_BASE_URL) {
desensitizedEndpoint = desensitizeUrl(this.baseURL);
}
if ('status' in (error as any)) {
switch ((error as Response).status) {
case 401: {
throw AgentRuntimeError.chat({
endpoint: desensitizedEndpoint,
error: error as any,
errorType: AgentRuntimeErrorType.InvalidProviderAPIKey,
provider: ModelProvider.Anthropic,
});
}
case 403: {
throw AgentRuntimeError.chat({
endpoint: desensitizedEndpoint,
error: error as any,
errorType: AgentRuntimeErrorType.LocationNotSupportError,
provider: ModelProvider.Anthropic,
});
}
default: {
break;
}
}
}
throw AgentRuntimeError.chat({
endpoint: desensitizedEndpoint,
error: error as any,
errorType: AgentRuntimeErrorType.ProviderBizError,
provider: ModelProvider.Anthropic,
});
throw this.handleError(error);
}
}
@@ -191,6 +167,48 @@ export class LobeAnthropicAI implements LobeRuntimeAI {
})
.filter(Boolean) as ChatModelCard[];
}
private handleError(error: any): ChatCompletionErrorPayload {
let desensitizedEndpoint = this.baseURL;
if (this.baseURL !== DEFAULT_BASE_URL) {
desensitizedEndpoint = desensitizeUrl(this.baseURL);
}
if ('status' in (error as any)) {
switch ((error as Response).status) {
case 401: {
throw AgentRuntimeError.chat({
endpoint: desensitizedEndpoint,
error: error as any,
errorType: AgentRuntimeErrorType.InvalidProviderAPIKey,
provider: this.id,
});
}
case 403: {
throw AgentRuntimeError.chat({
endpoint: desensitizedEndpoint,
error: error as any,
errorType: AgentRuntimeErrorType.LocationNotSupportError,
provider: this.id,
});
}
default: {
break;
}
}
}
const { errorResult } = handleAnthropicError(error);
throw AgentRuntimeError.chat({
endpoint: desensitizedEndpoint,
error: errorResult,
errorType: AgentRuntimeErrorType.ProviderBizError,
provider: this.id,
});
}
}
export default LobeAnthropicAI;
+7 -1
View File
@@ -13,10 +13,16 @@ import { transformResponseToStream } from '../utils/openaiCompatibleFactory';
import { StreamingResponse } from '../utils/response';
import { OpenAIStream, createSSEDataExtractor } from '../utils/streams';
interface AzureAIParams {
apiKey?: string;
apiVersion?: string;
baseURL?: string;
}
export class LobeAzureAI implements LobeRuntimeAI {
client: ModelClient;
constructor(params?: { apiKey?: string; apiVersion?: string; baseURL?: string }) {
constructor(params?: AzureAIParams) {
if (!params?.apiKey || !params?.baseURL)
throw AgentRuntimeError.createError(AgentRuntimeErrorType.InvalidProviderAPIKey);
+20 -25
View File
@@ -1,9 +1,9 @@
import type { ChatModelCard } from '@/types/llm';
import { AgentRuntimeErrorType } from '../error';
import { pruneReasoningPayload } from '../openai';
import { ModelProvider } from '../types';
import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory';
import type { ChatModelCard } from '@/types/llm';
import { pruneReasoningPayload } from '../utils/openaiHelpers';
export interface GithubModelCard {
description: string;
@@ -39,27 +39,20 @@ export const LobeGithubAI = LobeOpenAICompatibleFactory({
models: async ({ client }) => {
const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels');
const functionCallKeywords = [
'function',
'tool',
];
const functionCallKeywords = ['function', 'tool'];
const visionKeywords = [
'vision',
];
const visionKeywords = ['vision'];
const reasoningKeywords = [
'deepseek-r1',
'o1',
'o3',
];
const reasoningKeywords = ['deepseek-r1', 'o1', 'o3'];
const modelsPage = (await client.models.list()) as any;
const modelList: GithubModelCard[] = modelsPage.body;
return modelList
.map((model) => {
const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.name.toLowerCase() === m.id.toLowerCase());
const knownModel = LOBE_DEFAULT_MODEL_LIST.find(
(m) => model.name.toLowerCase() === m.id.toLowerCase(),
);
return {
contextWindowTokens: knownModel?.contextWindowTokens ?? undefined,
@@ -67,18 +60,20 @@ export const LobeGithubAI = LobeOpenAICompatibleFactory({
displayName: model.friendly_name,
enabled: knownModel?.enabled || false,
functionCall:
functionCallKeywords.some(keyword => model.description.toLowerCase().includes(keyword))
|| knownModel?.abilities?.functionCall
|| false,
functionCallKeywords.some((keyword) =>
model.description.toLowerCase().includes(keyword),
) ||
knownModel?.abilities?.functionCall ||
false,
id: model.name,
reasoning:
reasoningKeywords.some(keyword => model.name.toLowerCase().includes(keyword))
|| knownModel?.abilities?.reasoning
|| false,
reasoningKeywords.some((keyword) => model.name.toLowerCase().includes(keyword)) ||
knownModel?.abilities?.reasoning ||
false,
vision:
visionKeywords.some(keyword => model.description.toLowerCase().includes(keyword))
|| knownModel?.abilities?.vision
|| false,
visionKeywords.some((keyword) => model.description.toLowerCase().includes(keyword)) ||
knownModel?.abilities?.vision ||
false,
};
})
.filter(Boolean) as ChatModelCard[];
+2
View File
@@ -19,6 +19,8 @@ export { LobeQwenAI } from './qwen';
export { LobeTogetherAI } from './togetherai';
export * from './types';
export { AgentRuntimeError } from './utils/createError';
export { LobeOpenAICompatibleFactory } from './utils/openaiCompatibleFactory';
export { pruneReasoningPayload } from './utils/openaiHelpers';
export { LobeVolcengineAI } from './volcengine';
export { LobeZeroOneAI } from './zeroone';
export { LobeZhipuAI } from './zhipu';
@@ -57,9 +57,6 @@ describe('specific LobeMistralAI tests', () => {
messages: [{ content: 'Hello', role: 'user' }],
model: 'open-mistral-7b',
stream: true,
stream_options: {
include_usage: true,
},
temperature: 0.35,
top_p: 1,
},
+10 -7
View File
@@ -1,8 +1,8 @@
import type { ChatModelCard } from '@/types/llm';
import { ModelProvider } from '../types';
import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory';
import type { ChatModelCard } from '@/types/llm';
export interface MistralModelCard {
capabilities: {
function_calling: boolean;
@@ -16,6 +16,9 @@ export interface MistralModelCard {
export const LobeMistralAI = LobeOpenAICompatibleFactory({
baseURL: 'https://api.mistral.ai/v1',
chatCompletion: {
// Mistral API does not support stream_options: { include_usage: true }
// refs: https://github.com/lobehub/lobe-chat/issues/6825
excludeUsage: true,
handlePayload: (payload) => ({
...(payload.max_tokens !== undefined && { max_tokens: payload.max_tokens }),
messages: payload.messages as any,
@@ -33,12 +36,14 @@ export const LobeMistralAI = LobeOpenAICompatibleFactory({
models: async ({ client }) => {
const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels');
const modelsPage = await client.models.list() as any;
const modelsPage = (await client.models.list()) as any;
const modelList: MistralModelCard[] = modelsPage.data;
return modelList
.map((model) => {
const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.toLowerCase() === m.id.toLowerCase());
const knownModel = LOBE_DEFAULT_MODEL_LIST.find(
(m) => model.id.toLowerCase() === m.id.toLowerCase(),
);
return {
contextWindowTokens: model.max_context_length,
@@ -47,9 +52,7 @@ export const LobeMistralAI = LobeOpenAICompatibleFactory({
enabled: knownModel?.enabled || false,
functionCall: model.capabilities.function_calling,
id: model.id,
reasoning:
knownModel?.abilities?.reasoning
|| false,
reasoning: knownModel?.abilities?.reasoning || false,
vision: model.capabilities.vision,
};
})
+2 -22
View File
@@ -1,33 +1,13 @@
import { disableStreamModels, systemToUserModels } from '@/const/models';
import type { ChatModelCard } from '@/types/llm';
import { ChatStreamPayload, ModelProvider, OpenAIChatMessage } from '../types';
import { ModelProvider } from '../types';
import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory';
import { pruneReasoningPayload } from '../utils/openaiHelpers';
export interface OpenAIModelCard {
id: string;
}
export const pruneReasoningPayload = (payload: ChatStreamPayload) => {
return {
...payload,
frequency_penalty: 0,
messages: payload.messages.map((message: OpenAIChatMessage) => ({
...message,
role:
message.role === 'system'
? systemToUserModels.has(payload.model)
? 'user'
: 'developer'
: message.role,
})),
presence_penalty: 0,
stream: !disableStreamModels.has(payload.model),
temperature: 1,
top_p: 1,
};
};
export const LobeOpenAI = LobeOpenAICompatibleFactory({
baseURL: 'https://api.openai.com/v1',
chatCompletion: {
@@ -92,6 +92,39 @@ describe('LobeOpenRouterAI', () => {
expect(result).toBeInstanceOf(Response);
});
it('should add reasoning field when thinking is enabled', async () => {
// Arrange
const mockStream = new ReadableStream();
const mockResponse = Promise.resolve(mockStream);
(instance['client'].chat.completions.create as Mock).mockResolvedValue(mockResponse);
// Act
const result = await instance.chat({
messages: [{ content: 'Hello', role: 'user' }],
model: 'mistralai/mistral-7b-instruct:free',
temperature: 0.7,
thinking: {
type: 'enabled',
budget_tokens: 1500,
},
});
// Assert
expect(instance['client'].chat.completions.create).toHaveBeenCalledWith(
expect.objectContaining({
messages: [{ content: 'Hello', role: 'user' }],
model: 'mistralai/mistral-7b-instruct:free',
reasoning: {
max_tokens: 1500,
},
temperature: 0.7,
}),
{ headers: { Accept: '*/*' } },
);
expect(result).toBeInstanceOf(Response);
});
describe('Error', () => {
it('should return OpenRouterBizError with an openai error response when OpenAI.APIError is thrown', async () => {
// Arrange
+11 -2
View File
@@ -2,7 +2,7 @@ import type { ChatModelCard } from '@/types/llm';
import { ModelProvider } from '../types';
import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory';
import { OpenRouterModelCard, OpenRouterModelExtraInfo } from './type';
import { OpenRouterModelCard, OpenRouterModelExtraInfo, OpenRouterReasoning } from './type';
const formatPrice = (price: string) => {
if (price === '-1') return undefined;
@@ -13,10 +13,19 @@ export const LobeOpenRouterAI = LobeOpenAICompatibleFactory({
baseURL: 'https://openrouter.ai/api/v1',
chatCompletion: {
handlePayload: (payload) => {
const { thinking } = payload;
let reasoning: OpenRouterReasoning = {};
if (thinking?.type === 'enabled') {
reasoning = {
max_tokens: thinking.budget_tokens,
};
}
return {
...payload,
include_reasoning: true,
model: payload.enabledSearch ? `${payload.model}:online` : payload.model,
reasoning,
stream: payload.stream ?? true,
} as any;
},
+19
View File
@@ -37,3 +37,22 @@ export interface OpenRouterModelExtraInfo {
endpoint?: OpenRouterModelEndpoint;
slug: string;
}
interface OpenRouterOpenAIReasoning {
effort: 'high' | 'medium' | 'low';
exclude?: boolean;
}
interface OpenRouterAnthropicReasoning {
exclude?: boolean;
max_tokens: number;
}
interface OpenRouterCommonReasoning {
exclude?: boolean;
}
export type OpenRouterReasoning =
| OpenRouterOpenAIReasoning
| OpenRouterAnthropicReasoning
| OpenRouterCommonReasoning;
+1 -1
View File
@@ -13,7 +13,7 @@ export interface ChatCompletionErrorPayload {
endpoint?: string;
error: object;
errorType: ILobeAgentRuntimeErrorType;
provider: ModelProvider;
provider: string;
}
export interface CreateChatCompletionOptions {
+1 -1
View File
@@ -35,7 +35,7 @@ export const debugStream = async (stream: ReadableStream) => {
console.log(`[chunk ${chunk}] ${getTime()}`);
console.log(chunkValue);
console.log(`\n`);
console.log('');
finished = done;
chunk++;
@@ -57,6 +57,7 @@ interface OpenAICompatibleFactoryOptions<T extends Record<string, any> = any> {
apiKey?: string;
baseURL?: string;
chatCompletion?: {
excludeUsage?: boolean;
handleError?: (
error: any,
options: ConstructorOptions<T>,
@@ -168,6 +169,8 @@ export const LobeOpenAICompatibleFactory = <T extends Record<string, any> = any>
return class LobeOpenAICompatibleAI implements LobeRuntimeAI {
client!: OpenAI;
private id: string;
baseURL!: string;
protected _options: ConstructorOptions<T>;
@@ -192,6 +195,8 @@ export const LobeOpenAICompatibleFactory = <T extends Record<string, any> = any>
}
this.baseURL = baseURL || this.client.baseURL;
this.id = options.id || provider;
}
async chat({ responseMode, ...payload }: ChatStreamPayload, options?: ChatCompetitionOptions) {
@@ -210,7 +215,7 @@ export const LobeOpenAICompatibleFactory = <T extends Record<string, any> = any>
const streamOptions: OpenAIStreamOptions = {
bizErrorTypeTransformer: chatCompletion?.handleStreamBizErrorType,
callbacks: options?.callback,
provider,
provider: this.id,
};
if (customClient?.createChatCompletionStream) {
@@ -220,12 +225,17 @@ export const LobeOpenAICompatibleFactory = <T extends Record<string, any> = any>
...postPayload,
messages,
...(chatCompletion?.noUserId ? {} : { user: options?.user }),
stream_options: postPayload.stream ? { include_usage: true } : undefined,
stream_options:
postPayload.stream && !chatCompletion?.excludeUsage
? { include_usage: true }
: undefined,
};
if (debug?.chatCompletion?.()) {
console.log('[requestPayload]:', JSON.stringify(finalPayload, null, 2));
console.log('[requestPayload]');
console.log(JSON.stringify(finalPayload), '\n');
}
response = await this.client.chat.completions.create(finalPayload, {
// https://github.com/lobehub/lobe-chat/pull/318
headers: { Accept: '*/*', ...options?.requestHeaders },
@@ -368,7 +378,7 @@ export const LobeOpenAICompatibleFactory = <T extends Record<string, any> = any>
if (errorResult)
return AgentRuntimeError.chat({
...errorResult,
provider,
provider: this.id,
} as ChatCompletionErrorPayload);
}
@@ -379,7 +389,7 @@ export const LobeOpenAICompatibleFactory = <T extends Record<string, any> = any>
endpoint: desensitizedEndpoint,
error: error as any,
errorType: ErrorType.invalidAPIKey,
provider: provider as ModelProvider,
provider: this.id as ModelProvider,
});
}
@@ -397,7 +407,7 @@ export const LobeOpenAICompatibleFactory = <T extends Record<string, any> = any>
endpoint: desensitizedEndpoint,
error: errorResult,
errorType: AgentRuntimeErrorType.InsufficientQuota,
provider: provider as ModelProvider,
provider: this.id as ModelProvider,
});
}
@@ -406,7 +416,7 @@ export const LobeOpenAICompatibleFactory = <T extends Record<string, any> = any>
endpoint: desensitizedEndpoint,
error: errorResult,
errorType: AgentRuntimeErrorType.ModelNotFound,
provider: provider as ModelProvider,
provider: this.id as ModelProvider,
});
}
@@ -417,7 +427,7 @@ export const LobeOpenAICompatibleFactory = <T extends Record<string, any> = any>
endpoint: desensitizedEndpoint,
error: errorResult,
errorType: AgentRuntimeErrorType.ExceededContextWindow,
provider: provider as ModelProvider,
provider: this.id as ModelProvider,
});
}
}
@@ -426,7 +436,7 @@ export const LobeOpenAICompatibleFactory = <T extends Record<string, any> = any>
endpoint: desensitizedEndpoint,
error: errorResult,
errorType: RuntimeError || ErrorType.bizError,
provider: provider as ModelProvider,
provider: this.id as ModelProvider,
});
}
};
@@ -1,5 +1,7 @@
import OpenAI from 'openai';
import { disableStreamModels, systemToUserModels } from '@/const/models';
import { ChatStreamPayload, OpenAIChatMessage } from '@/libs/agent-runtime';
import { imageUrlToBase64 } from '@/utils/imageToBase64';
import { parseDataUri } from './uriParser';
@@ -38,3 +40,23 @@ export const convertOpenAIMessages = async (messages: OpenAI.ChatCompletionMessa
})),
)) as OpenAI.ChatCompletionMessageParam[];
};
export const pruneReasoningPayload = (payload: ChatStreamPayload) => {
return {
...payload,
frequency_penalty: 0,
messages: payload.messages.map((message: OpenAIChatMessage) => ({
...message,
role:
message.role === 'system'
? systemToUserModels.has(payload.model)
? 'user'
: 'developer'
: message.role,
})),
presence_penalty: 0,
stream: !disableStreamModels.has(payload.model),
temperature: 1,
top_p: 1,
};
};
+1
View File
@@ -42,6 +42,7 @@ export default {
debug: authEnv.NEXT_AUTH_DEBUG,
pages: {
error: '/next-auth/error',
signIn: '/next-auth/signin',
},
providers: initSSOProviders(),
secret: authEnv.NEXT_AUTH_SECRET,
+1 -1
View File
@@ -36,7 +36,7 @@ export const config = {
'/login(.*)',
'/signup(.*)',
'/next-auth/error',
'/next-auth/(.*)',
// ↓ cloud ↓
],
};
+19 -13
View File
@@ -17,13 +17,19 @@ import {
} from '@/libs/agent-runtime';
import { filesPrompts } from '@/prompts/files';
import { BuiltinSystemRolePrompts } from '@/prompts/systemRole';
import { aiModelSelectors, aiProviderSelectors, useAiInfraStore } from '@/store/aiInfra';
import { getAgentChatConfig } from '@/store/chat/slices/aiChat/actions/helpers';
import { useSessionStore } from '@/store/session';
import { getAgentStoreState } from '@/store/agent';
import { agentChatConfigSelectors } from '@/store/agent/selectors';
import {
aiModelSelectors,
aiProviderSelectors,
getAiInfraStoreState,
useAiInfraStore,
} from '@/store/aiInfra';
import { getSessionStoreState } from '@/store/session';
import { sessionMetaSelectors } from '@/store/session/selectors';
import { useToolStore } from '@/store/tool';
import { getToolStoreState } from '@/store/tool';
import { pluginSelectors, toolSelectors } from '@/store/tool/selectors';
import { useUserStore } from '@/store/user';
import { getUserStoreState, useUserStore } from '@/store/user';
import {
modelConfigSelectors,
modelProviderSelectors,
@@ -46,10 +52,10 @@ import { API_ENDPOINTS } from './_url';
const isCanUseFC = (model: string, provider: string) => {
// TODO: remove isDeprecatedEdition condition in V2.0
if (isDeprecatedEdition) {
return modelProviderSelectors.isModelEnabledFunctionCall(model)(useUserStore.getState());
return modelProviderSelectors.isModelEnabledFunctionCall(model)(getUserStoreState());
}
return aiModelSelectors.isModelSupportToolUse(model, provider)(useAiInfraStore.getState());
return aiModelSelectors.isModelSupportToolUse(model, provider)(getAiInfraStoreState());
};
/**
@@ -169,7 +175,7 @@ class ChatService {
);
// =================== 0. process search =================== //
const chatConfig = getAgentChatConfig();
const chatConfig = agentChatConfigSelectors.currentChatConfig(getAgentStoreState());
const enabledSearch = chatConfig.searchMode !== 'off';
const isModelHasBuiltinSearch = aiModelSelectors.isModelHasBuiltinSearch(
@@ -200,7 +206,7 @@ class ChatService {
// ============ 2. preprocess tools ============ //
let filterTools = toolSelectors.enabledSchema(pluginIds)(useToolStore.getState());
let filterTools = toolSelectors.enabledSchema(pluginIds)(getToolStoreState());
// check this model can use function call
const canUseFC = isCanUseFC(payload.model, payload.provider!);
@@ -378,7 +384,7 @@ class ChatService {
* @param options
*/
runPluginApi = async (params: PluginRequestPayload, options?: FetchOptions) => {
const s = useToolStore.getState();
const s = getToolStoreState();
const settings = pluginSelectors.getPluginSettingsById(params.identifier)(s);
const manifest = pluginSelectors.getToolManifestById(params.identifier)(s);
@@ -537,7 +543,7 @@ class ChatService {
const hasTools = tools && tools?.length > 0;
const hasFC = hasTools && isCanUseFC(model, provider);
const toolsSystemRoles =
hasFC && toolSelectors.enabledSystemRoles(tools)(useToolStore.getState());
hasFC && toolSelectors.enabledSystemRoles(tools)(getToolStoreState());
const injectSystemRoles = BuiltinSystemRolePrompts({
historySummary: options?.historySummary,
@@ -565,9 +571,9 @@ class ChatService {
};
private mapTrace = (trace?: TracePayload, tag?: TraceTagMap): TracePayload => {
const tags = sessionMetaSelectors.currentAgentMeta(useSessionStore.getState()).tags || [];
const tags = sessionMetaSelectors.currentAgentMeta(getSessionStoreState()).tags || [];
const enabled = preferenceSelectors.userAllowTrace(useUserStore.getState());
const enabled = preferenceSelectors.userAllowTrace(getUserStoreState());
if (!enabled) return { ...trace, enabled: false };
+1 -1
View File
@@ -1,2 +1,2 @@
export type { AgentStore } from './store';
export { useAgentStore } from './store';
export { getAgentStoreState, useAgentStore } from './store';
@@ -1,4 +1,5 @@
import { contextCachingModels, thinkingWithToolClaudeModels } from '@/const/models';
import { DEFAULT_AGENT_CHAT_CONFIG } from '@/const/settings';
import { AgentStoreState } from '@/store/agent/initialState';
import { LobeAgentChatConfig } from '@/types/agent';
@@ -30,10 +31,10 @@ const enableHistoryCount = (s: AgentStoreState) => {
return chatConfig.enableHistoryCount;
};
const historyCount = (s: AgentStoreState) => {
const historyCount = (s: AgentStoreState): number => {
const chatConfig = currentAgentChatConfig(s);
return chatConfig.historyCount;
return chatConfig.historyCount || (DEFAULT_AGENT_CHAT_CONFIG.historyCount as number);
};
const displayMode = (s: AgentStoreState) => {
+2
View File
@@ -20,3 +20,5 @@ const createStore: StateCreator<AgentStore, [['zustand/devtools', never]]> = (..
const devtools = createDevtools('agent');
export const useAgentStore = createWithEqualityFn<AgentStore>()(devtools(createStore), shallow);
export const getAgentStoreState = () => useAgentStore.getState();
+1 -1
View File
@@ -1,2 +1,2 @@
export * from './selectors';
export { useAiInfraStore } from './store';
export { getAiInfraStoreState,useAiInfraStore } from './store';
+2
View File
@@ -23,3 +23,5 @@ const createStore: StateCreator<AiInfraStore, [['zustand/devtools', never]]> = (
const devtools = createDevtools('aiInfra');
export const useAiInfraStore = createWithEqualityFn<AiInfraStore>()(devtools(createStore), shallow);
export const getAiInfraStoreState = () => useAiInfraStore.getState();
@@ -5,13 +5,14 @@ import { template } from 'lodash-es';
import { StateCreator } from 'zustand/vanilla';
import { LOADING_FLAT, MESSAGE_CANCEL_FLAT } from '@/const/message';
import { DEFAULT_AGENT_CHAT_CONFIG } from '@/const/settings';
import { TraceEventType, TraceNameMap } from '@/const/trace';
import { isServerMode } from '@/const/version';
import { knowledgeBaseQAPrompts } from '@/prompts/knowledgeBaseQA';
import { chatService } from '@/services/chat';
import { messageService } from '@/services/message';
import { useAgentStore } from '@/store/agent';
import { agentChatConfigSelectors, agentSelectors } from '@/store/agent/selectors';
import { getAgentStoreState } from '@/store/agent/store';
import { chatHelpers } from '@/store/chat/helpers';
import { ChatStore } from '@/store/chat/store';
import { messageMapKey } from '@/store/chat/utils/messageMapKey';
@@ -21,12 +22,6 @@ import { MessageSemanticSearchChunk } from '@/types/rag';
import { setNamespace } from '@/utils/storeDebug';
import { chatSelectors, topicSelectors } from '../../../selectors';
import {
getAgentChatConfig,
getAgentConfig,
getAgentEnableHistoryCount,
getAgentKnowledge,
} from './helpers';
const n = setNamespace('ai');
@@ -163,7 +158,7 @@ export const generateAIChat: StateCreator<
threadId: activeThreadId,
};
const agentConfig = getAgentChatConfig();
const agentConfig = agentChatConfigSelectors.currentChatConfig(getAgentStoreState());
let tempMessageId: string | undefined = undefined;
let newTopicId: string | undefined = undefined;
@@ -288,7 +283,7 @@ export const generateAIChat: StateCreator<
// create a new array to avoid the original messages array change
const messages = [...originalMessages];
const { model, provider, chatConfig } = getAgentConfig();
const { model, provider, chatConfig } = agentSelectors.currentAgentConfig(getAgentStoreState());
let fileChunks: MessageSemanticSearchChunk[] | undefined;
let ragQueryId;
@@ -312,7 +307,7 @@ export const generateAIChat: StateCreator<
chunks,
userQuery: lastMsg.content,
rewriteQuery,
knowledge: getAgentKnowledge(),
knowledge: agentSelectors.currentEnabledKnowledge(getAgentStoreState()),
});
// 3. add the retrieve context messages to the messages history
@@ -354,11 +349,10 @@ export const generateAIChat: StateCreator<
}
// 5. summary history if context messages is larger than historyCount
const historyCount =
chatConfig.historyCount || (DEFAULT_AGENT_CHAT_CONFIG.historyCount as number);
const historyCount = agentChatConfigSelectors.historyCount(getAgentStoreState());
if (
chatConfig.enableHistoryCount &&
agentChatConfigSelectors.enableHistoryCount(getAgentStoreState()) &&
chatConfig.enableCompressHistory &&
originalMessages.length > historyCount
) {
@@ -387,7 +381,7 @@ export const generateAIChat: StateCreator<
n('generateMessage(start)', { messageId, messages }) as string,
);
const agentConfig = getAgentConfig();
const agentConfig = agentSelectors.currentAgentConfig(getAgentStoreState());
const chatConfig = agentConfig.chatConfig;
const compiler = template(chatConfig.inputTemplate, { interpolate: /{{([\S\s]+?)}}/g });
@@ -397,10 +391,13 @@ export const generateAIChat: StateCreator<
// ================================== //
// 1. slice messages with config
const historyCount = agentChatConfigSelectors.historyCount(getAgentStoreState());
const enableHistoryCount = agentChatConfigSelectors.enableHistoryCount(getAgentStoreState());
let preprocessMsgs = chatHelpers.getSlicedMessages(messages, {
includeNewUserMessage: true,
enableHistoryCount: getAgentEnableHistoryCount(),
historyCount: chatConfig.historyCount,
enableHistoryCount,
historyCount,
});
// 2. replace inputMessage template
@@ -1,13 +0,0 @@
import { useAgentStore } from '@/store/agent';
import { agentChatConfigSelectors, agentSelectors } from '@/store/agent/selectors';
export const getAgentConfig = () => agentSelectors.currentAgentConfig(useAgentStore.getState());
export const getAgentChatConfig = () =>
agentChatConfigSelectors.currentChatConfig(useAgentStore.getState());
export const getAgentEnableHistoryCount = () =>
agentChatConfigSelectors.enableHistoryCount(useAgentStore.getState());
export const getAgentKnowledge = () =>
agentSelectors.currentEnabledKnowledge(useAgentStore.getState());
+1 -1
View File
@@ -1,2 +1,2 @@
export type { SessionStore } from './store';
export { useSessionStore } from './store';
export { getSessionStoreState,useSessionStore } from './store';
+2
View File
@@ -31,3 +31,5 @@ export const useSessionStore = createWithEqualityFn<SessionStore>()(
),
shallow,
);
export const getSessionStoreState = () => useSessionStore.getState();
+1 -1
View File
@@ -1,2 +1,2 @@
export * from './helpers';
export { useToolStore } from './store';
export { getToolStoreState, useToolStore } from './store';
+2
View File
@@ -30,3 +30,5 @@ const createStore: StateCreator<ToolStore, [['zustand/devtools', never]]> = (...
const devtools = createDevtools('tools');
export const useToolStore = createWithEqualityFn<ToolStore>()(devtools(createStore), shallow);
export const getToolStoreState = () => useToolStore.getState();
+2
View File
@@ -40,3 +40,5 @@ export const useUserStore = createWithEqualityFn<UserStore>()(
subscribeWithSelector(devtools(createStore)),
shallow,
);
export const getUserStoreState = () => useUserStore.getState();
@@ -51,7 +51,8 @@ const useStyles = createStyles(({ token, css }) => {
}
`,
footer: css`
padding: 8px 16px;
padding-block: 8px;
padding-inline: 16px;
text-align: center;
background-color: ${token.colorFillQuaternary};
`,
+66
View File
@@ -0,0 +1,66 @@
/* eslint-disable sort-keys-fix/sort-keys-fix, typescript-sort-keys/interface */
import { z } from 'zod';
import { SearchMode } from '@/types/search';
export interface WorkingModel {
model: string;
provider: string;
}
export interface LobeAgentChatConfig {
displayMode?: 'chat' | 'docs';
enableAutoCreateTopic?: boolean;
autoCreateTopicThreshold: number;
enableMaxTokens?: boolean;
/**
*
*/
enableReasoning?: boolean;
/**
*
*/
enableReasoningEffort?: boolean;
reasoningBudgetToken?: number;
/**
*
*/
disableContextCaching?: boolean;
/**
*
*/
historyCount?: number;
/**
*
*/
enableHistoryCount?: boolean;
/**
*
*/
enableCompressHistory?: boolean;
inputTemplate?: string;
searchMode?: SearchMode;
searchFCModel?: WorkingModel;
useModelBuiltinSearch?: boolean;
}
/* eslint-enable */
export const AgentChatConfigSchema = z.object({
autoCreateTopicThreshold: z.number().default(2),
displayMode: z.enum(['chat', 'docs']).optional(),
enableAutoCreateTopic: z.boolean().optional(),
enableCompressHistory: z.boolean().optional(),
enableHistoryCount: z.boolean().optional(),
enableMaxTokens: z.boolean().optional(),
enableReasoning: z.boolean().optional(),
enableReasoningEffort: z.boolean().optional(),
historyCount: z.number().optional(),
reasoningBudgetToken: z.number().optional(),
searchMode: z.enum(['off', 'on', 'auto']).optional(),
});
+4 -61
View File
@@ -1,9 +1,8 @@
import { z } from 'zod';
import { FileItem } from '@/types/files';
import { KnowledgeBaseItem } from '@/types/knowledgeBase';
import { FewShots, LLMParams } from '@/types/llm';
import { SearchMode } from '@/types/search';
import { LobeAgentChatConfig } from './chatConfig';
export type TTSServer = 'openai' | 'edge' | 'microsoft';
@@ -55,64 +54,8 @@ export interface LobeAgentConfig {
tts: LobeAgentTTSConfig;
}
/* eslint-disable sort-keys-fix/sort-keys-fix, typescript-sort-keys/interface */
export interface LobeAgentChatConfig {
displayMode?: 'chat' | 'docs';
enableAutoCreateTopic?: boolean;
autoCreateTopicThreshold: number;
enableMaxTokens?: boolean;
/**
*
*/
enableReasoning?: boolean;
/**
*
*/
enableReasoningEffort?: boolean;
reasoningBudgetToken?: number;
/**
*
*/
disableContextCaching?: boolean;
/**
*
*/
historyCount?: number;
/**
*
*/
enableHistoryCount?: boolean;
/**
*
*/
enableCompressHistory?: boolean;
inputTemplate?: string;
searchMode?: SearchMode;
useModelBuiltinSearch?: boolean;
}
/* eslint-enable */
export const AgentChatConfigSchema = z.object({
autoCreateTopicThreshold: z.number().default(2),
displayMode: z.enum(['chat', 'docs']).optional(),
enableAutoCreateTopic: z.boolean().optional(),
enableCompressHistory: z.boolean().optional(),
enableHistoryCount: z.boolean().optional(),
enableMaxTokens: z.boolean().optional(),
enableReasoning: z.boolean().optional(),
enableReasoningEffort: z.boolean().optional(),
historyCount: z.number().optional(),
reasoningBudgetToken: z.number().optional(),
searchMode: z.enum(['off', 'on', 'auto']).optional(),
});
export type LobeAgentConfigKeys =
| keyof LobeAgentConfig
| ['params', keyof LobeAgentConfig['params']];
export * from './chatConfig';