diff --git a/app/Http/Controllers/Api/SystemController.php b/app/Http/Controllers/Api/SystemController.php index ae5379972..3e46f3b8c 100755 --- a/app/Http/Controllers/Api/SystemController.php +++ b/app/Http/Controllers/Api/SystemController.php @@ -331,7 +331,8 @@ class SystemController extends AbstractController * @apiGroup system * @apiName setting__aibot_defmodels * - * @apiParam {String} type AI类型 + * @apiParam {String} type AI类型 + * @apiParam {String} [base_url] 基础URL(仅 type=ollama 时有效) * * @apiSuccess {Number} ret 返回状态码(1正确、0错误) * @apiSuccess {String} msg 返回信息(错误描述) @@ -340,6 +341,13 @@ class SystemController extends AbstractController public function setting__aibot_defmodels() { $type = trim(Request::input('type')); + $baseUrl = trim(Request::input('base_url')); + if ($type == 'ollama') { + if (empty($baseUrl)) { + return Base::retError('请填写基础URL'); + } + return Extranet::ollamaModels($baseUrl); + } $models = Setting::AIDefaultModels($type); if (empty($models)) { return Base::retError('未找到默认模型'); diff --git a/app/Module/Extranet.php b/app/Module/Extranet.php index 6eed2c568..bc2db2a82 100644 --- a/app/Module/Extranet.php +++ b/app/Module/Extranet.php @@ -159,6 +159,35 @@ class Extranet return Base::retSuccess("success", $result); } + /** + * 获取 ollama 模型 + * @param $baseUrl + * @return array + */ + public static function ollamaModels($baseUrl) + { + $res = Ihttp::ihttp_request($baseUrl . '/api/tags', [], [], 15); + if (Base::isError($res)) { + return Base::retError("获取失败", $res); + } + $resData = Base::json2array($res['data']); + if (empty($resData['models'])) { + return Base::retError("获取失败", $resData); + } + $models = []; + foreach ($resData['models'] as $model) { + if ($model['name'] !== $model['model']) { + $models[] = "{$model['model']} | {$model['name']}"; + } else { + $models[] = $model['model']; + } + } + return Base::retSuccess("success", [ + 'models' => $models, + 'original' => $resData['models'] + ]); + } + /** * 获取IP地址经纬度 * @param string $ip diff --git a/app/Tasks/BotReceiveMsgTask.php b/app/Tasks/BotReceiveMsgTask.php index 52fef2e82..790491c7d 100644 --- a/app/Tasks/BotReceiveMsgTask.php +++ b/app/Tasks/BotReceiveMsgTask.php @@ -443,6 +443,9 @@ class BotReceiveMsgTask extends AbstractTask if ($type === 'wenxin') { $extras['api_key'] .= ':' . $setting['wenxin_secret']; } + if ($type === 'ollama' && empty($extras['api_key'])) { + $extras['api_key'] = Base::strRandom(6); + } if (empty($extras['api_key'])) { $errorContent = '机器人未启用。'; } diff --git a/resources/assets/js/pages/manage/setting/components/SystemAibot.vue b/resources/assets/js/pages/manage/setting/components/SystemAibot.vue index 48a0c2eaa..b3dbbc8c6 100644 --- a/resources/assets/js/pages/manage/setting/components/SystemAibot.vue +++ b/resources/assets/js/pages/manage/setting/components/SystemAibot.vue @@ -182,8 +182,17 @@ export default { functionClick(prop) { if (prop === `${this.type}_models`) { + const data = {}; + if (this.type === 'ollama') { + if (!this.formData[`${this.type}_base_url`]) { + $A.modalError('请先填写 Base URL'); + return; + } + data.base_url = this.formData[`${this.type}_base_url`]; + } this.$store.dispatch("call", { url: 'system/setting/aibot_defmodels?type=' + this.type, + data, spinner: 600, }).then(({data}) => { this.formData[prop] = data.models.join('\n'); diff --git a/resources/assets/js/store/ai.js b/resources/assets/js/store/ai.js index d22da68bf..dc7bdd4fc 100644 --- a/resources/assets/js/store/ai.js +++ b/resources/assets/js/store/ai.js @@ -200,11 +200,17 @@ const AISystemConfig = { { prop: "key", placeholder: "Ollama API Key", + tip: "如果没有请留空", }, { prop: "models", link: "https://ollama.com/models", - functions: null, + functions: "获取本地模型列表", + }, + { + prop: "base_url", + placeholder: "Enter base URL...", + tip: "API请求的URL路径", } ] },