mirror of
https://github.com/kuaifan/dootask.git
synced 2026-01-26 04:18:29 +00:00
feat(ai): add AiTaskLoopTask timer and register to crontab
This commit is contained in:
parent
eef4c6fbe5
commit
106465b932
@ -23,6 +23,7 @@ use App\Tasks\CheckinRemindTask;
|
||||
use App\Tasks\CloseMeetingRoomTask;
|
||||
use App\Tasks\ManticoreSyncTask;
|
||||
use App\Tasks\UnclaimedTaskRemindTask;
|
||||
use App\Tasks\AiTaskLoopTask;
|
||||
use Hhxsv5\LaravelS\Swoole\Task\Task;
|
||||
use Laravolt\Avatar\Avatar;
|
||||
|
||||
@ -273,6 +274,8 @@ class IndexController extends InvokeController
|
||||
Task::deliver(new CloseMeetingRoomTask());
|
||||
// Manticore Search 同步
|
||||
Task::deliver(new ManticoreSyncTask());
|
||||
// AI 任务建议
|
||||
Task::deliver(new AiTaskLoopTask());
|
||||
|
||||
return "success";
|
||||
}
|
||||
|
||||
119
app/Tasks/AiTaskLoopTask.php
Normal file
119
app/Tasks/AiTaskLoopTask.php
Normal file
@ -0,0 +1,119 @@
|
||||
<?php
|
||||
|
||||
namespace App\Tasks;
|
||||
|
||||
use App\Models\Apps;
|
||||
use App\Models\ProjectTask;
|
||||
use App\Models\ProjectTaskAiEvent;
|
||||
use App\Module\Base;
|
||||
use Carbon\Carbon;
|
||||
use Hhxsv5\LaravelS\Swoole\Task\Task;
|
||||
|
||||
/**
|
||||
* AI 任务建议定时任务
|
||||
* 扫描新建任务并投递分析任务
|
||||
*/
|
||||
class AiTaskLoopTask extends AbstractTask
|
||||
{
|
||||
/**
|
||||
* 单次处理任务数量上限
|
||||
*/
|
||||
const BATCH_SIZE = 5;
|
||||
|
||||
/**
|
||||
* 任务创建后多久开始分析(秒)
|
||||
*/
|
||||
const DELAY_SECONDS = 60;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function start()
|
||||
{
|
||||
// 检查 AI 插件是否安装
|
||||
if (!Apps::isInstalled('ai')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查功能开关
|
||||
if (Base::settingFind('aiAssistant', 'taskSuggestion') !== 'open') {
|
||||
return;
|
||||
}
|
||||
|
||||
// 查询待处理的任务
|
||||
$tasks = $this->findPendingTasks();
|
||||
|
||||
foreach ($tasks as $task) {
|
||||
// 为任务创建事件记录
|
||||
$this->createEventRecords($task);
|
||||
|
||||
// 投递异步分析任务
|
||||
Task::deliver(new AiTaskAnalyzeTask($task->id));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找待处理的任务
|
||||
*/
|
||||
private function findPendingTasks(): \Illuminate\Support\Collection
|
||||
{
|
||||
$delayTime = Carbon::now()->subSeconds(self::DELAY_SECONDS);
|
||||
|
||||
// 子查询:已经有 AI 事件记录的任务
|
||||
$processedTaskIds = ProjectTaskAiEvent::select('task_id')
|
||||
->distinct()
|
||||
->pluck('task_id');
|
||||
|
||||
// 查询新建任务(未处理过的)
|
||||
$newTasks = ProjectTask::where('parent_id', 0) // 只处理主任务
|
||||
->whereNull('deleted_at')
|
||||
->whereNull('archived_at')
|
||||
->where('created_at', '<=', $delayTime) // 创建超过延迟时间
|
||||
->where('created_at', '>=', Carbon::now()->subDays(1)) // 只处理1天内的
|
||||
->whereNotNull('dialog_id') // 有对话ID
|
||||
->whereNotIn('id', $processedTaskIds)
|
||||
->orderBy('created_at', 'asc')
|
||||
->take(self::BATCH_SIZE)
|
||||
->get();
|
||||
|
||||
// 查询需要重试的任务(优先处理较早失败的)
|
||||
$retryTaskIds = ProjectTaskAiEvent::where('status', ProjectTaskAiEvent::STATUS_FAILED)
|
||||
->where('retry_count', '<', ProjectTaskAiEvent::MAX_RETRY)
|
||||
->select('task_id')
|
||||
->distinct()
|
||||
->orderBy('updated_at', 'asc')
|
||||
->take(self::BATCH_SIZE - $newTasks->count())
|
||||
->pluck('task_id');
|
||||
|
||||
$retryTasks = ProjectTask::whereIn('id', $retryTaskIds)
|
||||
->whereNull('deleted_at')
|
||||
->get();
|
||||
|
||||
return $newTasks->merge($retryTasks)->take(self::BATCH_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 为任务创建事件记录
|
||||
*/
|
||||
private function createEventRecords(ProjectTask $task): void
|
||||
{
|
||||
foreach (ProjectTaskAiEvent::getEventTypes() as $eventType) {
|
||||
ProjectTaskAiEvent::firstOrCreate(
|
||||
[
|
||||
'task_id' => $task->id,
|
||||
'event_type' => $eventType,
|
||||
],
|
||||
[
|
||||
'status' => ProjectTaskAiEvent::STATUS_PENDING,
|
||||
'retry_count' => 0,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function end()
|
||||
{
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user