@lobehub/chat 0.89.4 → 0.89.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,49 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ### [Version 0.89.6](https://github.com/lobehub/lobe-chat/compare/v0.89.5...v0.89.6)
6
+
7
+ <sup>Released on **2023-10-15**</sup>
8
+
9
+ <br/>
10
+
11
+ <details>
12
+ <summary><kbd>Improvements and Fixes</kbd></summary>
13
+
14
+ </details>
15
+
16
+ <div align="right">
17
+
18
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
19
+
20
+ </div>
21
+
22
+ ### [Version 0.89.5](https://github.com/lobehub/lobe-chat/compare/v0.89.4...v0.89.5)
23
+
24
+ <sup>Released on **2023-10-15**</sup>
25
+
26
+ #### 🐛 Bug Fixes
27
+
28
+ - **misc**: Fix fallback to en when the locale is zh, fix reset button not clear plugin settings.
29
+
30
+ <br/>
31
+
32
+ <details>
33
+ <summary><kbd>Improvements and Fixes</kbd></summary>
34
+
35
+ #### What's fixed
36
+
37
+ - **misc**: Fix fallback to en when the locale is zh ([ff2c00e](https://github.com/lobehub/lobe-chat/commit/ff2c00e))
38
+ - **misc**: Fix reset button not clear plugin settings ([aa1e657](https://github.com/lobehub/lobe-chat/commit/aa1e657))
39
+
40
+ </details>
41
+
42
+ <div align="right">
43
+
44
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
45
+
46
+ </div>
47
+
5
48
  ### [Version 0.89.4](https://github.com/lobehub/lobe-chat/compare/v0.89.3...v0.89.4)
6
49
 
7
50
  <sup>Released on **2023-10-15**</sup>
package/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  <h1>Lobe Chat</h1>
10
10
 
11
- LobeChat is an open-source, extensible ([Function Calling][fc-link]), high-performance chatbot framework. <br/> It supports one-click free deployment of your private ChatGPT/LLM web application.
11
+ LobeChat is an open-source, extensible ([Function Calling][fc-link]) high-performance chatbot framework. <br/> It supports one-click free deployment of your private ChatGPT/LLM web application.
12
12
 
13
13
  **English** · [简体中文](./README.zh-CN.md) · [Changelog](./CHANGELOG.md) · [Wiki][github-wiki-link] · [Report Bug][github-issues-link] · [Request Feature][github-issues-link]
14
14
 
@@ -66,14 +66,14 @@ LobeChat is an open-source, extensible ([Function Calling][fc-link]), high-perfo
66
66
 
67
67
  ## 👋🏻 Getting Started & Join Our Community
68
68
 
69
- Please be aware that LobeChat is currently under active development,feedback is welcome for any [issues][issues-link] encountered.
69
+ Please be aware that LobeChat is currently under active development, and feedback is welcome for any [issues][issues-link] encountered.
70
70
 
71
71
  | [![][vercel-shield-badge]][vercel-link] | No installation or registration necessary! Visit our website to experience it firsthand. |
72
72
  | :---------------------------------------- | :----------------------------------------------------------------------------------------------------------------- |
73
73
  | [![][discord-shield-badge]][discord-link] | Join our Discord community! This is where you can connect with developers and other enthusiastic users of LobeHub. |
74
74
 
75
75
  > **Important**\
76
- > **Star Us**,You will receive all releases notifications from GitHub without any delay \~ ⭐️
76
+ > **Star Us**, You will receive all release notifications from GitHub without any delay \~ ⭐️
77
77
 
78
78
  ![](https://gw.alipayobjects.com/zos/kitchen/0hcO8QiU9c/star.webp)
79
79
 
@@ -86,12 +86,12 @@ Please be aware that LobeChat is currently under active development,feedback i
86
86
 
87
87
  ## ✨ Features
88
88
 
89
- - [x] 💨 **Quick Deployment**: Using the Vercel platform, you can deploy with just one click and complete the process within 1 minute, without any complex configuration;
89
+ - [x] 💨 **Quick Deployment**: Using the Vercel platform, you can deploy with just one click and complete the process within 1 minute without any complex configuration;
90
90
  - [x] 💎 **Exquisite UI Design**: With a carefully designed interface, it offers an elegant appearance and smooth interaction. It supports light and dark themes and is mobile-friendly. PWA support provides a more native-like experience;
91
91
  - [x] 🗣️ **Smooth Conversation Experience**: Fluid responses ensure a smooth conversation experience. It fully supports Markdown rendering, including code highlighting, LaTex formulas, Mermaid flowcharts, and more;
92
92
  - [x] 🧩 **Plugin Support & Custom Plugin Development**: Conversations are extendable with plugins. Users can install and use various plugins, such as search engines, web extraction, etc. It also supports the development of custom plugins to meet custom needs;
93
93
  - [x] 🔒 **Privacy Protection**: All data is stored locally in the user's browser, ensuring user privacy;
94
- - [x] 🤖 **Customizable Agent Roles**: Users can create, share, and debug personalized dialogue agent roles according to their needs, providing more flexible and personalized dialogue functions;
94
+ - [x] 🤖 **Customizable Agent Roles**: Users can create, share, and debug personalized dialogue agent roles according to their needs, providing more flexible and customized dialogue functions;
95
95
  - [x] 🌐 **Custom Domain**: If users have their own domain, they can bind it to the platform for quick access to the dialogue agent from anywhere.
96
96
  - [x] 🏬 **Role Market**: A Role Market is provided where users can select their preferred dialogue agent roles, enriching the content and style of the dialogue;
97
97
 
@@ -110,7 +110,7 @@ Please be aware that LobeChat is currently under active development,feedback i
110
110
 
111
111
  #### `1` Function Calling Plugin System
112
112
 
113
- By building a powerful plugin ecosystem, ChatGPT not only can provide real-time news updates, but it can also assist you in easily querying documents and accessing various e-commerce data. This allows ChatGPT to play a key role in a wider range of fields. If you are interested in writing plugins, we provide detailed component development documentation, SDKs, and template files in the [🧩 Plugin System](#-Plugin-System) section below. Let's work together to make ChatGPT more powerful and easier to use.
113
+ By building a robust plugin ecosystem, ChatGPT cannot only provide real-time news updates but can also assist you in efficiently querying documents and accessing various e-commerce data. This allows ChatGPT to play a vital role in a wider range of fields. If you are interested in writing plugins, we provide detailed component development documentation, SDKs, and template files in the [🧩 Plugin System](#-Plugin-System) section below. Let's work together to make ChatGPT more powerful and easier to use.
114
114
 
115
115
  <br/>
116
116
 
@@ -118,7 +118,7 @@ By building a powerful plugin ecosystem, ChatGPT not only can provide real-time
118
118
 
119
119
  #### `2` Prompt Agent Market
120
120
 
121
- In our agent market, we have accumulated a large number of practical prompt agents that have been used in daily work and study. You can also share your agents here and iterate and optimize your prompt agents with more people. You can submit your agents through [🤖/🏪 Submit Agents][submit-agents-link], and our automated i18n workflow will automatically translate your agents into multiple languages, allowing users around the world to enjoy your wisdom.
121
+ In our agent market, we have accumulated a large number of practical, prompt agents that have been used in daily work and study. You can also share your agents here and iterate and optimize your prompt agents with more people. You can submit your agents through [🤖/🏪 Submit Agents][submit-agents-link], and our automated i18n workflow will automatically translate your agents into multiple languages, allowing users worldwide to enjoy your wisdom.
122
122
 
123
123
  <br/>
124
124
 
@@ -176,22 +176,26 @@ We have carried out a series of optimization designs for mobile devices to enhan
176
176
 
177
177
  ## 🛳 Self Hosting
178
178
 
179
- LobeChat provides [Self-Hosted Version][deploy-link] with Vercel and [Docker Image][docker-release-link]. This allows you to deploy your own chatbot within a few minutes, without any prior knowledge.
180
-
181
- <br/>
179
+ LobeChat provides Self-Hosted Version with Vercel and [Docker Image][docker-release-link]. This allows you to deploy your own chatbot within a few minutes without any prior knowledge.
182
180
 
183
181
  ### `A` Deploying with Vercel
184
182
 
185
183
  If you want to deploy this service yourself on Vercel, you can follow these steps:
186
184
 
187
185
  - Prepare your [OpenAI API Key](https://platform.openai.com/account/api-keys).
188
- - Click the button below to start deployment: Deploy with Vercel. Log in directly with your GitHub account and remember to fill in the API Key and access code CODE on the environment variable page;
186
+ - Click the button below to start deployment: Deploy with Vercel. Log in directly with your GitHub account, and remember to fill in the `OPENAI_API_KEY`(required) and `ACCESS_CODE` (recommended) on the environment variable section;
189
187
  - After deployment, you can start using it;
190
- - Bind a custom domain (optional): The DNS of the domain assigned by Vercel is polluted in some areas, binding a custom domain can connect directly.
188
+ - Bind a custom domain (optional): The DNS of the domain assigned by Vercel is polluted in some areas; binding a custom domain can connect directly.
189
+
190
+ <div align="center">
191
+
192
+ [![][deploy-button-image]][deploy-link]
193
+
194
+ </div>
191
195
 
192
196
  #### Keep Updated
193
197
 
194
- If you have deployed your own project following the one-click deployment steps in the README, you might encounter constant prompts indicating "updates available". This is because Vercel defaults to creating a new project instead of forking this one, resulting in an inability to accurately detect updates.
198
+ If you have deployed your own project following the one-click deployment steps in the README, you might encounter constant prompts indicating "updates available." This is because Vercel defaults to creating a new project instead of forking this one, resulting in an inability to detect updates accurately.
195
199
 
196
200
  > **Important**\
197
201
  > We suggest you redeploy using the following steps, [📘 Maintaining Updates with LobeChat Self-Deployment](https://github.com/lobehub/lobe-chat/wiki/Upstream-Sync).
@@ -231,13 +235,13 @@ $ docker run -d -p 3210:3210 \
231
235
 
232
236
  ### Environment Variable
233
237
 
234
- This project provides some additional configuration items, set with environment variables:
238
+ This project provides some additional configuration items set with environment variables:
235
239
 
236
240
  | Environment Variable | Required | Description | Example |
237
241
  | -------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
238
242
  | `OPENAI_API_KEY` | Yes | This is the API key you apply on the OpenAI account page | `sk-xxxxxx...xxxxxx` |
239
243
  | `OPENAI_PROXY_URL` | No | If you manually configure the OpenAI interface proxy, you can use this configuration item to override the default OpenAI API request base URL | `https://api.chatanywhere.cn/v1`<br/>The default value is<br/>`https://api.openai.com/v1` |
240
- | `ACCESS_CODE` | No | Add a password to access this service, the password should be a 6-digit number or letter | `awCT74` or `e3@09!` |
244
+ | `ACCESS_CODE` | No | Add a password to access this service; the password should be a 6-digit number or letter | `awCT74` or `e3@09!` |
241
245
 
242
246
  > **Note**\
243
247
  > The complete list of environment variables can be found in the [📘 Environment Variables](https://github.com/lobehub/lobe-chat/wiki/Environment-Variable)
@@ -264,12 +268,12 @@ This project provides some additional configuration items, set with environment
264
268
 
265
269
  ## 🧩 Plugins
266
270
 
267
- Plugins provide a means to extend the [Function Calling][fc-link] capabilities of LobeChat. They can be used to introduce new function calls, and even new ways to render message results. If you are interested in plugin development, please refer to our [📘 Plugin Development Guide](https://github.com/lobehub/lobe-chat/wiki/Plugin-Development) in the Wiki.
271
+ Plugins provide a means to extend the [Function Calling][fc-link] capabilities of LobeChat. They can be used to introduce new function calls and even new ways to render message results. If you are interested in plugin development, please refer to our [📘 Plugin Development Guide](https://github.com/lobehub/lobe-chat/wiki/Plugin-Development) in the Wiki.
268
272
 
269
273
  - [lobe-chat-plugins][lobe-chat-plugins]: This is the plugin index for LobeChat. It accesses index.json from this repository to display a list of available plugins for LobeChat to the user.
270
274
  - [chat-plugin-template][chat-plugin-template]: This is the plugin template for LobeChat plugin development.
271
275
  - [@lobehub/chat-plugin-sdk][chat-plugin-sdk]: The LobeChat Plugin SDK assists you in creating exceptional chat plugins for Lobe Chat.
272
- - [@lobehub/chat-plugins-gateway][chat-plugins-gateway]: The LobeChat Plugins Gateway is a backend service that serves as a gateway for LobeChat plugins. We deploy this service using Vercel. The primary API POST /api/v1/runner is deployed as an Edge Function.
276
+ - [@lobehub/chat-plugins-gateway][chat-plugins-gateway]: The LobeChat Plugins Gateway is a backend service that provides a gateway for LobeChat plugins. We deploy this service using Vercel. The primary API POST /api/v1/runner is deployed as an Edge Function.
273
277
 
274
278
  > **Note**\
275
279
  > The plugin system is currently undergoing major development. You can learn more in the following issues:
@@ -315,7 +319,7 @@ $ bun dev
315
319
 
316
320
  ## 🤝 Contributing
317
321
 
318
- Contributions of all types are more than welcome, if you are interested in contributing code, feel free to check out our GitHub [Issues][github-issues-link] and [Projects][github-project-link] to get stuck in to show us what you’re made of.
322
+ Contributions of all types are more than welcome; if you are interested in contributing code, feel free to check out our GitHub [Issues][github-issues-link] and [Projects][github-project-link] to get stuck in to show us what you’re made of.
319
323
 
320
324
  [![][pr-welcome-shield]][pr-welcome-link]
321
325
  [![][submit-agents-shield]][submit-agents-link]
@@ -331,9 +335,9 @@ Contributions of all types are more than welcome, if you are interested in contr
331
335
 
332
336
  ## 🔗 More Products
333
337
 
334
- - **[🤯 Lobe Theme][lobe-theme] :** The modern theme for stable diffusion webui, exquisite interface design, highly customizable UI, and efficiency boosting features.
338
+ - **[🤯 Lobe Theme][lobe-theme]:** The modern theme for stable diffusion webui, exquisite interface design, highly customizable UI, and efficiency-boosting features.
335
339
  - **[🌏 Lobe i18n][lobe-i18n] :** Lobe i18n is an automation tool for the i18n (internationalization) translation process, powered by ChatGPT. It supports features such as automatic splitting of large files, incremental updates, and customization options for the OpenAI model, API proxy, and temperature.
336
- - **[💌 Lobe Commit][lobe-commit] :** Lobe Commit is a CLI tool that leverages Langchain/ChatGPT to generate Gitmoji-based commit messages.
340
+ - **[💌 Lobe Commit][lobe-commit]:** Lobe Commit is a CLI tool that leverages Langchain/ChatGPT to generate Gitmoji-based commit messages.
337
341
 
338
342
  <div align="right">
339
343
 
@@ -371,7 +375,8 @@ This project is [MIT](./LICENSE) licensed.
371
375
  [codespaces-shield]: https://github.com/codespaces/badge.svg
372
376
  [contributors-contrib]: https://contrib.rocks/image?repo=lobehub/lobe-chat
373
377
  [contributors-link]: https://github.com/lobehub/lobe-chat/graphs/contributors
374
- [deploy-link]: https://vercel.com/new/clone?repository-link=https%3A%2F%2Fgithub.com%2Flobehub%2Flobe-chat&env=OPENAI_API_KEY&envDescription=Find%20your%20OpenAI%20API%20Key%20by%20click%20the%20right%20Learn%20More%20button.%20%20&envLink=https%3A%2F%2Fplatform.openai.com%2Faccount%2Fapi-keys&project-name=lobe-chat&repository-name=lobe-chat
378
+ [deploy-button-image]: https://vercel.com/button
379
+ [deploy-link]: https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Flobehub%2Flobe-chat&env=OPENAI_API_KEY&envDescription=Find%20your%20OpenAI%20API%20Key%20by%20click%20the%20right%20Learn%20More%20button.&envLink=https%3A%2F%2Fplatform.openai.com%2Faccount%2Fapi-keys&project-name=lobe-chat&repository-name=lobe-chat
375
380
  [discord-link]: https://discord.gg/AYFPHvv2jT
376
381
  [discord-shield]: https://img.shields.io/discord/1127171173982154893?color=5865F2&label=discord&labelColor=black&logo=discord&logoColor=white&style=flat-square
377
382
  [discord-shield-badge]: https://img.shields.io/discord/1127171173982154893?color=5865F2&label=discord&labelColor=black&logo=discord&logoColor=white&style=for-the-badge
package/README.zh-CN.md CHANGED
@@ -178,7 +178,7 @@ LobeChat 提供了两种独特的主题模式 - 明亮模式和暗黑模式,
178
178
 
179
179
  ## 🛳 开箱即用
180
180
 
181
- LobeChat 提供了 Vercel 的 [自托管版本][deploy-link] 和 [Docker 镜像][docker-release-link],这使你可以在几分钟内构建自己的聊天机器人,无需任何基础知识。
181
+ LobeChat 提供了 Vercel 的 自托管版本 和 [Docker 镜像][docker-release-link],这使你可以在几分钟内构建自己的聊天机器人,无需任何基础知识。
182
182
 
183
183
  <br/>
184
184
 
@@ -187,10 +187,16 @@ LobeChat 提供了 Vercel 的 [自托管版本][deploy-link] 和 [Docker 镜像]
187
187
  如果想在 Vercel 上部署该服务,可以按照以下步骤进行操作:
188
188
 
189
189
  - 准备好你的 [OpenAI API Key](https://platform.openai.com/account/api-keys) 。
190
- - 点击下方按钮开始部署: Deploy with Vercel,直接使用 GitHub 账号登录即可,记得在环境变量页填入 API Key 和页面访问密码 CODE;
190
+ - 点击下方按钮开始部署: Deploy with Vercel,直接使用 GitHub 账号登录即可,记得在环境变量页填入 `OPENAI_API_KEY` (必填) and `ACCESS_CODE`(推荐);
191
191
  - 部署完毕后,即可开始使用;
192
192
  - 绑定自定义域名(可选):Vercel 分配的域名 DNS 在某些区域被污染了,绑定自定义域名即可直连。
193
193
 
194
+ <div align="center">
195
+
196
+ [![][deploy-button-image]][deploy-link]
197
+
198
+ </div>
199
+
194
200
  #### 保持更新
195
201
 
196
202
  如果你根据 README 中的一键部署步骤部署了自己的项目,你可能会发现总是被提示 “有可用更新”。这是因为 Vercel 默认为你创建新项目而非 fork 本项目,这将导致无法准确检测更新。
@@ -373,7 +379,8 @@ This project is [MIT](./LICENSE) licensed.
373
379
  [codespaces-shield]: https://github.com/codespaces/badge.svg
374
380
  [contributors-contrib]: https://contrib.rocks/image?repo=lobehub/lobe-chat
375
381
  [contributors-link]: https://github.com/lobehub/lobe-chat/graphs/contributors
376
- [deploy-link]: https://vercel.com/new/clone?repository-link=https%3A%2F%2Fgithub.com%2Flobehub%2Flobe-chat&env=OPENAI_API_KEY&envDescription=Find%20your%20OpenAI%20API%20Key%20by%20click%20the%20right%20Learn%20More%20button.%20%20&envLink=https%3A%2F%2Fplatform.openai.com%2Faccount%2Fapi-keys&project-name=lobe-chat&repository-name=lobe-chat
382
+ [deploy-button-image]: https://vercel.com/button
383
+ [deploy-link]: https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Flobehub%2Flobe-chat&env=OPENAI_API_KEY&envDescription=Find%20your%20OpenAI%20API%20Key%20by%20click%20the%20right%20Learn%20More%20button.&envLink=https%3A%2F%2Fplatform.openai.com%2Faccount%2Fapi-keys&project-name=lobe-chat&repository-name=lobe-chat
377
384
  [discord-link]: https://discord.gg/AYFPHvv2jT
378
385
  [discord-shield]: https://img.shields.io/discord/1127171173982154893?color=5865F2&label=discord&labelColor=black&logo=discord&logoColor=white&style=flat-square
379
386
  [discord-shield-badge]: https://img.shields.io/discord/1127171173982154893?color=5865F2&label=discord&labelColor=black&logo=discord&logoColor=white&style=for-the-badge
@@ -0,0 +1,37 @@
1
+ ## 架构设计
2
+
3
+ LobeChat 是一个基于 Next.js 框架构建的 AI 会话应用,旨在提供一个 AI 生产力平台,使用户能够与 AI 进行自然语言交互。以下是 LobeChat 的架构设计介稿:
4
+
5
+ ## 应用架构概览
6
+
7
+ LobeChat 的整体架构由前端、EdgeRuntime API、Agents 市场、插件市场和独立插件组成。这些组件相互协作,以提供完整的 AI 体验。
8
+
9
+ ## 前端架构
10
+
11
+ LobeChat 的前端采用 Next.js 框架,利用其强大的 SSR(服务器端渲染)能力和路由功能。前端使用了一系列技术栈,包括 antd 组件库和 lobe-ui AIGC 组件库、zustand 状态管理、swr 请求库、i18next 国际化库等。这些技术栈共同支持了 LobeChat 的功能和特性。
12
+
13
+ 前端架构中的组件包括 app、components、config、const、features、helpers、hooks、layout、locales、migrations、prompts、services、store、styles、types 和 utils。每个组件都有特定的职责,并与其他组件协同工作,以实现不同的功能。
14
+
15
+ ## Edge Runtime API
16
+
17
+ Edge Runtime API 是 LobeChat 的核心组件之一,负责处理 AI 会话的核心逻辑。它提供了与 AI 引擎的交互接口,包括自然语言处理、意图识别和回复生成等。EdgeRuntime API 与前端进行通信,接收用户的输入并返回相应的回复。
18
+
19
+ ## Agents 市场
20
+
21
+ Agents 市场是 LobeChat 的一个重要组成部分,它提供了各种不同场景的 AI Agent,用于处理特定的任务和领域。Agents 市场还提供了使用和上传 Agent 的功能,使用户能够发现其他人制作的 Agent ,也可以一键分享自己的 Agent 到市场上。
22
+
23
+ ## 插件市场
24
+
25
+ 插件市场是 LobeChat 的另一个关键组件,它提供了各种插件,用于扩展 LobeChat 的功能和特性。插件可以是独立的功能模块,也可以与 Agents 市场的 Agent 进行集成。在会话中,助手将自动识别用户的输入,并识别适合的插件并传递给相应的插件进行处理,并返回处理结果。
26
+
27
+ ## 安全性和性能优化
28
+
29
+ LobeChat 的安全性策略包括身份验证和权限管理。用户需要进行身份验证后才能使用 LobeChat,同时根据用户的权限进行相应的操作限制。
30
+
31
+ 为了优化性能,LobeChat 使用了 Next.js 的 SSR 功能,实现了快速的页面加载和响应时间。此外,还采用了一系列的性能优化措施,包括代码分割、缓存和资源压缩等。
32
+
33
+ ## 开发和部署流程
34
+
35
+ LobeChat 的开发流程包括版本控制、测试、持续集成和持续部署。开发团队使用版本控制系统进行代码管理,并进行单元测试和集成测试以确保代码质量。持续集成和持续部署流程确保了代码的快速交付和部署。
36
+
37
+ 以上是 LobeChat 的架构设计介绍简介,详细解释了各个组件的职责和协作方式,以及设计决策对应用功能和性能的影响。
@@ -0,0 +1,127 @@
1
+ # LobeChat 会话 API 实现逻辑
2
+
3
+ LobeChat 的大模型 AI 实现主要依赖于 OpenAI 的 API,包括后端的核心会话 API 和前端的集成 API。接下来,我们将分别介绍后端和前端的实现思路和代码。
4
+
5
+ ## 后端实现
6
+
7
+ 以下代码中移除了鉴权、错误处理等逻辑,仅保留了核心的主要功能逻辑。
8
+
9
+ ### 核心会话 API
10
+
11
+ 在 `src/app/api/openai/chat/handler.ts` 文件中,我们定义了 `POST` 方法,该方法首先从请求中解析出 payload 数据(即客户端发送的会话内容),然后从请求中获取 OpenAI 的授权信息。之后,我们创建一个 `openai` 对象,并调用 `createChatCompletion` 方法,该方法负责发送会话请求到 OpenAI 并返回结果。
12
+
13
+ ```ts
14
+ export const POST = async (req: Request) => {
15
+ const payload = await req.json();
16
+
17
+ const { apiKey, endpoint } = getOpenAIAuthFromRequest(req);
18
+
19
+ const openai = createOpenai(apiKey, endpoint);
20
+
21
+ return createChatCompletion({ openai, payload });
22
+ };
23
+ ```
24
+
25
+ ### 会话结果处理
26
+
27
+ 在 `src/app/api/openai/chat/createChatCompletion.ts` 文件中,我们定义了 `createChatCompletion` 方法,该方法首先对 payload 数据进行预处理,然后调用 OpenAI 的 `chat.completions.create` 方法发送请求,并使用 [Vercel AI SDK](https://sdk.vercel.ai/docs) 中的 `OpenAIStream` 将返回的结果转化为流式响应。
28
+
29
+ ```ts
30
+ import { OpenAIStream, StreamingTextResponse } from 'ai';
31
+
32
+ export const createChatCompletion = async ({ payload, openai }: CreateChatCompletionOptions) => {
33
+ const { messages, ...params } = payload;
34
+
35
+ const formatMessages = messages.map((m) => ({
36
+ content: m.content,
37
+ name: m.name,
38
+ role: m.role,
39
+ }));
40
+
41
+ const response = await openai.chat.completions.create(
42
+ {
43
+ messages: formatMessages,
44
+ ...params,
45
+ stream: true,
46
+ },
47
+ { headers: { Accept: '*/*' } },
48
+ );
49
+ const stream = OpenAIStream(response);
50
+ return new StreamingTextResponse(stream);
51
+ };
52
+ ```
53
+
54
+ ## 前端实现
55
+
56
+ ### 前端集成
57
+
58
+ 在 `src/services/chatModel.ts` 文件中,我们定义了 `fetchChatModel` 方法,该方法首先对 payload 数据进行前置处理,然后发送 POST 请求到后端的 `/chat` 接口,并将请求结果返回。
59
+
60
+ ```ts
61
+ export const fetchChatModel = (
62
+ { plugins: enabledPlugins, ...params }: Partial<OpenAIStreamPayload>,
63
+ options?: FetchChatModelOptions,
64
+ ) => {
65
+ const payload = merge(
66
+ {
67
+ model: initialLobeAgentConfig.model,
68
+ stream: true,
69
+ ...initialLobeAgentConfig.params,
70
+ },
71
+ params,
72
+ );
73
+
74
+ const filterFunctions: ChatCompletionFunctions[] = pluginSelectors.enabledSchema(enabledPlugins)(
75
+ usePluginStore.getState(),
76
+ );
77
+
78
+ const functions = filterFunctions.length === 0 ? undefined : filterFunctions;
79
+
80
+ return fetch(OPENAI_URLS.chat, {
81
+ body: JSON.stringify({ ...payload, functions }),
82
+ headers: createHeaderWithOpenAI({ 'Content-Type': 'application/json' }),
83
+ method: 'POST',
84
+ signal: options?.signal,
85
+ });
86
+ };
87
+ ```
88
+
89
+ ### 使用流式获取结果
90
+
91
+ 在 `src/utils/fetch.ts` 文件中,我们定义了 `fetchSSE` 方法,该方法使用流式方法获取数据,当读取到新的数据块时,会调用 `onMessageHandle` 回调函数处理数据块,进而实现打字机输出效果。
92
+
93
+ ```ts
94
+ export const fetchSSE = async (fetchFn: () => Promise<Response>, options: FetchSSEOptions = {}) => {
95
+ const response = await fetchFn();
96
+
97
+ if (!response.ok) {
98
+ const chatMessageError = await getMessageError(response);
99
+
100
+ options.onErrorHandle?.(chatMessageError);
101
+ return;
102
+ }
103
+
104
+ const returnRes = response.clone();
105
+
106
+ const data = response.body;
107
+
108
+ if (!data) return;
109
+
110
+ const reader = data.getReader();
111
+ const decoder = new TextDecoder();
112
+
113
+ let done = false;
114
+
115
+ while (!done) {
116
+ const { value, done: doneReading } = await reader.read();
117
+ done = doneReading;
118
+ const chunkValue = decoder.decode(value);
119
+
120
+ options.onMessageHandle?.(chunkValue);
121
+ }
122
+
123
+ return returnRes;
124
+ };
125
+ ```
126
+
127
+ 以上就是 LobeChat 会话 API 的核心实现。在理解了这些核心代码的基础上,便可以进一步扩展和优化 LobeChat 的 AI 功能。
@@ -0,0 +1,118 @@
1
+ ## 如何开发一个新功能
2
+
3
+ LobeChat 基于 Next.js 框架构建,使用 TypeScript 作为主要开发语言。在开发新功能时,我们需要遵循一定的开发流程,以确保代码的质量和稳定性。大致的流程分为以下五步:
4
+
5
+ 1. 路由:定义路由 (`src/app`)
6
+ 2. 数据结构: 定义数据结构 ( `src/types` )
7
+ 3. 业务功能实现: zustand store (`src/store`)
8
+ 4. 页面展示:书写静态组件 / 页面 (`src/app/<new-page>/features/<new-feature>.tsx`)
9
+ 5. 功能绑定:绑定 store 与页面的触发 (`const [state,function]= useNewStore(s=>[s.state,s.function])`)
10
+
11
+ 我们以 "会话消息" 功能为例,以下是实现这个功能的简要步骤:
12
+
13
+ ## 1. 定义路由
14
+
15
+ 在 `src/app` 目录下,我们需要定义一个新的路由来承载 "会话消息" 页面。一般来说,我们会在 `src/app` 下创建一个新的文件夹,例如 `chat`,并且在这个文件夹中创建 `page.tsx`文件,在该文件中导出 React 组件作为页面的主体。
16
+
17
+ ```tsx
18
+ // src/app/chat/page.tsx
19
+ import ChatPage from './features/chat';
20
+
21
+ export default ChatPage;
22
+ ```
23
+
24
+ ## 2. 定义数据结构
25
+
26
+ 在 `src/types` 目录下,我们需要定义 "会话消息" 的数据结构。例如,我们创建一个 `chat.ts` 文件,并在其中定义 `ChatMessage` 类型:
27
+
28
+ ```ts
29
+ // src/types/chat.ts
30
+
31
+ export type ChatMessage = {
32
+ id: string;
33
+ content: string;
34
+ timestamp: number;
35
+ sender: 'user' | 'bot';
36
+ };
37
+ ```
38
+
39
+ ## 3. 创建 Zustand Store
40
+
41
+ 在 `src/store` 目录下,我们需要创建一个新的 Zustand Store 来管理 "会话消息" 的状态。例如,我们创建一个 `chatStore.ts` 文件,并在其中定义一个 Zustand Store:
42
+
43
+ ```ts
44
+ // src/store/chatStore.ts
45
+ import create from 'zustand';
46
+
47
+ type ChatState = {
48
+ messages: ChatMessage[];
49
+ addMessage: (message: ChatMessage) => void;
50
+ };
51
+
52
+ export const useChatStore = create<ChatState>((set) => ({
53
+ messages: [],
54
+ addMessage: (message) => set((state) => ({ messages: [...state.messages, message] })),
55
+ }));
56
+ ```
57
+
58
+ ## 4. 创建页面与组件
59
+
60
+ 在 `src/app/<new-page>/features/<new-feature>.tsx` 中,我们需要创建一个新的页面或组件来显示 "会话消息"。在这个文件中,我们可以使用上面创建的 Zustand Store,以及 Ant Design 的组件来构建 UI:
61
+
62
+ ```jsx
63
+ // src/features/chat/index.tsx
64
+ import { List, Typography } from 'antd';
65
+ import { useChatStore } from 'src/store/chatStore';
66
+
67
+ const ChatPage = () => {
68
+ const messages = useChatStore((state) => state.messages);
69
+
70
+ return (
71
+ <List
72
+ dataSource={messages}
73
+ renderItem={(message) => (
74
+ <List.Item>
75
+ <Typography.Text>{message.content}</Typography.Text>
76
+ </List.Item>
77
+ )}
78
+ />
79
+ );
80
+ };
81
+
82
+ export default ChatPage;
83
+ ```
84
+
85
+ ## 5. 功能绑定
86
+
87
+ 在页面或组件中,我们需要将 Zustand Store 的状态和方法绑定到 UI 上。在上面的示例中,我们已经将 `messages` 状态绑定到了列表的 `dataSource` 属性上。现在,我们还需要一个方法来添加新的消息。我们可以在 Zustand Store 中定义这个方法,然后在页面或组件中使用它:
88
+
89
+ ```jsx
90
+ import { Button } from 'antd';
91
+
92
+ const ChatPage = () => {
93
+ const messages = useChatStore((state) => state.messages);
94
+ const addMessage = useChatStore((state) => state.addMessage);
95
+
96
+ const handleSend = () => {
97
+ addMessage({ id: '1', content: 'Hello, world!', timestamp: Date.now(), sender: 'user' });
98
+ };
99
+
100
+ return (
101
+ <>
102
+ <List
103
+ dataSource={messages}
104
+ renderItem={(message) => (
105
+ <List.Item>
106
+ <Typography.Text>{message.content}</Typography.Text>
107
+ </List.Item>
108
+ )}
109
+ />
110
+ <Button onClick={handleSend}>Send</Button>
111
+ </>
112
+ );
113
+ };
114
+
115
+ export default ChatPage;
116
+ ```
117
+
118
+ 以上就是在 LobeChat 中实现 "会话消息" 功能的步骤。当然,在 LobeChat 的实际开发中,真实场景所面临的业务诉求和场景远比上述 demo 复杂,请根据实际情况进行开发。
@@ -0,0 +1,19 @@
1
+ # 资源与参考
2
+
3
+ LobeChat 的设计和开发离不开社区和生态中的优秀项目。我们在设计和开发过程中使用或参考了一些优秀的资源和指南。以下是一些主要的参考资源,供开发者在开发和学习过程中参考:
4
+
5
+ 1. **OpenAI API 指南**:我们使用 OpenAI 的 API 来获取和处理 AI 的会话数据。你可以查看 [OpenAI API 指南](https://platform.openai.com/docs/api-reference/introduction) 了解更多详情。
6
+
7
+ 2. **OpenAI SDK**:我们使用 OpenAI 的 Node.js SDK 来与 OpenAI 的 API 交互。你可以在 [OpenAI SDK](https://github.com/openai/openai-node) 的 GitHub 仓库中查看源码和文档。
8
+
9
+ 3. **AI SDK**:我们使用 Vercel 的 AI SDK 来获取和处理 AI 的会话数据。你可以查看 [AI SDK](https://sdk.vercel.ai/docs) 的文档来了解更多详情。
10
+
11
+ 4. **LangChain**:我们早期的会话功能是基于 LangChain 实现的。你可以访问 [LangChain](https://langchain.com) 来了解更多关于它的信息。
12
+
13
+ 5. **Chat-Next-Web**:Chat Next Web 是一个优秀的项目,LobeChat 的部分功能、Workflow 等参考了它的实现。你可以在 [Chat-Next-Web](https://github.com/Yidadaa/ChatGPT-Next-Web) 的 GitHub 仓库中查看源码和文档。
14
+
15
+ 6. **Next.js 文档**:我们的项目是基于 Next.js 构建的,你可以查看 [Next.js 文档](https://nextjs.org/docs) 来了解更多关于 Next.js 的信息。
16
+
17
+ 7. **FlowGPT**:FlowGPT 是目前全球最大的 Prompt 社区,LobeChat 中的一些 Agent 来自 FlowGPT 的活跃作者。你可以访问 [FlowGPT](https://flowgpt.com/) 来了解更多关于它的信息。
18
+
19
+ 我们会持续更新和补充这个列表,为开发者提供更多的参考资源。
@@ -0,0 +1,79 @@
1
+ # LobeChat 测试指南
2
+
3
+ LobeChat 的测试策略包括单元测试和端到端 (E2E) 测试。下面是每种测试的详细说明:
4
+
5
+ ## 单元测试
6
+
7
+ 单元测试用于测试应用中的独立单元(如组件、函数、工具函数等)的功能。我们使用 [vitest][vitest-url] 进行单元测试。
8
+
9
+ 要运行单元测试,可以使用以下命令:
10
+
11
+ ```
12
+ npm run test
13
+ ```
14
+
15
+ 这将运行所有的单元测试,并生成测试报告。
16
+
17
+ 我们鼓励开发者在编写代码时,同时编写对应的单元测试,以确保代码的质量和稳定性。
18
+
19
+ ## 🚧 端到端测试
20
+
21
+ 端到端测试用于测试应用在真实环境中的功能和性能。它模拟用户的真实操作,并验证应用在不同场景下的表现。
22
+
23
+ 在 LobeChat 中,目前暂时没有集成端到端测试,我们会在后续迭代中逐步引入端到端测试。
24
+
25
+ ## 开发测试
26
+
27
+ ### 1. 单元测试
28
+
29
+ 单元测试是针对应用中的最小可测试单元进行的测试,通常是针对函数、组件或模块进行的测试。在 LobeChat 中,我们使用 [vitest][vitest-url] 进行单元测试。
30
+
31
+ #### 编写测试用例
32
+
33
+ 在编写单元测试之前,您需要创建一个与被测试文件相同的目录,并将测试文件命名为 `<filename>.test.ts`。例如,如果要测试 `src/utils/formatDate.ts` 文件,测试文件应命名为 `src/utils/formatDate.test.ts`。
34
+
35
+ 在测试文件中,您可以使用 `describe` 和 `it` 函数来组织和编写测试用例。`describe` 函数用于创建测试套件,`it` 函数用于编写具体的测试用例。
36
+
37
+ ```typescript
38
+ import { formatNumber } from './formatNumber';
39
+
40
+ describe('formatNumber', () => {
41
+ it('should format number with comma separator', () => {
42
+ const result = formatNumber(1000);
43
+ expect(result).toBe('1,000');
44
+ });
45
+
46
+ it('should return the same number if it is less than 1000', () => {
47
+ const result = formatNumber(500);
48
+ expect(result).toBe('500');
49
+ });
50
+ });
51
+ ```
52
+
53
+ 在测试用例中,您可以使用 `expect` 函数来断言测试结果是否符合预期。`expect` 函数可以与各种匹配器(matchers)一起使用,例如 `toBe`、`toEqual`、`toBeTruthy` 等。
54
+
55
+ #### 运行单元测试
56
+
57
+ 通过运行以下命令来执行单元测试:
58
+
59
+ ```
60
+ npm run test
61
+ ```
62
+
63
+ 这将运行所有的单元测试,并输出测试结果。
64
+
65
+ ## 测试策略
66
+
67
+ 为了编写有效的测试用例,您可以考虑以下测试策略:
68
+
69
+ - **边界条件测试**:测试输入的边界条件,例如最小值、最大值、空值等。
70
+ - **异常情况测试**:测试处理异常情况的代码,例如错误处理、异常情况下的回退等。
71
+ - **功能测试**:测试应用的各个功能模块是否正常工作,包括用户交互、数据处理等。
72
+ - **兼容性测试**:测试应用在不同浏览器和设备上的兼容性。
73
+ - **性能测试**:测试应用在不同负载下的性能表现,例如响应时间、资源占用等。
74
+
75
+ 同时,请确保您的测试用例具有良好的覆盖率,覆盖到应用中的关键代码和功能。
76
+
77
+ 通过合理编写和执行单元测试、集成测试和端到端测试,您可以提高应用的质量和稳定性,并及时发现和修复潜在的问题。
78
+
79
+ [vitest-url]: https://vitest.dev/
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "0.89.4",
3
+ "version": "0.89.6",
4
4
  "description": "An open-source, extensible (Function Calling), high-performance chatbot framework. It supports one-click free deployment of your private ChatGPT/LLM web application",
5
5
  "keywords": [
6
6
  "chatbot",
@@ -13,7 +13,7 @@ import ChatInput from './features/ChatInput';
13
13
  import SideBar from './features/SideBar';
14
14
  import Layout from './layout.desktop';
15
15
 
16
- const Mobile: FC = dynamic(() => import('../(mobile)')) as FC;
16
+ const Mobile: FC = dynamic(() => import('../(mobile)'), { ssr: false }) as FC;
17
17
 
18
18
  const DesktopPage = memo(() => (
19
19
  <ResponsiveIndex Mobile={Mobile}>
@@ -8,7 +8,7 @@ import ResponsiveIndex from '@/components/ResponsiveIndex';
8
8
  import EditPage from '../features/EditPage';
9
9
  import Layout from './layout.desktop';
10
10
 
11
- const Mobile: FC = dynamic(() => import('../(mobile)')) as FC;
11
+ const Mobile: FC = dynamic(() => import('../(mobile)'), { ssr: false }) as FC;
12
12
 
13
13
  const ChatSettings = memo(() => (
14
14
  <ResponsiveIndex Mobile={Mobile}>
@@ -11,7 +11,8 @@ import { AgentsMarketIndexItem } from '@/types/market';
11
11
  import Index from '../index';
12
12
  import Layout from './layout.desktop';
13
13
 
14
- const Mobile: FC = dynamic(() => import('../(mobile)')) as FC;
14
+ const Mobile: FC = dynamic(() => import('../(mobile)'), { ssr: false }) as FC;
15
+
15
16
  export default memo<{ defaultAgents?: AgentsMarketIndexItem[] }>(({ defaultAgents }) => (
16
17
  <ResponsiveIndex Mobile={Mobile}>
17
18
  <Layout>
@@ -8,7 +8,7 @@ import ResponsiveIndex from '@/components/ResponsiveIndex';
8
8
  import Common from '../common';
9
9
  import Layout from './layout.desktop';
10
10
 
11
- const Mobile: FC = dynamic(() => import('../(mobile)')) as FC;
11
+ const Mobile: FC = dynamic(() => import('../(mobile)'), { ssr: false }) as FC;
12
12
 
13
13
  export default memo(() => (
14
14
  <ResponsiveIndex Mobile={Mobile}>
@@ -7,7 +7,7 @@ import ResponsiveLayout from '@/layout/ResponsiveLayout.client';
7
7
 
8
8
  import DesktopLayout from './layout.desktop';
9
9
 
10
- const MobileLayout = dynamic(() => import('../(mobile)/layout.mobile')) as FC;
10
+ const MobileLayout = dynamic(() => import('../(mobile)/layout.mobile'), { ssr: false }) as FC;
11
11
 
12
12
  export default memo(({ children }: PropsWithChildren) => (
13
13
  <ResponsiveLayout Desktop={DesktopLayout} Mobile={MobileLayout}>
@@ -11,6 +11,7 @@ import { DEFAULT_SETTINGS } from '@/const/settings';
11
11
  import AvatarWithUpload from '@/features/AvatarWithUpload';
12
12
  import { localeOptions } from '@/locales/options';
13
13
  import { settingsSelectors, useGlobalStore } from '@/store/global';
14
+ import { usePluginStore } from '@/store/plugin';
14
15
  import { useSessionStore } from '@/store/session';
15
16
  import { switchLang } from '@/utils/switchLang';
16
17
 
@@ -22,6 +23,7 @@ const Common = memo(() => {
22
23
  const { t } = useTranslation('setting');
23
24
  const [form] = AntForm.useForm();
24
25
  const clearSessions = useSessionStore((s) => s.clearSessions);
26
+ const resetPluginSettings = usePluginStore((s) => s.resetPluginSettings);
25
27
 
26
28
  const settings = useGlobalStore(settingsSelectors.currentSettings, isEqual);
27
29
  const [setThemeMode, setSettings, resetSettings] = useGlobalStore((s) => [
@@ -45,6 +47,7 @@ const Common = memo(() => {
45
47
  title: t('danger.reset.confirm'),
46
48
  });
47
49
  }, []);
50
+
48
51
  const handleClear = useCallback(() => {
49
52
  modal.confirm({
50
53
  cancelText: t('cancel', { ns: 'common' }),
@@ -55,6 +58,7 @@ const Common = memo(() => {
55
58
  okText: t('ok', { ns: 'common' }),
56
59
  onOk: () => {
57
60
  clearSessions();
61
+ resetPluginSettings();
58
62
  message.success(t('danger.clear.success'));
59
63
  },
60
64
  title: t('danger.clear.confirm'),
@@ -9,7 +9,7 @@ import Footer from './features/Footer';
9
9
  import Showcase from './features/Showcase';
10
10
  import Layout from './layout.desktop';
11
11
 
12
- const Mobile: FC = dynamic(() => import('../(mobile)')) as FC;
12
+ const Mobile: FC = dynamic(() => import('../(mobile)'), { ssr: false }) as FC;
13
13
 
14
14
  export default memo(() => (
15
15
  <ResponsiveIndex Mobile={Mobile}>
@@ -13,7 +13,7 @@ import { SessionLoadingState } from '../store/initialState';
13
13
  import AutoGenerateInput from './AutoGenerateInput';
14
14
  import BackgroundSwatches from './BackgroundSwatches';
15
15
 
16
- const EmojiPicker = dynamic(() => import('@/components/EmojiPicker'));
16
+ const EmojiPicker = dynamic(() => import('@/components/EmojiPicker'), { ssr: false });
17
17
 
18
18
  const AgentMeta = memo(() => {
19
19
  const { t } = useTranslation('setting');
@@ -6,7 +6,7 @@ import { useTranslation } from 'react-i18next';
6
6
 
7
7
  import { pluginSelectors, usePluginStore } from '@/store/plugin';
8
8
 
9
- const EmojiPicker = dynamic(() => import('@/components/EmojiPicker'));
9
+ const EmojiPicker = dynamic(() => import('@/components/EmojiPicker'), { ssr: false });
10
10
 
11
11
  const MetaForm = memo<{ form: FormInstance; mode?: 'edit' | 'create' }>(({ form, mode }) => {
12
12
  const isEditMode = mode === 'edit';
@@ -10,6 +10,7 @@ const resources = {
10
10
  'ja-JP': ja_JP,
11
11
  'ko-KR': ko_KR,
12
12
  'ru-RU': ru_RU,
13
+ 'zh': zh_CN,
13
14
  'zh-CN': zh_CN,
14
15
  'zh-TW': zh_TW,
15
16
  } as const;
@@ -20,13 +20,14 @@ import { PluginDispatch, pluginManifestReducer } from './reducers/manifest';
20
20
  const t = setNamespace('plugin');
21
21
 
22
22
  /**
23
- * 代理行为接口
23
+ * 插件接口
24
24
  */
25
25
  export interface PluginAction {
26
26
  checkLocalEnabledPlugins: (sessions: LobeSessions) => void;
27
27
  deletePluginSettings: (id: string) => void;
28
28
  dispatchPluginManifest: (payload: PluginDispatch) => void;
29
29
  fetchPluginManifest: (identifier: string) => Promise<void>;
30
+ resetPluginSettings: () => void;
30
31
  updateManifestLoadingState: (key: string, value: boolean | undefined) => void;
31
32
  updatePluginSettings: <T>(id: string, settings: Partial<T>) => void;
32
33
  useFetchPluginList: () => SWRResponse<LobeChatPluginsMarketIndex>;
@@ -71,7 +72,6 @@ export const createPluginSlice: StateCreator<
71
72
 
72
73
  set({ pluginManifestMap: nextManifest }, false, t('dispatchPluginManifest', payload));
73
74
  },
74
-
75
75
  fetchPluginManifest: async (name) => {
76
76
  const plugin = pluginSelectors.getPluginMetaById(name)(get());
77
77
  // 1. 校验文件
@@ -113,6 +113,9 @@ export const createPluginSlice: StateCreator<
113
113
  // 4. 存储 manifest 信息
114
114
  get().dispatchPluginManifest({ id: plugin.identifier, plugin: data, type: 'addManifest' });
115
115
  },
116
+ resetPluginSettings: () => {
117
+ set({ pluginsSettings: {} }, false, t('resetPluginSettings'));
118
+ },
116
119
  updateManifestLoadingState: (key, value) => {
117
120
  set(
118
121
  produce((draft) => {