@lobehub/chat 1.105.0 → 1.105.2

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 (62) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/changelog/v1.json +18 -0
  3. package/locales/ar/auth.json +54 -0
  4. package/locales/bg-BG/auth.json +54 -0
  5. package/locales/de-DE/auth.json +54 -0
  6. package/locales/en-US/auth.json +54 -0
  7. package/locales/es-ES/auth.json +54 -0
  8. package/locales/fa-IR/auth.json +54 -0
  9. package/locales/fr-FR/auth.json +54 -0
  10. package/locales/it-IT/auth.json +54 -0
  11. package/locales/ja-JP/auth.json +54 -0
  12. package/locales/ko-KR/auth.json +54 -0
  13. package/locales/nl-NL/auth.json +54 -0
  14. package/locales/pl-PL/auth.json +54 -0
  15. package/locales/pt-BR/auth.json +54 -0
  16. package/locales/ru-RU/auth.json +54 -0
  17. package/locales/tr-TR/auth.json +54 -0
  18. package/locales/vi-VN/auth.json +54 -0
  19. package/locales/zh-CN/auth.json +54 -0
  20. package/locales/zh-TW/auth.json +54 -0
  21. package/package.json +2 -2
  22. package/src/app/(backend)/middleware/auth/index.test.ts +5 -5
  23. package/src/app/(backend)/middleware/auth/index.ts +6 -6
  24. package/src/app/(backend)/webapi/chat/[provider]/route.test.ts +11 -9
  25. package/src/app/(backend)/webapi/plugin/gateway/route.ts +2 -2
  26. package/src/app/sitemap.tsx +1 -10
  27. package/src/config/aiModels/giteeai.ts +269 -2
  28. package/src/config/aiModels/qwen.ts +207 -2
  29. package/src/config/aiModels/siliconcloud.ts +24 -2
  30. package/src/config/aiModels/stepfun.ts +67 -2
  31. package/src/config/aiModels/volcengine.ts +56 -2
  32. package/src/config/aiModels/wenxin.ts +62 -2
  33. package/src/config/aiModels/xai.ts +19 -2
  34. package/src/const/auth.ts +2 -3
  35. package/src/libs/model-runtime/ModelRuntime.test.ts +3 -3
  36. package/src/libs/model-runtime/qwen/createImage.ts +29 -9
  37. package/src/libs/trpc/async/context.ts +3 -3
  38. package/src/libs/trpc/edge/context.ts +7 -2
  39. package/src/libs/trpc/edge/middleware/jwtPayload.test.ts +4 -4
  40. package/src/libs/trpc/edge/middleware/jwtPayload.ts +2 -2
  41. package/src/libs/trpc/lambda/context.ts +2 -2
  42. package/src/libs/trpc/lambda/middleware/keyVaults.ts +2 -2
  43. package/src/server/modules/AgentRuntime/index.test.ts +28 -25
  44. package/src/server/modules/AgentRuntime/index.ts +3 -3
  45. package/src/server/routers/async/caller.ts +2 -2
  46. package/src/server/routers/lambda/market/index.ts +0 -14
  47. package/src/server/routers/tools/search.test.ts +2 -2
  48. package/src/server/services/chunk/index.ts +3 -3
  49. package/src/server/services/discover/index.ts +0 -13
  50. package/src/server/sitemap.test.ts +0 -52
  51. package/src/server/sitemap.ts +1 -38
  52. package/src/services/_auth.ts +3 -3
  53. package/src/services/discover.ts +0 -4
  54. package/src/store/discover/slices/mcp/action.ts +0 -8
  55. package/src/utils/client/xor-obfuscation.test.ts +370 -0
  56. package/src/utils/client/xor-obfuscation.ts +39 -0
  57. package/src/utils/server/xor.test.ts +123 -0
  58. package/src/utils/server/xor.ts +42 -0
  59. package/src/utils/jwt.test.ts +0 -27
  60. package/src/utils/jwt.ts +0 -37
  61. package/src/utils/server/jwt.test.ts +0 -62
  62. package/src/utils/server/jwt.ts +0 -28
@@ -1,7 +1,7 @@
1
1
  // @vitest-environment node
2
2
  import { describe, expect, it, vi } from 'vitest';
3
3
 
