@lobehub/lobehub 2.0.0-next.47 → 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 (228) hide show
  1. package/.env.example +11 -0
  2. package/CHANGELOG.md +17 -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 +5 -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/message.ts +1 -1
  74. package/packages/database/src/models/session.ts +42 -1
  75. package/packages/database/src/schemas/agent.ts +1 -0
  76. package/packages/database/src/schemas/message.ts +5 -8
  77. package/packages/electron-client-ipc/src/events/index.ts +6 -1
  78. package/packages/electron-client-ipc/src/events/remoteServer.ts +8 -0
  79. package/packages/fetch-sse/package.json +29 -0
  80. package/packages/{utils/src/fetch → fetch-sse/src}/__tests__/fetchSSE.test.ts +4 -4
  81. package/packages/{utils/src/fetch → fetch-sse/src}/__tests__/parseError.test.ts +7 -4
  82. package/packages/{utils/src/fetch → fetch-sse/src}/fetchSSE.ts +2 -2
  83. package/packages/{utils/src/fetch → fetch-sse/src}/parseError.ts +3 -3
  84. package/packages/model-bank/src/aiModels/mistral.ts +2 -1
  85. package/packages/model-runtime/src/core/contextBuilders/anthropic.test.ts +17 -11
  86. package/packages/model-runtime/src/core/contextBuilders/anthropic.ts +1 -1
  87. package/packages/model-runtime/src/core/contextBuilders/google.test.ts +1 -1
  88. package/packages/model-runtime/src/core/contextBuilders/google.ts +3 -6
  89. package/packages/model-runtime/src/core/contextBuilders/openai.test.ts +4 -2
  90. package/packages/model-runtime/src/core/contextBuilders/openai.ts +1 -1
  91. package/packages/model-runtime/src/core/openaiCompatibleFactory/createImage.test.ts +1 -1
  92. package/packages/model-runtime/src/core/openaiCompatibleFactory/createImage.ts +1 -1
  93. package/packages/model-runtime/src/core/openaiCompatibleFactory/index.test.ts +3 -6
  94. package/packages/model-runtime/src/core/streams/openai/responsesStream.test.ts +1 -1
  95. package/packages/model-runtime/src/helpers/mergeChatMethodOptions.ts +2 -1
  96. package/packages/model-runtime/src/providers/aihubmix/index.test.ts +1 -1
  97. package/packages/model-runtime/src/providers/anthropic/generateObject.test.ts +1 -1
  98. package/packages/model-runtime/src/providers/anthropic/index.test.ts +1 -1
  99. package/packages/model-runtime/src/providers/baichuan/index.test.ts +1 -1
  100. package/packages/model-runtime/src/providers/bedrock/index.test.ts +1 -1
  101. package/packages/model-runtime/src/providers/bfl/createImage.test.ts +4 -4
  102. package/packages/model-runtime/src/providers/bfl/createImage.ts +1 -1
  103. package/packages/model-runtime/src/providers/cloudflare/index.test.ts +1 -1
  104. package/packages/model-runtime/src/providers/cohere/index.test.ts +1 -1
  105. package/packages/model-runtime/src/providers/google/createImage.test.ts +2 -2
  106. package/packages/model-runtime/src/providers/google/createImage.ts +1 -1
  107. package/packages/model-runtime/src/providers/google/generateObject.test.ts +1 -1
  108. package/packages/model-runtime/src/providers/google/index.test.ts +1 -4
  109. package/packages/model-runtime/src/providers/groq/index.test.ts +1 -1
  110. package/packages/model-runtime/src/providers/hunyuan/index.test.ts +1 -1
  111. package/packages/model-runtime/src/providers/minimax/createImage.test.ts +1 -1
  112. package/packages/model-runtime/src/providers/mistral/index.test.ts +1 -1
  113. package/packages/model-runtime/src/providers/moonshot/index.test.ts +1 -1
  114. package/packages/model-runtime/src/providers/novita/index.test.ts +1 -1
  115. package/packages/model-runtime/src/providers/ollama/index.test.ts +43 -32
  116. package/packages/model-runtime/src/providers/ollama/index.ts +31 -7
  117. package/packages/model-runtime/src/providers/openrouter/index.test.ts +1 -1
  118. package/packages/model-runtime/src/providers/perplexity/index.test.ts +1 -1
  119. package/packages/model-runtime/src/providers/ppio/index.test.ts +1 -1
  120. package/packages/model-runtime/src/providers/qwen/createImage.test.ts +1 -1
  121. package/packages/model-runtime/src/providers/search1api/index.test.ts +1 -1
  122. package/packages/model-runtime/src/providers/siliconcloud/createImage.ts +1 -1
  123. package/packages/model-runtime/src/providers/taichu/index.test.ts +1 -1
  124. package/packages/model-runtime/src/providers/wenxin/index.test.ts +1 -1
  125. package/packages/model-runtime/src/providers/zhipu/index.test.ts +1 -1
  126. package/packages/model-runtime/src/utils/errorResponse.test.ts +1 -1
  127. package/packages/ssrf-safe-fetch/index.browser.ts +14 -0
  128. package/packages/ssrf-safe-fetch/package.json +8 -1
  129. package/packages/types/src/discover/assistants.ts +16 -0
  130. package/packages/types/src/index.ts +1 -0
  131. package/packages/types/src/message/common/tools.ts +10 -0
  132. package/packages/types/src/message/db/item.ts +15 -1
  133. package/packages/types/src/message/ui/params.ts +15 -1
  134. package/packages/types/src/meta.ts +4 -0
  135. package/packages/types/src/session/agentSession.ts +2 -0
  136. package/packages/utils/src/imageToBase64.ts +17 -10
  137. package/packages/utils/src/index.ts +1 -1
  138. package/src/app/(backend)/market/agent/[[...segments]]/route.ts +153 -0
  139. package/src/app/(backend)/market/oidc/[[...segments]]/route.ts +207 -0
  140. package/src/app/[variants]/(main)/(mobile)/me/settings/features/useCategory.tsx +1 -0
  141. package/src/app/[variants]/(main)/_layout/Desktop/SideBar/PinList/index.tsx +4 -2
  142. package/src/app/[variants]/(main)/chat/settings/features/AgentInfoDescription/index.tsx +349 -0
  143. package/src/app/[variants]/(main)/chat/settings/features/HeaderContent.tsx +2 -2
  144. package/src/app/[variants]/(main)/chat/settings/features/PublishResultModal/index.tsx +64 -0
  145. package/src/app/[variants]/(main)/chat/settings/features/SmartAgentActionButton/MarketPublishButton.tsx +196 -0
  146. package/src/app/[variants]/(main)/chat/settings/features/SmartAgentActionButton/MarketPublishModal.tsx +358 -0
  147. package/src/app/[variants]/(main)/chat/settings/features/SmartAgentActionButton/index.tsx +75 -0
  148. package/src/app/[variants]/(main)/discover/(detail)/assistant/AssistantDetailPage.tsx +11 -2
  149. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/Client.tsx +12 -1
  150. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/Nav.tsx +19 -12
  151. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/Overview/TagList.tsx +14 -5
  152. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/Overview/index.tsx +2 -0
  153. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/Related/index.tsx +14 -5
  154. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/SystemRole/TagList.tsx +14 -5
  155. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/SystemRole/index.tsx +43 -29
  156. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/Versions/index.tsx +137 -0
  157. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/index.tsx +2 -0
  158. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Header.tsx +9 -10
  159. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Sidebar/ActionButton/AddAgent.tsx +105 -14
  160. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Sidebar/Related/index.tsx +20 -6
  161. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/StatusPage/index.tsx +113 -0
  162. package/src/app/[variants]/(main)/discover/(detail)/features/Breadcrumb.tsx +4 -3
  163. package/src/app/[variants]/(main)/discover/(list)/_layout/Desktop/Nav.tsx +3 -1
  164. package/src/app/[variants]/(main)/discover/(list)/assistant/AssistantPage.tsx +4 -1
  165. package/src/app/[variants]/(main)/discover/(list)/assistant/Client.tsx +6 -2
  166. package/src/app/[variants]/(main)/discover/(list)/assistant/features/Category/index.tsx +7 -3
  167. package/src/app/[variants]/(main)/discover/(list)/assistant/features/List/Item.tsx +13 -2
  168. package/src/app/[variants]/(main)/discover/(list)/assistant/features/MarketSourceSwitch.tsx +64 -0
  169. package/src/app/[variants]/(main)/discover/(list)/features/SortButton/index.tsx +26 -7
  170. package/src/app/[variants]/(main)/profile/_layout/Desktop/index.tsx +10 -10
  171. package/src/app/[variants]/(main)/settings/_layout/type.ts +1 -1
  172. package/src/app/[variants]/(main)/settings/agent/index.tsx +11 -10
  173. package/src/app/[variants]/(main)/settings/common/index.tsx +1 -1
  174. package/src/app/[variants]/(main)/settings/page.tsx +13 -10
  175. package/src/app/[variants]/(main)/settings/provider/ProviderMenu/Item.tsx +35 -36
  176. package/src/app/[variants]/(main)/settings/provider/ProviderMenu/SearchResult.tsx +5 -5
  177. package/src/app/[variants]/(main)/settings/provider/_layout/Desktop/Container.tsx +10 -4
  178. package/src/app/market-auth-callback/layout.tsx +15 -0
  179. package/src/app/market-auth-callback/page.tsx +196 -0
  180. package/src/features/AgentSetting/AgentPrompt/TokenTag.tsx +3 -2
  181. package/src/features/AgentSetting/AgentTTS/SelectWithTTSPreview.tsx +1 -1
  182. package/src/features/AgentSetting/store/action.ts +1 -1
  183. package/src/features/ChatInput/ActionBar/STT/browser.tsx +1 -1
  184. package/src/features/ChatInput/ActionBar/STT/openai.tsx +1 -1
  185. package/src/features/Conversation/components/Extras/TTS/InitPlayer.tsx +1 -1
  186. package/src/features/PluginTag/PluginStatus.tsx +1 -1
  187. package/src/hooks/useAgentOwnershipCheck.ts +143 -0
  188. package/src/instrumentation.node.ts +3 -2
  189. package/src/layout/AuthProvider/MarketAuth/MarketAuthProvider.tsx +364 -0
  190. package/src/layout/AuthProvider/MarketAuth/errors.ts +75 -0
  191. package/src/layout/AuthProvider/MarketAuth/index.ts +2 -0
  192. package/src/layout/AuthProvider/MarketAuth/oidc.ts +382 -0
  193. package/src/layout/AuthProvider/MarketAuth/types.ts +64 -0
  194. package/src/layout/AuthProvider/index.tsx +17 -4
  195. package/src/locales/default/discover.ts +46 -0
  196. package/src/locales/default/index.ts +2 -0
  197. package/src/locales/default/marketAuth.ts +42 -0
  198. package/src/locales/default/setting.ts +94 -1
  199. package/src/server/globalConfig/genServerAiProviderConfig.test.ts +5 -5
  200. package/src/server/globalConfig/genServerAiProviderConfig.ts +1 -1
  201. package/src/server/routers/lambda/market/index.ts +36 -14
  202. package/src/server/routers/lambda/message.ts +2 -2
  203. package/src/server/services/discover/index.test.ts +153 -11
  204. package/src/server/services/discover/index.ts +339 -40
  205. package/src/server/sitemap.ts +49 -35
  206. package/src/services/_url.ts +15 -1
  207. package/src/services/chat/chat.test.ts +5 -5
  208. package/src/services/chat/clientModelRuntime.test.ts +1 -1
  209. package/src/services/chat/index.ts +6 -6
  210. package/src/services/chat/types.ts +1 -2
  211. package/src/services/discover.ts +16 -5
  212. package/src/services/electron/remoteServer.ts +8 -1
  213. package/src/services/marketApi.ts +124 -0
  214. package/src/services/models.ts +2 -1
  215. package/src/store/discover/slices/assistant/action.ts +20 -7
  216. package/{packages/utils/src → src/utils}/electron/desktopRemoteRPCFetch.ts +1 -1
  217. package/{packages/utils/src → src/utils/server}/parseModels.ts +1 -2
  218. package/vitest.config.mts +2 -0
  219. package/packages/model-runtime/src/utils/imageToBase64.test.ts +0 -91
  220. package/packages/model-runtime/src/utils/imageToBase64.ts +0 -62
  221. package/src/app/[variants]/(main)/chat/settings/features/SubmitAgentButton/SubmitAgentModal.tsx +0 -98
  222. package/src/app/[variants]/(main)/chat/settings/features/SubmitAgentButton/index.tsx +0 -35
  223. package/src/app/[variants]/(main)/chat/settings/features/SubmitAgentButton/style.ts +0 -47
  224. /package/packages/{utils/src/fetch → fetch-sse/src}/headers.ts +0 -0
  225. /package/packages/{utils/src/fetch → fetch-sse/src}/index.ts +0 -0
  226. /package/packages/{utils/src/fetch → fetch-sse/src}/request.ts +0 -0
  227. /package/{packages/utils/src → src/utils/server}/__snapshots__/parseModels.test.ts.snap +0 -0
  228. /package/{packages/utils/src → src/utils/server}/parseModels.test.ts +0 -0
