@lobehub/lobehub 2.0.0-next.46 → 2.0.0-next.48

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 (254) hide show
  1. package/.env.example +11 -0
  2. package/CHANGELOG.md +42 -0
  3. package/apps/desktop/src/main/controllers/AuthCtr.ts +27 -2
  4. package/apps/desktop/src/main/core/infrastructure/ProtocolManager.ts +9 -4
  5. package/changelog/v1.json +14 -0
  6. package/docs/development/database-schema.dbml +2 -0
  7. package/docs/self-hosting/environment-variables/basic.mdx +49 -3
  8. package/docs/self-hosting/environment-variables/basic.zh-CN.mdx +49 -4
  9. package/locales/ar/discover.json +45 -0
  10. package/locales/ar/marketAuth.json +42 -0
  11. package/locales/ar/setting.json +94 -1
  12. package/locales/bg-BG/discover.json +45 -0
  13. package/locales/bg-BG/marketAuth.json +42 -0
  14. package/locales/bg-BG/setting.json +94 -1
  15. package/locales/de-DE/discover.json +45 -0
  16. package/locales/de-DE/marketAuth.json +42 -0
  17. package/locales/de-DE/setting.json +94 -1
  18. package/locales/en-US/discover.json +45 -0
  19. package/locales/en-US/marketAuth.json +42 -0
  20. package/locales/en-US/setting.json +94 -1
  21. package/locales/es-ES/discover.json +45 -0
  22. package/locales/es-ES/marketAuth.json +42 -0
  23. package/locales/es-ES/setting.json +94 -1
  24. package/locales/fa-IR/discover.json +45 -0
  25. package/locales/fa-IR/marketAuth.json +42 -0
  26. package/locales/fa-IR/setting.json +94 -1
  27. package/locales/fr-FR/discover.json +45 -0
  28. package/locales/fr-FR/marketAuth.json +42 -0
  29. package/locales/fr-FR/setting.json +94 -1
  30. package/locales/it-IT/discover.json +45 -0
  31. package/locales/it-IT/marketAuth.json +42 -0
  32. package/locales/it-IT/setting.json +94 -1
  33. package/locales/ja-JP/discover.json +45 -0
  34. package/locales/ja-JP/marketAuth.json +42 -0
  35. package/locales/ja-JP/setting.json +94 -1
  36. package/locales/ko-KR/discover.json +45 -0
  37. package/locales/ko-KR/marketAuth.json +42 -0
  38. package/locales/ko-KR/setting.json +94 -1
  39. package/locales/nl-NL/discover.json +45 -0
  40. package/locales/nl-NL/marketAuth.json +42 -0
  41. package/locales/nl-NL/setting.json +94 -1
  42. package/locales/pl-PL/discover.json +45 -0
  43. package/locales/pl-PL/marketAuth.json +42 -0
  44. package/locales/pl-PL/setting.json +94 -1
  45. package/locales/pt-BR/discover.json +45 -0
  46. package/locales/pt-BR/marketAuth.json +42 -0
  47. package/locales/pt-BR/setting.json +94 -1
  48. package/locales/ru-RU/discover.json +45 -0
  49. package/locales/ru-RU/marketAuth.json +42 -0
  50. package/locales/ru-RU/setting.json +94 -1
  51. package/locales/tr-TR/discover.json +45 -0
  52. package/locales/tr-TR/marketAuth.json +42 -0
  53. package/locales/tr-TR/setting.json +94 -1
  54. package/locales/vi-VN/discover.json +45 -0
  55. package/locales/vi-VN/marketAuth.json +42 -0
  56. package/locales/vi-VN/setting.json +94 -1
  57. package/locales/zh-CN/discover.json +45 -0
  58. package/locales/zh-CN/marketAuth.json +42 -0
  59. package/locales/zh-CN/setting.json +94 -1
  60. package/locales/zh-TW/discover.json +45 -0
  61. package/locales/zh-TW/marketAuth.json +42 -0
  62. package/locales/zh-TW/setting.json +94 -1
  63. package/package.json +27 -26
  64. package/packages/const/src/url.ts +1 -0
  65. package/packages/database/migrations/0044_add_tool_intervention.sql +1 -0
  66. package/packages/database/migrations/0044_high_toxin.sql +1 -0
  67. package/packages/database/migrations/0045_add_tool_intervention.sql +1 -0
  68. package/packages/database/migrations/meta/0039_snapshot.json +1 -1
  69. package/packages/database/migrations/meta/0044_snapshot.json +7813 -0
  70. package/packages/database/migrations/meta/0045_snapshot.json +8431 -0
  71. package/packages/database/migrations/meta/_journal.json +14 -0
  72. package/packages/database/src/core/migrations.json +36 -7
  73. package/packages/database/src/models/file.ts +15 -1
  74. package/packages/database/src/models/message.ts +1 -1
  75. package/packages/database/src/models/session.ts +42 -1
  76. package/packages/database/src/repositories/aiInfra/index.test.ts +1 -1
  77. package/packages/database/src/repositories/dataExporter/index.test.ts +1 -1
  78. package/packages/database/src/repositories/tableViewer/index.test.ts +1 -1
  79. package/packages/database/src/schemas/agent.ts +1 -0
  80. package/packages/database/src/schemas/message.ts +5 -8
  81. package/packages/electron-client-ipc/src/events/index.ts +6 -1
  82. package/packages/electron-client-ipc/src/events/remoteServer.ts +8 -0
  83. package/packages/fetch-sse/package.json +29 -0
  84. package/packages/{utils/src/fetch → fetch-sse/src}/__tests__/fetchSSE.test.ts +4 -4
  85. package/packages/{utils/src/fetch → fetch-sse/src}/__tests__/parseError.test.ts +7 -4
  86. package/packages/{utils/src/fetch → fetch-sse/src}/fetchSSE.ts +2 -2
  87. package/packages/{utils/src/fetch → fetch-sse/src}/parseError.ts +3 -3
  88. package/packages/model-bank/src/aiModels/mistral.ts +2 -1
  89. package/packages/model-runtime/src/core/contextBuilders/anthropic.test.ts +17 -11
  90. package/packages/model-runtime/src/core/contextBuilders/anthropic.ts +1 -1
  91. package/packages/model-runtime/src/core/contextBuilders/google.test.ts +1 -1
  92. package/packages/model-runtime/src/core/contextBuilders/google.ts +3 -6
  93. package/packages/model-runtime/src/core/contextBuilders/openai.test.ts +4 -2
  94. package/packages/model-runtime/src/core/contextBuilders/openai.ts +1 -1
  95. package/packages/model-runtime/src/core/openaiCompatibleFactory/createImage.test.ts +1 -1
  96. package/packages/model-runtime/src/core/openaiCompatibleFactory/createImage.ts +1 -1
  97. package/packages/model-runtime/src/core/openaiCompatibleFactory/index.test.ts +3 -6
  98. package/packages/model-runtime/src/core/streams/openai/responsesStream.test.ts +1 -1
  99. package/packages/model-runtime/src/helpers/mergeChatMethodOptions.ts +2 -1
  100. package/packages/model-runtime/src/providers/aihubmix/index.test.ts +1 -1
  101. package/packages/model-runtime/src/providers/anthropic/generateObject.test.ts +1 -1
  102. package/packages/model-runtime/src/providers/anthropic/index.test.ts +1 -1
  103. package/packages/model-runtime/src/providers/baichuan/index.test.ts +1 -1
  104. package/packages/model-runtime/src/providers/bedrock/index.test.ts +1 -1
  105. package/packages/model-runtime/src/providers/bfl/createImage.test.ts +4 -4
  106. package/packages/model-runtime/src/providers/bfl/createImage.ts +1 -1
  107. package/packages/model-runtime/src/providers/cloudflare/index.test.ts +1 -1
  108. package/packages/model-runtime/src/providers/cohere/index.test.ts +1 -1
  109. package/packages/model-runtime/src/providers/google/createImage.test.ts +2 -2
  110. package/packages/model-runtime/src/providers/google/createImage.ts +1 -1
  111. package/packages/model-runtime/src/providers/google/generateObject.test.ts +1 -1
  112. package/packages/model-runtime/src/providers/google/index.test.ts +1 -4
  113. package/packages/model-runtime/src/providers/groq/index.test.ts +1 -1
  114. package/packages/model-runtime/src/providers/hunyuan/index.test.ts +1 -1
  115. package/packages/model-runtime/src/providers/minimax/createImage.test.ts +1 -1
  116. package/packages/model-runtime/src/providers/mistral/index.test.ts +1 -1
  117. package/packages/model-runtime/src/providers/moonshot/index.test.ts +1 -1
  118. package/packages/model-runtime/src/providers/novita/index.test.ts +1 -1
  119. package/packages/model-runtime/src/providers/ollama/index.test.ts +43 -32
  120. package/packages/model-runtime/src/providers/ollama/index.ts +31 -7
  121. package/packages/model-runtime/src/providers/openrouter/index.test.ts +1 -1
  122. package/packages/model-runtime/src/providers/perplexity/index.test.ts +1 -1
  123. package/packages/model-runtime/src/providers/ppio/index.test.ts +1 -1
  124. package/packages/model-runtime/src/providers/qwen/createImage.test.ts +1 -1
  125. package/packages/model-runtime/src/providers/search1api/index.test.ts +1 -1
  126. package/packages/model-runtime/src/providers/siliconcloud/createImage.ts +1 -1
  127. package/packages/model-runtime/src/providers/taichu/index.test.ts +1 -1
  128. package/packages/model-runtime/src/providers/wenxin/index.test.ts +1 -1
  129. package/packages/model-runtime/src/providers/zhipu/index.test.ts +1 -1
  130. package/packages/model-runtime/src/utils/errorResponse.test.ts +1 -1
  131. package/packages/ssrf-safe-fetch/index.browser.ts +14 -0
  132. package/packages/ssrf-safe-fetch/package.json +8 -1
  133. package/packages/types/src/aiProvider.ts +1 -1
  134. package/packages/types/src/discover/assistants.ts +16 -0
  135. package/packages/types/src/document/index.ts +38 -38
  136. package/packages/types/src/exportConfig.ts +15 -15
  137. package/packages/types/src/generation/index.ts +5 -5
  138. package/packages/types/src/index.ts +1 -0
  139. package/packages/types/src/message/common/tools.ts +10 -0
  140. package/packages/types/src/message/db/item.ts +15 -1
  141. package/packages/types/src/message/ui/params.ts +15 -1
  142. package/packages/types/src/meta.ts +4 -0
  143. package/packages/types/src/openai/chat.ts +15 -15
  144. package/packages/types/src/plugins/mcp.ts +29 -29
  145. package/packages/types/src/plugins/protocol.ts +43 -43
  146. package/packages/types/src/search.ts +4 -4
  147. package/packages/types/src/session/agentSession.ts +2 -0
  148. package/packages/types/src/tool/plugin.ts +3 -3
  149. package/packages/utils/src/imageToBase64.ts +17 -10
  150. package/packages/utils/src/index.ts +1 -1
  151. package/src/app/(backend)/f/[id]/route.ts +55 -0
  152. package/src/app/(backend)/market/agent/[[...segments]]/route.ts +153 -0
  153. package/src/app/(backend)/market/oidc/[[...segments]]/route.ts +207 -0
  154. package/src/app/[variants]/(main)/(mobile)/me/settings/features/useCategory.tsx +1 -0
  155. package/src/app/[variants]/(main)/_layout/Desktop/SideBar/PinList/index.tsx +4 -2
  156. package/src/app/[variants]/(main)/chat/settings/features/AgentInfoDescription/index.tsx +349 -0
  157. package/src/app/[variants]/(main)/chat/settings/features/HeaderContent.tsx +2 -2
  158. package/src/app/[variants]/(main)/chat/settings/features/PublishResultModal/index.tsx +64 -0
  159. package/src/app/[variants]/(main)/chat/settings/features/SmartAgentActionButton/MarketPublishButton.tsx +196 -0
  160. package/src/app/[variants]/(main)/chat/settings/features/SmartAgentActionButton/MarketPublishModal.tsx +358 -0
  161. package/src/app/[variants]/(main)/chat/settings/features/SmartAgentActionButton/index.tsx +75 -0
  162. package/src/app/[variants]/(main)/discover/(detail)/assistant/AssistantDetailPage.tsx +11 -2
  163. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/Client.tsx +12 -1
  164. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/Nav.tsx +19 -12
  165. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/Overview/TagList.tsx +14 -5
  166. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/Overview/index.tsx +2 -0
  167. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/Related/index.tsx +14 -5
  168. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/SystemRole/TagList.tsx +14 -5
  169. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/SystemRole/index.tsx +43 -29
  170. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/Versions/index.tsx +137 -0
  171. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/index.tsx +2 -0
  172. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Header.tsx +9 -10
  173. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Sidebar/ActionButton/AddAgent.tsx +105 -14
  174. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Sidebar/Related/index.tsx +20 -6
  175. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/StatusPage/index.tsx +113 -0
  176. package/src/app/[variants]/(main)/discover/(detail)/features/Breadcrumb.tsx +4 -3
  177. package/src/app/[variants]/(main)/discover/(list)/_layout/Desktop/Nav.tsx +3 -1
  178. package/src/app/[variants]/(main)/discover/(list)/assistant/AssistantPage.tsx +4 -1
  179. package/src/app/[variants]/(main)/discover/(list)/assistant/Client.tsx +6 -2
  180. package/src/app/[variants]/(main)/discover/(list)/assistant/features/Category/index.tsx +7 -3
  181. package/src/app/[variants]/(main)/discover/(list)/assistant/features/List/Item.tsx +13 -2
  182. package/src/app/[variants]/(main)/discover/(list)/assistant/features/MarketSourceSwitch.tsx +64 -0
  183. package/src/app/[variants]/(main)/discover/(list)/features/SortButton/index.tsx +26 -7
  184. package/src/app/[variants]/(main)/profile/_layout/Desktop/index.tsx +10 -10
  185. package/src/app/[variants]/(main)/settings/_layout/type.ts +1 -1
  186. package/src/app/[variants]/(main)/settings/agent/index.tsx +11 -10
  187. package/src/app/[variants]/(main)/settings/common/index.tsx +1 -1
  188. package/src/app/[variants]/(main)/settings/page.tsx +13 -10
  189. package/src/app/[variants]/(main)/settings/provider/ProviderMenu/Item.tsx +35 -36
  190. package/src/app/[variants]/(main)/settings/provider/ProviderMenu/SearchResult.tsx +5 -5
  191. package/src/app/[variants]/(main)/settings/provider/_layout/Desktop/Container.tsx +10 -4
  192. package/src/app/market-auth-callback/layout.tsx +15 -0
  193. package/src/app/market-auth-callback/page.tsx +196 -0
  194. package/src/envs/app.ts +4 -3
  195. package/src/features/AgentSetting/AgentPrompt/TokenTag.tsx +3 -2
  196. package/src/features/AgentSetting/AgentTTS/SelectWithTTSPreview.tsx +1 -1
  197. package/src/features/AgentSetting/store/action.ts +1 -1
  198. package/src/features/ChatInput/ActionBar/STT/browser.tsx +1 -1
  199. package/src/features/ChatInput/ActionBar/STT/openai.tsx +1 -1
  200. package/src/features/Conversation/components/Extras/TTS/InitPlayer.tsx +1 -1
  201. package/src/features/Conversation/components/VirtualizedList/index.tsx +2 -1
  202. package/src/features/PluginTag/PluginStatus.tsx +1 -1
  203. package/src/features/PluginsUI/Render/MCPType/index.tsx +26 -6
  204. package/src/hooks/useAgentOwnershipCheck.ts +143 -0
  205. package/src/instrumentation.node.ts +3 -2
  206. package/src/layout/AuthProvider/MarketAuth/MarketAuthProvider.tsx +364 -0
  207. package/src/layout/AuthProvider/MarketAuth/errors.ts +75 -0
  208. package/src/layout/AuthProvider/MarketAuth/index.ts +2 -0
  209. package/src/layout/AuthProvider/MarketAuth/oidc.ts +382 -0
  210. package/src/layout/AuthProvider/MarketAuth/types.ts +64 -0
  211. package/src/layout/AuthProvider/index.tsx +17 -4
  212. package/src/locales/default/discover.ts +46 -0
  213. package/src/locales/default/index.ts +2 -0
  214. package/src/locales/default/marketAuth.ts +42 -0
  215. package/src/locales/default/setting.ts +94 -1
  216. package/src/server/globalConfig/genServerAiProviderConfig.test.ts +5 -5
  217. package/src/server/globalConfig/genServerAiProviderConfig.ts +1 -1
  218. package/src/server/routers/desktop/mcp.ts +23 -8
  219. package/src/server/routers/lambda/market/index.ts +36 -14
  220. package/src/server/routers/lambda/message.ts +2 -2
  221. package/src/server/routers/tools/mcp.ts +24 -4
  222. package/src/server/services/discover/index.test.ts +153 -11
  223. package/src/server/services/discover/index.ts +339 -40
  224. package/src/server/services/file/impls/local.ts +4 -1
  225. package/src/server/services/file/index.ts +96 -1
  226. package/src/server/services/mcp/contentProcessor.ts +101 -0
  227. package/src/server/services/mcp/index.test.ts +52 -10
  228. package/src/server/services/mcp/index.ts +29 -26
  229. package/src/server/sitemap.ts +49 -35
  230. package/src/services/_url.ts +15 -1
  231. package/src/services/chat/chat.test.ts +5 -5
  232. package/src/services/chat/clientModelRuntime.test.ts +1 -1
  233. package/src/services/chat/index.ts +6 -6
  234. package/src/services/chat/types.ts +1 -2
  235. package/src/services/discover.ts +16 -5
  236. package/src/services/electron/remoteServer.ts +8 -1
  237. package/src/services/marketApi.ts +124 -0
  238. package/src/services/models.ts +2 -1
  239. package/src/services/session/index.ts +0 -14
  240. package/src/store/discover/slices/assistant/action.ts +20 -7
  241. package/{packages/utils/src → src/utils}/electron/desktopRemoteRPCFetch.ts +1 -1
  242. package/{packages/utils/src → src/utils/server}/parseModels.ts +1 -2
  243. package/src/utils/server/routeVariants.test.ts +340 -0
  244. package/vitest.config.mts +2 -0
  245. package/packages/model-runtime/src/utils/imageToBase64.test.ts +0 -91
  246. package/packages/model-runtime/src/utils/imageToBase64.ts +0 -62
  247. package/src/app/[variants]/(main)/chat/settings/features/SubmitAgentButton/SubmitAgentModal.tsx +0 -98
  248. package/src/app/[variants]/(main)/chat/settings/features/SubmitAgentButton/index.tsx +0 -35
  249. package/src/app/[variants]/(main)/chat/settings/features/SubmitAgentButton/style.ts +0 -47
  250. /package/packages/{utils/src/fetch → fetch-sse/src}/headers.ts +0 -0
  251. /package/packages/{utils/src/fetch → fetch-sse/src}/index.ts +0 -0
  252. /package/packages/{utils/src/fetch → fetch-sse/src}/request.ts +0 -0
  253. /package/{packages/utils/src → src/utils/server}/__snapshots__/parseModels.test.ts.snap +0 -0
  254. /package/{packages/utils/src → src/utils/server}/parseModels.test.ts +0 -0
