Changes
This commit is contained in:
@@ -88,12 +88,31 @@ class ProcessMixedFilesAction
|
|||||||
$categories = Category::all();
|
$categories = Category::all();
|
||||||
|
|
||||||
// Отправляем текст в AI
|
// Отправляем текст в AI
|
||||||
$newsData = $this->callAiServiceTask->run($extractedText, $categories);
|
Log::info('[ProcessMixedFilesAction] Отправка текста в AI сервис', [
|
||||||
|
'text_length' => strlen($extractedText ?? ''),
|
||||||
|
'categories_count' => $categories->count(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$newsData = $this->callAiServiceTask->run($extractedText, $categories);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Log::error('[ProcessMixedFilesAction] Ошибка вызова AI сервиса', [
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
'trace' => $e->getTraceAsString(),
|
||||||
|
]);
|
||||||
|
throw new \RuntimeException('Ошибка при обработке данных AI: ' . $e->getMessage(), 0, $e);
|
||||||
|
}
|
||||||
|
|
||||||
if (!$newsData) {
|
if (!$newsData) {
|
||||||
throw new \RuntimeException('Не удалось распознать данные через AI сервис');
|
Log::error('[ProcessMixedFilesAction] AI сервис вернул пустой ответ');
|
||||||
|
throw new \RuntimeException('Не удалось распознать данные через AI сервис. Проверьте логи AI запроса.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log::info('[ProcessMixedFilesAction] AI данные успешно получены', [
|
||||||
|
'title' => $newsData['title'] ?? 'N/A',
|
||||||
|
'category_id' => $newsData['category_id'] ?? 'N/A',
|
||||||
|
]);
|
||||||
|
|
||||||
// Создаём пост
|
// Создаём пост
|
||||||
$post = $this->createPostFromAiDataTask->run($newsData, $documentPath, $mediaPaths, $attachedFiles);
|
$post = $this->createPostFromAiDataTask->run($newsData, $documentPath, $mediaPaths, $attachedFiles);
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ namespace App\Containers\Dashboard\Tasks;
|
|||||||
|
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Support\Facades\Http;
|
use Illuminate\Support\Facades\Http;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
class CallAiServiceTask
|
class CallAiServiceTask
|
||||||
{
|
{
|
||||||
@@ -16,33 +17,109 @@ class CallAiServiceTask
|
|||||||
*/
|
*/
|
||||||
public function run(string $text, Collection $categories): ?array
|
public function run(string $text, Collection $categories): ?array
|
||||||
{
|
{
|
||||||
$categoryList = collect($categories)
|
try {
|
||||||
->map(fn($cat) => "{$cat->id}: {$cat->title}")
|
Log::info('[CallAiServiceTask] Начало AI запроса', [
|
||||||
->implode("\n");
|
'text_length' => strlen($text),
|
||||||
|
'categories_count' => $categories->count(),
|
||||||
|
]);
|
||||||
|
|
||||||
$systemPrompt = $this->buildSystemPrompt($categoryList);
|
// Проверяем наличие API ключа
|
||||||
|
$apiKey = env('QWEN_API_KEY');
|
||||||
|
if (empty($apiKey)) {
|
||||||
|
Log::error('[CallAiServiceTask] API ключ не настроен', [
|
||||||
|
'env_key' => 'QWEN_API_KEY',
|
||||||
|
]);
|
||||||
|
throw new \RuntimeException('AI API ключ не настроен в окружении');
|
||||||
|
}
|
||||||
|
|
||||||
$response = Http::withHeaders([
|
$categoryList = collect($categories)
|
||||||
'Authorization' => 'Bearer ' . env('QWEN_API_KEY'),
|
->map(fn($cat) => "{$cat->id}: {$cat->title}")
|
||||||
'Content-Type' => 'application/json',
|
->implode("\n");
|
||||||
])->post('https://routerai.ru/api/v1/chat/completions', [
|
|
||||||
'model' => 'qwen/qwen3.5-flash-02-23',
|
|
||||||
'reasoning' => ['enabled' => false],
|
|
||||||
'messages' => [
|
|
||||||
['role' => 'system', 'content' => $systemPrompt],
|
|
||||||
['role' => 'user', 'content' => $text],
|
|
||||||
],
|
|
||||||
'response_format' => ['type' => 'json_object'],
|
|
||||||
'temperature' => 0,
|
|
||||||
'max_tokens' => 2000,
|
|
||||||
]);
|
|
||||||
|
|
||||||
if ($response->successful()) {
|
$systemPrompt = $this->buildSystemPrompt($categoryList);
|
||||||
$result = $response->json();
|
|
||||||
return json_decode($result['choices'][0]['message']['content'], true);
|
Log::info('[CallAiServiceTask] Отправка запроса к AI', [
|
||||||
|
'url' => 'https://routerai.ru/api/v1/chat/completions',
|
||||||
|
'model' => 'qwen/qwen3.5-flash-02-23',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response = Http::withHeaders([
|
||||||
|
'Authorization' => 'Bearer ' . $apiKey,
|
||||||
|
'Content-Type' => 'application/json',
|
||||||
|
])
|
||||||
|
->timeout(60) // Увеличиваем timeout до 60 секунд
|
||||||
|
->retry(3, 1000, function ($exception, $response) {
|
||||||
|
// Повторяем только при ошибках соединения или 5xx
|
||||||
|
if ($response && $response->successful()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Log::warning('[CallAiServiceTask] Попытка не удалась, повтор...', [
|
||||||
|
'exception' => $exception->getMessage(),
|
||||||
|
]);
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
->post('https://routerai.ru/api/v1/chat/completions', [
|
||||||
|
'model' => 'qwen/qwen3.5-flash-02-23',
|
||||||
|
'reasoning' => ['enabled' => false],
|
||||||
|
'messages' => [
|
||||||
|
['role' => 'system', 'content' => $systemPrompt],
|
||||||
|
['role' => 'user', 'content' => $text],
|
||||||
|
],
|
||||||
|
'response_format' => ['type' => 'json_object'],
|
||||||
|
'temperature' => 0,
|
||||||
|
'max_tokens' => 2000,
|
||||||
|
]);
|
||||||
|
|
||||||
|
Log::info('[CallAiServiceTask] Ответ от AI', [
|
||||||
|
'status' => $response->status(),
|
||||||
|
'successful' => $response->successful(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($response->successful()) {
|
||||||
|
$result = $response->json();
|
||||||
|
$content = $result['choices'][0]['message']['content'] ?? null;
|
||||||
|
|
||||||
|
if (empty($content)) {
|
||||||
|
Log::error('[CallAiServiceTask] Пустой ответ от AI', [
|
||||||
|
'response' => $result,
|
||||||
|
]);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = json_decode($content, true);
|
||||||
|
|
||||||
|
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||||
|
Log::error('[CallAiServiceTask] Ошибка парсинга JSON ответа', [
|
||||||
|
'error' => json_last_error_msg(),
|
||||||
|
'content' => substr($content, 0, 500),
|
||||||
|
]);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::info('[CallAiServiceTask] AI данные успешно распознаны', [
|
||||||
|
'title' => $data['title'] ?? 'N/A',
|
||||||
|
'has_body' => isset($data['body']),
|
||||||
|
'category_id' => $data['category_id'] ?? 'N/A',
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::error('[CallAiServiceTask] AI запрос не удался', [
|
||||||
|
'status' => $response->status(),
|
||||||
|
'body' => $response->body(),
|
||||||
|
'headers' => $response->headers(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Log::error('[CallAiServiceTask] Критическая ошибка AI запроса', [
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
'trace' => $e->getTraceAsString(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
throw $e;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user