@@ -2,6 +2,45 @@ export default {
2
2
  about: {
3
3
  title: '关于',
4
4
  },
5
+ agentInfoDescription: {
6
+ basic: {
7
+ avatar: '头像',
8
+ description: '描述',
9
+ name: '名称',
10
+ tags: '标签',
11
+ title: '助手信息',
12
+ },
13
+ chat: {
14
+ displayMode: '展示模式',
15
+ enableHistoryCount: '启用历史消息计数',
16
+ historyCount: '历史消息数量',
17
+ no: '否',
18
+ searchMode: '搜索模式',
19
+ title: '聊天偏好',
20
+ yes: '是',
21
+ },
22
+ model: {
23
+ maxTokens: '最大 Token 数',
24
+ model: '模型',
25
+ provider: '服务商',
26
+ temperature: '温度',
27
+ title: '模型设置',
28
+ topP: 'Top P 值',
29
+ },
30
+ plugins: {
31
+ count: '插件设置({{count}})',
32
+ empty: '尚未安装插件',
33
+ title: '已安装插件',
34
+ },
35
+ role: {
36
+ systemRole: '系统提示词',
37
+ title: '角色设置',
38
+ },
39
+ value: {
40
+ unset: '未设置',
41
+ untitled: '未命名助手',
42
+ },
43
+ },
5
44
  agentTab: {
6
45
  chat: '聊天偏好',
7
46
  meta: '助手信息',
@@ -18,6 +57,8 @@ export default {
18
57
  },
19
58
  title: '数据统计',
20
59
  },
60
+ checking: '检查中...',
61
+ checkingPermissions: '检查权限中...',
21
62
  danger: {
22
63
  clear: {
23
64
  action: '立即清除',
@@ -148,6 +189,58 @@ export default {
148
189
  },
149
190
  waitingForMore: '更多模型正在 <1>计划接入</1> 中,敬请期待',
150
191
  },
192
+ marketPublish: {
193
+ modal: {
194
+ changelog: {
195
+ extra: '描述此版本的主要变更和改进',
196
+ label: '变更日志',
197
+ maxLengthError: '变更日志不能超过500个字符',
198
+ placeholder: '请输入变更日志',
199
+ required: '请输入变更日志',
200
+ },
201
+ comparison: {
202
+ local: '本地当前版本',
203
+ remote: '当前发布版本',
204
+ },
205
+ identifier: {
206
+ extra: '标识符将作为助手的唯一标识,建议使用小写字母、数字和连字符',
207
+ label: '助手标识符',
208
+ lengthError: '标识符长度应在3-50个字符之间',
209
+ patternError: '标识符只能包含小写字母、数字和连字符',
210
+ placeholder: '请输入助手的唯一标识符,如: web-development',
211
+ required: '请输入助手标识符',
212
+ },
213
+ loading: {
214
+ fetchingRemote: '正在加载远程数据...',
215
+ submit: '正在发布助手...',
216
+ upload: '正在发布新版本...',
217
+ },
218
+ messages: {
219
+ createVersionFailed: '版本创建失败: {{message}}',
220
+ fetchRemoteFailed: '获取远程助手数据失败',
221
+ missingIdentifier: '当前助手还没有市场标识符',
222
+ notAuthenticated: '请先登录市场账户',
223
+ publishFailed: '发布失败: {{message}}',
224
+ },
225
+ submitButton: '发布',
226
+ title: {
227
+ submit: '分享到助手市场',
228
+ upload: '发布新版本',
229
+ },
230
+ },
231
+ resultModal: {
232
+ message: '助手已提交审核,审核通过后将自动上线。点击「在市场查看」查看已发布的助手。',
233
+ view: '在市场查看',
234
+ },
235
+ submit: {
236
+ button: '分享到市场',
237
+ tooltip: '分享助手到市场',
238
+ },
239
+ upload: {
240
+ button: '发布新版本',
241
+ tooltip: '发布新版本到助手市场',
242
+ },
243
+ },
151
244
  message: {
152
245
  success: '更新成功',
153
246
  },
@@ -565,7 +658,7 @@ export default {
565
658
  },
566
659
  submitAgentModal: {
567
660
  button: '提交助手',
568
- identifier: 'identifier 助手标识符',
661
+ identifier: '助手标识符(identifier',
569
662
  metaMiss: '请补全助手信息后提交,需要包含名称、描述和标签',
570
663
  placeholder: '请输入助手的标识符,需要是唯一的,比如 web-development',
571
664
  tooltips: '分享到助手市场',
@@ -19,7 +19,7 @@ vi.mock('@/envs/llm', () => ({
19
19
  })),
20
20
  }));
