@lobehub/lobehub 2.0.0-next.47 → 2.0.0-next.49

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 (311) hide show
  1. package/.env.example +11 -0
  2. package/CHANGELOG.md +50 -0
  3. package/README.md +1 -1
  4. package/README.zh-CN.md +1 -1
  5. package/apps/desktop/src/main/controllers/AuthCtr.ts +27 -2
  6. package/apps/desktop/src/main/core/infrastructure/ProtocolManager.ts +9 -4
  7. package/changelog/v1.json +17 -0
  8. package/docs/development/database-schema.dbml +2 -0
  9. package/docs/self-hosting/environment-variables/basic.mdx +49 -3
  10. package/docs/self-hosting/environment-variables/basic.zh-CN.mdx +49 -4
  11. package/locales/ar/chat.json +1 -0
  12. package/locales/ar/discover.json +45 -0
  13. package/locales/ar/marketAuth.json +42 -0
  14. package/locales/ar/setting.json +94 -1
  15. package/locales/ar/topic.json +1 -0
  16. package/locales/bg-BG/chat.json +1 -0
  17. package/locales/bg-BG/discover.json +45 -0
  18. package/locales/bg-BG/marketAuth.json +42 -0
  19. package/locales/bg-BG/setting.json +94 -1
  20. package/locales/bg-BG/topic.json +1 -0
  21. package/locales/de-DE/chat.json +1 -0
  22. package/locales/de-DE/discover.json +45 -0
  23. package/locales/de-DE/marketAuth.json +42 -0
  24. package/locales/de-DE/setting.json +94 -1
  25. package/locales/de-DE/topic.json +1 -0
  26. package/locales/en-US/chat.json +1 -0
  27. package/locales/en-US/discover.json +45 -0
  28. package/locales/en-US/marketAuth.json +42 -0
  29. package/locales/en-US/setting.json +94 -1
  30. package/locales/en-US/topic.json +1 -0
  31. package/locales/es-ES/chat.json +1 -0
  32. package/locales/es-ES/discover.json +45 -0
  33. package/locales/es-ES/marketAuth.json +42 -0
  34. package/locales/es-ES/setting.json +94 -1
  35. package/locales/es-ES/topic.json +1 -0
  36. package/locales/fa-IR/chat.json +1 -0
  37. package/locales/fa-IR/discover.json +45 -0
  38. package/locales/fa-IR/marketAuth.json +42 -0
  39. package/locales/fa-IR/setting.json +94 -1
  40. package/locales/fa-IR/topic.json +1 -0
  41. package/locales/fr-FR/chat.json +1 -0
  42. package/locales/fr-FR/discover.json +45 -0
  43. package/locales/fr-FR/marketAuth.json +42 -0
  44. package/locales/fr-FR/setting.json +94 -1
  45. package/locales/fr-FR/topic.json +1 -0
  46. package/locales/it-IT/chat.json +1 -0
  47. package/locales/it-IT/discover.json +45 -0
  48. package/locales/it-IT/marketAuth.json +42 -0
  49. package/locales/it-IT/setting.json +94 -1
  50. package/locales/it-IT/topic.json +1 -0
  51. package/locales/ja-JP/chat.json +1 -0
  52. package/locales/ja-JP/discover.json +45 -0
  53. package/locales/ja-JP/marketAuth.json +42 -0
  54. package/locales/ja-JP/setting.json +94 -1
  55. package/locales/ja-JP/topic.json +1 -0
  56. package/locales/ko-KR/chat.json +1 -0
  57. package/locales/ko-KR/discover.json +45 -0
  58. package/locales/ko-KR/marketAuth.json +42 -0
  59. package/locales/ko-KR/setting.json +94 -1
  60. package/locales/ko-KR/topic.json +1 -0
  61. package/locales/nl-NL/chat.json +1 -0
  62. package/locales/nl-NL/discover.json +45 -0
  63. package/locales/nl-NL/marketAuth.json +42 -0
  64. package/locales/nl-NL/setting.json +94 -1
  65. package/locales/nl-NL/topic.json +1 -0
  66. package/locales/pl-PL/chat.json +1 -0
  67. package/locales/pl-PL/discover.json +45 -0
  68. package/locales/pl-PL/marketAuth.json +42 -0
  69. package/locales/pl-PL/setting.json +94 -1
  70. package/locales/pl-PL/topic.json +1 -0
  71. package/locales/pt-BR/chat.json +1 -0
  72. package/locales/pt-BR/discover.json +45 -0
  73. package/locales/pt-BR/marketAuth.json +42 -0
  74. package/locales/pt-BR/setting.json +94 -1
  75. package/locales/pt-BR/topic.json +1 -0
  76. package/locales/ru-RU/chat.json +1 -0
  77. package/locales/ru-RU/discover.json +45 -0
  78. package/locales/ru-RU/marketAuth.json +42 -0
  79. package/locales/ru-RU/setting.json +94 -1
  80. package/locales/ru-RU/topic.json +1 -0
  81. package/locales/tr-TR/chat.json +1 -0
  82. package/locales/tr-TR/discover.json +45 -0
  83. package/locales/tr-TR/marketAuth.json +42 -0
  84. package/locales/tr-TR/setting.json +94 -1
  85. package/locales/tr-TR/topic.json +1 -0
  86. package/locales/vi-VN/chat.json +1 -0
  87. package/locales/vi-VN/discover.json +45 -0
  88. package/locales/vi-VN/marketAuth.json +42 -0
  89. package/locales/vi-VN/setting.json +94 -1
  90. package/locales/vi-VN/topic.json +1 -0
  91. package/locales/zh-CN/chat.json +1 -0
  92. package/locales/zh-CN/discover.json +45 -0
  93. package/locales/zh-CN/marketAuth.json +42 -0
  94. package/locales/zh-CN/setting.json +94 -1
  95. package/locales/zh-CN/topic.json +1 -0
  96. package/locales/zh-TW/chat.json +1 -0
  97. package/locales/zh-TW/discover.json +45 -0
  98. package/locales/zh-TW/marketAuth.json +42 -0
  99. package/locales/zh-TW/setting.json +94 -1
  100. package/locales/zh-TW/topic.json +1 -0
  101. package/package.json +34 -27
  102. package/packages/agent-runtime/src/core/InterventionChecker.ts +5 -16
  103. package/packages/agent-runtime/src/core/__tests__/InterventionChecker.test.ts +27 -80
  104. package/packages/agent-runtime/src/core/__tests__/runtime.test.ts +32 -13
  105. package/packages/agent-runtime/src/core/runtime.ts +7 -3
  106. package/packages/agent-runtime/src/types/event.ts +2 -1
  107. package/packages/agent-runtime/src/types/generalAgent.ts +1 -0
  108. package/packages/agent-runtime/src/types/instruction.ts +3 -2
  109. package/packages/agent-runtime/src/types/state.ts +3 -1
  110. package/packages/const/src/url.ts +1 -0
  111. package/packages/conversation-flow/src/transformation/FlatListBuilder.ts +4 -1
  112. package/packages/database/migrations/0044_add_tool_intervention.sql +1 -0
  113. package/packages/database/migrations/0044_high_toxin.sql +1 -0
  114. package/packages/database/migrations/0045_add_tool_intervention.sql +1 -0
  115. package/packages/database/migrations/meta/0039_snapshot.json +1 -1
  116. package/packages/database/migrations/meta/0044_snapshot.json +7813 -0
  117. package/packages/database/migrations/meta/0045_snapshot.json +8431 -0
  118. package/packages/database/migrations/meta/_journal.json +14 -0
  119. package/packages/database/src/core/migrations.json +36 -7
  120. package/packages/database/src/models/message.ts +4 -1
  121. package/packages/database/src/models/session.ts +42 -1
  122. package/packages/database/src/schemas/agent.ts +1 -0
  123. package/packages/database/src/schemas/message.ts +5 -8
  124. package/packages/electron-client-ipc/src/events/index.ts +6 -1
  125. package/packages/electron-client-ipc/src/events/remoteServer.ts +8 -0
  126. package/packages/fetch-sse/package.json +29 -0
  127. package/packages/{utils/src/fetch → fetch-sse/src}/__tests__/fetchSSE.test.ts +4 -4
  128. package/packages/{utils/src/fetch → fetch-sse/src}/__tests__/parseError.test.ts +7 -4
  129. package/packages/{utils/src/fetch → fetch-sse/src}/fetchSSE.ts +2 -2
  130. package/packages/{utils/src/fetch → fetch-sse/src}/parseError.ts +3 -3
  131. package/packages/model-bank/src/aiModels/mistral.ts +2 -1
  132. package/packages/model-runtime/src/core/contextBuilders/anthropic.test.ts +17 -11
  133. package/packages/model-runtime/src/core/contextBuilders/anthropic.ts +1 -1
  134. package/packages/model-runtime/src/core/contextBuilders/google.test.ts +1 -1
  135. package/packages/model-runtime/src/core/contextBuilders/google.ts +3 -6
  136. package/packages/model-runtime/src/core/contextBuilders/openai.test.ts +4 -2
  137. package/packages/model-runtime/src/core/contextBuilders/openai.ts +1 -1
  138. package/packages/model-runtime/src/core/openaiCompatibleFactory/createImage.test.ts +1 -1
  139. package/packages/model-runtime/src/core/openaiCompatibleFactory/createImage.ts +1 -1
  140. package/packages/model-runtime/src/core/openaiCompatibleFactory/index.test.ts +3 -6
  141. package/packages/model-runtime/src/core/streams/openai/responsesStream.test.ts +1 -1
  142. package/packages/model-runtime/src/helpers/mergeChatMethodOptions.ts +2 -1
  143. package/packages/model-runtime/src/providers/aihubmix/index.test.ts +1 -1
  144. package/packages/model-runtime/src/providers/anthropic/generateObject.test.ts +1 -1
  145. package/packages/model-runtime/src/providers/anthropic/index.test.ts +1 -1
  146. package/packages/model-runtime/src/providers/baichuan/index.test.ts +1 -1
  147. package/packages/model-runtime/src/providers/bedrock/index.test.ts +1 -1
  148. package/packages/model-runtime/src/providers/bfl/createImage.test.ts +4 -4
  149. package/packages/model-runtime/src/providers/bfl/createImage.ts +1 -1
  150. package/packages/model-runtime/src/providers/cloudflare/index.test.ts +1 -1
  151. package/packages/model-runtime/src/providers/cohere/index.test.ts +1 -1
  152. package/packages/model-runtime/src/providers/google/createImage.test.ts +2 -2
  153. package/packages/model-runtime/src/providers/google/createImage.ts +1 -1
  154. package/packages/model-runtime/src/providers/google/generateObject.test.ts +1 -1
  155. package/packages/model-runtime/src/providers/google/index.test.ts +1 -4
  156. package/packages/model-runtime/src/providers/groq/index.test.ts +1 -1
  157. package/packages/model-runtime/src/providers/hunyuan/index.test.ts +1 -1
  158. package/packages/model-runtime/src/providers/minimax/createImage.test.ts +1 -1
  159. package/packages/model-runtime/src/providers/mistral/index.test.ts +1 -1
  160. package/packages/model-runtime/src/providers/moonshot/index.test.ts +1 -1
  161. package/packages/model-runtime/src/providers/novita/index.test.ts +1 -1
  162. package/packages/model-runtime/src/providers/ollama/index.test.ts +43 -32
  163. package/packages/model-runtime/src/providers/ollama/index.ts +31 -7
  164. package/packages/model-runtime/src/providers/openrouter/index.test.ts +1 -1
  165. package/packages/model-runtime/src/providers/perplexity/index.test.ts +1 -1
  166. package/packages/model-runtime/src/providers/ppio/index.test.ts +1 -1
  167. package/packages/model-runtime/src/providers/qwen/createImage.test.ts +1 -1
  168. package/packages/model-runtime/src/providers/search1api/index.test.ts +1 -1
  169. package/packages/model-runtime/src/providers/siliconcloud/createImage.ts +1 -1
  170. package/packages/model-runtime/src/providers/taichu/index.test.ts +1 -1
  171. package/packages/model-runtime/src/providers/wenxin/index.test.ts +1 -1
  172. package/packages/model-runtime/src/providers/zhipu/index.test.ts +1 -1
  173. package/packages/model-runtime/src/utils/errorResponse.test.ts +1 -1
  174. package/packages/obervability-otel/src/node.ts +15 -1
  175. package/packages/ssrf-safe-fetch/index.browser.ts +14 -0
  176. package/packages/ssrf-safe-fetch/package.json +8 -1
  177. package/packages/types/src/discover/assistants.ts +16 -0
  178. package/packages/types/src/index.ts +1 -0
  179. package/packages/types/src/message/common/base.ts +2 -2
  180. package/packages/types/src/message/common/tools.ts +16 -0
  181. package/packages/types/src/message/db/item.ts +15 -1
  182. package/packages/types/src/message/ui/chat.ts +7 -1
  183. package/packages/types/src/message/ui/params.ts +15 -1
  184. package/packages/types/src/meta.ts +4 -0
  185. package/packages/types/src/session/agentSession.ts +2 -0
  186. package/packages/types/src/tool/intervention.ts +2 -3
  187. package/packages/types/src/user/settings/tool.ts +15 -28
  188. package/packages/utils/src/imageToBase64.ts +17 -10
  189. package/packages/utils/src/index.ts +1 -1
  190. package/renovate.json +28 -11
  191. package/src/app/(backend)/market/agent/[[...segments]]/route.ts +153 -0
  192. package/src/app/(backend)/market/oidc/[[...segments]]/route.ts +207 -0
  193. package/src/app/[variants]/(main)/(mobile)/me/settings/features/useCategory.tsx +1 -0
  194. package/src/app/[variants]/(main)/_layout/Desktop/SideBar/PinList/index.tsx +4 -2
  195. package/src/app/[variants]/(main)/chat/components/topic/features/Topic/TopicListContent/TopicItem/TopicContent.tsx +1 -1
  196. package/src/app/[variants]/(main)/chat/session/features/SessionListContent/List/Item/Actions.tsx +1 -1
  197. package/src/app/[variants]/(main)/chat/settings/features/AgentInfoDescription/index.tsx +349 -0
  198. package/src/app/[variants]/(main)/chat/settings/features/HeaderContent.tsx +2 -2
  199. package/src/app/[variants]/(main)/chat/settings/features/PublishResultModal/index.tsx +64 -0
  200. package/src/app/[variants]/(main)/chat/settings/features/SmartAgentActionButton/MarketPublishButton.tsx +196 -0
  201. package/src/app/[variants]/(main)/chat/settings/features/SmartAgentActionButton/MarketPublishModal.tsx +358 -0
  202. package/src/app/[variants]/(main)/chat/settings/features/SmartAgentActionButton/index.tsx +75 -0
  203. package/src/app/[variants]/(main)/discover/(detail)/assistant/AssistantDetailPage.tsx +11 -2
  204. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/Client.tsx +12 -1
  205. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/Nav.tsx +19 -12
  206. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/Overview/TagList.tsx +14 -5
  207. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/Overview/index.tsx +2 -0
  208. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/Related/index.tsx +14 -5
  209. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/SystemRole/TagList.tsx +14 -5
  210. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/SystemRole/index.tsx +43 -29
  211. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/Versions/index.tsx +137 -0
  212. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/index.tsx +2 -0
  213. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Header.tsx +9 -10
  214. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Sidebar/ActionButton/AddAgent.tsx +105 -14
  215. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Sidebar/Related/index.tsx +20 -6
  216. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/StatusPage/index.tsx +113 -0
  217. package/src/app/[variants]/(main)/discover/(detail)/features/Breadcrumb.tsx +4 -3
  218. package/src/app/[variants]/(main)/discover/(list)/_layout/Desktop/Nav.tsx +3 -1
  219. package/src/app/[variants]/(main)/discover/(list)/assistant/AssistantPage.tsx +4 -1
  220. package/src/app/[variants]/(main)/discover/(list)/assistant/Client.tsx +6 -2
  221. package/src/app/[variants]/(main)/discover/(list)/assistant/features/Category/index.tsx +7 -3
  222. package/src/app/[variants]/(main)/discover/(list)/assistant/features/List/Item.tsx +13 -2
  223. package/src/app/[variants]/(main)/discover/(list)/assistant/features/MarketSourceSwitch.tsx +64 -0
  224. package/src/app/[variants]/(main)/discover/(list)/features/SortButton/index.tsx +26 -7
  225. package/src/app/[variants]/(main)/profile/_layout/Desktop/index.tsx +10 -10
  226. package/src/app/[variants]/(main)/settings/_layout/type.ts +1 -1
  227. package/src/app/[variants]/(main)/settings/agent/index.tsx +11 -10
  228. package/src/app/[variants]/(main)/settings/common/index.tsx +1 -1
  229. package/src/app/[variants]/(main)/settings/page.tsx +13 -10
  230. package/src/app/[variants]/(main)/settings/provider/ProviderMenu/Item.tsx +35 -36
  231. package/src/app/[variants]/(main)/settings/provider/ProviderMenu/SearchResult.tsx +5 -5
  232. package/src/app/[variants]/(main)/settings/provider/_layout/Desktop/Container.tsx +10 -4
  233. package/src/app/market-auth-callback/layout.tsx +15 -0
  234. package/src/app/market-auth-callback/page.tsx +196 -0
  235. package/src/features/AgentSetting/AgentPrompt/TokenTag.tsx +3 -2
  236. package/src/features/AgentSetting/AgentTTS/SelectWithTTSPreview.tsx +1 -1
  237. package/src/features/AgentSetting/store/action.ts +1 -1
  238. package/src/features/ChatInput/ActionBar/STT/browser.tsx +1 -1
  239. package/src/features/ChatInput/ActionBar/STT/openai.tsx +1 -1
  240. package/src/features/Conversation/Messages/Group/GroupChildren.tsx +20 -15
  241. package/src/features/Conversation/Messages/Group/GroupContext.tsx +15 -0
  242. package/src/features/Conversation/Messages/Group/Tool/Inspector/BuiltinPluginTitle.tsx +2 -4
  243. package/src/features/Conversation/Messages/Group/Tool/Inspector/ToolTitle.tsx +3 -5
  244. package/src/features/Conversation/Messages/Group/Tool/Inspector/index.tsx +19 -7
  245. package/src/features/Conversation/Messages/Group/Tool/Render/Arguments/index.tsx +14 -12
  246. package/src/features/Conversation/Messages/Group/Tool/Render/Intervention/ApprovalActions.tsx +143 -0
  247. package/src/features/Conversation/Messages/Group/Tool/Render/Intervention/KeyValueEditor.tsx +213 -0
  248. package/src/features/Conversation/Messages/Group/Tool/Render/Intervention/ModeSelector.tsx +134 -0
  249. package/src/features/Conversation/Messages/Group/Tool/Render/Intervention/index.tsx +99 -0
  250. package/src/features/Conversation/Messages/Group/Tool/Render/RejectedResponse.tsx +45 -0
  251. package/src/features/Conversation/Messages/Group/Tool/Render/index.tsx +23 -1
  252. package/src/features/Conversation/Messages/Group/Tool/index.tsx +42 -18
  253. package/src/features/Conversation/Messages/Group/Tools.tsx +3 -1
  254. package/src/features/Conversation/components/Extras/TTS/InitPlayer.tsx +1 -1
  255. package/src/features/PluginTag/PluginStatus.tsx +1 -1
  256. package/src/hooks/useAgentOwnershipCheck.ts +143 -0
  257. package/src/instrumentation.node.ts +3 -2
  258. package/src/layout/AuthProvider/MarketAuth/MarketAuthProvider.tsx +364 -0
  259. package/src/layout/AuthProvider/MarketAuth/errors.ts +75 -0
  260. package/src/layout/AuthProvider/MarketAuth/index.ts +2 -0
  261. package/src/layout/AuthProvider/MarketAuth/oidc.ts +382 -0
  262. package/src/layout/AuthProvider/MarketAuth/types.ts +64 -0
  263. package/src/layout/AuthProvider/index.tsx +17 -4
  264. package/src/locales/default/chat.ts +22 -0
  265. package/src/locales/default/common.ts +1 -0
  266. package/src/locales/default/discover.ts +46 -0
  267. package/src/locales/default/index.ts +2 -0
  268. package/src/locales/default/marketAuth.ts +42 -0
  269. package/src/locales/default/setting.ts +94 -1
  270. package/src/locales/default/topic.ts +1 -0
  271. package/src/server/globalConfig/genServerAiProviderConfig.test.ts +5 -5
  272. package/src/server/globalConfig/genServerAiProviderConfig.ts +1 -1
  273. package/src/server/routers/lambda/market/index.ts +36 -14
  274. package/src/server/routers/lambda/message.ts +6 -3
  275. package/src/server/services/discover/index.test.ts +153 -11
  276. package/src/server/services/discover/index.ts +339 -40
  277. package/src/server/services/message/index.ts +13 -0
  278. package/src/server/sitemap.ts +49 -35
  279. package/src/services/_url.ts +15 -1
  280. package/src/services/chat/chat.test.ts +5 -5
  281. package/src/services/chat/clientModelRuntime.test.ts +1 -1
  282. package/src/services/chat/index.ts +6 -6
  283. package/src/services/chat/types.ts +1 -2
  284. package/src/services/discover.ts +16 -5
  285. package/src/services/electron/remoteServer.ts +8 -1
  286. package/src/services/marketApi.ts +124 -0
  287. package/src/services/message/index.ts +17 -2
  288. package/src/services/models.ts +2 -1
  289. package/src/store/chat/agents/GeneralChatAgent.ts +141 -24
  290. package/src/store/chat/agents/__tests__/GeneralChatAgent.test.ts +605 -0
  291. package/src/store/chat/agents/createAgentExecutors.ts +144 -26
  292. package/src/store/chat/agents/createToolEngine.ts +22 -0
  293. package/src/store/chat/slices/aiChat/actions/conversationControl.ts +106 -0
  294. package/src/store/chat/slices/aiChat/actions/streamingExecutor.ts +54 -26
  295. package/src/store/chat/slices/message/reducer.ts +2 -1
  296. package/src/store/chat/slices/plugin/actions/optimisticUpdate.ts +26 -1
  297. package/src/store/discover/slices/assistant/action.ts +20 -7
  298. package/src/store/user/slices/settings/action.ts +15 -0
  299. package/{packages/utils/src → src/utils}/electron/desktopRemoteRPCFetch.ts +1 -1
  300. package/{packages/utils/src → src/utils/server}/parseModels.ts +1 -2
  301. package/vitest.config.mts +2 -0
  302. package/packages/model-runtime/src/utils/imageToBase64.test.ts +0 -91
  303. package/packages/model-runtime/src/utils/imageToBase64.ts +0 -62
  304. package/src/app/[variants]/(main)/chat/settings/features/SubmitAgentButton/SubmitAgentModal.tsx +0 -98
  305. package/src/app/[variants]/(main)/chat/settings/features/SubmitAgentButton/index.tsx +0 -35
  306. package/src/app/[variants]/(main)/chat/settings/features/SubmitAgentButton/style.ts +0 -47
  307. /package/packages/{utils/src/fetch → fetch-sse/src}/headers.ts +0 -0
  308. /package/packages/{utils/src/fetch → fetch-sse/src}/index.ts +0 -0
  309. /package/packages/{utils/src/fetch → fetch-sse/src}/request.ts +0 -0
  310. /package/{packages/utils/src → src/utils/server}/__snapshots__/parseModels.test.ts.snap +0 -0
  311. /package/{packages/utils/src → src/utils/server}/parseModels.test.ts +0 -0
