@lobehub/chat 1.105.1 → 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 (60) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/changelog/v1.json +9 -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/siliconcloud.ts +24 -2
  29. package/src/config/aiModels/stepfun.ts +67 -2
  30. package/src/config/aiModels/volcengine.ts +56 -2
  31. package/src/config/aiModels/wenxin.ts +62 -2
  32. package/src/config/aiModels/xai.ts +19 -2
  33. package/src/const/auth.ts +2 -3
  34. package/src/libs/model-runtime/ModelRuntime.test.ts +3 -3
  35. package/src/libs/trpc/async/context.ts +3 -3
  36. package/src/libs/trpc/edge/context.ts +7 -2
  37. package/src/libs/trpc/edge/middleware/jwtPayload.test.ts +4 -4
  38. package/src/libs/trpc/edge/middleware/jwtPayload.ts +2 -2
  39. package/src/libs/trpc/lambda/context.ts +2 -2
  40. package/src/libs/trpc/lambda/middleware/keyVaults.ts +2 -2
  41. package/src/server/modules/AgentRuntime/index.test.ts +28 -25
  42. package/src/server/modules/AgentRuntime/index.ts +3 -3
  43. package/src/server/routers/async/caller.ts +2 -2
  44. package/src/server/routers/lambda/market/index.ts +0 -14
  45. package/src/server/routers/tools/search.test.ts +2 -2
  46. package/src/server/services/chunk/index.ts +3 -3
  47. package/src/server/services/discover/index.ts +0 -13
  48. package/src/server/sitemap.test.ts +0 -52
  49. package/src/server/sitemap.ts +1 -38
  50. package/src/services/_auth.ts +3 -3
  51. package/src/services/discover.ts +0 -4
  52. package/src/store/discover/slices/mcp/action.ts +0 -8
  53. package/src/utils/client/xor-obfuscation.test.ts +370 -0
  54. package/src/utils/client/xor-obfuscation.ts +39 -0
  55. package/src/utils/server/xor.test.ts +123 -0
  56. package/src/utils/server/xor.ts +42 -0
  57. package/src/utils/jwt.test.ts +0 -27
  58. package/src/utils/jwt.ts +0 -37
  59. package/src/utils/server/jwt.test.ts +0 -62
  60. package/src/utils/server/jwt.ts +0 -28
@@ -1,4 +1,4 @@
1
- import { AIChatModelCard } from '@/types/aiModel';
1
+ import { AIChatModelCard, AIImageModelCard } from '@/types/aiModel';
2
2
 