@@ -0,0 +1,349 @@
1
+ 'use client';
2
+
3
+ import { ProDescriptions } from '@ant-design/pro-components';
4
+ import { AgentItemDetail } from '@lobehub/market-sdk';
5
+ import { Tag } from 'antd';
6
+ import Image from 'next/image';
7
+ import { memo } from 'react';
8
+ import { useTranslation } from 'react-i18next';
9
+ import { Flexbox } from 'react-layout-kit';
10
+
11
+ import Tokens from '@/features/AgentSetting/AgentPrompt/TokenTag';
12
+
13
+ interface AgentConfig {
14
+ params?: {
15
+ max_tokens?: number;
16
+ temperature?: number;
17
+ top_p?: number;
18
+ };
19
+ }
20
+
21
+ interface ChatConfig {
22
+ displayMode?: string;
23
+ enableHistoryCount?: boolean;
24
+ historyCount?: number;
25
+ searchMode?: string;
26
+ }
27
+
28
+ interface TTSConfig {
29
+ ttsService?: string;
30
+ voice?: any;
31
+ }
32
+
33
+ interface AgentInfoDescriptionProps {
34
+ agentConfig?: AgentConfig;
35
+ chatConfig?: ChatConfig;
36
+ files?: Array<{
37
+ enabled?: boolean;
38
+ id: string;
39
+ name: string;
40
+ type: string;
41
+ }>;
42
+ isRemote?: boolean;
43
+ knowledgeBases?: Array<{
44
+ enabled?: boolean;
45
+ id: string;
46
+ name: string;
47
+ }>;
48
+ meta?: Partial<AgentItemDetail> & {
49
+ description?: string;
50
+ name?: string;
51
+ title?: string;
52
+ };
53
+ model?: string;
54
+ plugins?: string[];
55
+ provider?: string;
56
+ systemRole?: string;
57
+ ttsConfig?: TTSConfig;
58
+ }
59
+
60
+ const AgentInfoDescription = memo<AgentInfoDescriptionProps>(
61
+ ({
62
+ agentConfig,
63
+ chatConfig,
64
+ files = [],
65
+ isRemote = false,
66
+ knowledgeBases = [],
67
+ meta,
68
+ model,
69
+ plugins = [],
70
+ provider,
71
+ systemRole,
72
+ ttsConfig,
73
+ }) => {
74
+ const { t } = useTranslation('setting');
75
+ // 转换远程数据格式
76
+ const getProcessedData = () => {
77
+ if (!isRemote || !meta) {
78
+ return {
79
+ agentConfig,
80
+ chatConfig,
81
+ files,
82
+ knowledgeBases,
83
+ meta,
84
+ model,
85
+ plugins,
86
+ provider,
87
+ systemRole,
88
+ ttsConfig,
89
+ };
90
+ }
91
+
92
+ // 远程数据格式转换
93
+ const remoteData = meta;
94
+ const config = remoteData.config || {};
95
+
96
+ return {
97
+ agentConfig: {
98
+ params: config.model?.parameters || {},
99
+ },
100
+ chatConfig: config.chatConfig || {},
101
+ files: config.files || [],
102
+ knowledgeBases: config.knowledgeBases || [],
103
+ meta: {
104
+ avatar: remoteData?.avatar,
105
+ description: remoteData?.description,
106
+ name: remoteData?.versionName,
107
+ tags: remoteData?.tags ? [remoteData.tags] : undefined,
108
+ title: remoteData?.name,
109
+ },
110
+ model: config.model?.model,
111
+ plugins: config.plugins?.map((p: any) => (typeof p === 'string' ? p : p.identifier)) || [],
112
+ provider: config.model?.provider,
113
+ systemRole: config.systemRole,
114
+ ttsConfig: config.tts || {},
115
+ };
116
+ };
117
+
118
+ const {
119
+ agentConfig: processedAgentConfig,
120
+ chatConfig: processedChatConfig,
121
+ meta: processedMeta,
122
+ model: processedModel,
123
+ plugins: processedPlugins,
124
+ provider: processedProvider,
125
+ systemRole: processedSystemRole,
126
+ } = getProcessedData();
127
+ const unsetText = t('agentInfoDescription.value.unset');
128
+ const unnamedText = t('agentInfoDescription.value.untitled');
129
+ const pluginEmptyText = t('agentInfoDescription.plugins.empty');
130
+ const renderAvatar = (avatar: string | undefined) => {
131
+ if (!avatar || avatar === '未设置') return unsetText;
132
+
133
+ // 如果是 http 或 https 链接,显示图片
134
+ if (avatar.startsWith('http://') || avatar.startsWith('https://')) {
135
+ return (
136
+ <Image alt="avatar" height={40} src={avatar} style={{ borderRadius: '50%' }} width={40} />
137
+ );
138
+ }
139
+
140
+ // 否则直接显示字符(emoji)
141
+ return (
142
+ <div
143
+ style={{
144
+ fontSize: '24px',
145
+ height: 40,
146
+ lineHeight: '40px',
147
+ textAlign: 'center',
148
+ width: 40,
149
+ }}
150
+ >
151
+ {avatar}
152
+ </div>
153
+ );
154
+ };
155
+
156
+ return (
157
+ <div style={{ height: '500px', overflow: 'auto' }}>
158
+ <Flexbox gap={16}>
159
+ {/* 基础信息 */}
160
+ <ProDescriptions
161
+ bordered
162
+ column={2}
163
+ columns={[
164
+ {
165
+ dataIndex: 'title',
166
+ key: 'title',
167
+ title: t('agentInfoDescription.basic.name'),
168
+ },
169
+ {
170
+ dataIndex: 'avatar',
171
+ key: 'avatar',
172
+ render: (_: any, record: any) => renderAvatar(record.avatar),
173
+ title: t('agentInfoDescription.basic.avatar'),
174
+ },
175
+ {
176
+ dataIndex: 'description',
177
+ key: 'description',
178
+ span: 2,
179
+ title: t('agentInfoDescription.basic.description'),
180
+ },
181
+ {
182
+ dataIndex: 'tags',
183
+ key: 'tags',
184
+ render: (_: any, record: any) => {
185
+ const tags = record.tags;
186
+ if (!tags || !tags.length) return unsetText;
187
+ return tags.map((tag: string, index: number) => (
188
+ <Tag color="blue" key={index}>
189
+ {tag}
190
+ </Tag>
191
+ ));
192
+ },
193
+ span: 2,
194
+ title: t('agentInfoDescription.basic.tags'),
195
+ },
196
+ ]}
197
+ dataSource={{
198
+ avatar: processedMeta?.avatar || unsetText,
199
+ description: processedMeta?.description || unsetText,
200
+ tags: processedMeta?.tags?.length ? processedMeta.tags : undefined,
201
+ title: processedMeta?.title || processedMeta?.name || unnamedText,
202
+ }}
203
+ size="small"
204
+ title={t('agentInfoDescription.basic.title')}
205
+ />
206
+
207
+ {/* 角色设定 */}
208
+ <ProDescriptions
209
+ bordered
210
+ column={1}
211
+ columns={[
212
+ {
213
+ dataIndex: 'systemRole',
214
+ key: 'systemRole',
215
+ render: (_: any, record: any) => {
216
+ const text = record.systemRole;
217
+ if (text === unsetText) return text;
218
+ return text;
219
+ },
220
+ title: t('agentInfoDescription.role.systemRole'),
221
+ },
222
+ ]}
223
+ dataSource={{
224
+ systemRole: processedSystemRole || unsetText,
225
+ }}
226
+ size="small"
227
+ title={
228
+ <Flexbox align={'center'} gap={8} horizontal>
229
+ <span>{t('agentInfoDescription.role.title')}</span>
230
+ <Tokens style={{ marginTop: 0 }} value={processedSystemRole || ''} />
231
+ </Flexbox>
232
+ }
233
+ />
234
+
235
+ {/* 模型设置 */}
236
+ <ProDescriptions
237
+ bordered
238
+ column={2}
239
+ columns={[
240
+ {
241
+ dataIndex: 'model',
242
+ key: 'model',
243
+ title: t('agentInfoDescription.model.model'),
244
+ },
245
+ {
246
+ dataIndex: 'provider',
247
+ key: 'provider',
248
+ title: t('agentInfoDescription.model.provider'),
249
+ },
250
+ {
251
+ dataIndex: 'temperature',
252
+ key: 'temperature',
253
+ title: t('agentInfoDescription.model.temperature'),
254
+ },
255
+ {
256
+ dataIndex: 'topP',
257
+ key: 'topP',
258
+ title: 'Top P',
259
+ },
260
+ {
261
+ dataIndex: 'maxTokens',
262
+ key: 'maxTokens',
263
+ span: 2,
264
+ title: t('agentInfoDescription.model.maxTokens'),
265
+ },
266
+ ]}
267
+ dataSource={{
268
+ maxTokens: processedAgentConfig?.params?.max_tokens ?? unsetText,
269
+ model: processedModel || unsetText,
270
+ provider: processedProvider || unsetText,
271
+ temperature: processedAgentConfig?.params?.temperature ?? unsetText,
272
+ topP: processedAgentConfig?.params?.top_p ?? unsetText,
273
+ }}
274
+ size="small"
275
+ title={t('agentInfoDescription.model.title')}
276
+ />
277
+
278
+ {/* 聊天偏好 */}
279
+ <ProDescriptions
280
+ bordered
281
+ column={2}
282
+ columns={[
283
+ {
284
+ dataIndex: 'historyCount',
285
+ key: 'historyCount',
286
+ title: t('agentInfoDescription.chat.historyCount'),
287
+ },
288
+ {
289
+ dataIndex: 'enableHistoryCount',
290
+ key: 'enableHistoryCount',
291
+ title: t('agentInfoDescription.chat.enableHistoryCount'),
292
+ },
293
+ {
294
+ dataIndex: 'displayMode',
295
+ key: 'displayMode',
296
+ title: t('agentInfoDescription.chat.displayMode'),
297
+ },
298
+ {
299
+ dataIndex: 'searchMode',
300
+ key: 'searchMode',
301
+ title: t('agentInfoDescription.chat.searchMode'),
302
+ },
303
+ ]}
304
+ dataSource={{
305
+ displayMode: processedChatConfig?.displayMode || unsetText,
306
+ enableHistoryCount: processedChatConfig?.enableHistoryCount
307
+ ? t('agentInfoDescription.chat.yes')
308
+ : t('agentInfoDescription.chat.no'),
309
+ historyCount: processedChatConfig?.historyCount ?? unsetText,
310
+ searchMode: processedChatConfig?.searchMode || unsetText,
311
+ }}
312
+ size="small"
313
+ title={t('agentInfoDescription.chat.title')}
314
+ />
315
+
316
+ <ProDescriptions
317
+ bordered
318
+ column={1}
319
+ columns={[
320
+ {
321
+ dataIndex: 'plugins',
322
+ key: 'plugins',
323
+ render: (_: any, record: any) => {
324
+ const pluginList = record.plugins;
325
+ if (!pluginList?.length) return pluginEmptyText;
326
+ return pluginList.map((plugin: string, index: number) => (
327
+ <Tag color="green" key={index}>
328
+ {plugin}
329
+ </Tag>
330
+ ));
331
+ },
332
+ title: t('agentInfoDescription.plugins.title'),
333
+ },
334
+ ]}
335
+ dataSource={{
336
+ plugins: processedPlugins?.length ? processedPlugins : [],
337
+ }}
338
+ size="small"
339
+ title={t('agentInfoDescription.plugins.count', {
340
+ count: processedPlugins?.length || 0,
341
+ })}
342
+ />
343
+ </Flexbox>
344
+ </div>
345
+ );
346
+ },
347
+ );
348
+
349
+ export default AgentInfoDescription;
@@ -1,9 +1,9 @@
1
1
  import { memo } from 'react';
