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:
+1
-1
@@ -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
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
@@ -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)
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user