@lobehub/lobehub 2.0.0-next.34 → 2.0.0-next.36

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 (282) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/changelog/v1.json +18 -0
  3. package/next.config.ts +5 -6
  4. package/package.json +2 -2
  5. package/packages/agent-runtime/src/core/__tests__/runtime.test.ts +112 -77
  6. package/packages/agent-runtime/src/core/runtime.ts +63 -18
  7. package/packages/agent-runtime/src/types/generalAgent.ts +55 -0
  8. package/packages/agent-runtime/src/types/index.ts +1 -0
  9. package/packages/agent-runtime/src/types/instruction.ts +10 -3
  10. package/packages/const/src/user.ts +0 -1
  11. package/packages/context-engine/src/processors/GroupMessageFlatten.ts +8 -6
  12. package/packages/context-engine/src/processors/__tests__/GroupMessageFlatten.test.ts +12 -12
  13. package/packages/conversation-flow/src/__tests__/fixtures/inputs/branch/assistant-group-branches.json +249 -0
  14. package/packages/conversation-flow/src/__tests__/fixtures/inputs/branch/index.ts +4 -0
  15. package/packages/conversation-flow/src/__tests__/fixtures/inputs/branch/multi-assistant-group.json +260 -0
  16. package/packages/conversation-flow/src/__tests__/fixtures/outputs/branch/active-index-1.json +4 -0
  17. package/packages/conversation-flow/src/__tests__/fixtures/outputs/branch/assistant-group-branches.json +481 -0
  18. package/packages/conversation-flow/src/__tests__/fixtures/outputs/branch/conversation.json +5 -1
  19. package/packages/conversation-flow/src/__tests__/fixtures/outputs/branch/index.ts +4 -0
  20. package/packages/conversation-flow/src/__tests__/fixtures/outputs/branch/multi-assistant-group.json +407 -0
  21. package/packages/conversation-flow/src/__tests__/fixtures/outputs/branch/nested.json +18 -2
  22. package/packages/conversation-flow/src/__tests__/fixtures/outputs/complex-scenario.json +25 -3
  23. package/packages/conversation-flow/src/__tests__/parse.test.ts +12 -0
  24. package/packages/conversation-flow/src/index.ts +1 -1
  25. package/packages/conversation-flow/src/transformation/FlatListBuilder.ts +112 -34
  26. package/packages/conversation-flow/src/types/flatMessageList.ts +0 -12
  27. package/packages/conversation-flow/src/{types.ts → types/index.ts} +3 -14
  28. package/packages/database/src/models/message.ts +18 -19
  29. package/packages/types/src/aiChat.ts +2 -0
  30. package/packages/types/src/importer.ts +2 -2
  31. package/packages/types/src/message/ui/chat.ts +17 -1
  32. package/packages/types/src/message/ui/extra.ts +2 -2
  33. package/packages/types/src/message/ui/params.ts +2 -2
  34. package/packages/types/src/user/preference.ts +0 -4
  35. package/packages/utils/src/tokenizer/index.ts +3 -11
  36. package/src/app/[variants]/(main)/chat/ChatRouter.tsx +83 -0
  37. package/src/app/[variants]/(main)/chat/_layout/ChatLayout.tsx +22 -0
  38. package/src/app/[variants]/(main)/chat/_layout/Desktop/SessionPanel.tsx +12 -7
  39. package/src/app/[variants]/(main)/chat/_layout/Desktop/index.tsx +2 -2
  40. package/src/app/[variants]/(main)/chat/_layout/FeatureFlagsProvider.tsx +24 -0
  41. package/src/app/[variants]/(main)/chat/_layout/Mobile.tsx +3 -2
  42. package/src/app/[variants]/(main)/chat/_layout/type.ts +0 -1
  43. package/src/app/[variants]/(main)/chat/components/ConversationArea.tsx +29 -0
  44. package/src/app/[variants]/(main)/chat/components/MainChatPage.tsx +25 -0
  45. package/src/app/[variants]/(main)/chat/components/PortalPanel.tsx +28 -0
  46. package/src/app/[variants]/(main)/chat/components/SessionPanel.tsx +33 -0
  47. package/src/app/[variants]/(main)/chat/{settings/page.tsx → components/SettingsPage.tsx} +35 -3
  48. package/src/app/[variants]/(main)/chat/components/TopicSidebar.tsx +30 -0
  49. package/src/app/[variants]/(main)/chat/components/WorkspaceLayout.tsx +73 -0
  50. package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/Desktop/MessageFromUrl.tsx +3 -3
  51. package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/V1Mobile/index.tsx +1 -1
  52. package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/V1Mobile/useSend.ts +3 -3
  53. package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/useSend.ts +6 -6
  54. package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/ChatItem/index.tsx +1 -1
  55. package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/Content.tsx +5 -3
  56. package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/WelcomeChatItem/AgentWelcome/OpeningQuestions.tsx +2 -2
  57. package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/WelcomeChatItem/GroupWelcome/GroupUsageSuggest.tsx +2 -2
  58. package/src/app/[variants]/(main)/chat/{layout.ts → layout.tsx} +0 -1
  59. package/src/app/[variants]/(main)/chat/page.tsx +12 -0
  60. package/src/app/[variants]/(main)/labs/page.tsx +0 -9
  61. package/src/features/ChatInput/ActionBar/STT/browser.tsx +3 -3
  62. package/src/features/ChatInput/ActionBar/STT/openai.tsx +3 -3
  63. package/src/features/Conversation/Error/AccessCodeForm.tsx +1 -1
  64. package/src/features/Conversation/Error/ChatInvalidApiKey.tsx +1 -1
  65. package/src/features/Conversation/Error/ClerkLogin/index.tsx +1 -1
  66. package/src/features/Conversation/Error/OAuthForm.tsx +1 -1
  67. package/src/features/Conversation/Error/index.tsx +0 -5
  68. package/src/features/Conversation/Messages/Assistant/Actions/index.tsx +13 -10
  69. package/src/features/Conversation/Messages/Assistant/Extra/index.test.tsx +3 -8
  70. package/src/features/Conversation/Messages/Assistant/Extra/index.tsx +2 -6
  71. package/src/features/Conversation/Messages/Assistant/MessageContent.tsx +7 -9
  72. package/src/features/Conversation/Messages/Assistant/Tool/Inspector/PluginResult.tsx +2 -2
  73. package/src/features/Conversation/Messages/Assistant/Tool/Inspector/PluginState.tsx +2 -2
  74. package/src/features/Conversation/Messages/Assistant/Tool/Render/PluginSettings.tsx +4 -1
  75. package/src/features/Conversation/Messages/Assistant/Tool/Render/index.tsx +2 -3
  76. package/src/features/Conversation/Messages/Assistant/index.tsx +57 -60
  77. package/src/features/Conversation/Messages/Default.tsx +1 -0
  78. package/src/features/Conversation/Messages/Group/Actions/WithContentId.tsx +38 -10
  79. package/src/features/Conversation/Messages/Group/Actions/index.tsx +1 -1
  80. package/src/features/Conversation/Messages/Group/ContentBlock.tsx +1 -3
  81. package/src/features/Conversation/Messages/Group/GroupChildren.tsx +12 -12
  82. package/src/features/Conversation/Messages/Group/MessageContent.tsx +7 -1
  83. package/src/features/Conversation/Messages/Group/Tool/Render/PluginSettings.tsx +1 -1
  84. package/src/features/Conversation/Messages/Group/index.tsx +2 -1
  85. package/src/features/Conversation/Messages/Supervisor/index.tsx +2 -2
  86. package/src/features/Conversation/Messages/User/{Actions.tsx → Actions/ActionsBar.tsx} +26 -25
  87. package/src/features/Conversation/Messages/User/Actions/MessageBranch.tsx +107 -0
  88. package/src/features/Conversation/Messages/User/Actions/index.tsx +42 -0
  89. package/src/features/Conversation/Messages/User/index.tsx +43 -44
  90. package/src/features/Conversation/Messages/index.tsx +3 -3
  91. package/src/features/Conversation/components/AutoScroll.tsx +3 -3
  92. package/src/features/Conversation/components/Extras/Usage/UsageDetail/AnimatedNumber.tsx +55 -0
  93. package/src/features/Conversation/components/Extras/Usage/UsageDetail/index.tsx +5 -2
  94. package/src/features/Conversation/components/VirtualizedList/index.tsx +29 -20
  95. package/src/features/Conversation/hooks/useChatListActionsBar.tsx +8 -10
  96. package/src/features/Portal/GroupThread/Body/index.tsx +1 -1
  97. package/src/features/Portal/Thread/Chat/ChatInput/useSend.ts +3 -3
  98. package/src/hooks/useHotkeys/chatScope.ts +16 -8
  99. package/src/server/routers/lambda/__tests__/aiChat.test.ts +1 -1
  100. package/src/server/routers/lambda/__tests__/integration/message.integration.test.ts +0 -26
  101. package/src/server/routers/lambda/aiChat.ts +3 -2
  102. package/src/server/routers/lambda/message.ts +8 -16
  103. package/src/server/services/message/__tests__/index.test.ts +29 -39
  104. package/src/server/services/message/index.ts +41 -36
  105. package/src/services/electron/desktopNotification.ts +6 -6
  106. package/src/services/electron/file.ts +6 -6
  107. package/src/services/file/ClientS3/index.ts +8 -8
  108. package/src/services/message/__tests__/metadata-race-condition.test.ts +157 -0
  109. package/src/services/message/index.ts +21 -15
  110. package/src/services/upload.ts +11 -11
  111. package/src/services/utils/abortableRequest.test.ts +161 -0
  112. package/src/services/utils/abortableRequest.ts +67 -0
  113. package/src/store/chat/agents/GeneralChatAgent.ts +137 -0
  114. package/src/store/chat/agents/createAgentExecutors.ts +395 -0
  115. package/src/store/chat/helpers.test.ts +0 -99
  116. package/src/store/chat/helpers.ts +0 -11
  117. package/src/store/chat/slices/aiChat/actions/__tests__/conversationControl.test.ts +332 -0
  118. package/src/store/chat/slices/aiChat/actions/__tests__/conversationLifecycle.test.ts +257 -0
  119. package/src/store/chat/slices/aiChat/actions/__tests__/helpers.ts +11 -2
  120. package/src/store/chat/slices/aiChat/actions/__tests__/rag.test.ts +6 -6
  121. package/src/store/chat/slices/aiChat/actions/__tests__/streamingExecutor.test.ts +391 -0
  122. package/src/store/chat/slices/aiChat/actions/__tests__/streamingStates.test.ts +179 -0
  123. package/src/store/chat/slices/aiChat/actions/conversationControl.ts +157 -0
  124. package/src/store/chat/slices/aiChat/actions/conversationLifecycle.ts +329 -0
  125. package/src/store/chat/slices/aiChat/actions/generateAIGroupChat.ts +14 -14
  126. package/src/store/chat/slices/aiChat/actions/index.ts +12 -6
  127. package/src/store/chat/slices/aiChat/actions/rag.ts +9 -6
  128. package/src/store/chat/slices/aiChat/actions/streamingExecutor.ts +604 -0
  129. package/src/store/chat/slices/aiChat/actions/streamingStates.ts +84 -0
  130. package/src/store/chat/slices/builtinTool/actions/__tests__/localSystem.test.ts +4 -4
  131. package/src/store/chat/slices/builtinTool/actions/__tests__/search.test.ts +11 -11
  132. package/src/store/chat/slices/builtinTool/actions/interpreter.ts +8 -8
  133. package/src/store/chat/slices/builtinTool/actions/localSystem.ts +2 -2
  134. package/src/store/chat/slices/builtinTool/actions/search.ts +8 -8
  135. package/src/store/chat/slices/message/action.test.ts +79 -68
  136. package/src/store/chat/slices/message/actions/index.ts +39 -0
  137. package/src/store/chat/slices/message/actions/internals.ts +77 -0
  138. package/src/store/chat/slices/message/actions/optimisticUpdate.ts +260 -0
  139. package/src/store/chat/slices/message/actions/publicApi.ts +224 -0
  140. package/src/store/chat/slices/message/actions/query.ts +120 -0
  141. package/src/store/chat/slices/message/actions/runtimeState.ts +108 -0
  142. package/src/store/chat/slices/message/initialState.ts +13 -0
  143. package/src/store/chat/slices/message/reducer.test.ts +48 -370
  144. package/src/store/chat/slices/message/reducer.ts +17 -81
  145. package/src/store/chat/slices/message/selectors/chat.test.ts +13 -50
  146. package/src/store/chat/slices/message/selectors/chat.ts +78 -242
  147. package/src/store/chat/slices/message/selectors/dbMessage.ts +140 -0
  148. package/src/store/chat/slices/message/selectors/displayMessage.ts +301 -0
  149. package/src/store/chat/slices/message/selectors/messageState.ts +5 -2
  150. package/src/store/chat/slices/plugin/action.test.ts +62 -64
  151. package/src/store/chat/slices/plugin/action.ts +34 -28
  152. package/src/store/chat/slices/thread/action.test.ts +28 -31
  153. package/src/store/chat/slices/thread/action.ts +13 -10
  154. package/src/store/chat/slices/thread/selectors/index.ts +8 -6
  155. package/src/store/chat/slices/topic/reducer.ts +11 -3
  156. package/src/store/chat/store.ts +1 -1
  157. package/src/store/user/slices/preference/selectors/labPrefer.ts +0 -3
  158. package/packages/database/src/models/__tests__/message.grouping.test.ts +0 -812
  159. package/packages/database/src/utils/__tests__/groupMessages.test.ts +0 -1132
  160. package/packages/database/src/utils/groupMessages.ts +0 -361
  161. package/packages/utils/src/tokenizer/client.ts +0 -35
  162. package/packages/utils/src/tokenizer/estimated.ts +0 -4
  163. package/packages/utils/src/tokenizer/server.ts +0 -11
  164. package/packages/utils/src/tokenizer/tokenizer.worker.ts +0 -12
  165. package/src/app/(backend)/webapi/tokenizer/index.test.ts +0 -32
  166. package/src/app/(backend)/webapi/tokenizer/route.ts +0 -8
  167. package/src/app/[variants]/(main)/chat/(workspace)/layout.ts +0 -11
  168. package/src/app/[variants]/(main)/chat/(workspace)/page.tsx +0 -53
  169. package/src/app/[variants]/(main)/chat/@session/default.tsx +0 -31
  170. package/src/app/[variants]/(main)/chat/settings/layout.tsx +0 -21
  171. package/src/features/Conversation/Error/InvalidAccessCode.tsx +0 -79
  172. package/src/store/chat/slices/aiChat/actions/__tests__/generateAIChat.test.ts +0 -975
  173. package/src/store/chat/slices/aiChat/actions/__tests__/generateAIChatV2.test.ts +0 -1050
  174. package/src/store/chat/slices/aiChat/actions/generateAIChat.ts +0 -720
  175. package/src/store/chat/slices/aiChat/actions/generateAIChatV2.ts +0 -849
  176. package/src/store/chat/slices/message/action.ts +0 -629
  177. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/default.tsx +0 -0
  178. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatHydration/index.tsx +0 -0
  179. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/Desktop/ClassicChat.tsx +0 -0
  180. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/Desktop/GroupChat.tsx +0 -0
  181. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/Desktop/index.tsx +0 -0
  182. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/Desktop/useSendMenuItems.tsx +0 -0
  183. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/Mobile/MentionedUsers/MentionedUserItem.tsx +0 -0
  184. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/Mobile/MentionedUsers/index.tsx +0 -0
  185. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/Mobile/index.tsx +0 -0
  186. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/V1Mobile/ActionBar.tsx +0 -0
  187. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/V1Mobile/Files/index.tsx +0 -0
  188. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/V1Mobile/InputArea/Container.tsx +0 -0
  189. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/V1Mobile/InputArea/index.tsx +0 -0
  190. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/V1Mobile/Send.tsx +0 -0
  191. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/index.tsx +0 -0
  192. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/ChatItem/OrchestratorThinking.tsx +0 -0
  193. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/ChatItem/Thread.tsx +0 -0
  194. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/ChatItem/ThreadItem.tsx +0 -0
  195. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/WelcomeChatItem/AgentWelcome/AddButton.tsx +0 -0
  196. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/WelcomeChatItem/AgentWelcome/index.tsx +0 -0
  197. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/WelcomeChatItem/GroupWelcome/index.tsx +0 -0
  198. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/WelcomeChatItem/GroupWelcome/useTemplateMatching.ts +0 -0
  199. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/WelcomeChatItem/index.tsx +0 -0
  200. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/index.tsx +0 -0
  201. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatMinimap/index.tsx +0 -0
  202. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ThreadHydration.tsx +0 -0
  203. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ZenModeToast/Toast.tsx +0 -0
  204. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ZenModeToast/index.tsx +0 -0
  205. /package/src/app/[variants]/(main)/chat/{(workspace) → components}/features/AgentSettings/index.tsx +0 -0
  206. /package/src/app/[variants]/(main)/chat/{(workspace) → components}/features/AgentTeamSettings/index.tsx +0 -0
  207. /package/src/app/[variants]/(main)/chat/{(workspace) → components}/features/ChangelogModal.tsx +0 -0
  208. /package/src/app/[variants]/(main)/chat/{(workspace) → components}/features/SettingButton.tsx +0 -0
  209. /package/src/app/[variants]/(main)/chat/{(workspace) → components}/features/ShareButton/index.tsx +0 -0
  210. /package/src/app/[variants]/(main)/chat/{(workspace) → components}/features/TelemetryNotification.tsx +0 -0
  211. /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Desktop/ChatHeader/HeaderAction.tsx +0 -0
  212. /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Desktop/ChatHeader/Main.tsx +0 -0
  213. /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Desktop/ChatHeader/Tags/HistoryLimitTags.tsx +0 -0
  214. /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Desktop/ChatHeader/Tags/KnowledgeTag.tsx +0 -0
  215. /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Desktop/ChatHeader/Tags/MemberCountTag.tsx +0 -0
  216. /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Desktop/ChatHeader/Tags/SearchTags.tsx +0 -0
  217. /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Desktop/ChatHeader/Tags/index.tsx +0 -0
  218. /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Desktop/ChatHeader/index.tsx +0 -0
  219. /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Desktop/Portal.tsx +0 -0
  220. /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Desktop/TopicPanel.tsx +0 -0
  221. /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Desktop/index.tsx +0 -0
  222. /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Mobile/ChatHeader/ChatHeaderTitle.tsx +0 -0
  223. /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Mobile/ChatHeader/index.tsx +0 -0
  224. /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Mobile/TopicModal.tsx +0 -0
  225. /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Mobile/index.tsx +0 -0
  226. /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/type.ts +0 -0
  227. /package/src/app/[variants]/(main)/chat/{(workspace)/@portal → components/portal}/_layout/Desktop.tsx +0 -0
  228. /package/src/app/[variants]/(main)/chat/{(workspace)/@portal → components/portal}/_layout/Mobile.tsx +0 -0
  229. /package/src/app/[variants]/(main)/chat/{(workspace)/@portal → components/portal}/default.tsx +0 -0
  230. /package/src/app/[variants]/(main)/chat/{(workspace)/@portal → components/portal}/error.tsx +0 -0
  231. /package/src/app/[variants]/(main)/chat/{(workspace)/@portal → components/portal}/features/Body.tsx +0 -0
  232. /package/src/app/[variants]/(main)/chat/{(workspace)/@portal → components/portal}/loading.tsx +0 -0
  233. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/_layout/Desktop.tsx +0 -0
  234. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/_layout/Mobile.tsx +0 -0
  235. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/default.tsx +0 -0
  236. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/AgentConfig/SystemRole.tsx +0 -0
  237. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/AgentConfig/index.tsx +0 -0
  238. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/ConfigLayout.tsx +0 -0
  239. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/ConfigSwitcher.tsx +0 -0
  240. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/GroupConfig/GroupMember.tsx +0 -0
  241. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/GroupConfig/GroupMemberItem.tsx +0 -0
  242. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/GroupConfig/GroupRole.tsx +0 -0
  243. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/GroupConfig/index.tsx +0 -0
  244. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/GroupConfig/style.ts +0 -0
  245. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/SkeletonList.tsx +0 -0
  246. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/Header.tsx +0 -0
  247. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/TopicListContent/ByTimeMode/GroupItem.tsx +0 -0
  248. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/TopicListContent/ByTimeMode/index.tsx +0 -0
  249. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/TopicListContent/FlatMode/index.tsx +0 -0
  250. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/TopicListContent/SearchResult/index.tsx +0 -0
  251. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/TopicListContent/ThreadItem/Content.tsx +0 -0
  252. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/TopicListContent/ThreadItem/index.tsx +0 -0
  253. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/TopicListContent/ThreadList/index.tsx +0 -0
  254. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/TopicListContent/TopicItem/DefaultContent.tsx +0 -0
  255. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/TopicListContent/TopicItem/TopicContent.tsx +0 -0
  256. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/TopicListContent/TopicItem/index.tsx +0 -0
  257. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/TopicListContent/index.tsx +0 -0
  258. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/TopicSearchBar/index.tsx +0 -0
  259. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/index.tsx +0 -0
  260. /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionHydration.tsx +0 -0
  261. /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/CollapseGroup/Actions.tsx +0 -0
  262. /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/CollapseGroup/index.tsx +0 -0
  263. /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/DefaultMode.tsx +0 -0
  264. /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/Inbox/index.tsx +0 -0
  265. /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/List/AddButton.tsx +0 -0
  266. /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/List/Item/Actions.tsx +0 -0
  267. /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/List/Item/index.tsx +0 -0
  268. /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/List/index.tsx +0 -0
  269. /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/ListItem/index.tsx +0 -0
  270. /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/Modals/ConfigGroupModal/GroupItem.tsx +0 -0
  271. /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/Modals/ConfigGroupModal/index.tsx +0 -0
  272. /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/Modals/CreateGroupModal.tsx +0 -0
  273. /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/Modals/RenameGroupModal.tsx +0 -0
  274. /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/SearchMode.tsx +0 -0
  275. /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/index.tsx +0 -0
  276. /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionSearchBar.tsx +0 -0
  277. /package/src/app/[variants]/(main)/chat/{@session → session}/features/SkeletonList.tsx +0 -0
  278. /package/src/app/[variants]/(main)/chat/{@session/_layout → session/layout}/Desktop/PanelBody.tsx +0 -0
  279. /package/src/app/[variants]/(main)/chat/{@session/_layout → session/layout}/Desktop/SessionHeader.tsx +0 -0
  280. /package/src/app/[variants]/(main)/chat/{@session/_layout → session/layout}/Desktop/index.tsx +0 -0
  281. /package/src/app/[variants]/(main)/chat/{@session/_layout → session/layout}/Mobile/SessionHeader.tsx +0 -0
  282. /package/src/app/[variants]/(main)/chat/{@session/_layout → session/layout}/Mobile/index.tsx +0 -0
