feat: costo OCR en dashboard, logs correctos y fix de thinking tokens
- OcrExtractionService: registra cada llamada en ai_usage_logs (servicio=ocr, costo=5 COP/foto) y ahora tambien loggea cuando SI funciona, no solo cuando falla (antes era imposible confirmar por log que el OCR corrio). - GeminiVisionService: el log decia siempre "[Gemini Vision]" sin importar si la llamada fue de imagen o de texto post-OCR, haciendo imposible distinguir cual camino se uso realmente. Ahora usa el servicio real. - GeminiVisionService: agrega thinkingConfig.thinkingBudget=0 (igual que GeminiIntentService) para que el modelo no gaste tokens narrando su razonamiento en texto plano antes del JSON final -- se estaba colando ese razonamiento en la respuesta y comiendose el presupuesto de tokens. - GeminiIntentService: resultado ya no queda forzado a 'ok'; ahora filtra bloques 'thought' igual que vision, y guarda tokens/raw en el detalle para poder diagnosticar sin acceso al servidor. - ShowAiLogs: card y filtro de costo OCR en el dashboard de consumo. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
7b21cd9773
commit
5e0c0367d9
@@ -9,9 +9,10 @@
|
||||
@php
|
||||
$costoGemini = $resumen->costo_gemini ?? 0;
|
||||
$costoWhisper = $resumen->costo_whisper ?? 0;
|
||||
$costoTotal = $costoGemini + $costoWhisper;
|
||||
$costoOcr = $resumen->costo_ocr ?? 0;
|
||||
$costoTotal = $costoGemini + $costoWhisper + $costoOcr;
|
||||
@endphp
|
||||
<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-4">
|
||||
<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-4">
|
||||
<div class="bg-white rounded-2xl border border-gray-100 shadow p-4">
|
||||
<p class="text-xs text-gray-400 mb-1">Total llamadas</p>
|
||||
<p class="text-2xl font-bold text-gray-800">{{ number_format($resumen->total_llamadas ?? 0) }}</p>
|
||||
@@ -38,6 +39,11 @@
|
||||
<p class="text-2xl font-bold text-blue-700">${{ number_format($costoGemini, 0, ',', '.') }}</p>
|
||||
<p class="text-xs text-gray-400 mt-1">$20.000 / millón tokens</p>
|
||||
</div>
|
||||
<div class="bg-white rounded-2xl border border-gray-100 shadow p-4">
|
||||
<p class="text-xs text-gray-400 mb-1">Costo OCR</p>
|
||||
<p class="text-2xl font-bold text-orange-600">${{ number_format($costoOcr, 0, ',', '.') }}</p>
|
||||
<p class="text-xs text-gray-400 mt-1">{{ number_format($resumen->total_fotos_ocr ?? 0) }} fotos · $5/foto</p>
|
||||
</div>
|
||||
<div class="bg-white rounded-2xl border border-gray-100 shadow p-4">
|
||||
<p class="text-xs text-gray-400 mb-1">Costo Total</p>
|
||||
<p class="text-2xl font-bold text-emerald-700">${{ number_format($costoTotal, 0, ',', '.') }}</p>
|
||||
@@ -75,6 +81,8 @@
|
||||
<option value="">Todos</option>
|
||||
<option value="gemini_intent">Gemini Intent</option>
|
||||
<option value="gemini_vision">Gemini Vision</option>
|
||||
<option value="gemini_text">Gemini Texto (post-OCR)</option>
|
||||
<option value="ocr">OCR</option>
|
||||
<option value="whisper">Whisper</option>
|
||||
</select>
|
||||
</div>
|
||||
@@ -118,16 +126,20 @@
|
||||
$badgeServicio = match($log->servicio) {
|
||||
'gemini_intent' => 'bg-blue-100 text-blue-700',
|
||||
'gemini_vision' => 'bg-indigo-100 text-indigo-700',
|
||||
'gemini_text' => 'bg-sky-100 text-sky-700',
|
||||
'ocr' => 'bg-orange-100 text-orange-700',
|
||||
'whisper' => 'bg-purple-100 text-purple-700',
|
||||
default => 'bg-gray-100 text-gray-600',
|
||||
};
|
||||
$labelServicio = match($log->servicio) {
|
||||
'gemini_intent' => 'Gemini Intent',
|
||||
'gemini_vision' => 'Gemini Vision',
|
||||
'gemini_text' => 'Gemini Texto',
|
||||
'ocr' => 'OCR',
|
||||
'whisper' => 'Whisper',
|
||||
default => $log->servicio,
|
||||
};
|
||||
$costoFila = in_array($log->servicio, ['gemini_intent', 'gemini_vision'])
|
||||
$costoFila = in_array($log->servicio, ['gemini_intent', 'gemini_vision', 'gemini_text'])
|
||||
? (($log->input_tokens ?? 0) + ($log->output_tokens ?? 0)) / 1000000 * 20000
|
||||
: ($log->costo ?? 0);
|
||||
@endphp
|
||||
|
||||
Reference in New Issue
Block a user