diff --git a/app/Models/WebSocketDialogSession.php b/app/Models/WebSocketDialogSession.php index 7a0f6516e..ef7cebcbd 100644 --- a/app/Models/WebSocketDialogSession.php +++ b/app/Models/WebSocketDialogSession.php @@ -3,6 +3,8 @@ namespace App\Models; use App\Module\Base; +use App\Module\Extranet; +use Swoole\Coroutine; use Cache; /** @@ -69,17 +71,30 @@ class WebSocketDialogSession extends AbstractModel if (Cache::has($cacheKey)) { return; } + $originalTitle = $dialogMsg->key ?: $dialogMsg->msg['text'] ?: 'Untitled'; + $title = Base::cutStr($originalTitle, 100); + if ($title == '...') { + return; + } $session = self::whereId($sessionId)->first(); if (!$session) { return; } - $title = Base::cutStr($dialogMsg->key ?: $dialogMsg->msg['text'], 100); - if (empty($title)) { - return; - } $session->title = $title; $session->save(); - // todo 通过AI生成标题 Cache::forever($cacheKey, true); + // 通过AI接口更新对话标题 + go(function () use ($session, $title, $originalTitle) { + Coroutine::sleep(0.1); + $res = Extranet::openAIGenerateTitle($originalTitle); + if (Base::isError($res)) { + return; + } + $newTitle = $res['data']; + if ($newTitle && $newTitle != $title) { + $session->title = Base::cutStr($newTitle, 100); + $session->save(); + } + }); } } diff --git a/app/Module/Extranet.php b/app/Module/Extranet.php index f1ff7518c..76b56412c 100644 --- a/app/Module/Extranet.php +++ b/app/Module/Extranet.php @@ -108,6 +108,57 @@ class Extranet return Base::retSuccess("success", $result); } + /** + * 通过 openAI 生成标题 + * @param $text + * @return array + */ + public static function openAIGenerateTitle($text) + { + $aibotSetting = Base::setting('aibotSetting'); + if (empty($aibotSetting['openai_key'])) { + return Base::retError("AI接口未配置"); + } + $extra = [ + 'Content-Type' => 'application/json', + 'Authorization' => 'Bearer ' . $aibotSetting['openai_key'], + ]; + if ($aibotSetting['openai_agency']) { + $extra['CURLOPT_PROXY'] = $aibotSetting['openai_agency']; + if (str_contains($aibotSetting['openai_agency'], 'socks')) { + $extra['CURLOPT_PROXYTYPE'] = CURLPROXY_SOCKS5; + } else { + $extra['CURLOPT_PROXYTYPE'] = CURLPROXY_HTTP; + } + } + $res = Ihttp::ihttp_request('https://api.openai.com/v1/chat/completions', json_encode([ + "model" => "gpt-3.5-turbo", + "messages" => [ + [ + "role" => "system", + "content" => "你是一个专业的标题生成器,擅长为对话生成简洁的标题,请将提供的文本生成一个标题。" + ], + [ + "role" => "user", + "content" => $text + ] + ] + ]), $extra, 15); + if (Base::isError($res)) { + return Base::retError("生成失败", $res); + } + $resData = Base::json2array($res['data']); + if (empty($resData['choices'])) { + return Base::retError("生成失败", $resData); + } + $result = $resData['choices'][0]['message']['content']; + $result = preg_replace('/^\"|\"$/', '', $result); + if (empty($result)) { + return Base::retError("生成失败", $result); + } + return Base::retSuccess("success", $result); + } + /** * 获取IP地址经纬度 * @param string $ip diff --git a/resources/assets/sass/pages/components/dialog-session-history.scss b/resources/assets/sass/pages/components/dialog-session-history.scss index 01d0f5103..d22b2d48c 100644 --- a/resources/assets/sass/pages/components/dialog-session-history.scss +++ b/resources/assets/sass/pages/components/dialog-session-history.scss @@ -29,9 +29,7 @@ > li { list-style: none; padding: 12px; - margin: 6px; - border-top-right-radius: 6px; - border-top-left-radius: 6px; + margin: 0 6px; position: relative; &::after { @@ -80,6 +78,7 @@ .history-time { float: right; opacity: 0.5; + font-size: 13px; } } }