Files
hoshpoint-backend/app/Services/Ai/OpenAiCompatibleTextGenerator.php

82 lines
2.9 KiB
PHP

<?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"));
}
}