- Migration + AiUsageLog model with tokens, duration, time, cost fields - GeminiIntentService and GeminiVisionService log every API call with input/output token counts from usageMetadata and response time - TelegramBotService logs Whisper calls with audio duration (from Telegram) and calculates cost at $1/second - Whisper voice duration now passed from TelegramWebhookController - Free text in Telegram now tries Gemini intent detection before showing menu - /chat/ia-logs: Livewire component with summary cards + filterable table - Whisper connection test button in config panel - "Logs IA" link added to Chat/Bot nav section Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
65 lines
2.5 KiB
PHP
65 lines
2.5 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Livewire\Chat;
|
|
|
|
use App\Models\AiUsageLog;
|
|
use Livewire\Component;
|
|
use Livewire\WithPagination;
|
|
|
|
class ShowAiLogs extends Component
|
|
{
|
|
use WithPagination;
|
|
|
|
public string $filtroServicio = '';
|
|
public string $filtroCanal = '';
|
|
public string $filtroFechaDesde = '';
|
|
public string $filtroFechaHasta = '';
|
|
|
|
protected $queryString = ['filtroServicio', 'filtroCanal', 'filtroFechaDesde', 'filtroFechaHasta'];
|
|
|
|
public function updatingFiltroServicio(): void { $this->resetPage(); }
|
|
public function updatingFiltroCanal(): void { $this->resetPage(); }
|
|
public function updatingFiltroFechaDesde(): void { $this->resetPage(); }
|
|
public function updatingFiltroFechaHasta(): void { $this->resetPage(); }
|
|
|
|
public function render()
|
|
{
|
|
$query = AiUsageLog::query()->latest();
|
|
|
|
if ($this->filtroServicio) {
|
|
$query->where('servicio', $this->filtroServicio);
|
|
}
|
|
if ($this->filtroCanal) {
|
|
$query->where('canal', $this->filtroCanal);
|
|
}
|
|
if ($this->filtroFechaDesde) {
|
|
$query->whereDate('created_at', '>=', $this->filtroFechaDesde);
|
|
}
|
|
if ($this->filtroFechaHasta) {
|
|
$query->whereDate('created_at', '<=', $this->filtroFechaHasta);
|
|
}
|
|
|
|
$logs = $query->paginate(30);
|
|
|
|
// Resumen total (aplicando mismos filtros sin paginación)
|
|
$resumenQuery = AiUsageLog::query();
|
|
if ($this->filtroServicio) $resumenQuery->where('servicio', $this->filtroServicio);
|
|
if ($this->filtroCanal) $resumenQuery->where('canal', $this->filtroCanal);
|
|
if ($this->filtroFechaDesde) $resumenQuery->whereDate('created_at', '>=', $this->filtroFechaDesde);
|
|
if ($this->filtroFechaHasta) $resumenQuery->whereDate('created_at', '<=', $this->filtroFechaHasta);
|
|
|
|
$resumen = $resumenQuery->selectRaw('
|
|
COUNT(*) as total_llamadas,
|
|
SUM(CASE WHEN resultado = "ok" THEN 1 ELSE 0 END) as total_ok,
|
|
SUM(CASE WHEN resultado = "error" THEN 1 ELSE 0 END) as total_errores,
|
|
SUM(input_tokens) as total_input_tokens,
|
|
SUM(output_tokens) as total_output_tokens,
|
|
SUM(audio_segundos) as total_segundos_whisper,
|
|
SUM(CASE WHEN servicio = "whisper" THEN costo ELSE 0 END) as costo_whisper,
|
|
AVG(tiempo_ms) as avg_tiempo_ms
|
|
')->first();
|
|
|
|
return view('livewire.chat.show-ai-logs', compact('logs', 'resumen'));
|
|
}
|
|
}
|