Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ feat: support 01.AI as a new provider #1627

Merged
merged 16 commits into from
Mar 25, 2024
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@ OPENAI_API_KEY=sk-xxxxxxxxx

#OPENROUTER_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxx

########################################
######### 01.AI Service ##########
########################################

#ZEROONEAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxx

########################################
############ Market Service ############
########################################
Expand Down
3 changes: 3 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,7 @@ ENV MISTRAL_API_KEY ""
# OpenRouter
ENV OPENROUTER_API_KEY ""

# 01.AI
ENV ZEROONE_API_KEY ""

CMD ["node", "server.js"]
1 change: 1 addition & 0 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@
- **Anthropic (Claude)**:接入了 Anthropic 的 **Claude** 系列模型,包括 Claude 3 和 Claude 2,多模态突破,超长上下文,树立行业新基准。[了解更多](https://www.anthropic.com/claude)
- **ChatGLM**:加入了智谱的 **ChatGLM** 系列模型(GLM-4/GLM-4-vision/GLM-3-turbo),为用户提供了另一种高效的会话模型选择。[了解更多](https://www.zhipuai.cn/)
- **Moonshot AI (月之暗面)**:集成了 Moonshot 系列模型,这是一家来自中国的创新性 AI 创业公司,旨在提供更深层次的会话理解。[了解更多](https://www.moonshot.cn/)
- **01.AI (零一万物)**:集成了零一万物模型,系列 API 具备较快的推理速度,这不仅缩短了处理时间,同时也保持了出色的模型效果。[了解更多](https://www.lingyiwanwu.com/)
- **Groq**:接入了 Groq 的 AI 模型,高效处理消息序列,生成回应,胜任多轮对话及单次交互任务。[了解更多](https://groq.com/)
- **OpenRouter**:其支持包括 **Claude 3**,**Gemma**,**Mistral**,**Llama2**和**Cohere**等模型路由,支持智能路由优化,提升使用效率,开放且灵活。[了解更多](https://openrouter.ai/)

Expand Down
10 changes: 10 additions & 0 deletions docs/self-hosting/environment-variables/model-provider.zh-CN.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ LobeChat 在部署时提供了丰富的模型服务商相关的环境变量,
- 描述:这是你在 Groq AI 服务中申请的 API 密钥
- 默认值:-
- 示例:`gsk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxx`

## OpenRouter AI

### `OPENROUTER_API_KEY`
Expand All @@ -185,4 +186,13 @@ LobeChat 在部署时提供了丰富的模型服务商相关的环境变量,
- 默认值:-
- 示例:`sk-or-v1-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=`

## 01 AI

### `ZEROONE_API_KEY`

- 类型:必选
- 描述:这是你在零一万物服务中申请的 API 密钥
- 默认值:-
- 示例:`xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`

[azure-api-verion-url]: https://docs.microsoft.com/zh-cn/azure/developer/javascript/api-reference/es-modules/azure-sdk/ai-translation/translationconfiguration?view=azure-node-latest#api-version
1 change: 1 addition & 0 deletions docs/usage/features/multi-ai-providers.zh-CN.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
- **Google AI (Gemini Pro、Gemini Vision)**:接入了 Google 的 **Gemini** 系列模型,包括 Gemini 和 Gemini Pro,以支持更高级的语言理解和生成。[了解更多](https://deepmind.google/technologies/gemini/)
- **ChatGLM**:加入了智谱的 **ChatGLM** 系列模型(GLM-4/GLM-4-vision/GLM-3-turbo),为用户提供了另一种高效的会话模型选择。[了解更多](https://www.zhipuai.cn/)
- **Moonshot AI (月之暗面)**:集成了 Moonshot 系列模型,这是一家来自中国的创新性 AI 创业公司,旨在提供更深层次的会话理解。[了解更多](https://www.moonshot.cn/)
- **01 AI (零一万物)**:集成了零一万物模型,系列 API 具备较快的推理速度,这不仅缩短了处理时间,同时也保持了出色的模型效果。[了解更多](https://www.lingyiwanwu.com/)

同时,我们也在计划支持更多的模型服务商,如 Replicate 和 Perplexity 等,以进一步丰富我们的服务商库。如果你希望让 LobeChat 支持你喜爱的服务商,欢迎加入我们的[社区讨论](https://github.com/lobehub/lobe-chat/discussions/1284)。

Expand Down
1 change: 1 addition & 0 deletions locales/en-US/common.json
MapleEve marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
"openai": "OpenAI",
"openrouter": "OpenRouter",
"perplexity": "Perplexity",
"zeroone": "01-AI",
"zhipu": "Zhipu AI"
},
"noDescription": "No description available",
Expand Down
8 changes: 7 additions & 1 deletion locales/en-US/error.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"InvalidOllamaArgs": "Invalid Ollama configuration, please check Ollama configuration and try again",
"InvalidOpenRouterAPIKey": "Invalid or empty OpenRouter API Key. Please check your OpenRouter API Key and try again.",
"InvalidPerplexityAPIKey": "Perplexity API Key is incorrect or empty. Please check the Perplexity API Key and retry.",
"InvalidZeroOneAPIKey": "01-AI API Key is incorrect or empty. Please check the 01-AI API Key and retry.",
"InvalidZhipuAPIKey": "Zhipu API Key is incorrect or empty. Please check the Zhipu API Key and retry.",
"LocationNotSupportError": "We're sorry, your current location does not support this model service. This may be due to regional restrictions or the service not being available. Please confirm if the current location supports using this service, or try using a different location.",
"MistralBizError": "Error occurred while requesting Mistral AI service. Please troubleshoot based on the following information or retry.",
Expand All @@ -60,6 +61,7 @@
"OpenAIBizError": "Error requesting OpenAI service. Please troubleshoot or retry based on the following information.",
"OpenRouterBizError": "Error requesting OpenRouter AI service. Please troubleshoot or retry based on the following information.",
"PerplexityBizError": "Error requesting Perplexity AI service. Please troubleshoot or retry based on the following information.",
"ZeroOneBizError": "Error requesting 01-AI service. Please troubleshoot or retry based on the following information.",
"PluginApiNotFound": "Sorry, the API does not exist in the plugin's manifest. Please check if your request method matches the plugin manifest API",
"PluginApiParamsError": "Sorry, the input parameter validation for the plugin request failed. Please check if the input parameters match the API description",
"PluginGatewayError": "Sorry, there was an error with the plugin gateway. Please check if the plugin gateway configuration is correct.",
Expand Down Expand Up @@ -120,6 +122,10 @@
"description": "Enter your Perplexity API Key to start the session. The app will not store your API Key.",
"title": "Use custom Perplexity API Key"
},
"ZeroOne": {
"description": "Enter your 01-AI API Key to start the session. The application will not store your API Key.",
"title": "Use Custom 01-AI API Key"
},
"Zhipu": {
"description": "Enter your Zhipu API Key to start the session. The app will not store your API Key.",
"title": "Use custom Zhipu API Key"
Expand Down Expand Up @@ -150,4 +156,4 @@
"password": "Password"
}
}
}
}
8 changes: 8 additions & 0 deletions locales/en-US/setting.json
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,14 @@
"title": "API Key"
}
},
"ZeroOne": {
"title": "01-AI",
"token": {
"desc": "Enter the API Key from 01-AI",
"placeholder": "01-AI API Key",
"title": "API Key"
}
},
"Zhipu": {
"title": "Zhipu",
"token": {
Expand Down
1 change: 1 addition & 0 deletions locales/zh-CN/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
"openai": "OpenAI",
"openrouter": "OpenRouter",
"perplexity": "Perplexity",
"zeroone": "零一万物",
"zhipu": "智谱AI"
},
"noDescription": "暂无描述",
Expand Down
8 changes: 7 additions & 1 deletion locales/zh-CN/error.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@
"GroqBizError": "请求 Groq 服务出错,请根据以下信息排查或重试",
"InvalidOpenRouterAPIKey": "OpenRouter API Key 不正确或为空,请检查 OpenRouter API Key 后重试",
"OpenRouterBizError": "请求 OpenRouter AI 服务出错,请根据以下信息排查或重试",
"ZeroOneBizError": "请求零一万物服务出错,请根据以下信息排查或重试",
"InvalidZeroOneAPIKey": "零一万物 API Key 不正确或为空,请检查零一万物 API Key 后重试",
"InvalidOllamaArgs": "Ollama 配置不正确,请检查 Ollama 配置后重试",
"OllamaBizError": "请求 Ollama 服务出错,请根据以下信息排查或重试",
"OllamaServiceUnavailable": "未检测到 Ollama 服务,请检查是否正常启动",
Expand Down Expand Up @@ -120,6 +122,10 @@
"description": "输入你的 Perplexity API Key 即可开始会话。应用不会记录你的 API Key",
"title": "使用自定义 Perplexity API Key"
},
"ZeroOne": {
"description": "输入你的零一万物 API Key 即可开始会话。应用不会记录你的 API Key",
"title": "使用自定义零一万物 API Key"
},
"Zhipu": {
"description": "输入你的 Zhipu API Key 即可开始会话。应用不会记录你的 API Key",
"title": "使用自定义 Zhipu API Key"
Expand Down Expand Up @@ -150,4 +156,4 @@
"password": "密码"
}
}
}
}
8 changes: 8 additions & 0 deletions locales/zh-CN/setting.json
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,14 @@
"title": "API Key"
}
},
"ZeroOne": {
"title": "零一万物",
"token": {
"desc": "填入来自零一万物的 API Key",
"placeholder": "零一万物 API Key",
"title": "API Key"
}
},
"Zhipu": {
"title": "智谱",
"token": {
Expand Down
17 changes: 15 additions & 2 deletions src/app/api/chat/[provider]/agentRuntime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
LobeOpenRouterAI,
LobePerplexityAI,
LobeRuntimeAI,
LobeZeroOneAI,
LobeZhipuAI,
ModelProvider,
} from '@/libs/agent-runtime';
Expand Down Expand Up @@ -174,11 +175,16 @@
runtimeModel = this.initGroq(payload);
break;
}

