mirror of
https://github.com/kuaifan/dootask.git
synced 2025-12-14 21:02:49 +00:00
perf: 更新 AI 支持更多模型和支持提示词
This commit is contained in:
parent
61b1206091
commit
0d4b005f4e
@ -957,7 +957,8 @@ class DialogController extends AbstractController
|
||||
* @apiGroup dialog
|
||||
* @apiName msg__stream
|
||||
*
|
||||
* @apiParam {Number} dialog_id 对话ID
|
||||
* @apiParam {String} [type] 消息类型(暂时无用,预留)
|
||||
* - ai: 默认
|
||||
* @apiParam {Number} userid 通知会员ID
|
||||
* @apiParam {String} stream_url 流动消息地址
|
||||
*
|
||||
@ -967,7 +968,6 @@ class DialogController extends AbstractController
|
||||
*/
|
||||
public function msg__stream()
|
||||
{
|
||||
// $dialog_id = intval(Request::input('dialog_id'));
|
||||
$userid = intval(Request::input('userid'));
|
||||
$stream_url = trim(Request::input('stream_url'));
|
||||
//
|
||||
@ -975,6 +975,8 @@ class DialogController extends AbstractController
|
||||
return Base::retError('参数错误');
|
||||
}
|
||||
//
|
||||
$stream_url = '/ai' . preg_replace('/^\/ai/?', '/', $stream_url);
|
||||
//
|
||||
$params = [
|
||||
'userid' => $userid,
|
||||
'msg' => [
|
||||
|
||||
@ -97,10 +97,10 @@ class SystemController extends AbstractController
|
||||
return Base::retError('自动归档时间不可大于100天!');
|
||||
}
|
||||
}
|
||||
if ($all['voice2text'] == 'open' && empty(Base::settingFind('aibotSetting', 'openai_key'))) {
|
||||
if ($all['voice2text'] == 'open' && !Setting::AIOpen()) {
|
||||
return Base::retError('开启语音转文字功能需要在应用中开启 ChatGPT AI 机器人。');
|
||||
}
|
||||
if ($all['translation'] == 'open' && empty(Base::settingFind('aibotSetting', 'openai_key'))) {
|
||||
if ($all['translation'] == 'open' && !Setting::AIOpen()) {
|
||||
return Base::retError('开启翻译功能需要在应用中开启 ChatGPT AI 机器人。');
|
||||
}
|
||||
if ($all['system_alias'] == env('APP_NAME')) {
|
||||
@ -282,7 +282,7 @@ class SystemController extends AbstractController
|
||||
*
|
||||
* @apiParam {String} type
|
||||
* - get: 获取(默认)
|
||||
* - save: 保存设置(参数:['openai_key', 'openai_agency', 'claude_token', 'claude_agency'])
|
||||
* - save: 保存设置(参数:[...])
|
||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||
* @apiSuccess {Object} data 返回数据
|
||||
@ -293,32 +293,13 @@ class SystemController extends AbstractController
|
||||
//
|
||||
$type = trim(Request::input('type'));
|
||||
$setting = Base::setting('aibotSetting');
|
||||
|
||||
$keys = [
|
||||
'openai_key',
|
||||
'openai_agency',
|
||||
'openai_model',
|
||||
'claude_token',
|
||||
'claude_agency',
|
||||
'wenxin_key',
|
||||
'wenxin_secret',
|
||||
'wenxin_model',
|
||||
'qianwen_key',
|
||||
'qianwen_model',
|
||||
'gemini_key',
|
||||
'gemini_model',
|
||||
'gemini_agency',
|
||||
'zhipu_key',
|
||||
'zhipu_model',
|
||||
];
|
||||
|
||||
if ($type == 'save') {
|
||||
if (env("SYSTEM_SETTING") == 'disabled') {
|
||||
return Base::retError('当前环境禁止修改');
|
||||
}
|
||||
$all = Request::input();
|
||||
foreach ($all as $key => $value) {
|
||||
if (!in_array($key, $keys)) {
|
||||
if (!isset($setting[$key])) {
|
||||
unset($all[$key]);
|
||||
}
|
||||
}
|
||||
@ -335,7 +316,7 @@ class SystemController extends AbstractController
|
||||
WebSocketDialogMsg::sendMsg(null, $dialog->id, 'template', $tempMsg, $botUser->userid, true, false, true);
|
||||
}
|
||||
}
|
||||
if ($backup['claude_token'] != $setting['claude_token']) {
|
||||
if ($backup['claude_key'] != $setting['claude_key']) {
|
||||
$botUser = User::botGetOrCreate('ai-claude');
|
||||
if ($botUser && $dialog = WebSocketDialog::checkUserDialog($botUser, $user->userid)) {
|
||||
WebSocketDialogMsg::sendMsg(null, $dialog->id, 'template', $tempMsg, $botUser->userid, true, false, true);
|
||||
@ -367,15 +348,10 @@ class SystemController extends AbstractController
|
||||
}
|
||||
}
|
||||
//
|
||||
$setting['openai_model'] = $setting['openai_model'] ?: 'gpt-3.5-turbo';
|
||||
$setting['wenxin_model'] = $setting['wenxin_model'] ?: 'eb-instant';
|
||||
$setting['qianwen_model'] = $setting['qianwen_model'] ?: 'qwen-v1';
|
||||
$setting['gemini_model'] = $setting['gemini_model'] ?: 'gemini-1.0-pro';
|
||||
$setting['zhipu_model'] = $setting['zhipu_model'] ?: 'glm-4';
|
||||
if (env("SYSTEM_SETTING") == 'disabled') {
|
||||
foreach ($keys as $item) {
|
||||
if (strlen($setting[$item]) > 12) {
|
||||
$setting[$item] = substr($setting[$item], 0, 4) . str_repeat('*', strlen($setting[$item]) - 8) . substr($setting[$item], -4);
|
||||
foreach ($setting as $key => $item) {
|
||||
if (str_contains($key, '_key')) {
|
||||
$setting[$key] = substr($item, 0, 4) . str_repeat('*', strlen($item) - 8) . substr($item, -4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,14 +51,50 @@ class Setting extends AbstractModel
|
||||
$value['task_default_time'] = ['09:00', '18:00'];
|
||||
}
|
||||
break;
|
||||
|
||||
case 'fileSetting':
|
||||
$value['permission_pack_type'] = $value['permission_pack_type'] ?: 'all';
|
||||
$value['permission_pack_userids'] = is_array($value['permission_pack_userids']) ? $value['permission_pack_userids'] : [];
|
||||
break;
|
||||
|
||||
case 'aibotSetting':
|
||||
if ($value['claude_token'] && empty($value['claude_key'])) {
|
||||
$value['claude_key'] = $value['claude_token'];
|
||||
}
|
||||
$array = [];
|
||||
$aiList = ['openai', 'claude', 'gemini', 'zhipu', 'qianwen', 'wenxin'];
|
||||
$fieldList = ['key', 'model', 'agency', 'system', 'secret'];
|
||||
foreach ($aiList as $aiName) {
|
||||
foreach ($fieldList as $fieldName) {
|
||||
$key = $aiName . '_' . $fieldName;
|
||||
$array[$key] = $value[$key] ?: match ($key) {
|
||||
'openai_model' => 'gpt-4o-mini',
|
||||
'claude_model' => 'claude-3-5-sonnet-latest',
|
||||
'gemini_model' => 'gemini-1.5-flash',
|
||||
'zhipu_model' => 'glm-4',
|
||||
'qianwen_model' => 'qwen-turbo',
|
||||
'wenxin_model' => 'ernie-4.0-8k',
|
||||
default => '',
|
||||
};
|
||||
}
|
||||
}
|
||||
$value = $array;
|
||||
break;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否开启AI
|
||||
* @param $ai
|
||||
* @return bool
|
||||
*/
|
||||
public static function AIOpen($ai = 'openai')
|
||||
{
|
||||
$array = Base::setting('aibotSetting');
|
||||
return !!$array[$ai . '_key'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证邮箱地址(过滤忽略地址)
|
||||
* @param $array
|
||||
|
||||
@ -177,7 +177,7 @@ class UserBot extends AbstractModel
|
||||
];
|
||||
|
||||
default:
|
||||
if (preg_match('/^ai-(.*?)@bot.system$/', $email)) {
|
||||
if (preg_match('/^ai-(.*?)@bot\.system$/', $email)) {
|
||||
return [
|
||||
[
|
||||
'key' => '%3A.clear',
|
||||
|
||||
@ -409,113 +409,33 @@ class BotReceiveMsgTask extends AbstractTask
|
||||
$userBot = null;
|
||||
$extras = [];
|
||||
$errorContent = null;
|
||||
switch ($botUser->email) {
|
||||
// ChatGPT 机器人
|
||||
case 'ai-openai@bot.system':
|
||||
$setting = Base::setting('aibotSetting');
|
||||
$webhookUrl = "{$serverUrl}/ai/openai/send";
|
||||
$extras = [
|
||||
'openai_key' => $setting['openai_key'],
|
||||
'openai_agency' => $setting['openai_agency'],
|
||||
'openai_model' => $setting['openai_model'],
|
||||
'server_url' => $serverUrl,
|
||||
'chunk_size' => 7,
|
||||
];
|
||||
if (empty($extras['openai_key'])) {
|
||||
$errorContent = '机器人未启用。';
|
||||
} elseif (in_array($this->client['platform'], ['win', 'mac', 'web'])
|
||||
&& !Base::judgeClientVersion("0.29.11", $this->client['version'])) {
|
||||
$errorContent = '当前客户端版本低(所需版本≥v0.29.11)。';
|
||||
}
|
||||
break;
|
||||
// Claude 机器人
|
||||
case 'ai-claude@bot.system':
|
||||
$setting = Base::setting('aibotSetting');
|
||||
$webhookUrl = "{$serverUrl}/ai/claude/send";
|
||||
$extras = [
|
||||
'claude_token' => $setting['claude_token'],
|
||||
'claude_agency' => $setting['claude_agency'],
|
||||
'server_url' => $serverUrl,
|
||||
];
|
||||
if (empty($extras['claude_token'])) {
|
||||
$errorContent = '机器人未启用。';
|
||||
} elseif (in_array($this->client['platform'], ['win', 'mac', 'web'])
|
||||
&& !Base::judgeClientVersion("0.29.11", $this->client['version'])) {
|
||||
$errorContent = '当前客户端版本低(所需版本≥v0.29.11)。';
|
||||
}
|
||||
break;
|
||||
// Wenxin 机器人
|
||||
case 'ai-wenxin@bot.system':
|
||||
$setting = Base::setting('aibotSetting');
|
||||
$webhookUrl = "{$serverUrl}/ai/wenxin/send";
|
||||
$extras = [
|
||||
'wenxin_key' => $setting['wenxin_key'],
|
||||
'wenxin_secret' => $setting['wenxin_secret'],
|
||||
'wenxin_model' => $setting['wenxin_model'],
|
||||
'server_url' => $serverUrl,
|
||||
];
|
||||
if (empty($extras['wenxin_key'])) {
|
||||
$errorContent = '机器人未启用。';
|
||||
} elseif (in_array($this->client['platform'], ['win', 'mac', 'web'])
|
||||
&& !Base::judgeClientVersion("0.29.11", $this->client['version'])) {
|
||||
$errorContent = '当前客户端版本低(所需版本≥v0.29.12)。';
|
||||
}
|
||||
break;
|
||||
// QianWen 机器人
|
||||
case 'ai-qianwen@bot.system':
|
||||
$setting = Base::setting('aibotSetting');
|
||||
$webhookUrl = "{$serverUrl}/ai/qianwen/send";
|
||||
$extras = [
|
||||
'qianwen_key' => $setting['qianwen_key'],
|
||||
'qianwen_model' => $setting['qianwen_model'],
|
||||
'server_url' => $serverUrl,
|
||||
];
|
||||
if (empty($extras['qianwen_key'])) {
|
||||
$errorContent = '机器人未启用。';
|
||||
} elseif (in_array($this->client['platform'], ['win', 'mac', 'web'])
|
||||
&& !Base::judgeClientVersion("0.29.11", $this->client['version'])) {
|
||||
$errorContent = '当前客户端版本低(所需版本≥v0.29.12)。';
|
||||
}
|
||||
break;
|
||||
// Gemini 机器人
|
||||
case 'ai-gemini@bot.system':
|
||||
$setting = Base::setting('aibotSetting');
|
||||
$webhookUrl = "{$serverUrl}/ai/gemini/send";
|
||||
$extras = [
|
||||
'gemini_key' => $setting['gemini_key'],
|
||||
'gemini_model' => $setting['gemini_model'],
|
||||
'gemini_agency' => $setting['gemini_agency'],
|
||||
'gemini_timeout' => 20,
|
||||
'server_url' => $serverUrl,
|
||||
];
|
||||
if (empty($extras['gemini_key'])) {
|
||||
$errorContent = '机器人未启用。';
|
||||
} elseif (in_array($this->client['platform'], ['win', 'mac', 'web'])
|
||||
&& !Base::judgeClientVersion("0.29.11", $this->client['version'])) {
|
||||
$errorContent = '当前客户端版本低(所需版本≥v0.29.12)。';
|
||||
}
|
||||
break;
|
||||
// 智谱清言 机器人
|
||||
case 'ai-zhipu@bot.system':
|
||||
$setting = Base::setting('aibotSetting');
|
||||
$webhookUrl = "{$serverUrl}/ai/zhipu/send";
|
||||
$extras = [
|
||||
'zhipu_key' => $setting['zhipu_key'],
|
||||
'zhipu_model' => $setting['zhipu_model'],
|
||||
'server_url' => $serverUrl,
|
||||
];
|
||||
if (empty($extras['zhipu_key'])) {
|
||||
$errorContent = '机器人未启用。';
|
||||
} elseif (in_array($this->client['platform'], ['win', 'mac', 'web'])
|
||||
&& !Base::judgeClientVersion("0.29.11", $this->client['version'])) {
|
||||
$errorContent = '当前客户端版本低(所需版本≥v0.29.12)。';
|
||||
}
|
||||
break;
|
||||
// 其他机器人
|
||||
default:
|
||||
$userBot = UserBot::whereBotId($botUser->userid)->first();
|
||||
$webhookUrl = $userBot?->webhook_url;
|
||||
break;
|
||||
if (preg_match('/^ai-(.*?)@bot\.system$/', $botUser->email, $matches)) {
|
||||
$setting = Base::setting('aibotSetting');
|
||||
$type = $matches[1];
|
||||
$extras = [
|
||||
'model_type' => match ($type) {
|
||||
'qianwen' => 'qwen',
|
||||
default => $type,
|
||||
},
|
||||
'model_name' => $setting[$type . '_model'],
|
||||
'system_message' => $setting[$type . '_system'],
|
||||
'api_key' => $setting[$type . '_key'],
|
||||
'agency' => $setting[$type . '_agency'],
|
||||
'server_url' => $serverUrl,
|
||||
];
|
||||
if ($type === 'wenxin') {
|
||||
$extras['api_key'] .= ':' . $setting['wenxin_secret'];
|
||||
}
|
||||
if (empty($extras[$type . '_key'])) {
|
||||
$errorContent = '机器人未启用。';
|
||||
} elseif (in_array($this->client['platform'], ['win', 'mac', 'web'])
|
||||
&& !Base::judgeClientVersion("0.29.11", $this->client['version'])) {
|
||||
$errorContent = '当前客户端版本低(所需版本≥v0.29.11)。';
|
||||
}
|
||||
$webhookUrl = "{$serverUrl}/ai/chat";
|
||||
} else {
|
||||
$userBot = UserBot::whereBotId($botUser->userid)->first();
|
||||
$webhookUrl = $userBot?->webhook_url;
|
||||
}
|
||||
if ($errorContent) {
|
||||
WebSocketDialogMsg::sendMsg(null, $msg->dialog_id, 'template', [
|
||||
|
||||
@ -167,10 +167,15 @@ services:
|
||||
|
||||
ai:
|
||||
container_name: "dootask-ai-${APP_ID}"
|
||||
image: "kuaifan/dooai:0.2.1"
|
||||
image: "kuaifan/dootask-ai:0.0.5"
|
||||
environment:
|
||||
REDIS_HOST: "${REDIS_HOST}"
|
||||
REDIS_PORT: "${REDIS_PORT}"
|
||||
networks:
|
||||
extnetwork:
|
||||
ipv4_address: "${APP_IPPR}.12"
|
||||
depends_on:
|
||||
- redis
|
||||
restart: unless-stopped
|
||||
|
||||
okr:
|
||||
|
||||
@ -195,7 +195,7 @@ server {
|
||||
proxy_set_header Scheme $scheme;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection $connection_upgrade;
|
||||
proxy_pass http://ai:8881/;
|
||||
proxy_pass http://ai:5001/;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -47,7 +47,7 @@
|
||||
</DrawerOverlay>
|
||||
|
||||
<!--AI 机器人-->
|
||||
<DrawerOverlay v-model="aibotShow" placement="right" :size="650">
|
||||
<DrawerOverlay v-model="aibotShow" placement="right" :size="720">
|
||||
<div class="ivu-modal-wrap-apply">
|
||||
<div class="ivu-modal-wrap-apply-title">
|
||||
{{ $L('AI 机器人') }}
|
||||
@ -73,14 +73,19 @@
|
||||
<SystemAibot type="ChatGPT" v-if="aibotTabAction == 'opanai'" />
|
||||
</div>
|
||||
</TabPane>
|
||||
<TabPane label="Claude" name="claude">
|
||||
<div class="aibot-warp">
|
||||
<SystemAibot type="Claude" v-if="aibotTabAction == 'claude'" />
|
||||
</div>
|
||||
</TabPane>
|
||||
<TabPane label="Gemini" name="gemini">
|
||||
<div class="aibot-warp">
|
||||
<SystemAibot type="Gemini" v-if="aibotTabAction == 'gemini'" />
|
||||
</div>
|
||||
</TabPane>
|
||||
<TabPane label="Claude" name="claude">
|
||||
<TabPane :label="$L('智谱清言')" name="zhipu">
|
||||
<div class="aibot-warp">
|
||||
<SystemAibot type="Claude" v-if="aibotTabAction == 'claude'" />
|
||||
<SystemAibot type="Zhipu" v-if="aibotTabAction == 'zhipu'" />
|
||||
</div>
|
||||
</TabPane>
|
||||
<TabPane :label="$L('文心一言')" name="wenxin">
|
||||
@ -93,11 +98,6 @@
|
||||
<SystemAibot type="Qianwen" v-if="aibotTabAction == 'qianwen'" />
|
||||
</div>
|
||||
</TabPane>
|
||||
<TabPane :label="$L('智谱清言')" name="zhipu">
|
||||
<div class="aibot-warp">
|
||||
<SystemAibot type="Zhipu" v-if="aibotTabAction == 'zhipu'" />
|
||||
</div>
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -834,7 +834,7 @@ export default {
|
||||
}
|
||||
}
|
||||
} else if (dialog.type == 'user') {
|
||||
if (this.systemConfig.server_closeai === 'close' && /^ai-(.*?)@bot.system/.test(dialog.email)) {
|
||||
if (this.systemConfig.server_closeai === 'close' && /^ai-(.*?)@bot\.system/.test(dialog.email)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,120 +6,57 @@
|
||||
:rules="ruleData"
|
||||
v-bind="formOptions"
|
||||
@submit.native.prevent>
|
||||
<div class="block-setting-box" v-if="type=='all' || type=='ChatGPT'">
|
||||
<h3>ChatGPT</h3>
|
||||
<div class="block-setting-box" v-if="aiConfig[type]">
|
||||
<h3>{{ type }}</h3>
|
||||
<div class="form-box">
|
||||
<FormItem label="API Key" prop="openai_key">
|
||||
<Input :maxlength="255" v-model="formData.openai_key" type="password" placeholder="OpenAI API Key"/>
|
||||
<div class="form-tip">{{$L('访问OpenAI网站查看')}}: <a href="https://platform.openai.com/account/api-keys" target="_blank">https://platform.openai.com/account/api-keys</a></div>
|
||||
</FormItem>
|
||||
<FormItem :label="$L('模型')" prop="openai_model">
|
||||
<Select v-model="formData.openai_model" placement="top" transfer>
|
||||
<Option value="gpt-4o">gpt-4o</Option>
|
||||
<Option value="gpt-4o-mini">gpt-4o-mini</Option>
|
||||
<Option value="gpt-4-turbo">gpt-4-turbo</Option>
|
||||
<Option value="gpt-3.5-turbo">gpt-3.5-turbo</Option>
|
||||
</Select>
|
||||
<div class="form-tip">{{$L('查看说明')}} <a href="https://platform.openai.com/docs/models" target="_blank">https://platform.openai.com/docs/models</a></div>
|
||||
</FormItem>
|
||||
<FormItem :label="$L('使用代理')" prop="openai_agency">
|
||||
<Input :maxlength="500" v-model="formData.openai_agency" :placeholder="$L('支持 http 或 socks 代理')"/>
|
||||
<div class="form-tip">{{$L('例如:http://proxy.com 或 socks5://proxy.com')}}</div>
|
||||
</FormItem>
|
||||
</div>
|
||||
</div>
|
||||
<div class="block-setting-box" v-if="type=='all' || type=='Claude'">
|
||||
<h3>Claude</h3>
|
||||
<div class="form-box">
|
||||
<FormItem label="Token" prop="claude_token">
|
||||
<Input :maxlength="255" v-model="formData.claude_token" type="password" placeholder="Claude Token"/>
|
||||
<div class="form-tip">{{$L('登录')}} <a href="https://claude.ai" target="_blank">https://claude.ai</a> {{$L('查看 Cookie 中的 sessionKey 便是')}}</div>
|
||||
</FormItem>
|
||||
<FormItem :label="$L('使用代理')" prop="claude_agency">
|
||||
<Input :maxlength="500" v-model="formData.claude_agency" :placeholder="$L('支持 http 或 socks 代理')"/>
|
||||
<div class="form-tip">{{$L('例如:http://proxy.com 或 socks5://proxy.com')}}</div>
|
||||
</FormItem>
|
||||
</div>
|
||||
</div>
|
||||
<div class="block-setting-box" v-if="type=='all' || type=='Wenxin'">
|
||||
<h3>文心一言 (Wenxin)</h3>
|
||||
<div class="form-box">
|
||||
<FormItem label="API Key" prop="wenxin_key">
|
||||
<Input :maxlength="255" v-model="formData.wenxin_key" type="password" placeholder="API Key"/>
|
||||
<div class="form-tip">{{$L('获取方式')}} <a href="https://ai.baidu.com/ai-doc/REFERENCE/Ck3dwjgn3#3-%E8%8E%B7%E5%8F%96%E5%AF%86%E9%92%A5" target="_blank">https://ai.baidu.com/ai-doc/REFERENCE/Ck3dwjgn3</a></div>
|
||||
</FormItem>
|
||||
<FormItem label="API Secret" prop="wenxin_secret">
|
||||
<Input :maxlength="500" v-model="formData.wenxin_secret" type="password" placeholder="API Secret"/>
|
||||
<div class="form-tip">{{$L('获取方式')}} <a href="https://ai.baidu.com/ai-doc/REFERENCE/Ck3dwjgn3#3-%E8%8E%B7%E5%8F%96%E5%AF%86%E9%92%A5" target="_blank">https://ai.baidu.com/ai-doc/REFERENCE/Ck3dwjgn3</a></div>
|
||||
</FormItem>
|
||||
<FormItem :label="$L('模型')" prop="wenxin_model">
|
||||
<Select v-model="formData.wenxin_model" placement="top" transfer>
|
||||
<Option value="completions_pro">ERNIE-Bot 4.0</Option>
|
||||
<Option value="completions">ERNIE-Bot</Option>
|
||||
<Option value="eb-instant">ERNIE-Bot-turbo</Option>
|
||||
<Option value="llama_2_7b">Llama-2-7b-chat</Option>
|
||||
<Option value="llama_2_13b">Llama-2-13B-Chat</Option>
|
||||
</Select>
|
||||
<div class="form-tip">{{$L('查看说明')}} <a href="https://cloud.baidu.com/doc/WENXINWORKSHOP/s/vliu6vq7u" target="_blank">https://cloud.baidu.com/doc/WENXINWORKSHOP/s/vliu6vq7u</a></div>
|
||||
</FormItem>
|
||||
</div>
|
||||
</div>
|
||||
<div class="block-setting-box" v-if="type=='all' || type=='Qianwen'">
|
||||
<h3>通义千问 (Qianwen)</h3>
|
||||
<div class="form-box">
|
||||
<FormItem label="API Key" prop="qianwen_key">
|
||||
<Input :maxlength="255" v-model="formData.qianwen_key" type="password" placeholder="API Key"/>
|
||||
<div class="form-tip">{{$L('获取方式')}} <a href="https://help.aliyun.com/document_detail/611472.html" target="_blank">https://help.aliyun.com/document_detail/611472.html</a></div>
|
||||
</FormItem>
|
||||
<FormItem :label="$L('模型')" prop="qianwen_model">
|
||||
<Select v-model="formData.qianwen_model" placement="top" transfer>
|
||||
<Option value="qwen-v1">qwen-v1</Option>
|
||||
<Option value="qwen-plus-v1">qwen-plus-v1</Option>
|
||||
</Select>
|
||||
<div class="form-tip">{{$L('查看说明')}} <a href="https://help.aliyun.com/document_detail/2399481.html" target="_blank">https://help.aliyun.com/document_detail/2399481.html</a></div>
|
||||
</FormItem>
|
||||
</div>
|
||||
</div>
|
||||
<div class="block-setting-box" v-if="type=='all' || type=='Gemini'">
|
||||
<h3>Gemini</h3>
|
||||
<div class="form-box">
|
||||
<FormItem label="API Key" prop="gemini_key">
|
||||
<Input :maxlength="255" v-model="formData.gemini_key" type="password" placeholder="API Key"/>
|
||||
<div class="form-tip">{{$L('获取方式')}} <a href="https://ai.google.dev/tutorials/setup?hl=zh-cn" target="_blank">https://ai.google.dev/tutorials/setup?hl=zh-cn</a></div>
|
||||
</FormItem>
|
||||
<FormItem :label="$L('模型')" prop="gemini_model">
|
||||
<Select v-model="formData.gemini_model" placement="top" transfer>
|
||||
<Option value="gemini-1.0-pro">gemini-1.0-pro</Option>
|
||||
</Select>
|
||||
<div class="form-tip">{{$L('查看说明')}} <a href="https://ai.google.dev/models?hl=zh-cn" target="_blank">https://ai.google.dev/models?hl=zh-cn</a></div>
|
||||
</FormItem>
|
||||
<FormItem :label="$L('使用代理')" prop="gemini_agency">
|
||||
<Input :maxlength="500" v-model="formData.gemini_agency" :placeholder="$L('支持 http 或 socks 代理')"/>
|
||||
<div class="form-tip">{{$L('例如:http://proxy.com 或 socks5://proxy.com')}}</div>
|
||||
</FormItem>
|
||||
</div>
|
||||
</div>
|
||||
<div class="block-setting-box" v-if="type=='all' || type=='Zhipu'">
|
||||
<h3>智谱清言</h3>
|
||||
<div class="form-box">
|
||||
<FormItem label="API Key" prop="zhipu_key">
|
||||
<Input :maxlength="255" v-model="formData.zhipu_key" type="password" placeholder="API Key"/>
|
||||
<div class="form-tip">{{$L('获取方式')}} <a href="https://open.bigmodel.cn/usercenter/apikeys" target="_blank">https://open.bigmodel.cn/usercenter/apikeys</a></div>
|
||||
</FormItem>
|
||||
<FormItem :label="$L('模型')" prop="zhipu_model">
|
||||
<Select v-model="formData.zhipu_model" placement="top" transfer>
|
||||
<Option value="glm-4">glm-4</Option>
|
||||
<Option value="glm-4v">glm-4v</Option>
|
||||
<Option value="glm-3-turbo">glm-3-turbo</Option>
|
||||
</Select>
|
||||
<div class="form-tip">{{$L('查看说明')}} <a href="https://open.bigmodel.cn/dev/howuse/model" target="_blank">https://open.bigmodel.cn/dev/howuse/model</a></div>
|
||||
</FormItem>
|
||||
<template v-for="field in aiConfig[type].fields">
|
||||
<FormItem :label="$L(field.label)" :prop="field.prop">
|
||||
<template v-if="field.type === 'password'">
|
||||
<Input
|
||||
:maxlength="255"
|
||||
v-model="formData[field.prop]"
|
||||
type="password"
|
||||
:placeholder="$L(field.placeholder)"/>
|
||||
</template>
|
||||
<template v-else-if="field.type === 'select'">
|
||||
<Select v-model="formData[field.prop]" placement="top" transfer>
|
||||
<Option v-for="option in field.options"
|
||||
:key="option.value"
|
||||
:value="option.value">
|
||||
{{ option.value }}
|
||||
</Option>
|
||||
</Select>
|
||||
</template>
|
||||
<template v-else-if="field.type === 'textarea'">
|
||||
<Input
|
||||
:maxlength="500"
|
||||
type="textarea"
|
||||
:autosize="{minRows:2,maxRows:5}"
|
||||
v-model="formData[field.prop]"
|
||||
:placeholder="$L(field.placeholder)"/>
|
||||
</template>
|
||||
<template v-else>
|
||||
<Input
|
||||
:maxlength="500"
|
||||
v-model="formData[field.prop]"
|
||||
:placeholder="$L(field.placeholder)"/>
|
||||
</template>
|
||||
<div v-if="field.link || field.tip" class="form-tip">
|
||||
<template v-if="field.link">
|
||||
{{$L(field.tipPrefix || '获取方式')}} <a :href="field.link" target="_blank">{{ field.link }}</a>
|
||||
</template>
|
||||
<template v-else-if="field.tip">
|
||||
{{$L(field.tip)}}
|
||||
</template>
|
||||
</div>
|
||||
</FormItem>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
<div class="setting-footer">
|
||||
<Button :loading="loadIng > 0" type="primary" @click="submitForm">{{ $L('提交') }}</Button>
|
||||
<Button :loading="loadIng > 0" @click="resetForm" style="margin-left: 8px">{{ $L('重置') }}</Button>
|
||||
<Button :loading="loadIng > 0" @click="resetForm">{{ $L('重置') }}</Button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -131,7 +68,7 @@ export default {
|
||||
name: "SystemAibot",
|
||||
props: {
|
||||
type: {
|
||||
default: 'all'
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@ -139,17 +76,247 @@ export default {
|
||||
loadIng: 0,
|
||||
formData: {},
|
||||
ruleData: {},
|
||||
aiConfig: {
|
||||
ChatGPT: {
|
||||
fields: [
|
||||
{
|
||||
label: 'API Key',
|
||||
prop: 'openai_key',
|
||||
type: 'password',
|
||||
placeholder: 'OpenAI API Key',
|
||||
tipPrefix: '访问OpenAI网站查看',
|
||||
link: 'https://platform.openai.com/account/api-keys'
|
||||
},
|
||||
{
|
||||
label: '模型',
|
||||
prop: 'openai_model',
|
||||
type: 'select',
|
||||
options: [
|
||||
{ value: 'gpt-4' },
|
||||
{ value: 'gpt-4-turbo' },
|
||||
{ value: 'gpt-4o' },
|
||||
{ value: 'gpt-4o-mini' },
|
||||
{ value: 'gpt-3.5-turbo' },
|
||||
{ value: 'gpt-3.5-turbo-16k' },
|
||||
{ value: 'gpt-3.5-turbo-0125' },
|
||||
{ value: 'gpt-3.5-turbo-1106' }
|
||||
],
|
||||
tipPrefix: '查看说明',
|
||||
link: 'https://platform.openai.com/docs/models'
|
||||
},
|
||||
{
|
||||
label: '使用代理',
|
||||
prop: 'openai_agency',
|
||||
placeholder: '支持 http 或 socks 代理',
|
||||
tip: '例如:http://proxy.com 或 socks5://proxy.com'
|
||||
},
|
||||
{
|
||||
label: '默认提示词',
|
||||
prop: 'openai_system',
|
||||
type: 'textarea',
|
||||
placeholder: '请输入默认提示词',
|
||||
tip: '例如:你是一个人开发的AI助手'
|
||||
}
|
||||
]
|
||||
},
|
||||
Claude: {
|
||||
fields: [
|
||||
{
|
||||
label: 'API Key',
|
||||
prop: 'claude_key',
|
||||
type: 'password',
|
||||
placeholder: 'Claude API Key',
|
||||
link: 'https://docs.anthropic.com/en/api/getting-started'
|
||||
},
|
||||
{
|
||||
label: '模型',
|
||||
prop: 'claude_model',
|
||||
type: 'select',
|
||||
options: [
|
||||
{ value: 'claude-3-opus-20240229' },
|
||||
{ value: 'claude-3-sonnet-20240229' },
|
||||
{ value: 'claude-2.1' },
|
||||
{ value: 'claude-2.0' }
|
||||
],
|
||||
tipPrefix: '查看说明',
|
||||
link: 'https://docs.anthropic.com/en/docs/about-claude/models'
|
||||
},
|
||||
{
|
||||
label: '使用代理',
|
||||
prop: 'claude_agency',
|
||||
placeholder: '支持 http 或 socks 代理',
|
||||
tip: '例如:http://proxy.com 或 socks5://proxy.com'
|
||||
},
|
||||
{
|
||||
label: '默认提示词',
|
||||
prop: 'claude_system',
|
||||
type: 'textarea',
|
||||
placeholder: '请输入默认提示词',
|
||||
tip: '例如:你是一个人开发的AI助手'
|
||||
}
|
||||
]
|
||||
},
|
||||
Gemini: {
|
||||
fields: [
|
||||
{
|
||||
label: 'API Key',
|
||||
prop: 'gemini_key',
|
||||
type: 'password',
|
||||
placeholder: 'Gemini API Key',
|
||||
link: 'https://makersuite.google.com/app/apikey'
|
||||
},
|
||||
{
|
||||
label: '模型',
|
||||
prop: 'gemini_model',
|
||||
type: 'select',
|
||||
options: [
|
||||
{ value: 'gemini-pro' },
|
||||
{ value: 'gemini-pro-vision' }
|
||||
],
|
||||
tipPrefix: '查看说明',
|
||||
link: 'https://ai.google.dev/models/gemini'
|
||||
},
|
||||
{
|
||||
label: '使用代理',
|
||||
prop: 'gemini_agency',
|
||||
placeholder: '仅支持 http 代理',
|
||||
tip: '例如:http://proxy.com 或 https://proxy.com'
|
||||
},
|
||||
{
|
||||
label: '默认提示词',
|
||||
prop: 'gemini_system',
|
||||
type: 'textarea',
|
||||
placeholder: '请输入默认提示词',
|
||||
tip: '例如:你是一个人开发的AI助手'
|
||||
}
|
||||
]
|
||||
},
|
||||
Zhipu: {
|
||||
fields: [
|
||||
{
|
||||
label: 'API Key',
|
||||
prop: 'zhipu_key',
|
||||
type: 'password',
|
||||
placeholder: 'Zhipu API Key',
|
||||
link: 'https://bigmodel.cn/usercenter/apikeys'
|
||||
},
|
||||
{
|
||||
label: '模型',
|
||||
prop: 'zhipu_model',
|
||||
type: 'select',
|
||||
options: [
|
||||
{ value: 'glm-4' },
|
||||
{ value: 'glm-4v' },
|
||||
{ value: 'glm-3-turbo' }
|
||||
],
|
||||
tipPrefix: '查看说明',
|
||||
link: 'https://open.bigmodel.cn/dev/api'
|
||||
},
|
||||
{
|
||||
label: '使用代理',
|
||||
prop: 'zhipu_agency',
|
||||
placeholder: '支持 http 或 socks 代理',
|
||||
tip: '例如:http://proxy.com 或 socks5://proxy.com'
|
||||
},
|
||||
{
|
||||
label: '默认提示词',
|
||||
prop: 'zhipu_system',
|
||||
type: 'textarea',
|
||||
placeholder: '请输入默认提示词',
|
||||
tip: '例如:你是一个人开发的AI助手'
|
||||
}
|
||||
]
|
||||
},
|
||||
Qianwen: {
|
||||
fields: [
|
||||
{
|
||||
label: 'API Key',
|
||||
prop: 'qianwen_key',
|
||||
type: 'password',
|
||||
placeholder: 'Qianwen API Key',
|
||||
link: 'https://help.aliyun.com/zh/model-studio/developer-reference/get-api-key'
|
||||
},
|
||||
{
|
||||
label: '模型',
|
||||
prop: 'qianwen_model',
|
||||
type: 'select',
|
||||
options: [
|
||||
{ value: 'qwen-turbo' },
|
||||
{ value: 'qwen-plus' },
|
||||
{ value: 'qwen-max' },
|
||||
{ value: 'qwen-max-longcontext' }
|
||||
],
|
||||
tipPrefix: '查看说明',
|
||||
link: 'https://help.aliyun.com/zh/model-studio/getting-started/models'
|
||||
},
|
||||
{
|
||||
label: '使用代理',
|
||||
prop: 'qianwen_agency',
|
||||
placeholder: '支持 http 或 socks 代理',
|
||||
tip: '例如:http://proxy.com 或 socks5://proxy.com'
|
||||
},
|
||||
{
|
||||
label: '默认提示词',
|
||||
prop: 'qianwen_system',
|
||||
type: 'textarea',
|
||||
placeholder: '请输入默认提示词',
|
||||
tip: '例如:你是一个人开发的AI助手'
|
||||
}
|
||||
]
|
||||
},
|
||||
Wenxin: {
|
||||
fields: [
|
||||
{
|
||||
label: 'API Key',
|
||||
prop: 'wenxin_key',
|
||||
type: 'password',
|
||||
placeholder: 'Wenxin API Key',
|
||||
link: 'https://console.bce.baidu.com/qianfan/ais/console/applicationConsole/application'
|
||||
},
|
||||
{
|
||||
label: 'Secret Key',
|
||||
prop: 'wenxin_secret',
|
||||
type: 'password',
|
||||
placeholder: 'Wenxin Secret Key',
|
||||
link: 'https://console.bce.baidu.com/qianfan/ais/console/applicationConsole/application'
|
||||
},
|
||||
{
|
||||
label: '模型',
|
||||
prop: 'wenxin_model',
|
||||
type: 'select',
|
||||
options: [
|
||||
{ value: 'ernie-bot-4' },
|
||||
{ value: 'ernie-bot-8k' },
|
||||
{ value: 'ernie-bot-turbo' },
|
||||
{ value: 'ernie-bot' }
|
||||
],
|
||||
tipPrefix: '查看说明',
|
||||
link: 'https://cloud.baidu.com/doc/WENXINWORKSHOP/s/Blfmc9dlf'
|
||||
},
|
||||
{
|
||||
label: '使用代理',
|
||||
prop: 'wenxin_agency',
|
||||
placeholder: '支持 http 或 socks 代理',
|
||||
tip: '例如:http://proxy.com 或 socks5://proxy.com'
|
||||
},
|
||||
{
|
||||
label: '默认提示词',
|
||||
prop: 'wenxin_system',
|
||||
type: 'textarea',
|
||||
placeholder: '请输入默认提示词',
|
||||
tip: '例如:你是一个人开发的AI助手'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.systemSetting();
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['formOptions']),
|
||||
},
|
||||
|
||||
methods: {
|
||||
submitForm() {
|
||||
this.$refs.formData.validate((valid) => {
|
||||
@ -158,11 +325,9 @@ export default {
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
resetForm() {
|
||||
this.formData = $A.cloneJSON(this.formDatum_bak);
|
||||
},
|
||||
|
||||
systemSetting(save) {
|
||||
this.loadIng++;
|
||||
this.$store.dispatch("call", {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user