perf: 优化AI支持分析指定文件

This commit is contained in:
kuaifan 2025-02-23 23:55:02 +08:00
parent e6167119e0
commit 3f56c64086
4 changed files with 80 additions and 35 deletions

View File

@ -2,7 +2,6 @@
namespace App\Models;
use App\Module\Base;
use App\Module\Timer;
use Illuminate\Database\Eloquent\SoftDeletes;
@ -157,4 +156,28 @@ class FileContent extends AbstractModel
}
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;
}
}

View File

@ -242,6 +242,19 @@ class User extends AbstractModel
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;
}
/**
* 判断是否管理员
*/

View File

@ -1,6 +1,6 @@
<?php
namespace App\Module\AiBot;
namespace App\Module;
use Exception;
use Illuminate\Support\Facades\Log;
@ -154,16 +154,11 @@ class TextExtractor
/** ********************************************************************* */
/** ********************************************************************* */
public static function parsePaths($filePath)
{
// todo
// (see below for file content)
// <file_content path="${mentionPath}">\n${content}\n</file_content>
// (see below for site content)
// <site_content url="${mention}">\n${result}\n</site_content>
}
/**
* 获取文件内容
* @param $filePath
* @return string
*/
public static function getFileContent($filePath)
{
if (!file_exists($filePath) || !is_file($filePath)) {

View File

@ -2,6 +2,7 @@
namespace App\Tasks;
use App\Models\FileContent;
use App\Models\Project;
use App\Models\ProjectTask;
use App\Models\User;
@ -12,6 +13,7 @@ use App\Models\WebSocketDialogMsg;
use App\Module\Base;
use App\Module\Doo;
use App\Module\Ihttp;
use App\Module\TextExtractor;
use Cache;
use Carbon\Carbon;
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)) {
return;
}
@ -415,10 +417,9 @@ class BotReceiveMsgTask extends AbstractTask
$userBot = null;
$extras = [];
$errorContent = null;
if (preg_match('/^ai-(.*?)@bot\.system$/', $botUser->email, $matches)) {
if ($botUser->isAiBot($type)) {
// AI机器人
$setting = Base::setting('aibotSetting');
$type = $matches[1];
$extras = [
'model_type' => match ($type) {
'qianwen' => 'qwen',
@ -462,7 +463,7 @@ class BotReceiveMsgTask extends AbstractTask
$replyMsg = WebSocketDialogMsg::find($msg->reply_id);
$replyCommand = '';
if ($replyMsg) {
$replyCommand = $this->extractCommand($replyMsg);
$replyCommand = $this->extractCommand($replyMsg, true);
if ($replyCommand) {
$replyCommand = Base::cutStr($replyCommand, 2000);
$replyCommand = <<<EOF
@ -559,10 +560,11 @@ class BotReceiveMsgTask extends AbstractTask
/**
* 提取消息指令(提取消息内容)
* @param WebSocketDialogMsg $msg
* @param bool $isAiBot
* @param bool $mention
* @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') {
return '';
@ -576,37 +578,49 @@ class BotReceiveMsgTask extends AbstractTask
if (str_starts_with($command, '%3A.')) {
$command = ":" . substr($command, 4);
}
} else {
$attachments = [];
return $command;
}
$aiContents = [];
if ($isAiBot) {
if (preg_match_all("/<span class=\"mention task\" data-id=\"(\d+)\">(.*?)<\/span>/", $original, $match)) {
$taskIds = Base::newIntval($match[1]);
foreach ($taskIds as $index => $taskId) {
$taskName = addslashes($match[2][$index]) . " (ID:{$taskId})";
$taskContext = "任务状态:不存在或已删除";
$taskInfo = ProjectTask::with(['content'])->whereId($taskId)->first();
if ($taskInfo) {
$taskName = addslashes($taskInfo->name) . " (ID:{$taskId})";
$taskContext = implode("\n", $taskInfo->AIContext());
} else {
$taskName = addslashes($match[2][$index]) . " (ID:{$taskId})";
$taskContext = "任务状态:不存在或已删除";
}
$replName = "'{$taskName}'";
$attachments[] = [
'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);
$aiContents[] = "<task_content path=\"{$taskName}\">\n{$taskContext}\n</task_content>";
$original = str_replace($match[0][$index], "'{$taskName}' (see below for task_content tag)", $original);
}
}
if ($attachments) {
Cache::put("bot:{$msg->id}:attachments", Base::array2json($attachments), 60);
if (preg_match_all("/<a class=\"mention file\" href=\"([^\"']+?)\"[^>]*?>(.*?)<\/a>/", $original, $match)) {
$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)) {
return '';
$command = trim(strip_tags($original));
if ($aiContents) {
$command .= "\n\n" . implode("\n\n", $aiContents);
}
return $command;
return $command ?: '';
}
/**