From 26e4266c8281fe196ad2262d44aa52a1ae7eaefd Mon Sep 17 00:00:00 2001 From: Egutierrez Date: Tue, 12 May 2026 03:17:43 +0200 Subject: [PATCH] chore(issues): auto-commit Co-Authored-By: Claude Opus 4.7 (1M context) --- dev/issues/0079-tables-drill-ext.md | 71 +++++++++++++ dev/issues/0080-tables-llm-api.md | 77 ++++++++++++++ dev/issues/0081-tables-promote-registry.md | 118 +++++++++++++++++++++ 3 files changed, 266 insertions(+) create mode 100644 dev/issues/0079-tables-drill-ext.md create mode 100644 dev/issues/0080-tables-llm-api.md create mode 100644 dev/issues/0081-tables-promote-registry.md diff --git a/dev/issues/0079-tables-drill-ext.md b/dev/issues/0079-tables-drill-ext.md new file mode 100644 index 00000000..4e4905f8 --- /dev/null +++ b/dev/issues/0079-tables-drill-ext.md @@ -0,0 +1,71 @@ +--- +id: 0079 +title: tables playground — drill-through extendido (fase 10) +status: pending +priority: medium +created: 2026-05-12 +related_components: [cpp/apps/primitives_gallery/playground/tables] +--- + +## Contexto + +Fase 10 del roadmap del tables playground. Drill-down basico ya implementado +(`make_drill_filter` + chip de filtro en stage previo). Falta granularidad de +zoom, presets rapidos, click sobre elementos del chart, historial de drill y +row inspector. + +## Cambios + +### 1. Zoom granularity sobre cols Date + +- Detectar col tipo `Date` en breakout. +- Combo en chip de breakout: "year / month / week / day / hour". +- Pure fn `truncate_date_cpp_core(date_str, granularity) -> string`. +- Stage 1 con breakout `:month` agrega valores formateados al granular. +- TQL: `breakout = {"col:month"}` (sufijo despues de `:`). +- Auto-detect granularity inicial: si rango > 2 anios -> year; > 60 dias -> month; > 14 dias -> week; resto -> day. + +### 2. Quick filter presets + +- Boton "Presets" en chip row de filtros. +- Menu con: + - "Top 10 by " (auto-sugiere col numerica) + - "Last 7 / 30 / 90 dias" (si hay col Date) + - "Exclude nulls in " + - "Non-zero only" +- Aplica como filtros al stage activo. + +### 3. Click-to-drill sobre chart elements + +- Bar/Column/Pie/Funnel: click en elemento -> `make_drill_filter(col_idx, value)` -> push filter en stage previo, `active_stage--`. +- Scatter/Bubble: click en punto -> filter por X y Y rangos cercanos (snap to nearest data point) o muestra row inspector. +- Heatmap: click en celda -> filtro por par (row, col). +- ImPlot api: `ImPlot::IsPlotHovered() + GetPlotMousePos()`. Hit-test propio para barras. + +### 4. Drill history (back/forward) + +- Pila de `DrillStep { stage_idx, filter_added }` en `UiState.drill_history`. +- Botones `<` `>` en breadcrumb para back/forward. +- TQL preserva el stage agrupado pero no la history (es UI state efimero). + +### 5. Row inspector + +- Click derecho sobre row de tabla o punto de chart -> popup modal con todas las cols + valores de la fila. +- Incluye cols ocultas. +- Solo lectura. Boton "Copy as TSV" + "Filter by this row". + +### 6. Drill-up: vuelve un stage atras sin perder filtros nuevos + +- Boton `<` en breadcrumb del stage previo: pushdown del filter actual al stage anterior + active--. +- Inverso de drill-down. Usuario navega la jerarquia sin perder camino. + +## Tests + +- `truncate_date_cpp_core` para granularities (round-trip por fecha conocida). +- Pure fn de quick filter presets (build `vector` desde preset id). +- Round-trip TQL con breakout sufijo `:month`. + +## No-objetivos + +- Map drill (lat/lng -> region) — fuera de scope. +- Cross-filter entre paneles (click en panel A filtra panel B) — fase futura. diff --git a/dev/issues/0080-tables-llm-api.md b/dev/issues/0080-tables-llm-api.md new file mode 100644 index 00000000..35ff388a --- /dev/null +++ b/dev/issues/0080-tables-llm-api.md @@ -0,0 +1,77 @@ +--- +id: 0080 +title: tables playground — LLM API "Ask AI" (fase 11) +status: pending +priority: medium +created: 2026-05-12 +related_components: [cpp/apps/primitives_gallery/playground/tables] +--- + +## Contexto + +Fase 11 del roadmap del tables playground. El user escribe en lenguaje natural +una pregunta sobre los datos ("show me top 10 langs by total size"). El LLM +recibe el TQL actual + schema + pregunta, devuelve nuevo TQL. App aplica via +`tql::apply` y renderiza. + +## Cambios + +### 1. UI + +- Boton "Ask AI" en toolbar (al lado de "+ Viz"). +- Modal con: + - InputText multiline para la pregunta. + - Boton "Send" + spinner durante la llamada. + - Diff side-by-side: TQL actual vs TQL propuesto (texto con highlight). + - Botones "Apply" / "Reject" / "Edit before apply". + +### 2. Backend LLM + +- Provider: Anthropic Claude (API key desde `pass anthropic/api-key`). +- Endpoint: `https://api.anthropic.com/v1/messages`. +- Model: `claude-sonnet-4-6` por defecto. Configurable via env `FN_LLM_MODEL`. +- Cliente HTTP: cURL via popen (sin deps nuevas) o libcurl si ya esta linkada. +- Prompt template incluye: + - Esquema TQL (de `docs/TQL.md`). + - Cols disponibles del stage 0 (name, type) + cols joinables. + - Funciones Lua disponibles (de `lua_engine`). + - TQL actual. + - Pregunta del user. +- Response: extraer ```lua``` block del markdown, strip prose. + +### 3. Validacion + safety + +- Antes de aplicar: `tql::apply` con dry-run (parsea sin mutar State). Si fail, mostrar error + boton "Ask AI again with this error". +- Lua sandbox ya cubre side effects en formulas — el TQL en si es declarativo, no ejecuta nada peligroso. + +### 4. Streaming + +- Stream tokens via SSE (`stream=true` en Anthropic API). +- Mostrar texto en vivo en el modal. +- Cuando termina, parsear lua block final. + +### 5. Persistencia conversation + +- UiState guarda lista de turns (pregunta + TQL propuesto + resultado apply). +- "Ask AI" siguiente turn incluye history previa. +- Boton "Reset chat" limpia. +- NO persistido en TQL (es UI state). + +### 6. Coste / rate limit + +- Mostrar tokens estimados antes de enviar (rough char count / 4). +- Cap input a 8000 tokens. +- Error handling: 429 / 5xx -> mensaje + reintentar. + +## Tests + +- Mockear HTTP response con cURL stub. +- Test: prompt build incluye schema + TQL + pregunta en formato esperado. +- Test: response parse extrae lua block correctamente. +- Test: tql::apply sobre output del LLM funciona end-to-end con dataset sintetico. + +## No-objetivos + +- Generacion de visualizaciones nuevas via LLM (la viz la elige TQL `display`, suficiente). +- Acciones del LLM mas alla de modificar TQL (sin acceso a I/O del sistema). +- Multi-provider (OpenAI / local) — fase futura. Hardcode Anthropic primero. diff --git a/dev/issues/0081-tables-promote-registry.md b/dev/issues/0081-tables-promote-registry.md new file mode 100644 index 00000000..e4aa1c38 --- /dev/null +++ b/dev/issues/0081-tables-promote-registry.md @@ -0,0 +1,118 @@ +--- +id: 0081 +title: tables playground — promote a registry + migrar apps C++ (fase 12) +status: pending +priority: high +created: 2026-05-12 +related_components: [cpp/apps/primitives_gallery/playground/tables, cpp/functions, fn_framework] +--- + +## Contexto + +Fase 12 final del roadmap. Extraer el playground completo al registry como +funciones reutilizables. Migrar todas las apps C++ que renderizan tablas para +que usen `data_table_cpp_viz` en vez de codigo propio. + +## Extraccion al registry + +### Funciones a crear + +| ID | Lang | Domain | Purity | Que hace | +|-------------------------------|------|----------|--------|----------| +| `data_table_cpp_viz` | cpp | viz | impure | UI completa: chips + tabla + viz + extras + joins + TQL | +| `compute_stage_cpp_core` | cpp | core | pure | Ejecuta un Stage (filter+breakout+agg+sort) | +| `compute_pipeline_cpp_core` | cpp | core | pure | Chain de stages 0..N -> StageOutput final | +| `tql_emit_cpp_core` | cpp | core | pure | State -> Lua text | +| `tql_apply_cpp_core` | cpp | core | pure | Lua text -> State (+ warnings) | +| `viz_render_cpp_viz` | cpp | viz | impure | Dispatcher ImPlot sobre StageOutput | +| `lua_engine_cpp_core` | cpp | core | impure | Eval de formulas Lua sandboxed | +| `join_tables_cpp_core` | cpp | core | pure | Hash join multi-key, 4 estrategias | +| `auto_detect_type_cpp_core` | cpp | core | pure | Auto-detect ColumnType desde sample (ya existe en logic) | +| `compute_column_stats_cpp_core` | cpp | core | pure | Stats por col (mean/p25/p50/p75/uniq/missing/hist) | + +### Tipos + +| ID | Algebraic | +|-----------------------------|-----------| +| `ColumnType_cpp_core` | sum | +| `Op_cpp_core` | sum | +| `Filter_cpp_core` | product | +| `Stage_cpp_core` | product | +| `StageOutput_cpp_core` | product | +| `Aggregation_cpp_core` | product | +| `Join_cpp_core` | product | +| `TableInput_cpp_core` | product | +| `ViewMode_cpp_viz` | sum | +| `ViewConfig_cpp_viz` | product | +| `VizPanel_cpp_viz` | product | +| `State_cpp_viz` | product | +| `ColStats_cpp_core` | product | + +### Estructura en el registry + +``` +cpp/functions/core/ + compute_stage.{h,cpp,md} + compute_pipeline.{h,cpp,md} + tql_emit.{h,cpp,md} + tql_apply.{h,cpp,md} + lua_engine.{h,cpp,md} + join_tables.{h,cpp,md} + data_table_logic.h # tipos compartidos (Stage, ColumnType, etc.) + ... +cpp/functions/viz/ + data_table.{h,cpp,md} # UI principal + viz_render.{h,cpp,md} # dispatcher ImPlot +``` + +Dominio nuevo `viz` para funciones de visualizacion. Alternativa: usar `tui` +si encaja, pero `viz` es mas explicito. + +### Bundle en `fn_framework` + +`fn_framework` ya bundle a `lua54`, `implot`. Añadir las funciones core/viz +como parte del lib estatico opcional `fn_table_viz` que las apps linkan via +`target_link_libraries( PRIVATE fn_table_viz)`. + +## Migracion de apps existentes + +Apps con tabla custom hoy: + +| App | Cambios | +|----------------------------------------------|---------| +| `cpp/apps/chart_demo` | Sustituir tabla por `data_table::render({tables}, state)`. Persistir State en SQLite local. | +| `projects/osint_graph/apps/graph_explorer` | Reemplaza panels que listan entities/relations con render(). Pasa multiples TableInput (entities, relations, jobs). | +| `projects/fn_monitoring/apps/registry_dashboard` | Tablas de funciones/types/apps via render. Joinables: cross-references entre tablas. | +| `projects/fn_monitoring/apps/sqlite_api` | Resultado de query como TableInput. | +| `apps/kanban` | NO migrar — kanban no es tabla, es board. | +| `apps/deploy_server` | Tabla de deploys + targets. | + +Cada migracion en su rama TBD propia (ver `apps_tbd.md`). + +## TQL como contrato textual + +Documento `docs/TQL.md` ya existe pero hay que actualizar: +- Anadir `joins`, `views`, `main_source` (faltan) +- Listado completo de viz tokens +- Funciones Lua disponibles + sandbox + +## Tests + +- `compute_stage/pipeline` ya tienen tests en playground self_test. Mover a `cpp/functions/core/*_test.cpp`. +- Smoke test: app fake con TableInput hardcoded -> render() compila + tests basicos pasan. +- `fn run` debe poder ejecutar tests de las nuevas funciones. + +## Doctor + +`fn doctor cpp-apps` añadir check: apps con tablas custom (heuristica: `ImGui::BeginTable` en main.cpp) sugieren migracion a `data_table_cpp_viz`. + +## Riesgos + +- Linker bloat: cada app que use `data_table_cpp_viz` arrastra lua54 (~150KB) + implot (~200KB). Aceptable. +- API stability: una vez en registry hay que mantener `render()` signature. Cualquier breaking change requiere proposal. +- Tests duplicados: borrar self_test.cpp del playground si los tests se mueven al registry. + +## No-objetivos + +- Migrar a otras tecnologias (web, mobile) — fase futura via TS/Kotlin equivalentes. +- Reescribir apps que no usen tablas — fuera de scope.