111 lines
3.3 KiB
PHP
111 lines
3.3 KiB
PHP
<?php
|
|
|
|
namespace Modules\Communication\Services;
|
|
|
|
use Illuminate\Support\Facades\Http;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
class SorenaAiClient
|
|
{
|
|
private string $apiUrl;
|
|
|
|
private string $model;
|
|
|
|
private float $temperature;
|
|
|
|
private int $timeout;
|
|
|
|
private string $token;
|
|
|
|
public function __construct()
|
|
{
|
|
$config = config('communication.sorena_ai', []);
|
|
$this->apiUrl = $config['url'] ?? 'https://saeed-taghadosi.ir/ai/demo';
|
|
$this->model = $config['model'] ?? 'gpt-3.5-turbo-0125';
|
|
$this->temperature = (float) ($config['temperature'] ?? 0.3);
|
|
$this->timeout = (int) ($config['timeout'] ?? 60);
|
|
$this->token = $config['token'] ?? '';
|
|
}
|
|
|
|
/**
|
|
* @param array<int, array{role: string, content: string}> $messages
|
|
*/
|
|
public function chat(array $messages, ?float $temperature = null): ?string
|
|
{
|
|
try {
|
|
$response = Http::timeout($this->timeout)
|
|
->withHeaders([
|
|
'Content-Type' => 'application/json',
|
|
'Authorization' => 'Bearer '.$this->token,
|
|
])
|
|
->withOptions(['verify' => false])
|
|
->post($this->apiUrl, [
|
|
'model' => $this->model,
|
|
'messages' => $messages,
|
|
'temperature' => $temperature ?? $this->temperature,
|
|
]);
|
|
|
|
if (! $response->successful()) {
|
|
Log::warning('Sorena AI HTTP '.$response->status(), ['body' => $response->body()]);
|
|
|
|
return null;
|
|
}
|
|
|
|
return $this->extractText($response->json());
|
|
} catch (\Throwable $e) {
|
|
Log::error('Sorena AI request failed: '.$e->getMessage());
|
|
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public function translate(string $text, string $from = 'fa', string $to = 'en'): ?string
|
|
{
|
|
$text = trim($text);
|
|
if ($text === '') {
|
|
return '';
|
|
}
|
|
|
|
$langNames = config('communication.translation_languages', [
|
|
'fa' => 'فارسی',
|
|
'en' => 'English',
|
|
'ar' => 'العربية',
|
|
]);
|
|
|
|
$fromName = $langNames[$from] ?? $from;
|
|
$toName = $langNames[$to] ?? $to;
|
|
|
|
$system = "تو یک مترجم حرفهای {$fromName} به {$toName} هستی.\n\n"
|
|
."قوانین:\n"
|
|
."- فقط متن ترجمهشده را برگردان\n"
|
|
."- اصطلاحات فنی را دقیق ترجمه کن\n"
|
|
."- این متن گفتگوی زنده در جلسه آنلاین است";
|
|
|
|
return $this->chat([
|
|
['role' => 'system', 'content' => $system],
|
|
['role' => 'user', 'content' => $text],
|
|
], 0.3);
|
|
}
|
|
|
|
/**
|
|
* @param array<string, mixed>|null $data
|
|
*/
|
|
private function extractText(?array $data): ?string
|
|
{
|
|
if (! is_array($data)) {
|
|
return null;
|
|
}
|
|
|
|
$text = $data['res'] ?? $data['message'] ?? $data['response'] ?? $data['text'] ?? null;
|
|
if (isset($data['choices'][0]['message']['content'])) {
|
|
$text = $data['choices'][0]['message']['content'];
|
|
}
|
|
|
|
if (! $text || $text === 'Error') {
|
|
return null;
|
|
}
|
|
|
|
return trim((string) $text);
|
|
}
|
|
}
|