mirror of
https://github.com/kuaifan/dootask.git
synced 2026-01-06 04:18:13 +00:00
perf: 优化AI支持分析指定文件
This commit is contained in:
parent
e6167119e0
commit
3f56c64086
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
|
|
||||||
use App\Module\Base;
|
use App\Module\Base;
|
||||||
use App\Module\Timer;
|
use App\Module\Timer;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
@ -157,4 +156,28 @@ class FileContent extends AbstractModel
|
|||||||
}
|
}
|
||||||
return Base::retSuccess('success', [ 'content' => $content ]);
|
return Base::retSuccess('success', [ 'content' => $content ]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取文件内容
|
||||||
|
* @param $id
|
||||||
|
* @return self|null
|
||||||
|
*/
|
||||||
|
public static function idOrCodeToContent($id)
|
||||||
|
{
|
||||||
|
$builder = null;
|
||||||
|
if (Base::isNumber($id)) {
|
||||||
|
$builder = FileContent::whereFid($id);
|
||||||
|
} elseif ($id) {
|
||||||
|
$fileLink = FileLink::whereCode($id)->first();
|
||||||
|
if ($fileLink) {
|
||||||
|
$builder = FileContent::whereFid($fileLink->file_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/** @var self $fileContent */
|
||||||
|
$fileContent = $builder?->orderByDesc('id')->first();
|
||||||
|
if ($fileContent) {
|
||||||
|
$fileContent->content = Base::json2array($fileContent->content ?: []);
|
||||||
|
}
|
||||||
|
return $fileContent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -242,6 +242,19 @@ class User extends AbstractModel
|
|||||||
return in_array('admin', $this->identity);
|
return in_array('admin', $this->identity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回是否AI机器人
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isAiBot(&$aiName = '')
|
||||||
|
{
|
||||||
|
if (preg_match('/^ai-(.*?)@bot\.system$/', $this->email, $matches)) {
|
||||||
|
$aiName = $matches[1];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断是否管理员
|
* 判断是否管理员
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Module\AiBot;
|
namespace App\Module;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
@ -154,16 +154,11 @@ class TextExtractor
|
|||||||
/** ********************************************************************* */
|
/** ********************************************************************* */
|
||||||
/** ********************************************************************* */
|
/** ********************************************************************* */
|
||||||
|
|
||||||
public static function parsePaths($filePath)
|
/**
|
||||||
{
|
* 获取文件内容
|
||||||
// todo
|
* @param $filePath
|
||||||
// (see below for file content)
|
* @return string
|
||||||
// <file_content path="${mentionPath}">\n${content}\n</file_content>
|
*/
|
||||||
|
|
||||||
// (see below for site content)
|
|
||||||
// <site_content url="${mention}">\n${result}\n</site_content>
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getFileContent($filePath)
|
public static function getFileContent($filePath)
|
||||||
{
|
{
|
||||||
if (!file_exists($filePath) || !is_file($filePath)) {
|
if (!file_exists($filePath) || !is_file($filePath)) {
|
||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Tasks;
|
namespace App\Tasks;
|
||||||
|
|
||||||
|
use App\Models\FileContent;
|
||||||
use App\Models\Project;
|
use App\Models\Project;
|
||||||
use App\Models\ProjectTask;
|
use App\Models\ProjectTask;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
@ -12,6 +13,7 @@ use App\Models\WebSocketDialogMsg;
|
|||||||
use App\Module\Base;
|
use App\Module\Base;
|
||||||
use App\Module\Doo;
|
use App\Module\Doo;
|
||||||
use App\Module\Ihttp;
|
use App\Module\Ihttp;
|
||||||
|
use App\Module\TextExtractor;
|
||||||
use Cache;
|
use Cache;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use DB;
|
use DB;
|
||||||
@ -86,7 +88,7 @@ class BotReceiveMsgTask extends AbstractTask
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 提取指令
|
// 提取指令
|
||||||
$command = $this->extractCommand($msg, $this->mention);
|
$command = $this->extractCommand($msg, $botUser->isAiBot(), $this->mention);
|
||||||
if (empty($command)) {
|
if (empty($command)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -415,10 +417,9 @@ class BotReceiveMsgTask extends AbstractTask
|
|||||||
$userBot = null;
|
$userBot = null;
|
||||||
$extras = [];
|
$extras = [];
|
||||||
$errorContent = null;
|
$errorContent = null;
|
||||||
if (preg_match('/^ai-(.*?)@bot\.system$/', $botUser->email, $matches)) {
|
if ($botUser->isAiBot($type)) {
|
||||||
// AI机器人
|
// AI机器人
|
||||||
$setting = Base::setting('aibotSetting');
|
$setting = Base::setting('aibotSetting');
|
||||||
$type = $matches[1];
|
|
||||||
$extras = [
|
$extras = [
|
||||||
'model_type' => match ($type) {
|
'model_type' => match ($type) {
|
||||||
'qianwen' => 'qwen',
|
'qianwen' => 'qwen',
|
||||||
@ -462,7 +463,7 @@ class BotReceiveMsgTask extends AbstractTask
|
|||||||
$replyMsg = WebSocketDialogMsg::find($msg->reply_id);
|
$replyMsg = WebSocketDialogMsg::find($msg->reply_id);
|
||||||
$replyCommand = '';
|
$replyCommand = '';
|
||||||
if ($replyMsg) {
|
if ($replyMsg) {
|
||||||
$replyCommand = $this->extractCommand($replyMsg);
|
$replyCommand = $this->extractCommand($replyMsg, true);
|
||||||
if ($replyCommand) {
|
if ($replyCommand) {
|
||||||
$replyCommand = Base::cutStr($replyCommand, 2000);
|
$replyCommand = Base::cutStr($replyCommand, 2000);
|
||||||
$replyCommand = <<<EOF
|
$replyCommand = <<<EOF
|
||||||
@ -559,10 +560,11 @@ class BotReceiveMsgTask extends AbstractTask
|
|||||||
/**
|
/**
|
||||||
* 提取消息指令(提取消息内容)
|
* 提取消息指令(提取消息内容)
|
||||||
* @param WebSocketDialogMsg $msg
|
* @param WebSocketDialogMsg $msg
|
||||||
|
* @param bool $isAiBot
|
||||||
* @param bool $mention
|
* @param bool $mention
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
private function extractCommand(WebSocketDialogMsg $msg, bool $mention = false)
|
private function extractCommand(WebSocketDialogMsg $msg, bool $isAiBot = false, bool $mention = false)
|
||||||
{
|
{
|
||||||
if ($msg->type !== 'text') {
|
if ($msg->type !== 'text') {
|
||||||
return '';
|
return '';
|
||||||
@ -576,37 +578,49 @@ class BotReceiveMsgTask extends AbstractTask
|
|||||||
if (str_starts_with($command, '%3A.')) {
|
if (str_starts_with($command, '%3A.')) {
|
||||||
$command = ":" . substr($command, 4);
|
$command = ":" . substr($command, 4);
|
||||||
}
|
}
|
||||||
} else {
|
return $command;
|
||||||
$attachments = [];
|
}
|
||||||
|
$aiContents = [];
|
||||||
|
if ($isAiBot) {
|
||||||
if (preg_match_all("/<span class=\"mention task\" data-id=\"(\d+)\">(.*?)<\/span>/", $original, $match)) {
|
if (preg_match_all("/<span class=\"mention task\" data-id=\"(\d+)\">(.*?)<\/span>/", $original, $match)) {
|
||||||
$taskIds = Base::newIntval($match[1]);
|
$taskIds = Base::newIntval($match[1]);
|
||||||
foreach ($taskIds as $index => $taskId) {
|
foreach ($taskIds as $index => $taskId) {
|
||||||
|
$taskName = addslashes($match[2][$index]) . " (ID:{$taskId})";
|
||||||
|
$taskContext = "任务状态:不存在或已删除";
|
||||||
$taskInfo = ProjectTask::with(['content'])->whereId($taskId)->first();
|
$taskInfo = ProjectTask::with(['content'])->whereId($taskId)->first();
|
||||||
if ($taskInfo) {
|
if ($taskInfo) {
|
||||||
$taskName = addslashes($taskInfo->name) . " (ID:{$taskId})";
|
$taskName = addslashes($taskInfo->name) . " (ID:{$taskId})";
|
||||||
$taskContext = implode("\n", $taskInfo->AIContext());
|
$taskContext = implode("\n", $taskInfo->AIContext());
|
||||||
} else {
|
|
||||||
$taskName = addslashes($match[2][$index]) . " (ID:{$taskId})";
|
|
||||||
$taskContext = "任务状态:不存在或已删除";
|
|
||||||
}
|
}
|
||||||
$replName = "'{$taskName}'";
|
$aiContents[] = "<task_content path=\"{$taskName}\">\n{$taskContext}\n</task_content>";
|
||||||
$attachments[] = [
|
$original = str_replace($match[0][$index], "'{$taskName}' (see below for task_content tag)", $original);
|
||||||
'search' => $replName,
|
|
||||||
'replace' => "{$replName} (see below for task_content tag)",
|
|
||||||
'context' => "<task_content path=\"{$taskName}\">\n{$taskContext}\n</task_content>",
|
|
||||||
];
|
|
||||||
$original = str_replace($match[0][$index], $replName, $original);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($attachments) {
|
if (preg_match_all("/<a class=\"mention file\" href=\"([^\"']+?)\"[^>]*?>(.*?)<\/a>/", $original, $match)) {
|
||||||
Cache::put("bot:{$msg->id}:attachments", Base::array2json($attachments), 60);
|
$filePaths = $match[1];
|
||||||
|
foreach ($filePaths as $index => $filePath) {
|
||||||
|
if (preg_match("/single\/file\/(.*?)$/", $filePath, $fileMatch)) {
|
||||||
|
$fileName = addslashes($match[2][$index]);
|
||||||
|
$fileContent = "文件状态:不存在或已删除";
|
||||||
|
$fileInfo = FileContent::idOrCodeToContent($fileMatch[1]);
|
||||||
|
if ($fileInfo && isset($fileInfo->content['url'])) {
|
||||||
|
$filePath = public_path($fileInfo->content['url']);
|
||||||
|
if (file_exists($filePath)) {
|
||||||
|
$fileName .= " (ID:{$fileInfo->id})";
|
||||||
|
$fileContent = TextExtractor::getFileContent($filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$aiContents[] = "<file_content path=\"{$fileName}\">\n{$fileContent}\n</file_content>";
|
||||||
|
$original = str_replace($match[0][$index], "'{$fileName}' (see below for file_content tag)", $original);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$command = trim(strip_tags($original));
|
|
||||||
}
|
}
|
||||||
if (empty($command)) {
|
$command = trim(strip_tags($original));
|
||||||
return '';
|
if ($aiContents) {
|
||||||
|
$command .= "\n\n" . implode("\n\n", $aiContents);
|
||||||
}
|
}
|
||||||
return $command;
|
return $command ?: '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user