@lobehub/chat 0.128.9 → 0.129.0

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 (76) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/locales/ar/common.json +2 -1
  3. package/locales/ar/error.json +6 -0
  4. package/locales/ar/setting.json +9 -1
  5. package/locales/de-DE/common.json +1 -0
  6. package/locales/de-DE/error.json +6 -0
  7. package/locales/de-DE/setting.json +9 -1
  8. package/locales/en-US/common.json +1 -0
  9. package/locales/en-US/error.json +6 -0
  10. package/locales/en-US/setting.json +8 -0
  11. package/locales/es-ES/common.json +1 -0
  12. package/locales/es-ES/error.json +6 -0
  13. package/locales/es-ES/setting.json +9 -1
  14. package/locales/fr-FR/common.json +1 -0
  15. package/locales/fr-FR/error.json +6 -0
  16. package/locales/fr-FR/setting.json +8 -0
  17. package/locales/it-IT/common.json +1 -0
  18. package/locales/it-IT/error.json +6 -0
  19. package/locales/it-IT/setting.json +8 -0
  20. package/locales/ja-JP/common.json +1 -0
  21. package/locales/ja-JP/error.json +6 -0
  22. package/locales/ja-JP/setting.json +8 -0
  23. package/locales/ko-KR/common.json +1 -0
  24. package/locales/ko-KR/error.json +6 -0
  25. package/locales/ko-KR/setting.json +8 -0
  26. package/locales/nl-NL/common.json +2 -1
  27. package/locales/nl-NL/error.json +6 -0
  28. package/locales/nl-NL/setting.json +8 -0
  29. package/locales/pl-PL/common.json +2 -1
  30. package/locales/pl-PL/error.json +6 -0
  31. package/locales/pl-PL/setting.json +8 -0
  32. package/locales/pt-BR/common.json +1 -0
  33. package/locales/pt-BR/error.json +6 -0
  34. package/locales/pt-BR/setting.json +9 -1
  35. package/locales/ru-RU/common.json +1 -0
  36. package/locales/ru-RU/error.json +6 -0
  37. package/locales/ru-RU/setting.json +9 -1
  38. package/locales/tr-TR/common.json +1 -0
  39. package/locales/tr-TR/error.json +6 -0
  40. package/locales/tr-TR/setting.json +9 -1
  41. package/locales/vi-VN/common.json +1 -0
  42. package/locales/vi-VN/error.json +6 -0
  43. package/locales/vi-VN/setting.json +9 -1
  44. package/locales/zh-CN/common.json +1 -0
  45. package/locales/zh-CN/error.json +6 -0
  46. package/locales/zh-CN/setting.json +8 -0
  47. package/locales/zh-TW/common.json +1 -0
  48. package/locales/zh-TW/error.json +6 -0
  49. package/locales/zh-TW/setting.json +8 -0
  50. package/package.json +1 -1
  51. package/public/robots.txt +0 -2
  52. package/src/app/api/chat/[provider]/agentRuntime.ts +13 -0
  53. package/src/app/api/config/route.ts +2 -0
  54. package/src/app/api/errorResponse.ts +3 -0
  55. package/src/app/settings/llm/Perplexity/index.tsx +52 -0
  56. package/src/app/settings/llm/index.tsx +2 -0
  57. package/src/components/ModelIcon/index.tsx +3 -1
  58. package/src/components/ModelProviderIcon/index.tsx +19 -1
  59. package/src/components/ModelTag/ModelIcon.tsx +3 -1
  60. package/src/config/modelProviders/index.ts +3 -0
  61. package/src/config/modelProviders/perplexity.ts +44 -0
  62. package/src/config/server/provider.ts +8 -0
  63. package/src/const/settings.ts +4 -0
  64. package/src/features/Conversation/Error/APIKeyForm/Perplexity.tsx +60 -0
  65. package/src/features/Conversation/Error/APIKeyForm/index.tsx +5 -0
  66. package/src/features/Conversation/Error/index.tsx +1 -0
  67. package/src/libs/agent-runtime/error.ts +3 -0
  68. package/src/libs/agent-runtime/index.ts +1 -0
  69. package/src/libs/agent-runtime/perplexity/index.ts +86 -0
  70. package/src/libs/agent-runtime/types/type.ts +1 -0
  71. package/src/locales/default/common.ts +1 -0
  72. package/src/locales/default/error.ts +7 -0
  73. package/src/locales/default/setting.ts +8 -0
  74. package/src/services/_auth.ts +4 -0
  75. package/src/store/global/slices/settings/selectors/modelProvider.ts +9 -0
  76. package/src/types/settings/modelProvider.ts +7 -0