2
2
 
3
- import SubmitAgentButton from './SubmitAgentButton';
3
+ import SmartAgentActionButton from './SmartAgentActionButton';
4
4
 
5
5
  export const HeaderContent = memo<{ mobile?: boolean; modal?: boolean }>(({ modal }) => {
6
- return <SubmitAgentButton modal={modal} />;
6
+ return <SmartAgentActionButton modal={modal} />;
7
7
  });
8
8
 
9
9
  export default HeaderContent;
@@ -0,0 +1,64 @@
1
+ 'use client';
2
+
3
+ import { CheckCircleOutlined } from '@ant-design/icons';
4
+ import { Button, Modal, Space } from 'antd';
5
+ import { useRouter } from 'next/navigation';
6
+ import { memo } from 'react';
7
+ import { useTranslation } from 'react-i18next';
8
+
9
+ interface PublishResultModalProps {
10
+ identifier?: string;
11
+ onCancel: () => void;
12
+ open: boolean;
13
+ }
14
+
15
+ const PublishResultModal = memo<PublishResultModalProps>(({ identifier, onCancel, open }) => {
16
+ const router = useRouter();
17
+ const { t } = useTranslation('setting');
18
+ const { t: tCommon } = useTranslation('common');
19
+
20
+ const handleGoToMarket = () => {
21
+ if (identifier) {
22
+ router.push(`/discover/assistant/${identifier}`);
23
+ }
24
+ onCancel();
25
+ };
26
+
27
+ const successContent = (
28
+ <div style={{ padding: '20px 0', textAlign: 'center' }}>
29
+ <CheckCircleOutlined
30
+ style={{
31
+ color: '#52c41a',
32
+ display: 'block',
33
+ fontSize: '48px',
34
+ marginBottom: '16px',
35
+ }}
36
+ />
37
+ <div style={{ fontSize: '16px', marginBottom: '24px' }}>
38
+ {t('marketPublish.resultModal.message')}
39
+ </div>
40
+ <Space>
41
+ <Button onClick={onCancel}>{tCommon('cancel')}</Button>
42
+ <Button onClick={handleGoToMarket} type="primary">
43
+ {t('marketPublish.resultModal.view')}
44
+ </Button>
45
+ </Space>
46
+ </div>
47
+ );
48
+
49
+ return (
50
+ <Modal
51
+ centered
52
+ closable={false}
53
+ footer={null}
54
+ onCancel={onCancel}
55
+ open={open}
56
+ title={null}
57
+ width={480}
58
+ >
59
+ {successContent}
60
+ </Modal>
61
+ );
62
+ });
63
+
64
+ export default PublishResultModal;
@@ -0,0 +1,196 @@
1
+ import { ActionIcon, Button } from '@lobehub/ui';
2
+ import { message } from 'antd';
3
+ import { LogIn, Share2, Upload } from 'lucide-react';
4
+ import { memo, useCallback, useMemo, useState } from 'react';
5
+ import { useTranslation } from 'react-i18next';
6
+
7
+ import { HEADER_ICON_SIZE } from '@/const/layoutTokens';
8
+ import { checkOwnership } from '@/hooks/useAgentOwnershipCheck';
9
+ import { useMarketAuth } from '@/layout/AuthProvider/MarketAuth';
10
+ import { resolveMarketAuthError } from '@/layout/AuthProvider/MarketAuth/errors';
11
+ import { useServerConfigStore } from '@/store/serverConfig';
12
+
13
+ import MarketPublishModal, { type MarketPublishAction } from './MarketPublishModal';
14
+
15
+ interface MarketPublishButtonProps {
16
+ action: MarketPublishAction;
17
+ marketIdentifier?: string;
18
+ modal?: boolean;
19
+ }
20
+
21
+ const MarketPublishButton = memo<MarketPublishButtonProps>(
22
+ ({ action, marketIdentifier, modal }) => {
23
+ const { t: tSetting } = useTranslation('setting');
24
+ const { t: tMarketAuth } = useTranslation('marketAuth');
25
+ const mobile = useServerConfigStore((s) => s.isMobile);
26
+ const [openState, setOpenState] = useState<{ submit: boolean; upload: boolean }>({
27
+ submit: false,
28
+ upload: false,
29
+ });
30
+ const { isAuthenticated, isLoading, session, signIn } = useMarketAuth();
31
+
32
+ const buttonCopy = useMemo(() => {
33
+ if (action === 'upload') {
34
+ return {
35
+ authenticated: {
36
+ icon: Upload,
37
+ text: tSetting('marketPublish.upload.button'),
38
+ title: tSetting('marketPublish.upload.tooltip'),
39
+ },
40
+ successMessage: tMarketAuth('messages.success.upload'),
41
+ unauthenticated: {
42
+ icon: LogIn,
43
+ text: tSetting('marketPublish.upload.button'),
44
+ title: tSetting('marketPublish.upload.tooltip'),
45
+ },
46
+ } as const;
47
+ }
48
+
49
+ const submitText = tSetting('submitAgentModal.tooltips');
50
+
51
+ return {
52
+ authenticated: {
53
+ icon: Share2,
54
+ text: submitText,
55
+ title: submitText,
56
+ },
57
+ successMessage: tMarketAuth('messages.success.submit'),
58
+ unauthenticated: {
59
+ icon: LogIn,
60
+ text: tSetting('marketPublish.submit.button'),
61
+ title: tSetting('marketPublish.submit.tooltip'),
62
+ },
63
+ } as const;
64
+ }, [action, tMarketAuth, tSetting]);
65
+
66
+ const openModal = useCallback((target: MarketPublishAction) => {
67
+ setOpenState((prev) => ({ ...prev, [target]: true }));
68
+ }, []);
69
+
70
+ const closeModal = useCallback((target: MarketPublishAction) => {
71
+ setOpenState((prev) => ({ ...prev, [target]: false }));
72
+ }, []);
73
+
74
+ const handleButtonClick = useCallback(async () => {
75
+ console.log(
76
+ `[MarketPublishButton][${action}] Button clicked, isAuthenticated:`,
77
+ isAuthenticated,
78
+ );
79
+
80
+ if (isAuthenticated) {
81
+ console.log(`[MarketPublishButton][${action}] User is authenticated, opening modal`);
82
+ openModal(action);
83
+ return;
84
+ }
85
+
86
+ console.log(
87
+ `[MarketPublishButton][${action}] User not authenticated, starting authorization`,
88
+ );
89
+ try {
90
+ message.loading({ content: tMarketAuth('messages.loading'), key: 'market-auth' });
91
+ const accountId = await signIn();
92
+ message.success({ content: buttonCopy.successMessage, key: 'market-auth' });
93
+
94
+ let targetAction: MarketPublishAction = action;
95
+
96
+ if (marketIdentifier && accountId !== null) {
97
+ let accessToken = session?.accessToken;
98
+
99
+ if (!accessToken && typeof window !== 'undefined') {
100
+ const storedSession = sessionStorage.getItem('market_auth_session');
101
+ if (storedSession) {
102
+ try {
103
+ const parsed = JSON.parse(storedSession) as { accessToken?: string };
104
+ accessToken = parsed.accessToken;
105
+ } catch (parseError) {
106
+ console.error('[MarketPublishButton] Failed to parse stored session:', parseError);
107
+ }
108
+ }
109
+ }
110
+
111
+ if (accessToken) {
112
+ try {
113
+ const isOwner = await checkOwnership({
114
+ accessToken,
115
+ accountId,
116
+ marketIdentifier,
117
+ skipCache: true,
118
+ });
119
+
120
+ targetAction = isOwner ? 'upload' : 'submit';
121
+ } catch (ownershipError) {
122
+ console.error('[MarketPublishButton] Failed to confirm ownership:', ownershipError);
123
+ }
124
+ }
125
+ }
126
+
127
+ openModal(targetAction);
128
+ } catch (error) {
129
+ console.error(`[MarketPublishButton][${action}] Authorization failed:`, error);
130
+ const normalizedError = resolveMarketAuthError(error);
131
+ message.error({
132
+ content: tMarketAuth(`errors.${normalizedError.code}`),
133
+ key: 'market-auth',
134
+ });
135
+ }
136
+ }, [
137
+ action,
138
+ buttonCopy.successMessage,
139
+ isAuthenticated,
140
+ marketIdentifier,
141
+ openModal,
142
+ session?.accessToken,
143
+ signIn,
144
+ tMarketAuth,
145
+ ]);
146
+
147
+ const buttonProps = isAuthenticated ? buttonCopy.authenticated : buttonCopy.unauthenticated;
148
+
149
+ return (
150
+ <>
151
+ {modal ? (
152
+ <Button
153
+ block
154
+ disabled={isLoading}
155
+ icon={buttonProps.icon}
156
+ loading={isLoading}
157
+ onClick={handleButtonClick}
158
+ variant={'filled'}
159
+ >
160
+ {buttonProps.text}
161
+ </Button>
162
+ ) : (
163
+ <ActionIcon
164
+ icon={buttonProps.icon}
165
+ loading={isLoading}
166
+ onClick={handleButtonClick}
167
+ size={HEADER_ICON_SIZE(mobile)}
168
+ title={buttonProps.title}
169
+ />
170
+ )}
171
+
172
+ {isAuthenticated && (
173
+ <>
174
+ <MarketPublishModal
175
+ action="submit"
176
+ onCancel={() => closeModal('submit')}
177
+ onSuccess={() => closeModal('submit')}
178
+ open={openState.submit}
179
+ />
180
+
181
+ <MarketPublishModal
182
+ action="upload"
183
+ onCancel={() => closeModal('upload')}
184
+ onSuccess={() => closeModal('upload')}
185
+ open={openState.upload}
186
+ />
187
+ </>
188
+ )}
189
+ </>
190
+ );
191
+ },
192
+ );
193
+
194
+ MarketPublishButton.displayName = 'MarketPublishButton';
195
+
196
+ export default MarketPublishButton;