@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,91 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
2
-
3
- import { imageToBase64, imageUrlToBase64 } from './imageToBase64';
4
-
5
- describe('imageToBase64', () => {
6
- let mockImage: HTMLImageElement;
7
- let mockCanvas: HTMLCanvasElement;
8
- let mockContext: CanvasRenderingContext2D;
9
-
10
- beforeEach(() => {
11
- mockImage = {
12
- width: 200,
13
- height: 100,
14
- } as HTMLImageElement;
15
-
16
- mockContext = {
17
- drawImage: vi.fn(),
18
- } as unknown as CanvasRenderingContext2D;
19
-
20
- mockCanvas = {
21
- width: 0,
22
- height: 0,
23
- getContext: vi.fn().mockReturnValue(mockContext),
24
- toDataURL: vi.fn().mockReturnValue('data:image/webp;base64,mockBase64Data'),
25
- } as unknown as HTMLCanvasElement;
26
-
27
- vi.spyOn(document, 'createElement').mockReturnValue(mockCanvas);
28
- });
29
-
30
- afterEach(() => {
31
- vi.restoreAllMocks();
32
- });
33
-
34
- it('should convert image to base64 with correct size and type', () => {
35
- const result = imageToBase64({ img: mockImage, size: 100, type: 'image/jpeg' });
36
-
37
- expect(document.createElement).toHaveBeenCalledWith('canvas');
38
- expect(mockCanvas.width).toBe(100);
39
- expect(mockCanvas.height).toBe(100);
40
- expect(mockCanvas.getContext).toHaveBeenCalledWith('2d');
41
- expect(mockContext.drawImage).toHaveBeenCalledWith(mockImage, 50, 0, 100, 100, 0, 0, 100, 100);
42
- expect(mockCanvas.toDataURL).toHaveBeenCalledWith('image/jpeg');
43
- expect(result).toBe('data:image/webp;base64,mockBase64Data');
44
- });
45
-
46
- it('should use default type when not specified', () => {
47
- imageToBase64({ img: mockImage, size: 100 });
48
- expect(mockCanvas.toDataURL).toHaveBeenCalledWith('image/webp');
49
- });
50
-
51
- it('should handle taller images correctly', () => {
52
- mockImage.width = 100;
53
- mockImage.height = 200;
54
- imageToBase64({ img: mockImage, size: 100 });
55
- expect(mockContext.drawImage).toHaveBeenCalledWith(mockImage, 0, 50, 100, 100, 0, 0, 100, 100);
56
- });
57
- });
58
-
59
- describe('imageUrlToBase64', () => {
60
- const mockFetch = vi.fn();
61
- const mockArrayBuffer = new ArrayBuffer(8);
62
-
63
- beforeEach(() => {
64
- global.fetch = mockFetch;
65
- global.btoa = vi.fn().mockReturnValue('mockBase64String');
66
- });
67
-
68
- afterEach(() => {
69
- vi.restoreAllMocks();
70
- });
71
-
72
- it('should convert image URL to base64 string', async () => {
73
- mockFetch.mockResolvedValue({
74
- arrayBuffer: () => Promise.resolve(mockArrayBuffer),
75
- blob: () => Promise.resolve(new Blob([mockArrayBuffer], { type: 'image/jpg' })),
76
- });
77
-
78
- const result = await imageUrlToBase64('https://example.com/image.jpg');
79
-
80
- expect(mockFetch).toHaveBeenCalledWith('https://example.com/image.jpg');
81
- expect(global.btoa).toHaveBeenCalled();
82
- expect(result).toEqual({ base64: 'mockBase64String', mimeType: 'image/jpg' });
83
- });
84
-
85
- it('should throw an error when fetch fails', async () => {
86
- const mockError = new Error('Fetch failed');
87
- mockFetch.mockRejectedValue(mockError);
88
-
89
- await expect(imageUrlToBase64('https://example.com/image.jpg')).rejects.toThrow('Fetch failed');
90
- });
91
- });
@@ -1,62 +0,0 @@
1
- export const imageToBase64 = ({
2
- size,
3
- img,
4
- type = 'image/webp',
5
- }: {
6
- img: HTMLImageElement;
7
- size: number;
8
- type?: string;
9
- }) => {
10
- const canvas = document.createElement('canvas');
11
- const ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
12
- let startX = 0;
13
- let startY = 0;
14
-
15
- if (img.width > img.height) {
16
- startX = (img.width - img.height) / 2;
17
- } else {
18
- startY = (img.height - img.width) / 2;
19
- }
20
-
21
- canvas.width = size;
22
- canvas.height = size;
23
-
24
- ctx.drawImage(
25
- img,
26
- startX,
27
- startY,
28
- Math.min(img.width, img.height),
29
- Math.min(img.width, img.height),
30
- 0,
31
- 0,
32
- size,
33
- size,
34
- );
35
-
36
- return canvas.toDataURL(type);
37
- };
38
-
39
- export const imageUrlToBase64 = async (
40
- imageUrl: string,
41
- ): Promise<{ base64: string; mimeType: string }> => {
42
- try {
43
- const res = await fetch(imageUrl);
44
- const blob = await res.blob();
45
- const arrayBuffer = await blob.arrayBuffer();
46
-
47
- const base64 =
48
- typeof btoa === 'function'
49
- ? btoa(
50
- new Uint8Array(arrayBuffer).reduce(
51
- (data, byte) => data + String.fromCharCode(byte),
52
- '',
53
- ),
54
- )
55
- : Buffer.from(arrayBuffer).toString('base64');
56
-
57
- return { base64, mimeType: blob.type };
58
- } catch (error) {
59
- console.error('Error converting image to base64:', error);
60
- throw error;
61
- }
62
- };
@@ -1,98 +0,0 @@
1
- 'use client';
2
-
3
- import { Alert, Button, Input, Modal, type ModalProps } from '@lobehub/ui';
4
- import { Divider } from 'antd';
5
- import { useTheme } from 'antd-style';
6
- import isEqual from 'fast-deep-equal';
7
- import { kebabCase } from 'lodash-es';
8
- import qs from 'query-string';
9
- import { memo, useState } from 'react';
10
- import { useTranslation } from 'react-i18next';
11
- import { Flexbox } from 'react-layout-kit';
12
-
13
- import { AGENTS_INDEX_GITHUB_ISSUE } from '@/const/url';
14
- import AgentInfo from '@/features/AgentInfo';
15
- import { useAgentStore } from '@/store/agent';
16
- import { agentSelectors } from '@/store/agent/selectors';
17
- import { useGlobalStore } from '@/store/global';
18
- import { globalGeneralSelectors } from '@/store/global/selectors';
19
- import { useSessionStore } from '@/store/session';
20
- import { sessionMetaSelectors } from '@/store/session/selectors';
21
-
22
- const SubmitAgentModal = memo<ModalProps>(({ open, onCancel }) => {
23
- const { t } = useTranslation('setting');
24
- const [identifier, setIdentifier] = useState('');
25
- const systemRole = useAgentStore(agentSelectors.currentAgentSystemRole);
26
- const theme = useTheme();
27
- const meta = useSessionStore(sessionMetaSelectors.currentAgentMeta, isEqual);
28
- const language = useGlobalStore(globalGeneralSelectors.currentLanguage);
29
-
30
- const isMetaPass = Boolean(
31
- meta && meta.title && meta.description && (meta.tags as string[])?.length > 0 && meta.avatar,
32
- );
33
-
34
- const handleSubmit = () => {
35
- const body = [
36
- '### systemRole',
37
- systemRole,
38
- '### identifier',
39
- kebabCase(identifier),
40
- '### avatar',
41
- meta.avatar,
42
- '### title',
43
- meta.title,
44
- '### description',
45
- meta.description,
46
- '### tags',
47
- (meta.tags as string[]).join(', '),
48
- '### locale',
49
- language,
50
- ].join('\n\n');
51
-
52
- const url = qs.stringifyUrl({
53
- query: { body, labels: '🤖 Agent PR', title: `[Agent] ${meta.title}` },
54
- url: AGENTS_INDEX_GITHUB_ISSUE,
55
- });
56
-
57
- window.open(url, '_blank');
58
- };
59
-
60
- return (
61
- <Modal
62
- allowFullscreen
63
- footer={
64
- <Button
65
- block
66
- disabled={!isMetaPass || !identifier}
67
- onClick={handleSubmit}
68
- size={'large'}
69
- type={'primary'}
70
- >
71
- {t('submitAgentModal.button')}
72
- </Button>
73
- }
74
- onCancel={onCancel}
75
- open={open}
76
- title={t('submitAgentModal.tooltips')}
77
- >
78
- <Flexbox gap={16}>
79
- {!isMetaPass && (
80
- <Alert message={t('submitAgentModal.metaMiss')} showIcon type={'warning'} />
81
- )}
82
- <AgentInfo meta={meta} systemRole={systemRole} />
83
- <Divider style={{ margin: '8px 0' }} />
84
- <strong>
85
- <span style={{ color: theme.colorError, marginRight: 4 }}>*</span>
86
- {t('submitAgentModal.identifier')}
87
- </strong>
88
- <Input
89
- onChange={(e) => setIdentifier(e.target.value)}
90
- placeholder={t('submitAgentModal.placeholder')}
91
- value={identifier}
92
- />
93
- </Flexbox>
94
- </Modal>
95
- );
96
- });
97
-
98
- export default SubmitAgentModal;
@@ -1,35 +0,0 @@
1
- import { ActionIcon, Button } from '@lobehub/ui';
2
- import { Share2 } from 'lucide-react';
3
- import { memo, useState } from 'react';
4
- import { useTranslation } from 'react-i18next';
5
-
6
- import { HEADER_ICON_SIZE } from '@/const/layoutTokens';
7
- import { useServerConfigStore } from '@/store/serverConfig';
8
-
9
- import SubmitAgentModal from './SubmitAgentModal';
10
-
11
- const SubmitAgentButton = memo<{ modal?: boolean }>(({ modal }) => {
12
- const { t } = useTranslation('setting');
13
- const mobile = useServerConfigStore((s) => s.isMobile);
14
- const [isModalOpen, setIsModalOpen] = useState(false);
15
-
16
- return (
17
- <>
18
- {modal ? (
19
- <Button block icon={Share2} onClick={() => setIsModalOpen(true)} variant={'filled'}>
20
- {t('submitAgentModal.tooltips')}
21
- </Button>
22
- ) : (
23
- <ActionIcon
24
- icon={Share2}
25
- onClick={() => setIsModalOpen(true)}
26
- size={HEADER_ICON_SIZE(mobile)}
27
- title={t('submitAgentModal.tooltips')}
28
- />
29
- )}
30
- <SubmitAgentModal onCancel={() => setIsModalOpen(false)} open={isModalOpen} />
31
- </>
32
- );
33
- });
34
-
35
- export default SubmitAgentButton;
@@ -1,47 +0,0 @@
1
- import { createStyles } from 'antd-style';
2
-
3
- export const useStyles = createStyles(({ css, token, prefixCls }) => ({
4
- author: css`
5
- font-size: 12px;
6
- `,
7
-
8
- avatar: css`
9
- flex: none;
10
- `,
11
- container: css`
12
- position: relative;
13
- padding-block: 16px 24px;
14
- padding-inline: 16px;
15
- border-block-end: 1px solid ${token.colorBorderSecondary};
16
- `,
17
- date: css`
18
- font-size: 12px;
19
- color: ${token.colorTextDescription};
20
- `,
21
- desc: css`
22
- color: ${token.colorTextDescription};
23
- text-align: center;
24
- `,
25
- loading: css`
26
- .${prefixCls}-skeleton-content {
27
- display: flex;
28
- flex-direction: column;
29
- }
30
- `,
31
- nav: css`
32
- padding-block-start: 4px;
33
-
34
- .${prefixCls}-tabs-tab {
35
- margin: 4px !important;
36
-
37
- + .${prefixCls}-tabs-tab {
38
- margin: 4px !important;
39
- }
40
- }
41
- `,
42
- title: css`
43
- font-size: 20px;
44
- font-weight: 600;
45
- text-align: center;
46
- `,
47
- }));