case ModelProvider.OpenRouter: {
runtimeModel = this.initOpenRouter(payload);
break;
}

case ModelProvider.ZeroOne: {
runtimeModel = this.initZeroOne(payload);
break;
}

Check warning on line 187 in src/app/api/chat/[provider]/agentRuntime.ts

View check run for this annotation

Codecov / codecov/patch

src/app/api/chat/[provider]/agentRuntime.ts#L185-L187

Added lines #L185 - L187 were not covered by tests
}

return new AgentRuntime(runtimeModel);
Expand Down Expand Up @@ -287,14 +293,21 @@

return new LobeGroq({ apiKey });
}

private static initOpenRouter(payload: JWTPayload) {
const { OPENROUTER_API_KEY } = getServerConfig();
const apiKey = apiKeyManager.pick(payload?.apiKey || OPENROUTER_API_KEY);

return new LobeOpenRouterAI({ apiKey });
}

private static initZeroOne(payload: JWTPayload) {
const { ZEROONE_API_KEY } = getServerConfig();
const apiKey = apiKeyManager.pick(payload?.apiKey || ZEROONE_API_KEY);

return new LobeZeroOneAI({ apiKey });
}

Check warning on line 309 in src/app/api/chat/[provider]/agentRuntime.ts

View check run for this annotation