21
21
 
22
- vi.mock('@/utils/parseModels', () => ({
22
+ vi.mock('@/utils/server/parseModels', () => ({
23
23
  extractEnabledModels: vi.fn(async (providerId: string, modelString?: string) => {
24
24
  if (!modelString) return undefined;
25
25
  return [`${providerId}-model-1`, `${providerId}-model-2`];
@@ -98,7 +98,7 @@ describe('genServerAiProvidersConfig', () => {
98
98
  it('should use environment variables for model lists', async () => {
99
99
  process.env.OPENAI_MODEL_LIST = '+gpt-4,+gpt-3.5-turbo';
100
100
 
101
- const { extractEnabledModels } = vi.mocked(await import('@/utils/parseModels'));
101
+ const { extractEnabledModels } = vi.mocked(await import('@/utils/server/parseModels'));
102
102
  extractEnabledModels.mockResolvedValue(['gpt-4', 'gpt-3.5-turbo']);
103
103
 
104
104
  const result = await genServerAiProvidersConfig({});
@@ -116,7 +116,7 @@ describe('genServerAiProvidersConfig', () => {
116
116
 
117
117
  process.env.CUSTOM_OPENAI_MODELS = '+custom-model';
118
118
 
119
- const { extractEnabledModels } = vi.mocked(await import('@/utils/parseModels'));
119
+ const { extractEnabledModels } = vi.mocked(await import('@/utils/server/parseModels'));
120
120
 
121
121
  await genServerAiProvidersConfig(specificConfig);
122
122
 
@@ -133,7 +133,7 @@ describe('genServerAiProvidersConfig', () => {
133
133
  process.env.OPENAI_MODEL_LIST = '+gpt-4->deployment1';
134
134
 
135
135
  const { extractEnabledModels, transformToAiModelList } = vi.mocked(
136
- await import('@/utils/parseModels'),
136
+ await import('@/utils/server/parseModels'),
137
137
  );
138
138
 
139
139
  await genServerAiProvidersConfig(specificConfig);
@@ -206,7 +206,7 @@ describe('genServerAiProvidersConfig Error Handling', () => {
206
206
  getLLMConfig: vi.fn(() => ({})),
207
207
  }));
208
208
 
209
- vi.doMock('@/utils/parseModels', () => ({
209
+ vi.doMock('@/utils/server/parseModels', () => ({
210
210
  extractEnabledModels: vi.fn(async () => undefined),
211
211
  transformToAiModelList: vi.fn(async () => []),
212
212
  }));
@@ -1,9 +1,9 @@
1
1
  import { ProviderConfig } from '@lobechat/types';
2
- import { extractEnabledModels, transformToAiModelList } from '@lobechat/utils';
3
2
  import { AiFullModelCard, ModelProvider } from 'model-bank';
4
3
  import * as AiModels from 'model-bank';
5
4
 
6
5
  import { getLLMConfig } from '@/envs/llm';
6
+ import { extractEnabledModels, transformToAiModelList } from '@/utils/server/parseModels';
7
7
 
8
8
  interface ProviderSpecificConfig {
9
9
  enabled?: boolean;
@@ -1,15 +1,24 @@
1
+ import { isDesktop } from '@lobechat/const';
1
2
  import { TRPCError } from '@trpc/server';
2
3
  import { serialize } from 'cookie';
3
4
  import debug from 'debug';
4
5
  import { z } from 'zod';
5
6
 
6
- import { isDesktop } from '@lobechat/const';
7
7
  import { publicProcedure, router } from '@/libs/trpc/lambda';
8
8
  import { DiscoverService } from '@/server/services/discover';
9
- import { AssistantSorts, McpConnectionType, McpSorts, ModelSorts, PluginSorts, ProviderSorts } from '@/types/discover';
9
+ import {
10
+ AssistantSorts,
11
+ McpConnectionType,
12
+ McpSorts,
13
+ ModelSorts,
14
+ PluginSorts,
15
+ ProviderSorts,
16
+ } from '@/types/discover';
10
17
 
11
18
  const log = debug('lambda-router:market');
12
19
 
20
+ const marketSourceSchema = z.enum(['legacy', 'new']);
21
+
13
22
  const marketProcedure = publicProcedure.use(async ({ ctx, next }) => {
14
23
  return next({
15
24
  ctx: {
@@ -26,6 +35,7 @@ export const marketRouter = router({
26
35
  .object({
27
36
  locale: z.string().optional(),
28
37
  q: z.string().optional(),
38
+ source: marketSourceSchema.optional(),
29
39
  })
30
40
  .optional(),
31
41
  )
@@ -48,6 +58,8 @@ export const marketRouter = router({
48
58
  z.object({
49
59
  identifier: z.string(),
50
60
  locale: z.string().optional(),
61
+ source: marketSourceSchema.optional(),
62
+ version: z.string().optional(),
51
63
  }),
52
64
  )
53
65
  .query(async ({ input, ctx }) => {
@@ -64,19 +76,27 @@ export const marketRouter = router({
64
76
  }
65
77
  }),
66
78
 
67
- getAssistantIdentifiers: marketProcedure.query(async ({ ctx }) => {
68
- log('getAssistantIdentifiers called');
79
+ getAssistantIdentifiers: marketProcedure
80
+ .input(
81
+ z
82
+ .object({
83
+ source: marketSourceSchema.optional(),
84
+ })
85
+ .optional(),
86
+ )
87
+ .query(async ({ input, ctx }) => {
88
+ log('getAssistantIdentifiers called with input: %O', input);
69
89
 
70
- try {
71
- return await ctx.discoverService.getAssistantIdentifiers();
72
- } catch (error) {
73
- log('Error fetching assistant identifiers: %O', error);
74
- throw new TRPCError({
75
- code: 'INTERNAL_SERVER_ERROR',
76
- message: 'Failed to fetch assistant identifiers',
77
- });
78
- }
79
- }),
90
+ try {
91
+ return await ctx.discoverService.getAssistantIdentifiers(input);
92
+ } catch (error) {
93
+ log('Error fetching assistant identifiers: %O', error);
94
+ throw new TRPCError({
95
+ code: 'INTERNAL_SERVER_ERROR',
96
+ message: 'Failed to fetch assistant identifiers',
97
+ });
98
+ }
99
+ }),
80
100
 
81
101
  getAssistantList: marketProcedure
82
102
  .input(
@@ -86,10 +106,12 @@ export const marketRouter = router({
86
106
  connectionType: z.nativeEnum(McpConnectionType).optional(),
87
107
  locale: z.string().optional(),
88
108
  order: z.enum(['asc', 'desc']).optional(),
109
+ ownerId: z.string().optional(),
89
110
  page: z.number().optional(),
90
111
  pageSize: z.number().optional(),
91
112
  q: z.string().optional(),
92
113
  sort: z.nativeEnum(AssistantSorts).optional(),
114
+ source: marketSourceSchema.optional(),
93
115
  })
94
116
  .optional(),
95
117
  )
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  CreateNewMessageParamsSchema,
3
3
  UpdateMessageParamsSchema,
4
+ UpdateMessagePluginSchema,
4
5
  UpdateMessageRAGParamsSchema,
5
6
  } from '@lobechat/types';
6
7
  import { z } from 'zod';
7
8
 
8
9
  import { MessageModel } from '@/database/models/message';
9
- import { updateMessagePluginSchema } from '@/database/schemas';
10
10
  import { getServerDB } from '@/database/server';
11
11
  import { authedProcedure, publicProcedure, router } from '@/libs/trpc/lambda';
12
12
  import { serverDatabase } from '@/libs/trpc/lambda/middleware';
@@ -179,7 +179,7 @@ export const messageRouter = router({
179
179
  .input(
180
180
  z.object({
181
181
  id: z.string(),
182
- value: updateMessagePluginSchema.partial(),
182
+ value: UpdateMessagePluginSchema.partial(),
183
183
  }),
184
184
  )
185
185
  .mutation(async ({ input, ctx }) => {
@@ -19,9 +19,6 @@ vi.mock('@/locales/resources', () => ({
19
19
  }),
20
20
  }));
21
21
 
22
- // Set environment variable for tests
23
- process.env.MARKET_BASE_URL = 'http://localhost:8787/api';
24
-
25
22
  // Mock constants with inline data
26
23
  vi.mock('model-bank', async (importOriginal) => {
27
24
  const actual = await importOriginal();
@@ -130,6 +127,68 @@ const mockAssistantList = [
130
127
  },
131
128
  ];
132
129
 
130
+ const mockMarketAssistantList = [
131
+ {
132
+ identifier: 'market-assistant-1',
133
+ name: 'Market Assistant 1',
134
+ summary: 'First market assistant from new source',
135
+ author: { name: 'Market Author 1', avatar: 'https://example.com/avatar1.png' },
136
+ ownerId: 101,
137
+ category: 'productivity',
138
+ createdAt: '2024-02-01T00:00:00Z',
139
+ updatedAt: '2024-02-02T00:00:00Z',
140
+ avatar: 'https://example.com/avatar1.png',
141
+ tags: ['market', 'assistant'],
142
+ status: 'published',
143
+ tokenUsage: 256,
144
+ config: {
145
+ systemRole: 'You are a productive assistant.',
146
+ knowledgeBases: [{ id: 'kb-1' }],
147
+ plugins: [{ id: 'plugin-1' }],
148
+ },
149
+ },
150
+ {
151
+ identifier: 'market-assistant-2',
152
+ name: 'Market Assistant 2',
153
+ summary: 'Second market assistant from new source',
154
+ author: 'Market Author 2',
155
+ ownerId: 202,
156
+ category: 'creativity',
157
+ createdAt: '2024-02-04T00:00:00Z',
158
+ updatedAt: '2024-02-05T00:00:00Z',
159
+ avatar: 'https://example.com/avatar2.png',
160
+ tags: ['market', 'creative'],
161
+ status: 'published',
162
+ tokenUsage: 128,
163
+ config: {
164
+ systemRole: 'You are a creative assistant.',
165
+ knowledgeBases: [],
166
+ plugins: [],
167
+ },
168
+ },
169
+ ];
170
+
171
+ const mockMarketAgentDetail = {
172
+ ...mockMarketAssistantList[0],
173
+ documentationUrl: 'https://example.com/docs',
174
+ version: '1.0.0',
175
+ versions: [
176
+ {
177
+ version: '1.0.0',
178
+ status: 'published',
179
+ isLatest: true,
180
+ isValidated: true,
181
+ createdAt: '2024-02-02T00:00:00Z',
182
+ },
183
+ ],
184
+ examples: [
185
+ {
186
+ content: 'Example content',
187
+ role: 'user',
188
+ },
189
+ ],
190
+ };
191
+
133
192
  const mockPluginList = [
134
193
  {
135
194
  identifier: 'plugin-1',
@@ -182,6 +241,24 @@ describe('DiscoverService', () => {
182
241
 
183
242
  // Setup MarketSDK mock
184
243
  mockMarket = {
244
+ agents: {
245
+ getAgentList: vi.fn().mockResolvedValue({
246
+ items: mockMarketAssistantList,
247
+ totalCount: mockMarketAssistantList.length,
248
+ currentPage: 1,
249
+ pageSize: 20,
250
+ totalPages: 1,
251
+ }),
252
+ getAgentDetail: vi.fn().mockResolvedValue(mockMarketAgentDetail),
253
+ getCategories: vi.fn().mockResolvedValue([
254
+ { category: 'productivity', count: 10 },
255
+ { category: 'creativity', count: 5 },
256
+ ]),
257
+ getPublishedIdentifiers: vi.fn().mockResolvedValue([
258
+ { id: 'market-assistant-1', lastModified: '2024-02-02T00:00:00Z' },
259
+ { id: 'market-assistant-2', lastModified: '2024-02-05T00:00:00Z' },
260
+ ]),
261
+ },
185
262
  plugins: {
186
263
  getCategories: vi.fn().mockResolvedValue([
187
264
  { category: 'tools', count: 5 },
@@ -214,10 +291,68 @@ describe('DiscoverService', () => {
214
291
  service.market = mockMarket;
215
292
  });
216
293
 
217
- describe('Assistant Market', () => {
294
+ describe('Assistant Market (new source)', () => {
295
+ it('getAssistantList should transform market SDK response', async () => {
296
+ const result = await service.getAssistantList();
297
+
298
+ expect(mockMarket.agents.getAgentList).toHaveBeenCalled();
299
+ expect(result.items[0]).toEqual(
300
+ expect.objectContaining({
301
+ identifier: 'market-assistant-1',
302
+ title: 'Market Assistant 1',
303
+ author: 'Market Author 1',
304
+ knowledgeCount: 1,
305
+ pluginCount: 1,
306
+ }),
307
+ );
308
+ });
309
+
310
+ it('getAssistantDetail should fetch from market SDK by default', async () => {
311
+ const result = await service.getAssistantDetail({
312
+ identifier: 'market-assistant-1',
313
+ });
314
+
315
+ expect(mockMarket.agents.getAgentDetail).toHaveBeenCalledWith('market-assistant-1', {
316
+ locale: 'en',
317
+ version: undefined,
318
+ });
319
+ expect(result).toEqual(
320
+ expect.objectContaining({
321
+ identifier: 'market-assistant-1',
322
+ title: 'Market Assistant 1',
323
+ related: expect.any(Array),
324
+ }),
325
+ );
326
+ });
327
+
328
+ it('getAssistantCategories should proxy to market SDK', async () => {
329
+ const result = await service.getAssistantCategories({ locale: 'en-US', q: 'market' });
330
+
331
+ expect(mockMarket.agents.getCategories).toHaveBeenCalledWith({
332
+ locale: 'en',
333
+ q: 'market',
334
+ });
335
+ expect(result).toEqual([
336
+ { category: 'productivity', count: 10 },
337
+ { category: 'creativity', count: 5 },
338
+ ]);
339
+ });
340
+
341
+ it('getAssistantIdentifiers should read from market SDK', async () => {
342
+ const result = await service.getAssistantIdentifiers();
343
+
344
+ expect(mockMarket.agents.getPublishedIdentifiers).toHaveBeenCalled();
345
+ expect(result).toEqual([
346
+ { identifier: 'market-assistant-1', lastModified: '2024-02-02T00:00:00Z' },
347
+ { identifier: 'market-assistant-2', lastModified: '2024-02-05T00:00:00Z' },
348
+ ]);
349
+ });
350
+ });
351
+
352
+ describe('Assistant Market (legacy source)', () => {
218
353
  describe('getAssistantList', () => {
219
354
  it('should return formatted assistant list with default parameters', async () => {
220
- const result = await service.getAssistantList();
355
+ const result = await service.getAssistantList({ source: 'legacy' });
221
356
 
222
357
  expect(result).toEqual({
223
358
  currentPage: 1,
@@ -242,7 +377,10 @@ describe('DiscoverService', () => {
242
377
  });
243
378
 
244
379
  it('should filter by category', async () => {
245
- const result = await service.getAssistantList({ category: 'productivity' });
380
+ const result = await service.getAssistantList({
381
+ category: 'productivity',
382
+ source: 'legacy',
383
+ });
246
384
 
247
385
  expect(result.items).toHaveLength(2);
248
386
  expect(result.items.map((item) => item.identifier)).toContain('assistant-1');
@@ -250,7 +388,7 @@ describe('DiscoverService', () => {
250
388
  });
251
389
 
252
390
  it('should filter by search query', async () => {
253
- const result = await service.getAssistantList({ q: 'creative' });
391
+ const result = await service.getAssistantList({ q: 'creative', source: 'legacy' });
254
392
 
255
393
  expect(result.items).toHaveLength(2);
256
394
  expect(result.items.map((item) => item.identifier)).toContain('assistant-2');
@@ -261,6 +399,7 @@ describe('DiscoverService', () => {
261
399
  const result = await service.getAssistantList({
262
400
  sort: AssistantSorts.CreatedAt,
263
401
  order: 'desc',
402
+ source: 'legacy',
264
403
  });
265
404
 
266
405
  expect(result.items[0].identifier).toBe('assistant-3');
@@ -272,6 +411,7 @@ describe('DiscoverService', () => {
272
411
  const result = await service.getAssistantList({
273
412
  sort: AssistantSorts.Title,
274
413
  order: 'asc',
414
+ source: 'legacy',
275
415
  });
276
416
 
277
417
  // Note: The service has reversed logic for title sorting
@@ -280,7 +420,7 @@ describe('DiscoverService', () => {
280
420
  });
281
421
 
282
422
  it('should paginate results', async () => {
283
- const result = await service.getAssistantList({ page: 1, pageSize: 1 });
423
+ const result = await service.getAssistantList({ page: 1, pageSize: 1, source: 'legacy' });
284
424
 
285
425
  expect(result.items).toHaveLength(1);
286
426
  expect(result.currentPage).toBe(1);
@@ -293,6 +433,7 @@ describe('DiscoverService', () => {
293
433
  it('should return assistant detail with related items', async () => {
294
434
  const result = await service.getAssistantDetail({
295
435
  identifier: 'assistant-1',
436
+ source: 'legacy',
296
437
  });
297
438
 
298
439
  expect(result).toEqual(
@@ -311,6 +452,7 @@ describe('DiscoverService', () => {
311
452
 
312
453
  const result = await service.getAssistantDetail({
313
454
  identifier: 'non-existent',
455
+ source: 'legacy',
314
456
  });
315
457
 
316
458
  expect(result).toBeUndefined();
@@ -319,7 +461,7 @@ describe('DiscoverService', () => {
319
461
 
320
462
  describe('getAssistantCategories', () => {
321
463
  it('should return category counts', async () => {
322
- const result = await service.getAssistantCategories();
464
+ const result = await service.getAssistantCategories({ source: 'legacy' });
323
465
 
324
466
  expect(result).toEqual([
325
467
  { category: 'productivity', count: 2 },
@@ -328,7 +470,7 @@ describe('DiscoverService', () => {
328
470
  });
329
471
 
330
472
  it('should filter categories by search query', async () => {
331
- const result = await service.getAssistantCategories({ q: 'creative' });
473
+ const result = await service.getAssistantCategories({ q: 'creative', source: 'legacy' });
332
474
 
333
475
  expect(result).toEqual([
334
476
  {
@@ -345,7 +487,7 @@ describe('DiscoverService', () => {
345
487
 
346
488
  describe('getAssistantIdentifiers', () => {
347
489
  it('should return list of identifiers with lastModified dates', async () => {
348
- const result = await service.getAssistantIdentifiers();
490
+ const result = await service.getAssistantIdentifiers({ source: 'legacy' });
349
491
 
350
492
  expect(result).toEqual([
351
493
  { identifier: 'assistant-1', lastModified: '2024-01-01T00:00:00Z' },