get('DatabaseDriver'); $raw = (string) $db->setQuery( $db->getQuery(true) ->select($db->quoteName('params')) ->from($db->quoteName('#__extensions')) ->where($db->quoteName('type') . ' = ' . $db->quote('component')) ->where($db->quoteName('element') . ' = ' . $db->quote('com_testquestions')) )->loadResult(); $this->settings = json_decode($raw, true) ?: []; $this->usageTotals = [ 'openai' => ['calls' => 0, 'input_tokens' => 0, 'output_tokens' => 0, 'total_tokens' => 0, 'cost_usd' => 0.0, 'cost_calls' => 0], 'grok' => ['calls' => 0, 'input_tokens' => 0, 'output_tokens' => 0, 'total_tokens' => 0, 'cost_usd' => 0.0, 'cost_calls' => 0], ]; $usageRows = $db->setQuery( $db->getQuery(true) ->select($db->quoteName('answers')) ->from($db->quoteName('#__testquestions_results')) ->where($db->quoteName('answers') . ' LIKE ' . $db->quote('%ai_usage%')) )->loadColumn(); foreach ($usageRows as $answersJson) { $answers = json_decode((string) $answersJson, true); if (!is_array($answers)) { continue; } foreach ($answers as $answer) { if (!is_array($answer)) { continue; } $usages = $answer['ai_usage_history'] ?? (isset($answer['ai_usage']) ? [$answer['ai_usage']] : []); if (!is_array($usages)) { continue; } foreach ($usages as $usage) { if (!is_array($usage)) { continue; } $provider = (string) ($usage['provider'] ?? ''); if (!isset($this->usageTotals[$provider])) { continue; } $this->usageTotals[$provider]['calls']++; $this->usageTotals[$provider]['input_tokens'] += (int) ($usage['input_tokens'] ?? 0); $this->usageTotals[$provider]['output_tokens'] += (int) ($usage['output_tokens'] ?? 0); $this->usageTotals[$provider]['total_tokens'] += (int) ($usage['total_tokens'] ?? 0); if (is_numeric($usage['cost_usd'] ?? null)) { $this->usageTotals[$provider]['cost_usd'] += (float) $usage['cost_usd']; $this->usageTotals[$provider]['cost_calls']++; } } } } ToolbarHelper::title(Text::_('COM_TESTQUESTIONS_AI_SETTINGS')); ToolbarHelper::link('index.php?option=com_testquestions&view=questions', 'COM_TESTQUESTIONS_QUESTIONS', 'arrow-left'); return parent::display($tpl); } }