---
name: data_table_ai_panel
kind: function
lang: cpp
domain: viz
version: "1.0.0"
purity: impure
signature: "void data_table::draw_ask_ai_modal(AskAiState& ask_ai, State& st, const std::vector<std::string>& active_headers, const std::vector<ColumnType>& active_types, int orig_cols)"
description: "Modal 'Ask AI' de la tabla TQL: UI de prompt en lenguaje natural, llamada bloqueante a llm_anthropic::ask, render de la respuesta (codigo TQL o SQL editable), botones Apply/Reject/Close. El Apply ejecuta tql::apply sobre el estado actual de la tabla. Soporta modo TQL (default) y SQL (requiere FN_TQL_DUCKDB). Sub-funcion extraida de modules/data_table/data_table.cpp (issue 0107c, fase 11 / issue 0080)."
tags: [viz, table, imgui, ui, ai, llm, tql, cpp-tables, ask-ai]
uses_functions:
  - data_table_cpp_viz
uses_types:
  - data_table_types_cpp_core
returns: []
returns_optional: false
error_type: "error_go_core"
imports: [imgui]
tested: false
tests: []
test_file_path: ""
file_path: "cpp/functions/viz/data_table_ai_panel.cpp"
framework: imgui
params:
  - name: ask_ai
    desc: "Estado mutable del modal (AskAiState): prompt, modo TQL/SQL, buffers de respuesta, flags open/busy. Debe persistir entre frames (vive en UiState del data_table)."
  - name: st
    desc: "State principal de la tabla. Mutado por Apply: tql::apply modifica st.stages, filtros, sorts."
  - name: active_headers / active_types
    desc: "Snapshot del output del stage activo en el momento de abrir el modal. Se pasan a llm_anthropic::AskInput para que el modelo conozca el schema."
  - name: orig_cols
    desc: "Numero de columnas originales. Necesario para la firma de tql::apply."
output: "Void. Efectos: mutates ask_ai (flags, buffers), mutates st (via tql::apply en Apply)."
---

## Documentacion

Sub-funcion que encapsula el modal "Ask AI" de la tabla TQL (issue 0080, fase 11). Permite al usuario escribir una pregunta en lenguaje natural y recibir codigo TQL o SQL generado por un modelo de lenguaje.

### Flujo del modal

1. `ask_ai.open = true` (seteado por boton "Ask AI" en `draw_viz_selector`).
2. Primer frame con `open=true`: `ImGui::OpenPopup("Ask AI")`.
3. Modal se abre: prompt input, combo modo TQL/SQL.
4. Usuario escribe pregunta y hace click en "Send":
   - Construye `llm_anthropic::AskInput` con `question`, `col_names`, `col_types`, `tql_current`.
   - Llamada **bloqueante** a `llm_anthropic::ask(in)` → `AskResult`.
   - Si error: `ask_ai.error` se muestra en rojo.
   - Si ok: `ask_ai.response_code` se copia a `ask_ai.edit_buf` (editable).
5. Panel dividido en dos columnas: TQL actual (read-only) | propuesta (editable).
6. Botones:
   - **Apply**: ejecuta `tql::apply(ask_ai.edit_buf, st, ...)`. Si ok: cierra modal.
   - **Reject**: limpia `edit_buf` y `response_code`.
   - **Close**: `ask_ai.open = false`.

### Dependencia llm_anthropic

Si `FN_LLM_ANTHROPIC` esta definido en el build, se incluye `core/llm_anthropic.h` (real). Si no, se usa el stub no-op que retorna error "not available". Pendiente promover a `cpp/functions/infra/llm_anthropic` (Wave 4, issue 0107c deuda tecnica).

## Ejemplo

```cpp
// En el render principal, llamar una vez por frame tras el grid:
data_table::draw_ask_ai_modal(U.ask_ai, st,
    U.active_headers, U.active_types, orig_cols);

// El boton de apertura vive en draw_viz_selector:
//   if (ImGui::SmallButton("Ask AI##ask_open")) U.ask_ai.open = true;
```

## Cuando usarla

Llamar una vez por frame desde el entrypoint thin `data_table::render()` en el bloque de modales (junto a TQL show/apply, Custom column, etc.), SIEMPRE que el contexto ImGui tenga la ventana activa. No llamar desde apps directamente.

## Gotchas

- La llamada a `llm_anthropic::ask` es **bloqueante** (red HTTP). La UI se congela brevemente. Consideracion futura: mover a hilo background + flag de estado asincrono.
- El modal se destruye (EndPopup) si el usuario hace click fuera. `ask_ai.open` se pone a false por el `&ask_ai.open` del `BeginPopupModal`. Esto borra el estado del prompt en curso — consideracion UX conocida.
- En modo SQL (`ask_ai.mode == 1`), Apply solo funciona si `FN_TQL_DUCKDB` esta definido; de lo contrario muestra mensaje de error informativo.
- `llm_anthropic` no esta en el registry (deuda Wave 4). Hasta que se promueva, el stub vive inlined en este .cpp. No duplicar el stub en otros archivos.