3
3
  const wenxinChatModels: AIChatModelCard[] = [
4
4
  {
@@ -564,6 +564,66 @@ const wenxinChatModels: AIChatModelCard[] = [
564
564
  },
565
565
  ];
566
566
 
567
- export const allModels = [...wenxinChatModels];
567
+ const wenxinImageModels: AIImageModelCard[] = [
568
+ {
569
+ description:
570
+ '百度自研的iRAG(image based RAG),检索增强的文生图技术,将百度搜索的亿级图片资源跟强大的基础模型能力相结合,就可以生成各种超真实的图片,整体效果远远超过文生图原生系统,去掉了AI味儿,而且成本很低。iRAG具备无幻觉、超真实、立等可取等特点。',
571
+ displayName: 'ERNIE iRAG',
572
+ enabled: true,
573
+ id: 'irag-1.0',
574
+ parameters: {
575
+ prompt: {
576
+ default: '',
577
+ },
578
+ size: {
579
+ default: '1024x1024',
580
+ enum: ['768x768', '1024x1024', '1536x1536', '2048x2048', '1024x768', '2048x1536', '768x1024', '1536x2048', '1024x576', '2048x1152', '576x1024', '1152x2048'],
581
+ },
582
+ },
583
+ releasedAt: '2025-02-05',
584
+ type: 'image',
585
+ },
586
+ {
587
+ description:
588
+ '百度自研的ERNIE iRAG Edit图像编辑模型支持基于图片进行erase(消除对象)、repaint(重绘对象)、variation(生成变体)等操作。',
589
+ displayName: 'ERNIE iRAG Edit',
590
+ enabled: true,
591
+ id: 'ernie-irag-edit',
592
+ parameters: {
593
+ imageUrl: { default: null },
594
+ prompt: {
595
+ default: '',
596
+ },
597
+ size: {
598
+ default: '1024x1024',
599
+ enum: ['768x768', '1024x1024', '1536x1536', '2048x2048', '1024x768', '2048x1536', '768x1024', '1536x2048', '1024x576', '2048x1152', '576x1024', '1152x2048'],
600
+ },
601
+ },
602
+ releasedAt: '2025-04-17',
603
+ type: 'image',
604
+ },
605
+ {
606
+ description:
607
+ '具有120亿参数的修正流变换器,能够根据文本描述生成图像。',
608
+ displayName: 'FLUX.1-schnell',
609
+ enabled: true,
610
+ id: 'flux.1-schnell',
611
+ parameters: {
612
+ prompt: {
613
+ default: '',
614
+ },
615
+ seed: { default: null },
616
+ size: {
617
+ default: '1024x1024',
618
+ enum: ['768x768', '1024x1024', '1536x1536', '2048x2048', '1024x768', '2048x1536', '768x1024', '1536x2048', '1024x576', '2048x1152', '576x1024', '1152x2048'],
619
+ },
620
+ steps: { default: 25, max: 50, min: 1 },
621
+ },
622
+ releasedAt: '2025-03-27',
623
+ type: 'image',
624
+ },
625
+ ];
626
+
627
+ export const allModels = [...wenxinChatModels, ...wenxinImageModels];
568
628
 
569
629
  export default allModels;
@@ -1,4 +1,4 @@
1
- import { AIChatModelCard } from '@/types/aiModel';
1
+ import { AIChatModelCard, AIImageModelCard } from '@/types/aiModel';
2
2
 
3
3
  // https://docs.x.ai/docs/models
4
4
  const xaiChatModels: AIChatModelCard[] = [
@@ -158,6 +158,23 @@ const xaiChatModels: AIChatModelCard[] = [
158
158
  },
159
159
  ];
160
160
 
161
- export const allModels = [...xaiChatModels];
161
+ const xaiImageModels: AIImageModelCard[] = [
162
+ {
163
+ description:
164
+ '我们最新的图像生成模型可以根据文本提示生成生动逼真的图像。它在营销、社交媒体和娱乐等领域的图像生成方面表现出色。',
165
+ displayName: 'Grok 2 Image 1212',
166
+ enabled: true,
167
+ id: 'grok-2-image-1212',
168
+ parameters: {
169
+ prompt: {
170
+ default: '',
171
+ },
172
+ },
173
+ releasedAt: '2024-12-12',
174
+ type: 'image',
175
+ },
176
+ ];
177
+
178
+ export const allModels = [...xaiChatModels, ...xaiImageModels];
162
179
 
163
180
  export default allModels;
package/src/const/auth.ts CHANGED
@@ -9,11 +9,10 @@ export const LOBE_CHAT_OIDC_AUTH_HEADER = 'Oidc-Auth';
9
9
 
10
10
  export const OAUTH_AUTHORIZED = 'X-oauth-authorized';
11
11
 
12
- export const JWT_SECRET_KEY = 'LobeHub · LobeChat';
13
- export const NON_HTTP_PREFIX = 'http_nosafe';
12
+ export const SECRET_XOR_KEY = 'LobeHub · LobeHub';
14
13
 
15
14
  /* eslint-disable typescript-sort-keys/interface */
16
- export interface JWTPayload {
15
+ export interface ClientSecretPayload {
17
16
  /**
18
17
  * password
19
18
  */
@@ -4,7 +4,7 @@ import { LangfuseGenerationClient, LangfuseTraceClient } from 'langfuse-core';
4
4
  import { beforeEach, describe, expect, it, vi } from 'vitest';
5
5
 
6
6
  import * as langfuseCfg from '@/config/langfuse';
7
- import { JWTPayload } from '@/const/auth';
7
+ import { ClientSecretPayload } from '@/const/auth';
8
8
  import { TraceNameMap } from '@/const/trace';
9
9
  import { AgentRuntime, ChatStreamPayload, LobeOpenAI, ModelProvider } from '@/libs/model-runtime';
10
10
  import { providerRuntimeMap } from '@/libs/model-runtime/runtimeMap';
@@ -51,7 +51,7 @@ const specialProviders = [
51
51
  const testRuntime = (providerId: string, payload?: any) => {
52
52
  describe(`${providerId} provider runtime`, () => {
53
53
  it('should initialize correctly', async () => {
54
- const jwtPayload: JWTPayload = { apiKey: 'user-key', ...payload };
54
+ const jwtPayload: ClientSecretPayload = { apiKey: 'user-key', ...payload };
55
55
  const runtime = await AgentRuntime.initializeWithProvider(providerId, jwtPayload);
56
56
 
57
57
  // @ts-ignore
@@ -66,7 +66,7 @@ const testRuntime = (providerId: string, payload?: any) => {
66
66
 
67
67
  let mockModelRuntime: AgentRuntime;
68
68
  beforeEach(async () => {
69
- const jwtPayload: JWTPayload = { apiKey: 'user-openai-key', baseURL: 'user-endpoint' };
69
+ const jwtPayload: ClientSecretPayload = { apiKey: 'user-openai-key', baseURL: 'user-endpoint' };
70
70
  mockModelRuntime = await AgentRuntime.initializeWithProvider(ModelProvider.OpenAI, jwtPayload);
71
71
  });
72
72
 
@@ -1,14 +1,14 @@
1
1
  import debug from 'debug';
2
2
  import { NextRequest } from 'next/server';
3
3
 
4
- import { JWTPayload, LOBE_CHAT_AUTH_HEADER } from '@/const/auth';
4
+ import { ClientSecretPayload, LOBE_CHAT_AUTH_HEADER } from '@/const/auth';
5
5
  import { LobeChatDatabase } from '@/database/type';
6
6
  import { KeyVaultsGateKeeper } from '@/server/modules/KeyVaultsEncrypt';
7
7
 
8
8
  const log = debug('lobe-async:context');
9
9
 
10
10
  export interface AsyncAuthContext {
11
- jwtPayload: JWTPayload;
11
+ jwtPayload: ClientSecretPayload;
12
12
  secret: string;
13
13
  serverDB?: LobeChatDatabase;
14
14
  userId?: string | null;
@@ -19,7 +19,7 @@ export interface AsyncAuthContext {
19
19
  * This is useful for testing when we don't want to mock Next.js' request/response
20
20
  */
21
21
  export const createAsyncContextInner = async (params?: {
22
- jwtPayload?: JWTPayload;
22
+ jwtPayload?: ClientSecretPayload;
23
23
  secret?: string;
24
24
  userId?: string | null;
25
25
  }): Promise<AsyncAuthContext> => ({
@@ -1,13 +1,18 @@
1
1
  import { User } from 'next-auth';
2
2
  import { NextRequest } from 'next/server';
3
3
 
4
- import { JWTPayload, LOBE_CHAT_AUTH_HEADER, enableClerk, enableNextAuth } from '@/const/auth';
4
+ import {
5
+ ClientSecretPayload,
6
+ LOBE_CHAT_AUTH_HEADER,
7
+ enableClerk,
8
+ enableNextAuth,
9
+ } from '@/const/auth';
5
10
  import { ClerkAuth, IClerkAuth } from '@/libs/clerk-auth';
6
11
 
7
12
  export interface AuthContext {
8
13
  authorizationHeader?: string | null;
9
14
  clerkAuth?: IClerkAuth;
10
- jwtPayload?: JWTPayload | null;
15
+ jwtPayload?: ClientSecretPayload | null;
11
16
  nextAuth?: User;
12
17
  userId?: string | null;
13
18
  }
@@ -5,7 +5,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest';
5
5
  import { createCallerFactory } from '@/libs/trpc/edge';
6
6
  import { AuthContext, createContextInner } from '@/libs/trpc/edge/context';
7
7
  import { edgeTrpc as trpc } from '@/libs/trpc/edge/init';
8
- import * as utils from '@/utils/server/jwt';
8
+ import * as utils from '@/utils/server/xor';
9
9
 
10
10
  import { jwtPayloadChecker } from './jwtPayload';
11
11
 
@@ -40,7 +40,7 @@ describe('passwordChecker middleware', () => {
40
40
  it('should call next with jwtPayload in context if access code is correct', async () => {
41
41
  const jwtPayload = { accessCode: '123' };
42
42
 
43
- vi.spyOn(utils, 'getJWTPayload').mockResolvedValue(jwtPayload);
43
+ vi.spyOn(utils, 'getXorPayload').mockResolvedValue(jwtPayload);
44
44
 
45
45
  ctx = await createContextInner({ authorizationHeader: 'Bearer token' });
46
46
  router = createCaller(ctx);
@@ -52,7 +52,7 @@ describe('passwordChecker middleware', () => {
52
52
 
53
53
  it('should call next with jwtPayload in context if no access codes are set', async () => {
54
54
  const jwtPayload = {};
55
- vi.spyOn(utils, 'getJWTPayload').mockResolvedValue(jwtPayload);
55
+ vi.spyOn(utils, 'getXorPayload').mockResolvedValue(jwtPayload);
56
56
 
57
57
  ctx = await createContextInner({ authorizationHeader: 'Bearer token' });
58
58
  router = createCaller(ctx);
@@ -63,7 +63,7 @@ describe('passwordChecker middleware', () => {
63
63
  });
64
64
  it('should call next with jwtPayload in context if access codes is undefined', async () => {
65
65
  const jwtPayload = {};
66
- vi.spyOn(utils, 'getJWTPayload').mockResolvedValue(jwtPayload);
66
+ vi.spyOn(utils, 'getXorPayload').mockResolvedValue(jwtPayload);
67
67
 
68
68
  ctx = await createContextInner({ authorizationHeader: 'Bearer token' });
69
69
  router = createCaller(ctx);
@@ -1,6 +1,6 @@
1
1
  import { TRPCError } from '@trpc/server';
2
2
 
3
- import { getJWTPayload } from '@/utils/server/jwt';
3
+ import { getXorPayload } from '@/utils/server/xor';
4
4
 
5
5
  import { edgeTrpc } from '../init';
6
6
 
@@ -9,7 +9,7 @@ export const jwtPayloadChecker = edgeTrpc.middleware(async (opts) => {
9
9
 
10
10
  if (!ctx.authorizationHeader) throw new TRPCError({ code: 'UNAUTHORIZED' });
11
11
 
12
- const jwtPayload = await getJWTPayload(ctx.authorizationHeader);
12
+ const jwtPayload = getXorPayload(ctx.authorizationHeader);
13
13
 
14
14
  return opts.next({ ctx: { jwtPayload } });
15
15
  });
@@ -4,7 +4,7 @@ import { User } from 'next-auth';
4
4
  import { NextRequest } from 'next/server';
5
5
 
6
6
  import {
7
- JWTPayload,
7
+ ClientSecretPayload,
8
8
  LOBE_CHAT_AUTH_HEADER,
9
9
  LOBE_CHAT_OIDC_AUTH_HEADER,
10
10
  enableClerk,
@@ -29,7 +29,7 @@ export interface OIDCAuth {
29
29
  export interface AuthContext {
30
30
  authorizationHeader?: string | null;
31
31
  clerkAuth?: IClerkAuth;
32
- jwtPayload?: JWTPayload | null;
32
+ jwtPayload?: ClientSecretPayload | null;
33
33
  marketAccessToken?: string;
34
34
  nextAuth?: User;
35
35
  // Add OIDC authentication information
@@ -1,6 +1,6 @@
1
1
  import { TRPCError } from '@trpc/server';
2
2
 
3
- import { getJWTPayload } from '@/utils/server/jwt';
3
+ import { getXorPayload } from '@/utils/server/xor';
4
4
 
5
5
  import { trpc } from '../init';
6
6
 
@@ -10,7 +10,7 @@ export const keyVaults = trpc.middleware(async (opts) => {
10
10
  if (!ctx.authorizationHeader) throw new TRPCError({ code: 'UNAUTHORIZED' });
11
11
 
12
12
  try {
13
- const jwtPayload = await getJWTPayload(ctx.authorizationHeader);
13
+ const jwtPayload = getXorPayload(ctx.authorizationHeader);
14
14
 
15
15
  return opts.next({ ctx: { jwtPayload } });
16
16
  } catch (e) {
@@ -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;