@@ -1,6 +1,5 @@
1
1
  /* eslint-disable sort-keys-fix/sort-keys-fix */
2
2
 
3
-
4
3
  export const API_ENDPOINTS = {
5
4
  oauth: '/api/auth',
6
5
 
@@ -30,3 +29,18 @@ export const API_ENDPOINTS = {
30
29
  edge: '/webapi/tts/edge',
31
30
  microsoft: '/webapi/tts/microsoft',
32
31
  };
32
+
33
+ export const MARKET_OIDC_ENDPOINTS = {
34
+ auth: '/lobehub-oidc/auth',
35
+ token: '/market/oidc/token',
36
+ userinfo: '/market/oidc/userinfo',
37
+ handoff: '/market/oidc/handoff',
38
+ desktopCallback: '/lobehub-oidc/callback/desktop',
39
+ };
40
+
41
+ export const MARKET_ENDPOINTS = {
42
+ base: '/market',
43
+ createAgent: '/market/agent/create',
44
+ getAgentDetail: (identifier: string) => `/market/agent/${encodeURIComponent(identifier)}`,
45
+ createAgentVersion: '/market/agent/versions/create',
46
+ };
@@ -27,7 +27,7 @@ vi.stubGlobal(
27
27
  );
28
28
 
29
29
  // Mock image processing utilities
30
- vi.mock('@/utils/fetch', async (importOriginal) => {
30
+ vi.mock('@lobechat/fetch-sse', async (importOriginal) => {
31
31
  const module = await importOriginal();
32
32
 
33
33
  return { ...(module as any), getMessageError: vi.fn() };
@@ -988,7 +988,7 @@ describe('ChatService', () => {
988
988
 
989
989
  beforeEach(async () => {
990
990
  // Setup common fetchSSE mock for getChatCompletion tests
991
- const { fetchSSE } = await import('@/utils/fetch');
991
+ const { fetchSSE } = await import('@lobechat/fetch-sse');
992
992
  mockFetchSSE = vi.fn().mockResolvedValue(new Response('mock response'));
993
993
  vi.mocked(fetchSSE).mockImplementation(mockFetchSSE);
994
994
  });
@@ -1049,7 +1049,7 @@ describe('ChatService', () => {
1049
1049
 
1050
1050
  it('should return InvalidAccessCode error when enableFetchOnClient is true and auth is enabled but user is not signed in', async () => {
1051
1051
  // Mock fetchSSE to call onErrorHandle with the error
1052
- const { fetchSSE } = await import('@/utils/fetch');
1052
+ const { fetchSSE } = await import('@lobechat/fetch-sse');
1053
1053
 
1054
1054
  const mockFetchSSEWithError = vi.fn().mockImplementation((url, options) => {
1055
1055
  // Simulate the error being caught and passed to onErrorHandle
@@ -1211,8 +1211,8 @@ vi.mock('../_auth', async (importOriginal) => {
1211
1211
  describe('ChatService private methods', () => {
1212
1212
  describe('getChatCompletion', () => {
1213
1213
  it('should merge responseAnimation styles correctly', async () => {
1214
- const { fetchSSE } = await import('@/utils/fetch');
1215
- vi.mock('@/utils/fetch', async (importOriginal) => {
1214
+ const { fetchSSE } = await import('@lobechat/fetch-sse');
1215
+ vi.mock('@lobechat/fetch-sse', async (importOriginal) => {
1216
1216
  const module = await importOriginal();
1217
1217
  return {
1218
1218
  ...(module as any),
@@ -38,7 +38,7 @@ vi.stubGlobal(
38
38
  vi.fn(() => Promise.resolve(new Response(JSON.stringify({ some: 'data' })))),
39
39
  );
40
40
 
41
- vi.mock('@/utils/fetch', async (importOriginal) => {
41
+ vi.mock('@lobechat/fetch-sse', async (importOriginal) => {
42
42
  const module = await importOriginal();
43
43
 
44
44
  return { ...(module as any), getMessageError: vi.fn() };
@@ -1,3 +1,9 @@
1
+ import {
2
+ FetchSSEOptions,
3
+ fetchSSE,
4
+ getMessageError,
5
+ standardizeAnimationStyle,
6
+ } from '@lobechat/fetch-sse';
1
7
  import { AgentRuntimeError, ChatCompletionErrorPayload } from '@lobechat/model-runtime';
2
8
  import { ChatErrorType, TracePayload, TraceTagMap, UIChatMessage } from '@lobechat/types';
3
9
  import { PluginRequestPayload, createHeadersWithPluginSettings } from '@lobehub/chat-plugin-sdk';
@@ -25,12 +31,6 @@ import {
25
31
  import type { ChatStreamPayload, OpenAIChatMessage } from '@/types/openai/chat';
26
32
  import { fetchWithInvokeStream } from '@/utils/electron/desktopRemoteRPCFetch';
27
33
  import { createErrorResponse } from '@/utils/errorResponse';
28
- import {
29
- FetchSSEOptions,
30
- fetchSSE,
31
- getMessageError,
32
- standardizeAnimationStyle,
33
- } from '@/utils/fetch';
34
34
  import { createTraceHeader, getTraceId } from '@/utils/trace';
35
35
 
36
36
  import { createHeaderWithAuth } from '../_auth';
@@ -1,7 +1,6 @@
1
+ import { FetchSSEOptions } from '@lobechat/fetch-sse';
1
2
  import { TracePayload } from '@lobechat/types';
2
3
 
3
- import { FetchSSEOptions } from '@/utils/fetch';
4
-
5
4
  export interface FetchOptions extends FetchSSEOptions {
6
5
  historySummary?: string;
7
6
  signal?: AbortSignal | undefined;
@@ -7,6 +7,7 @@ import { useUserStore } from '@/store/user';
7
7
  import { preferenceSelectors } from '@/store/user/selectors';
8
8
  import {
9
9
  AssistantListResponse,
10
+ AssistantMarketSource,
10
11
  AssistantQueryParams,
11
12
  DiscoverAssistantDetail,
12
13
  DiscoverMcpDetail,
@@ -30,27 +31,37 @@ class DiscoverService {
30
31
  private _isRetrying = false;
31
32
 
32
33
  // ============================== Assistant Market ==============================
33
- getAssistantCategories = async (params: CategoryListQuery = {}): Promise<CategoryItem[]> => {
34
+ getAssistantCategories = async (
35
+ params: CategoryListQuery & { source?: AssistantMarketSource } = {},
36
+ ): Promise<CategoryItem[]> => {
34
37
  const locale = globalHelpers.getCurrentLanguage();
38
+ const { source, ...rest } = params;
35
39
  return lambdaClient.market.getAssistantCategories.query({
36
- ...params,
40
+ ...rest,
37
41
  locale,
42
+ source,
38
43
  });
39
44
  };
40
45
 
41
46
  getAssistantDetail = async (params: {
42
47
  identifier: string;
43
48
  locale?: string;
49
+ source?: AssistantMarketSource;
50
+ version?: string;
44
51
  }): Promise<DiscoverAssistantDetail | undefined> => {
45
52
  const locale = globalHelpers.getCurrentLanguage();
46
53
  return lambdaClient.market.getAssistantDetail.query({
47
- ...params,
54
+ identifier: params.identifier,
48
55
  locale,
56
+ source: params.source,
57
+ version: params.version,
49
58
  });
50
59
  };
51
60
 
52
- getAssistantIdentifiers = async (): Promise<IdentifiersResponse> => {
53
- return lambdaClient.market.getAssistantIdentifiers.query();
61
+ getAssistantIdentifiers = async (
62
+ params: { source?: AssistantMarketSource } = {},
63
+ ): Promise<IdentifiersResponse> => {
64
+ return lambdaClient.market.getAssistantIdentifiers.query(params);
54
65
  };
55
66
 
56
67
  getAssistantList = async (params: AssistantQueryParams = {}): Promise<AssistantListResponse> => {
@@ -1,4 +1,4 @@
1
- import { DataSyncConfig, dispatch } from '@lobechat/electron-client-ipc';
1
+ import { DataSyncConfig, MarketAuthorizationParams, dispatch } from '@lobechat/electron-client-ipc';
2
2
 
3
3
  class RemoteServerService {
4
4
  /**
@@ -28,6 +28,13 @@ class RemoteServerService {
28
28
  requestAuthorization = async (config: DataSyncConfig) => {
29
29
  return dispatch('requestAuthorization', config);
30
30
  };
31
+
32
+ /**
33
+ * 请求 Market 授权
34
+ */
35
+ requestMarketAuthorization = async (params: MarketAuthorizationParams) => {
36
+ return dispatch('requestMarketAuthorization', params);
37
+ };
31
38
  }
32
39
 
33
40
  export const remoteServerService = new RemoteServerService();
@@ -0,0 +1,124 @@
1
+ import { AgentItemDetail } from '@lobehub/market-sdk';
2
+
3
+ import { MARKET_ENDPOINTS } from '@/services/_url';
4
+
5
+ export class MarketApiService {
6
+ private accessToken?: string;
7
+
8
+ // eslint-disable-next-line no-undef
9
+ private async request<T>(endpoint: string, init?: RequestInit): Promise<T> {
10
+ const headers = new Headers(init?.headers);
11
+
12
+ if (init?.body && !headers.has('content-type')) {
13
+ headers.set('content-type', 'application/json');
14
+ }
15
+
16
+ if (this.accessToken && !headers.has('authorization')) {
17
+ headers.set('authorization', `Bearer ${this.accessToken}`);
18
+ }
19
+
20
+ const response = await fetch(endpoint, {
21
+ ...init,
22
+ credentials: init?.credentials ?? 'same-origin',
23
+ headers,
24
+ });
25
+
26
+ if (!response.ok) {
27
+ let message = 'Unknown error';
28
+
29
+ try {
30
+ const errorBody = await response.json();
31
+ message = errorBody?.message ?? message;
32
+ } catch {
33
+ message = await response.text();
34
+ }
35
+
36
+ throw new Error(message || 'Market request failed');
37
+ }
38
+
39
+ if (response.status === 204) {
40
+ return undefined as T;
41
+ }
42
+
43
+ return (await response.json()) as T;
44
+ }
45
+
46
+ setAccessToken(token: string) {
47
+ this.accessToken = token;
48
+ }
49
+ // Create new agent
50
+ async createAgent(agentData: {
51
+ homepage?: string;
52
+ identifier: string;
53
+ isFeatured?: boolean;
54
+ name: string;
55
+ status?: 'published' | 'unpublished' | 'archived' | 'deprecated';
56
+ tokenUsage?: number;
57
+ visibility?: 'public' | 'private' | 'internal';
58
+ }): Promise<AgentItemDetail> {
59
+ return this.request(MARKET_ENDPOINTS.createAgent, {
60
+ body: JSON.stringify(agentData),
61
+ method: 'POST',
62
+ });
63
+ }
64
+
65
+ // Get agent detail by identifier
66
+ async getAgentDetail(identifier: string): Promise<AgentItemDetail> {
67
+ return this.request(MARKET_ENDPOINTS.getAgentDetail(identifier), {
68
+ method: 'GET',
69
+ });
70
+ }
71
+
72
+ // Check if agent exists (returns true if exists, false if not)
73
+ async checkAgentExists(identifier: string): Promise<boolean> {
74
+ try {
75
+ await this.getAgentDetail(identifier);
76
+ return true;
77
+ } catch {
78
+ return false;
79
+ }
80
+ }
81
+
82
+ // Create agent version
83
+ async createAgentVersion(versionData: {
84
+ a2aProtocolVersion?: string;
85
+ avatar?: string;
86
+ category?: string;
87
+ changelog?: string;
88
+ config?: Record<string, any>;
89
+ defaultInputModes?: string[];
90
+ defaultOutputModes?: string[];
91
+ description?: string;
92
+ documentationUrl?: string;
93
+ extensions?: Record<string, any>[];
94
+ hasPushNotifications?: boolean;
95
+ hasStateTransitionHistory?: boolean;
96
+ hasStreaming?: boolean;
97
+ identifier: string;
98
+ interfaces?: Record<string, any>[];
99
+ name?: string;
100
+ preferredTransport?: string;
101
+ providerId?: number;
102
+ securityRequirements?: Record<string, any>[];
103
+ securitySchemes?: Record<string, any>;
104
+ setAsCurrent?: boolean;
105
+ summary?: string;
106
+ supportsAuthenticatedExtendedCard?: boolean;
107
+ tokenUsage?: number;
108
+ url?: string;
109
+ }): Promise<AgentItemDetail> {
110
+ const { identifier, ...rest } = versionData;
111
+ const targetIdentifier = identifier;
112
+ if (!targetIdentifier) throw new Error('Identifier is required');
113
+
114
+ return this.request(MARKET_ENDPOINTS.createAgentVersion, {
115
+ body: JSON.stringify({
116
+ identifier: targetIdentifier,
117
+ ...rest,
118
+ }),
119
+ method: 'POST',
120
+ });
121
+ }
122
+ }
123
+
124
+ export const marketApiService = new MarketApiService();
@@ -6,6 +6,7 @@ import {
6
6
  CreateMessageParams,
7
7
  CreateMessageResult,
8
8
  MessageMetadata,
9
+ MessagePluginItem,
9
10
  ModelRankItem,
10
11
  UIChatMessage,
11
12
  UpdateMessageParams,
@@ -77,8 +78,9 @@ export class MessageService {
77
78
  };
78
79
 
79
80
  updateMessageError = async (id: string, value: ChatMessageError) => {
80
- const error = value.type ? value : { body: value, message: value.message, type: 'ApplicationRuntimeError' };
81
-
81
+ const error = value.type
82
+ ? value
83
+ : { body: value, message: value.message, type: 'ApplicationRuntimeError' };
82
84
 
83
85
  return lambdaClient.message.update.mutate({ id, value: { error } });
84
86
  };
@@ -153,6 +155,19 @@ export class MessageService {
153
155
  });
154
156
  };
155
157
 
158
+ updateMessagePlugin = async (
159
+ id: string,
160
+ value: Partial<Omit<MessagePluginItem, 'id'>>,
161
+ options?: { sessionId?: string | null; topicId?: string | null },
162
+ ): Promise<UpdateMessageResult> => {
163
+ return lambdaClient.message.updateMessagePlugin.mutate({
164
+ id,
165
+ sessionId: options?.sessionId,
166
+ topicId: options?.topicId,
167
+ value,
168
+ });
169
+ };
170
+
156
171
  updateMessageRAG = async (
157
172
  id: string,
158
173
  data: UpdateMessageRAGParams,
@@ -1,7 +1,8 @@
1
+ import { getMessageError } from '@lobechat/fetch-sse';
2
+
1
3
  import { createHeaderWithAuth } from '@/services/_auth';
2
4
  import { aiProviderSelectors, getAiInfraStoreState } from '@/store/aiInfra';
3
5
  import { ChatModelCard } from '@/types/llm';
4
- import { getMessageError } from '@/utils/fetch';
5
6
 
6
7
  import { API_ENDPOINTS } from './_url';
7
8
  import { initializeWithClientStore } from './chat/clientModelRuntime';
@@ -9,20 +9,22 @@ import {
9
9
  GeneralAgentCallToolsBatchInstructionPayload,
10
10
  GeneralAgentCallingToolInstructionPayload,
11
11
  GeneralAgentConfig,
12
+ InterventionChecker,
12
13
  } from '@lobechat/agent-runtime';
14
+ import type { ChatToolPayload, HumanInterventionConfig } from '@lobechat/types';
13
15
 
14
16
  /**
15
17
  * ChatAgent - The "Brain" of the chat agent
16
18
  *
17
19
  * This agent implements a simple but powerful decision loop:
18
20
  * 1. user_input → call_llm (with optional RAG/Search preprocessing)
19
- * 2. llm_result → check for tool_calls
20
- * - If has tool_calls → call_tools_batch (parallel execution)
21
- * - If no tool_callsfinish
21
+ * 2. llm_result → check for tool_calls and intervention requirements
22
+ * - Tools not requiring intervention → call_tools_batch (execute immediately)
23
+ * - Tools requiring interventionrequest_human_approve (wait for approval)
24
+ * - Mixed (both types) → [call_tools_batch, request_human_approve] (execute safe ones first, then request approval)
25
+ * - No tool_calls → finish
22
26
  * 3. tools_batch_result → call_llm (process tool results)
23
27
  *
24
- * Note: RAG and Search workflow preprocessing are handled externally
25
- * before creating the agent runtime, keeping the agent logic simple.
26
28
  */
27
29
  export class GeneralChatAgent implements Agent {
28
30
  private config: GeneralAgentConfig;
@@ -31,6 +33,63 @@ export class GeneralChatAgent implements Agent {
31
33
  this.config = config;
32
34
  }
33
35
 
36
+ /**
37
+ * Get intervention configuration for a specific tool call
38
+ */
39
+ private getToolInterventionConfig(
40
+ toolCalling: ChatToolPayload,
41
+ state: AgentState,
42
+ ): HumanInterventionConfig | undefined {
43
+ const { identifier, apiName } = toolCalling;
44
+ const manifest = state.toolManifestMap[identifier];
45
+
46
+ if (!manifest) return undefined;
47
+
48
+ // Find the specific API in the manifest
49
+ const api = manifest.api?.find((a: any) => a.name === apiName);
50
+
51
+ // API-level config takes precedence over tool-level config
52
+ return api?.humanIntervention ?? manifest.humanIntervention;
53
+ }
54
+
55
+ /**
56
+ * Check if tool calls need human intervention
57
+ * Returns [toolsNeedingIntervention, toolsToExecute]
58
+ */
59
+ private checkInterventionNeeded(
60
+ toolsCalling: ChatToolPayload[],
61
+ state: AgentState,
62
+ ): [ChatToolPayload[], ChatToolPayload[]] {
63
+ const toolsNeedingIntervention: ChatToolPayload[] = [];
64
+ const toolsToExecute: ChatToolPayload[] = [];
65
+
66
+ for (const toolCalling of toolsCalling) {
67
+ const config = this.getToolInterventionConfig(toolCalling, state);
68
+
69
+ // Parse arguments for intervention checking
70
+ let toolArgs: Record<string, any> = {};
71
+ try {
72
+ toolArgs = JSON.parse(toolCalling.arguments || '{}');
73
+ } catch {
74
+ // Invalid JSON, treat as empty args
75
+ }
76
+
77
+ const policy = InterventionChecker.shouldIntervene({
78
+ config,
79
+ toolArgs,
80
+ });
81
+
82
+ if (policy === 'never') {
83
+ toolsToExecute.push(toolCalling);
84
+ } else {
85
+ // 'require' or 'first' (when not confirmed) requires intervention
86
+ toolsNeedingIntervention.push(toolCalling);
87
+ }
88
+ }
89
+
90
+ return [toolsNeedingIntervention, toolsToExecute];
91
+ }
92
+
34
93
  async runner(
35
94
  context: AgentRuntimeContext,
36
95
  state: AgentState,
@@ -55,26 +114,47 @@ export class GeneralChatAgent implements Agent {
55
114
  context.payload as GeneralAgentCallLLMResultPayload;
56
115
 
57
116
  if (hasToolsCalling && toolsCalling && toolsCalling.length > 0) {
58
- // No intervention needed, proceed with tool execution
59
- // Use batch execution for multiple tool calls to improve performance
60
- if (toolsCalling.length > 1) {
61
- return {
62
- payload: {
63
- parentMessageId,
64
- toolsCalling,
65
- } as GeneralAgentCallToolsBatchInstructionPayload,
66
- type: 'call_tools_batch',
67
- };
68
- } else if (toolsCalling.length === 1) {
69
- // Single tool executes directly
70
- return {
71
- payload: {
72
- parentMessageId,
73
- toolCalling: toolsCalling[0],
74
- } as GeneralAgentCallingToolInstructionPayload,
75
- type: 'call_tool',
76
- };
117
+ // Check which tools need human intervention
118
+ const [toolsNeedingIntervention, toolsToExecute] = this.checkInterventionNeeded(
119
+ toolsCalling,
120
+ state,
121
+ );
122
+
123
+ const instructions: AgentInstruction[] = [];
124
+
125
+ // Execute tools that don't need intervention first
126
+ // These will run immediately before any approval requests
127
+ if (toolsToExecute.length > 0) {
128
+ if (toolsToExecute.length > 1) {
129
+ instructions.push({
130
+ payload: {
131
+ parentMessageId,
132
+ toolsCalling: toolsToExecute,
133
+ } as GeneralAgentCallToolsBatchInstructionPayload,
134
+ type: 'call_tools_batch',
135
+ });
136
+ } else {
137
+ instructions.push({
138
+ payload: {
139
+ parentMessageId,
140
+ toolCalling: toolsToExecute[0],
141
+ } as GeneralAgentCallingToolInstructionPayload,
142
+ type: 'call_tool',
143
+ });
144
+ }
145
+ }
146
+
147
+ // Request approval for tools that need intervention
148
+ // Runtime will execute this after safe tools and pause with status='waiting_for_human'
149
+ if (toolsNeedingIntervention.length > 0) {
150
+ instructions.push({
151
+ pendingToolsCalling: toolsNeedingIntervention,
152
+ reason: 'human_intervention_required',
153
+ type: 'request_human_approve',
154
+ });
77
155
  }
156
+
157
+ return instructions;
78
158
  }
79
159
 
80
160
  // No tool calls, conversation is complete
@@ -88,6 +168,24 @@ export class GeneralChatAgent implements Agent {
88
168
  case 'tool_result': {
89
169
  const { parentMessageId } = context.payload as GeneralAgentCallToolResultPayload;
90
170
 
171
+ // Check if there are still pending tool messages waiting for approval
172
+ const pendingToolMessages = state.messages.filter(
173
+ (m: any) => m.role === 'tool' && m.pluginIntervention?.status === 'pending',
174
+ );
175
+
176
+ // If there are pending tools, wait for human approval
177
+ if (pendingToolMessages.length > 0) {
178
+ const pendingTools = pendingToolMessages.map((m: any) => m.plugin).filter(Boolean);
179
+
180
+ return {
181
+ pendingToolsCalling: pendingTools,
182
+ reason: 'Some tools still pending approval',
183
+ skipCreateToolMessage: true,
184
+ type: 'request_human_approve',
185
+ };
186
+ }
187
+
188
+ // No pending tools, continue to call LLM with tool results
91
189
  return {
92
190
  payload: {
93
191
  messages: state.messages,
@@ -102,6 +200,25 @@ export class GeneralChatAgent implements Agent {
102
200
 
103
201
  case 'tools_batch_result': {
104
202
  const { parentMessageId } = context.payload as GeneralAgentCallToolResultPayload;
203
+
204
+ // Check if there are still pending tool messages waiting for approval
205
+ const pendingToolMessages = state.messages.filter(
206
+ (m: any) => m.role === 'tool' && m.pluginIntervention?.status === 'pending',
207
+ );
208
+
209
+ // If there are pending tools, wait for human approval
210
+ if (pendingToolMessages.length > 0) {
211
+ const pendingTools = pendingToolMessages.map((m: any) => m.plugin).filter(Boolean);
212
+
213
+ return {
214
+ pendingToolsCalling: pendingTools,
215
+ reason: 'Some tools still pending approval',
216
+ skipCreateToolMessage: true,
217
+ type: 'request_human_approve',
218
+ };
219
+ }
220
+
221
+ // No pending tools, continue to call LLM with tool results
105
222
  return {
106
223
  payload: {
107
224
  messages: state.messages,