Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7d9efd64f4 |
@@ -30,6 +30,6 @@ Szkielet komponentu Joomla 6 do gromadzenia pytań testowych.
|
||||
|
||||
## Instalacja
|
||||
|
||||
W Joomla wybierz **System → Install → Install from Folder** i wskaż ten katalog. Manifestem instalacyjnym jest `com_testquestions.xml` (wersja 1.43.3).
|
||||
W Joomla wybierz **System → Install → Install from Folder** i wskaż ten katalog. Manifestem instalacyjnym jest `com_testquestions.xml` (wersja 1.43.4).
|
||||
|
||||
Po instalacji komponent jest dostępny w panelu administratora jako **Pytania testowe**.
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
-- No database changes required for version 1.43.4.
|
||||
@@ -151,6 +151,9 @@ class ResultModel extends BaseDatabaseModel
|
||||
);
|
||||
$item->answers[$questionId]['ai_feedback'] = $aiResult['feedback'];
|
||||
$item->answers[$questionId]['awarded_points'] = $aiResult['awarded_points'];
|
||||
if ($aiResult['usage'] !== null) {
|
||||
$item->answers[$questionId]['ai_usage'] = $aiResult['usage'];
|
||||
}
|
||||
|
||||
$correctionPoints = 0;
|
||||
foreach ($item->answers as $savedAnswer) {
|
||||
|
||||
@@ -73,9 +73,46 @@ class AiService
|
||||
throw new \RuntimeException('AI zwróciło nieprawidłowy format oceny i punktów.');
|
||||
}
|
||||
|
||||
$usage = $this->getUsage($body, $provider, $config['model']);
|
||||
|
||||
return [
|
||||
'awarded_points' => min(max(0, $maxPoints), max(0, (int) $result['awarded_points'])),
|
||||
'feedback' => trim((string) ($result['feedback'] ?? '')),
|
||||
'usage' => $usage,
|
||||
];
|
||||
}
|
||||
|
||||
private function getUsage(array $body, string $provider, string $model): ?array
|
||||
{
|
||||
$usage = $body['usage'] ?? null;
|
||||
if (!is_array($usage) || !isset($usage['input_tokens'], $usage['output_tokens'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$inputTokens = max(0, (int) $usage['input_tokens']);
|
||||
$outputTokens = max(0, (int) $usage['output_tokens']);
|
||||
$cachedTokens = min($inputTokens, max(0, (int) ($usage['input_tokens_details']['cached_tokens'] ?? 0)));
|
||||
$cost = null;
|
||||
$costSource = '';
|
||||
|
||||
if ($provider === 'grok' && isset($usage['cost_in_usd_ticks']) && is_numeric($usage['cost_in_usd_ticks'])) {
|
||||
$cost = (float) $usage['cost_in_usd_ticks'] / 10000000000;
|
||||
$costSource = 'provider';
|
||||
} elseif ($provider === 'openai' && $model === 'gpt-4.1-mini') {
|
||||
$uncachedTokens = $inputTokens - $cachedTokens;
|
||||
$cost = ($uncachedTokens * 0.40 + $cachedTokens * 0.10 + $outputTokens * 1.60) / 1000000;
|
||||
$costSource = 'token_rates';
|
||||
}
|
||||
|
||||
return [
|
||||
'provider' => $provider,
|
||||
'model' => $model,
|
||||
'input_tokens' => $inputTokens,
|
||||
'output_tokens' => $outputTokens,
|
||||
'total_tokens' => (int) ($usage['total_tokens'] ?? ($inputTokens + $outputTokens)),
|
||||
'cached_input_tokens' => $cachedTokens,
|
||||
'cost_usd' => $cost,
|
||||
'cost_source' => $costSource,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,25 @@
|
||||
<button type="submit" class="btn btn-primary" formaction="<?php echo Route::_('index.php?option=com_testquestions&task=result.aiAll&id=' . (int) $this->item->id); ?>" onclick="this.form.task.value='result.aiAll';">
|
||||
<?php echo \Joomla\CMS\Language\Text::sprintf('COM_TESTQUESTIONS_AI_EVALUATE_ALL', $pendingAiCount); ?>
|
||||
</button>
|
||||
<?php
|
||||
$usageTotals = ['input_tokens' => 0, 'output_tokens' => 0, 'total_tokens' => 0, 'cost_usd' => 0.0, 'providers' => []];
|
||||
foreach ($this->item->answers as $savedAnswer) {
|
||||
$usage = $savedAnswer['ai_usage'] ?? null;
|
||||
if (!is_array($usage)) continue;
|
||||
$usageTotals['input_tokens'] += (int) ($usage['input_tokens'] ?? 0);
|
||||
$usageTotals['output_tokens'] += (int) ($usage['output_tokens'] ?? 0);
|
||||
$usageTotals['total_tokens'] += (int) ($usage['total_tokens'] ?? 0);
|
||||
if (is_numeric($usage['cost_usd'] ?? null)) $usageTotals['cost_usd'] += (float) $usage['cost_usd'];
|
||||
if (!empty($usage['provider'])) $usageTotals['providers'][(string) $usage['provider']] = true;
|
||||
}
|
||||
?>
|
||||
<?php if ($usageTotals['total_tokens'] > 0) : ?>
|
||||
<span class="badge text-bg-light border ms-2" title="Suma dotychczasowych ocen AI">
|
||||
✦ <?php echo implode(' + ', array_map('htmlspecialchars', array_keys($usageTotals['providers']))); ?>:
|
||||
<?php echo number_format($usageTotals['total_tokens'], 0, ',', ' '); ?> tokenów,
|
||||
<?php echo number_format($usageTotals['cost_usd'], 8, ',', ' '); ?> USD
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<h2><?php echo \Joomla\CMS\Language\Text::_('COM_TESTQUESTIONS_RESULT_ANSWERS'); ?></h2>
|
||||
@@ -55,6 +74,17 @@
|
||||
<button type="submit" name="ai_question_id" value="<?php echo (int) $questionId; ?>" onclick="this.form.task.value='result.ai';" formaction="<?php echo Route::_('index.php?option=com_testquestions&task=result.ai&id=' . (int) $this->item->id); ?>" class="btn btn-outline-primary">
|
||||
<?php echo \Joomla\CMS\Language\Text::_('COM_TESTQUESTIONS_AI_EVALUATE'); ?>
|
||||
</button>
|
||||
<?php if (!empty($answer['ai_usage']) && is_array($answer['ai_usage'])) : ?>
|
||||
<?php $usage = $answer['ai_usage']; ?>
|
||||
<?php $usageProvider = (string) ($usage['provider'] ?? ''); ?>
|
||||
<span class="badge text-bg-light border ms-2" title="<?php echo $usageProvider === 'grok' ? 'Koszt zwrócony przez dostawcę' : 'Koszt obliczony z faktycznie wykorzystanych tokenów i stawek modelu'; ?>">
|
||||
<?php echo $usageProvider === 'grok' ? '✦ Grok' : '◉ OpenAI'; ?> ·
|
||||
<?php echo number_format((int) ($usage['input_tokens'] ?? 0), 0, ',', ' '); ?> in /
|
||||
<?php echo number_format((int) ($usage['output_tokens'] ?? 0), 0, ',', ' '); ?> out ·
|
||||
<?php echo is_numeric($usage['cost_usd'] ?? null) ? number_format((float) $usage['cost_usd'], 8, ',', ' ') . ' USD' : 'koszt niedostępny'; ?>
|
||||
<?php echo ($usage['cost_source'] ?? '') === 'token_rates' ? ' (wyliczony)' : ''; ?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php if (!empty($answer['ai_feedback'])) : ?>
|
||||
<div class="alert alert-info mt-3"><strong><?php echo \Joomla\CMS\Language\Text::_('COM_TESTQUESTIONS_AI_RESULT'); ?>:</strong><br><?php echo nl2br(htmlspecialchars((string) $answer['ai_feedback'], ENT_QUOTES, 'UTF-8')); ?></div>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<creationDate>2026-10-14</creationDate>
|
||||
<author>Komponent</author>
|
||||
<license>GNU General Public License version 2 or later</license>
|
||||
<version>1.43.3</version>
|
||||
<version>1.43.4</version>
|
||||
<description>COM_TESTQUESTIONS_DESCRIPTION</description>
|
||||
<element>com_testquestions</element>
|
||||
<namespace path="src">Komponent\Component\Testquestions</namespace>
|
||||
|
||||
Reference in New Issue
Block a user