chore: auto-commit (5 archivos)

- CMakeLists.txt
- agent.cpp
- agent.h
- gx-cli
- main.cpp

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-10 13:30:27 +02:00
parent fb84a566f2
commit 0bab5c97c7
5 changed files with 20 additions and 20 deletions
+1 -1
View File
@@ -26,7 +26,7 @@ add_imgui_app(graph_explorer
node_groups.cpp node_groups.cpp
jobs.cpp jobs.cpp
enrichers.cpp enrichers.cpp
chat.cpp agent.cpp
extract_panel.cpp extract_panel.cpp
# --- viz --- # --- viz ---
${FN_CPP_ROOT_DIR}/functions/viz/graph_renderer.cpp ${FN_CPP_ROOT_DIR}/functions/viz/graph_renderer.cpp
+8 -8
View File
@@ -1,4 +1,4 @@
#include "chat.h" #include "agent.h"
#include "app_base.h" #include "app_base.h"
#include "imgui.h" #include "imgui.h"
@@ -40,7 +40,7 @@
#include <unistd.h> #include <unistd.h>
#endif #endif
namespace ge { namespace app_agent {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Logger con tags // Logger con tags
@@ -697,7 +697,7 @@ void on_stream_line(const std::string& line) {
std::string build_system_prompt() { std::string build_system_prompt() {
return return
"Eres Echo — copiloto OSINT del usuario sobre la operations.db\n" "Eres el Agente — copiloto OSINT del usuario sobre la operations.db\n"
"abierta en graph_explorer. Tu trabajo es explorar, investigar y\n" "abierta en graph_explorer. Tu trabajo es explorar, investigar y\n"
"conectar piezas. El usuario VE el grafo en pantalla; tu lo\n" "conectar piezas. El usuario VE el grafo en pantalla; tu lo\n"
"modificas y razonas sobre el.\n\n" "modificas y razonas sobre el.\n\n"
@@ -730,7 +730,7 @@ std::string build_system_prompt() {
" que sugerencias de proximo paso, hallazgos no obvios.\n\n" " que sugerencias de proximo paso, hallazgos no obvios.\n\n"
"Tu objetivo: ser un copiloto util para investigacion OSINT, no un\n" "Tu objetivo: ser un copiloto util para investigacion OSINT, no un\n"
"ejecutor mecanico. Propon, conecta, descubre patrones. Firmas\n" "ejecutor mecanico. Propon, conecta, descubre patrones. Firmas\n"
"como Echo cuando tenga sentido marcar identidad."; "como Agente cuando tenga sentido marcar identidad.";
} }
// Convierte un path Windows (UNC \\wsl.localhost\<distro>\... o C:\...) al // Convierte un path Windows (UNC \\wsl.localhost\<distro>\... o C:\...) al
@@ -1018,7 +1018,7 @@ bool chat_init(const char* ops_db_path, const char* app_db_path,
// strip ".db" / sustituir extension // strip ".db" / sustituir extension
size_t slash = p.find_last_of("/\\"); size_t slash = p.find_last_of("/\\");
size_t dir_end = (slash == std::string::npos) ? 0 : slash + 1; size_t dir_end = (slash == std::string::npos) ? 0 : slash + 1;
g_log_path = p.substr(0, dir_end) + "chat.log"; g_log_path = p.substr(0, dir_end) + "agent.log";
// arranca con un separador para distinguir sesiones // arranca con un separador para distinguir sesiones
FILE* f = std::fopen(g_log_path.c_str(), "ab"); FILE* f = std::fopen(g_log_path.c_str(), "ab");
if (f) { if (f) {
@@ -1126,7 +1126,7 @@ void chat_render(bool* panel_open) {
if (!g_st) return; if (!g_st) return;
if (panel_open && !*panel_open) return; if (panel_open && !*panel_open) return;
if (!ImGui::Begin(TI_MESSAGE_CIRCLE " Echo", panel_open)) { if (!ImGui::Begin(TI_MESSAGE_CIRCLE " Agent", panel_open)) {
ImGui::End(); ImGui::End();
return; return;
} }
@@ -1157,7 +1157,7 @@ void chat_render(bool* panel_open) {
break; break;
case ChatMessage::ASSISTANT: case ChatMessage::ASSISTANT:
ImGui::TextColored(ImVec4(0.7f, 0.9f, 0.7f, 1.0f), ImGui::TextColored(ImVec4(0.7f, 0.9f, 0.7f, 1.0f),
TI_ROBOT " Echo"); TI_ROBOT " Agent");
fn_ui::selectable_text_wrapped_force(m.text.c_str()); fn_ui::selectable_text_wrapped_force(m.text.c_str());
break; break;
case ChatMessage::TOOL_USE: case ChatMessage::TOOL_USE:
@@ -1238,4 +1238,4 @@ void chat_shutdown() {
g_st = nullptr; g_st = nullptr;
} }
} // namespace ge } // namespace app_agent
+2 -2
View File
@@ -9,7 +9,7 @@
// fragmentos al historial. gx-cli muta operations.db; el contador // fragmentos al historial. gx-cli muta operations.db; el contador
// agent_mutations en graph_explorer.db dispara reload del viewport. // agent_mutations en graph_explorer.db dispara reload del viewport.
namespace ge { namespace app_agent {
// Inicia el subprocess claude -p (lazy: hasta el primer mensaje no se // Inicia el subprocess claude -p (lazy: hasta el primer mensaje no se
// arranca). Setea env vars GX_OPS_DB / GX_APP_DB / GX_APP_DIR. Devuelve // arranca). Setea env vars GX_OPS_DB / GX_APP_DB / GX_APP_DIR. Devuelve
@@ -62,4 +62,4 @@ void chat_log(const char* tag, const char* fmt, ...);
// Devuelve el path absoluto del fichero de log (vacio si no inicializado). // Devuelve el path absoluto del fichero de log (vacio si no inicializado).
const char* chat_log_path(); const char* chat_log_path();
} // namespace ge } // namespace app_agent
+2 -2
View File
@@ -62,7 +62,7 @@ def _app_db() -> str:
def _log(tag: str, msg: str) -> None: def _log(tag: str, msg: str) -> None:
"""Log a stderr y al fichero gx-cli.log junto a app_db (mismo dir """Log a stderr y al fichero gx-cli.log junto a app_db (mismo dir
que chat.log y .mutations.marker). El fichero permite auditar lo que chat.log y .mutations.marker). El fichero permite auditar lo
que el agente Echo hace cuando algo va mal — `_emit` solo va al que el agente hace cuando algo va mal — `_emit` solo va al
stdout de la herramienta y se pierde en pipelines MCP.""" stdout de la herramienta y se pierde en pipelines MCP."""
line = f"[gx-cli {tag}] {msg}\n" line = f"[gx-cli {tag}] {msg}\n"
sys.stderr.write(line) sys.stderr.write(line)
@@ -609,7 +609,7 @@ def cmd_group_page(args) -> None:
Espejea exactamente la query del loader C++ Espejea exactamente la query del loader C++
`node_groups_page_for_group` para que los tests pytest verifiquen `node_groups_page_for_group` para que los tests pytest verifiquen
el contrato SQL (mismo orden de filas, mismas columnas) sin depender el contrato SQL (mismo orden de filas, mismas columnas) sin depender
del binario. Util tambien como tool MCP para que el agente Echo del binario. Util tambien como tool MCP para que el agente
inspeccione el contenido de un Group sin abrir la app. inspeccione el contenido de un Group sin abrir la app.
""" """
cn = _connect(_ops_db(), readonly=True) cn = _connect(_ops_db(), readonly=True)
+7 -7
View File
@@ -29,7 +29,7 @@
#include "project_manager.h" #include "project_manager.h"
#include "jobs.h" #include "jobs.h"
#include "enrichers.h" #include "enrichers.h"
#include "chat.h" #include "agent.h"
#include "extract_panel.h" #include "extract_panel.h"
#include "../../../../cpp/vendor/sqlite3/sqlite3.h" #include "../../../../cpp/vendor/sqlite3/sqlite3.h"
@@ -725,7 +725,7 @@ static bool load_input(bool first_load) {
// issue 0026 — apunta el JobRunner a la nueva operations.db. // issue 0026 — apunta el JobRunner a la nueva operations.db.
if (g_input.uri) ge::jobs_set_ops_db(g_input.uri); if (g_input.uri) ge::jobs_set_ops_db(g_input.uri);
// Chat agent — refrescar contexto de la nueva operations.db. // Chat agent — refrescar contexto de la nueva operations.db.
if (g_input.uri) ge::chat_set_ops_db(g_input.uri); if (g_input.uri) app_agent::chat_set_ops_db(g_input.uri);
// Cargar posiciones guardadas para este graph_hash. Ahora ANTES del // Cargar posiciones guardadas para este graph_hash. Ahora ANTES del
// bootstrap circular: si tenemos posiciones guardadas las respetamos; // bootstrap circular: si tenemos posiciones guardadas las respetamos;
@@ -1351,12 +1351,12 @@ static void render() {
static int s_throttle = 0; static int s_throttle = 0;
if (++s_throttle >= 8) { if (++s_throttle >= 8) {
s_throttle = 0; s_throttle = 0;
int m = ge::chat_mutations_counter(); int m = app_agent::chat_mutations_counter();
if (s_last_mut == -1) { if (s_last_mut == -1) {
// Primera lectura: solo memorizar, sin disparar reload. // Primera lectura: solo memorizar, sin disparar reload.
s_last_mut = m; s_last_mut = m;
} else if (m != s_last_mut) { } else if (m != s_last_mut) {
ge::chat_log("mut", app_agent::chat_log("mut",
"marker mtime cambio %d -> %d, disparando reload", "marker mtime cambio %d -> %d, disparando reload",
s_last_mut, m); s_last_mut, m);
s_last_mut = m; s_last_mut = m;
@@ -2178,7 +2178,7 @@ static void render() {
ImGui::SetNextWindowPos (ImVec2(vp->WorkPos.x + W * 0.55f, top + 40.0f), ImGui::SetNextWindowPos (ImVec2(vp->WorkPos.x + W * 0.55f, top + 40.0f),
ImGuiCond_FirstUseEver); ImGuiCond_FirstUseEver);
ImGui::SetNextWindowSize(ImVec2(520.0f, 720.0f), ImGuiCond_FirstUseEver); ImGui::SetNextWindowSize(ImVec2(520.0f, 720.0f), ImGuiCond_FirstUseEver);
ge::chat_render(&g_app.panel_chat); app_agent::chat_render(&g_app.panel_chat);
// Extract panel (issue 0013) — flotante, dockeable. // Extract panel (issue 0013) — flotante, dockeable.
ImGui::SetNextWindowPos (ImVec2(vp->WorkPos.x + W * 0.30f, top + 50.0f), ImGui::SetNextWindowPos (ImVec2(vp->WorkPos.x + W * 0.30f, top + 50.0f),
@@ -2501,7 +2501,7 @@ int main(int argc, char** argv) {
// Chat panel (claude -p) — el agente invoca gx-cli para mutar // Chat panel (claude -p) — el agente invoca gx-cli para mutar
// operations.db. agent_mutations counter en graph_explorer.db dispara // operations.db. agent_mutations counter en graph_explorer.db dispara
// reload del viewport en cada cambio. // reload del viewport en cada cambio.
if (!ge::chat_init(g_input.uri ? g_input.uri : "", if (!app_agent::chat_init(g_input.uri ? g_input.uri : "",
app_db, app_dir.c_str())) { app_db, app_dir.c_str())) {
std::fprintf(stderr, std::fprintf(stderr,
"[graph_explorer] chat_init: claude no detectado " "[graph_explorer] chat_init: claude no detectado "
@@ -2586,7 +2586,7 @@ int main(int argc, char** argv) {
sizeof(g_panels) / sizeof(g_panels[0])); sizeof(g_panels) / sizeof(g_panels[0]));
// Cleanup // Cleanup
ge::chat_shutdown(); app_agent::chat_shutdown();
ge::extract_panel_shutdown(); ge::extract_panel_shutdown();
ge::jobs_shutdown(); ge::jobs_shutdown();
if (g_layout_storage) { if (g_layout_storage) {