@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,153 @@
1
+ import { MarketSDK } from '@lobehub/market-sdk';
2
+ import { NextRequest, NextResponse } from 'next/server';
3
+
4
+ type RouteContext = {
5
+ params: Promise<{
6
+ segments?: string[];
7
+ }>;
8
+ };
9
+
10
+ const MARKET_BASE_URL = process.env.NEXT_PUBLIC_MARKET_BASE_URL || 'http://127.0.0.1:8787';
11
+
12
+ const extractAccessToken = (req: NextRequest) => {
13
+ const authorization = req.headers.get('authorization');
14
+ if (!authorization) return undefined;
15
+
16
+ const [scheme, token] = authorization.split(' ');
17
+ if (scheme?.toLowerCase() !== 'bearer' || !token) return undefined;
18
+
19
+ return token;
20
+ };
21
+
22
+ const methodNotAllowed = (methods: string[]) =>
23
+ NextResponse.json(
24
+ {
25
+ error: 'method_not_allowed',
26
+ message: `Allowed methods: ${methods.join(', ')}`,
27
+ status: 'error',
28
+ },
29
+ {
30
+ headers: { Allow: methods.join(', ') },
31
+ status: 405,
32
+ },
33
+ );
34
+
35
+ const badRequest = (error: string, message: string) =>
36
+ NextResponse.json(
37
+ {
38
+ error,
39
+ message,
40
+ status: 'error',
41
+ },
42
+ { status: 400 },
43
+ );
44
+
45
+ const notFound = (reason: string) =>
46
+ NextResponse.json(
47
+ {
48
+ error: 'not_found',
49
+ message: reason,
50
+ status: 'error',
51
+ },
52
+ { status: 404 },
53
+ );
54
+
55
+ const handleAgent = async (req: NextRequest, segments: string[]) => {
56
+ const accessToken = extractAccessToken(req);
57
+ const market = new MarketSDK({
58
+ accessToken,
59
+ baseURL: MARKET_BASE_URL,
60
+ });
61
+
62
+ if (segments.length === 0) {
63
+ return notFound('Missing agent action.');
64
+ }
65
+
66
+ const [action, ...rest] = segments;
67
+
68
+ if (action === 'create') {
69
+ if (req.method !== 'POST') return methodNotAllowed(['POST']);
70
+
71
+ try {
72
+ const payload = await req.json();
73
+ const response = await market.agents.createAgent(payload);
74
+ return NextResponse.json(response);
75
+ } catch (error) {
76
+ console.error('[Market] Failed to create agent:', error);
77
+ return NextResponse.json(
78
+ {
79
+ error: 'create_agent_failed',
80
+ message: error instanceof Error ? error.message : 'Unknown error',
81
+ status: 'error',
82
+ },
83
+ { status: 500 },
84
+ );
85
+ }
86
+ }
87
+
88
+ if (action === 'versions') {
89
+ if (rest.length !== 1 || rest[0] !== 'create') {
90
+ return notFound('Requested agent version endpoint is not available.');
91
+ }
92
+
93
+ if (req.method !== 'POST') return methodNotAllowed(['POST']);
94
+
95
+ try {
96
+ const payload = await req.json();
97
+ if (typeof payload !== 'object' || payload === null) {
98
+ return badRequest('invalid_payload', 'Request body must be a JSON object.');
99
+ }
100
+
101
+ const identifier = (payload as { identifier?: string }).identifier;
102
+ if (!identifier) {
103
+ return badRequest('missing_identifier', 'Identifier is required to create agent version.');
104
+ }
105
+
106
+ const response = await market.agents.createAgentVersion(payload);
107
+ return NextResponse.json(response);
108
+ } catch (error) {
109
+ console.error('[Market] Failed to create agent version:', error);
110
+ return NextResponse.json(
111
+ {
112
+ error: 'create_agent_version_failed',
113
+ message: error instanceof Error ? error.message : 'Unknown error',
114
+ status: 'error',
115
+ },
116
+ { status: 500 },
117
+ );
118
+ }
119
+ }
120
+
121
+ if (segments.length === 1) {
122
+ if (req.method !== 'GET') return methodNotAllowed(['GET']);
123
+
124
+ try {
125
+ const response = await market.agents.getAgentDetail(action);
126
+ return NextResponse.json(response);
127
+ } catch (error) {
128
+ console.error('[Market] Failed to get agent detail:', error);
129
+ return NextResponse.json(
130
+ {
131
+ error: 'get_agent_detail_failed',
132
+ message: error instanceof Error ? error.message : 'Unknown error',
133
+ status: 'error',
134
+ },
135
+ { status: 500 },
136
+ );
137
+ }
138
+ }
139
+
140
+ return notFound('Requested agent endpoint is not available.');
141
+ };
142
+
143
+ const handleProxy = async (req: NextRequest, context: RouteContext) => {
144
+ const { segments } = await context.params;
145
+ const normalizedSegments = segments?.map((segment) => decodeURIComponent(segment)) ?? [];
146
+
147
+ return handleAgent(req, normalizedSegments);
148
+ };
149
+
150
+ export const GET = (req: NextRequest, context: RouteContext) => handleProxy(req, context);
151
+ export const POST = (req: NextRequest, context: RouteContext) => handleProxy(req, context);
152
+
153
+ export const dynamic = 'force-dynamic';
@@ -0,0 +1,207 @@
1
+ import { MarketSDK } from '@lobehub/market-sdk';
2
+ import { NextRequest, NextResponse } from 'next/server';
3
+
4
+ type RouteContext = {
5
+ params: Promise<{
6
+ segments?: string[];
7
+ }>;
8
+ };
9
+
10
+ const MARKET_BASE_URL = process.env.NEXT_PUBLIC_MARKET_BASE_URL || 'http://127.0.0.1:8787';
11
+ const ALLOWED_ENDPOINTS = new Set(['handoff', 'token', 'userinfo']);
12
+
13
+ const ensureEndpoint = (segments?: string[]) => {
14
+ if (!segments || segments.length === 0) {
15
+ return { error: 'missing_endpoint', status: 404 } as const;
16
+ }
17
+
18
+ if (segments.length !== 1) {
19
+ return { error: 'unsupported_nested_path', status: 404 } as const;
20
+ }
21
+
22
+ const endpoint = segments[0];
23
+
24
+ if (!ALLOWED_ENDPOINTS.has(endpoint)) {
25
+ return { error: 'unknown_endpoint', status: 404 } as const;
26
+ }
27
+
28
+ return { endpoint } as const;
29
+ };
30
+
31
+ const methodNotAllowed = (allowed: string[]) =>
32
+ NextResponse.json(
33
+ {
34
+ error: 'method_not_allowed',
35
+ message: `Allowed methods: ${allowed.join(', ')}`,
36
+ status: 'error',
37
+ },
38
+ {
39
+ headers: { Allow: allowed.join(', ') },
40
+ status: 405,
41
+ },
42
+ );
43
+
44
+ const handleProxy = async (req: NextRequest, context: RouteContext) => {
45
+ const market = new MarketSDK({
46
+ baseURL: MARKET_BASE_URL,
47
+ });
48
+
49
+ const { segments } = await context.params;
50
+ const endpointResult = ensureEndpoint(segments);
51
+
52
+ if ('error' in endpointResult) {
53
+ return NextResponse.json(
54
+ {
55
+ error: endpointResult.error,
56
+ message: 'Requested endpoint is not available.',
57
+ status: 'error',
58
+ },
59
+ { status: endpointResult.status },
60
+ );
61
+ }
62
+
63
+ const endpoint = endpointResult.endpoint;
64
+
65
+ switch (endpoint) {
66
+ case 'handoff': {
67
+ try {
68
+ const id = req.nextUrl.searchParams.get('id');
69
+ if (id) {
70
+ const handoff = await market.auth.getOAuthHandoff(id);
71
+ return new NextResponse(JSON.stringify(handoff), { status: 200 });
72
+ } else {
73
+ return NextResponse.json(
74
+ {
75
+ error: 'missing_id',
76
+ message: 'ID is required for handoff proxy.',
77
+ status: 'error',
78
+ },
79
+ { status: 400 },
80
+ );
81
+ }
82
+ } catch (error) {
83
+ return NextResponse.json(
84
+ {
85
+ error: 'handoff_proxy_failed',
86
+ message: error instanceof Error ? error.message : 'Unknown error',
87
+ status: 'error',
88
+ },
89
+ { status: 500 },
90
+ );
91
+ }
92
+ }
93
+
94
+ case 'token': {
95
+ if (req.method !== 'POST') {
96
+ return methodNotAllowed(['POST']);
97
+ }
98
+
99
+ try {
100
+ const body = await req.text();
101
+ const form = new URLSearchParams(body);
102
+
103
+ const grantType = (form.get('grant_type') || 'authorization_code') as
104
+ | 'authorization_code'
105
+ | 'refresh_token';
106
+
107
+ if (grantType === 'authorization_code') {
108
+ const clientId = form.get('client_id');
109
+ const code = form.get('code');
110
+ const codeVerifier = form.get('code_verifier');
111
+ const redirectUri = form.get('redirect_uri');
112
+
113
+ const response = await market.auth.exchangeOAuthToken({
114
+ clientId: clientId as string,
115
+ code: code as string,
116
+ codeVerifier: codeVerifier as string,
117
+ grantType: 'authorization_code',
118
+ redirectUri: redirectUri as string,
119
+ });
120
+
121
+ return NextResponse.json(response);
122
+ }
123
+
124
+ if (grantType === 'refresh_token') {
125
+ const refreshToken = form.get('refresh_token');
126
+ const clientId = form.get('client_id');
127
+
128
+ const response = await market.auth.exchangeOAuthToken({
129
+ clientId: clientId ?? undefined,
130
+ grantType: 'refresh_token',
131
+ refreshToken: refreshToken as string,
132
+ });
133
+
134
+ return NextResponse.json(response);
135
+ }
136
+
137
+ return NextResponse.json(
138
+ {
139
+ error: 'unsupported_grant_type',
140
+ message: `Unsupported grant_type: ${grantType}`,
141
+ status: 'error',
142
+ },
143
+ { status: 400 },
144
+ );
145
+ } catch (error) {
146
+ console.error('[MarketOIDC] Failed to proxy token request:', error);
147
+ return NextResponse.json(
148
+ {
149
+ error: 'token_proxy_failed',
150
+ message: error instanceof Error ? error.message : 'Unknown error',
151
+ status: 'error',
152
+ },
153
+ { status: 500 },
154
+ );
155
+ }
156
+ }
157
+
158
+ case 'userinfo': {
159
+ if (req.method !== 'POST') {
160
+ return methodNotAllowed(['POST']);
161
+ }
162
+
163
+ try {
164
+ const { token } = (await req.json()) as { token?: string };
165
+ if (!token) {
166
+ return NextResponse.json(
167
+ {
168
+ error: 'missing_token',
169
+ message: 'Token is required for userinfo proxy.',
170
+ status: 'error',
171
+ },
172
+ { status: 400 },
173
+ );
174
+ }
175
+
176
+ const response = await market.auth.getUserInfo(token);
177
+ return NextResponse.json(response);
178
+ } catch (error) {
179
+ console.error('[MarketOIDC] Failed to proxy userinfo request:', error);
180
+ return NextResponse.json(
181
+ {
182
+ error: 'userinfo_proxy_failed',
183
+ message: error instanceof Error ? error.message : 'Unknown error',
184
+ status: 'error',
185
+ },
186
+ { status: 500 },
187
+ );
188
+ }
189
+ }
190
+
191
+ default: {
192
+ return NextResponse.json(
193
+ {
194
+ error: 'unsupported_endpoint',
195
+ message: 'Requested endpoint is not supported.',
196
+ status: 'error',
197
+ },
198
+ { status: 404 },
199
+ );
200
+ }
201
+ }
202
+ };
203
+
204
+ export const GET = (req: NextRequest, context: RouteContext) => handleProxy(req, context);
205
+ export const POST = (req: NextRequest, context: RouteContext) => handleProxy(req, context);
206
+
207
+ export const dynamic = 'force-dynamic';
@@ -1,6 +1,7 @@
1
1
  import { Bot, Brain, Info, Mic2, Settings2, Sparkles } from 'lucide-react';
