From 7d459d5579b578c9a79504a49cba8ad53e31d533 Mon Sep 17 00:00:00 2001 From: Rodrigo Rodriguez Date: Thu, 29 Aug 2024 19:53:56 -0300 Subject: [PATCH] fix(all): TRUE multicloud. --- .../basic.gblib/services/DialogKeywords.ts | 2 +- packages/basic.gblib/services/GBVMService.ts | 129 +++++++++--------- packages/core.gbapp/services/GBCoreService.ts | 6 +- packages/core.gbapp/services/GBDeployer.ts | 23 +++- packages/core.gbapp/services/GBMinService.ts | 6 +- packages/kb.gbapp/services/KBService.ts | 2 +- packages/llm.gblib/services/ChatServices.ts | 60 ++++---- .../instagram.gbdialog/poster.bas | 7 - .../marketing.gbdialog/poster.bas | 20 +++ .../talk-to-data.gbdata/northwind.db | Bin 24702976 -> 24707072 bytes .../talk-to-data.gbialog/start.bas | 10 ++ .../talk-to-data.gbot/config.csv | 4 + 12 files changed, 160 insertions(+), 109 deletions(-) delete mode 100644 templates/instagram.gbai/instagram.gbdialog/poster.bas create mode 100644 templates/marketing.gbai/marketing.gbdialog/poster.bas create mode 100644 templates/talk-to-data.gbai/talk-to-data.gbialog/start.bas create mode 100644 templates/talk-to-data.gbai/talk-to-data.gbot/config.csv diff --git a/packages/basic.gblib/services/DialogKeywords.ts b/packages/basic.gblib/services/DialogKeywords.ts index 1ee49ea2..26741617 100644 --- a/packages/basic.gblib/services/DialogKeywords.ts +++ b/packages/basic.gblib/services/DialogKeywords.ts @@ -782,7 +782,7 @@ export class DialogKeywords { */ public async getConfig({ pid, name }) { let { min, user, params } = await DialogKeywords.getProcessInfo(pid); - return min.core.getParam(min.instance, name, null); + return min.core.getParam(min.instance, name, null, false); } /** diff --git a/packages/basic.gblib/services/GBVMService.ts b/packages/basic.gblib/services/GBVMService.ts index c70be620..6e339992 100644 --- a/packages/basic.gblib/services/GBVMService.ts +++ b/packages/basic.gblib/services/GBVMService.ts @@ -221,6 +221,72 @@ export class GBVMService extends GBService { } } + public static async loadConnections(min) { + + + // Loads storage custom connections. + const path = DialogKeywords.getGBAIPath(min.botId, null); + const filePath = Path.join('work', path, 'connections.json'); + let connections = []; + if (Fs.existsSync(filePath)) { + connections = JSON.parse(Fs.readFileSync(filePath, 'utf8')); + } + + connections.forEach(async con => { + const connectionName = con['name']; + + const dialect = con['storageDriver']; + const host = con['storageServer']; + const port = con['storagePort']; + const storageName = con['storageName']; + const username = con['storageUsername']; + const password = con['storagePassword']; + + const logging: boolean | Function = + GBConfigService.get('STORAGE_LOGGING') === 'true' + ? (str: string): void => { + GBLogEx.info(min, str); + } + : false; + + const encrypt: boolean = GBConfigService.get('STORAGE_ENCRYPT') === 'true'; + const acquire = parseInt(GBConfigService.get('STORAGE_ACQUIRE_TIMEOUT')); + const sequelizeOptions = { + define: { + charset: 'utf8', + collate: 'utf8_general_ci', + freezeTableName: true, + timestamps: false + }, + host: host, + port: port, + logging: logging as boolean, + dialect: dialect, + quoteIdentifiers: false, // set case-insensitive + dialectOptions: { + options: { + trustServerCertificate: true, + encrypt: encrypt, + requestTimeout: 120 * 1000 + } + }, + pool: { + max: 5, + min: 0, + idle: 10000, + evict: 10000, + acquire: acquire + } + }; + + if (!min[connectionName]) { + GBLogEx.info(min, `Loading custom connection ${connectionName}...`); + min[connectionName] = new Sequelize(storageName, username, password, sequelizeOptions); + min[connectionName]['gbconnection'] = con; + } + }); + } + private syncStorageFromTABLE(folder: string, filename: string, min: GBMinInstance, mainName: string) { const tablesFile = urlJoin(folder, `${filename}.tables.json`); let sync = false; @@ -282,68 +348,6 @@ export class GBVMService extends GBService { const associations = []; - // Loads storage custom connections. - const path = DialogKeywords.getGBAIPath(min.botId, null); - const filePath = Path.join('work', path, 'connections.json'); - let connections = []; - if (Fs.existsSync(filePath)) { - connections = JSON.parse(Fs.readFileSync(filePath, 'utf8')); - } - - connections.forEach(async con => { - const connectionName = con['name']; - - const dialect = con['storageDriver']; - const host = con['storageServer']; - const port = con['storagePort']; - const storageName = con['storageName']; - const username = con['storageUsername']; - const password = con['storagePassword']; - - const logging: boolean | Function = - GBConfigService.get('STORAGE_LOGGING') === 'true' - ? (str: string): void => { - GBLogEx.info(min, str); - } - : false; - - const encrypt: boolean = GBConfigService.get('STORAGE_ENCRYPT') === 'true'; - const acquire = parseInt(GBConfigService.get('STORAGE_ACQUIRE_TIMEOUT')); - const sequelizeOptions = { - define: { - charset: 'utf8', - collate: 'utf8_general_ci', - freezeTableName: true, - timestamps: false - }, - host: host, - port: port, - logging: logging as boolean, - dialect: dialect, - quoteIdentifiers: false, // set case-insensitive - dialectOptions: { - options: { - trustServerCertificate: true, - encrypt: encrypt, - requestTimeout: 120 * 1000 - } - }, - pool: { - max: 5, - min: 0, - idle: 10000, - evict: 10000, - acquire: acquire - } - }; - - if (!min[connectionName]) { - GBLogEx.info(min, `Loading custom connection ${connectionName}...`); - min[connectionName] = new Sequelize(storageName, username, password, sequelizeOptions); - min[connectionName]['gbconnection'] = con; - } - }); - const shouldSync = min.core.getParam(min.instance, 'Synchronize Database', false); tableDef.forEach(async t => { @@ -1144,7 +1148,6 @@ export class GBVMService extends GBService { }); const s = new VMScript(code, { filename: scriptPath }); result = vm1.run(s); - }); })(); } else { diff --git a/packages/core.gbapp/services/GBCoreService.ts b/packages/core.gbapp/services/GBCoreService.ts index bdc02c76..cf3cf2ca 100644 --- a/packages/core.gbapp/services/GBCoreService.ts +++ b/packages/core.gbapp/services/GBCoreService.ts @@ -724,7 +724,7 @@ ENDPOINT_UPDATE=true * @param name Name of param to get from instance. * @param defaultValue Value returned when no param is defined in Config.xlsx. */ - public getParam(instance: IGBInstance, name: string, defaultValue?: T): any { + public getParam(instance: IGBInstance, name: string, defaultValue?: T, platform=false): any { let value = null; let params; name = name.trim(); @@ -774,6 +774,10 @@ ENDPOINT_UPDATE=true value = null; } + if (!value && platform){ + value = process.env[name.replace(/ /g, "_").toUpperCase()]; + } + if (value && typeof defaultValue === 'boolean') { return new Boolean(value ? value.toString().toLowerCase() === 'true' : defaultValue).valueOf(); } diff --git a/packages/core.gbapp/services/GBDeployer.ts b/packages/core.gbapp/services/GBDeployer.ts index 03aa7362..9245f8a0 100644 --- a/packages/core.gbapp/services/GBDeployer.ts +++ b/packages/core.gbapp/services/GBDeployer.ts @@ -447,7 +447,7 @@ export class GBDeployer implements IGBDeployer { rows.shift(); } } else if (Fs.existsSync(csv)) { - await workbook.csv.readFile(filePath); + await workbook.csv.readFile(csv); let worksheet = workbook.worksheets[0]; // Assuming the CSV file has only one sheet rows = worksheet.getSheetValues(); @@ -636,12 +636,23 @@ export class GBDeployer implements IGBDeployer { const connectionName = t.replace(strFind, ''); let con = {}; con['name'] = connectionName; - con['storageServer'] = min.core.getParam(min.instance, `${connectionName} Server`, null); - con['storageUsername'] = min.core.getParam(min.instance, `${connectionName} Username`, null); - con['storageName'] = min.core.getParam(min.instance, `${connectionName} Name`, null); - con['storagePort'] = min.core.getParam(min.instance, `${connectionName} Port`, null); - con['storagePassword'] = min.core.getParam(min.instance, `${connectionName} Password`, null); con['storageDriver'] = min.core.getParam(min.instance, `${connectionName} Driver`, null); + const storageName = min.core.getParam(min.instance, `${connectionName} Name`, null); + + let file = min.core.getParam(min.instance, `${connectionName} File`, null); + + if (storageName) { + con['storageName'] = storageName; + con['storageServer'] = min.core.getParam(min.instance, `${connectionName} Server`, null); + con['storageUsername'] = min.core.getParam(min.instance, `${connectionName} Username`, null); + con['storagePort'] = min.core.getParam(min.instance, `${connectionName} Port`, null); + con['storagePassword'] = min.core.getParam(min.instance, `${connectionName} Password`, null); + } else if (file) { + const path = DialogKeywords.getGBAIPath(min.botId, 'gbdata'); + con['storageFile'] = Path.join(GBConfigService.get('STORAGE_LIBRARY'), path, file); + } else { + GBLogEx.debug(min, `No storage information found for ${connectionName}, missing storage name or file.`); + } connections.push(con); }); diff --git a/packages/core.gbapp/services/GBMinService.ts b/packages/core.gbapp/services/GBMinService.ts index 35d3909f..f6cc73a7 100644 --- a/packages/core.gbapp/services/GBMinService.ts +++ b/packages/core.gbapp/services/GBMinService.ts @@ -377,9 +377,9 @@ export class GBMinService { } res.end(); }); + GBLog.verbose(`GeneralBots(${instance.engineName}) listening on: ${url}.`); - // Generates MS Teams manifest. const manifest = `${instance.botId}-Teams.zip`; @@ -390,7 +390,9 @@ export class GBMinService { Fs.writeFileSync(packageTeams, data); } - // Serves individual URL for each bot user interface. + await GBVMService.loadConnections(min); + + // Serves individual URL for each bot user interface. if (process.env.DISABLE_WEB !== 'true') { const uiUrl = `/${instance.botId}`; diff --git a/packages/kb.gbapp/services/KBService.ts b/packages/kb.gbapp/services/KBService.ts index 76c346aa..34e11b49 100644 --- a/packages/kb.gbapp/services/KBService.ts +++ b/packages/kb.gbapp/services/KBService.ts @@ -1061,7 +1061,7 @@ export class KBService implements IGBKBService { let logo = await this.getLogoByPage(min, page); if (logo) { path = DialogKeywords.getGBAIPath(min.botId); - const logoPath = Path.join(process.env.PWD, 'work', path, 'cache'); + const baseUrl = page.url().split('/').slice(0, 3).join('/'); logo = logo.startsWith('https') ? logo : urlJoin(baseUrl, logo); diff --git a/packages/llm.gblib/services/ChatServices.ts b/packages/llm.gblib/services/ChatServices.ts index 1a2e3f2f..53c51d0b 100644 --- a/packages/llm.gblib/services/ChatServices.ts +++ b/packages/llm.gblib/services/ChatServices.ts @@ -294,28 +294,29 @@ export class ChatServices { let model; - const azureOpenAIKey = await min.core.getParam(min.instance, 'Azure Open AI Key', null); - const azureOpenAIGPTModel = await min.core.getParam(min.instance, 'Azure Open AI GPT Model', null); - const azureOpenAIVersion = await min.core.getParam(min.instance, 'Azure Open AI Version', null); - const azureOpenAIApiInstanceName = await min.core.getParam(min.instance, 'Azure Open AI Instance', null); + const azureOpenAIKey = await (min.core as any)['getParam'](min.instance, 'Azure Open AI Key', null, true); + const azureOpenAIGPTModel = await (min.core as any)['getParam']( + min.instance, + 'Azure Open AI GPT Model', + null, + true + ); + const azureOpenAIVersion = await (min.core as any)['getParam'](min.instance, 'Azure Open AI Version', null, true); + const azureOpenAIApiInstanceName = await (min.core as any)['getParam']( + min.instance, + 'Azure Open AI Instance', + null, + true + ); - if (azureOpenAIKey) { - model = new ChatOpenAI({ - azureOpenAIApiKey: azureOpenAIKey, - azureOpenAIApiInstanceName: azureOpenAIApiInstanceName, - azureOpenAIApiDeploymentName: azureOpenAIGPTModel, - azureOpenAIApiVersion: azureOpenAIVersion, - temperature: 0, - callbacks: [logHandler] - }); - } else { - model = new ChatOpenAI({ - openAIApiKey: process.env.OPENAI_API_KEY, - modelName: 'gpt-3.5-turbo-0125', - temperature: 0, - callbacks: [logHandler] - }); - } + model = new ChatOpenAI({ + azureOpenAIApiKey: azureOpenAIKey, + azureOpenAIApiInstanceName: azureOpenAIApiInstanceName, + azureOpenAIApiDeploymentName: azureOpenAIGPTModel, + azureOpenAIApiVersion: azureOpenAIVersion, + temperature: 0, + callbacks: [logHandler] + }); let tools = await ChatServices.getTools(min); let toolsAsText = ChatServices.getToolsAsText(tools); @@ -476,21 +477,24 @@ export class ChatServices { }); } else if (LLMMode === 'sql') { const con = min[`llm`]['gbconnection']; - + const dialect = con['storageDriver']; - const host = con['storageServer']; - const port = con['storagePort']; - const storageName = con['storageName']; - const username = con['storageUsername']; - const password = con['storagePassword']; let dataSource; if (dialect === 'sqlite') { dataSource = new DataSource({ type: 'sqlite', - database: storageName + database: con['storageFile'], + synchronize: false, + logging: true }); } else { + const host = con['storageServer']; + const port = con['storagePort']; + const storageName = con['storageName']; + const username = con['storageUsername']; + const password = con['storagePassword']; + dataSource = new DataSource({ type: dialect as any, host: host, diff --git a/templates/instagram.gbai/instagram.gbdialog/poster.bas b/templates/instagram.gbai/instagram.gbdialog/poster.bas deleted file mode 100644 index 7bed7e8e..00000000 --- a/templates/instagram.gbai/instagram.gbdialog/poster.bas +++ /dev/null @@ -1,7 +0,0 @@ -REM SET SCHEDULE "* 8 * * * *" -user = “user@domain.com” -pass= "*************" -o =get "https://oooooooooo" -caption = REWRITE "Crie um post sobre hotmart e seus produtos, no estilo dica do dia incluíndo 10 hashtags, estilo instagram o texto! Importante, retorne só a saída de texto pronta" -image = GET IMAGE caption -POST username, password, image, caption diff --git a/templates/marketing.gbai/marketing.gbdialog/poster.bas b/templates/marketing.gbai/marketing.gbdialog/poster.bas new file mode 100644 index 00000000..d85f64af --- /dev/null +++ b/templates/marketing.gbai/marketing.gbdialog/poster.bas @@ -0,0 +1,20 @@ +REM SET SCHEDULE "* 8 * * * *" + +user = "user@domain.com" +pass = "*************" +o = get "https://oooooooooo" + +# Criar a legenda para o post +caption = REWRITE "Crie um post sobre Hotmart e seus produtos, no estilo dica do dia, incluindo 10 hashtags, estilo Instagram o texto! Importante, retorne só a saída de texto pronta" + +# Obter uma imagem relacionada ao conteúdo +image = GET IMAGE caption + +# Postar no Instagram +POST TO INSTAGRAM username, password, image, caption + +# Postar no Facebook +POST TO FACEBOOK username, password, image, caption + +# Postar no Twitter +TWEET username, password, image, caption diff --git a/templates/talk-to-data.gbai/talk-to-data.gbdata/northwind.db b/templates/talk-to-data.gbai/talk-to-data.gbdata/northwind.db index 3c55834518c1336fb31edf661a24cb0c3cdead81..f69338a1acaa4632504ad47f4793755211852e69 100644 GIT binary patch delta 3413 zcmZYB3s_U<9mnzaoRgCfZh@RY42T?p+yq1f#JdIviVDOKsZa!h93&M8Cb3GpDYxNP z+lsZ@+1kz8t=-mL7)nRlt*f1FH)prbb?q*-t9Y4PJLhogx^BJg_XoK>@;slfA?KX; zyg7OB`FD?93G42@8a5aotuSUDoW!yiWAf3gJW*kb@98|*Je>T&PsIB+L7AsT0_VtUdxhtICf0wE;%(Q z${NEfIBCyK@$6BDX5@|G_ak+Ag2j7q=>kU-6$Br=`zg>60gyn(6+_g4I!+&!Af-;;Jg9Hb!x| zqcSJTTEjEUa1k5LealRrX^0D+w{hc~hOzL(;7i5adttg1oyg+XG4)LwC+iZmB1_3& z>bYVrZq&hv4$*L#87`}~aq)@Z&6T)JHGy_XZQ{ z`74~%+rpVxytx2}*TvsDoboo`tG@P$@OpSeWEA7WJuKW4*&YlZ<9CEheG3H>OPshM zH{sR=xnul+;JZV-h2wUprW<^X)EA|}vIzw-Nl69M%iiF7RKtV(r=#OM*BGTOXCilv z375HRAvKXhx*&H&Eam7KACdaHwAge!?P`rBEj~I;Vrojg&>f7)7CfBP-zu6|f+Y=y zGbaw?Gc~ycUoh^~kZYVKbP4-N-C8YtAoWJ*vDp|}CueG%rfQ)}tvN3AOMNb#iN#px z=!U7I1$9DiaA~_xL|>fdKrp{nxK1yHvEahG$(P)?YN{6=k$NjbunY4VTwXZ!8SS+~ zpQ?P!KR3`Q3^Zy68pVM|?Leb$v@s-B=J?>vb9JjHKI8R+{c@_#oRh;JYM=Pixa}|H zwl~a!#ZJ4;WtUyHqAhmWdfN$BIXzTwwYPV+dAk&)ti-A>t8m#j*qvE;dyCs2sBpI{ zR=vx<-IW!3P;V{u_~yQ+x4Jxmw&_!D{aV>l?A_}NDE_XgYxUM5k1x<#;tt^45^RZX zu+igF=DuTVZuTjD|IAgzp1|}PxW7}`{PeOI3KW-gAIzH z7)rnnrLX}uLK$p=&9DW^p#mzw0b9WdRp5ecPz`s$cBp|`xD)DN2h>9YG=dwNU?((# z0xhr$TEPQ%!ER`ScIW^vbiy9+fgb{}7w(3AupheM9=I1i1D}Nha1gqo2YR6o`r&gh z0Egi7@CCRJ4#WNM06YjsU=WVNLvRcphA+aGK!q>ESKtwN6ut^ygX8cRoPfvS>+lVD z0-l6#!nfet@DzLpz6;-j@52!M0EXctoPrT}8h!|)5QJyoS@;qB7@mWl!1Hh#UVxv% z8F&$1f|ucE@N+l|zkqY_3j7j&1+T)d;XM2XUW4Dl>+lBr4t@`RfIq^UZ~@+eKf&8@ z5ys#WT!t%f75)s@;4ko3cn98vzrl6*JKTVOz&PB5f5N}uJ@_}g5C4G=;J@%c_z*sV zkKq&e^l(!@cLXRrMWARXB1KElQ9>wsN+>0a5>APrL{bctC`vTNNRcQeN(?2IVy4Wa zSSWFnc*=ZA0%ZXuks?!)C{{``Wg#Vnl1fRVq*F2|izu0tEJ`+IF(rqxgpx~HO39<- zQwk`{D20^elogbflvR|~lr@yKly#K#6dR?8QcNkK*eRuy4U~yIi-S9 zNpVoNQk;}3ii@(1QcbyovYk>xsioXWsiW+m)KeNLjTASfiL#T@Oi?H;lwFioiidI+ zWjCdb(oX51cqyHfJrp0sPYF==Qtqbg<4)th9q#ze9xR6yPzbrO6qdj$SPd%yvk((O3k5nP6vBXJ^+8}&KeVq{kudg zJbO%>H6suc<*HLdZY*c)Z|8B_*)#R5k=od+a9DWuNUcs! G)c*&m*@43V delta 4411 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 TC7m*ZGLtfkEyuFMZl3rLuO4*h diff --git a/templates/talk-to-data.gbai/talk-to-data.gbialog/start.bas b/templates/talk-to-data.gbai/talk-to-data.gbialog/start.bas new file mode 100644 index 00000000..cbbb7d05 --- /dev/null +++ b/templates/talk-to-data.gbai/talk-to-data.gbialog/start.bas @@ -0,0 +1,10 @@ + +data = FIND "products.csv" +BEGIN SYSTEM PROMPT +Engage users effectively as if you're a sales assistant in the virtual store. +Begin by welcoming them warmly and encouraging them to explore our range of products. + Provide clear instructions on how to inquire about specific items or browse + categories. Ensure the tone is friendly, helpful, and inviting to encourage + interaction. Use prompts to guide users through the purchasing process and offer + assistance whenever needed. Offer them this products: ${ TOJSON (data) } +END SYSTEM PROMPT \ No newline at end of file diff --git a/templates/talk-to-data.gbai/talk-to-data.gbot/config.csv b/templates/talk-to-data.gbai/talk-to-data.gbot/config.csv new file mode 100644 index 00000000..b5f99f48 --- /dev/null +++ b/templates/talk-to-data.gbai/talk-to-data.gbot/config.csv @@ -0,0 +1,4 @@ +name,value +Answer Mode,sql +llm File,northwind.db +llm Driver,sqlite \ No newline at end of file