15 KiB
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. 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)
- Analizar el formato de salida exacto como se muestra en la aplicación
- 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.
{"index": 0, "type": "input", "content": "10.1.1.1 + 1"}
Query tipo exec
Ejecuta código Python para inspeccionar el estado interno del motor.
{"index": 1, "type": "exec", "content": "type(engine.last_result).__name__"}
Plantilla Base
{
"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.
{
"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.
{
"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.
{
"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.
{
"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
{
"execution_info": {
"timestamp": "2025-06-05T18:01:28.644799Z",
"total_queries": 5,
"successful": 4,
"failed": 1
},
"results": [...]
}
Resultado Individual (Query input
)
{
"index": 0,
"input": "10.1.1.1 + 1",
"output": "10.1.1.2", // Resultado básico
"result_type": "FourBytes", // Tipo del objeto resultado
"success": true,
"error": null,
"display_class": "[FourBytes]", // Nombre de clase para display
"output_raw": { // ⭐ INFORMACIÓN DE FORMATO
"parts": [
["custom_type", "10.1.1.2"], // [tag_color, contenido]
["class_hint", "[FourBytes]"]
],
"formatted_text": "[custom_type]10.1.1.2[class_hint][FourBytes]",
"tag_info": { // Información de colores
"custom_type": {"fg": "#f9a825"},
"class_hint": {"fg": "#888888"}
}
}
}
Resultado Individual (Query exec
)
{
"index": 1,
"input": "type(engine.last_result).__name__",
"output": "FourBytes",
"result_type": "str",
"success": true,
"error": null,
"exec_result": "FourBytes" // Resultado crudo del exec
}
Resultado con Error
{
"index": 2,
"input": "IP4Mask(255.240.0.3)",
"output": "None",
"result_type": "NoneType",
"success": false,
"error": "❌ Máscara inválida: 255.240.0.3...",
"output_raw": {
"parts": [["error", "Error: ❌ Máscara inválida..."]],
"formatted_text": "[error]Error: ❌ Máscara inválida...",
"tag_info": {"error": {"fg": "#ff6b6b", "font": "bold"}}
}
}
Funciones de Inspección Útiles
Estado del Motor
"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
"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
"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
# 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.
{
"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.
{
"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.
{
"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 Display/Formato
Cuándo usar: Verificar cómo se muestra exactamente un resultado.
{
"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__"}
]
}
Análisis de output_raw
El campo output_raw
contiene información exacta sobre cómo se muestra el resultado en la aplicación:
Tags de Color Importantes
error
(#ff6b6b
): Errorescustom_type
(#f9a825
): Tipos personalizados (FourBytes, IntBase, etc.)symbolic
(#82aaff
): Expresiones simbólicasnumeric
(#c3e88d
): Aproximaciones numéricasclass_hint
(#888888
): Pistas de clase[FourBytes]
ip
(#fff176
): Direcciones IP específicamentehex
(#f9a825
): Números hexadecimales
Interpretación de Parts
"parts": [
["custom_type", "192.168.1.2"], // Resultado principal en naranja
["class_hint", "[FourBytes]"] // Pista de clase en gris
]
Esto significa: "192.168.1.2" se muestra en color naranjo seguido de "[FourBytes]" en gris.
Comandos de Ejecución
# 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
Formato de Display
Archivo: debug_templates/display_format_test.json
- Demostración de
output_raw
- Diferentes tipos de formato
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 formato/display?
- ¿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 - Analizar
output_raw
para problemas de display - Usar
exec_result
para inspección detallada
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
{
"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
python simple_debug.py debug_problema.json
Paso 3: Analizar resultados
- Verificar si
192.168.1.x + 1
se evalúa correctamente - Comprobar el tipo resultante
- 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
- Siempre usa índices secuenciales en las queries para facilitar la lectura
- Combina queries
input
yexec
para obtener contexto completo - Verifica tanto
output
comooutput_raw
para problemas de display - Usa los templates existentes como punto de partida
- Examina
success
yerror
antes de analizar resultados - Aprovecha
exec_result
para inspección detallada del estado - Crea queries incrementales que construyan sobre resultados anteriores
Con esta API, puedes debuggear efectivamente la calculadora sin necesidad de modificar código fuente o crear scripts adicionales.
Referencia Rápida
Query Básica
{"index": N, "type": "input|exec", "content": "CONTENIDO"}
Comandos Esenciales
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
"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
"success": true/false # ¿Éxito?
"error": "mensaje" # Error si falla
"output": "resultado" # Resultado básico
"output_raw": {...} # Formato exacto de la app
"exec_result": valor # Resultado crudo (exec queries)
Templates Disponibles
debug_templates/basic_test.json
- Pruebas básicasdebug_templates/error_debug.json
- Testing de erroresdebug_templates/context_debug.json
- Estado del motordebug_templates/tokenization_test.json
- Debug de parsingdebug_templates/display_format_test.json
- Formato de display
Workflow Típico
- Identificar problema → Crear query
input
para reproducir - Inspeccionar estado → Añadir queries
exec
para diagnosticar - Analizar resultados → Examinar
success
,error
,output_raw
- Iterar → Crear nuevas queries basadas en hallazgos