feat(AI): add ai manager admin and create powerpoint with ai

This commit is contained in:
2026-07-22 08:06:48 +03:30
parent ae974c2afa
commit 4a3c109bf3
23 changed files with 743 additions and 23 deletions

View File

@@ -0,0 +1,81 @@
<?php
namespace App\Services\Ai;
use App\Enums\TemplateKeyType;
use App\Models\AiProvider;
use App\Models\Template;
use App\Models\TemplateKey;
use Illuminate\Support\Facades\Http;
use RuntimeException;
class OpenAiCompatibleTextGenerator
{
/**
* @return array<string, string>
*/
public function generateForTemplate(Template $template, string $topic, AiProvider $provider): array
{
$textKeys = $template->keys->where('type', TemplateKeyType::Text);
if ($textKeys->isEmpty()) {
return [];
}
$keysDescription = $textKeys
->map(fn (TemplateKey $key): string => sprintf('- %s (%s)%s', $key->key, $key->label, $key->description ? ': '.$key->description : ''))
->implode("\n");
$systemPrompt = <<<PROMPT
شما دستیار تولید محتوای پاورپوینت هستید. بر اساس موضوعی که کاربر می‌دهد، برای هرکدام از کلیدهای زیر یک متن مناسب فارسی تولید کن.
فقط یک JSON معتبر برگردان که کلیدهای آن دقیقاً و بدون هیچ تغییری (بدون تغییر حروف بزرگ/کوچک، بدون ترجمه، بدون حذف فاصله) برابر با نام کلیدهای زیر باشد. هیچ توضیح اضافه‌ای برنگردان.
کلیدها:
{$keysDescription}
PROMPT;
$response = Http::withToken($provider->api_key)
->timeout(60)
->post(rtrim($provider->resolvedBaseUrl(), '/').'/chat/completions', [
'model' => $provider->model,
'response_format' => ['type' => 'json_object'],
'messages' => [
['role' => 'system', 'content' => $systemPrompt],
['role' => 'user', 'content' => $topic],
],
]);
if ($response->failed()) {
throw new RuntimeException('خطا در ارتباط با سرویس هوش مصنوعی: '.$response->body());
}
$decoded = json_decode((string) $response->json('choices.0.message.content'), true);
if (! is_array($decoded)) {
throw new RuntimeException('پاسخ هوش مصنوعی قابل تفسیر نبود.');
}
$normalizedDecoded = [];
foreach ($decoded as $decodedKey => $decodedValue) {
$normalizedDecoded[$this->normalizeKey((string) $decodedKey)] = $decodedValue;
}
$values = [];
foreach ($textKeys as $key) {
$normalizedKey = $this->normalizeKey($key->key);
if (array_key_exists($normalizedKey, $normalizedDecoded)) {
$values[$key->key] = (string) $normalizedDecoded[$normalizedKey];
}
}
return $values;
}
private function normalizeKey(string $key): string
{
return mb_strtolower(trim($key, "{} \t\n\r\0\x0B"));
}
}