auto(0129): agents_dashboard — secret_store_cpp_infra + CMakeLists register #4

Open
dataforge wants to merge 615 commits from auto/0129 into master
3 changed files with 266 additions and 0 deletions
Showing only changes of commit b4c28da2ba - Show all commits
+71
View File
@@ -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 `<col>: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 <col>" (auto-sugiere col numerica)
- "Last 7 / 30 / 90 dias" (si hay col Date)
- "Exclude nulls in <col>"
- "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<Filter>` 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.
+77
View File
@@ -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.
+118
View File
@@ -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(<app> 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.