4
- import { JWTPayload } from '@/const/auth';
4
+ import { ClientSecretPayload } from '@/const/auth';
5
5
  import {
6
6
  LobeAnthropicAI,
7
7
  LobeAzureOpenAI,
@@ -67,7 +67,10 @@ vi.mock('@/config/llm', () => ({
67
67
  describe('initAgentRuntimeWithUserPayload method', () => {
68
68
  describe('should initialize with options correctly', () => {
69
69
  it('OpenAI provider: with apikey and endpoint', async () => {
70
- const jwtPayload: JWTPayload = { apiKey: 'user-openai-key', baseURL: 'user-endpoint' };
70
+ const jwtPayload: ClientSecretPayload = {
71
+ apiKey: 'user-openai-key',
72
+ baseURL: 'user-endpoint',
73
+ };
71
74
  const runtime = await initAgentRuntimeWithUserPayload(ModelProvider.OpenAI, jwtPayload);
72
75
  expect(runtime).toBeInstanceOf(AgentRuntime);
73
76
  expect(runtime['_runtime']).toBeInstanceOf(LobeOpenAI);
@@ -75,7 +78,7 @@ describe('initAgentRuntimeWithUserPayload method', () => {
75
78
  });
76
79
 
77
80
  it('Azure AI provider: with apikey, endpoint and apiversion', async () => {
78
- const jwtPayload: JWTPayload = {
81
+ const jwtPayload: ClientSecretPayload = {
79
82
  apiKey: 'user-azure-key',
80
83
  baseURL: 'user-azure-endpoint',
81
84
  azureApiVersion: '2024-06-01',
@@ -87,35 +90,35 @@ describe('initAgentRuntimeWithUserPayload method', () => {
87
90
  });
88
91
 
89
92
  it('ZhiPu AI provider: with apikey', async () => {
90
- const jwtPayload: JWTPayload = { apiKey: 'zhipu.user-key' };
93
+ const jwtPayload: ClientSecretPayload = { apiKey: 'zhipu.user-key' };
91
94
  const runtime = await initAgentRuntimeWithUserPayload(ModelProvider.ZhiPu, jwtPayload);
92
95
  expect(runtime).toBeInstanceOf(AgentRuntime);
93
96
  expect(runtime['_runtime']).toBeInstanceOf(LobeZhipuAI);
94
97
  });
95
98
 
96
99
  it('Google provider: with apikey', async () => {
97
- const jwtPayload: JWTPayload = { apiKey: 'user-google-key' };
100
+ const jwtPayload: ClientSecretPayload = { apiKey: 'user-google-key' };
98
101
  const runtime = await initAgentRuntimeWithUserPayload(ModelProvider.Google, jwtPayload);
99
102
  expect(runtime).toBeInstanceOf(AgentRuntime);
100
103
  expect(runtime['_runtime']).toBeInstanceOf(LobeGoogleAI);
101
104
  });
102
105
 
103
106
  it('Moonshot AI provider: with apikey', async () => {
104
- const jwtPayload: JWTPayload = { apiKey: 'user-moonshot-key' };
107
+ const jwtPayload: ClientSecretPayload = { apiKey: 'user-moonshot-key' };
105
108
  const runtime = await initAgentRuntimeWithUserPayload(ModelProvider.Moonshot, jwtPayload);
106
109
  expect(runtime).toBeInstanceOf(AgentRuntime);
107
110
  expect(runtime['_runtime']).toBeInstanceOf(LobeMoonshotAI);
108
111
  });
109
112
 
110
113
  it('Qwen AI provider: with apikey', async () => {
111
- const jwtPayload: JWTPayload = { apiKey: 'user-qwen-key' };
114
+ const jwtPayload: ClientSecretPayload = { apiKey: 'user-qwen-key' };
112
115
  const runtime = await initAgentRuntimeWithUserPayload(ModelProvider.Qwen, jwtPayload);
113
116
  expect(runtime).toBeInstanceOf(AgentRuntime);
114
117
  expect(runtime['_runtime']).toBeInstanceOf(LobeQwenAI);
115
118
  });
116
119
 
117
120
  it('Bedrock AI provider: with apikey, awsAccessKeyId, awsSecretAccessKey, awsRegion', async () => {
118
- const jwtPayload: JWTPayload = {
121
+ const jwtPayload: ClientSecretPayload = {
119
122
  apiKey: 'user-bedrock-key',
120
123
  awsAccessKeyId: 'user-aws-id',
121
124
  awsSecretAccessKey: 'user-aws-secret',
@@ -127,7 +130,7 @@ describe('initAgentRuntimeWithUserPayload method', () => {
127
130
  });
128
131
 
129
132
  it('Ollama provider: with endpoint', async () => {
130
- const jwtPayload: JWTPayload = { baseURL: 'http://user-ollama-url' };
133
+ const jwtPayload: ClientSecretPayload = { baseURL: 'http://user-ollama-url' };
131
134
  const runtime = await initAgentRuntimeWithUserPayload(ModelProvider.Ollama, jwtPayload);
132
135
  expect(runtime).toBeInstanceOf(AgentRuntime);
133
136
  expect(runtime['_runtime']).toBeInstanceOf(LobeOllamaAI);
@@ -135,49 +138,49 @@ describe('initAgentRuntimeWithUserPayload method', () => {
135
138
  });
136
139
 
137
140
  it('Perplexity AI provider: with apikey', async () => {
138
- const jwtPayload: JWTPayload = { apiKey: 'user-perplexity-key' };
141
+ const jwtPayload: ClientSecretPayload = { apiKey: 'user-perplexity-key' };
139
142
  const runtime = await initAgentRuntimeWithUserPayload(ModelProvider.Perplexity, jwtPayload);
140
143
  expect(runtime).toBeInstanceOf(AgentRuntime);
141
144
  expect(runtime['_runtime']).toBeInstanceOf(LobePerplexityAI);
142
145
  });
143
146
 
144
147
  it('Anthropic AI provider: with apikey', async () => {
145
- const jwtPayload: JWTPayload = { apiKey: 'user-anthropic-key' };
148
+ const jwtPayload: ClientSecretPayload = { apiKey: 'user-anthropic-key' };
146
149
  const runtime = await initAgentRuntimeWithUserPayload(ModelProvider.Anthropic, jwtPayload);
147
150
  expect(runtime).toBeInstanceOf(AgentRuntime);
148
151
  expect(runtime['_runtime']).toBeInstanceOf(LobeAnthropicAI);
149
152
  });
150
153
 
151
154
  it('Minimax AI provider: with apikey', async () => {
152
- const jwtPayload: JWTPayload = { apiKey: 'user-minimax-key' };
155
+ const jwtPayload: ClientSecretPayload = { apiKey: 'user-minimax-key' };
153
156
  const runtime = await initAgentRuntimeWithUserPayload(ModelProvider.Minimax, jwtPayload);
154
157
  expect(runtime).toBeInstanceOf(AgentRuntime);
155
158
  expect(runtime['_runtime']).toBeInstanceOf(LobeMinimaxAI);
156
159
  });
157
160
 
158
161
  it('Mistral AI provider: with apikey', async () => {
159
- const jwtPayload: JWTPayload = { apiKey: 'user-mistral-key' };
162
+ const jwtPayload: ClientSecretPayload = { apiKey: 'user-mistral-key' };
160
163
  const runtime = await initAgentRuntimeWithUserPayload(ModelProvider.Mistral, jwtPayload);
161
164
  expect(runtime).toBeInstanceOf(AgentRuntime);
162
165
  expect(runtime['_runtime']).toBeInstanceOf(LobeMistralAI);
163
166
  });
164
167
 
165
168
  it('OpenRouter AI provider: with apikey', async () => {
166
- const jwtPayload: JWTPayload = { apiKey: 'user-openrouter-key' };
169
+ const jwtPayload: ClientSecretPayload = { apiKey: 'user-openrouter-key' };
167
170
  const runtime = await initAgentRuntimeWithUserPayload(ModelProvider.OpenRouter, jwtPayload);
168
171
  expect(runtime).toBeInstanceOf(AgentRuntime);
169
172
  expect(runtime['_runtime']).toBeInstanceOf(LobeOpenRouterAI);
170
173
  });
171
174
 
172
175
  it('DeepSeek AI provider: with apikey', async () => {
173
- const jwtPayload: JWTPayload = { apiKey: 'user-deepseek-key' };
176
+ const jwtPayload: ClientSecretPayload = { apiKey: 'user-deepseek-key' };
174
177
  const runtime = await initAgentRuntimeWithUserPayload(ModelProvider.DeepSeek, jwtPayload);
175
178
  expect(runtime).toBeInstanceOf(AgentRuntime);
176
179
  expect(runtime['_runtime']).toBeInstanceOf(LobeDeepSeekAI);
177
180
  });
178
181
 
179
182
  it('Together AI provider: with apikey', async () => {
180
- const jwtPayload: JWTPayload = { apiKey: 'user-togetherai-key' };
183
+ const jwtPayload: ClientSecretPayload = { apiKey: 'user-togetherai-key' };
181
184
  const runtime = await initAgentRuntimeWithUserPayload(ModelProvider.TogetherAI, jwtPayload);
182
185
  expect(runtime).toBeInstanceOf(AgentRuntime);
183
186
  expect(runtime['_runtime']).toBeInstanceOf(LobeTogetherAI);
@@ -205,7 +208,7 @@ describe('initAgentRuntimeWithUserPayload method', () => {
205
208
  });
206
209
 
207
210
  it('Unknown Provider: with apikey and endpoint, should initialize to OpenAi', async () => {
208
- const jwtPayload: JWTPayload = {
211
+ const jwtPayload: ClientSecretPayload = {
209
212
  apiKey: 'user-unknown-key',
210
213
  baseURL: 'user-unknown-endpoint',
211
214
  };
@@ -218,13 +221,13 @@ describe('initAgentRuntimeWithUserPayload method', () => {
218
221
 
219
222
  describe('should initialize without some options', () => {
220
223
  it('OpenAI provider: without apikey', async () => {
221
- const jwtPayload: JWTPayload = {};
224
+ const jwtPayload: ClientSecretPayload = {};
222
225
  const runtime = await initAgentRuntimeWithUserPayload(ModelProvider.OpenAI, jwtPayload);
223
226
  expect(runtime['_runtime']).toBeInstanceOf(LobeOpenAI);
224
227
  });
225
228
 
226
229
  it('Azure AI Provider: without apikey', async () => {
227
- const jwtPayload: JWTPayload = {
230
+ const jwtPayload: ClientSecretPayload = {
228
231
  azureApiVersion: 'test-azure-api-version',
229
232
  };
230
233
  const runtime = await initAgentRuntimeWithUserPayload(ModelProvider.Azure, jwtPayload);
@@ -233,7 +236,7 @@ describe('initAgentRuntimeWithUserPayload method', () => {
233
236
  });
234
237
 
235
238
  it('ZhiPu AI provider: without apikey', async () => {
236
- const jwtPayload: JWTPayload = {};
239
+ const jwtPayload: ClientSecretPayload = {};
237
240
  const runtime = await initAgentRuntimeWithUserPayload(ModelProvider.ZhiPu, jwtPayload);
238
241
 
239
242
  // 假设 LobeZhipuAI 是 ZhiPu 提供者的实现类
@@ -248,7 +251,7 @@ describe('initAgentRuntimeWithUserPayload method', () => {
248
251
  });
249
252
 
250
253
  it('Moonshot AI provider: without apikey', async () => {
251
- const jwtPayload: JWTPayload = {};
254
+ const jwtPayload: ClientSecretPayload = {};
252
255
  const runtime = await initAgentRuntimeWithUserPayload(ModelProvider.Moonshot, jwtPayload);
253
256
 
254
257
  // 假设 LobeMoonshotAI 是 Moonshot 提供者的实现类
@@ -256,7 +259,7 @@ describe('initAgentRuntimeWithUserPayload method', () => {
256
259
  });
257
260
 
258
261
  it('Qwen AI provider: without apikey', async () => {
259
- const jwtPayload: JWTPayload = {};
262
+ const jwtPayload: ClientSecretPayload = {};
260
263
  const runtime = await initAgentRuntimeWithUserPayload(ModelProvider.Qwen, jwtPayload);
261
264
 
262
265
  // 假设 LobeQwenAI 是 Qwen 提供者的实现类
@@ -264,7 +267,7 @@ describe('initAgentRuntimeWithUserPayload method', () => {
264
267
  });
265
268
 
266
269
  it('Qwen AI provider: without endpoint', async () => {
267
- const jwtPayload: JWTPayload = { apiKey: 'user-qwen-key' };
270
+ const jwtPayload: ClientSecretPayload = { apiKey: 'user-qwen-key' };
268
271
  const runtime = await initAgentRuntimeWithUserPayload(ModelProvider.Qwen, jwtPayload);
269
272
 
270
273
  // 假设 LobeQwenAI 是 Qwen 提供者的实现类
@@ -356,7 +359,7 @@ describe('initAgentRuntimeWithUserPayload method', () => {
356
359
  it('OpenAI provider: without apikey with OPENAI_PROXY_URL', async () => {
357
360
  process.env.OPENAI_PROXY_URL = 'https://proxy.example.com/v1';
358
361
 
359
- const jwtPayload: JWTPayload = {};
362
+ const jwtPayload: ClientSecretPayload = {};
360
363
  const runtime = await initAgentRuntimeWithUserPayload(ModelProvider.OpenAI, jwtPayload);
361
364
  expect(runtime['_runtime']).toBeInstanceOf(LobeOpenAI);
362
365
  // 应返回 OPENAI_PROXY_URL
@@ -366,7 +369,7 @@ describe('initAgentRuntimeWithUserPayload method', () => {
366
369
  it('Qwen AI provider: without apiKey and endpoint with OPENAI_PROXY_URL', async () => {
367
370
  process.env.OPENAI_PROXY_URL = 'https://proxy.example.com/v1';
368
371
 
369
- const jwtPayload: JWTPayload = {};
372
+ const jwtPayload: ClientSecretPayload = {};
370
373
  const runtime = await initAgentRuntimeWithUserPayload(ModelProvider.Qwen, jwtPayload);
371
374
 
372
375
  // 假设 LobeQwenAI 是 Qwen 提供者的实现类
@@ -1,5 +1,5 @@
1
1
  import { getLLMConfig } from '@/config/llm';
2
- import { JWTPayload } from '@/const/auth';
2
+ import { ClientSecretPayload } from '@/const/auth';
3
3
  import { AgentRuntime, ModelProvider } from '@/libs/model-runtime';
4
4
 
5
5
  import apiKeyManager from './apiKeyManager';
@@ -14,7 +14,7 @@ export * from './trace';
14
14
  * @param payload - The JWT payload.
15
15
  * @returns The options object.
16
16
  */
17
- const getParamsFromPayload = (provider: string, payload: JWTPayload) => {
17
+ const getParamsFromPayload = (provider: string, payload: ClientSecretPayload) => {
18
18
  const llmConfig = getLLMConfig() as Record<string, any>;
19
19
 
20
20
  switch (provider) {
@@ -115,7 +115,7 @@ const getParamsFromPayload = (provider: string, payload: JWTPayload) => {
115
115
  */
116
116
  export const initAgentRuntimeWithUserPayload = (
117
117
  provider: string,
118
- payload: JWTPayload,
118
+ payload: ClientSecretPayload,
119
119
  params: any = {},
120
120
  ) => {
121
121
  return AgentRuntime.initializeWithProvider(provider, {
@@ -3,7 +3,7 @@ import superjson from 'superjson';
3
3
  import urlJoin from 'url-join';
4
4
 
5
5
  import { serverDBEnv } from '@/config/db';
6
- import { JWTPayload, LOBE_CHAT_AUTH_HEADER } from '@/const/auth';
6
+ import { ClientSecretPayload, LOBE_CHAT_AUTH_HEADER } from '@/const/auth';
7
7
  import { isDesktop } from '@/const/version';
8
8
  import { appEnv } from '@/envs/app';
9
9
  import { createAsyncCallerFactory } from '@/libs/trpc/async';
@@ -13,7 +13,7 @@ import { KeyVaultsGateKeeper } from '@/server/modules/KeyVaultsEncrypt';
13
13
  import { asyncRouter } from './index';
14
14
  import type { AsyncRouter } from './index';
15
15
 
16
- export const createAsyncServerClient = async (userId: string, payload: JWTPayload) => {
16
+ export const createAsyncServerClient = async (userId: string, payload: ClientSecretPayload) => {
17
17
  const gateKeeper = await KeyVaultsGateKeeper.initWithEnvKey();
18
18
  const headers: Record<string, string> = {
19
19
  Authorization: `Bearer ${serverDBEnv.KEY_VAULTS_SECRET}`,
@@ -173,20 +173,6 @@ export const marketRouter = router({
173
173
  }
174
174
  }),
175
175
 
176
- getMcpIdentifiers: marketProcedure.query(async ({ ctx }) => {
177
- log('getMcpIdentifiers called');
178
-
179
- try {
180
- return await ctx.discoverService.getMcpIdentifiers();
181
- } catch (error) {
182
- log('Error fetching mcp identifiers: %O', error);
183
- throw new TRPCError({
184
- code: 'INTERNAL_SERVER_ERROR',
185
- message: 'Failed to fetch mcp identifiers',
186
- });
187
- }
188
- }),
189
-
190
176
  getMcpList: marketProcedure
191
177
  .input(
192
178
  z
@@ -9,8 +9,8 @@ import { SEARCH_SEARXNG_NOT_CONFIG } from '@/types/tool/search';
9
9
  import { searchRouter } from './search';
10
10
 
11
11
  // Mock JWT verification
12
- vi.mock('@/utils/server/jwt', () => ({
13
- getJWTPayload: vi.fn().mockResolvedValue({ userId: '1' }),
12
+ vi.mock('@/utils/server/xor', () => ({
13
+ getXorPayload: vi.fn().mockReturnValue({ userId: '1' }),
14
14
  }));
15
15
 
16
16
  vi.mock('@lobechat/web-crawler', () => ({
@@ -1,4 +1,4 @@
1
- import { JWTPayload } from '@/const/auth';
1
+ import { ClientSecretPayload } from '@/const/auth';
2
2
  import { AsyncTaskModel } from '@/database/models/asyncTask';
3
3
  import { FileModel } from '@/database/models/file';
4
4
  import { serverDB } from '@/database/server';
@@ -30,7 +30,7 @@ export class ChunkService {
30
30
  return this.chunkClient.chunkContent(params);
31
31
  }
32
32
 
33
- async asyncEmbeddingFileChunks(fileId: string, payload: JWTPayload) {
33
+ async asyncEmbeddingFileChunks(fileId: string, payload: ClientSecretPayload) {
34
34
  const result = await this.fileModel.findById(fileId);
35
35
 
36
36
  if (!result) return;
@@ -66,7 +66,7 @@ export class ChunkService {
66
66
  /**
67
67
  * parse file to chunks with async task
68
68
  */
69
- async asyncParseFileToChunks(fileId: string, payload: JWTPayload, skipExist?: boolean) {
69
+ async asyncParseFileToChunks(fileId: string, payload: ClientSecretPayload, skipExist?: boolean) {
70
70
  const result = await this.fileModel.findById(fileId);
71
71
 
72
72
  if (!result) return;
@@ -462,19 +462,6 @@ export class DiscoverService {
462
462
  return result;
463
463
  };
464
464
 
465
- getMcpIdentifiers = async (): Promise<IdentifiersResponse> => {
466
- log('getMcpIdentifiers: fetching identifiers');
467
- const result = await this.market.plugins.getPublishedIdentifiers({
468
- cache: 'force-cache',
469
- next: {
470
- revalidate: CacheRevalidate.List,
471
- tags: [CacheTag.Discover, CacheTag.MCP],
472
- },
473
- });
474
- log('getMcpIdentifiers: returning %d identifiers', result.length);
475
- return result;
476
- };
477
-
478
465
  getMcpList = async (params: McpQueryParams = {}): Promise<McpListResponse> => {
479
466
  log('getMcpList: params=%O', params);
480
467
  const { locale } = params;
@@ -13,7 +13,6 @@ describe('Sitemap', () => {
13
13
  // Mock the page count methods to return specific values for testing
14
14
  vi.spyOn(sitemap, 'getPluginPageCount').mockResolvedValue(2);
15
15
  vi.spyOn(sitemap, 'getAssistantPageCount').mockResolvedValue(3);
16
- vi.spyOn(sitemap, 'getMcpPageCount').mockResolvedValue(1);
17
16
  vi.spyOn(sitemap, 'getModelPageCount').mockResolvedValue(2);
18
17
 
19
18
  const index = await sitemap.getIndex();
@@ -31,7 +30,6 @@ describe('Sitemap', () => {
31
30
  expect(index).toContain(`<loc>${getCanonicalUrl('/sitemap/assistants-1.xml')}</loc>`);
32
31
  expect(index).toContain(`<loc>${getCanonicalUrl('/sitemap/assistants-2.xml')}</loc>`);
33
32
  expect(index).toContain(`<loc>${getCanonicalUrl('/sitemap/assistants-3.xml')}</loc>`);
34
- expect(index).toContain(`<loc>${getCanonicalUrl('/sitemap/mcp-1.xml')}</loc>`);
35
33
  expect(index).toContain(`<loc>${getCanonicalUrl('/sitemap/models-1.xml')}</loc>`);
36
34
  expect(index).toContain(`<loc>${getCanonicalUrl('/sitemap/models-2.xml')}</loc>`);
37
35
 
@@ -218,46 +216,6 @@ describe('Sitemap', () => {
218
216
  });
219
217
  });
220
218
 
221
- describe('getMcp', () => {
222
- it('should return a valid mcp sitemap without pagination', async () => {
223
- vi.spyOn(sitemap['discoverService'], 'getMcpIdentifiers').mockResolvedValue([
224
- // @ts-ignore
225
- { identifier: 'test-mcp', lastModified: '2023-01-01' },
226
- ]);
227
-
228
- const mcpSitemap = await sitemap.getMcp();
229
- expect(mcpSitemap.length).toBe(15);
230
- expect(mcpSitemap).toContainEqual(
231
- expect.objectContaining({
232
- url: getCanonicalUrl('/discover/mcp/test-mcp'),
233
- lastModified: '2023-01-01T00:00:00.000Z',
234
- }),
235
- );
236
- expect(mcpSitemap).toContainEqual(
237
- expect.objectContaining({
238
- url: getCanonicalUrl('/discover/mcp/test-mcp?hl=zh-CN'),
239
- lastModified: '2023-01-01T00:00:00.000Z',
240
- }),
241
- );
242
- });
243
-
244
- it('should return a valid mcp sitemap with pagination', async () => {
245
- const mockMcps = Array.from({ length: 80 }, (_, i) => ({
246
- identifier: `test-mcp-${i}`,
247
- lastModified: '2023-01-01',
248
- }));
249
-
250
- vi.spyOn(sitemap['discoverService'], 'getMcpIdentifiers').mockResolvedValue(
251
- // @ts-ignore
252
- mockMcps,
253
- );
254
-
255
- // Test first page (should have 80 items, all on first page)
256
- const firstPageSitemap = await sitemap.getMcp(1);
257
- expect(firstPageSitemap.length).toBe(80 * 15); // 80 items * 15 locales
258
- });
259
- });
260
-
261
219
  describe('getProviders', () => {
262
220
  it('should return a valid providers sitemap', async () => {
263
221
  vi.spyOn(sitemap['discoverService'], 'getProviderIdentifiers').mockResolvedValue([
@@ -303,16 +261,6 @@ describe('Sitemap', () => {
303
261
  expect(pageCount).toBe(3); // 250 items / 100 per page = ceil(2.5) = 3 pages
304
262
  });
305
263
 
306
- it('should return correct mcp page count', async () => {
307
- vi.spyOn(sitemap['discoverService'], 'getMcpIdentifiers').mockResolvedValue(
308
- // @ts-ignore
309
- Array.from({ length: 50 }, (_, i) => ({ identifier: `mcp-${i}` })),
310
- );
311
-
312
- const pageCount = await sitemap.getMcpPageCount();
313
- expect(pageCount).toBe(1); // 50 items / 100 per page = 1 page
314
- });
315
-
316
264
  it('should return correct model page count', async () => {
317
265
  vi.spyOn(sitemap['discoverService'], 'getModelIdentifiers').mockResolvedValue(
318
266
  // @ts-ignore
@@ -52,12 +52,6 @@ export class Sitemap {
52
52
  return Math.ceil(list.length / ITEMS_PER_PAGE);
53
53
  }
54
54
 
55
- // 获取MCP总页数
56
- async getMcpPageCount(): Promise<number> {
57
- const list = await this.discoverService.getMcpIdentifiers();
58
- return Math.ceil(list.length / ITEMS_PER_PAGE);
59
- }
60
-
61
55
  // 获取模型总页数
62
56
  async getModelPageCount(): Promise<number> {
63
57
  const list = await this.discoverService.getModelIdentifiers();
@@ -171,10 +165,9 @@ export class Sitemap {
171
165
  );
172
166
 
173
167
  // 获取需要分页的类型的页数
174
- const [pluginPages, assistantPages, mcpPages, modelPages] = await Promise.all([
168
+ const [pluginPages, assistantPages, modelPages] = await Promise.all([
175
169
  this.getPluginPageCount(),
176
170
  this.getAssistantPageCount(),
177
- this.getMcpPageCount(),
178
171
  this.getModelPageCount(),
179
172
  ]);
180
173
 
@@ -193,11 +186,6 @@ export class Sitemap {
193
186
  ),
194
187
  ),
195
188
  ),
196
- ...Array.from({ length: mcpPages }, (_, i) =>
197
- this._generateSitemapLink(
198
- getCanonicalUrl(SITEMAP_BASE_URL, isDev ? `mcp-${i + 1}` : `mcp-${i + 1}.xml`),
199
- ),
200
- ),
201
189
  ...Array.from({ length: modelPages }, (_, i) =>
202
190
  this._generateSitemapLink(
203
191
  getCanonicalUrl(SITEMAP_BASE_URL, isDev ? `models-${i + 1}` : `models-${i + 1}.xml`),
@@ -239,31 +227,6 @@ export class Sitemap {
239
227
  return flatten(sitmap);
240
228
  }
241
229
 
242
- async getMcp(page?: number): Promise<MetadataRoute.Sitemap> {
243
- const list = await this.discoverService.getMcpIdentifiers();
244
-
245
- if (page !== undefined) {
246
- const startIndex = (page - 1) * ITEMS_PER_PAGE;
247
- const endIndex = startIndex + ITEMS_PER_PAGE;
248
- const pageMcps = list.slice(startIndex, endIndex);
249
-
250
- const sitmap = pageMcps.map((item) =>
251
- this._genSitemap(urlJoin('/discover/mcp', item.identifier), {
252
- lastModified: item?.lastModified || LAST_MODIFIED,
253
- }),
254
- );
255
- return flatten(sitmap);
256
- }
257
-
258
- // 如果没有指定页数,返回所有(向后兼容)
259
- const sitmap = list.map((item) =>
260
- this._genSitemap(urlJoin('/discover/mcp', item.identifier), {
261
- lastModified: item?.lastModified || LAST_MODIFIED,
262
- }),
263
- );
264
- return flatten(sitmap);
265
- }
266
-
267
230
  async getPlugins(page?: number): Promise<MetadataRoute.Sitemap> {
268
231
  const list = await this.discoverService.getPluginIdentifiers();
269
232
 
@@ -1,4 +1,4 @@
1
- import { JWTPayload, LOBE_CHAT_AUTH_HEADER } from '@/const/auth';
1
+ import { ClientSecretPayload, LOBE_CHAT_AUTH_HEADER } from '@/const/auth';
2
2
  import { isDeprecatedEdition } from '@/const/version';
3
3
  import { ModelProvider } from '@/libs/model-runtime';
4
4
  import { aiProviderSelectors, useAiInfraStore } from '@/store/aiInfra';
@@ -10,7 +10,7 @@ import {
10
10
  CloudflareKeyVault,
11
11
  OpenAICompatibleKeyVault,
12
12
  } from '@/types/user/settings';
13
- import { createJWT } from '@/utils/jwt';
13
+ import { obfuscatePayloadWithXOR } from '@/utils/client/xor-obfuscation';
14
14
 
15
15
  export const getProviderAuthPayload = (
16
16
  provider: string,
@@ -80,7 +80,7 @@ const createAuthTokenWithPayload = async (payload = {}) => {
80
80
  const accessCode = keyVaultsConfigSelectors.password(useUserStore.getState());
81
81
  const userId = userProfileSelectors.userId(useUserStore.getState());
82
82
 
83
- return createJWT<JWTPayload>({ accessCode, userId, ...payload });
83
+ return obfuscatePayloadWithXOR<ClientSecretPayload>({ accessCode, userId, ...payload });
84
84
  };
85
85
 
86
86
  interface AuthParams {
@@ -83,10 +83,6 @@ class DiscoverService {
83
83
  });
84
84
  };
85
85
 
86
- getMcpIdentifiers = async (): Promise<IdentifiersResponse> => {
87
- return lambdaClient.market.getMcpIdentifiers.query();
88
- };
89
-
90
86
  getMcpList = async (params: McpQueryParams = {}): Promise<McpListResponse> => {
91
87
  const locale = globalHelpers.getCurrentLanguage();
92
88
  return lambdaClient.market.getMcpList.query({
@@ -8,7 +8,6 @@ import { DiscoverStore } from '@/store/discover';
8
8
  import { globalHelpers } from '@/store/global/helpers';
9
9
  import {
10
10
  DiscoverMcpDetail,
11
- IdentifiersResponse,
12
11
  McpListResponse,
13
12
  McpQueryParams,
14
13
  } from '@/types/discover';
@@ -20,7 +19,6 @@ export interface MCPAction {
20
19
  }) => SWRResponse<DiscoverMcpDetail>;
21
20
  useFetchMcpList: (params: McpQueryParams) => SWRResponse<McpListResponse>;
22
21
  useMcpCategories: (params: CategoryListQuery) => SWRResponse<CategoryItem[]>;
23
- useMcpIdentifiers: () => SWRResponse<IdentifiersResponse>;
24
22
  }
25
23
 
26
24
  export const createMCPSlice: StateCreator<
@@ -61,10 +59,4 @@ export const createMCPSlice: StateCreator<
61
59
  },
62
60
  );
63
61
  },
64
-
65
- useMcpIdentifiers: () => {
66
- return useClientDataSWR('mcp-identifiers', async () => discoverService.getMcpIdentifiers(), {
67
- revalidateOnFocus: false,
68
- });
69
- },
70
62
  });