feat: 移除未使用的函数和代码,优化BotReceiveMsgTask和WebSocketDialogMsg的消息处理逻辑

This commit is contained in:
kuaifan 2025-11-11 05:31:59 +00:00
parent 477bb1ac8f
commit 944824b552
4 changed files with 24 additions and 253 deletions

View File

@ -33,7 +33,6 @@ use App\Models\WebSocketDialogSession;
use App\Models\UserRecentItem;
use App\Module\Table\OnlineData;
use App\Module\ZincSearch\ZincSearchDialogMsg;
use App\Tasks\BotReceiveMsgTask;
use Hhxsv5\LaravelS\Swoole\Task\Task;
/**
@ -2494,33 +2493,6 @@ class DialogController extends AbstractController
return Base::retSuccess("success", $data);
}
/**
* @api {post} api/dialog/msg/webhookmsg2ai 转换为AI对话
*
* @apiDescription 需要token身份将webhook消息转换为适合AI对话的格式消息用于AI对话
* @apiVersion 1.0.0
* @apiGroup dialog
* @apiName msg__webhookmsg2ai
*
* @apiParam {String} msg 消息内容
*
* @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述)
* @apiSuccess {Object} data 返回数据
*/
public function msg__webhookmsg2ai()
{
User::auth();
//
$msg = Request::input('msg');
try {
$res = BotReceiveMsgTask::convertMentionForAI($msg);
return Base::retSuccess("success", ['msg' => $res]);
} catch (\Exception $e) {
return Base::retError($e->getMessage());
}
}
/**
* @api {get} api/dialog/group/add 新增群组
*

View File

@ -1948,66 +1948,6 @@ class ProjectTask extends AbstractModel
return true;
}
/**
* 生成AI上下文
* @return array
*/
public function AIContext()
{
$contexts = [];
if ($this->archived_at) {
$contexts[] = "任务状态:已归档";
$contexts[] = "归档时间:" . $this->archived_at;
} elseif ($this->complete_at) {
$contexts[] = "任务状态:已完成";
$contexts[] = "完成时间:" . $this->complete_at;
} elseif ($this->end_at && Carbon::parse($this->end_at)->lt(Carbon::now())) {
$contexts[] = "任务状态:已过期";
$contexts[] = "任务截止时间:" . $this->end_at;
} else {
$contexts[] = "任务状态:进行中";
if ($this->start_at) {
$contexts[] = "任务开始时间:" . $this->start_at;
}
if ($this->end_at) {
$contexts[] = "任务截止时间:" . $this->end_at;
}
}
$contexts[] = "当前系统时间:" . Carbon::now()->toDateTimeString();
if ($this->content) {
$taskDesc = $this->content?->getContentInfo();
if ($taskDesc) {
$descContent = Base::cutStr(Base::html2markdown($taskDesc['content'], ['strip_tags' => true]), 2000);
$contexts[] = <<<EOF
任务描述:
```md
{$descContent}
```
EOF;
}
}
$subTask = ProjectTask::select(['id', 'name', 'complete_at', 'end_at'])->whereParentId($this->id)->get();
if ($subTask->isNotEmpty()) {
$subTaskContent = $subTask->map(function($item) {
if ($item->complete_at) {
$status = " (已完成)";
} elseif ($item->end_at && Carbon::parse($item->end_at)->lt(Carbon::now())) {
$status = " (已过期)";
} else {
$status = " (进行中)";
}
return " - {$item->name} {$status}";
})->join("\n");
if ($subTaskContent) {
$contexts[] = <<<EOF
子任务列表:
{$subTaskContent}
EOF;
}
}
return $contexts;
}
/**
* 获取任务
* @param $task_id

View File

@ -865,8 +865,7 @@ class WebSocketDialogMsg extends AbstractModel
switch ($this->type) {
case "file":
// 提取文件消息
$msgData = Base::json2array($this->getRawOriginal('msg'));
$result = $this->convertMentionFormat("path", $msgData['path'], $msgData['name'], $reserves);
$result = " 文件:{$this->msg['name']}、大小:{$this->msg['size']}、下载URL:{$this->msg['path']} ";
break;
case "text":
@ -889,29 +888,31 @@ class WebSocketDialogMsg extends AbstractModel
// 提及任务、文件、报告
$result = preg_replace_callback_array([
// 用户
"/<span class=\"mention user\" data-id=\"(\d+)\">(.*?)<\/span>/" => function () {
return "";
"/<span class=\"mention user\" data-id=\"(\d+)\">(.*?)<\/span>/" => function ($match) {
return " 提及用户ID:{$match[1]} ";
},
// 任务
"/<span class=\"mention task\" data-id=\"(\d+)\">#?(.*?)<\/span>/" => function ($match) use (&$reserves) {
return $this->convertMentionFormat("task", $match[1], $match[2], $reserves);
"/<span class=\"mention task\" data-id=\"(\d+)\">#?(.*?)<\/span>/" => function ($match) {
return " 任务:{$match[2]} (任务ID:{$match[1]}) ";
},
// 文件
"/<a class=\"mention file\" href=\"([^\"']+?)\"[^>]*?>~?(.*?)<\/a>/" => function ($match) use (&$reserves) {
$idOrCode = "";
if (preg_match("/single\/file\/(.*?)$/", $match[1], $subMatch)) {
return $this->convertMentionFormat("file", $subMatch[1], $match[2], $reserves);
$idOrCode = " (" . (Base::isNumber($subMatch[1]) ? "文件ID:{$subMatch[1]}" : "文件分享码:{$subMatch[1]}") . ")";
}
return "";
return " 文件:{$match[2]}{$idOrCode} ";
},
// 报告
"/<a class=\"mention report\" href=\"([^\"']+?)\"[^>]*?>%?(.*?)<\/a>/" => function ($match) use (&$reserves) {
$idOrCode = "";
if (preg_match("/single\/report\/detail\/(.*?)$/", $match[1], $subMatch)) {
return $this->convertMentionFormat("report", $subMatch[1], $match[2], $reserves);
$idOrCode = " (" . (Base::isNumber($subMatch[1]) ? "报告ID:{$subMatch[1]}" : "报告分享码:{$subMatch[1]}") . ")";
}
return "";
return " 工作汇报:{$match[2]}{$idOrCode} ";
},
], $result);
@ -926,11 +927,6 @@ class WebSocketDialogMsg extends AbstractModel
return '';
}
// 处理 reserves
foreach ($reserves as $rand => $mention) {
$result = str_replace($rand, $mention, $result);
}
// 截取最大长度
if ($maxLength > 0 && mb_strlen($result) > $maxLength) {
$result = mb_substr($result, 0, $maxLength);
@ -939,24 +935,6 @@ class WebSocketDialogMsg extends AbstractModel
return $result;
}
/**
* 转换提及消息格式
* 将提及的任务、文件、报告等转换为统一的格式 [type#key#name]
*
* @param string $type 提及类型task、file、report、path
* @param string $key 提及对象的唯一标识
* @param string $name 提及对象的显示名称
* @return string 格式化后的提及字符串
*/
private function convertMentionFormat($type, $key, $name, &$reserves)
{
$key = str_replace(['#', '-->'], '', $key);
$name = str_replace(['#', '-->'], '', $name);
$rand = Base::generatePassword(12);
$reserves[$rand] = "<!--{$type}#{$key}#{$name}-->";
return $rand;
}
/**
* 处理文本消息内容,用于发送前
* @param $text

View File

@ -510,15 +510,13 @@ class BotReceiveMsgTask extends AbstractTask
}
$this->generateSystemPromptForAI($msg->userid, $dialog, $extras);
// 转换提及格式
$sendText = self::convertMentionForAI($sendText);
$replyText = self::convertMentionForAI($replyText);
if ($replyText) {
$sendText = <<<EOF
<quoted_content>
{$replyText}
</quoted_content>
The content within the above quoted_content tags is a citation.
上述 quoted_content 标签中的内容为引用。
{$sendText}
EOF;
@ -598,99 +596,6 @@ class BotReceiveMsgTask extends AbstractTask
}
}
/**
* 为AI机器人转换提及消息格式
* 将提及的任务、文件、报告转换为AI可理解的格式并提取相关内容
*
* @param string $original 原始消息文本
* @return string 转换后的消息文本,包含相关内容的标签
* @throws Exception 当提及的对象不存在或读取失败时抛出异常
*/
public static function convertMentionForAI($original)
{
$array = [];
$original = preg_replace_callback('/<!--(.*?)#(.*?)#(.*?)-->/', function ($match) use (&$array) {
// 初始化 tag 内容
$pathTag = null;
$pathName = null;
$pathContent = null;
// 根据 type 提取 tag 内容
switch ($match[1]) {
// 任务
case 'task':
$taskInfo = ProjectTask::with(['content'])->whereId(intval($match[2]))->first();
if (!$taskInfo) {
throw new Exception("任务不存在或已被删除");
}
$pathTag = "task_content";
$pathName = addslashes($taskInfo->name) . " (ID:{$taskInfo->id})";
$pathContent = implode("\n", $taskInfo->AIContext());
break;
// 文件
case 'file':
$fileInfo = FileContent::idOrCodeToContent($match[2]);
if (!$fileInfo || !isset($fileInfo->content['url'])) {
throw new Exception("文件不存在或已被删除");
}
$urlPath = public_path($fileInfo->content['url']);
if (!file_exists($urlPath)) {
throw new Exception("文件不存在或已被删除");
}
$fileResult = TextExtractor::extractFile($urlPath);
if (Base::isError($fileResult)) {
throw new Exception("文件读取失败:" . $fileResult['msg']);
}
$pathTag = "file_content";
$pathName = addslashes($match[3]) . " (ID:{$fileInfo->id})";
$pathContent = $fileResult['data'];
break;
// 文件路径
case 'path':
$urlPath = public_path($match[2]);
if (!file_exists($urlPath)) {
throw new Exception("文件不存在或已被删除");
}
$fileResult = TextExtractor::extractFile($urlPath);
if (Base::isError($fileResult)) {
throw new Exception("文件读取失败:" . $fileResult['msg']);
}
$pathTag = "file_content";
$pathName = addslashes($match[3]);
$pathContent = $fileResult['data'];
break;
// 报告
case 'report':
$reportInfo = Report::idOrCodeToContent($match[2]);
if (!$reportInfo) {
throw new Exception("报告不存在或已被删除");
}
$pathTag = "report_content";
$pathName = addslashes($match[3]) . " (ID:{$reportInfo->id})";
$pathContent = Base::html2markdown($reportInfo->content);
break;
}
// 如果提取到 tag 内容,则添加到 contents 数组中
if ($pathTag) {
$array[] = "<{$pathTag} path=\"{$pathName}\">\n{$pathContent}\n</{$pathTag}>";
return "`{$pathName}` (see below for {$pathTag} tag)";
}
return "";
}, $original);
// 添加 tag 内容
if ($array) {
$original .= "\n\n" . implode("\n\n", $array);
}
return $original;
}
/**
* 为AI机器人生成系统提示词
* 根据对话类型(用户对话、项目群、任务群、部门群等)生成相应的系统提示词
@ -739,29 +644,15 @@ class BotReceiveMsgTask extends AbstractTask
case 'project':
$projectInfo = Project::whereDialogId($dialog->id)->first();
if ($projectInfo) {
$projectDesc = $projectInfo->desc ?: "-";
$projectStatus = $projectInfo->archived_at ? '已归档' : '正在进行中';
$currentTime = Carbon::now()->toDateTimeString();
$sections[] = <<<EOF
<context_info>
当前我在项目【{$projectInfo->name}】中
项目描述:{$projectDesc}
项目状态:{$projectStatus}
当前我在项目群聊中
项目ID{$projectInfo->id}
项目名称:{$projectInfo->name}
当前时间:{$currentTime}
</context_info>
EOF;
$sections[] = <<<EOF
<instructions>
如果你判断我想要或需要添加任务,请按照以下格式回复:
::: create-task-list
title: 任务标题1
desc: 任务描述1
title: 任务标题2
desc: 任务描述2
:::
</instructions>
EOF;
}
break;
@ -769,26 +660,15 @@ class BotReceiveMsgTask extends AbstractTask
case 'task':
$taskInfo = ProjectTask::with(['content'])->whereDialogId($dialog->id)->first();
if ($taskInfo) {
$taskContext = implode("\n", $taskInfo->AIContext());
$currentTime = Carbon::now()->toDateTimeString();
$sections[] = <<<EOF
<context_info>
当前我在任务【{$taskInfo->name}】中
当前时间:{$taskInfo->updated_at}
当前我在任务群聊中
任务ID{$taskInfo->id}
{$taskContext}
任务名称:{$taskInfo->name}
当前时间:{$currentTime}
</context_info>
EOF;
$sections[] = <<<EOF
<instructions>
如果你判断我想要或需要添加子任务,请按照以下格式回复:
::: create-subtask-list
title: 子任务标题1
title: 子任务标题2
:::
</instructions>
EOF;
}
break;
@ -798,7 +678,9 @@ class BotReceiveMsgTask extends AbstractTask
if ($userDepartment) {
$sections[] = <<<EOF
<context_info>
当前我在【{$userDepartment->name}】的部门群聊中
当前我在部门群聊中
部门ID{$userDepartment->id}
部门名称:{$userDepartment->name}
</context_info>
EOF;
}
@ -836,7 +718,6 @@ class BotReceiveMsgTask extends AbstractTask
// 添加标签说明
$tagDescs = [
'role_setting' => '你的基础角色和行为定义',
'instructions' => '特定功能的操作指令',
'context_info' => '当前环境和状态信息',
'chat_history' => '最近的对话历史记录',
];