462 lines
14 KiB
Markdown
462 lines
14 KiB
Markdown
# Simple Debug API - Guía para LLM
|
|
|
|
## Propósito
|
|
|
|
Esta API permite debuggear la **Calculadora MAV CAS** sin modificar código fuente ni crear scripts adicionales.
|
|
|
|
**Principio**: **texto → texto** tal como se muestra en la aplicación.
|
|
**NO duplica lógica**, solo encapsula llamadas directas al motor existente.
|
|
|
|
Como LLM, puedes usar esta herramienta para:
|
|
|
|
- **Diagnosticar problemas** en el motor de evaluación
|
|
- **Verificar comportamiento** de tipos personalizados (FourBytes, IntBase, IP4Mask, etc.)
|
|
- **Inspeccionar el estado interno** del motor (variables, contexto, tipos registrados)
|
|
- **Testing de regresión** para verificar que cambios no rompan funcionalidad existente
|
|
|
|
## Flujo de Trabajo Recomendado
|
|
|
|
### 1. Crear archivo JSON con queries
|
|
### 2. Ejecutar: `python simple_debug.py archivo.json`
|
|
### 3. Analizar resultados en el archivo `*_results.json`
|
|
|
|
---
|
|
|
|
## Tipos de Query
|
|
|
|
### Query tipo `input`
|
|
Evalúa expresiones como si el usuario las escribiera en la calculadora.
|
|
**Resultado**: texto tal como se muestra en la aplicación.
|
|
|
|
```json
|
|
{"index": 0, "type": "input", "content": "10.1.1.1 + 1"}
|
|
```
|
|
|
|
### Query tipo `exec`
|
|
Ejecuta código Python para inspeccionar el estado interno del motor.
|
|
**Resultado**: valor directo de la evaluación Python.
|
|
|
|
```json
|
|
{"index": 1, "type": "exec", "content": "type(engine.last_result).__name__"}
|
|
```
|
|
|
|
---
|
|
|
|
## Plantilla Base
|
|
|
|
```json
|
|
{
|
|
"queries": [
|
|
{"index": 0, "type": "input", "content": "EXPRESION_A_EVALUAR"},
|
|
{"index": 1, "type": "exec", "content": "CODIGO_PYTHON_INSPECCION"}
|
|
]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Casos de Uso Comunes
|
|
|
|
### Debugging de Tipos Personalizados
|
|
|
|
**Problema**: Verificar si FourBytes maneja correctamente operaciones IP.
|
|
|
|
```json
|
|
{
|
|
"queries": [
|
|
{"index": 0, "type": "input", "content": "192.168.1.1 + 1"},
|
|
{"index": 1, "type": "exec", "content": "type(engine.last_result).__name__"},
|
|
{"index": 2, "type": "exec", "content": "engine.last_result.original"},
|
|
{"index": 3, "type": "exec", "content": "engine.last_result._numeric_value"},
|
|
{"index": 4, "type": "input", "content": "10.0.0.0/8 + 256"},
|
|
{"index": 5, "type": "exec", "content": "engine.last_result.has_symbols"}
|
|
]
|
|
}
|
|
```
|
|
|
|
### Debugging de Tokenización
|
|
|
|
**Problema**: La expresión `192.168.1.x + 16#FF` no se tokeniza correctamente.
|
|
|
|
```json
|
|
{
|
|
"queries": [
|
|
{"index": 0, "type": "exec", "content": "engine.parser.process_expression('192.168.1.x + 16#FF')"},
|
|
{"index": 1, "type": "input", "content": "192.168.1.x + 16#FF"},
|
|
{"index": 2, "type": "exec", "content": "engine.parser.get_tokenization_info()"},
|
|
{"index": 3, "type": "exec", "content": "len(engine.parser.tokenizer.tokenization_rules)"}
|
|
]
|
|
}
|
|
```
|
|
|
|
### Debugging de Errores
|
|
|
|
**Problema**: IP4Mask rechaza máscaras que deberían ser válidas.
|
|
|
|
```json
|
|
{
|
|
"queries": [
|
|
{"index": 0, "type": "input", "content": "mask = 255.240.0.0"},
|
|
{"index": 1, "type": "input", "content": "IP4Mask(mask)"},
|
|
{"index": 2, "type": "exec", "content": "engine.last_result"},
|
|
{"index": 3, "type": "input", "content": "IP4Mask(255.240.0.3)"},
|
|
{"index": 4, "type": "exec", "content": "engine.last_result"}
|
|
]
|
|
}
|
|
```
|
|
|
|
### Debugging de Estado del Motor
|
|
|
|
**Problema**: Las variables no se están guardando correctamente.
|
|
|
|
```json
|
|
{
|
|
"queries": [
|
|
{"index": 0, "type": "input", "content": "x = 5"},
|
|
{"index": 1, "type": "input", "content": "y = x + 10"},
|
|
{"index": 2, "type": "exec", "content": "engine.symbol_table"},
|
|
{"index": 3, "type": "exec", "content": "len(engine.symbol_table)"},
|
|
{"index": 4, "type": "exec", "content": "list(engine.symbol_table.keys())"},
|
|
{"index": 5, "type": "input", "content": "solve(z**2 + x, z)"},
|
|
{"index": 6, "type": "exec", "content": "len(engine.equations)"}
|
|
]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Interpretación de Resultados
|
|
|
|
### Estructura del Resultado
|
|
|
|
```json
|
|
{
|
|
"execution_info": {
|
|
"timestamp": "2025-06-05T18:25:22.256442Z",
|
|
"total_queries": 5,
|
|
"successful": 4,
|
|
"failed": 1
|
|
},
|
|
"results": [...]
|
|
}
|
|
```
|
|
|
|
### Resultado Individual (Query `input`)
|
|
|
|
```json
|
|
{
|
|
"index": 0,
|
|
"input": "10.1.1.1 + 1",
|
|
"output": "10.1.1.2", // Texto tal como se muestra en la app
|
|
"result_type": "FourBytes", // Tipo del objeto resultado
|
|
"success": true,
|
|
"error": null
|
|
}
|
|
```
|
|
|
|
### Resultado Individual (Query `exec`)
|
|
|
|
```json
|
|
{
|
|
"index": 1,
|
|
"input": "type(engine.last_result).__name__",
|
|
"output": "FourBytes", // String del resultado
|
|
"result_type": "str", // Tipo del resultado de la evaluación
|
|
"success": true,
|
|
"error": null,
|
|
"exec_result": "FourBytes" // Valor directo (serializado si es necesario)
|
|
}
|
|
```
|
|
|
|
### Resultado con Error
|
|
|
|
```json
|
|
{
|
|
"index": 2,
|
|
"input": "IP4Mask(255.240.0.3)",
|
|
"output": "None",
|
|
"result_type": "NoneType",
|
|
"success": false,
|
|
"error": "❌ Máscara inválida: 255.240.0.3..."
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Funciones de Inspección Útiles
|
|
|
|
### Estado del Motor
|
|
|
|
```python
|
|
"engine.symbol_table" # Variables actuales
|
|
"engine.last_result" # Último resultado
|
|
"engine.symbolic_mode" # ¿Modo simbólico activo?
|
|
"len(engine.equations)" # Cantidad de ecuaciones en el sistema
|
|
"engine.debug" # ¿Debug habilitado?
|
|
"list(engine.base_context.keys())[:10]" # Funciones disponibles (muestra 10)
|
|
```
|
|
|
|
### Información de Tipos
|
|
|
|
```python
|
|
"engine.get_available_types()" # Info completa de tipos registrados
|
|
"list(engine.registered_types_info['registered_classes'].keys())" # Lista de tipos
|
|
"engine.registered_types_info['class_count']" # Cantidad de tipos registrados
|
|
"type(engine.last_result).__name__" # Tipo del último resultado
|
|
"hasattr(engine.last_result, 'has_symbols')" # ¿El resultado tiene símbolos?
|
|
```
|
|
|
|
### Tokenización y Parsing
|
|
|
|
```python
|
|
"engine.parser.get_tokenization_info()" # Info completa de tokenización
|
|
"engine.parser.process_expression('test')" # Procesar expresión específica
|
|
"len(engine.parser.tokenizer.tokenization_rules)" # Cantidad de reglas
|
|
"engine._classify_line('x = 5')" # Clasificar tipo de línea
|
|
"engine._extract_variable_names('x + y')" # Extraer nombres de variables
|
|
```
|
|
|
|
### Análisis de Objetos Específicos
|
|
|
|
```python
|
|
# Para FourBytes
|
|
"engine.last_result.original" # String original
|
|
"engine.last_result._numeric_value" # Valor numérico interno
|
|
"engine.last_result.has_symbols" # ¿Tiene símbolos?
|
|
|
|
# Para IntBase
|
|
"engine.last_result.base" # Base numérica (10, 16, 8, 2)
|
|
"engine.last_result.value_str" # String del valor
|
|
"engine.last_result._symbols" # Símbolos detectados
|
|
|
|
# Para IP4Mask
|
|
"engine.last_result.get_prefix_int()" # Prefijo como entero
|
|
"engine.last_result.is_valid()" # ¿Es máscara válida?
|
|
```
|
|
|
|
---
|
|
|
|
## Patrones de Debugging
|
|
|
|
### 1. Debugging de Regresión
|
|
|
|
**Cuándo usar**: Verificar que cambios no rompan funcionalidad existente.
|
|
|
|
```json
|
|
{
|
|
"queries": [
|
|
{"index": 0, "type": "input", "content": "10.1.1.1 + 1"},
|
|
{"index": 1, "type": "exec", "content": "type(engine.last_result).__name__"},
|
|
{"index": 2, "type": "input", "content": "16#FF + 10"},
|
|
{"index": 3, "type": "exec", "content": "engine.last_result.base"},
|
|
{"index": 4, "type": "input", "content": "IP4Mask(255.255.0.0)"},
|
|
{"index": 5, "type": "exec", "content": "engine.last_result.get_prefix_int()"}
|
|
]
|
|
}
|
|
```
|
|
|
|
### 2. Debugging de Nuevas Funcionalidades
|
|
|
|
**Cuándo usar**: Verificar que nueva funcionalidad trabaja correctamente.
|
|
|
|
```json
|
|
{
|
|
"queries": [
|
|
{"index": 0, "type": "input", "content": "NUEVA_FUNCIONALIDAD_AQUI"},
|
|
{"index": 1, "type": "exec", "content": "type(engine.last_result)"},
|
|
{"index": 2, "type": "exec", "content": "dir(engine.last_result)"},
|
|
{"index": 3, "type": "exec", "content": "str(engine.last_result)"},
|
|
{"index": 4, "type": "exec", "content": "engine.symbol_table"}
|
|
]
|
|
}
|
|
```
|
|
|
|
### 3. Debugging de Performance
|
|
|
|
**Cuándo usar**: Identificar operaciones lentas o problemáticas.
|
|
|
|
```json
|
|
{
|
|
"queries": [
|
|
{"index": 0, "type": "exec", "content": "import time; start = time.time()"},
|
|
{"index": 1, "type": "input", "content": "OPERACION_LENTA"},
|
|
{"index": 2, "type": "exec", "content": "time.time() - start"},
|
|
{"index": 3, "type": "exec", "content": "len(engine.symbol_table)"}
|
|
]
|
|
}
|
|
```
|
|
|
|
### 4. Debugging de Comportamiento
|
|
|
|
**Cuándo usar**: Verificar comportamiento específico de tipos o funciones.
|
|
|
|
```json
|
|
{
|
|
"queries": [
|
|
{"index": 0, "type": "input", "content": "EXPRESION"},
|
|
{"index": 1, "type": "exec", "content": "str(engine.last_result)"},
|
|
{"index": 2, "type": "exec", "content": "repr(engine.last_result)"},
|
|
{"index": 3, "type": "exec", "content": "type(engine.last_result).__name__"}
|
|
]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Comandos de Ejecución
|
|
|
|
```bash
|
|
# Ejecución básica
|
|
python simple_debug.py mi_debug.json
|
|
|
|
# Con archivo de salida específico
|
|
python simple_debug.py mi_debug.json --output resultados.json
|
|
|
|
# Modo verboso (para ver progreso)
|
|
python simple_debug.py mi_debug.json --verbose
|
|
```
|
|
|
|
---
|
|
|
|
## Templates Existentes para Reutilizar
|
|
|
|
### Casos Básicos
|
|
**Archivo**: `debug_templates/basic_test.json`
|
|
- Operaciones con FourBytes e IntBase
|
|
- Variables y SymPy básico
|
|
|
|
### Testing de Errores
|
|
**Archivo**: `debug_templates/error_debug.json`
|
|
- Máscaras inválidas
|
|
- IPs fuera de rango
|
|
- Expresiones malformadas
|
|
|
|
### Información de Contexto
|
|
**Archivo**: `debug_templates/context_debug.json`
|
|
- Estado completo del motor
|
|
- Tipos registrados
|
|
- Sistema de ecuaciones
|
|
|
|
### Tokenización
|
|
**Archivo**: `debug_templates/tokenization_test.json`
|
|
- Debug del sistema de parsing
|
|
- Reglas de tokenización
|
|
|
|
---
|
|
|
|
## Flujo de Resolución de Problemas
|
|
|
|
### 1. Identificar el Problema
|
|
- ¿Es un error de evaluación?
|
|
- ¿Es un problema de tokenización?
|
|
- ¿Es un problema de estado del motor?
|
|
|
|
### 2. Crear Query de Diagnóstico
|
|
- Usar query `input` para reproducir el problema
|
|
- Usar query `exec` para inspeccionar el estado
|
|
|
|
### 3. Analizar Resultados
|
|
- Verificar `success: true/false`
|
|
- Examinar `error` si hay fallo
|
|
- Comparar `output` (texto de la app) con `exec_result` (valor interno)
|
|
|
|
### 4. Iterar
|
|
- Crear nuevas queries basadas en hallazgos
|
|
- Profundizar en áreas problemáticas
|
|
- Verificar soluciones con queries adicionales
|
|
|
|
---
|
|
|
|
## Ejemplo Completo de Debugging
|
|
|
|
**Problema**: "La operación `192.168.1.x + 1` no funciona correctamente"
|
|
|
|
### Paso 1: Crear archivo de debug
|
|
|
|
```json
|
|
{
|
|
"queries": [
|
|
{"index": 0, "type": "input", "content": "192.168.1.x + 1"},
|
|
{"index": 1, "type": "exec", "content": "type(engine.last_result).__name__"},
|
|
{"index": 2, "type": "exec", "content": "engine.last_result.has_symbols"},
|
|
{"index": 3, "type": "exec", "content": "engine.parser.process_expression('192.168.1.x + 1')"},
|
|
{"index": 4, "type": "input", "content": "ip = 192.168.1.x"},
|
|
{"index": 5, "type": "exec", "content": "type(engine.symbol_table['ip'])"},
|
|
{"index": 6, "type": "input", "content": "ip.substitute(x=5)"}
|
|
]
|
|
}
|
|
```
|
|
|
|
### Paso 2: Ejecutar
|
|
```bash
|
|
python simple_debug.py debug_problema.json
|
|
```
|
|
|
|
### Paso 3: Analizar resultados
|
|
- Verificar si `192.168.1.x + 1` se evalúa correctamente (campo `output`)
|
|
- Comprobar el tipo resultante con `exec`
|
|
- Verificar si tiene símbolos
|
|
- Examinar cómo se tokeniza la expresión
|
|
- Probar operaciones relacionadas
|
|
|
|
Este flujo te permite identificar exactamente dónde está el problema y verificar la solución.
|
|
|
|
---
|
|
|
|
## Consejos para LLMs
|
|
|
|
1. **Siempre usa índices secuenciales** en las queries para facilitar la lectura
|
|
2. **Combina queries `input` y `exec`** para obtener contexto completo
|
|
3. **El campo `output` es texto tal como se muestra en la aplicación**
|
|
4. **El campo `exec_result` es el valor directo de la evaluación Python**
|
|
5. **Usa los templates existentes** como punto de partida
|
|
6. **Examina `success` y `error`** antes de analizar resultados
|
|
7. **Crea queries incrementales** que construyan sobre resultados anteriores
|
|
8. **NO intentes duplicar lógica de la aplicación** - usa solo llamadas directas
|
|
|
|
---
|
|
|
|
## Referencia Rápida
|
|
|
|
### Query Básica
|
|
```json
|
|
{"index": N, "type": "input|exec", "content": "CONTENIDO"}
|
|
```
|
|
|
|
### Comandos Esenciales
|
|
```bash
|
|
python simple_debug.py archivo.json # Ejecutar debug
|
|
python simple_debug.py archivo.json --verbose # Con detalles
|
|
python simple_debug.py archivo.json -o resultado.json # Salida específica
|
|
```
|
|
|
|
### Inspección Básica del Motor
|
|
```python
|
|
"engine.last_result" # Último resultado
|
|
"type(engine.last_result)" # Tipo del resultado
|
|
"engine.symbol_table" # Variables actuales
|
|
"engine.get_available_types()" # Tipos registrados
|
|
"engine.parser.get_tokenization_info()" # Info de parsing
|
|
```
|
|
|
|
### Análisis de Resultado
|
|
```python
|
|
"success": true/false # ¿Éxito?
|
|
"error": "mensaje" # Error si falla
|
|
"output": "resultado" # Texto tal como se muestra en la app
|
|
"exec_result": valor # Valor directo (exec queries)
|
|
```
|
|
|
|
### Templates Disponibles
|
|
- `debug_templates/basic_test.json` - Pruebas básicas
|
|
- `debug_templates/error_debug.json` - Testing de errores
|
|
- `debug_templates/context_debug.json` - Estado del motor
|
|
- `debug_templates/tokenization_test.json` - Debug de parsing
|
|
|
|
### Workflow Típico
|
|
1. **Identificar problema** → Crear query `input` para reproducir
|
|
2. **Inspeccionar estado** → Añadir queries `exec` para diagnosticar
|
|
3. **Analizar resultados** → Examinar `success`, `error`, `output`
|
|
4. **Iterar** → Crear nuevas queries basadas en hallazgos
|
|
|
|
**Principio clave**: texto → texto. La API no interpreta ni procesa, solo encapsula llamadas directas al motor existente. |