@lobehub/chat 0.162.17 → 0.162.18

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 (149) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/docs/self-hosting/advanced/settings-url-share.mdx +89 -57
  3. package/docs/self-hosting/advanced/settings-url-share.zh-CN.mdx +87 -56
  4. package/locales/ar/error.json +7 -39
  5. package/locales/ar/modelProvider.json +15 -183
  6. package/locales/ar/setting.json +5 -8
  7. package/locales/bg-BG/error.json +6 -38
  8. package/locales/bg-BG/modelProvider.json +15 -183
  9. package/locales/bg-BG/setting.json +5 -8
  10. package/locales/de-DE/error.json +6 -38
  11. package/locales/de-DE/modelProvider.json +15 -183
  12. package/locales/de-DE/setting.json +5 -8
  13. package/locales/en-US/error.json +6 -38
  14. package/locales/en-US/modelProvider.json +15 -183
  15. package/locales/en-US/setting.json +6 -9
  16. package/locales/es-ES/error.json +6 -38
  17. package/locales/es-ES/modelProvider.json +15 -183
  18. package/locales/es-ES/setting.json +5 -8
  19. package/locales/fr-FR/error.json +6 -38
  20. package/locales/fr-FR/modelProvider.json +15 -183
  21. package/locales/fr-FR/setting.json +9 -12
  22. package/locales/it-IT/error.json +6 -38
  23. package/locales/it-IT/modelProvider.json +15 -183
  24. package/locales/it-IT/setting.json +5 -8
  25. package/locales/ja-JP/error.json +6 -38
  26. package/locales/ja-JP/modelProvider.json +15 -183
  27. package/locales/ja-JP/setting.json +5 -8
  28. package/locales/ko-KR/error.json +6 -38
  29. package/locales/ko-KR/modelProvider.json +15 -183
  30. package/locales/ko-KR/setting.json +5 -8
  31. package/locales/nl-NL/error.json +6 -38
  32. package/locales/nl-NL/modelProvider.json +15 -183
  33. package/locales/nl-NL/setting.json +5 -8
  34. package/locales/pl-PL/error.json +6 -38
  35. package/locales/pl-PL/modelProvider.json +15 -183
  36. package/locales/pl-PL/setting.json +6 -9
  37. package/locales/pt-BR/error.json +6 -38
  38. package/locales/pt-BR/modelProvider.json +15 -183
  39. package/locales/pt-BR/setting.json +5 -8
  40. package/locales/ru-RU/error.json +6 -38
  41. package/locales/ru-RU/modelProvider.json +15 -183
  42. package/locales/ru-RU/setting.json +5 -8
  43. package/locales/tr-TR/error.json +6 -38
  44. package/locales/tr-TR/modelProvider.json +15 -183
  45. package/locales/tr-TR/setting.json +5 -8
  46. package/locales/vi-VN/error.json +6 -38
  47. package/locales/vi-VN/modelProvider.json +15 -183
  48. package/locales/vi-VN/setting.json +5 -8
  49. package/locales/zh-CN/error.json +7 -39
  50. package/locales/zh-CN/modelProvider.json +15 -183
  51. package/locales/zh-CN/setting.json +5 -8
  52. package/locales/zh-TW/error.json +7 -39
  53. package/locales/zh-TW/modelProvider.json +15 -183
  54. package/locales/zh-TW/setting.json +5 -8
  55. package/package.json +1 -2
  56. package/src/app/(main)/settings/llm/ProviderList/Azure/index.tsx +107 -0
  57. package/src/app/(main)/settings/llm/ProviderList/Bedrock/index.tsx +68 -0
  58. package/src/app/(main)/settings/llm/ProviderList/Ollama/index.tsx +29 -0
  59. package/src/app/(main)/settings/llm/ProviderList/OpenAI/index.tsx +20 -0
  60. package/src/app/(main)/settings/llm/ProviderList/providers.tsx +141 -0
  61. package/src/app/(main)/settings/llm/components/ProviderConfig/index.tsx +18 -27
  62. package/src/app/(main)/settings/llm/index.tsx +7 -36
  63. package/src/app/(main)/settings/llm/type.ts +5 -0
  64. package/src/app/api/chat/[provider]/route.ts +8 -3
  65. package/src/app/api/errorResponse.test.ts +7 -95
  66. package/src/app/api/errorResponse.ts +6 -46
  67. package/src/app/api/middleware/auth/index.ts +7 -3
  68. package/src/components/ModelSelect/index.tsx +7 -10
  69. package/src/config/modelProviders/anthropic.ts +5 -0
  70. package/src/config/modelProviders/azure.ts +2 -0
  71. package/src/config/modelProviders/bedrock.ts +2 -0
  72. package/src/config/modelProviders/deepseek.ts +4 -1
  73. package/src/config/modelProviders/google.ts +5 -0
  74. package/src/config/modelProviders/groq.ts +5 -0
  75. package/src/config/modelProviders/minimax.ts +2 -0
  76. package/src/config/modelProviders/mistral.ts +2 -0
  77. package/src/config/modelProviders/moonshot.ts +2 -0
  78. package/src/config/modelProviders/ollama.ts +4 -0
  79. package/src/config/modelProviders/openai.ts +3 -0
  80. package/src/config/modelProviders/openrouter.ts +3 -0
  81. package/src/config/modelProviders/perplexity.ts +5 -0
  82. package/src/config/modelProviders/qwen.ts +3 -0
  83. package/src/config/modelProviders/togetherai.ts +3 -0
  84. package/src/config/modelProviders/zeroone.ts +4 -2
  85. package/src/config/modelProviders/zhipu.ts +2 -0
  86. package/src/features/Conversation/Error/APIKeyForm/ProviderApiKeyForm.tsx +6 -3
  87. package/src/features/Conversation/Error/OllamaBizError/InvalidOllamaModel/index.tsx +11 -14
  88. package/src/features/Conversation/Error/index.tsx +29 -20
  89. package/src/features/Conversation/components/ChatItem/index.tsx +4 -13
  90. package/src/features/ModelSelect/index.tsx +1 -1
  91. package/src/features/ModelSwitchPanel/index.tsx +1 -1
  92. package/src/hooks/useProviderName.ts +8 -0
  93. package/src/libs/agent-runtime/anthropic/index.test.ts +8 -5
  94. package/src/libs/agent-runtime/anthropic/index.ts +3 -3
  95. package/src/libs/agent-runtime/azureOpenai/index.test.ts +5 -2
  96. package/src/libs/agent-runtime/azureOpenai/index.ts +2 -2
  97. package/src/libs/agent-runtime/bedrock/index.test.ts +2 -2
  98. package/src/libs/agent-runtime/bedrock/index.ts +2 -2
  99. package/src/libs/agent-runtime/deepseek/index.test.ts +3 -2
  100. package/src/libs/agent-runtime/deepseek/index.ts +0 -5
  101. package/src/libs/agent-runtime/error.ts +11 -46
  102. package/src/libs/agent-runtime/google/index.test.ts +3 -4
  103. package/src/libs/agent-runtime/google/index.ts +4 -4
  104. package/src/libs/agent-runtime/groq/index.test.ts +3 -2
  105. package/src/libs/agent-runtime/groq/index.ts +0 -4
  106. package/src/libs/agent-runtime/minimax/index.test.ts +3 -2
  107. package/src/libs/agent-runtime/minimax/index.ts +5 -5
  108. package/src/libs/agent-runtime/mistral/index.test.ts +2 -2
  109. package/src/libs/agent-runtime/mistral/index.ts +0 -5
  110. package/src/libs/agent-runtime/moonshot/index.test.ts +3 -2
  111. package/src/libs/agent-runtime/moonshot/index.ts +0 -5
  112. package/src/libs/agent-runtime/openrouter/index.test.ts +3 -2
  113. package/src/libs/agent-runtime/openrouter/index.ts +0 -6
  114. package/src/libs/agent-runtime/perplexity/index.test.ts +2 -2
  115. package/src/libs/agent-runtime/perplexity/index.ts +0 -5
  116. package/src/libs/agent-runtime/qwen/index.test.ts +2 -2
  117. package/src/libs/agent-runtime/qwen/index.ts +0 -5
  118. package/src/libs/agent-runtime/togetherai/index.test.ts +3 -2
  119. package/src/libs/agent-runtime/togetherai/index.ts +0 -5
  120. package/src/libs/agent-runtime/utils/openaiCompatibleFactory/index.test.ts +2 -6
  121. package/src/libs/agent-runtime/utils/openaiCompatibleFactory/index.ts +12 -6
  122. package/src/libs/agent-runtime/zeroone/index.test.ts +3 -2
  123. package/src/libs/agent-runtime/zeroone/index.ts +1 -5
  124. package/src/libs/agent-runtime/zhipu/index.test.ts +8 -5
  125. package/src/libs/agent-runtime/zhipu/index.ts +2 -2
  126. package/src/locales/default/error.ts +10 -51
  127. package/src/locales/default/modelProvider.ts +12 -169
  128. package/src/locales/default/setting.ts +5 -8
  129. package/src/services/message/client.test.ts +4 -1
  130. package/src/types/fetch.ts +3 -1
  131. package/src/types/llm.ts +22 -0
  132. package/src/app/(main)/settings/llm/Anthropic/index.tsx +0 -25
  133. package/src/app/(main)/settings/llm/Azure/index.tsx +0 -110
  134. package/src/app/(main)/settings/llm/Bedrock/index.tsx +0 -74
  135. package/src/app/(main)/settings/llm/DeepSeek/index.tsx +0 -21
  136. package/src/app/(main)/settings/llm/Google/index.tsx +0 -31
  137. package/src/app/(main)/settings/llm/Groq/index.tsx +0 -26
  138. package/src/app/(main)/settings/llm/Minimax/index.tsx +0 -20
  139. package/src/app/(main)/settings/llm/Mistral/index.tsx +0 -20
  140. package/src/app/(main)/settings/llm/Moonshot/index.tsx +0 -28
  141. package/src/app/(main)/settings/llm/Ollama/index.tsx +0 -37
  142. package/src/app/(main)/settings/llm/OpenAI/index.tsx +0 -28
  143. package/src/app/(main)/settings/llm/OpenRouter/index.tsx +0 -21
  144. package/src/app/(main)/settings/llm/Perplexity/index.tsx +0 -23
  145. package/src/app/(main)/settings/llm/Qwen/index.tsx +0 -21
  146. package/src/app/(main)/settings/llm/TogetherAI/index.tsx +0 -19
  147. package/src/app/(main)/settings/llm/ZeroOne/index.tsx +0 -20
  148. package/src/app/(main)/settings/llm/Zhipu/index.tsx +0 -18
  149. /package/src/app/(main)/settings/llm/{Ollama → ProviderList/Ollama}/Checker.tsx +0 -0
