perf: 更新 AI 支持更多模型和支持提示词

This commit is contained in:
kuaifan 2024-11-29 21:11:16 +08:00
parent 61b1206091
commit 0d4b005f4e
10 changed files with 371 additions and 267 deletions

View File

@ -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' => [

View File

@ -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);
}
}
}

View File

@ -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

View File

@ -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',

View File

@ -409,113 +409,33 @@ class BotReceiveMsgTask extends AbstractTask
$userBot = null;
$extras = [];
$errorContent = null;
switch ($botUser->email) {
// ChatGPT 机器人
case 'ai-openai@bot.system':
if (preg_match('/^ai-(.*?)@bot\.system$/', $botUser->email, $matches)) {
$setting = Base::setting('aibotSetting');
$webhookUrl = "{$serverUrl}/ai/openai/send";
$type = $matches[1];
$extras = [
'openai_key' => $setting['openai_key'],
'openai_agency' => $setting['openai_agency'],
'openai_model' => $setting['openai_model'],
'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,
'chunk_size' => 7,
];
if (empty($extras['openai_key'])) {
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)。';
}
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:
$webhookUrl = "{$serverUrl}/ai/chat";
} else {
$userBot = UserBot::whereBotId($botUser->userid)->first();
$webhookUrl = $userBot?->webhook_url;
break;
}
if ($errorContent) {
WebSocketDialogMsg::sendMsg(null, $msg->dialog_id, 'template', [

View File

@ -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:

View File

@ -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/;
}
}

View File

@ -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>

View File

@ -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
}
}

View File

@ -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>
<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>
<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>
</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>
</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>
</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", {