@@ -0,0 +1,60 @@
1
+ import { Perplexity } from '@lobehub/icons';
2
+ import { Input } from 'antd';
3
+ import { memo } from 'react';
4
+ import { useTranslation } from 'react-i18next';
5
+
6
+ import { ModelProvider } from '@/libs/agent-runtime';
7
+ import { useGlobalStore } from '@/store/global';
8
+ import { modelProviderSelectors } from '@/store/global/selectors';
9
+
10
+ import { FormAction } from '../style';
11
+
12
+ const PerplexityForm = memo(() => {
13
+ const { t } = useTranslation('error');
14
+ // const [showProxy, setShow] = useState(false);
15
+
16
+ const [apiKey, setConfig] = useGlobalStore((s) => [
17
+ modelProviderSelectors.perplexityAPIKey(s),
18
+ s.setModelProviderConfig,
19
+ ]);
20
+
21
+ return (
22
+ <FormAction
23
+ avatar={<Perplexity size={56} />}
24
+ description={t('unlock.apikey.Perplexity.description')}
25
+ title={t('unlock.apikey.Perplexity.title')}
26
+ >
27
+ <Input.Password
28
+ autoComplete={'new-password'}
29
+ onChange={(e) => {
30
+ setConfig(ModelProvider.Perplexity, { apiKey: e.target.value });
31
+ }}
32
+ placeholder={'*********************************'}
33
+ type={'block'}
34
+ value={apiKey}
35
+ />
36
+ {/*{showProxy ? (*/}
37
+ {/* <Input*/}
38
+ {/* onChange={(e) => {*/}
39
+ {/* setConfig({ endpoint: e.target.value });*/}
40
+ {/* }}*/}
41
+ {/* placeholder={'https://api.openai.com/v1'}*/}
42
+ {/* type={'block'}*/}
43
+ {/* value={proxyUrl}*/}
44
+ {/* />*/}
45
+ {/*) : (*/}
46
+ {/* <Button*/}
47
+ {/* icon={<Icon icon={Network} />}*/}
48
+ {/* onClick={() => {*/}
49
+ {/* setShow(true);*/}
50
+ {/* }}*/}
51
+ {/* type={'text'}*/}
52
+ {/* >*/}
53
+ {/* {t('unlock.apikey.addProxyUrl')}*/}
54
+ {/* </Button>*/}
55
+ {/*)}*/}
56
+ </FormAction>
57
+ );
58
+ });
59
+
60
+ export default PerplexityForm;
@@ -10,6 +10,7 @@ import BedrockForm from './Bedrock';
10
10
  import GoogleForm from './Google';
11
11
  import MoonshotForm from './Moonshot';
12
12
  import OpenAIForm from './OpenAI';
13
+ import PerplexityForm from './Perplexity';
13
14
  import ZhipuForm from './Zhipu';
14
15
 