Codecov / codecov/patch

src/app/api/chat/[provider]/agentRuntime.ts#L305-L309

Added lines #L305 - L309 were not covered by tests

}

export default AgentRuntime;
2 changes: 2 additions & 0 deletions src/app/api/config/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export const GET = async () => {
ENABLED_ANTHROPIC,
ENABLED_MISTRAL,
ENABLED_OPENROUTER,
ENABLED_ZEROONE,
DEFAULT_AGENT_CONFIG,
OLLAMA_CUSTOM_MODELS,
} = getServerConfig();
Expand All @@ -44,6 +45,7 @@ export const GET = async () => {
ollama: { customModelName: OLLAMA_CUSTOM_MODELS, enabled: ENABLE_OLLAMA },
openrouter: { enabled: ENABLED_OPENROUTER },
perplexity: { enabled: ENABLED_PERPLEXITY },
zeroone: { enabled: ENABLED_ZEROONE },
zhipu: { enabled: ENABLED_ZHIPU },
},
telemetry: {
Expand Down
3 changes: 3 additions & 0 deletions src/app/api/errorResponse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@
case AgentRuntimeErrorType.GroqBizError: {
return 482;
}
case AgentRuntimeErrorType.ZeroOneBizError: {
return 483;
}

Check warning on line 61 in src/app/api/errorResponse.ts

View check run for this annotation

Codecov / codecov/patch

src/app/api/errorResponse.ts#L60-L61

Added lines #L60 - L61 were not covered by tests
}
return errorType as number;
};
Expand Down
13 changes: 10 additions & 3 deletions src/app/settings/llm/Google/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Google } from '@lobehub/icons';
import { Input } from 'antd';
import { Google, Gemini } from '@lobehub/icons';
import { Input, Divider } from 'antd';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
import { Flexbox } from 'react-layout-kit';

