--- 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& active_headers, const std::vector& 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.