Files
System-testowy/administrator/components/com_testquestions/src/Service/AiService.php
T

80 lines
2.7 KiB
PHP

<?php
namespace Komponent\Component\Testquestions\Administrator\Service;
defined('_JEXEC') or die;
use Joomla\CMS\Http\HttpFactory;
class AiService
{
public function evaluate(string $provider, string $apiKey, string $question, string $answer, string $pattern): string
{
$provider = strtolower(trim($provider));
$provider = preg_replace('/[^a-z]/', '', $provider);
$config = $provider === 'grok'
? ['url' => 'https://api.x.ai/v1/responses', 'model' => 'grok-4.7']
: ['url' => 'https://api.openai.com/v1/responses', 'model' => 'gpt-4.1-mini'];
if (trim($apiKey) === '') {
throw new \RuntimeException('AI_NOT_CONFIGURED');
}
if (!in_array($provider, ['openai', 'grok'], true)) {
throw new \RuntimeException('Nieprawidłowy dostawca AI: ' . $provider);
}
$input = "Oceń odpowiedź ucznia na pytanie otwarte.\n\n"
. "Pytanie:\n" . $question . "\n\n"
. "Wzorzec odpowiedzi:\n" . $pattern . "\n\n"
. "Odpowiedź ucznia:\n" . ($answer !== '' ? $answer : 'Brak odpowiedzi') . "\n\n"
. "Napisz po polsku krótką ocenę: czy odpowiedź może zostać uznana za poprawną, jakie elementy są poprawne lub błędne oraz czy warto przyznać punkty. Nie zmieniaj wzorca odpowiedzi.";
$payload = json_encode([
'model' => $config['model'],
'input' => $input,
'temperature' => 0.1,
], JSON_UNESCAPED_UNICODE);
$response = HttpFactory::getHttp()->post(
$config['url'],
$payload,
[
'Authorization' => 'Bearer ' . trim($apiKey),
'Content-Type' => 'application/json',
],
60
);
$body = json_decode((string) $response->body, true);
if ((int) $response->code < 200 || (int) $response->code >= 300) {
throw new \RuntimeException((string) ($body['error']['message'] ?? ('HTTP ' . (int) $response->code)));
}
$text = $this->extractText($body);
if ($text === '') {
throw new \RuntimeException('Brak treści odpowiedzi AI.');
}
return $text;
}
private function extractText(array $body): string
{
if (!empty($body['output_text']) && is_string($body['output_text'])) {
return trim($body['output_text']);
}
$parts = [];
foreach ((array) ($body['output'] ?? []) as $output) {
foreach ((array) ($output['content'] ?? []) as $content) {
if (!empty($content['text']) && is_string($content['text'])) {
$parts[] = $content['text'];
}
}
}
return trim(implode("\n", $parts));
}
}