@@ -42,7 +42,9 @@ const Minimax: ModelProviderCard = {
42
42
  tokens: 8192,
43
43
  },
44
44
  ],
45
+ checkModel: 'abab5.5s-chat',
45
46
  id: 'minimax',
47
+ name: 'Minimax',
46
48
  };
47
49
 
48
50
  export default Minimax;
@@ -41,7 +41,9 @@ const Mistral: ModelProviderCard = {
41
41
  tokens: 32_768,
42
42
  },
43
43
  ],
44
+ checkModel: 'open-mistral-7b',
44
45
  id: 'mistral',
46
+ name: 'Mistral',
45
47
  };
46
48
 
47
49
  export default Mistral;
@@ -25,7 +25,9 @@ const Moonshot: ModelProviderCard = {
25
25
  tokens: 128_000,
26
26
  },
27
27
  ],
28
+ checkModel: 'moonshot-v1-8k',
28
29
  id: 'moonshot',
30
+ name: 'Moonshot',
29
31
  };
30
32
 
31
33
  export default Moonshot;
@@ -155,6 +155,10 @@ const Ollama: ModelProviderCard = {
155
155
  },
156
156
  ],
157
157
  id: 'ollama',
158
+ modelList: { showModelFetcher: true },
159
+ name: 'Ollama',
160
+ showApiKey: false,
161
+ showBrowserRequest: true,
158
162
  };
