Issues (34)

src/Console/Commands/ToonDashboardCommand.php (1 issue)

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Squareetlabs\LaravelToon\Console\Commands;
6
7
use Illuminate\Console\Command;
8
use Squareetlabs\LaravelToon\Services\CompressionMetrics;
9
use Squareetlabs\LaravelToon\Services\CostCalculator;
10
use Squareetlabs\LaravelToon\Services\ToonService;
11
12
class ToonDashboardCommand extends Command
13
{
14
    protected $signature = 'toon:dashboard';
15
16
    protected $description = 'Dashboard interactivo para LaravelToon';
17
18
    public function handle(
19
        ToonService $toonService,
20
        CompressionMetrics $metrics,
21
        CostCalculator $costCalculator
22
    ): int {
23
        $this->displayHeader();
24
25
        while (true) {
26
            $this->newLine();
27
            $option = $this->choice('¿Qué desea hacer?', [
28
                'Convertir JSON a TOON',
29
                'Decodificar TOON a JSON',
30
                'Analizar compresión',
31
                'Estimar costos de API',
32
                'Ver precios de modelos',
33
                'Salir',
34
            ]);
35
36
            match ($option) {
37
                'Convertir JSON a TOON' => $this->convertJsonToToon($toonService),
38
                'Decodificar TOON a JSON' => $this->decodeToonToJson($toonService),
39
                'Analizar compresión' => $this->analyzeCompression($metrics),
40
                'Estimar costos de API' => $this->estimateCosts($costCalculator),
41
                'Ver precios de modelos' => $this->viewModelPrices($costCalculator),
42
                'Salir' => break,
0 ignored issues
show
A parse error occurred: Syntax error, unexpected T_BREAK on line 42 at column 27
Loading history...
43
            };
44
        }
45
46
        $this->info('¡Hasta luego!');
47
48
        return self::SUCCESS;
49
    }
50
51
    private function displayHeader(): void
52
    {
53
        $this->info('╔════════════════════════════════════════╗');
54
        $this->info('║      🧠 LaravelToon Dashboard 🧠        ║');
55
        $this->info('║  Token-Optimized Object Notation       ║');
56
        $this->info('╚════════════════════════════════════════╝');
57
    }
58
59
    private function convertJsonToToon(ToonService $toonService): void
60
    {
61
        $input = $this->ask('Ingrese JSON (o ruta de archivo)');
62
63
        if (file_exists($input)) {
64
            $json = file_get_contents($input);
65
        } else {
66
            $json = $input;
67
        }
68
69
        try {
70
            $data = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
71
72
            $format = $this->choice('Seleccione formato:', ['compact', 'readable', 'tabular']);
73
            $result = $toonService->convert($data, $format);
74
75
            $this->newLine();
76
            $this->info('Resultado TOON:');
77
            $this->line($result);
78
79
            if ($this->confirm('¿Guardar en archivo?')) {
80
                $filename = $this->ask('Nombre del archivo (sin extensión)', 'output.toon');
81
                file_put_contents($filename, $result);
82
                $this->info("✓ Guardado en: {$filename}");
83
            }
84
        } catch (\Exception $e) {
85
            $this->error('Error: '.$e->getMessage());
86
        }
87
    }
88
89
    private function decodeToonToJson(ToonService $toonService): void
90
    {
91
        $input = $this->ask('Ingrese TOON (o ruta de archivo)');
92
93
        if (file_exists($input)) {
94
            $toon = file_get_contents($input);
95
        } else {
96
            $toon = $input;
97
        }
98
99
        try {
100
            $data = $toonService->decode($toon);
101
            $json = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
102
103
            $this->newLine();
104
            $this->info('Resultado JSON:');
105
            $this->line($json);
106
107
            if ($this->confirm('¿Guardar en archivo?')) {
108
                $filename = $this->ask('Nombre del archivo (sin extensión)', 'output.json');
109
                file_put_contents($filename, $json);
110
                $this->info("✓ Guardado en: {$filename}");
111
            }
112
        } catch (\Exception $e) {
113
            $this->error('Error: '.$e->getMessage());
114
        }
115
    }
116
117
    private function analyzeCompression(CompressionMetrics $metrics): void
118
    {
119
        $input = $this->ask('Ingrese JSON (o ruta de archivo)');
120
121
        if (file_exists($input)) {
122
            $json = file_get_contents($input);
123
        } else {
124
            $json = $input;
125
        }
126
127
        try {
128
            $data = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
129
            $analysis = $metrics->full($data);
130
131
            $this->newLine();
132
            $this->info('📊 ANÁLISIS DE COMPRESIÓN:');
133
            $this->table(['Métrica', 'Valor'], [
134
                ['JSON Size', number_format($analysis['compression']['json_size_bytes']).' bytes'],
135
                ['TOON Size', number_format($analysis['compression']['toon_size_bytes']).' bytes'],
136
                ['Bytes Reducidos', $analysis['compression']['percent_reduced'].'%'],
137
                ['Tokens Reducidos', $analysis['tokens']['percent_saved'].'%'],
138
                ['Ratio', $analysis['compression']['compression_ratio']],
139
            ]);
140
141
            $this->info('Recomendaciones:');
142
            foreach ($analysis['recommendations'] as $rec) {
143
                $this->line("  ✓ {$rec['message']}");
144
            }
145
        } catch (\Exception $e) {
146
            $this->error('Error: '.$e->getMessage());
147
        }
148
    }
149
150
    private function estimateCosts(CostCalculator $costCalculator): void
151
    {
152
        $input = $this->ask('Ingrese JSON (o ruta de archivo)');
153
154
        if (file_exists($input)) {
155
            $json = file_get_contents($input);
156
        } else {
157
            $json = $input;
158
        }
159
160
        try {
161
            $data = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
162
163
            $models = $costCalculator->getAvailableModels();
164
            $modelList = array_keys($models);
165
            $model = $this->choice('Seleccione modelo:', $modelList);
166
167
            $comparison = $costCalculator->estimateWithJsonComparison($model, $data, 'input');
168
169
            $this->newLine();
170
            $this->info("💰 ESTIMACIÓN DE COSTOS - {$model}:");
171
            $this->table(['Formato', 'Tokens', 'Costo'], [
172
                ['JSON', number_format($comparison['json']['tokens']), $comparison['json']['cost_formatted']],
173
                ['TOON', number_format($comparison['toon']['tokens']), $comparison['toon']['cost_formatted']],
174
                ['Ahorros', number_format($comparison['savings']['tokens']), $comparison['savings']['cost_formatted'].' ('.$comparison['savings']['percent'].'%)'],
175
            ]);
176
        } catch (\Exception $e) {
177
            $this->error('Error: '.$e->getMessage());
178
        }
179
    }
180
181
    private function viewModelPrices(CostCalculator $costCalculator): void
182
    {
183
        $models = $costCalculator->getAvailableModels();
184
185
        $this->newLine();
186
        $this->info('💵 PRECIOS DE MODELOS (por 1M tokens):');
187
        $this->newLine();
188
189
        foreach ($models as $model => $roles) {
190
            $this->info("<fg=cyan>{$model}</>");
191
            $prices = config('laravel-toon.cost_calculation.models.'.$model, []);
192
            foreach ($roles as $role) {
193
                $price = $prices[$role] ?? 'N/A';
194
                $this->line("  {$role}: \${$price}");
195
            }
196
            $this->newLine();
197
        }
198
    }
199
}
200
201