Update: 2026-05-08 02:11:29

This commit is contained in:
Hamza-Ayed
2026-05-08 02:11:29 +03:00
parent 1cd511f12e
commit b49af44139
8 changed files with 491 additions and 164 deletions

View File

@@ -103,6 +103,71 @@ class AI
return null;
}
// Track token usage from Gemini response
$usage = $result['usageMetadata'] ?? [];
if (!empty($usage)) {
self::logTokenUsage($usage);
}
return $data;
}
/**
* Log AI token usage to the database for cost tracking
*/
private static function logTokenUsage(array $usage): void
{
try {
$db = Database::getInstance();
$inputTokens = (int)($usage['promptTokenCount'] ?? 0);
$outputTokens = (int)($usage['candidatesTokenCount'] ?? 0);
$totalTokens = (int)($usage['totalTokenCount'] ?? ($inputTokens + $outputTokens));
// Gemini Flash Lite pricing: $0.075/1M input, $0.30/1M output
$inputCost = ($inputTokens / 1000000) * 0.075;
$outputCost = ($outputTokens / 1000000) * 0.30;
$totalCostUsd = $inputCost + $outputCost;
$totalCostJod = $totalCostUsd * 0.709; // 1 USD ≈ 0.709 JOD
$db->prepare("
INSERT INTO ai_usage_log (id, input_tokens, output_tokens, total_tokens, cost_usd, cost_jod, model, created_at)
VALUES (UUID(), ?, ?, ?, ?, ?, 'gemini-flash-lite', NOW())
")->execute([
$inputTokens,
$outputTokens,
$totalTokens,
round($totalCostUsd, 8),
round($totalCostJod, 8),
]);
} catch (\Exception $e) {
// Never crash the main flow for logging
error_log("[AI] Token usage log failed: " . $e->getMessage());
}
}
/**
* Get aggregated AI usage stats
*/
public static function getUsageStats(?string $tenantId = null): array
{
try {
$db = Database::getInstance();
$stmt = $db->query("
SELECT
COUNT(*) as total_requests,
COALESCE(SUM(input_tokens), 0) as total_input_tokens,
COALESCE(SUM(output_tokens), 0) as total_output_tokens,
COALESCE(SUM(total_tokens), 0) as total_tokens,
COALESCE(SUM(cost_usd), 0) as total_cost_usd,
COALESCE(SUM(cost_jod), 0) as total_cost_jod,
COALESCE(AVG(total_tokens), 0) as avg_tokens_per_request,
COALESCE(AVG(cost_jod), 0) as avg_cost_jod_per_request
FROM ai_usage_log
");
return $stmt->fetch() ?: [];
} catch (\Exception $e) {
return [];
}
}
}