159
163
 
160
164
  export default Ollama;
@@ -132,8 +132,11 @@ const OpenAI: ModelProviderCard = {
132
132
  vision: true,
133
133
  },
134
134
  ],
135
+ checkModel: 'gpt-3.5-turbo',
135
136
  enabled: true,
136
137
  id: 'openai',
138
+ modelList: { showModelFetcher: true },
139
+ name: 'OpenAI',
137
140
  };
138
141
 
139
142
  export default OpenAI;
@@ -116,7 +116,10 @@ const OpenRouter: ModelProviderCard = {
116
116
  vision: false,
117
117
  },
118
118
  ],
119
+ checkModel: 'mistralai/mistral-7b-instruct:free',
119
120
  id: 'openrouter',
121
+ modelList: { showModelFetcher: true },
122
+ name: 'OpenRouter',
120
123
  };
121
124
 
122
125
  export default OpenRouter;
@@ -41,7 +41,12 @@ const Perplexity: ModelProviderCard = {
41
41
  tokens: 16_384,
42
42
  },
43
43
  ],
44
+ checkModel: 'pplx-7b-chat',
44
45
  id: 'perplexity',
46
+ name: 'Perplexity',
47
+ proxyUrl: {
48
+ placeholder: 'https://api.perplexity.ai',
49
+ },
45
50
  };
46
51
 
47
52
  export default Perplexity;
@@ -26,7 +26,10 @@ const Qwen: ModelProviderCard = {
26
26
  tokens: 8192,
27
27
  },
28
28
  ],
29
+ checkModel: 'qwen-turbo',
29
30
  id: 'qwen',
31
+ modelList: { showModelFetcher: true },
32
+ name: 'Qwen',
30
33
  };
31
34
 
32
35
  export default Qwen;
@@ -70,7 +70,10 @@ const TogetherAI: ModelProviderCard = {
70
70
  tokens: 32_768,
71
71
  },
72
72
  ],
73
+ checkModel: 'togethercomputer/alpaca-7b',
73
74
  id: 'togetherai',
75
+ modelList: { showModelFetcher: true },
76
+ name: 'Together AI',
74
77
  };
75
78
 
76
79
  export default TogetherAI;
@@ -39,7 +39,8 @@ const ZeroOne: ModelProviderCard = {
39
39
  tokens: 16_384,
40
40
  },
41
41
  {
42
- description: '基于Yi-Large超强模型的高阶服务,结合检索与生成技术提供精准答案,支持客⼾私有知识库(请联系客服申请)。',
42
+ description:
43
+ '基于Yi-Large超强模型的高阶服务,结合检索与生成技术提供精准答案,支持客⼾私有知识库(请联系客服申请)。',
43
44
  displayName: 'Yi Large RAG',
44
45
  id: 'yi-large-rag',
45
46
  tokens: 16_384,
@@ -64,9 +65,10 @@ const ZeroOne: ModelProviderCard = {
64
65
  id: 'yi-large-rag-preview',
65
66
  tokens: 16_384,
66
67
  },
67
-
68
68
  ],
69
+ checkModel: 'yi-34b-chat-0205',
69
70
  id: 'zeroone',
71
+ name: '01.AI',
70
72
  };
71
73
 
72
74
  export default ZeroOne;
@@ -29,7 +29,9 @@ const ZhiPu: ModelProviderCard = {
29
29
  tokens: 128_000,
30
30
  },
31
31
  ],
32
+ checkModel: 'glm-3-turbo',
32
33
  id: 'zhipu',
