@lobehub/chat 0.118.4 → 0.118.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 +50 -0
- package/README.md +8 -8
- package/README.zh-CN.md +8 -8
- package/docs/Development/Chat-API.zh-CN.md +90 -52
- package/next.config.mjs +0 -1
- package/package.json +1 -1
- package/src/app/chat/features/ChatHeader/ShareButton/Preview.tsx +1 -1
- package/src/features/Conversation/{ChatList/Actions → Actions}/Assistant.tsx +3 -1
- package/src/features/Conversation/{ChatList/Actions → Actions}/Error.tsx +3 -1
- package/src/features/Conversation/{ChatList/Actions → Actions}/Fallback.tsx +4 -1
- package/src/features/Conversation/{ChatList/Actions → Actions}/Function.tsx +4 -1
- package/src/features/Conversation/{ChatList/Actions → Actions}/User.tsx +3 -1
- package/src/features/Conversation/{ChatList/Actions → Actions}/index.ts +1 -2
- package/src/features/Conversation/{ChatList/Error → Error}/InvalidAccess.tsx +2 -1
- package/src/features/Conversation/{ChatList/Error → Error}/OpenAPIKey.tsx +1 -1
- package/src/features/Conversation/{ChatList/Error → Error}/OpenAiBizError.tsx +2 -1
- package/src/features/Conversation/{ChatList/Error → Error}/Plugin/PluginError.tsx +3 -1
- package/src/features/Conversation/{ChatList/Error → Error}/Plugin/PluginSettings.tsx +2 -1
- package/src/features/Conversation/{ChatList/Error → Error}/index.tsx +1 -1
- package/src/features/Conversation/{ChatList/Extras → Extras}/Translate.tsx +1 -1
- package/src/features/Conversation/{ChatList/Extras → Extras}/index.ts +1 -2
- package/src/features/Conversation/{ChatList/Messages → Messages}/Default.tsx +1 -1
- package/src/features/Conversation/{ChatList/Messages → Messages}/User.tsx +1 -1
- package/src/features/Conversation/{ChatList/Messages → Messages}/index.ts +5 -5
- package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/Loading.tsx +10 -11
- package/src/features/Conversation/components/ChatList/ActionsBar.tsx +27 -0
- package/src/features/Conversation/components/ChatList/HistoryDivider.tsx +23 -0
- package/src/features/Conversation/components/ChatList/Item.tsx +236 -0
- package/src/features/Conversation/components/ChatList/index.tsx +88 -0
- package/src/features/Conversation/components/ChatList/style.ts +10 -0
- package/src/features/Conversation/{ChatList → container}/index.tsx +6 -7
- package/src/features/Conversation/hooks/useChatListActionsBar.tsx +43 -0
- package/src/features/Conversation/index.tsx +3 -3
- package/src/hooks/useIsPWA.ts +3 -4
- package/src/store/chat/store.ts +20 -6
- package/src/store/middleware/createHyperStorage/index.test.ts +341 -0
- package/src/store/middleware/createHyperStorage/index.ts +8 -6
- package/src/store/middleware/createHyperStorage/indexedDB.test.ts +64 -0
- package/src/store/middleware/createHyperStorage/keyMapper.ts +4 -4
- package/src/store/middleware/createHyperStorage/type.ts +6 -2
- package/src/store/middleware/createHyperStorage/urlStorage.test.ts +84 -0
- package/src/store/middleware/createHyperStorage/urlStorage.ts +25 -8
- package/src/store/session/store.ts +24 -9
- package/src/utils/matchMedia.ts +10 -0
- package/src/utils/screen.ts +14 -0
- /package/src/features/Conversation/{ChatList/Actions → Actions}/customAction.ts +0 -0
- /package/src/features/Conversation/{ChatList/Error → Error}/ApiKeyForm.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Error → Error}/ErrorActionContainer.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Error → Error}/style.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Extras → Extras}/Assistant.test.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Extras → Extras}/Assistant.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Extras → Extras}/ExtraContainer.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Extras → Extras}/TTS/FilePlayer.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Extras → Extras}/TTS/InitPlayer.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Extras → Extras}/TTS/Player.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Extras → Extras}/TTS/index.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Extras → Extras}/User.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Extras → Extras}/type.ts +0 -0
- /package/src/features/Conversation/{ChatList/Messages → Messages}/Assistant.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Messages → Messages}/Function.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Inspector/PluginResultJSON.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Inspector/Settings.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Inspector/index.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Inspector/style.ts +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/BuiltinType/index.test.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/BuiltinType/index.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/DefaultType/IFrameRender/index.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/DefaultType/SystemJsRender/index.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/DefaultType/SystemJsRender/utils.ts +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/DefaultType/index.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/MarkdownType/index.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/StandaloneType/Iframe.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/StandaloneType/index.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/index.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/useParseContent.ts +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/utils/iframeOnReady.test.ts +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/utils/iframeOnReady.ts +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/utils/listenToPlugin.test.ts +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/utils/listenToPlugin.ts +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/utils/pluginSettings.test.ts +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/utils/pluginSettings.ts +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/utils/pluginState.test.ts +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/utils/pluginState.ts +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/utils/postMessage.test.ts +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/utils/postMessage.ts +0 -0
- /package/src/features/Conversation/{ChatList/Loading.tsx → components/BubblesLoading.tsx} +0 -0
- /package/src/features/Conversation/{ChatList → components}/OTPInput.tsx +0 -0
- /package/src/features/Conversation/{ScrollAnchor → components/ScrollAnchor}/index.tsx +0 -0
- /package/src/features/Conversation/{ScrollAnchor → components/ScrollAnchor}/useAtBottom.ts +0 -0
- /package/src/features/Conversation/{ChatList → components}/SkeletonList.tsx +0 -0
- /package/src/features/Conversation/{useInitConversation.ts → hooks/useInitConversation.ts} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,56 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
### [Version 0.118.6](https://github.com/lobehub/lobe-chat/compare/v0.118.5...v0.118.6)
|
|
6
|
+
|
|
7
|
+
<sup>Released on **2024-01-03**</sup>
|
|
8
|
+
|
|
9
|
+
#### ♻ Code Refactoring
|
|
10
|
+
|
|
11
|
+
- **misc**: Migration the ChatList into Conversation.
|
|
12
|
+
|
|
13
|
+
<br/>
|
|
14
|
+
|
|
15
|
+
<details>
|
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
17
|
+
|
|
18
|
+
#### Code refactoring
|
|
19
|
+
|
|
20
|
+
- **misc**: Migration the ChatList into Conversation, closes [#916](https://github.com/lobehub/lobe-chat/issues/916) ([6ee3795](https://github.com/lobehub/lobe-chat/commit/6ee3795))
|
|
21
|
+
|
|
22
|
+
</details>
|
|
23
|
+
|
|
24
|
+
<div align="right">
|
|
25
|
+
|
|
26
|
+
[](#readme-top)
|
|
27
|
+
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
### [Version 0.118.5](https://github.com/lobehub/lobe-chat/compare/v0.118.4...v0.118.5)
|
|
31
|
+
|
|
32
|
+
<sup>Released on **2024-01-02**</sup>
|
|
33
|
+
|
|
34
|
+
#### 🐛 Bug Fixes
|
|
35
|
+
|
|
36
|
+
- **misc**: Mobile device return to the previous page error.
|
|
37
|
+
|
|
38
|
+
<br/>
|
|
39
|
+
|
|
40
|
+
<details>
|
|
41
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
42
|
+
|
|
43
|
+
#### What's fixed
|
|
44
|
+
|
|
45
|
+
- **misc**: Mobile device return to the previous page error, closes [#886](https://github.com/lobehub/lobe-chat/issues/886) ([99cfc0f](https://github.com/lobehub/lobe-chat/commit/99cfc0f))
|
|
46
|
+
|
|
47
|
+
</details>
|
|
48
|
+
|
|
49
|
+
<div align="right">
|
|
50
|
+
|
|
51
|
+
[](#readme-top)
|
|
52
|
+
|
|
53
|
+
</div>
|
|
54
|
+
|
|
5
55
|
### [Version 0.118.4](https://github.com/lobehub/lobe-chat/compare/v0.118.3...v0.118.4)
|
|
6
56
|
|
|
7
57
|
<sup>Released on **2024-01-02**</sup>
|
package/README.md
CHANGED
|
@@ -208,14 +208,14 @@ Our marketplace is not just a showcase platform but also a collaborative space.
|
|
|
208
208
|
|
|
209
209
|
<!-- AGENT LIST -->
|
|
210
210
|
|
|
211
|
-
| Recent Submits
|
|
212
|
-
|
|
|
213
|
-
| [
|
|
214
|
-
| [
|
|
215
|
-
| [
|
|
216
|
-
| [
|
|
217
|
-
|
|
218
|
-
> 📊 Total agents: [<kbd>**
|
|
211
|
+
| Recent Submits | Description |
|
|
212
|
+
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
213
|
+
| [Amazon Title Assistant](https://chat-preview.lobehub.com/market?agent=amazon)<br/><sup>By **[cm2457618290](https://github.com/cm2457618290)** on **2024-01-02**</sup> | Provide product keywords or product links to automatically write titles and product introductions<br/>`assistant` |
|
|
214
|
+
| [Exam Assistant](https://chat-preview.lobehub.com/market?agent=generador-examenes)<br/><sup>By **[aitorroma](https://github.com/aitorroma)** on **2024-01-02**</sup> | I am a skills summary assistant and cannot conduct interactive exams. However, I can help you summarize your skills and knowledge in a clear and concise format.<br/>`exam` `learning` `statistics` |
|
|
215
|
+
| [Teaching Mentor](https://chat-preview.lobehub.com/market?agent=ljrwwjl-development)<br/><sup>By **[ljr1314](https://github.com/ljr1314)** on **2024-01-02**</sup> | A friendly and helpful mentor who customizes explanations and examples based on the user's learning level and interests to ensure clarity. Ask 4 questions, then provide explanations, examples, and analogies, and ensure understanding through questioning. Finally, have the user explain the topic in their own words and provide an example. End on a positive note and encourage further learning.<br/>`mentor` `education` `explanation` `communication` `learning` |
|
|
216
|
+
| [MidjourneyGPT](https://chat-preview.lobehub.com/market?agent=prompt-composition)<br/><sup>By **[richards199999](https://github.com/richards199999)** on **2023-12-30**</sup> | Write perfect and beautiful prompts for Midjourney. (Including V6!)<br/>`midjourney` `prompt` `ai` |
|
|
217
|
+
|
|
218
|
+
> 📊 Total agents: [<kbd>**87**</kbd> ](https://github.com/lobehub/lobe-chat-agents)
|
|
219
219
|
|
|
220
220
|
<!-- AGENT LIST -->
|
|
221
221
|
|
package/README.zh-CN.md
CHANGED
|
@@ -184,14 +184,14 @@ LobeChat 的插件生态系统是其核心功能的重要扩展,它极大地
|
|
|
184
184
|
|
|
185
185
|
<!-- AGENT LIST -->
|
|
186
186
|
|
|
187
|
-
| 最近新增
|
|
188
|
-
|
|
|
189
|
-
| [
|
|
190
|
-
| [
|
|
191
|
-
| [
|
|
192
|
-
| [
|
|
193
|
-
|
|
194
|
-
> 📊 Total agents: [<kbd>**
|
|
187
|
+
| 最近新增 | 助手说明 |
|
|
188
|
+
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
189
|
+
| [Amazon Title Assistant](https://chat-preview.lobehub.com/market?agent=amazon)<br/><sup>By **[cm2457618290](https://github.com/cm2457618290)** on **2024-01-02**</sup> | Provide product keywords or product links to automatically write titles and product introductions<br/>`assistant` |
|
|
190
|
+
| [考试助手](https://chat-preview.lobehub.com/market?agent=generador-examenes)<br/><sup>By **[aitorroma](https://github.com/aitorroma)** on **2024-01-02**</sup> | 我是一个技能总结助手,无法进行互动式考试。但我可以帮助你以清晰简洁的格式总结你的技能和知识。<br/>`考试` `学习` `统计` |
|
|
191
|
+
| [教学导师](https://chat-preview.lobehub.com/market?agent=ljrwwjl-development)<br/><sup>By **[ljr1314](https://github.com/ljr1314)** on **2024-01-02**</sup> | 友好乐于助人的导师,根据用户的学习水平和兴趣定制解释和示例,确保简洁明了。问 4 个问题,然后提供解释、例子和类比,并通过提问确保用户理解。最后让用户用自己的语言解释主题,并给出一个例子。以积极正面的方式结束,并鼓励用户深入学习。<br/>`导师` `教育` `解释` `交流` `学习` |
|
|
192
|
+
| [MidjourneyGPT](https://chat-preview.lobehub.com/market?agent=prompt-composition)<br/><sup>By **[richards199999](https://github.com/richards199999)** on **2023-12-30**</sup> | 为 Midjourney 编写完美而美丽的提示。(包括 V6!)<br/>`midjourney` `prompt` `ai` |
|
|
193
|
+
|
|
194
|
+
> 📊 Total agents: [<kbd>**87**</kbd> ](https://github.com/lobehub/lobe-chat-agents)
|
|
195
195
|
|
|
196
196
|
<!-- AGENT LIST -->
|
|
197
197
|
|
|
@@ -17,46 +17,70 @@ LobeChat 的大模型 AI 实现主要依赖于 OpenAI 的 API,包括后端的
|
|
|
17
17
|
|
|
18
18
|
### 核心会话 API
|
|
19
19
|
|
|
20
|
-
在 `src/app/api/openai/chat/
|
|
20
|
+
在 `src/app/api/openai/chat/route.ts` 中,定义了一个处理 POST 请求的方法,主要负责从请求体中提取 `OpenAIChatStreamPayload` 类型的 payload,并使用 `createBizOpenAI` 函数根据请求和模型信息创建 OpenAI 实例。随后,该方法调用 `createChatCompletion` 来处理实际的会话,并返回响应结果。如果创建 OpenAI 实例过程中出现错误,则直接返回错误响应。
|
|
21
21
|
|
|
22
22
|
```ts
|
|
23
23
|
export const POST = async (req: Request) => {
|
|
24
|
-
const payload = await req.json();
|
|
24
|
+
const payload = (await req.json()) as OpenAIChatStreamPayload;
|
|
25
25
|
|
|
26
|
-
const
|
|
26
|
+
const openaiOrErrResponse = createBizOpenAI(req, payload.model);
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
// if resOrOpenAI is a Response, it means there is an error,just return it
|
|
29
|
+
if (openaiOrErrResponse instanceof Response) return openaiOrErrResponse;
|
|
29
30
|
|
|
30
|
-
return createChatCompletion({ openai, payload });
|
|
31
|
+
return createChatCompletion({ openai: openaiOrErrResponse, payload });
|
|
31
32
|
};
|
|
32
33
|
```
|
|
33
34
|
|
|
34
35
|
### 会话结果处理
|
|
35
36
|
|
|
36
|
-
|
|
37
|
+
而在 `src/app/api/openai/chat/createChatCompletion.ts` 文件中,`createChatCompletion` 方法主要负责与 OpenAI API 进行交互,处理会话请求。它首先对 payload 中的消息进行预处理,然后通过 `openai.chat.completions.create` 方法发送 API 请求,并使用 `OpenAIStream` 将返回的响应转换为流式格式。如果在 API 调用过程中出现错误,方法将生成并处理相应的错误响应。
|
|
37
38
|
|
|
38
39
|
```ts
|
|
39
40
|
import { OpenAIStream, StreamingTextResponse } from 'ai';
|
|
40
41
|
|
|
41
42
|
export const createChatCompletion = async ({ payload, openai }: CreateChatCompletionOptions) => {
|
|
43
|
+
// 预处理消息
|
|
42
44
|
const { messages, ...params } = payload;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
45
|
+
// 发送 API 请求
|
|
46
|
+
try {
|
|
47
|
+
const response = await openai.chat.completions.create(
|
|
48
|
+
{
|
|
49
|
+
messages,
|
|
50
|
+
...params,
|
|
51
|
+
stream: true,
|
|
52
|
+
} as unknown as OpenAI.ChatCompletionCreateParamsStreaming,
|
|
53
|
+
{ headers: { Accept: '*/*' } },
|
|
54
|
+
);
|
|
55
|
+
const stream = OpenAIStream(response);
|
|
56
|
+
return new StreamingTextResponse(stream);
|
|
57
|
+
} catch (error) {
|
|
58
|
+
// 检查错误是否为 OpenAI APIError
|
|
59
|
+
if (error instanceof OpenAI.APIError) {
|
|
60
|
+
let errorResult: any;
|
|
61
|
+
// 如果错误是 OpenAI APIError,那么会有一个 error 对象
|
|
62
|
+
if (error.error) {
|
|
63
|
+
errorResult = error.error;
|
|
64
|
+
} else if (error.cause) {
|
|
65
|
+
errorResult = error.cause;
|
|
66
|
+
}
|
|
67
|
+
// 如果没有其他请求错误,错误对象是一个类似 Response 的对象
|
|
68
|
+
else {
|
|
69
|
+
errorResult = { headers: error.headers, stack: error.stack, status: error.status };
|
|
70
|
+
}
|
|
71
|
+
console.error(errorResult);
|
|
72
|
+
// 返回错误响应
|
|
73
|
+
return createErrorResponse(ChatErrorType.OpenAIBizError, {
|
|
74
|
+
endpoint: openai.baseURL,
|
|
75
|
+
error: errorResult,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
console.error(error);
|
|
79
|
+
return createErrorResponse(ChatErrorType.InternalServerError, {
|
|
80
|
+
endpoint: openai.baseURL,
|
|
81
|
+
error: JSON.stringify(error),
|
|
82
|
+
});
|
|
83
|
+
}
|
|
60
84
|
};
|
|
61
85
|
```
|
|
62
86
|
|
|
@@ -64,35 +88,45 @@ export const createChatCompletion = async ({ payload, openai }: CreateChatComple
|
|
|
64
88
|
|
|
65
89
|
### 前端集成
|
|
66
90
|
|
|
67
|
-
在 `src/services/
|
|
91
|
+
在 `src/services/chat.ts` 文件中,我们定义了 `ChatService` 类。这个类提供了一些方法来处理与 OpenAI 聊天 API 的交互。
|
|
92
|
+
|
|
93
|
+
`createAssistantMessage` 方法用于创建一个新的助手消息。它接收一个包含插件、消息和其他参数的对象,以及一个可选的 `FetchOptions` 对象。这个方法会合并默认的代理配置和传入的参数,预处理消息和工具,然后调用 `getChatCompletion` 方法获取聊天完成任务。
|
|
94
|
+
|
|
95
|
+
`getChatCompletion` 方法用于获取聊天完成任务。它接收一个 `OpenAIChatStreamPayload` 对象和一个可选的 `FetchOptions` 对象。这个方法会合并默认的代理配置和传入的参数,然后发送 POST 请求到 OpenAI 的聊天 API。
|
|
96
|
+
|
|
97
|
+
`runPluginApi` 方法用于运行插件 API 并获取结果。它接收一个 `PluginRequestPayload` 对象和一个可选的 `FetchOptions` 对象。这个方法会从工具存储中获取状态,通过插件标识符获取插件设置和清单,然后发送 POST 请求到插件的网关 URL。
|
|
98
|
+
|
|
99
|
+
`fetchPresetTaskResult` 方法用于获取预设任务的结果。它使用 `fetchAIFactory` 工厂函数创建一个新的函数,这个函数接收一个聊天完成任务的参数,并返回一个 Promise。当 Promise 解析时,返回的结果是聊天完成任务的结果。
|
|
100
|
+
|
|
101
|
+
`processMessages` 方法用于处理聊天消息。它接收一个聊天消息数组,一个可选的模型名称,和一个可选的工具数组。这个方法会处理消息内容,将输入的 `messages` 数组映射为 `OpenAIChatMessage` 类型的数组,如果存在启用的工具,将工具的系统角色添加到系统消息中。
|
|
68
102
|
|
|
69
103
|
```ts
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
95
|
-
}
|
|
104
|
+
class ChatService {
|
|
105
|
+
// 创建一个新的助手消息
|
|
106
|
+
createAssistantMessage(params: object, fetchOptions?: FetchOptions) {
|
|
107
|
+
// 实现细节...
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// 获取聊天完成任务
|
|
111
|
+
getChatCompletion(payload: OpenAIChatStreamPayload, fetchOptions?: FetchOptions) {
|
|
112
|
+
// 实现细节...
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// 运行插件 API 并获取结果
|
|
116
|
+
runPluginApi(payload: PluginRequestPayload, fetchOptions?: FetchOptions) {
|
|
117
|
+
// 实现细节...
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// 获取预设任务的结果
|
|
121
|
+
fetchPresetTaskResult() {
|
|
122
|
+
// 实现细节...
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// 处理聊天消息
|
|
126
|
+
processMessages(messages: ChatMessage[], modelName?: string, tools?: Tool[]) {
|
|
127
|
+
// 实现细节...
|
|
128
|
+
}
|
|
129
|
+
}
|
|
96
130
|
```
|
|
97
131
|
|
|
98
132
|
### 使用流式获取结果
|
|
@@ -103,6 +137,7 @@ export const fetchChatModel = (
|
|
|
103
137
|
export const fetchSSE = async (fetchFn: () => Promise<Response>, options: FetchSSEOptions = {}) => {
|
|
104
138
|
const response = await fetchFn();
|
|
105
139
|
|
|
140
|
+
// 如果不 ok 说明有请求错误
|
|
106
141
|
if (!response.ok) {
|
|
107
142
|
const chatMessageError = await getMessageError(response);
|
|
108
143
|
|
|
@@ -115,7 +150,7 @@ export const fetchSSE = async (fetchFn: () => Promise<Response>, options: FetchS
|
|
|
115
150
|
const data = response.body;
|
|
116
151
|
|
|
117
152
|
if (!data) return;
|
|
118
|
-
|
|
153
|
+
let output = '';
|
|
119
154
|
const reader = data.getReader();
|
|
120
155
|
const decoder = new TextDecoder();
|
|
121
156
|
|
|
@@ -124,11 +159,14 @@ export const fetchSSE = async (fetchFn: () => Promise<Response>, options: FetchS
|
|
|
124
159
|
while (!done) {
|
|
125
160
|
const { value, done: doneReading } = await reader.read();
|
|
126
161
|
done = doneReading;
|
|
127
|
-
const chunkValue = decoder.decode(value);
|
|
162
|
+
const chunkValue = decoder.decode(value, { stream: true });
|
|
128
163
|
|
|
164
|
+
output += chunkValue;
|
|
129
165
|
options.onMessageHandle?.(chunkValue);
|
|
130
166
|
}
|
|
131
167
|
|
|
168
|
+
await options?.onFinish?.(output);
|
|
169
|
+
|
|
132
170
|
return returnRes;
|
|
133
171
|
};
|
|
134
172
|
```
|
package/next.config.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobehub/chat",
|
|
3
|
-
"version": "0.118.
|
|
3
|
+
"version": "0.118.6",
|
|
4
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.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"framework",
|
|
@@ -5,7 +5,7 @@ import { useTranslation } from 'react-i18next';
|
|
|
5
5
|
import { Flexbox } from 'react-layout-kit';
|
|
6
6
|
|
|
7
7
|
import pkg from '@/../package.json';
|
|
8
|
-
import ChatList from '@/features/Conversation/
|
|
8
|
+
import ChatList from '@/features/Conversation/container';
|
|
9
9
|
import { useSessionStore } from '@/store/session';
|
|
10
10
|
import { agentSelectors, sessionSelectors } from '@/store/session/selectors';
|
|
11
11
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { ActionIconGroup
|
|
1
|
+
import { ActionIconGroup } from '@lobehub/ui';
|
|
2
2
|
import { memo } from 'react';
|
|
3
3
|
|
|
4
|
+
import { RenderAction } from '../components/ChatList';
|
|
5
|
+
import { useChatListActionsBar } from '../hooks/useChatListActionsBar';
|
|
4
6
|
import { ErrorActionsBar } from './Error';
|
|
5
7
|
import { useCustomActions } from './customAction';
|
|
6
8
|
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { ActionIconGroup
|
|
1
|
+
import { ActionIconGroup } from '@lobehub/ui';
|
|
2
2
|
import { ActionsBarProps } from '@lobehub/ui/es/ChatList/ActionsBar';
|
|
3
3
|
import { memo } from 'react';
|
|
4
4
|
|
|
5
|
+
import { useChatListActionsBar } from '../hooks/useChatListActionsBar';
|
|
6
|
+
|
|
5
7
|
export const ErrorActionsBar = memo<ActionsBarProps>(({ text, onActionClick }) => {
|
|
6
8
|
const { regenerate, del } = useChatListActionsBar(text);
|
|
7
9
|
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import { ActionIconGroup
|
|
1
|
+
import { ActionIconGroup } from '@lobehub/ui';
|
|
2
2
|
import { memo } from 'react';
|
|
3
3
|
|
|
4
|
+
import { RenderAction } from '../components/ChatList';
|
|
5
|
+
import { useChatListActionsBar } from '../hooks/useChatListActionsBar';
|
|
6
|
+
|
|
4
7
|
export const DefaultActionsBar: RenderAction = memo(({ text, onActionClick }) => {
|
|
5
8
|
const { del } = useChatListActionsBar(text);
|
|
6
9
|
return (
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import { ActionIconGroup
|
|
1
|
+
import { ActionIconGroup } from '@lobehub/ui';
|
|
2
2
|
import { memo } from 'react';
|
|
3
3
|
|
|
4
|
+
import { RenderAction } from '../components/ChatList';
|
|
5
|
+
import { useChatListActionsBar } from '../hooks/useChatListActionsBar';
|
|
6
|
+
|
|
4
7
|
export const FunctionActionsBar: RenderAction = memo(({ text, onActionClick }) => {
|
|
5
8
|
const { regenerate, divider, del } = useChatListActionsBar(text);
|
|
6
9
|
return (
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { ActionIconGroup
|
|
1
|
+
import { ActionIconGroup } from '@lobehub/ui';
|
|
2
2
|
import { memo } from 'react';
|
|
3
3
|
|
|
4
|
+
import { RenderAction } from '../components/ChatList';
|
|
5
|
+
import { useChatListActionsBar } from '../hooks/useChatListActionsBar';
|
|
4
6
|
import { useCustomActions } from './customAction';
|
|
5
7
|
|
|
6
8
|
export const UserActionsBar: RenderAction = memo(({ text, onActionClick }) => {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { ChatListProps } from '@lobehub/ui';
|
|
2
|
-
|
|
3
1
|
import { useChatStore } from '@/store/chat';
|
|
4
2
|
|
|
3
|
+
import { ChatListProps } from '../components/ChatList';
|
|
5
4
|
import { AssistantActionsBar } from './Assistant';
|
|
6
5
|
import { DefaultActionsBar } from './Fallback';
|
|
7
6
|
import { FunctionActionsBar } from './Function';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Icon
|
|
1
|
+
import { Icon } from '@lobehub/ui';
|
|
2
2
|
import { Button, Input, Segmented } from 'antd';
|
|
3
3
|
import { KeySquare, SquareAsterisk } from 'lucide-react';
|
|
4
4
|
import { memo, useState } from 'react';
|
|
@@ -8,6 +8,7 @@ import { Flexbox } from 'react-layout-kit';
|
|
|
8
8
|
import { useChatStore } from '@/store/chat';
|
|
9
9
|
import { useGlobalStore } from '@/store/global';
|
|
10
10
|
|
|
11
|
+
import { RenderErrorMessage } from '../components/ChatList';
|
|
11
12
|
import APIKeyForm from './ApiKeyForm';
|
|
12
13
|
import { ErrorActionContainer, FormAction } from './style';
|
|
13
14
|
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { Highlighter
|
|
1
|
+
import { Highlighter } from '@lobehub/ui';
|
|
2
2
|
import { memo } from 'react';
|
|
3
3
|
import { Flexbox } from 'react-layout-kit';
|
|
4
4
|
|
|
5
|
+
import { RenderErrorMessage } from '../components/ChatList';
|
|
5
6
|
import OpenAPIKey from './OpenAPIKey';
|
|
6
7
|
|
|
7
8
|
interface OpenAIError {
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { Highlighter
|
|
1
|
+
import { Highlighter } from '@lobehub/ui';
|
|
2
2
|
import { memo } from 'react';
|
|
3
3
|
import { Flexbox } from 'react-layout-kit';
|
|
4
4
|
|
|
5
|
+
import { RenderErrorMessage } from '../../components/ChatList';
|
|
6
|
+
|
|
5
7
|
interface OpenAIError {
|
|
6
8
|
code: 'invalid_api_key' | string;
|
|
7
9
|
message: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Avatar
|
|
1
|
+
import { Avatar } from '@lobehub/ui';
|
|
2
2
|
import { Button, Divider } from 'antd';
|
|
3
3
|
import { useTheme } from 'antd-style';
|
|
4
4
|
import isEqual from 'fast-deep-equal';
|
|
@@ -11,6 +11,7 @@ import { useChatStore } from '@/store/chat';
|
|
|
11
11
|
import { pluginHelpers, useToolStore } from '@/store/tool';
|
|
12
12
|
import { pluginSelectors } from '@/store/tool/selectors';
|
|
13
13
|
|
|
14
|
+
import { RenderErrorMessage } from '../../components/ChatList';
|
|
14
15
|
import { ErrorActionContainer, useStyles } from '../style';
|
|
15
16
|
|
|
16
17
|
const PluginSettings: RenderErrorMessage['Render'] = memo(({ id, plugin }) => {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { PluginErrorType } from '@lobehub/chat-plugin-sdk';
|
|
2
|
-
import { ChatListProps } from '@lobehub/ui';
|
|
3
2
|
|
|
4
3
|
import { ChatErrorType } from '@/types/fetch';
|
|
5
4
|
|
|
5
|
+
import { ChatListProps } from '../components/ChatList';
|
|
6
6
|
import InvalidAccess from './InvalidAccess';
|
|
7
7
|
import OpenAPIKey from './OpenAPIKey';
|
|
8
8
|
import OpenAiBizError from './OpenAiBizError';
|
|
@@ -10,7 +10,7 @@ import { Flexbox } from 'react-layout-kit';
|
|
|
10
10
|
import { useChatStore } from '@/store/chat';
|
|
11
11
|
import { ChatTranslate } from '@/types/message';
|
|
12
12
|
|
|
13
|
-
import BubblesLoading from '../
|
|
13
|
+
import BubblesLoading from '../components/BubblesLoading';
|
|
14
14
|
|
|
15
15
|
const useStyles = createStyles(({ stylish }) => ({
|
|
16
16
|
markdown: stylish.markdownInChat,
|
|
@@ -3,7 +3,7 @@ import { ReactNode, memo } from 'react';
|
|
|
3
3
|
import { LOADING_FLAT } from '@/const/message';
|
|
4
4
|
import { ChatMessage } from '@/types/message';
|
|
5
5
|
|
|
6
|
-
import BubblesLoading from '../
|
|
6
|
+
import BubblesLoading from '../components/BubblesLoading';
|
|
7
7
|
|
|
8
8
|
export const DefaultMessage = memo<
|
|
9
9
|
ChatMessage & {
|
|
@@ -5,7 +5,7 @@ import FileList from '@/components/FileList';
|
|
|
5
5
|
import { LOADING_FLAT } from '@/const/message';
|
|
6
6
|
import { ChatMessage } from '@/types/message';
|
|
7
7
|
|
|
8
|
-
import BubblesLoading from '../
|
|
8
|
+
import BubblesLoading from '../components/BubblesLoading';
|
|
9
9
|
|
|
10
10
|
export const UserMessage = memo<
|
|
11
11
|
ChatMessage & {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { ChatListProps } from '@lobehub/ui';
|
|
2
1
|
import { useResponsive } from 'antd-style';
|
|
3
2
|
import { useRouter } from 'next/navigation';
|
|
4
3
|
|
|
@@ -7,16 +6,17 @@ import { useSessionStore } from '@/store/session';
|
|
|
7
6
|
import { sessionSelectors } from '@/store/session/selectors';
|
|
8
7
|
import { pathString } from '@/utils/url';
|
|
9
8
|
|
|
9
|
+
import { ChatListProps } from '../components/ChatList';
|
|
10
10
|
import { AssistantMessage } from './Assistant';
|
|
11
11
|
import { DefaultMessage } from './Default';
|
|
12
12
|
import { FunctionMessage } from './Function';
|
|
13
13
|
import { UserMessage } from './User';
|
|
14
14
|
|
|
15
15
|
export const renderMessages: ChatListProps['renderMessages'] = {
|
|
16
|
-
assistant: AssistantMessage
|
|
17
|
-
default: DefaultMessage
|
|
18
|
-
function: FunctionMessage
|
|
19
|
-
user: UserMessage
|
|
16
|
+
assistant: AssistantMessage,
|
|
17
|
+
default: DefaultMessage,
|
|
18
|
+
function: FunctionMessage,
|
|
19
|
+
user: UserMessage,
|
|
20
20
|
};
|
|
21
21
|
|
|
22
22
|
export const useAvatarsClick = (): ChatListProps['onAvatarsClick'] => {
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import {createStyles} from 'antd-style';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
1
|
+
import { createStyles } from 'antd-style';
|
|
2
|
+
import { memo } from 'react';
|
|
3
|
+
import { useTranslation } from 'react-i18next';
|
|
4
|
+
import { Flexbox } from 'react-layout-kit';
|
|
6
5
|
|
|
7
6
|
const useStyles = createStyles(
|
|
8
|
-
({css, token}) => css`
|
|
7
|
+
({ css, token }) => css`
|
|
9
8
|
position: relative;
|
|
10
9
|
|
|
11
10
|
overflow: hidden;
|
|
@@ -46,16 +45,16 @@ const useStyles = createStyles(
|
|
|
46
45
|
}
|
|
47
46
|
`,
|
|
48
47
|
);
|
|
49
|
-
|
|
50
|
-
const {t} = useTranslation('plugin');
|
|
51
|
-
const {styles} = useStyles();
|
|
48
|
+
const Loading = memo(() => {
|
|
49
|
+
const { t } = useTranslation('plugin');
|
|
50
|
+
const { styles } = useStyles();
|
|
52
51
|
|
|
53
52
|
return (
|
|
54
53
|
<Flexbox align={'center'} gap={8} padding={16}>
|
|
55
|
-
<span className={styles}/>
|
|
54
|
+
<span className={styles} />
|
|
56
55
|
{t('loading.content')}
|
|
57
56
|
</Flexbox>
|
|
58
57
|
);
|
|
59
58
|
});
|
|
60
59
|
|
|
61
|
-
export default Loading
|
|
60
|
+
export default Loading;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ActionIconGroup, type ActionIconGroupProps } from '@lobehub/ui';
|
|
2
|
+
import { memo } from 'react';
|
|
3
|
+
|
|
4
|
+
import { useChatListActionsBar } from '../../hooks/useChatListActionsBar';
|
|
5
|
+
|
|
6
|
+
export interface ActionsBarProps extends ActionIconGroupProps {
|
|
7
|
+
text?: {
|
|
8
|
+
copy?: string;
|
|
9
|
+
delete?: string;
|
|
10
|
+
edit?: string;
|
|
11
|
+
regenerate?: string;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const ActionsBar = memo<ActionsBarProps>(({ text, ...rest }) => {
|
|
16
|
+
const { regenerate, edit, copy, divider, del } = useChatListActionsBar(text);
|
|
17
|
+
return (
|
|
18
|
+
<ActionIconGroup
|
|
19
|
+
dropdownMenu={[edit, copy, regenerate, divider, del]}
|
|
20
|
+
items={[regenerate, edit]}
|
|
21
|
+
type="ghost"
|
|
22
|
+
{...rest}
|
|
23
|
+
/>
|
|
24
|
+
);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
export default ActionsBar;
|