import { ModelProvider } from '@/libs/agent-runtime';
import { GlobalLLMProviderKey } from '@/types/settings';
Expand Down Expand Up @@ -37,7 +38,13 @@ const GoogleProvider = memo(() => {
},
]}
provider={providerKey}
title={<Google.BrandColor size={28} />}
title={
<Flexbox align={'center'} gap={8} horizontal>
<Google.BrandColor size={28} />
<Divider style={{ margin: '0 4px' }} type={'vertical'} />
<Gemini.Combine size={24} type={'color'} />
</Flexbox>
}
/>
);
});
Expand Down
2 changes: 1 addition & 1 deletion src/app/settings/llm/Groq/index.tsx
MapleEve marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const GroqProvider = memo(() => {
},
]}
provider={providerKey}
title={<Groq.Text color={theme.isDarkMode ? theme.colorText : Groq.colorPrimary} size={24} />}
title={<Groq.Combine color={theme.isDarkMode ? theme.colorText : Groq.colorPrimary} size={24} />}
arvinxx marked this conversation as resolved.
Show resolved Hide resolved
/>
);
});
Expand Down
52 changes: 52 additions & 0 deletions src/app/settings/llm/ZeroOne/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { ZeroOne } from '@lobehub/icons';
import { Input } from 'antd';
import { useTheme } from 'antd-style';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';

import { ModelProvider } from '@/libs/agent-runtime';

import Checker from '../components/Checker';
import ProviderConfig from '../components/ProviderConfig';
import { LLMProviderApiTokenKey, LLMProviderConfigKey } from '../const';

const providerKey = 'zeroone';

const ZeroOneProvider = memo(() => {
const { t } = useTranslation('setting');

const theme = useTheme();

return (
<ProviderConfig
configItems={[
{
children: (
<Input.Password
autoComplete={'new-password'}
placeholder={t('llm.ZeroOne.token.placeholder')}
/>
),
desc: t('llm.ZeroOne.token.desc'),
label: t('llm.ZeroOne.token.title'),
name: [LLMProviderConfigKey, providerKey, LLMProviderApiTokenKey],
},
{
children: <Checker model={'yi-34b-chat-0205'} provider={ModelProvider.ZeroOne} />,
desc: t('llm.checker.desc'),
label: t('llm.checker.title'),
minWidth: '100%',
},
]}
provider={providerKey}
title={
<ZeroOne.Combine
color={theme.isDarkMode ? theme.colorText : ZeroOne.colorPrimary}
size={32}
/>
}
/>
);
});

export default ZeroOneProvider;
2 changes: 2 additions & 0 deletions src/app/settings/llm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import Ollama from './Ollama';
import OpenAI from './OpenAI';
import OpenRouter from './OpenRouter';
import Perplexity from './Perplexity';
import ZeroOne from './ZeroOne';
import Zhipu from './Zhipu';

export default memo<{ showOllama: boolean }>(({ showOllama }) => {
Expand All @@ -37,6 +38,7 @@ export default memo<{ showOllama: boolean }>(({ showOllama }) => {
<Mistral />
<OpenRouter />
<Moonshot />
<ZeroOne />
<Zhipu />
<Footer>
<Trans i18nKey="llm.waitingForMore" ns={'setting'}>
Expand Down
2 changes: 2 additions & 0 deletions src/components/ModelIcon/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
OpenAI,
Perplexity,
Tongyi,
Yi,
} from '@lobehub/icons';
import { memo } from 'react';

Expand Down Expand Up @@ -40,6 +41,7 @@ const ModelIcon = memo<ModelProviderIconProps>(({ model, size = 12 }) => {
return <Baichuan.Avatar background={Baichuan.colorPrimary} size={size} />;
if (model.includes('mistral') || model.includes('mixtral')) return <Mistral.Avatar size={size} />;
if (model.includes('pplx')) return <Perplexity.Avatar size={size} />;
if (model.startsWith('yi-')) return <Yi.Avatar size={size} />;
});

export default ModelIcon;
5 changes: 5 additions & 0 deletions src/components/ModelProviderIcon/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
OpenAI,
OpenRouter,
Perplexity,
ZeroOne,
Zhipu,
} from '@lobehub/icons';
import { memo } from 'react';
Expand Down Expand Up @@ -79,6 +80,10 @@ const ModelProviderIcon = memo<ModelProviderIconProps>(({ provider }) => {
return <OpenRouter size={20} />;
}

case ModelProvider.ZeroOne: {
return <ZeroOne size={20} />;
}

default: {
return null;
}
Expand Down
2 changes: 2 additions & 0 deletions src/components/ModelTag/ModelIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
OpenAI,
Perplexity,
Tongyi,
ZeroOne,
} from '@lobehub/icons';
import { memo } from 'react';

Expand All @@ -38,6 +39,7 @@ const ModelIcon = memo<ModelIconProps>(({ model, size = 12 }) => {
if (model.includes('baichuan')) return <Baichuan size={size} />;
if (model.includes('mistral') || model.includes('mixtral')) return <Mistral size={size} />;
if (model.includes('pplx')) return <Perplexity size={size} />;
if (model.startsWith('yi-')) return <ZeroOne size={size} />;
});

export default ModelIcon;
Loading