perf: AI机器人支持多会话

This commit is contained in:
kuaifan 2025-02-10 16:48:08 +09:00
parent da0fa31181
commit 501235ef12
5 changed files with 186 additions and 14 deletions

View File

@ -25,6 +25,7 @@ use App\Models\WebSocketDialogConfig;
use App\Models\WebSocketDialogMsgRead;
use App\Models\WebSocketDialogMsgTodo;
use App\Models\WebSocketDialogMsgTranslate;
use App\Models\WebSocketDialogSession;
use Hhxsv5\LaravelS\Swoole\Task\Task;
/**
@ -3090,4 +3091,124 @@ class DialogController extends AbstractController
return Base::retSuccess('保存成功');
}
/**
* @api {get} api/dialog/session/create 62. AI-开启新会话
*
* @apiDescription 需要token身份仅限与AI用户会话
* @apiVersion 1.0.0
* @apiGroup dialog
* @apiName session_create
*
* @apiParam {Number} dialog_id 对话ID
*
* @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述)
* @apiSuccess {Object} data 返回数据
*/
public function session__create()
{
User::auth();
//
$dialog_id = intval(Request::input('dialog_id'));
//
$dialog = WebSocketDialog::checkDialog($dialog_id);
//
if ($dialog->type != 'user') {
return Base::retError('当前对话不支持');
}
//
$hasAiUser = WebSocketDialogUser::join('users as u', 'web_socket_dialog_users.userid', '=', 'u.userid')
->where('dialog_id', $dialog->id)
->where('u.email', 'like', 'ai-%@bot.system')
->exists();
if (!$hasAiUser) {
return Base::retError('当前对话不支持');
}
//
$session = WebSocketDialogSession::whereDialogId($dialog->id)
->whereTitle('')
->first();
if ($session) {
$dialog->session_id = $session->id;
$dialog->save();
return Base::retSuccess('success', $session);
}
//
$session = WebSocketDialogSession::create([
'dialog_id' => $dialog->id,
'status' => 1,
'title' => '',
]);
$session->save();
$dialog->session_id = $session->id;
$dialog->save();
//
return Base::retSuccess('success', $session);
}
/**
* @api {get} api/dialog/session/list 63. AI-获取会话列表
*
* @apiDescription 需要token身份
* @apiVersion 1.0.0
* @apiGroup dialog
* @apiName session_list
*
* @apiParam {Number} dialog_id 对话ID
*
* @apiParam {Number} [page] 当前页,默认:1
* @apiParam {Number} [pagesize] 每页显示数量,默认:20,最大:50
*
* @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述)
* @apiSuccess {Object} data 返回数据
*/
public function session__list()
{
User::auth();
//
$dialog_id = intval(Request::input('dialog_id'));
//
$dialog = WebSocketDialog::checkDialog($dialog_id);
//
$sessions = WebSocketDialogSession::whereDialogId($dialog->id)
->orderByDesc('id')
->paginate(Base::getPaginate(100, 10));
//
return Base::retSuccess('success', $sessions);
}
/**
* @api {get} api/dialog/session/open 64. AI-打开会话
*
* @apiDescription 需要token身份
* @apiVersion 1.0.0
* @apiGroup dialog
* @apiName session_open
*
* @apiParam {Number} session_id 会话ID
*
* @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述)
* @apiSuccess {Object} data 返回数据
*/
public function session__open()
{
User::auth();
//
$session_id = intval(Request::input('session_id'));
//
$session = WebSocketDialogSession::whereId($session_id)->first();
if (empty($session)) {
return Base::retError('会话不存在或已被删除');
}
//
$dialog = WebSocketDialog::checkDialog($session->dialog_id);
//
$dialog->session_id = $session->id;
$dialog->save();
//
return Base::retSuccess('success', $session);
}
}

View File

@ -205,15 +205,15 @@ class UserBot extends AbstractModel
]
],
[
'key' => '~ai-chat-new',
'label' => Doo::translate('开启新话'),
'key' => '~ai-session-create',
'label' => Doo::translate('开启新话'),
'config' => [
'model' => $aibotSetting[$match[1] . '_model']
]
],
[
'key' => '~ai-chat-history',
'label' => Doo::translate('历史话'),
'key' => '~ai-session-history',
'label' => Doo::translate('历史话'),
]
];
}

View File

@ -1196,6 +1196,8 @@ class WebSocketDialogMsg extends AbstractModel
$dialogMsg->send = 1;
$dialogMsg->generateKeyAndSave($search_key);
//
WebSocketDialogSession::updateTitle($dialogMsg->session_id, $dialogMsg);
//
if ($dialogMsg->type === 'meeting') {
MeetingMsg::createInstance([
'meetingid' => $dialogMsg->msg['meetingid'],

View File

@ -2,6 +2,9 @@
namespace App\Models;
use App\Module\Base;
use Cache;
/**
* App\Models\WebSocketDialogSession
*
@ -48,4 +51,35 @@ class WebSocketDialogSession extends AbstractModel
{
return $this->belongsTo(WebSocketDialog::class, 'dialog_id');
}
/**
* @param $sessionId
* @param WebSocketDialogMsg $dialogMsg
* @return void
*/
public static function updateTitle($sessionId, $dialogMsg)
{
if (!$sessionId) {
return;
}
if ($dialogMsg->type != 'text') {
return;
}
$cacheKey = 'dialog_session_title_' . $sessionId;
if (Cache::has($cacheKey)) {
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);
}
}

View File

@ -1321,12 +1321,7 @@ export default {
},
msgType() {
this.getMsgs({
dialog_id: this.dialogId,
msg_id: this.msgId,
msg_type: this.msgType,
clear_before: true
}).catch(_ => {})
this.onGetMsgClear()
},
searchKey(key) {
@ -1922,15 +1917,26 @@ export default {
}
break;
//
case "~ai-chat-new":
//
case "~ai-session-create":
if (!this.isAiBot) {
return
}
this.$store.dispatch("call", {
url: 'dialog/session/create',
data: {
dialog_id: this.dialogId,
},
spinner: 300
}).then(() => {
this.onGetMsgClear()
}).catch(({msg}) => {
$A.modalError(msg)
});
break;
//
case "~ai-chat-history":
//
case "~ai-session-history":
if (!this.isAiBot) {
return
}
@ -2578,6 +2584,15 @@ export default {
this.$store.dispatch("openOkr", this.dialogData.link_id);
},
onGetMsgClear() {
this.getMsgs({
dialog_id: this.dialogId,
msg_id: this.msgId,
msg_type: this.msgType,
clear_before: true
}).catch(_ => {})
},
onReGetMsg() {
this.scrollToBottomRefresh = false
this.getMsgs({