@@ -1,629 +0,0 @@
1
- /* eslint-disable sort-keys-fix/sort-keys-fix, typescript-sort-keys/interface */
2
- // Disable the auto sort key eslint rule to make the code more logic and readable
3
- import {
4
- ChatErrorType,
5
- ChatImageItem,
6
- ChatMessageError,
7
- ChatMessagePluginError,
8
- CreateMessageParams,
9
- GroundingSearch,
10
- MessageMetadata,
11
- MessageToolCall,
12
- ModelReasoning,
13
- TraceEventPayloads,
14
- TraceEventType,
15
- UIChatMessage,
16
- UpdateMessageRAGParams,
17
- } from '@lobechat/types';
18
- import { nanoid } from '@lobechat/utils';
19
- import { copyToClipboard } from '@lobehub/ui';
20
- import isEqual from 'fast-deep-equal';
21
- import { SWRResponse, mutate } from 'swr';
22
- import { StateCreator } from 'zustand/vanilla';
23
-
24
- import { useClientDataSWR } from '@/libs/swr';
25
- import { messageService } from '@/services/message';
26
- import { topicService } from '@/services/topic';
27
- import { traceService } from '@/services/trace';
28
- import { ChatStore } from '@/store/chat/store';
29
- import { messageMapKey } from '@/store/chat/utils/messageMapKey';
30
- import { useSessionStore } from '@/store/session';
31
- import { sessionSelectors } from '@/store/session/selectors';
32
- import { Action, setNamespace } from '@/utils/storeDebug';
33
-
34
- import type { ChatStoreState } from '../../initialState';
35
- import { chatSelectors } from '../../selectors';
36
- import { preventLeavingFn, toggleBooleanList } from '../../utils';
37
- import { MessageDispatch, messagesReducer } from './reducer';
38
-
39
- const n = setNamespace('m');
40
-
41
- const SWR_USE_FETCH_MESSAGES = 'SWR_USE_FETCH_MESSAGES';
42
-
43
- export interface ChatMessageAction {
44
- // create
45
- addAIMessage: () => Promise<void>;
46
- addUserMessage: (params: { message: string; fileList?: string[] }) => Promise<void>;
47
- // delete
48
- /**
49
- * clear message on the active session
50
- */
51
- clearMessage: () => Promise<void>;
52
- deleteMessage: (id: string) => Promise<void>;
53
- deleteToolMessage: (id: string) => Promise<void>;
54
- clearAllMessages: () => Promise<void>;
55
- // update
56
- updateInputMessage: (message: string) => void;
57
- modifyMessageContent: (id: string, content: string) => Promise<void>;
58
- toggleMessageEditing: (id: string, editing: boolean) => void;
59
- // query
60
- useFetchMessages: (
61
- enable: boolean,
62
- messageContextId: string,
63
- activeTopicId?: string,
64
- type?: 'session' | 'group',
65
- ) => SWRResponse<UIChatMessage[]>;
66
- copyMessage: (id: string, content: string) => Promise<void>;
67
- refreshMessages: () => Promise<void>;
68
- replaceMessages: (messages: UIChatMessage[]) => void;
69
- // ========= ↓ Internal Method ↓ ========== //
70
- // ========================================== //
71
- // ========================================== //
72
- internal_updateMessageRAG: (id: string, input: UpdateMessageRAGParams) => Promise<void>;
73
-
74
- /**
75
- * update message at the frontend
76
- * this method will not update messages to database
77
- */
78
- internal_dispatchMessage: (
79
- payload: MessageDispatch,
80
- context?: { topicId?: string | null; sessionId: string },
81
- ) => void;
82
-
83
- /**
84
- * update the message content with optimistic update
85
- * a method used by other action
86
- */
87
- internal_updateMessageContent: (
88
- id: string,
89
- content: string,
90
- extra?: {
91
- toolCalls?: MessageToolCall[];
92
- reasoning?: ModelReasoning;
93
- search?: GroundingSearch;
94
- metadata?: MessageMetadata;
95
- imageList?: ChatImageItem[];
96
- model?: string;
97
- provider?: string;
98
- },
99
- ) => Promise<void>;
100
- /**
101
- * update the message error with optimistic update
102
- */
103
- internal_updateMessageError: (id: string, error: ChatMessageError | null) => Promise<void>;
104
- internal_updateMessagePluginError: (
105
- id: string,
106
- error: ChatMessagePluginError | null,
107
- ) => Promise<void>;
108
- /**
109
- * create a message with optimistic update
110
- * returns the created message ID and updated message list
111
- */
112
- internal_createMessage: (
113
- params: CreateMessageParams,
114
- context?: { tempMessageId?: string; skipRefresh?: boolean; groupMessageId?: string },
115
- ) => Promise<{ id: string; messages: UIChatMessage[] } | undefined>;
116
- /**
117
- * create a temp message for optimistic update
118
- * otherwise the message will be too slow to show
119
- */
120
- internal_createTmpMessage: (params: CreateMessageParams) => string;
121
- /**
122
- * delete the message content with optimistic update
123
- */
124
- internal_deleteMessage: (id: string) => Promise<void>;
125
-
126
- internal_fetchMessages: () => Promise<void>;
127
- internal_traceMessage: (id: string, payload: TraceEventPayloads) => Promise<void>;
128
-
129
- /**
130
- * method to toggle message create loading state
131
- * the AI message status is creating -> generating
132
- * other message role like user and tool , only this method need to be called
133
- */
134
- internal_toggleMessageLoading: (loading: boolean, id: string) => void;
135
-
136
- /**
137
- * helper to toggle the loading state of the array,used by these three toggleXXXLoading
138
- */
139
- internal_toggleLoadingArrays: (
140
- key: keyof ChatStoreState,
141
- loading: boolean,
142
- id?: string,
143
- action?: Action,
144
- ) => AbortController | undefined;
145
-
146
- /**
147
- * Update active session type
148
- */
149
- internal_updateActiveSessionType: (sessionType?: 'agent' | 'group') => void;
150
- /**
151
- * Update active session ID with cleanup of pending operations
152
- */
153
- internal_updateActiveId: (activeId: string) => void;
154
- }
155
-
156
- export const chatMessage: StateCreator<
157
- ChatStore,
158
- [['zustand/devtools', never]],
159
- [],
160
- ChatMessageAction
161
- > = (set, get) => ({
162
- deleteMessage: async (id) => {
163
- const message = chatSelectors.getMessageById(id)(get());
164
- if (!message) return;
165
-
166
- let ids = [message.id];
167
- const allMessages = chatSelectors.activeBaseChats(get());
168
-
169
- // if the message is a tool calls, then delete all the related tool messages
170
- if (message.tools) {
171
- const toolMessageIds = message.tools.flatMap((tool) => {
172
- const messages = allMessages.filter((m) => m.tool_call_id === tool.id);
173
- return messages.map((m) => m.id);
174
- });
175
- ids = ids.concat(toolMessageIds);
176
- }
177
-
178
- // if the message is a group message, find all children messages (via parentId)
179
- if (message.role === 'group') {
180
- const childMessages = allMessages.filter((m) => m.parentId === message.id);
181
- const childMessageIds = childMessages.map((m) => m.id);
182
- ids = ids.concat(childMessageIds);
183
-
184
- // Also delete tool results of children messages
185
- const childToolMessageIds = childMessages.flatMap((child) => {
186
- if (!child.tools) return [];
187
- return child.tools.flatMap((tool) => {
188
- const toolMessages = allMessages.filter((m) => m.tool_call_id === tool.id);
189
- return toolMessages.map((m) => m.id);
190
- });
191
- });
192
- ids = ids.concat(childToolMessageIds);
193
- }
194
-
195
- get().internal_dispatchMessage({ type: 'deleteMessages', ids });
196
- const result = await messageService.removeMessages(ids, {
197
- sessionId: get().activeId,
198
- topicId: get().activeTopicId,
199
- });
200
- if (result?.success && result.messages) {
201
- get().replaceMessages(result.messages);
202
- }
203
- },
204
-
205
- deleteToolMessage: async (id) => {
206
- const message = chatSelectors.getMessageById(id)(get());
207
- if (!message || message.role !== 'tool') return;
208
-
209
- const removeToolInAssistantMessage = async () => {
210
- if (!message.parentId) return;
211
- await get().internal_removeToolToAssistantMessage(message.parentId, message.tool_call_id);
212
- };
213
-
214
- await Promise.all([
215
- // 1. remove tool message
216
- get().internal_deleteMessage(id),
217
- // 2. remove the tool item in the assistant tools
218
- removeToolInAssistantMessage(),
219
- ]);
220
- },
221
-
222
- clearMessage: async () => {
223
- const { activeId, activeTopicId, refreshTopic, switchTopic, activeSessionType } = get();
224
-
225
- // Check if this is a group session - use activeSessionType if available, otherwise check session store
226
- let isGroupSession = activeSessionType === 'group';
227
- if (activeSessionType === undefined) {
228
- // Fallback: check session store directly
229
- const sessionStore = useSessionStore.getState();
230
- isGroupSession = sessionSelectors.isCurrentSessionGroupSession(sessionStore);
231
- }
232
-
233
- // For group sessions, we need to clear group messages using groupId
234
- // For regular sessions, we clear session messages using sessionId
235
- if (isGroupSession) {
236
- // For group chat, activeId is the groupId
237
- await messageService.removeMessagesByGroup(activeId, activeTopicId);
238
- } else {
239
- // For regular session, activeId is the sessionId
240
- await messageService.removeMessagesByAssistant(activeId, activeTopicId);
241
- }
242
-
243
- if (activeTopicId) {
244
- await topicService.removeTopic(activeTopicId);
245
- }
246
- await refreshTopic();
247
-
248
- // Clear messages directly since all messages are deleted
249
- get().replaceMessages([]);
250
-
251
- // after remove topic , go back to default topic
252
- switchTopic();
253
- },
254
- clearAllMessages: async () => {
255
- await messageService.removeAllMessages();
256
- // Clear messages directly since all messages are deleted
257
- get().replaceMessages([]);
258
- },
259
- addAIMessage: async () => {
260
- const { internal_createMessage, updateInputMessage, activeTopicId, activeId, inputMessage } =
261
- get();
262
- if (!activeId) return;
263
-
264
- const result = await internal_createMessage({
265
- content: inputMessage,
266
- role: 'assistant',
267
- sessionId: activeId,
268
- // if there is activeTopicId,then add topicId to message
269
- topicId: activeTopicId,
270
- });
271
-
272
- if (result) {
273
- updateInputMessage('');
274
- }
275
- },
276
- addUserMessage: async ({ message, fileList }) => {
277
- const { internal_createMessage, updateInputMessage, activeTopicId, activeId, activeThreadId } =
278
- get();
279
- if (!activeId) return;
280
-
281
- const result = await internal_createMessage({
282
- content: message,
283
- files: fileList,
284
- role: 'user',
285
- sessionId: activeId,
286
- // if there is activeTopicId,then add topicId to message
287
- topicId: activeTopicId,
288
- threadId: activeThreadId,
289
- });
290
-
291
- if (result) {
292
- updateInputMessage('');
293
- }
294
- },
295
- copyMessage: async (id, content) => {
296
- await copyToClipboard(content);
297
-
298
- get().internal_traceMessage(id, { eventType: TraceEventType.CopyMessage });
299
- },
300
- toggleMessageEditing: (id, editing) => {
301
- set(
302
- { messageEditingIds: toggleBooleanList(get().messageEditingIds, id, editing) },
303
- false,
304
- 'toggleMessageEditing',
305
- );
306
- },
307
-
308
- updateInputMessage: (message) => {
309
- if (isEqual(message, get().inputMessage)) return;
310
-
311
- set({ inputMessage: message }, false, n('updateInputMessage', message));
312
- },
313
- modifyMessageContent: async (id, content) => {
314
- // tracing the diff of update
315
- // due to message content will change, so we need send trace before update,or will get wrong data
316
- get().internal_traceMessage(id, {
317
- eventType: TraceEventType.ModifyMessage,
318
- nextContent: content,
319
- });
320
-
321
- await get().internal_updateMessageContent(id, content);
322
- },
323
-
324
- /**
325
- * @param enable - whether to enable the fetch
326
- * @param messageContextId - Can be sessionId or groupId
327
- */
328
- useFetchMessages: (enable, messageContextId, activeTopicId, type = 'session') =>
329
- useClientDataSWR<UIChatMessage[]>(
330
- enable ? [SWR_USE_FETCH_MESSAGES, messageContextId, activeTopicId, type] : null,
331
- async ([, sessionId, topicId, type]: [string, string, string | undefined, string]) =>
332
- type === 'session'
333
- ? messageService.getMessages(sessionId, topicId)
334
- : messageService.getGroupMessages(sessionId, topicId),
335
- {
336
- onSuccess: (messages, key) => {
337
- const nextMap = {
338
- ...get().messagesMap,
339
- [messageMapKey(messageContextId || '', activeTopicId)]: messages,
340
- };
341
-
342
- // no need to update map if the messages have been init and the map is the same
343
- if (get().messagesInit && isEqual(nextMap, get().messagesMap)) return;
344
-
345
- set(
346
- { messagesInit: true, messagesMap: nextMap },
347
- false,
348
- n('useFetchMessages', { messages, queryKey: key }),
349
- );
350
- },
351
- },
352
- ),
353
- // TODO: The mutate should only be called once, but since we haven't merge session and group,
354
- // we need to call it twice
355
- refreshMessages: async () => {
356
- await mutate([SWR_USE_FETCH_MESSAGES, get().activeId, get().activeTopicId, 'session']);
357
- await mutate([SWR_USE_FETCH_MESSAGES, get().activeId, get().activeTopicId, 'group']);
358
- },
359
- replaceMessages: (messages) => {
360
- set(
361
- {
362
- messagesMap: {
363
- ...get().messagesMap,
364
- [messageMapKey(get().activeId, get().activeTopicId)]: messages,
365
- },
366
- },
367
- false,
368
- 'replaceMessages',
369
- );
370
- },
371
-
372
- internal_updateMessageRAG: async (id, data) => {
373
- const result = await messageService.updateMessageRAG(id, data, {
374
- sessionId: get().activeId,
375
- topicId: get().activeTopicId,
376
- });
377
- if (result?.success && result.messages) {
378
- get().replaceMessages(result.messages);
379
- }
380
- },
381
-
382
- // the internal process method of the AI message
383
- internal_dispatchMessage: (payload, context) => {
384
- const activeId = typeof context !== 'undefined' ? context.sessionId : get().activeId;
385
- const topicId = typeof context !== 'undefined' ? context.topicId : get().activeTopicId;
386
-
387
- const messagesKey = messageMapKey(activeId, topicId);
388
-
389
- const messages = messagesReducer(chatSelectors.getBaseChatsByKey(messagesKey)(get()), payload);
390
-
391
- const nextMap = { ...get().messagesMap, [messagesKey]: messages };
392
-
393
- if (isEqual(nextMap, get().messagesMap)) return;
394
-
395
- set({ messagesMap: nextMap }, false, { type: `dispatchMessage/${payload.type}`, payload });
396
- },
397
-
398
- internal_updateMessageError: async (id, error) => {
399
- get().internal_dispatchMessage({ id, type: 'updateMessage', value: { error } });
400
- const result = await messageService.updateMessage(
401
- id,
402
- { error },
403
- { topicId: get().activeTopicId, sessionId: get().activeId },
404
- );
405
- if (result?.success && result.messages) {
406
- get().replaceMessages(result.messages);
407
- } else {
408
- await get().refreshMessages();
409
- }
410
- },
411
-
412
- internal_updateMessagePluginError: async (id, error) => {
413
- const result = await messageService.updateMessagePluginError(id, error, {
414
- sessionId: get().activeId,
415
- topicId: get().activeTopicId,
416
- });
417
- if (result?.success && result.messages) {
418
- get().replaceMessages(result.messages);
419
- }
420
- },
421
-
422
- internal_updateMessageContent: async (id, content, extra) => {
423
- const {
424
- internal_dispatchMessage,
425
- refreshMessages,
426
- internal_transformToolCalls,
427
- replaceMessages,
428
- } = get();
429
-
430
- // Due to the async update method and refresh need about 100ms
431
- // we need to update the message content at the frontend to avoid the update flick
432
- // refs: https://medium.com/@kyledeguzmanx/what-are-optimistic-updates-483662c3e171
433
- if (extra?.toolCalls) {
434
- internal_dispatchMessage({
435
- id,
436
- type: 'updateMessage',
437
- value: { tools: internal_transformToolCalls(extra?.toolCalls) },
438
- });
439
- } else {
440
- internal_dispatchMessage({
441
- id,
442
- type: 'updateMessage',
443
- value: { content },
444
- });
445
- }
446
-
447
- const result = await messageService.updateMessage(
448
- id,
449
- {
450
- content,
451
- tools: extra?.toolCalls ? internal_transformToolCalls(extra?.toolCalls) : undefined,
452
- reasoning: extra?.reasoning,
453
- search: extra?.search,
454
- metadata: extra?.metadata,
455
- model: extra?.model,
456
- provider: extra?.provider,
457
- imageList: extra?.imageList,
458
- },
459
- { topicId: get().activeTopicId, sessionId: get().activeId },
460
- );
461
-
462
- if (result && result.success && result.messages) {
463
- replaceMessages(result.messages);
464
- } else {
465
- await refreshMessages();
466
- }
467
- },
468
-
469
- internal_fetchMessages: async () => {
470
- const messages = await messageService.getMessages(get().activeId, get().activeTopicId);
471
- const nextMap = { ...get().messagesMap, [chatSelectors.currentChatKey(get())]: messages };
472
- // no need to update map if the messages have been init and the map is the same
473
- if (get().messagesInit && isEqual(nextMap, get().messagesMap)) return;
474
-
475
- set(
476
- { messagesInit: true, messagesMap: nextMap },
477
- false,
478
- n('internal_fetchMessages', { messages }),
479
- );
480
- },
481
- internal_createTmpMessage: (message) => {
482
- const { internal_dispatchMessage } = get();
483
-
484
- // use optimistic update to avoid the slow waiting
485
- const tempId = 'tmp_' + nanoid();
486
- internal_dispatchMessage({ type: 'createMessage', id: tempId, value: message });
487
-
488
- return tempId;
489
- },
490
- internal_createMessage: async (message, context) => {
491
- const {
492
- internal_createTmpMessage,
493
- internal_toggleMessageLoading,
494
- internal_dispatchMessage,
495
- replaceMessages,
496
- } = get();
497
-
498
- let tempId = context?.tempMessageId;
499
- if (!tempId) {
500
- tempId = 'tmp_' + nanoid();
501
-
502
- // Check if should add as group block (explicitly controlled by caller)
503
- if (context?.groupMessageId) {
504
- internal_dispatchMessage({
505
- type: 'addGroupBlock',
506
- groupMessageId: context.groupMessageId,
507
- blockId: tempId,
508
- value: {
509
- id: tempId,
510
- content: message.content,
511
- },
512
- });
513
- internal_toggleMessageLoading(true, tempId);
514
- } else {
515
- // Regular message creation at top level
516
- tempId = internal_createTmpMessage(message as any);
517
- internal_toggleMessageLoading(true, tempId);
518
- }
519
- }
520
-
521
- try {
522
- const result = await messageService.createMessage(message);
523
-
524
- if (!context?.skipRefresh) {
525
- // Use the messages returned from createMessage (already grouped)
526
- replaceMessages(result.messages);
527
- }
528
-
529
- internal_toggleMessageLoading(false, tempId);
530
- return result;
531
- } catch (e) {
532
- internal_toggleMessageLoading(false, tempId);
533
- internal_dispatchMessage({
534
- id: tempId,
535
- type: 'updateMessage',
536
- value: {
537
- error: {
538
- type: ChatErrorType.CreateMessageError,
539
- message: (e as Error).message,
540
- body: e,
541
- },
542
- },
543
- });
544
- }
545
- },
546
-
547
- internal_deleteMessage: async (id: string) => {
548
- get().internal_dispatchMessage({ type: 'deleteMessage', id });
549
- const result = await messageService.removeMessage(id, {
550
- sessionId: get().activeId,
551
- topicId: get().activeTopicId,
552
- });
553
- if (result?.success && result.messages) {
554
- get().replaceMessages(result.messages);
555
- }
556
- },
557
- internal_traceMessage: async (id, payload) => {
558
- // tracing the diff of update
559
- const message = chatSelectors.getMessageById(id)(get());
560
- if (!message) return;
561
-
562
- const traceId = message?.traceId;
563
- const observationId = message?.observationId;
564
-
565
- if (traceId && message?.role === 'assistant') {
566
- traceService
567
- .traceEvent({ traceId, observationId, content: message.content, ...payload })
568
- .catch();
569
- }
570
- },
571
-
572
- // ----- Loading ------- //
573
- internal_toggleMessageLoading: (loading, id) => {
574
- set(
575
- {
576
- messageLoadingIds: toggleBooleanList(get().messageLoadingIds, id, loading),
577
- },
578
- false,
579
- `internal_toggleMessageLoading/${loading ? 'start' : 'end'}`,
580
- );
581
- },
582
- internal_toggleLoadingArrays: (key, loading, id, action) => {
583
- const abortControllerKey = `${key}AbortController`;
584
- if (loading) {
585
- window.addEventListener('beforeunload', preventLeavingFn);
586
-
587
- const abortController = new AbortController();
588
- set(
589
- {
590
- [abortControllerKey]: abortController,
591
- [key]: toggleBooleanList(get()[key] as string[], id!, loading),
592
- },
593
- false,
594
- action,
595
- );
596
-
597
- return abortController;
598
- } else {
599
- if (!id) {
600
- set({ [abortControllerKey]: undefined, [key]: [] }, false, action);
601
- } else
602
- set(
603
- {
604
- [abortControllerKey]: undefined,
605
- [key]: toggleBooleanList(get()[key] as string[], id, loading),
606
- },
607
- false,
608
- action,
609
- );
610
-
611
- window.removeEventListener('beforeunload', preventLeavingFn);
612
- }
613
- },
614
- internal_updateActiveSessionType: (sessionType?: 'agent' | 'group') => {
615
- if (get().activeSessionType === sessionType) return;
616
-
617
- set({ activeSessionType: sessionType }, false, n('updateActiveSessionType'));
618
- },
619
-
620
- internal_updateActiveId: (activeId: string) => {
621
- const currentActiveId = get().activeId;
622
- if (currentActiveId === activeId) return;
623
-
624
- // Before switching sessions, cancel all pending supervisor decisions
625
- get().internal_cancelAllSupervisorDecisions();
626
-
627
- set({ activeId }, false, n(`updateActiveId/${activeId}`));
628
- },
629
- });