mirror of
https://github.com/kuaifan/dootask.git
synced 2025-12-10 18:02:55 +00:00
feat: 移除未使用的函数和代码,优化BotReceiveMsgTask和WebSocketDialogMsg的消息处理逻辑
This commit is contained in:
parent
477bb1ac8f
commit
944824b552
@ -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 新增群组
|
||||
*
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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' => '最近的对话历史记录',
|
||||
];
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user