AiFullTab/Src/Tab/BaseTab.mqh

1129 lines
43 KiB
MQL5
Raw Permalink Normal View History

2026-04-17 12:28:17 -05:00
//+------------------------------------------------------------------+
//| BaseTab.mqh |
//| Copyright 2025, Niquel Mendoza. |
//| https://www.mql5.com/es/users/nique_372 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, Niquel Mendoza."
#property link "https://www.mql5.com/es/users/nique_372"
#property strict
2026-04-17 15:45:52 -05:00
#ifndef AIFULLTAB_SRC_TAB_BASETAB_MQH
#define AIFULLTAB_SRC_TAB_BASETAB_MQH
2026-04-17 12:28:17 -05:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
2026-04-25 21:50:36 -05:00
//---
#include "..\\Tlg\\TlgmSend.mqh"
//---
2026-04-17 12:28:17 -05:00
#define private public
#define protected public
// EAF (GUI Lib) y base tab
2026-04-25 21:50:36 -05:00
#include <TSN\\EAFModExt\\BaseTab.mqh>
2026-04-17 12:28:17 -05:00
#undef private
#undef protected
//---
2026-04-25 21:50:36 -05:00
#include <TSN\\EAFModExt\\Keys.mqh>
2026-04-17 12:28:17 -05:00
//---
2026-07-12 22:38:00 -05:00
#include <TSN\\LLM\\Main.mqh>
2026-04-25 21:50:36 -05:00
2026-04-17 12:28:17 -05:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
#ifndef TABLLMAGENT_COLORS
#define TABLLMAGENT_COLOR_FONDO C'26,29,39'
#define TABLLMAGENT_COLOR_TEXT_PRIMARY C'220,220,220'
#define TABLLMAGENT_COLOR_TEXT_SECONDARY C'160,165,185'
#define TABLLMAGENT_COLOR_ACCENT C'105,168,243'
#define TABLLMAGENT_COLOR_BORDER C'58,63,82'
#define TABLLMAGENT_COLOR_BORDER_HOVER C'61,142,240'
#define TABLLMAGENT_COLOR_EDIT_BACK C'40,44,58'
#define TABLLMAGENT_COLOR_EDIT_BORDER C'58,63,82'
#define TABLLMAGENT_COLOR_EDIT_TEXT_NORMAL C'180,185,200'
#define TABLLMAGENT_COLOR_EDIT_TEXT_SELECTED C'61,142,240'
#define TABLLMAGENT_COLOR_EDIT_TEXT_HIGHLIGHT C'255,255,255'
#define TABLLMAGENT_COLOR_BTN_BACK C'45,50,65'
#define TABLLMAGENT_COLOR_BTN_BORDER C'58,63,82'
#define TABLLMAGENT_COLOR_LABEL_TITLE_BACK C'38,42,55'
2026-04-17 15:45:52 -05:00
#define TABLLMAGENT_COLOR_FONDO_SUBTAB C'37,40,54'
#define TABLLMAGENT_COLOR_FONDO_SUBTAB_HOVER C'61,142,240'
#define TABLLMAGENT_COLOR_FONDO_SUBTAB_PRESSED C'46,50,66'
#define TABLLMAGENT_COLOR_FONDO_SUBTAB_LOCKED C'37,40,54'
2026-04-17 12:28:17 -05:00
#endif // TABLLMAGENT_COLORS
#ifndef TABLLMAGENT_FOLDER_AI
#define TABLLMAGENT_FOLDER_AI "AiAgent\\"
#endif
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
#define TABLLMAGENT_GAP_Y_FIRST (12)
#define TABLLMAGENT_GAP_Y_SEC (10)
#define TABLLMAGENT_GAP_Y_SECTION (25)
#define TABLLMAGENT_LABEL_X_PAD (5)
#define TABLLMAGENT_FONT ("Arial")
#define TABLLMAGENT_FONT_SIZE (10)
#define TABLLMAGENT_FONT_SIZE_TTL (14)
//---
string g_tab_llm_agent_base[];
//---
/*
m_btn_vis_apikey="Show and Hide value"
m_btn_vis_chat_id="Show and Hide value"
m_btn_vis_bot_token="Show and Hide value"
*/
2026-04-17 15:45:52 -05:00
//---
#define TABLLMAGENT_SUBTABS_TOTAL (2)
#define TABLLMAGENT_SUBTAB_TLGMAPI (0)
#define TABLLMAGENT_SUBTAB_MCP (1)
2026-04-17 12:28:17 -05:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class CTabLlmAgentBase : public CGuiBaseComponent<CLoggerBase>
{
private:
2026-04-17 15:45:52 -05:00
//---
CTabs m_tabs;
2026-06-03 19:11:11 -05:00
TSN::CJsonParser m_json_parser;
2026-04-17 15:45:52 -05:00
//--- Tab MCP
CTextLabel m_label_tit_mcp;
CTextEdit m_edit_mcp_soket_adress;
CTextEdit m_edit_mcp_soket_port;
CTextEdit m_edit_mcp_ea_pool_ms;
CTextEdit m_edit_mcp_soket_timeout_read_no_tls; // Timeout de lecutra para conexionses no TLS en MS
// Al hacer clcik se lanza el ea (con los paramtros) en caso exsita
// se quita y se vuleve a lanzar
CButton m_btn_mcp_ea_lanzar;
//--- Tab conexion por tlg + api
// Parte de telegram
2026-04-17 12:28:17 -05:00
CTextLabel m_label_config_tlg;
CTextEdit m_edit_bot_token;
CButton m_btn_vis_bot_token;
CTextEdit m_edit_chat_id;
CButton m_btn_vis_chat_id;
CButton m_bottom_basicconfig_save;
CButton m_bottom_basicconfig_load;
2026-04-17 15:45:52 -05:00
// Parte de modelos (final)
2026-04-17 12:28:17 -05:00
CTextLabel m_label_config_model;
CComboBox m_combox_models;
CTextEdit m_edit_apikey;
CButton m_btn_vis_apikey;
CTextEdit m_edit_max_tokens;
CButton m_bottom_state_conecting; // Conectar \ Desconectar
CButton m_bottom_chat_save;
CButton m_bottom_chat_load;
2026-04-17 15:45:52 -05:00
//--- Guardado
2026-04-17 12:28:17 -05:00
string m_base_folder;
int m_extra_file_flags;
2026-04-17 15:45:52 -05:00
//--- Bot telegram + Api
2026-04-17 12:28:17 -05:00
bool m_in_conexion;
CChatTelegramAgentLLmBase* m_tlg_bot;
2026-04-17 17:53:12 -05:00
2026-07-17 17:03:27 -05:00
//-- Sql
int m_sql_handle;
2026-04-17 15:45:52 -05:00
//--- Mcp
long m_last_chart_id_mcp_server;
2026-07-08 11:09:07 -05:00
MqlParam m_mcp_ea_params[7];
2026-04-17 15:45:52 -05:00
//---
void OnClickBtnLLmApi(const long lparam);
2026-04-17 12:28:17 -05:00
//--- apply style para campos
void ApplyEditStyle(CTextEdit& ediT);
void ApplyLabelTitleStyle(CTextLabel& label);
void ApplyButtonStyle(CButton& btn);
//--- Carga de config basica
2026-04-17 15:45:52 -05:00
bool SaveBasicConfigTlgm(const string& file_name);
2026-07-12 22:38:00 -05:00
bool LoadBasicConfigTlgm(string file_name);
2026-04-17 12:28:17 -05:00
2026-04-17 15:45:52 -05:00
//--- Creacion de tab para MCP
bool CreateTlgmTab(CWndCreate* p, CWindow& main_window, int top_gap, int left_gap, int right_gap, int bottom_gap);
bool CreateMcpTab(CWndCreate* p, CWindow& main_window, int top_gap, int left_gap, int right_gap, int bottom_gap);
2026-04-17 12:28:17 -05:00
public:
CTabLlmAgentBase(void);
2026-04-17 22:11:31 -05:00
~CTabLlmAgentBase(void);
2026-04-17 12:28:17 -05:00
//---
2026-07-08 11:09:07 -05:00
void Initialize(const string& base_folder, int extra_file_flags, CChatTelegramAgentLLmBase* tlg_bot,
2026-07-17 17:03:27 -05:00
const string& exp_path_mcp_ea, const string& tbpid, const string& folder_sql, bool sql_c);
2026-04-17 12:28:17 -05:00
//---
2026-04-17 15:45:52 -05:00
CChatTelegramAgentLLmBase* ChatTlgm() { return m_tlg_bot; }
2026-04-17 12:28:17 -05:00
//---
void OnLenguajeChange() override final;
//---
bool Create(CWndCreate* p, CWindow& main_window, int top_gap, int left_gap, int right_gap, int bottom_gap);
//---
bool OnClickBottom(const long lparam);
bool OnTextEdit(const long lparam);
bool OnChangeComBox(const long lparam);
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
CTabLlmAgentBase::CTabLlmAgentBase(void)
2026-04-17 15:45:52 -05:00
: CGuiBaseComponent<CLoggerBase>("CTabLlmAgentBase"), m_base_folder(""), m_extra_file_flags(0), m_in_conexion(false), m_tlg_bot(NULL),
2026-07-17 17:03:27 -05:00
m_last_chart_id_mcp_server(-1), m_sql_handle(INVALID_HANDLE)
2026-04-17 12:28:17 -05:00
{
2026-04-17 15:45:52 -05:00
m_mcp_ea_params[0].type = TYPE_STRING; // Expert path
2026-07-08 11:09:07 -05:00
//---
m_mcp_ea_params[1].type = TYPE_STRING; // TbpId
m_mcp_ea_params[2].type = TYPE_STRING; // Addres
m_mcp_ea_params[3].type = TYPE_UINT; // Port
m_mcp_ea_params[4].type = TYPE_INT; // Ms pool
m_mcp_ea_params[5].type = TYPE_INT; // Timeout ms de lecutra
m_mcp_ea_params[6].type = TYPE_LONG; // Chart id panel
m_mcp_ea_params[6].integer_value = ::ChartID();
2026-04-17 12:28:17 -05:00
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
2026-04-17 22:11:31 -05:00
CTabLlmAgentBase::~CTabLlmAgentBase(void)
{
if(::CheckPointer(m_tlg_bot) == POINTER_DYNAMIC)
delete m_tlg_bot;
2026-04-17 22:43:56 -05:00
if(m_last_chart_id_mcp_server != -1)
2026-04-17 22:11:31 -05:00
{
::ChartClose(m_last_chart_id_mcp_server);
}
2026-07-17 17:03:27 -05:00
if(m_sql_handle != INVALID_HANDLE)
{
DatabaseClose(m_sql_handle);
}
2026-04-17 22:11:31 -05:00
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
2026-07-08 11:09:07 -05:00
void CTabLlmAgentBase::Initialize(const string &base_folder, int extra_file_flags,
2026-07-17 17:03:27 -05:00
CChatTelegramAgentLLmBase* tlg_bot, const string& exp_path_mcp_ea,
const string& tbpid, const string& folder_sql, bool sql_c)
2026-04-17 12:28:17 -05:00
{
2026-07-17 17:03:27 -05:00
//---
const string fn = folder_sql + LLMREG_FILENAME_SQL;
::ResetLastError();
2026-07-17 17:20:14 -05:00
m_sql_handle = DatabaseOpen(fn, DATABASE_OPEN_READONLY | (sql_c ? DATABASE_OPEN_COMMON : 0));
2026-07-17 17:03:27 -05:00
if(m_sql_handle == INVALID_HANDLE)
{
LogError(StringFormat("Fallo al abari la db = %s, ultinmo errr =%d", fn, ::GetLastError()), FUNCION_ACTUAL);
Remover();
return;
}
//----
2026-04-17 12:28:17 -05:00
m_extra_file_flags = extra_file_flags;
m_base_folder = base_folder + TABLLMAGENT_FOLDER_AI;
m_tlg_bot = tlg_bot;
2026-04-17 15:45:52 -05:00
m_mcp_ea_params[0].string_value = exp_path_mcp_ea;
2026-07-08 11:09:07 -05:00
m_mcp_ea_params[1].string_value = tbpid;
2026-04-17 12:28:17 -05:00
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CTabLlmAgentBase::ApplyEditStyle(CTextEdit &edit)
{
edit.FontSize(TABLLMAGENT_FONT_SIZE);
edit.Font(TABLLMAGENT_FONT);
edit.CanvasFontSet();
edit.LabelColor(TABLLMAGENT_COLOR_TEXT_SECONDARY);
2026-04-17 21:58:00 -05:00
edit.BackColor(TABLLMAGENT_COLOR_FONDO_SUBTAB_PRESSED);
2026-04-17 12:28:17 -05:00
edit.GetTextBoxPointer().BackColor(TABLLMAGENT_COLOR_EDIT_BACK);
edit.GetTextBoxPointer().BorderColor(TABLLMAGENT_COLOR_EDIT_BORDER);
edit.GetTextBoxPointer().DefaultTextColor(TABLLMAGENT_COLOR_EDIT_TEXT_NORMAL);
edit.GetTextBoxPointer().LabelColor(TABLLMAGENT_COLOR_EDIT_TEXT_NORMAL);
edit.GetTextBoxPointer().SelectedBackColor(TABLLMAGENT_COLOR_EDIT_TEXT_SELECTED);
edit.GetTextBoxPointer().SelectedTextColor(TABLLMAGENT_COLOR_EDIT_TEXT_HIGHLIGHT);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CTabLlmAgentBase::ApplyLabelTitleStyle(CTextLabel &label)
{
label.FontSize(TABLLMAGENT_FONT_SIZE_TTL);
label.Font(TABLLMAGENT_FONT);
label.LabelColor(TABLLMAGENT_COLOR_TEXT_PRIMARY);
2026-04-17 21:58:00 -05:00
label.BackColor(TABLLMAGENT_COLOR_FONDO_SUBTAB_PRESSED);
2026-04-17 12:28:17 -05:00
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CTabLlmAgentBase::ApplyButtonStyle(CButton &btn)
{
btn.FontSize(TABLLMAGENT_FONT_SIZE);
btn.LabelColor(TABLLMAGENT_COLOR_TEXT_SECONDARY);
btn.BackColor(TABLLMAGENT_COLOR_BTN_BACK);
btn.BorderColor(TABLLMAGENT_COLOR_BTN_BORDER);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CTabLlmAgentBase::Create(CWndCreate *p, CWindow &main_window, int top_gap, int left_gap, int right_gap, int bottom_gap)
{
2026-04-17 15:45:52 -05:00
//--- Tab
string txt[TABLLMAGENT_SUBTABS_TOTAL] =
{
m_language[GUIBASE_COMPONENT_NAME(m_tabs) + "_0"],
m_language[GUIBASE_COMPONENT_NAME(m_tabs) + "_1"]
};
2026-04-17 21:58:00 -05:00
int width[TABLLMAGENT_SUBTABS_TOTAL] = {125, 70};
2026-04-17 15:45:52 -05:00
color clrs[TABLLMAGENT_SUBTABS_TOTAL] = {TABLLMAGENT_COLOR_TEXT_SECONDARY, TABLLMAGENT_COLOR_TEXT_SECONDARY};
color clrs_pressed[TABLLMAGENT_SUBTABS_TOTAL] = {TABLLMAGENT_COLOR_ACCENT, TABLLMAGENT_COLOR_ACCENT};
top_gap += 24;
left_gap += 4;
right_gap += 4;
bottom_gap += 4;
//---
m_tabs.BackColor(TABLLMAGENT_COLOR_FONDO_SUBTAB);
m_tabs.BackColorHover(TABLLMAGENT_COLOR_FONDO_SUBTAB_HOVER);
m_tabs.BackColorPressed(TABLLMAGENT_COLOR_FONDO_SUBTAB_PRESSED);
m_tabs.BackColorLocked(TABLLMAGENT_COLOR_FONDO_SUBTAB_LOCKED);
m_tabs.BorderColor(TABLLMAGENT_COLOR_BORDER);
m_tabs.BorderColorHover(TABLLMAGENT_COLOR_BORDER_HOVER);
m_tabs.BorderColorPressed(TABLLMAGENT_COLOR_BORDER_HOVER);
m_tabs.BorderColorLocked(TABLLMAGENT_COLOR_BORDER);
//---
if(!p.CreateTabs(m_tabs, main_window, 0, m_base_tab, m_base_tab_idx,
left_gap, top_gap, 0, 0,
txt, width, clrs, clrs_pressed,
TABS_TOP, true, true, right_gap, bottom_gap))
{
GUIBASE_ERROR_CREATION(m_tabs);
return false;
}
//---
if(!CreateTlgmTab(p, main_window, top_gap, left_gap, right_gap, bottom_gap))
return false;
//---
if(!CreateMcpTab(p, main_window, top_gap, left_gap, right_gap, bottom_gap))
return false;
//---
const string init_file_name = m_base_folder + "init_ai_tab.json";
if(SaveBasicConfigTlgm(init_file_name))
m_tlg_bot.GeneralConfig(init_file_name, m_extra_file_flags);
else
LogError("Fallo al guardar la configuracion inicial dela tab ia", FUNCION_ACTUAL);
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CTabLlmAgentBase::CreateTlgmTab(CWndCreate *p, CWindow &main_window, int top_gap, int left_gap, int right_gap, int bottom_gap)
{
2026-04-17 12:28:17 -05:00
//---
const int initial_x = left_gap + 5;
int x = initial_x;
int y = top_gap + 10;
string texto;
2026-04-17 15:45:52 -05:00
int width;
2026-04-17 12:28:17 -05:00
//--- Label telegram
ApplyLabelTitleStyle(m_label_config_tlg);
if(!p.CreateTextLabel(m_label_config_tlg, m_language[GUIBASE_COMPONENT_NAME(m_label_config_tlg)],
2026-04-17 15:45:52 -05:00
main_window, 0, m_tabs, TABLLMAGENT_SUBTAB_TLGMAPI, x, y, 230))
2026-04-17 12:28:17 -05:00
{
GUIBASE_ERROR_CREATION(m_label_config_tlg);
return false;
}
y += m_label_config_tlg.YSize() + TABLLMAGENT_GAP_Y_FIRST;
//--- Bot token
texto = m_language[GUIBASE_COMPONENT_NAME(m_edit_bot_token)];
ApplyEditStyle(m_edit_bot_token);
width = m_edit_bot_token.m_canvas.TextWidth(texto);
m_edit_bot_token.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_edit_bot_token)));
if(!p.CreateTextEdit(m_edit_bot_token, texto,
2026-04-17 15:45:52 -05:00
main_window, 0, m_tabs, TABLLMAGENT_SUBTAB_TLGMAPI, false, x, y,
2026-04-17 12:28:17 -05:00
width + TABLLMAGENT_LABEL_X_PAD + 425, 425, ""))
{
GUIBASE_ERROR_CREATION(m_edit_bot_token);
return false;
}
m_edit_bot_token.GetTextBoxPointer().Font(EAFMOD_KEY_FONT);
//--- Btn show/hide bot token
const int edit_y_size_token = m_edit_bot_token.YSize();
ApplyButtonStyle(m_btn_vis_bot_token);
m_btn_vis_bot_token.AddImagesGroup(1, 1, g_llmagetn_tab_images_vis_path);
m_btn_vis_bot_token.ChangeImage(0, EAFMOD_FORKEYS_IMAGES_VIS_CLOSED);
m_btn_vis_bot_token.XSize(edit_y_size_token);
m_btn_vis_bot_token.YSize(edit_y_size_token);
m_btn_vis_bot_token.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_btn_vis_bot_token)));
2026-04-17 15:45:52 -05:00
if(!p.CreateButton(m_btn_vis_bot_token, "", main_window, 0, m_tabs, TABLLMAGENT_SUBTAB_TLGMAPI,
2026-04-17 12:28:17 -05:00
x + m_edit_bot_token.XSize() + 5, y, edit_y_size_token))
{
GUIBASE_ERROR_CREATION(m_btn_vis_bot_token);
return false;
}
y += m_edit_bot_token.YSize() + TABLLMAGENT_GAP_Y_SEC;
//--- Chat ID
texto = m_language[GUIBASE_COMPONENT_NAME(m_edit_chat_id)];
ApplyEditStyle(m_edit_chat_id);
width = m_edit_chat_id.m_canvas.TextWidth(texto);
m_edit_chat_id.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_edit_chat_id)));
if(!p.CreateTextEdit(m_edit_chat_id, texto,
2026-04-17 15:45:52 -05:00
main_window, 0, m_tabs, TABLLMAGENT_SUBTAB_TLGMAPI, false, x, y,
2026-04-17 12:28:17 -05:00
width + TABLLMAGENT_LABEL_X_PAD + 300, 300, ""))
{
GUIBASE_ERROR_CREATION(m_edit_chat_id);
return false;
}
m_edit_chat_id.GetTextBoxPointer().Font(EAFMOD_KEY_FONT);
//--- Btn show/hide chat id
const int edit_y_size_chat = m_edit_chat_id.YSize();
ApplyButtonStyle(m_btn_vis_chat_id);
m_btn_vis_chat_id.AddImagesGroup(1, 1, g_llmagetn_tab_images_vis_path);
m_btn_vis_chat_id.ChangeImage(0, EAFMOD_FORKEYS_IMAGES_VIS_CLOSED);
m_btn_vis_chat_id.XSize(edit_y_size_chat);
m_btn_vis_chat_id.YSize(edit_y_size_chat);
m_btn_vis_chat_id.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_btn_vis_chat_id)));
2026-04-17 15:45:52 -05:00
if(!p.CreateButton(m_btn_vis_chat_id, "", main_window, 0, m_tabs, TABLLMAGENT_SUBTAB_TLGMAPI,
2026-04-17 12:28:17 -05:00
x + m_edit_chat_id.XSize() + 5, y, edit_y_size_chat))
{
GUIBASE_ERROR_CREATION(m_btn_vis_chat_id);
return false;
}
y += m_edit_chat_id.YSize() + TABLLMAGENT_GAP_Y_SEC;
//--- nueva seccion
2026-04-17 15:45:52 -05:00
y += TABLLMAGENT_GAP_Y_SECTION;
x = initial_x;
2026-04-17 12:28:17 -05:00
//--- Label modelo
ApplyLabelTitleStyle(m_label_config_model);
if(!p.CreateTextLabel(m_label_config_model, m_language[GUIBASE_COMPONENT_NAME(m_label_config_model)],
2026-04-17 15:45:52 -05:00
main_window, 0, m_tabs, TABLLMAGENT_SUBTAB_TLGMAPI, x, y, 225))
2026-04-17 12:28:17 -05:00
{
GUIBASE_ERROR_CREATION(m_label_config_model);
return false;
}
y += m_label_config_model.YSize() + TABLLMAGENT_GAP_Y_FIRST;
2026-04-17 15:45:52 -05:00
//--- Combox modelos
2026-04-17 12:28:17 -05:00
texto = m_language[GUIBASE_COMPONENT_NAME(m_combox_models)];
m_combox_models.FontSize(TABLLMAGENT_FONT_SIZE);
m_combox_models.Font(TABLLMAGENT_FONT);
m_combox_models.CanvasFontSet();
m_combox_models.LabelColor(TABLLMAGENT_COLOR_TEXT_SECONDARY);
m_combox_models.BackColor(TABLLMAGENT_COLOR_FONDO);
m_combox_models.GetListViewPointer().BackColor(TABLLMAGENT_COLOR_EDIT_BACK);
m_combox_models.GetListViewPointer().BorderColor(TABLLMAGENT_COLOR_EDIT_BORDER);
m_combox_models.GetListViewPointer().LabelColor(TABLLMAGENT_COLOR_TEXT_SECONDARY);
m_combox_models.GetButtonPointer().LabelColor(TABLLMAGENT_COLOR_TEXT_SECONDARY);
m_combox_models.GetButtonPointer().BackColor(TABLLMAGENT_COLOR_EDIT_BACK);
m_combox_models.GetButtonPointer().BorderColor(TABLLMAGENT_COLOR_EDIT_BORDER);
width = m_combox_models.m_canvas.TextWidth(texto);
m_combox_models.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_combox_models)));
2026-07-12 22:38:00 -05:00
// Obtenemos los modelos
string models[];
2026-07-17 17:03:27 -05:00
int r = ArrayResize(models, 8, 8);
int s = 0;
::ResetLastError();
const int req = DatabasePrepare(m_sql_handle, StringFormat("SELECT * FROM llm_models WHERE (org_id = '%s' AND (flags & %u) > 0);",
"groq", LLMDEF_FLAG_TOOLS)); // buscamos los que permitan reasonsin y tooling
if(req == INVALID_HANDLE)
{
LogFatalError(StringFormat("Fallo al hacer req a la base de datos, ultimo err = %d", ::GetLastError()), FUNCION_ACTUAL);
Remover();
return false;
}
while(DatabaseRead(req))
{
DatabaseColumnText(req, LLMIDX_TLLMMODELS_ID, models[s++]);
if(s >= r)
{
r <<= 1;
ArrayResize(models, r, r);
}
}
DatabaseFinalize(req);
ArrayResize(models, s);
DatabaseClose(m_sql_handle);
m_sql_handle = INVALID_HANDLE;
2026-07-12 22:38:00 -05:00
// Creamos
2026-04-17 12:28:17 -05:00
if(!p.CreateCombobox(m_combox_models, texto,
2026-04-17 15:45:52 -05:00
main_window, 0, m_tabs, TABLLMAGENT_SUBTAB_TLGMAPI, false, x, y,
2026-07-12 22:38:00 -05:00
width + TABLLMAGENT_LABEL_X_PAD + 150, 150, models, 150))
2026-04-17 12:28:17 -05:00
{
GUIBASE_ERROR_CREATION(m_combox_models);
return false;
}
m_combox_models.m_button.IconFile(RESOURCE_DOWN_THIN_WHITE);
m_combox_models.m_button.IconFileLocked(RESOURCE_DOWN_THIN_WHITE);
m_combox_models.m_button.CElement::IconFilePressed(RESOURCE_UP_THIN_WHITE);
m_combox_models.m_button.CElement::IconFilePressedLocked(RESOURCE_UP_THIN_WHITE);
x += m_combox_models.XSize() + 20;
2026-04-17 15:45:52 -05:00
//--- Max tokens
2026-04-17 12:28:17 -05:00
texto = m_language[GUIBASE_COMPONENT_NAME(m_edit_max_tokens)];
ApplyEditStyle(m_edit_max_tokens);
width = m_edit_max_tokens.m_canvas.TextWidth(texto);
m_edit_max_tokens.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_edit_max_tokens)));
if(!p.CreateTextEdit(m_edit_max_tokens, texto,
2026-04-17 15:45:52 -05:00
main_window, 0, m_tabs, TABLLMAGENT_SUBTAB_TLGMAPI, false, x, y,
2026-04-17 12:28:17 -05:00
width + TABLLMAGENT_LABEL_X_PAD + 100, 100, "1024"))
{
GUIBASE_ERROR_CREATION(m_edit_max_tokens);
return false;
}
y += m_combox_models.YSize() + TABLLMAGENT_GAP_Y_SEC;
2026-04-17 15:45:52 -05:00
x = initial_x;
2026-04-17 12:28:17 -05:00
//--- API Key
texto = m_language[GUIBASE_COMPONENT_NAME(m_edit_apikey)];
2026-04-17 15:45:52 -05:00
ApplyEditStyle(m_edit_apikey);
2026-04-17 12:28:17 -05:00
width = m_edit_apikey.m_canvas.TextWidth(texto);
m_edit_apikey.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_edit_apikey)));
if(!p.CreateTextEdit(m_edit_apikey, texto,
2026-04-17 15:45:52 -05:00
main_window, 0, m_tabs, TABLLMAGENT_SUBTAB_TLGMAPI, false, x, y,
2026-04-17 12:28:17 -05:00
width + TABLLMAGENT_LABEL_X_PAD + 400, 400, ""))
{
GUIBASE_ERROR_CREATION(m_edit_apikey);
return false;
}
m_edit_apikey.GetTextBoxPointer().Font(EAFMOD_KEY_FONT);
2026-04-17 15:45:52 -05:00
//--- Btn show/hide api key
const int edit_y_size = m_edit_apikey.YSize();
2026-04-17 12:28:17 -05:00
ApplyButtonStyle(m_btn_vis_apikey);
m_btn_vis_apikey.AddImagesGroup(1, 1, g_llmagetn_tab_images_vis_path);
m_btn_vis_apikey.ChangeImage(0, EAFMOD_FORKEYS_IMAGES_VIS_CLOSED);
m_btn_vis_apikey.XSize(edit_y_size);
m_btn_vis_apikey.YSize(edit_y_size);
m_btn_vis_apikey.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_btn_vis_apikey)));
2026-04-17 15:45:52 -05:00
if(!p.CreateButton(m_btn_vis_apikey, "", main_window, 0, m_tabs, TABLLMAGENT_SUBTAB_TLGMAPI,
x + m_edit_apikey.XSize() + 5, y, edit_y_size))
2026-04-17 12:28:17 -05:00
{
GUIBASE_ERROR_CREATION(m_btn_vis_apikey);
return false;
}
y += m_edit_apikey.YSize() + TABLLMAGENT_GAP_Y_SEC;
2026-04-17 15:45:52 -05:00
//--- Fila botones: Conectar + Load Config + Save Config
2026-04-17 12:28:17 -05:00
ApplyButtonStyle(m_bottom_state_conecting);
m_bottom_state_conecting.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_bottom_state_conecting)));
if(!p.CreateButton(m_bottom_state_conecting, m_language[GUIBASE_COMPONENT_NAME(m_bottom_state_conecting)],
2026-04-17 15:45:52 -05:00
main_window, 0, m_tabs, TABLLMAGENT_SUBTAB_TLGMAPI, x, y, 125))
2026-04-17 12:28:17 -05:00
{
GUIBASE_ERROR_CREATION(m_bottom_state_conecting);
return false;
}
x += m_bottom_state_conecting.XSize() + 10;
ApplyButtonStyle(m_bottom_basicconfig_load);
m_bottom_basicconfig_load.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_bottom_basicconfig_load)));
if(!p.CreateButton(m_bottom_basicconfig_load, m_language[GUIBASE_COMPONENT_NAME(m_bottom_basicconfig_load)],
2026-04-17 15:45:52 -05:00
main_window, 0, m_tabs, TABLLMAGENT_SUBTAB_TLGMAPI, x, y, 125))
2026-04-17 12:28:17 -05:00
{
GUIBASE_ERROR_CREATION(m_bottom_basicconfig_load);
return false;
}
x += m_bottom_basicconfig_load.XSize() + 10;
ApplyButtonStyle(m_bottom_basicconfig_save);
m_bottom_basicconfig_save.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_bottom_basicconfig_save)));
if(!p.CreateButton(m_bottom_basicconfig_save, m_language[GUIBASE_COMPONENT_NAME(m_bottom_basicconfig_save)],
2026-04-17 15:45:52 -05:00
main_window, 0, m_tabs, TABLLMAGENT_SUBTAB_TLGMAPI, x, y, 125))
2026-04-17 12:28:17 -05:00
{
GUIBASE_ERROR_CREATION(m_bottom_basicconfig_save);
return false;
}
2026-04-17 15:45:52 -05:00
//--- Fila botones: Load Chat + Save Chat
x = initial_x;
2026-04-17 12:28:17 -05:00
y += m_bottom_basicconfig_save.YSize() + TABLLMAGENT_GAP_Y_SEC;
ApplyButtonStyle(m_bottom_chat_load);
m_bottom_chat_load.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_bottom_chat_load)));
if(!p.CreateButton(m_bottom_chat_load, m_language[GUIBASE_COMPONENT_NAME(m_bottom_chat_load)],
2026-04-17 15:45:52 -05:00
main_window, 0, m_tabs, TABLLMAGENT_SUBTAB_TLGMAPI, x, y, 125))
2026-04-17 12:28:17 -05:00
{
GUIBASE_ERROR_CREATION(m_bottom_chat_load);
return false;
}
x += m_bottom_chat_load.XSize() + 10;
ApplyButtonStyle(m_bottom_chat_save);
m_bottom_chat_save.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_bottom_chat_save)));
if(!p.CreateButton(m_bottom_chat_save, m_language[GUIBASE_COMPONENT_NAME(m_bottom_chat_save)],
2026-04-17 15:45:52 -05:00
main_window, 0, m_tabs, TABLLMAGENT_SUBTAB_TLGMAPI, x, y, 125))
2026-04-17 12:28:17 -05:00
{
GUIBASE_ERROR_CREATION(m_bottom_chat_save);
return false;
}
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
2026-04-17 15:45:52 -05:00
bool CTabLlmAgentBase::CreateMcpTab(CWndCreate *p, CWindow &main_window, int top_gap, int left_gap, int right_gap, int bottom_gap)
2026-04-17 12:28:17 -05:00
{
2026-04-17 15:45:52 -05:00
//---
const int initial_x = left_gap + 5;
int x = initial_x;
int y = top_gap + 10;
string texto;
int width;
2026-04-17 12:28:17 -05:00
2026-04-17 15:45:52 -05:00
//--- Label titulo MCP
ApplyLabelTitleStyle(m_label_tit_mcp);
if(!p.CreateTextLabel(m_label_tit_mcp, m_language[GUIBASE_COMPONENT_NAME(m_label_tit_mcp)],
main_window, 0, m_tabs, TABLLMAGENT_SUBTAB_MCP, x, y, 230))
{
GUIBASE_ERROR_CREATION(m_label_tit_mcp);
return false;
}
y += m_label_tit_mcp.YSize() + TABLLMAGENT_GAP_Y_FIRST;
//--- Socket address
texto = m_language[GUIBASE_COMPONENT_NAME(m_edit_mcp_soket_adress)];
ApplyEditStyle(m_edit_mcp_soket_adress);
width = m_edit_mcp_soket_adress.m_canvas.TextWidth(texto);
m_edit_mcp_soket_adress.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_edit_mcp_soket_adress)));
if(!p.CreateTextEdit(m_edit_mcp_soket_adress, texto,
main_window, 0, m_tabs, TABLLMAGENT_SUBTAB_MCP, false, x, y,
width + TABLLMAGENT_LABEL_X_PAD + 300, 300, "127.0.0.1"))
{
GUIBASE_ERROR_CREATION(m_edit_mcp_soket_adress);
return false;
}
y += m_edit_mcp_soket_adress.YSize() + TABLLMAGENT_GAP_Y_SEC;
//--- Socket port
texto = m_language[GUIBASE_COMPONENT_NAME(m_edit_mcp_soket_port)];
ApplyEditStyle(m_edit_mcp_soket_port);
width = m_edit_mcp_soket_port.m_canvas.TextWidth(texto);
m_edit_mcp_soket_port.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_edit_mcp_soket_port)));
if(!p.CreateTextEdit(m_edit_mcp_soket_port, texto,
main_window, 0, m_tabs, TABLLMAGENT_SUBTAB_MCP, false, x, y,
width + TABLLMAGENT_LABEL_X_PAD + 150, 150, "8080"))
{
GUIBASE_ERROR_CREATION(m_edit_mcp_soket_port);
return false;
}
y += m_edit_mcp_soket_port.YSize() + TABLLMAGENT_GAP_Y_SEC;
//--- Pool ms
texto = m_language[GUIBASE_COMPONENT_NAME(m_edit_mcp_ea_pool_ms)];
ApplyEditStyle(m_edit_mcp_ea_pool_ms);
width = m_edit_mcp_ea_pool_ms.m_canvas.TextWidth(texto);
m_edit_mcp_ea_pool_ms.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_edit_mcp_ea_pool_ms)));
if(!p.CreateTextEdit(m_edit_mcp_ea_pool_ms, texto,
main_window, 0, m_tabs, TABLLMAGENT_SUBTAB_MCP, false, x, y,
2026-05-03 13:23:13 -05:00
width + TABLLMAGENT_LABEL_X_PAD + 150, 150, "75"))
2026-04-17 15:45:52 -05:00
{
GUIBASE_ERROR_CREATION(m_edit_mcp_ea_pool_ms);
return false;
}
y += m_edit_mcp_ea_pool_ms.YSize() + TABLLMAGENT_GAP_Y_SEC;
//--- Timeout lectura no TLS
texto = m_language[GUIBASE_COMPONENT_NAME(m_edit_mcp_soket_timeout_read_no_tls)];
ApplyEditStyle(m_edit_mcp_soket_timeout_read_no_tls);
width = m_edit_mcp_soket_timeout_read_no_tls.m_canvas.TextWidth(texto);
m_edit_mcp_soket_timeout_read_no_tls.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_edit_mcp_soket_timeout_read_no_tls)));
if(!p.CreateTextEdit(m_edit_mcp_soket_timeout_read_no_tls, texto,
main_window, 0, m_tabs, TABLLMAGENT_SUBTAB_MCP, false, x, y,
width + TABLLMAGENT_LABEL_X_PAD + 150, 150, "5000"))
{
GUIBASE_ERROR_CREATION(m_edit_mcp_soket_timeout_read_no_tls);
return false;
}
y += m_edit_mcp_soket_timeout_read_no_tls.YSize() + TABLLMAGENT_GAP_Y_SEC;
2026-04-17 12:28:17 -05:00
2026-04-17 15:45:52 -05:00
//--- Btn lanzar EA
ApplyButtonStyle(m_btn_mcp_ea_lanzar);
m_btn_mcp_ea_lanzar.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_btn_mcp_ea_lanzar)));
if(!p.CreateButton(m_btn_mcp_ea_lanzar, m_language[GUIBASE_COMPONENT_NAME(m_btn_mcp_ea_lanzar)],
main_window, 0, m_tabs, TABLLMAGENT_SUBTAB_MCP, x, y, 125))
{
GUIBASE_ERROR_CREATION(m_btn_mcp_ea_lanzar);
return false;
}
//---
return true;
}
2026-04-17 12:28:17 -05:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CTabLlmAgentBase::OnLenguajeChange(void)
{
2026-04-17 15:45:52 -05:00
//--- Tab text
string txt[TABLLMAGENT_SUBTABS_TOTAL] =
{
m_language[GUIBASE_COMPONENT_NAME(m_tabs) + "_0"],
m_language[GUIBASE_COMPONENT_NAME(m_tabs) + "_1"]
};
const int t = m_tabs.TabsTotal();
for(int i = 0; i < t; i++)
m_tabs.Text(i, txt[i]);
m_tabs.Update();
//--- Labels tlgm
2026-04-17 18:10:36 -05:00
UpdateTBasic(m_label_config_tlg, GUIBASE_COMPONENT_NAME(m_label_config_tlg), false);
2026-04-17 12:28:17 -05:00
UpdateTBasic(m_label_config_model, GUIBASE_COMPONENT_NAME(m_label_config_model), false);
2026-04-17 15:45:52 -05:00
//--- Edits tlgm
2026-04-17 18:10:36 -05:00
ResizeTElement(m_edit_bot_token, GUIBASE_COMPONENT_NAME(m_edit_bot_token), 425, TABLLMAGENT_LABEL_X_PAD);
ResizeTElement(m_edit_chat_id, GUIBASE_COMPONENT_NAME(m_edit_chat_id), 300, TABLLMAGENT_LABEL_X_PAD);
ResizeTElement(m_edit_apikey, GUIBASE_COMPONENT_NAME(m_edit_apikey), 400, TABLLMAGENT_LABEL_X_PAD);
ResizeTElement(m_edit_max_tokens, GUIBASE_COMPONENT_NAME(m_edit_max_tokens), 100, TABLLMAGENT_LABEL_X_PAD);
2026-04-17 12:28:17 -05:00
//--- Combox
2026-04-17 15:45:52 -05:00
ResizeTElement(m_combox_models, GUIBASE_COMPONENT_NAME(m_combox_models), 150, TABLLMAGENT_LABEL_X_PAD);
2026-04-17 12:28:17 -05:00
2026-04-17 15:45:52 -05:00
//--- Botones tlgm
2026-04-17 12:28:17 -05:00
UpdateTBasic(m_bottom_basicconfig_load, GUIBASE_COMPONENT_NAME(m_bottom_basicconfig_load));
UpdateTBasic(m_bottom_basicconfig_save, GUIBASE_COMPONENT_NAME(m_bottom_basicconfig_save));
2026-04-17 18:10:36 -05:00
UpdateTBasic(m_bottom_chat_load, GUIBASE_COMPONENT_NAME(m_bottom_chat_load));
UpdateTBasic(m_bottom_chat_save, GUIBASE_COMPONENT_NAME(m_bottom_chat_save));
2026-04-17 12:28:17 -05:00
2026-04-17 15:45:52 -05:00
//--- Conectar (key dinamica segun estado)
2026-04-17 12:28:17 -05:00
UpdateTBasic(m_bottom_state_conecting,
GUIBASE_COMPONENT_NAME(m_bottom_state_conecting) + (m_in_conexion ? "_d" : ""));
2026-04-17 15:45:52 -05:00
//--- Show/hide solo tooltip
2026-04-17 12:28:17 -05:00
m_btn_vis_bot_token.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_btn_vis_bot_token)));
m_btn_vis_chat_id.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_btn_vis_chat_id)));
m_btn_vis_apikey.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_btn_vis_apikey)));
2026-04-17 15:45:52 -05:00
//--- Label MCP
UpdateTBasic(m_label_tit_mcp, GUIBASE_COMPONENT_NAME(m_label_tit_mcp), false);
2026-04-17 12:28:17 -05:00
2026-04-17 15:45:52 -05:00
//--- Edits MCP
ResizeTElement(m_edit_mcp_soket_adress, GUIBASE_COMPONENT_NAME(m_edit_mcp_soket_adress), 300, TABLLMAGENT_LABEL_X_PAD);
ResizeTElement(m_edit_mcp_soket_port, GUIBASE_COMPONENT_NAME(m_edit_mcp_soket_port), 150, TABLLMAGENT_LABEL_X_PAD);
ResizeTElement(m_edit_mcp_ea_pool_ms, GUIBASE_COMPONENT_NAME(m_edit_mcp_ea_pool_ms), 150, TABLLMAGENT_LABEL_X_PAD);
ResizeTElement(m_edit_mcp_soket_timeout_read_no_tls, GUIBASE_COMPONENT_NAME(m_edit_mcp_soket_timeout_read_no_tls), 150, TABLLMAGENT_LABEL_X_PAD);
//--- Boton MCP
UpdateTBasic(m_btn_mcp_ea_lanzar, GUIBASE_COMPONENT_NAME(m_btn_mcp_ea_lanzar));
}
2026-04-17 12:28:17 -05:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CTabLlmAgentBase::OnChangeComBox(const long lparam)
{
if(m_combox_models.Id() == lparam)
{
2026-07-12 22:38:00 -05:00
m_tlg_bot.LlmModelName(m_combox_models.GetListViewPointer().SelectedItemText());
2026-04-17 12:28:17 -05:00
//---
return true;
}
return false;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CTabLlmAgentBase::OnTextEdit(const long lparam)
{
2026-04-17 15:45:52 -05:00
if(m_tabs.SelectedTab() == TABLLMAGENT_SUBTAB_TLGMAPI)
2026-04-17 12:28:17 -05:00
{
2026-04-17 15:45:52 -05:00
//--- Telegram
if(lparam == m_edit_bot_token.Id())
{
m_tlg_bot.TlgToken(m_edit_bot_token.GetValue());
return true;
}
if(lparam == m_edit_chat_id.Id())
{
const long chat_id = long(m_edit_chat_id.GetValue());
m_tlg_bot.TlgChatId(chat_id);
return true;
}
2026-04-17 12:28:17 -05:00
2026-04-17 15:45:52 -05:00
//--- LLm
if(lparam == m_edit_apikey.Id())
{
const string apikey = m_edit_apikey.GetValue();
m_tlg_bot.LlmApiKey(apikey);
return true;
}
if(lparam == m_edit_max_tokens.Id())
{
m_tlg_bot.LLmMaxTokens(int(m_edit_max_tokens.GetValue()));
return true;
}
2026-04-17 12:28:17 -05:00
}
2026-04-17 15:45:52 -05:00
/*
// Nota no hace fata capturarlo
else
{
if(lparam == m_edit_mcp_soket_adress.Id())
{
return true;
}
if(lparam == m_edit_mcp_soket_port.Id())
{
return true;
}
if(lparam == m_edit_mcp_ea_pool_ms.Id())
{
return true;
}
}*/
2026-04-17 12:28:17 -05:00
//---
return false;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
2026-04-17 15:45:52 -05:00
void CTabLlmAgentBase::OnClickBtnLLmApi(const long lparam)
2026-04-17 12:28:17 -05:00
{
//--- Botonoes de visualizacion de pass
if(m_btn_vis_bot_token.Id() == lparam)
{
CTextBox* tb = m_edit_bot_token.GetTextBoxPointer();
const bool is_hidden = tb.Font() == EAFMOD_KEY_FONT;
tb.ChangeFont(is_hidden ? TABLLMAGENT_FONT : EAFMOD_KEY_FONT, TABLLMAGENT_FONT_SIZE);
m_btn_vis_bot_token.SetImage(0, 0, g_llmagetn_tab_images_vis_path[is_hidden ? EAFMOD_FORKEYS_IMAGES_VIS_OPEN : EAFMOD_FORKEYS_IMAGES_VIS_CLOSED]);
m_btn_vis_bot_token.Update(true);
2026-04-17 15:45:52 -05:00
return;
2026-04-17 12:28:17 -05:00
}
if(m_btn_vis_chat_id.Id() == lparam)
{
CTextBox* tb = m_edit_chat_id.GetTextBoxPointer();
const bool is_hidden = tb.Font() == EAFMOD_KEY_FONT;
tb.ChangeFont(is_hidden ? TABLLMAGENT_FONT : EAFMOD_KEY_FONT, TABLLMAGENT_FONT_SIZE);
m_btn_vis_chat_id.SetImage(0, 0, g_llmagetn_tab_images_vis_path[is_hidden ? EAFMOD_FORKEYS_IMAGES_VIS_OPEN : EAFMOD_FORKEYS_IMAGES_VIS_CLOSED]);
m_btn_vis_chat_id.Update(true);
2026-04-17 15:45:52 -05:00
return;
2026-04-17 12:28:17 -05:00
}
if(m_btn_vis_apikey.Id() == lparam)
{
CTextBox* tb = m_edit_apikey.GetTextBoxPointer();
const bool is_hidden = tb.Font() == EAFMOD_KEY_FONT;
tb.ChangeFont(is_hidden ? TABLLMAGENT_FONT : EAFMOD_KEY_FONT, TABLLMAGENT_FONT_SIZE);
m_btn_vis_apikey.SetImage(0, 0, g_llmagetn_tab_images_vis_path[is_hidden ? EAFMOD_FORKEYS_IMAGES_VIS_OPEN : EAFMOD_FORKEYS_IMAGES_VIS_CLOSED]);
m_btn_vis_apikey.Update(true);
2026-04-17 15:45:52 -05:00
return;
2026-04-17 12:28:17 -05:00
}
//---
if(m_bottom_state_conecting.Id() == lparam)
{
m_in_conexion = !m_in_conexion;
if(m_in_conexion)
{
m_bottom_state_conecting.LabelText(m_language[GUIBASE_COMPONENT_NAME(m_bottom_state_conecting) + "_d"]); // esta conectado el siguiente estado es desconectar
m_bottom_state_conecting.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_bottom_state_conecting) + "_d"));
m_bottom_state_conecting.Update(true);
m_tlg_bot.TlgConnectReconect(true);
}
else
{
m_bottom_state_conecting.LabelText(m_language[GUIBASE_COMPONENT_NAME(m_bottom_state_conecting)]); // el siguiente estado es coectart
m_bottom_state_conecting.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_bottom_state_conecting)));
m_bottom_state_conecting.Update(true);
m_tlg_bot.TlgConnectReconect(false);
}
2026-04-17 15:45:52 -05:00
return;
2026-04-17 12:28:17 -05:00
}
//---
if(m_bottom_basicconfig_load.Id() == lparam)
{
2026-04-17 18:10:36 -05:00
if(::FileSelectDialog(GUIBASE_MSG("selec_config_load"), m_base_folder, "JSON files (*.json)|*.json",
2026-04-17 12:28:17 -05:00
((m_extra_file_flags & FILE_COMMON) != 0 ? FSD_COMMON_FOLDER : 0) | FSD_FILE_MUST_EXIST,
g_tab_llm_agent_base, NULL) != 1)
{
2026-04-17 18:10:36 -05:00
MessageBox(GUIBASE_MSG("err_selec_file"), GUIBASE_COMMON("error"), MB_OK | MB_ICONERROR);
2026-04-17 15:45:52 -05:00
return;
2026-04-17 12:28:17 -05:00
}
//---
2026-04-17 15:45:52 -05:00
if(LoadBasicConfigTlgm(g_tab_llm_agent_base[0]))
2026-04-17 18:10:36 -05:00
MessageBox(GUIBASE_MSG("suces_load_config"), GUIBASE_COMMON("info"), MB_OK | MB_ICONINFORMATION);
2026-04-17 12:28:17 -05:00
else
2026-04-17 18:10:36 -05:00
MessageBox(GUIBASE_MSG("err_load_config"), GUIBASE_COMMON("error"), MB_OK | MB_ICONERROR);
2026-04-17 12:28:17 -05:00
//---
2026-04-17 15:45:52 -05:00
return;
2026-04-17 12:28:17 -05:00
}
//---
if(m_bottom_basicconfig_save.Id() == lparam)
{
2026-04-17 18:10:36 -05:00
if(::FileSelectDialog(GUIBASE_MSG("selec_config_save"), m_base_folder, "JSON files (*.json)|*.json",
2026-04-17 12:28:17 -05:00
((m_extra_file_flags & FILE_COMMON) != 0 ? FSD_COMMON_FOLDER : 0),
g_tab_llm_agent_base, NULL) != 1)
{
2026-04-17 18:10:36 -05:00
MessageBox(GUIBASE_MSG("err_selec_file"), GUIBASE_COMMON("error"), MB_OK | MB_ICONERROR);
2026-04-17 15:45:52 -05:00
return;
2026-04-17 12:28:17 -05:00
}
//---
2026-04-17 15:45:52 -05:00
if(SaveBasicConfigTlgm(g_tab_llm_agent_base[0]))
2026-04-17 18:10:36 -05:00
MessageBox(GUIBASE_MSG("suces_save_config"), GUIBASE_COMMON("info"), MB_OK | MB_ICONINFORMATION);
2026-04-17 12:28:17 -05:00
else
2026-04-17 18:10:36 -05:00
MessageBox(GUIBASE_MSG("err_save_config"), GUIBASE_COMMON("error"), MB_OK | MB_ICONERROR);
2026-04-17 12:28:17 -05:00
//---
2026-04-17 15:45:52 -05:00
return;
2026-04-17 12:28:17 -05:00
}
//---
if(m_bottom_chat_load.Id() == lparam)
{
2026-04-17 18:10:36 -05:00
if(::FileSelectDialog(GUIBASE_MSG("selec_chat_load"), m_base_folder, "JSON files (*.json)|*.json",
2026-04-17 12:28:17 -05:00
((m_extra_file_flags & FILE_COMMON) != 0 ? FSD_COMMON_FOLDER : 0) | FSD_FILE_MUST_EXIST,
g_tab_llm_agent_base, NULL) != 1)
{
2026-04-17 18:10:36 -05:00
MessageBox(GUIBASE_MSG("err_selec_file"), GUIBASE_COMMON("error"), MB_OK | MB_ICONERROR);
2026-04-17 15:45:52 -05:00
return;
2026-04-17 12:28:17 -05:00
}
//---
if(m_tlg_bot.LLmMemoryLoad(g_tab_llm_agent_base[0], m_extra_file_flags))
2026-04-17 18:10:36 -05:00
MessageBox(GUIBASE_MSG("suces_load_chat"), GUIBASE_COMMON("info"), MB_OK | MB_ICONINFORMATION);
2026-04-17 12:28:17 -05:00
else
2026-04-17 18:10:36 -05:00
MessageBox(GUIBASE_MSG("err_load_chat"), GUIBASE_COMMON("error"), MB_OK | MB_ICONERROR);
2026-04-17 12:28:17 -05:00
//---
2026-04-17 15:45:52 -05:00
return;
2026-04-17 12:28:17 -05:00
}
//---
if(m_bottom_chat_save.Id() == lparam)
{
2026-04-17 18:10:36 -05:00
if(::FileSelectDialog(GUIBASE_MSG("selec_chat_save"), m_base_folder, "JSON files (*.json)|*.json",
2026-04-17 12:28:17 -05:00
((m_extra_file_flags & FILE_COMMON) != 0 ? FSD_COMMON_FOLDER : 0),
g_tab_llm_agent_base, NULL) != 1)
{
2026-04-17 18:10:36 -05:00
MessageBox(GUIBASE_MSG("err_selec_file"), GUIBASE_COMMON("error"), MB_OK | MB_ICONERROR);
2026-04-17 15:45:52 -05:00
return;
2026-04-17 12:28:17 -05:00
}
//---
if(m_tlg_bot.LLmMemorySave(g_tab_llm_agent_base[0], m_extra_file_flags))
2026-04-17 18:10:36 -05:00
MessageBox(GUIBASE_MSG("succes_save_chat"), GUIBASE_COMMON("info"), MB_OK | MB_ICONINFORMATION);
2026-04-17 12:28:17 -05:00
else
2026-04-17 18:10:36 -05:00
MessageBox(GUIBASE_MSG("err_save_chat"), GUIBASE_COMMON("error"), MB_OK | MB_ICONERROR);
2026-04-17 12:28:17 -05:00
//---
2026-04-17 15:45:52 -05:00
return;
2026-04-17 12:28:17 -05:00
}
2026-04-17 15:45:52 -05:00
}
2026-04-17 12:28:17 -05:00
2026-04-17 15:45:52 -05:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CTabLlmAgentBase::OnClickBottom(const long lparam)
{
//---
if(m_tabs.SelectedTab() == TABLLMAGENT_SUBTAB_TLGMAPI)
{
OnClickBtnLLmApi(lparam);
return true;
}
else
if(m_tabs.SelectedTab() == TABLLMAGENT_SUBTAB_MCP && lparam == m_btn_mcp_ea_lanzar.Id())
{
//--- En caos este correidno relanzamos
if(m_last_chart_id_mcp_server >= 0)
{
::ChartClose(m_last_chart_id_mcp_server);
m_last_chart_id_mcp_server = -1;
}
//--- Abrimos grafico
m_last_chart_id_mcp_server = OpenChartAndDevoler(ChartID(), _Symbol, _Period, 250);
if(m_last_chart_id_mcp_server == -1)
{
// Fallo al lanzarlo no se pudo abrir el grafico
MessageBox(GUIBASE_MSG("err_mcp_not_open_c"), GUIBASE_COMMON("error"), MB_OK);
return true;
}
// Se abrio el grafico
//---
const string addres = m_edit_mcp_soket_adress.GetValue();
if(addres.Length() < 1)
{
MessageBox(GUIBASE_MSG("err_mcp_empy_address"), GUIBASE_COMMON("error"), MB_OK);
return true;
}
//---
2026-04-17 18:10:36 -05:00
const int port = int(m_edit_mcp_soket_port.GetValue());
if(port > 65535 || port <= 0)
2026-04-17 15:45:52 -05:00
{
MessageBox(GUIBASE_MSG("err_mcp_invalid_port"), GUIBASE_COMMON("error"), MB_OK);
return true;
}
//---
const int ms_pool = int(m_edit_mcp_ea_pool_ms.GetValue());
if(ms_pool < 10)
{
MessageBox(GUIBASE_MSG("err_pool_is_too_pequeño"), GUIBASE_COMMON("error"), MB_OK);
return true;
}
//---
//m_mcp_ea_params[0]=esta la ruta al experto
2026-07-08 11:09:07 -05:00
//m_mcp_ea_params[1]=tbp id
m_mcp_ea_params[2].string_value = addres;
m_mcp_ea_params[3].integer_value = port;
m_mcp_ea_params[4].integer_value = ms_pool;
m_mcp_ea_params[5].integer_value = int(m_edit_mcp_soket_timeout_read_no_tls.GetValue()); // no revisamos dado que depende...
//m_mcp_ea_params[6]=chart id
2026-04-17 15:45:52 -05:00
//---
if(!EXPERT::Run(m_last_chart_id_mcp_server, m_mcp_ea_params, EXPERT_PERMISOS_FLAG_DLL))
{
MessageBox(GUIBASE_MSG("err_cannot_run_ea"), GUIBASE_COMMON("error"), MB_OK);
}
return true;
}
2026-04-17 12:28:17 -05:00
//---
return false;
}
//+------------------------------------------------------------------+
2026-04-17 15:45:52 -05:00
//| Save \\ Load config para telegram + api tab |
2026-04-17 12:28:17 -05:00
//+------------------------------------------------------------------+
2026-04-17 15:45:52 -05:00
bool CTabLlmAgentBase::SaveBasicConfigTlgm(const string& file_name)
2026-04-17 12:28:17 -05:00
{
//---
2026-06-03 19:11:11 -05:00
TSN::g_json_builder.Clear();
TSN::g_json_builder.Obj();
TSN::g_json_builder.Key("bot_token").ValSNoRef(m_edit_bot_token.GetValue());
TSN::g_json_builder.Key("chat_id").ValSNoRef(m_edit_chat_id.GetValue());
TSN::g_json_builder.Key("api_key").ValSNoRef(m_edit_apikey.GetValue());
2026-07-12 22:38:00 -05:00
TSN::g_json_builder.Key("max_completion_tokens").Val(long(m_edit_max_tokens.GetValue()));
TSN::g_json_builder.Key("model_name").ValSNoRef(m_combox_models.GetListViewPointer().SelectedItemText());
2026-06-03 19:11:11 -05:00
TSN::g_json_builder.EndObj();
2026-04-17 12:28:17 -05:00
//---
::ResetLastError();
const int fh = ::FileOpen(file_name, FILE_WRITE | FILE_TXT | m_extra_file_flags, 0);
if(fh == INVALID_HANDLE)
{
LogError(StringFormat("Fallo al abrir archivo =%s, error=%d", file_name, ::GetLastError()), FUNCION_ACTUAL);
return false;
}
//---
2026-06-03 19:11:11 -05:00
::FileWriteString(fh, TSN::g_json_builder.Build());
2026-04-17 12:28:17 -05:00
::FileClose(fh);
return true;
}
//+------------------------------------------------------------------+
2026-07-12 22:38:00 -05:00
bool CTabLlmAgentBase::LoadBasicConfigTlgm(string file_name)
2026-04-17 12:28:17 -05:00
{
//---
2026-07-12 22:38:00 -05:00
const int ext = m_json_parser.AssingFile(file_name, (m_extra_file_flags & FILE_COMMON) != 0);
if(!m_json_parser.AutoParseByFileExt(ext))
2026-04-17 12:28:17 -05:00
{
LogError(StringFormat("Fallo al parsear json =%s, error=%s", file_name,
2026-06-03 19:11:11 -05:00
::EnumToString(m_json_parser.LastErr())), FUNCION_ACTUAL);
2026-04-17 12:28:17 -05:00
return false;
}
//---
2026-06-03 19:11:11 -05:00
TSN::CJsonNode root = m_json_parser.GetRoot();
2026-04-17 12:28:17 -05:00
//--- Acutlizamos la ui
m_edit_bot_token.SetValue(root["bot_token"].ToString());
m_edit_bot_token.GetTextBoxPointer().Update(true);
m_edit_chat_id.SetValue(root["chat_id"].ToString());
m_edit_chat_id.GetTextBoxPointer().Update(true);
m_edit_apikey.SetValue(root["api_key"].ToString());
m_edit_apikey.GetTextBoxPointer().Update(true);
2026-07-12 22:38:00 -05:00
m_edit_max_tokens.SetValue(root["max_completion_tokens"].ToString());
2026-04-17 12:28:17 -05:00
m_edit_max_tokens.GetTextBoxPointer().Update(true);
2026-07-17 17:03:27 -05:00
const string m = root["model_name"].ToString("");
CListView* list = m_combox_models.GetListViewPointer();
const int model_idx = list.Find(m);
if(model_idx != -1)
{
m_combox_models.GetListViewPointer().SelectItem(model_idx);
m_combox_models.Update(true);
}
else
{
LogError("No se pudo seleicoinar el modelo en combox dado que no existe", FUNCION_ACTUAL);
}
2026-04-17 12:28:17 -05:00
2026-07-12 22:38:00 -05:00
//---
const string out = FileRemoveExtension(file_name) + "." + TSN_JSON_EXT_JSONTC;
if(!m_json_parser.SaveCompiled(out, ((m_extra_file_flags & FILE_COMMON) != 0)))
{
LogError("Fallo al guardar version compilada", FUNCION_ACTUAL);
return false;
}
2026-04-17 12:28:17 -05:00
//--- Aplicar al bot de tlgm externo mediante call
2026-07-12 22:38:00 -05:00
m_tlg_bot.GeneralConfig(out, m_extra_file_flags);
2026-04-17 12:28:17 -05:00
//---
return true;
}
//+------------------------------------------------------------------+
2026-04-17 15:45:52 -05:00
#endif // AIFULLTAB_SRC_TAB_BASETAB_MQH