34
+ name: 'ZhiPu',
33
35
  };
34
36
 
35
37
  export default ZhiPu;
@@ -4,6 +4,7 @@ import { Network } from 'lucide-react';
4
4
  import { ReactNode, memo, useState } from 'react';
5
5
  import { useTranslation } from 'react-i18next';
6
6
 
7
+ import { useProviderName } from '@/hooks/useProviderName';
7
8
  import { useUserStore } from '@/store/user';
8
9
  import { keyVaultsConfigSelectors } from '@/store/user/selectors';
9
10
  import { GlobalLLMProviderKey } from '@/types/user/settings';
@@ -19,7 +20,7 @@ interface ProviderApiKeyFormProps {
19
20
 
20
21
  const ProviderApiKeyForm = memo<ProviderApiKeyFormProps>(
21
22
  ({ provider, avatar, showEndpoint = false, apiKeyPlaceholder }) => {
22
- const { t } = useTranslation('modelProvider');
23
+ const { t } = useTranslation(['modelProvider', 'error']);
23
24
  const { t: errorT } = useTranslation('error');
24
25
  const [showProxy, setShow] = useState(false);
25
26
 
@@ -29,11 +30,13 @@ const ProviderApiKeyForm = memo<ProviderApiKeyFormProps>(
29
30
  s.updateKeyVaultConfig,
30
31
  ]);
31
32
 
33
+ const providerName = useProviderName(provider);
34
+
32
35
  return (
33
36
  <FormAction
34
37
  avatar={avatar}
35
- description={t(`${provider}.unlock.description` as any)}
36
- title={t(`${provider}.unlock.title` as any)}
38
+ description={t(`unlock.apiKey.description`, { name: providerName, ns: 'error' })}
39
+ title={t(`unlock.apiKey.title`, { name: providerName, ns: 'error' })}
37
40
  >
38
41
  <Input.Password
39
42
  autoComplete={'new-password'}
@@ -18,8 +18,7 @@ interface OllamaModelFormProps {
18
18
  }
19
19
 
20
20
  const OllamaModelForm = memo<OllamaModelFormProps>(({ id, model }) => {
21
- const { t } = useTranslation('error');
22
- const { t: settingT } = useTranslation('setting');
21
+ const { t } = useTranslation(['modelProvider', 'error']);
23
22
 
24
23
  const [modelToPull, setModelToPull] = useState(model);
25
24
  const [completed, setCompleted] = useState(0);
@@ -60,13 +59,11 @@ const OllamaModelForm = memo<OllamaModelFormProps>(({ id, model }) => {
60
59
  <Center gap={16} style={{ maxWidth: 300, width: '100%' }}>
61
60
  <FormAction
62
61
  avatar={<Ollama color={theme.colorPrimary} size={64} />}
63
- description={
64
- isDownloading ? settingT('ollama.download.desc') : t('unlock.ollama.description')
65
- }
62
+ description={isDownloading ? t('ollama.download.desc') : t('ollama.unlock.description')}
66
63
  title={
67
64
  isDownloading
68
- ? settingT('ollama.download.title', { model: modelToPull })
69
- : t('unlock.ollama.title')
65
+ ? t('ollama.download.title', { model: modelToPull })
66
+ : t('ollama.unlock.title')
70
67
  }
71
68
  >
72
69
  {!isDownloading && (
@@ -92,10 +89,10 @@ const OllamaModelForm = memo<OllamaModelFormProps>(({ id, model }) => {
92
89
  style={{ color: theme.colorTextDescription, fontSize: 12 }}
93
90
  >
94
91
  <span>
95
- {settingT('ollama.download.remainingTime')}: {remainingTime}
92
+ {t('ollama.download.remainingTime')}: {remainingTime}
96
93
  </span>
97
94
  <span>
98
- {settingT('ollama.download.speed')}: {downloadSpeed}
95
+ {t('ollama.download.speed')}: {downloadSpeed}
99
96
  </span>
100
97
  </Flexbox>
101
98
  </Flexbox>
@@ -111,11 +108,11 @@ const OllamaModelForm = memo<OllamaModelFormProps>(({ id, model }) => {
111
108
  type={'primary'}
112
109
  >
113
110
  {!isDownloading
114
- ? t('unlock.ollama.confirm')
111
+ ? t('ollama.unlock.confirm')
115
112
  : // if total is 0, show starting, else show downloaded
116
113
  !total
117
- ? t('unlock.ollama.starting')
118
- : t('unlock.ollama.downloaded', {
114
+ ? t('ollama.unlock.starting')
115
+ : t('ollama.unlock.downloaded', {
119
116
  completed: formatSize(completed),
120
117
  total: formatSize(total),
121
118
  })}
@@ -126,7 +123,7 @@ const OllamaModelForm = memo<OllamaModelFormProps>(({ id, model }) => {
126
123
  ollamaService.abort();
127
124
  }}
128
125
  >
129
- {t('unlock.ollama.cancel')}
126
+ {t('ollama.unlock.cancel')}
130
127
  </Button>
131
128
  ) : (
132
129
  <Button
@@ -134,7 +131,7 @@ const OllamaModelForm = memo<OllamaModelFormProps>(({ id, model }) => {
134
131
  deleteMessage(id);
135
132
  }}
136
133
  >
137
- {t('unlock.closeMessage')}
134
+ {t('unlock.closeMessage', { ns: 'error' })}
138
135
  </Button>
139
136
  )}
140
137
  </Flexbox>
@@ -2,8 +2,10 @@ import { IPluginErrorType, PluginErrorType } from '@lobehub/chat-plugin-sdk';
2
2
  import type { AlertProps } from '@lobehub/ui';
3
3
  import { Skeleton } from 'antd';
4
4
  import dynamic from 'next/dynamic';
5
- import { Suspense, memo } from 'react';
5
+ import { Suspense, memo, useMemo } from 'react';
6
+ import { useTranslation } from 'react-i18next';
6
7
 
8
+ import { useProviderName } from '@/hooks/useProviderName';
7
9
  import { AgentRuntimeErrorType, ILobeAgentRuntimeErrorType } from '@/libs/agent-runtime';
8
10
  import { ChatErrorType, ErrorType } from '@/types/fetch';
9
11
  import { ChatMessage, ChatMessageError } from '@/types/message';
@@ -20,7 +22,7 @@ const OllamaBizError = dynamic(() => import('./OllamaBizError'), { loading, ssr:
20
22
  const PluginSettings = dynamic(() => import('./PluginSettings'), { loading, ssr: false });
21
23
 
22
24
  // Config for the errorMessage display
23
- export const getErrorAlertConfig = (
25
+ const getErrorAlertConfig = (
24
26
  errorType?: IPluginErrorType | ILobeAgentRuntimeErrorType | ErrorType,
25
27
  ): AlertProps | undefined => {
26
28
  // OpenAIBizError / ZhipuBizError / GoogleBizError / ...
@@ -52,6 +54,23 @@ export const getErrorAlertConfig = (
52
54
  }
53
55
  };
54
56
 
57
+ export const useErrorContent = (error: any) => {
58
+ const { t } = useTranslation('error');
59
+ const providerName = useProviderName(error?.body?.provider || '');
60
+
61
+ return useMemo<AlertProps | undefined>(() => {
62
+ if (!error) return;
63
+ const messageError = error;
64
+
65
+ const alertConfig = getErrorAlertConfig(messageError.type);
66
+
67
+ return {
68
+ message: t(`response.${messageError.type}` as any, { provider: providerName }),
69
+ ...alertConfig,
70
+ };
71
+ }, [error]);
72
+ };
73
+
55
74
  const ErrorMessageExtra = memo<{ data: ChatMessage }>(({ data }) => {
56
75
  const error = data.error as ChatMessageError;
57
76
  if (!error?.type) return;
@@ -77,28 +96,18 @@ const ErrorMessageExtra = memo<{ data: ChatMessage }>(({ data }) => {
77
96
  return <InvalidAccessCode id={data.id} provider={data.error?.body?.provider} />;
78
97
  }
79
98
 
80
- case AgentRuntimeErrorType.InvalidBedrockCredentials:
81
- case AgentRuntimeErrorType.InvalidDeepSeekAPIKey:
82
- case AgentRuntimeErrorType.InvalidZhipuAPIKey:
83
- case AgentRuntimeErrorType.InvalidMinimaxAPIKey:
84
- case AgentRuntimeErrorType.InvalidMistralAPIKey:
85
- case AgentRuntimeErrorType.InvalidMoonshotAPIKey:
86
- case AgentRuntimeErrorType.InvalidGoogleAPIKey:
87
- case AgentRuntimeErrorType.InvalidPerplexityAPIKey:
88
- case AgentRuntimeErrorType.InvalidAnthropicAPIKey:
89
- case AgentRuntimeErrorType.InvalidGroqAPIKey:
90
- case AgentRuntimeErrorType.InvalidOpenRouterAPIKey:
91
- case AgentRuntimeErrorType.InvalidQwenAPIKey:
92
- case AgentRuntimeErrorType.InvalidTogetherAIAPIKey:
93
- case AgentRuntimeErrorType.InvalidZeroOneAPIKey:
94
99
  case AgentRuntimeErrorType.NoOpenAIAPIKey: {
95
- return <InvalidAPIKey id={data.id} provider={data.error?.body?.provider} />;
100
+ {
101
+ return <InvalidAPIKey id={data.id} provider={data.error?.body?.provider} />;
102
+ }
96
103
  }
104
+ }
97
105
 
98
- default: {
99
- return <ErrorJsonViewer error={data.error} id={data.id} />;
100
- }
106
+ if (error.type.toString().includes('Invalid')) {
107
+ return <InvalidAPIKey id={data.id} provider={data.error?.body?.provider} />;
101
108
  }
109
+
110
+ return <ErrorJsonViewer error={data.error} id={data.id} />;
102
111
  });
103
112
 
104
113
  export default memo<{ data: ChatMessage }>(({ data }) => (
@@ -1,7 +1,7 @@
1
- import { AlertProps, ChatItem } from '@lobehub/ui';
1
+ import { ChatItem } from '@lobehub/ui';
2
2
  import { createStyles } from 'antd-style';
3
3
  import isEqual from 'fast-deep-equal';
4
- import { ReactNode, memo, useCallback, useMemo } from 'react';
4
+ import { ReactNode, memo, useCallback } from 'react';
5
5
  import { useTranslation } from 'react-i18next';
6
6
 
7
7
  import { useAgentStore } from '@/store/agent';
@@ -14,7 +14,7 @@ import { useUserStore } from '@/store/user';
14
14
  import { userGeneralSettingsSelectors } from '@/store/user/selectors';
15
15
  import { ChatMessage } from '@/types/message';
16
16
 
17
- import ErrorMessageExtra, { getErrorAlertConfig } from '../../Error';
17
+ import ErrorMessageExtra, { useErrorContent } from '../../Error';
18
18
  import { renderMessagesExtra } from '../../Extras';
19
19
  import { renderMessages, useAvatarsClick } from '../../Messages';
20
20
  import ActionsBar from './ActionsBar';
@@ -91,16 +91,7 @@ const Item = memo<ChatListItemProps>(({ index, id }) => {
91
91
  },
92
92
  [item?.role],
93
93
  );
94
-
95
- const { t: errorT } = useTranslation('error');
96
- const error = useMemo<AlertProps | undefined>(() => {
97
- if (!item?.error) return;
98
- const messageError = item.error;
99
-
100
- const alertConfig = getErrorAlertConfig(messageError.type);
101
-
102
- return { message: errorT(`response.${messageError.type}` as any), ...alertConfig };
103
- }, [item?.error]);
94
+ const error = useErrorContent(item?.error);
104
95
 
105
96
  const enableHistoryDivider = useAgentStore((s) => {
106
97
  const config = agentSelectors.currentAgentChatConfig(s);
@@ -46,7 +46,7 @@ const ModelSelect = memo<ModelSelectProps>(({ value, onChange }) => {
46
46
  }
47
47
 
48
48
  return enabledList.map((provider) => ({
49
- label: <ProviderItemRender provider={provider.id} />,
49
+ label: <ProviderItemRender name={provider.name} provider={provider.id} />,
50
50
  options: getChatModels(provider),
51
51
  }));
52
52
  }, [enabledList]);
@@ -86,7 +86,7 @@ const ModelSwitchPanel = memo<PropsWithChildren>(({ children }) => {
86
86
  return enabledList.map((provider) => ({
87
87
  children: getModelItems(provider),
88
88
  key: provider.id,
89
- label: <ProviderItemRender provider={provider.id} />,
89
+ label: <ProviderItemRender name={provider.name} provider={provider.id} />,
90
90
  type: 'group',
91
91
  }));
92
92
  }, [enabledList]);
@@ -0,0 +1,8 @@
1
+ import { DEFAULT_MODEL_PROVIDER_LIST } from '@/config/modelProviders';
2
+
3
+ export const useProviderName = (provider: string) => {
4
+ // const { t } = useTranslation('modelProvider');
5
+ const providerCard = DEFAULT_MODEL_PROVIDER_LIST.find((p) => p.id === provider);
6
+
7
+ return providerCard?.name || provider;
8
+ };
@@ -9,6 +9,9 @@ import { LobeAnthropicAI } from './index';
9
9
 
10
10
  const provider = 'anthropic';
11
11
 
12
+ const bizErrorType = 'ProviderBizError';
13
+ const invalidErrorType = 'InvalidProviderAPIKey';
14
+
12
15
  // Mock the console.error to avoid polluting test output
13
16
  vi.spyOn(console, 'error').mockImplementation(() => {});
14
17
 
@@ -315,7 +318,7 @@ describe('LobeAnthropicAI', () => {
315
318
  expect(e).toEqual({
316
319
  endpoint: 'https://api.anthropic.com',
317
320
  error: apiError,
318
- errorType: 'InvalidAnthropicAPIKey',
321
+ errorType: invalidErrorType,
319
322
  provider,
320
323
  });
321
324
  }
@@ -346,7 +349,7 @@ describe('LobeAnthropicAI', () => {
346
349
  expect(e).toEqual({
347
350
  endpoint: 'https://api.anthropic.com',
348
351
  error: apiError,
349
- errorType: 'AnthropicBizError',
352
+ errorType: bizErrorType,
350
353
  provider,
351
354
  });
352
355
  }
@@ -356,7 +359,7 @@ describe('LobeAnthropicAI', () => {
356
359
  try {
357
360
  new LobeAnthropicAI({});
358
361
  } catch (e) {
359
- expect(e).toEqual({ errorType: 'InvalidAnthropicAPIKey' });
362
+ expect(e).toEqual({ errorType: invalidErrorType });
360
363
  }
361
364
  });
362
365
  });
@@ -397,7 +400,7 @@ describe('LobeAnthropicAI', () => {
397
400
  ).rejects.toEqual({
398
401
  endpoint: 'https://api.anthropic.com',
399
402
  error: apiError,
400
- errorType: 'AnthropicBizError',
403
+ errorType: bizErrorType,
401
404
  provider,
402
405
  });
403
406
  });
@@ -421,7 +424,7 @@ describe('LobeAnthropicAI', () => {
421
424
  ).rejects.toEqual({
422
425
  endpoint: 'https://api.cu****om.com/v1',
423
426
  error: apiError,
424
- errorType: 'InvalidAnthropicAPIKey',
427
+ errorType: invalidErrorType,
425
428
  provider,
426
429
  });
427
430
  });
@@ -21,7 +21,7 @@ export class LobeAnthropicAI implements LobeRuntimeAI {
21
21
  baseURL: string;
22
22
 
23
23
  constructor({ apiKey, baseURL = DEFAULT_BASE_URL }: ClientOptions) {
24
- if (!apiKey) throw AgentRuntimeError.createError(AgentRuntimeErrorType.InvalidAnthropicAPIKey);
24
+ if (!apiKey) throw AgentRuntimeError.createError(AgentRuntimeErrorType.InvalidProviderAPIKey);
25
25
 
26
26
  this.client = new Anthropic({ apiKey, baseURL });
27
27
  this.baseURL = this.client.baseURL;
@@ -80,7 +80,7 @@ export class LobeAnthropicAI implements LobeRuntimeAI {
80
80
  throw AgentRuntimeError.chat({
81
81
  endpoint: desensitizedEndpoint,
82
82
  error: error as any,
83
- errorType: AgentRuntimeErrorType.InvalidAnthropicAPIKey,
83
+ errorType: AgentRuntimeErrorType.InvalidProviderAPIKey,
84
84
  provider: ModelProvider.Anthropic,
85
85
  });
86
86
  }
@@ -101,7 +101,7 @@ export class LobeAnthropicAI implements LobeRuntimeAI {
101
101
  throw AgentRuntimeError.chat({
102
102
  endpoint: desensitizedEndpoint,
103
103
  error: error as any,
104
- errorType: AgentRuntimeErrorType.AnthropicBizError,
104
+ errorType: AgentRuntimeErrorType.ProviderBizError,
105
105
  provider: ModelProvider.Anthropic,
106
106
  });
107
107
  }
@@ -6,6 +6,9 @@ import { Mock, afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
6
6
  import * as debugStreamModule from '../utils/debugStream';
7
7
  import { LobeAzureOpenAI } from './index';
8
8
 
9
+ const bizErrorType = 'ProviderBizError';
10
+ const invalidErrorType = 'InvalidProviderAPIKey';
11
+
9
12
  // Mock the console.error to avoid polluting test output
10
13
  vi.spyOn(console, 'error').mockImplementation(() => {});
11
14
 
@@ -34,7 +37,7 @@ describe('LobeAzureOpenAI', () => {
34
37
  try {
35
38
  new LobeAzureOpenAI();
36
39
  } catch (e) {
37
- expect(e).toEqual({ errorType: 'InvalidAzureAPIKey' });
40
+ expect(e).toEqual({ errorType: invalidErrorType });
38
41
  }
39
42
  });
40
43
 
@@ -229,7 +232,7 @@ describe('LobeAzureOpenAI', () => {
229
232
  message: 'Deployment not found',
230
233
  deployId: 'text-davinci-003',
231
234
  },
232
- errorType: 'AzureBizError',
235
+ errorType: bizErrorType,
233
236
  provider: 'azure',
234
237
  });
235
238
  }
@@ -18,7 +18,7 @@ export class LobeAzureOpenAI implements LobeRuntimeAI {
18
18
 
19
19
  constructor(endpoint?: string, apikey?: string, apiVersion?: string) {
20
20
  if (!apikey || !endpoint)
21
- throw AgentRuntimeError.createError(AgentRuntimeErrorType.InvalidAzureAPIKey);
21
+ throw AgentRuntimeError.createError(AgentRuntimeErrorType.InvalidProviderAPIKey);
22
22
 
23
23
  this.client = new OpenAIClient(endpoint, new AzureKeyCredential(apikey), { apiVersion });
24
24
 
@@ -68,7 +68,7 @@ export class LobeAzureOpenAI implements LobeRuntimeAI {
68
68
  }
69
69
 
70
70
  const errorType = error.code
71
- ? AgentRuntimeErrorType.AzureBizError
71
+ ? AgentRuntimeErrorType.ProviderBizError
72
72
  : AgentRuntimeErrorType.AgentRuntimeError;
73
73
 
74
74
  throw AgentRuntimeError.chat({
@@ -281,7 +281,7 @@ describe('LobeBedrockAI', () => {
281
281
  message: errorMessage,
282
282
  type: 'Error',
283
283
  },
284
- errorType: AgentRuntimeErrorType.BedrockBizError,
284
+ errorType: AgentRuntimeErrorType.ProviderBizError,
285
285
  provider: ModelProvider.Bedrock,
286
286
  region: 'us-west-2',
287
287
  }),
@@ -346,7 +346,7 @@ describe('LobeBedrockAI', () => {
346
346
  region: 'us-west-2',
347
347
  type: 'Error',
348
348
  },
349
- errorType: AgentRuntimeErrorType.BedrockBizError,
349
+ errorType: AgentRuntimeErrorType.ProviderBizError,
350
350
  provider: ModelProvider.Bedrock,
351
351
  region: 'us-west-2',
352
352
  }),
@@ -96,7 +96,7 @@ export class LobeBedrockAI implements LobeRuntimeAI {
96
96
  message: err.message,
97
97
  type: err.name,
98
98
  },
99
- errorType: AgentRuntimeErrorType.BedrockBizError,
99
+ errorType: AgentRuntimeErrorType.ProviderBizError,
100
100
  provider: ModelProvider.Bedrock,
101
101
  region: this.region,
102
102
  });
@@ -143,7 +143,7 @@ export class LobeBedrockAI implements LobeRuntimeAI {
143
143
  region: this.region,
144
144
  type: err.name,
145
145
  },
146
- errorType: AgentRuntimeErrorType.BedrockBizError,
146
+ errorType: AgentRuntimeErrorType.ProviderBizError,
147
147
  provider: ModelProvider.Bedrock,
148
148
  region: this.region,
149
149
  });
@@ -13,8 +13,9 @@ import { LobeDeepSeekAI } from './index';
13
13
 
14
14
  const provider = ModelProvider.DeepSeek;
15
15
  const defaultBaseURL = 'https://api.deepseek.com/v1';
16
- const bizErrorType = 'DeepSeekBizError';
17
- const invalidErrorType = 'InvalidDeepSeekAPIKey';
16
+
17
+ const bizErrorType = 'ProviderBizError';
18
+ const invalidErrorType = 'InvalidProviderAPIKey';
18
19
 
19
20
  // Mock the console.error to avoid polluting test output
20
21
  vi.spyOn(console, 'error').mockImplementation(() => {});
@@ -1,4 +1,3 @@
1
- import { AgentRuntimeErrorType } from '../error';
2
1
  import { ModelProvider } from '../types';
3
2
  import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory';
4
3
 
@@ -7,9 +6,5 @@ export const LobeDeepSeekAI = LobeOpenAICompatibleFactory({
7
6
  debug: {
8
7
  chatCompletion: () => process.env.DEBUG_DEEPSEEK_CHAT_COMPLETION === '1',
9
8
  },
10
- errorType: {
11
- bizError: AgentRuntimeErrorType.DeepSeekBizError,
12
- invalidAPIKey: AgentRuntimeErrorType.InvalidDeepSeekAPIKey,
13
- },
14
9
  provider: ModelProvider.DeepSeek,
15
10
  });
@@ -4,57 +4,22 @@ export const AgentRuntimeErrorType = {
4
4
  AgentRuntimeError: 'AgentRuntimeError', // Agent Runtime 模块运行时错误
5
5
  LocationNotSupportError: 'LocationNotSupportError',
6
6
 
7
- OpenAIBizError: 'OpenAIBizError',
8
-
9
- NoOpenAIAPIKey: 'NoOpenAIAPIKey',
10
-
11
- InvalidAzureAPIKey: 'InvalidAzureAPIKey',
12
- AzureBizError: 'AzureBizError',
13
-
14
- InvalidZhipuAPIKey: 'InvalidZhipuAPIKey',
15
- ZhipuBizError: 'ZhipuBizError',
16
-
17
- InvalidGoogleAPIKey: 'InvalidGoogleAPIKey',
18
- GoogleBizError: 'GoogleBizError',
19
-
20
- InvalidBedrockCredentials: 'InvalidBedrockCredentials',
21
- BedrockBizError: 'BedrockBizError',
22
-
23
- InvalidMistralAPIKey: 'InvalidMistralAPIKey',
24
- MistralBizError: 'MistralBizError',
25
-
26
- InvalidMoonshotAPIKey: 'InvalidMoonshotAPIKey',
27
- MoonshotBizError: 'MoonshotBizError',
7
+ InvalidProviderAPIKey: 'InvalidProviderAPIKey',
8
+ ProviderBizError: 'ProviderBizError',
28
9
 
29
10
  InvalidOllamaArgs: 'InvalidOllamaArgs',
30
11
  OllamaBizError: 'OllamaBizError',
31
12
 
32
- InvalidPerplexityAPIKey: 'InvalidPerplexityAPIKey',
33
- PerplexityBizError: 'PerplexityBizError',
34
-
35
- InvalidAnthropicAPIKey: 'InvalidAnthropicAPIKey',
36
- AnthropicBizError: 'AnthropicBizError',
37
-
38
- InvalidGroqAPIKey: 'InvalidGroqAPIKey',
39
- GroqBizError: 'GroqBizError',
40
-
41
- InvalidZeroOneAPIKey: 'InvalidZeroOneAPIKey',
42
- ZeroOneBizError: 'ZeroOneBizError',
43
-
44
- InvalidOpenRouterAPIKey: 'InvalidOpenRouterAPIKey',
45
- OpenRouterBizError: 'OpenRouterBizError',
46
-
47
- InvalidTogetherAIAPIKey: 'InvalidTogetherAIAPIKey',
48
- TogetherAIBizError: 'TogetherAIBizError',
49
-
50
- InvalidMinimaxAPIKey: 'InvalidMinimaxAPIKey',
51
- MinimaxBizError: 'MinimaxBizError',
52
-
53
- InvalidDeepSeekAPIKey: 'InvalidDeepSeekAPIKey',
54
- DeepSeekBizError: 'DeepSeekBizError',
13
+ InvalidBedrockCredentials: 'InvalidBedrockCredentials',
55
14
 
56
- InvalidQwenAPIKey: 'InvalidQwenAPIKey',
57
- QwenBizError: 'QwenBizError',
15
+ /**
16
+ * @deprecated
17
+ */
18
+ NoOpenAIAPIKey: 'NoOpenAIAPIKey',
19
+ /**
20
+ * @deprecated
21
+ */
22
+ OpenAIBizError: 'OpenAIBizError',
58
23
  } as const;
59
24
 
60
25
  export type ILobeAgentRuntimeErrorType =