15
16
  interface APIKeyFormProps {
@@ -40,6 +41,10 @@ const APIKeyForm = memo<APIKeyFormProps>(({ id, provider }) => {
40
41
  return <MoonshotForm />;
41
42
  }
42
43
 
44
+ case ModelProvider.Perplexity: {
45
+ return <PerplexityForm />;
46
+ }
47
+
43
48
  default:
44
49
  case ModelProvider.OpenAI: {
45
50
  return <OpenAIForm />;
@@ -66,6 +66,7 @@ const ErrorMessageExtra = memo<{ data: ChatMessage }>(({ data }) => {
66
66
  case AgentRuntimeErrorType.InvalidZhipuAPIKey:
67
67
  case AgentRuntimeErrorType.InvalidMoonshotAPIKey:
68
68
  case AgentRuntimeErrorType.InvalidGoogleAPIKey:
69
+ case AgentRuntimeErrorType.InvalidPerplexityAPIKey:
69
70
  case AgentRuntimeErrorType.NoOpenAIAPIKey: {
70
71
  return <InvalidAPIKey id={data.id} provider={data.error?.body?.provider} />;
71
72
  }
@@ -25,6 +25,9 @@ export const AgentRuntimeErrorType = {
25
25
 
26
26
  InvalidOllamaArgs: 'InvalidOllamaArgs',
27
27
  OllamaBizError: 'OllamaBizError',
28
+
29
+ InvalidPerplexityAPIKey: 'InvalidPerplexityAPIKey',
30
+ PerplexityBizError: 'PerplexityBizError',
28
31
  } as const;
29
32
 
30
33
  export type ILobeAgentRuntimeErrorType =
@@ -6,6 +6,7 @@ export { LobeGoogleAI } from './google';
6
6
  export { LobeMoonshotAI } from './moonshot';
7
7
  export { LobeOllamaAI } from './ollama';
8
8
  export { LobeOpenAI } from './openai';
9
+ export { LobePerplexityAI } from './perplexity';
9
10
  export * from './types';
10
11
  export { AgentRuntimeError } from './utils/createError';
11
12
  export { LobeZhipuAI } from './zhipu';
@@ -0,0 +1,86 @@
1
+ import { OpenAIStream, StreamingTextResponse } from 'ai';
2
+ import OpenAI from 'openai';
3
+
4
+ import { LobeRuntimeAI } from '../BaseAI';
5
+ import { AgentRuntimeErrorType } from '../error';
6
+ import { ChatStreamPayload, ModelProvider } from '../types';
7
+ import { AgentRuntimeError } from '../utils/createError';
8
+ import { debugStream } from '../utils/debugStream';
9
+ import { desensitizeUrl } from '../utils/desensitizeUrl';
10
+ import { DEBUG_CHAT_COMPLETION } from '../utils/env';
11
+ import { handleOpenAIError } from '../utils/handleOpenAIError';
12
+
13
+ const DEFAULT_BASE_URL = 'https://api.perplexity.ai';
14
+
15
+ export class LobePerplexityAI implements LobeRuntimeAI {
16
+ private _llm: OpenAI;
17
+
18
+ baseURL: string;
19
+
20
+ constructor(apiKey?: string, baseURL: string = DEFAULT_BASE_URL) {
21
+ if (!apiKey) throw AgentRuntimeError.createError(AgentRuntimeErrorType.InvalidPerplexityAPIKey);
22
+
23
+ this._llm = new OpenAI({ apiKey, baseURL });
24
+ this.baseURL = this._llm.baseURL;
25
+ }
26
+
27
+ async chat(payload: ChatStreamPayload) {
28
+ try {
29
+ // Set a default frequency penalty value greater than 0
30
+ const defaultFrequencyPenalty = 0.1;
31
+ const chatPayload = {
32
+ ...payload,
33
+ frequency_penalty: payload.frequency_penalty || defaultFrequencyPenalty,
34
+ };
35
+ const response = await this._llm.chat.completions.create(
36
+ chatPayload as unknown as OpenAI.ChatCompletionCreateParamsStreaming,
37
+ );
38
+
39
+ const stream = OpenAIStream(response);
40
+
41
+ const [debug, returnStream] = stream.tee();
42
+
43
+ if (DEBUG_CHAT_COMPLETION) {
44
+ debugStream(debug).catch(console.error);
45
+ }
46
+
47
+ return new StreamingTextResponse(returnStream);
48
+ } catch (error) {
49
+ let desensitizedEndpoint = this.baseURL;
50
+
51
+ if (this.baseURL !== DEFAULT_BASE_URL) {
52
+ desensitizedEndpoint = desensitizeUrl(this.baseURL);
53
+ }
54
+
55
+ if ('status' in (error as any)) {
56
+ switch ((error as Response).status) {
57
+ case 401: {
58
+ throw AgentRuntimeError.chat({
59
+ endpoint: desensitizedEndpoint,
60
+ error: error as any,
61
+ errorType: AgentRuntimeErrorType.InvalidPerplexityAPIKey,
62
+ provider: ModelProvider.Perplexity,
63
+ });
64
+ }
65
+
66
+ default: {
67
+ break;
68
+ }
69
+ }
70
+ }
71
+
72
+ const { errorResult, RuntimeError } = handleOpenAIError(error);
73
+
74
+ const errorType = RuntimeError || AgentRuntimeErrorType.PerplexityBizError;
75
+
76
+ throw AgentRuntimeError.chat({
77
+ endpoint: desensitizedEndpoint,
78
+ error: errorResult,
79
+ errorType,
80
+ provider: ModelProvider.Perplexity,
81
+ });
82
+ }
83
+ }
84
+ }
85
+
86
+ export default LobePerplexityAI;
@@ -31,6 +31,7 @@ export enum ModelProvider {
31
31
  Moonshot = 'moonshot',
32
32
  Ollama = 'ollama',
33
33
  OpenAI = 'openai',
34
+ Perplexity = 'perplexity',
34
35
  Tongyi = 'tongyi',
35
36
  ZhiPu = 'zhipu',
36
37
  }
@@ -107,6 +107,7 @@ export default {
107
107
  ollama: 'Ollama',
108
108
  oneapi: 'One API',
109
109
  openai: 'OpenAI',
110
+ perplexity: 'Perplexity',
110
111
  zhipu: '智谱AI',
111
112
  },
112
113
  noDescription: '暂无描述',
@@ -73,6 +73,9 @@ export default {
73
73
  InvalidAzureAPIKey: 'Azure API Key 不正确或为空,请检查 Azure API Key 后重试',
74
74
  AzureBizError: '请求 Azure AI 服务出错,请根据以下信息排查或重试',
75
75
 
76
+ InvalidPerplexityAPIKey: 'Perplexity API Key 不正确或为空,请检查 Perplexity API Key 后重试',
77
+ PerplexityBizError: '请求 Perplexity AI 服务出错,请根据以下信息排查或重试',
78
+
76
79
  InvalidOllamaArgs: 'Ollama 配置不正确,请检查 Ollama 配置后重试',
77
80
  OllamaBizError: '请求 Ollama 服务出错,请根据以下信息排查或重试',
78
81
 
@@ -106,6 +109,10 @@ export default {
106
109
  description: '输入你的 OpenAI API Key 即可开始会话。应用不会记录你的 API Key',
107
110
  title: '使用自定义 OpenAI API Key',
108
111
  },
112
+ Perplexity: {
113
+ description: '输入你的 Perplexity API Key 即可开始会话。应用不会记录你的 API Key',
114
+ title: '使用自定义 Perplexity API Key',
115
+ },
109
116
  Zhipu: {
110
117
  description: '输入你的 Zhipu API Key 即可开始会话。应用不会记录你的 API Key',
111
118
  title: '使用自定义 Zhipu API Key',
@@ -139,6 +139,14 @@ export default {
139
139
  title: 'Azure OpenAI',
140
140
  },
141
141
  },
142
+ Perplexity: {
143
+ title: 'Perplexity',
144
+ token: {
145
+ desc: '填入来自 Perplexity AI 的 API Key',
146
+ placeholder: 'Perplexity AI API Key',
147
+ title: 'API Key',
148
+ },
149
+ },
142
150
  Zhipu: {
143
151
  title: '智谱',
144
152
  token: {
@@ -48,6 +48,10 @@ export const getProviderAuthPayload = (provider: string) => {
48
48
  };
49
49
  }
50
50
 
51
+ case ModelProvider.Perplexity: {
52
+ return { apiKey: modelProviderSelectors.perplexityAPIKey(useGlobalStore.getState()) };
53
+ }
54
+
51
55
  default:
52
56
  case ModelProvider.OpenAI: {
53
57
  const openai = modelProviderSelectors.openAIConfig(useGlobalStore.getState());
@@ -7,6 +7,7 @@ import {
7
7
  MoonshotProvider,
8
8
  OllamaProvider,
9
9
  OpenAIProvider,
10
+ PerplexityProvider,
10
11
  ZhiPuProvider,
11
12
  } from '@/config/modelProviders';
12
13
  import { ChatModelCard, ModelProviderCard } from '@/types/llm';
@@ -48,6 +49,9 @@ const enableOllamaConfigInSettings = (s: GlobalStore) =>
48
49
  const enableOllama = (s: GlobalStore) => modelProvider(s).ollama.enabled;
49
50
  const ollamaProxyUrl = (s: GlobalStore) => modelProvider(s).ollama.endpoint;
50
51
 
52
+ const enablePerplexity = (s: GlobalStore) => modelProvider(s).perplexity.enabled;
53
+ const perplexityAPIKey = (s: GlobalStore) => modelProvider(s).perplexity.apiKey;
54
+
51
55
  // const azureModelList = (s: GlobalStore): ModelProviderCard => {
52
56
  // const azure = azureConfig(s);
53
57
  // return {
@@ -133,6 +137,7 @@ const modelSelectList = (s: GlobalStore): ModelProviderCard[] => {
133
137
  { ...GoogleProvider, enabled: enableGoogle(s) },
134
138
  { ...BedrockProvider, enabled: enableBedrock(s) },
135
139
  { ...OllamaProvider, chatModels: ollamaChatModels, enabled: enableOllama(s) },
140
+ { ...PerplexityProvider, enabled: enablePerplexity(s) },
136
141
  ];
137
142
  };
138
143
 
@@ -203,4 +208,8 @@ export const modelProviderSelectors = {
203
208
  enableOllamaConfigInSettings,
204
209
  enableOllama,
205
210
  ollamaProxyUrl,
211
+
212
+ // Perplexity
213
+ enablePerplexity,
214
+ perplexityAPIKey,
206
215
  };
@@ -54,6 +54,12 @@ export interface OllamaConfig {
54
54
  endpoint?: string;
55
55
  }
56
56
 
57
+ export interface PerplexityConfig {
58
+ apiKey?: string;
59
+ enabled: boolean;
60
+ endpoint?: string;
61
+ }
62
+
57
63
  export interface GlobalLLMConfig {
58
64
  azure: AzureOpenAIConfig;
59
65
  bedrock: AWSBedrockConfig;
@@ -61,6 +67,7 @@ export interface GlobalLLMConfig {
61
67
  moonshot: MoonshotConfig;
62
68
  ollama: OllamaConfig;
63
69
  openAI: OpenAIConfig;
70
+ perplexity: PerplexityConfig;
64
71
  zhipu: ZhiPuConfig;
65
72
  }
66
73