@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.
Files changed (91) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/README.md +8 -8
  3. package/README.zh-CN.md +8 -8
  4. package/docs/Development/Chat-API.zh-CN.md +90 -52
  5. package/next.config.mjs +0 -1
  6. package/package.json +1 -1
  7. package/src/app/chat/features/ChatHeader/ShareButton/Preview.tsx +1 -1
  8. package/src/features/Conversation/{ChatList/Actions → Actions}/Assistant.tsx +3 -1
  9. package/src/features/Conversation/{ChatList/Actions → Actions}/Error.tsx +3 -1
  10. package/src/features/Conversation/{ChatList/Actions → Actions}/Fallback.tsx +4 -1
  11. package/src/features/Conversation/{ChatList/Actions → Actions}/Function.tsx +4 -1
  12. package/src/features/Conversation/{ChatList/Actions → Actions}/User.tsx +3 -1
  13. package/src/features/Conversation/{ChatList/Actions → Actions}/index.ts +1 -2
  14. package/src/features/Conversation/{ChatList/Error → Error}/InvalidAccess.tsx +2 -1
  15. package/src/features/Conversation/{ChatList/Error → Error}/OpenAPIKey.tsx +1 -1
  16. package/src/features/Conversation/{ChatList/Error → Error}/OpenAiBizError.tsx +2 -1
  17. package/src/features/Conversation/{ChatList/Error → Error}/Plugin/PluginError.tsx +3 -1
  18. package/src/features/Conversation/{ChatList/Error → Error}/Plugin/PluginSettings.tsx +2 -1
  19. package/src/features/Conversation/{ChatList/Error → Error}/index.tsx +1 -1
  20. package/src/features/Conversation/{ChatList/Extras → Extras}/Translate.tsx +1 -1
  21. package/src/features/Conversation/{ChatList/Extras → Extras}/index.ts +1 -2
  22. package/src/features/Conversation/{ChatList/Messages → Messages}/Default.tsx +1 -1
  23. package/src/features/Conversation/{ChatList/Messages → Messages}/User.tsx +1 -1
  24. package/src/features/Conversation/{ChatList/Messages → Messages}/index.ts +5 -5
  25. package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/Loading.tsx +10 -11
  26. package/src/features/Conversation/components/ChatList/ActionsBar.tsx +27 -0
  27. package/src/features/Conversation/components/ChatList/HistoryDivider.tsx +23 -0
  28. package/src/features/Conversation/components/ChatList/Item.tsx +236 -0
  29. package/src/features/Conversation/components/ChatList/index.tsx +88 -0
  30. package/src/features/Conversation/components/ChatList/style.ts +10 -0
  31. package/src/features/Conversation/{ChatList → container}/index.tsx +6 -7
  32. package/src/features/Conversation/hooks/useChatListActionsBar.tsx +43 -0
  33. package/src/features/Conversation/index.tsx +3 -3
  34. package/src/hooks/useIsPWA.ts +3 -4
  35. package/src/store/chat/store.ts +20 -6
  36. package/src/store/middleware/createHyperStorage/index.test.ts +341 -0
  37. package/src/store/middleware/createHyperStorage/index.ts +8 -6
  38. package/src/store/middleware/createHyperStorage/indexedDB.test.ts +64 -0
  39. package/src/store/middleware/createHyperStorage/keyMapper.ts +4 -4
  40. package/src/store/middleware/createHyperStorage/type.ts +6 -2
  41. package/src/store/middleware/createHyperStorage/urlStorage.test.ts +84 -0
  42. package/src/store/middleware/createHyperStorage/urlStorage.ts +25 -8
  43. package/src/store/session/store.ts +24 -9
  44. package/src/utils/matchMedia.ts +10 -0
  45. package/src/utils/screen.ts +14 -0
  46. /package/src/features/Conversation/{ChatList/Actions → Actions}/customAction.ts +0 -0
  47. /package/src/features/Conversation/{ChatList/Error → Error}/ApiKeyForm.tsx +0 -0
  48. /package/src/features/Conversation/{ChatList/Error → Error}/ErrorActionContainer.tsx +0 -0
  49. /package/src/features/Conversation/{ChatList/Error → Error}/style.tsx +0 -0
  50. /package/src/features/Conversation/{ChatList/Extras → Extras}/Assistant.test.tsx +0 -0
  51. /package/src/features/Conversation/{ChatList/Extras → Extras}/Assistant.tsx +0 -0
  52. /package/src/features/Conversation/{ChatList/Extras → Extras}/ExtraContainer.tsx +0 -0
  53. /package/src/features/Conversation/{ChatList/Extras → Extras}/TTS/FilePlayer.tsx +0 -0
  54. /package/src/features/Conversation/{ChatList/Extras → Extras}/TTS/InitPlayer.tsx +0 -0
  55. /package/src/features/Conversation/{ChatList/Extras → Extras}/TTS/Player.tsx +0 -0
  56. /package/src/features/Conversation/{ChatList/Extras → Extras}/TTS/index.tsx +0 -0
  57. /package/src/features/Conversation/{ChatList/Extras → Extras}/User.tsx +0 -0
  58. /package/src/features/Conversation/{ChatList/Extras → Extras}/type.ts +0 -0
  59. /package/src/features/Conversation/{ChatList/Messages → Messages}/Assistant.tsx +0 -0
  60. /package/src/features/Conversation/{ChatList/Messages → Messages}/Function.tsx +0 -0
  61. /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Inspector/PluginResultJSON.tsx +0 -0
  62. /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Inspector/Settings.tsx +0 -0
  63. /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Inspector/index.tsx +0 -0
  64. /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Inspector/style.ts +0 -0
  65. /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/BuiltinType/index.test.tsx +0 -0
  66. /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/BuiltinType/index.tsx +0 -0
  67. /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/DefaultType/IFrameRender/index.tsx +0 -0
  68. /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/DefaultType/SystemJsRender/index.tsx +0 -0
  69. /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/DefaultType/SystemJsRender/utils.ts +0 -0
  70. /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/DefaultType/index.tsx +0 -0
  71. /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/MarkdownType/index.tsx +0 -0
  72. /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/StandaloneType/Iframe.tsx +0 -0
  73. /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/StandaloneType/index.tsx +0 -0
  74. /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/index.tsx +0 -0
  75. /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/useParseContent.ts +0 -0
  76. /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/utils/iframeOnReady.test.ts +0 -0
  77. /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/utils/iframeOnReady.ts +0 -0
  78. /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/utils/listenToPlugin.test.ts +0 -0
  79. /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/utils/listenToPlugin.ts +0 -0
  80. /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/utils/pluginSettings.test.ts +0 -0
  81. /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/utils/pluginSettings.ts +0 -0
  82. /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/utils/pluginState.test.ts +0 -0
  83. /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/utils/pluginState.ts +0 -0
  84. /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/utils/postMessage.test.ts +0 -0
  85. /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/utils/postMessage.ts +0 -0
  86. /package/src/features/Conversation/{ChatList/Loading.tsx → components/BubblesLoading.tsx} +0 -0
  87. /package/src/features/Conversation/{ChatList → components}/OTPInput.tsx +0 -0
  88. /package/src/features/Conversation/{ScrollAnchor → components/ScrollAnchor}/index.tsx +0 -0
  89. /package/src/features/Conversation/{ScrollAnchor → components/ScrollAnchor}/useAtBottom.ts +0 -0
  90. /package/src/features/Conversation/{ChatList → components}/SkeletonList.tsx +0 -0
  91. /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
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#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
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#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 | Description |
212
- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
213
- | [Deployment Specialist Agent](https://chat-preview.lobehub.com/market?agent=deployment-agent)<br/><sup>By **[amitalokbera](https://github.com/amitalokbera)** on **2023-12-27**</sup> | An AI Deployment Specialist is an expert in managing the full deployment lifecycle of software applications, particularly web applications.<br/>`code` `deployment` `software` |
214
- | [Overview of Art Thesis Experts](https://chat-preview.lobehub.com/market?agent=thesis-overview)<br/><sup>By **[caoyang2002](https://github.com/caoyang2002)** on **2023-12-27**</sup> | Specializing in brief thesis and art criticism<br/>`art` `thesis` `critique` |
215
- | [American English Transcreation Expert](https://chat-preview.lobehub.com/market?agent=to-local-english)<br/><sup>By **[doresu](https://github.com/doresu)** on **2023-12-27**</sup> | Rough old editor, seasoned writer, and translator, proficient in translating English directly and transforming it into authentic American English<br/>`translation` `editing` `writing` `translator` |
216
- | [Academic Proofreading Expert](https://chat-preview.lobehub.com/market?agent=academic-paragraph-refiner)<br/><sup>By **[Feliks151450](https://github.com/Feliks151450)** on **2023-12-26**</sup> | Highly skilled in advanced research proofreading and language editing, specializing in multiple research fields and proficient in academic English.<br/>`proofreading` `writing` `research` |
217
-
218
- > 📊 Total agents: [<kbd>**82**</kbd> ](https://github.com/lobehub/lobe-chat-agents)
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
- | [部署专家代理](https://chat-preview.lobehub.com/market?agent=deployment-agent)<br/><sup>By **[amitalokbera](https://github.com/amitalokbera)** on **2023-12-27**</sup> | AI 部署专家是管理软件应用的完整部署生命周期的专家,特别是 Web 应用。<br/>`代码` `部署` `容器化` |
190
- | [美术论文概述专家](https://chat-preview.lobehub.com/market?agent=thesis-overview)<br/><sup>By **[caoyang2002](https://github.com/caoyang2002)** on **2023-12-27**</sup> | 擅长论文简述与美术评论<br/>`美术` `论文` `评论` |
191
- | [美式英语转译专家](https://chat-preview.lobehub.com/market?agent=to-local-english)<br/><sup>By **[doresu](https://github.com/doresu)** on **2023-12-27**</sup> | 粗鲁老编辑、资深作家和翻译家,擅长直译英文并转化为地道的美式英语<br/>`翻译` `编辑` `写作` `翻译家` |
192
- | [学术润色专家](https://chat-preview.lobehub.com/market?agent=academic-paragraph-refiner)<br/><sup>By **[Feliks151450](https://github.com/Feliks151450)** on **2023-12-26**</sup> | 高级研究校对及语言编辑,专业于多个研究领域,精通学术英语。<br/>`校对` `写作` `研究` |
193
-
194
- > 📊 Total agents: [<kbd>**82**</kbd> ](https://github.com/lobehub/lobe-chat-agents)
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/handler.ts` 文件中,我们定义了 `POST` 方法,该方法首先从请求中解析出 payload 数据(即客户端发送的会话内容),然后从请求中获取 OpenAI 的授权信息。之后,我们创建一个 `openai` 对象,并调用 `createChatCompletion` 方法,该方法负责发送会话请求到 OpenAI 并返回结果。
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 { apiKey, endpoint } = getOpenAIAuthFromRequest(req);
26
+ const openaiOrErrResponse = createBizOpenAI(req, payload.model);
27
27
 
28
- const openai = createOpenai(apiKey, endpoint);
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
- 在 `src/app/api/openai/chat/createChatCompletion.ts` 文件中,我们定义了 `createChatCompletion` 方法,该方法首先对 payload 数据进行预处理,然后调用 OpenAI 的 `chat.completions.create` 方法发送请求,并使用 [Vercel AI SDK](https://sdk.vercel.ai/docs) 中的 `OpenAIStream` 将返回的结果转化为流式响应。
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
- const formatMessages = messages.map((m) => ({
45
- content: m.content,
46
- name: m.name,
47
- role: m.role,
48
- }));
49
-
50
- const response = await openai.chat.completions.create(
51
- {
52
- messages: formatMessages,
53
- ...params,
54
- stream: true,
55
- },
56
- { headers: { Accept: '*/*' } },
57
- );
58
- const stream = OpenAIStream(response);
59
- return new StreamingTextResponse(stream);
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/chatModel.ts` 文件中,我们定义了 `fetchChatModel` 方法,该方法首先对 payload 数据进行前置处理,然后发送 POST 请求到后端的 `/chat` 接口,并将请求结果返回。
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
- export const fetchChatModel = (
71
- { plugins: enabledPlugins, ...params }: Partial<OpenAIStreamPayload>,
72
- options?: FetchChatModelOptions,
73
- ) => {
74
- const payload = merge(
75
- {
76
- model: initialLobeAgentConfig.model,
77
- stream: true,
78
- ...initialLobeAgentConfig.params,
79
- },
80
- params,
81
- );
82
-
83
- const filterFunctions: ChatCompletionFunctions[] = pluginSelectors.enabledSchema(enabledPlugins)(
84
- usePluginStore.getState(),
85
- );
86
-
87
- const functions = filterFunctions.length === 0 ? undefined : filterFunctions;
88
-
89
- return fetch(OPENAI_URLS.chat, {
90
- body: JSON.stringify({ ...payload, functions }),
91
- headers: createHeaderWithOpenAI({ 'Content-Type': 'application/json' }),
92
- method: 'POST',
93
- signal: options?.signal,
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
@@ -20,7 +20,6 @@ const withPWA = nextPWA({
20
20
  const nextConfig = {
21
21
  compress: isProd,
22
22
  experimental: {
23
- forceSwcTransforms: true,
24
23
  optimizePackageImports: [
25
24
  'modern-screenshot',
26
25
  'emoji-mart',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "0.118.4",
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/ChatList';
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, RenderAction, useChatListActionsBar } from '@lobehub/ui';
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, useChatListActionsBar } from '@lobehub/ui';
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, RenderAction, useChatListActionsBar } from '@lobehub/ui';
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, RenderAction, useChatListActionsBar } from '@lobehub/ui';
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, RenderAction, useChatListActionsBar } from '@lobehub/ui';
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, RenderErrorMessage } from '@lobehub/ui';
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,6 +1,6 @@
1
- import { RenderErrorMessage } from '@lobehub/ui';
2
1
  import { memo } from 'react';
3
2
 
3
+ import { RenderErrorMessage } from '../components/ChatList';
4
4
  import APIKeyForm from './ApiKeyForm';
5
5
  import { ErrorActionContainer } from './style';
6
6
 
@@ -1,7 +1,8 @@
1
- import { Highlighter, RenderErrorMessage } from '@lobehub/ui';
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, RenderErrorMessage } from '@lobehub/ui';
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, RenderErrorMessage } from '@lobehub/ui';
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 '../Loading';
13
+ import BubblesLoading from '../components/BubblesLoading';
14
14
 
15
15
  const useStyles = createStyles(({ stylish }) => ({
16
16
  markdown: stylish.markdownInChat,
@@ -1,5 +1,4 @@
1
- import { ChatListProps, RenderMessageExtra } from '@lobehub/ui';
2
-
1
+ import { ChatListProps, RenderMessageExtra } from '../components/ChatList';
3
2
  import { AssistantMessageExtra } from './Assistant';
4
3
  import { UserMessageExtra } from './User';
5
4
 
@@ -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 '../Loading';
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 '../Loading';
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 as any,
17
- default: DefaultMessage as any,
18
- function: FunctionMessage as any,
19
- user: UserMessage as any,
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 {useTranslation} from 'react-i18next';
3
- import {Flexbox} from 'react-layout-kit';
4
- import {memo} from "react";
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
- const Loading = memo(() => {
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;