2
2
  import { useRouter } from 'next/navigation';
3
3
  import { useTranslation } from 'react-i18next';
4
+
4
5
  import { CellProps } from '@/components/Cell';
5
6
  import { isDeprecatedEdition } from '@/const/version';
6
7
  import { SettingsTabs } from '@/store/global/initialState';
@@ -82,12 +82,14 @@ const PinList = () => {
82
82
  hasList && (
83
83
  <>
84
84
  <Divider style={{ marginBottom: 8, marginTop: 4 }} />
85
- <ScrollShadow height={"100%"} hideScrollBar={true} size={40}>
85
+ <ScrollShadow height={'100%'} hideScrollBar={true} size={40}>
86
86
  <Flexbox gap={12} style={{ padding: '0' }}>
87
87
  {list.map((item, index) => (
88
88
  <Flexbox key={item.id} style={{ position: 'relative' }}>
89
89
  <Tooltip
90
- hotkey={index < 9 ? hotkey.replaceAll(KeyEnum.Number, String(index + 1)) : undefined}
90
+ hotkey={
91
+ index < 9 ? hotkey.replaceAll(KeyEnum.Number, String(index + 1)) : undefined
92
+ }
91
93
  placement={'right'}
92
94
  title={sessionHelpers.getTitle(item.meta)}
93
95
  >