From 26b05aa394adf5dfe89416a4c4b452aafe488a78 Mon Sep 17 00:00:00 2001 From: Rodrigo Rodriguez Date: Sun, 3 Mar 2024 16:20:50 -0300 Subject: [PATCH] fix(basic.gblib): FUNCTION GPT. --- .../basic.gblib/services/DialogKeywords.ts | 123 +++++++++++++++--- packages/basic.gblib/services/GBVMService.ts | 6 +- .../basic.gblib/services/ScheduleServices.ts | 4 +- .../basic.gblib/services/SystemKeywords.ts | 2 +- packages/core.gbapp/services/GBMinService.ts | 35 ++--- packages/gpt.gblib/services/ChatServices.ts | 12 ++ 6 files changed, 141 insertions(+), 41 deletions(-) diff --git a/packages/basic.gblib/services/DialogKeywords.ts b/packages/basic.gblib/services/DialogKeywords.ts index 952b12cf..a6dc28b2 100644 --- a/packages/basic.gblib/services/DialogKeywords.ts +++ b/packages/basic.gblib/services/DialogKeywords.ts @@ -32,7 +32,7 @@ 'use strict'; -import { GBLog } from 'botlib'; +import { GBLog, GBMinInstance } from 'botlib'; import { GBConfigService } from '../../core.gbapp/services/GBConfigService.js'; import { ChartServices } from './ChartServices.js'; import urlJoin from 'url-join'; @@ -61,6 +61,10 @@ const { List, Buttons } = pkg; import mime from 'mime-types'; import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js'; import { GBUtil } from '../../../src/util.js'; +import SwaggerClient from 'swagger-client'; +import { GBVMService } from './GBVMService.js'; + + /** * Default check interval for user replay @@ -317,7 +321,7 @@ export class DialogKeywords { } // https://weblog.west-wind.com/posts/2008/Mar/18/A-simple-formatDate-function-for-JavaScript - public async format({pid, value, format}) { + public async format({ pid, value, format }) { const { min, user } = await DialogKeywords.getProcessInfo(pid); const contentLocale = min.core.getParam( @@ -327,10 +331,10 @@ export class DialogKeywords { ); if (!(value instanceof Date)) { - value = SystemKeywords.getDateFromLocaleString(pid,value, contentLocale); + value = SystemKeywords.getDateFromLocaleString(pid, value, contentLocale); } - var date:any = new Date(value); //don't change original date - + var date: any = new Date(value); //don't change original date + if (!format) format = "MM/dd/yyyy"; @@ -375,7 +379,7 @@ export class DialogKeywords { * * https://stackoverflow.com/a/1214753/18511 */ - public async dateAdd({pid, date, mode, units}) { + public async dateAdd({ pid, date, mode, units }) { const { min, user } = await DialogKeywords.getProcessInfo(pid); const contentLocale = min.core.getParam( @@ -386,7 +390,7 @@ export class DialogKeywords { let dateCopy = date; if (!(dateCopy instanceof Date)) { - dateCopy = SystemKeywords.getDateFromLocaleString(pid,dateCopy, contentLocale); + dateCopy = SystemKeywords.getDateFromLocaleString(pid, dateCopy, contentLocale); } var ret = new Date(dateCopy); //don't change original date var checkRollover = function () { @@ -617,8 +621,7 @@ export class DialogKeywords { if (!people) { throw new Error(`Invalid access. Check if People sheet has the role ${role} checked.`); } - else - { + else { GBLogEx.info(min, `Allowed access for ${user.userSystemId} on ${role}`); return people; } @@ -948,7 +951,7 @@ export class DialogKeywords { const path = DialogKeywords.getGBAIPath(botId); let url = `${baseUrl}/drive/root:/${path}:/children`; - GBLog.info(`Loading HEAR AS .xlsx options from Sheet: ${url}`); + GBLogEx.info(min, `Loading HEAR AS .xlsx options from Sheet: ${url}`); const res = await client.api(url).get(); // Finds .xlsx specified by arg. @@ -999,7 +1002,7 @@ export class DialogKeywords { } } else if (kind === 'file') { GBLog.info(`BASIC (${min.botId}): Upload done for ${answer.filename}.`); - const handle = WebAutomationServices.cyrb53({pid, str: min.botId + answer.filename}); + const handle = WebAutomationServices.cyrb53({ pid, str: min.botId + answer.filename }); GBServer.globals.files[handle] = answer; result = handle; } else if (kind === 'boolean') { @@ -1120,7 +1123,7 @@ export class DialogKeywords { } else if (kind === 'qr-scanner') { //https://github.com/GeneralBots/BotServer/issues/171 GBLog.info(`BASIC (${min.botId}): Upload done for ${answer.filename}.`); - const handle = WebAutomationServices.cyrb53({pid, str: min.botId + answer.filename}); + const handle = WebAutomationServices.cyrb53({ pid, str: min.botId + answer.filename }); GBServer.globals.files[handle] = answer; QrScanner.scanImage(GBServer.globals.files[handle]) .then(result => console.log(result)) @@ -1242,6 +1245,88 @@ export class DialogKeywords { } } + public async messageBot({ pid, text }) { + const { min, user } = await DialogKeywords.getProcessInfo(pid); + GBLogEx.info(min,`MESSAGE BOT: ${text}.`); + + const conversation = min['apiConversations'][pid]; + + conversation.client.apis.Conversations.Conversations_PostActivity({ + conversationId: conversation.conversationId, + activity: { + textFormat: 'plain', + text: text, + type: 'message', + from: { + id: 'word', + name: 'word' + } + } + }); + const watermarkMap = conversation.watermarkMap; + + let messages = []; + + const response = await conversation.client.apis.Conversations.Conversations_GetActivities({ + conversationId: conversation.conversationId, + watermark: conversation.watermark + }); + conversation.watermarkMap = response.obj.watermark; + let activities = response.obj.activites; + + + if (activities && activities.length) { + activities = activities.filter(m => m.from.id === min.botId && m.type === 'message'); + if (activities.length) { + activities.forEach(activity => { + messages.push({ text: activity.text }); + GBLogEx.info(min, `MESSAGE BOT answer from bot: ${activity.text}`); + }); + } + } + + return messages.join('\n'); + } + + + public async start({ botId, botApiKey, userSystemId, text }) { + + let min: GBMinInstance = GBServer.globals.minInstances.filter(p => p.instance.botId === botId)[0]; + let sec = new SecService(); + let user = await sec.getUserFromSystemId(userSystemId); + if (!user) { + user = await sec.ensureUser( + min, + userSystemId, + userSystemId, + null, + 'api', + 'API User', + null + ); + } + + + const pid = GBVMService.createProcessInfo(user, min, 'api', null); + + const conversation = min['apiConversations'][pid]; + + const client = await new SwaggerClient({ + spec: JSON.parse(Fs.readFileSync('directline-3.0.json', 'utf8')), + requestInterceptor: req => { + req.headers['Authorization'] = `Bearer ${min.instance.webchatKey}`; + } + }); + conversation.client = client; + const response = await client.apis.Conversations.Conversations_StartConversation(); + conversation.conversationId = response.obj.conversationId; + + return await GBVMService.callVM('start', min, null, pid); + + } + + + public static async getProcessInfo(pid: number) { const proc = GBServer.globals.processes[pid]; @@ -1270,10 +1355,10 @@ export class DialogKeywords { min, text, user.locale ? user.locale : min.core.getParam(min.instance, 'Locale', - GBConfigService.get('LOCALE')) + GBConfigService.get('LOCALE')) ); GBLog.verbose(`Translated text(playMarkdown): ${text}.`); - + await min.conversationalService['sendOnConversation'](min, user, text); } return { status: 0 }; @@ -1336,19 +1421,19 @@ export class DialogKeywords { else { - + const ext = Path.extname(filename); const gbaiName = DialogKeywords.getGBAIPath(min.botId); - + let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min); const fileUrl = urlJoin('/', gbaiName, `${min.botId}.gbdrive`, filename); GBLog.info(`BASIC: Direct send from .gbdrive: ${fileUrl} to ${mobile}.`); - + const sys = new SystemKeywords(); - + const pathOnly = fileUrl.substring(0, fileUrl.lastIndexOf('/')); const fileOnly = fileUrl.substring(fileUrl.lastIndexOf('/') + 1); - + let template = await sys.internalGetDocument(client, baseUrl, pathOnly, fileOnly); const driveUrl = template['@microsoft.graph.downloadUrl']; diff --git a/packages/basic.gblib/services/GBVMService.ts b/packages/basic.gblib/services/GBVMService.ts index f46c5020..93b972e4 100644 --- a/packages/basic.gblib/services/GBVMService.ts +++ b/packages/basic.gblib/services/GBVMService.ts @@ -940,8 +940,7 @@ export class GBVMService extends GBService { text: string, min: GBMinInstance, step, - user: GuaribasUser, - deployer: GBDeployer, + pid, debug: boolean = false, params = [] ) { @@ -1001,7 +1000,8 @@ export class GBVMService extends GBService { let code = min.sandBoxMap[text]; const channel = step ? step.context.activity.channelId : 'web'; - const pid = GBVMService.createProcessInfo(user, min, channel, text); + + const dk = new DialogKeywords(); const sys = new SystemKeywords(); await dk.setFilter({ pid: pid, value: null }); diff --git a/packages/basic.gblib/services/ScheduleServices.ts b/packages/basic.gblib/services/ScheduleServices.ts index 2851729a..19b29389 100644 --- a/packages/basic.gblib/services/ScheduleServices.ts +++ b/packages/basic.gblib/services/ScheduleServices.ts @@ -139,7 +139,9 @@ export class ScheduleServices extends GBService { p => p.instance.instanceId === item.instanceId )[0]; GBLogEx.info(min,`Running .gbdialog word ${item.name} on:${item.schedule}...`); - await GBVMService.callVM(script, min, null, null, null, false); + + const pid = GBVMService.createProcessInfo(null, min, 'batch', null); + await GBVMService.callVM(script, min, null, pid); }; (async () => { await finalData(); diff --git a/packages/basic.gblib/services/SystemKeywords.ts b/packages/basic.gblib/services/SystemKeywords.ts index 3039817f..634f16fd 100644 --- a/packages/basic.gblib/services/SystemKeywords.ts +++ b/packages/basic.gblib/services/SystemKeywords.ts @@ -90,7 +90,7 @@ export class SystemKeywords { const step = null; const deployer = null; - return await GBVMService.callVM(text, min, step, user, deployer, false); + return await GBVMService.callVM(text, min, step, pid,false, [text]); } public async append({ pid, args }) { diff --git a/packages/core.gbapp/services/GBMinService.ts b/packages/core.gbapp/services/GBMinService.ts index 43f0a10f..776fe691 100644 --- a/packages/core.gbapp/services/GBMinService.ts +++ b/packages/core.gbapp/services/GBMinService.ts @@ -759,6 +759,7 @@ export class GBMinService { const gbkbPath = DialogKeywords.getGBAIPath(min.botId, 'gbkb'); min['vectorStorePath'] = Path.join('work', gbkbPath, 'docs-vectorized'); } + min['apiConversations'] = {}; min.packages = sysPackages; // NLP Manager. @@ -942,7 +943,7 @@ export class GBMinService { req.body.channelId = req.body.from.channelIdEx === 'whatsapp' ? 'omnichannel' : req.body.channelId; req.body.group = req.body.from.group; - + // Default activity processing and handler. const handler = async context => { @@ -1048,7 +1049,7 @@ export class GBMinService { if (startDialog) { await sec.setParam(userId, 'welcomed', 'true'); GBLog.info(`Auto start (teams) dialog is now being called: ${startDialog} for ${min.instance.botId}...`); - await GBVMService.callVM(startDialog.toLowerCase(), min, step, user, this.deployer, false); + await GBVMService.callVM(startDialog.toLowerCase(), min, step, pid); } } } @@ -1064,6 +1065,12 @@ export class GBMinService { const startDialog = min.core.getParam(min.instance, 'Start Dialog', null); + let pid = step.context.activity['pid']; + if (!pid){ + pid = GBVMService.createProcessInfo(user, min, step.context.activity.channelId, null); + } + step.context.activity['pid'] = pid; + if (context.activity.type === 'installationUpdate') { GBLog.info(`Bot installed on Teams.`); } else if (context.activity.type === 'conversationUpdate' && context.activity.membersAdded.length > 0) { @@ -1095,7 +1102,7 @@ export class GBMinService { GBLog.info( `Auto start (web 1) dialog is now being called: ${startDialog} for ${min.instance.instanceId}...` ); - await GBVMService.callVM(startDialog.toLowerCase(), min, step, user, this.deployer, false); + await GBVMService.callVM(startDialog.toLowerCase(), min, step, pid); } } } else { @@ -1104,11 +1111,8 @@ export class GBMinService { return; } } else if (context.activity.type === 'message') { - // Processes messages activities. - const pid = GBVMService.createProcessInfo(user, min, step.context.activity.channelId, null); - step.context.activity['pid'] = pid; await this.processMessageActivity(context, min, step, pid); } else if (context.activity.type === 'event') { @@ -1171,7 +1175,7 @@ export class GBMinService { if (startDialog && !min['conversationWelcomed'][step.context.activity.conversation.id]) { user.welcomed = true; GBLog.info(`Auto start (web 2) dialog is now being called: ${startDialog} for ${min.instance.instanceId}...`); - await GBVMService.callVM(startDialog.toLowerCase(), min, step, user, this.deployer, false); + await GBVMService.callVM(startDialog.toLowerCase(), min, step, pid); } } else if (context.activity.name === 'updateToken') { const token = context.activity.data; @@ -1400,7 +1404,7 @@ export class GBMinService { GBLog.info( `Auto start (whatsapp) dialog is now being called: ${startDialog} for ${min.instance.instanceId}...` ); - await GBVMService.callVM(startDialog.toLowerCase(), min, step, user, this.deployer, false); + await GBVMService.callVM(startDialog.toLowerCase(), min, step, user, pid); return; } @@ -1418,7 +1422,7 @@ export class GBMinService { if (/create dialog|creative dialog|create a dialog|criar diálogo|criar diálogo/gi.test(context.activity.text)) { await step.beginDialog('/dialog'); } else if (isVMCall) { - await GBVMService.callVM(context.activity.text, min, step, user, this.deployer, false); + await GBVMService.callVM(context.activity.text, min, step, pid); } else if (context.activity.text.charAt(0) === '/') { const text = context.activity.text; const parts = text.split(' '); @@ -1430,11 +1434,11 @@ export class GBMinService { await min.conversationalService.sendEvent(min, step, 'loadInstance', {}); } else if (cmdOrDialogName === '/call') { - await GBVMService.callVM(args, min, step, user, this.deployer, false); + await GBVMService.callVM(args, min, step, pid); } else if (cmdOrDialogName === '/callsch') { - await GBVMService.callVM(args, min, null, null, null, false); + await GBVMService.callVM(args, min, null, pid); } else if (cmdOrDialogName === '/calldbg') { - await GBVMService.callVM(args, min, step, user, this.deployer, true); + await GBVMService.callVM(args, min, step, pid, true); } else { await step.beginDialog(cmdOrDialogName, { args: args }); } @@ -1592,11 +1596,8 @@ export class GBMinService { await CollectionUtil.asyncForEach(Object.values(min.scriptMap), async script => { dialogs[script] = async (data) => { - let params; - if (data) { - params = JSON.parse(data); - } - await GBVMService.callVM(script, min, null, null, null, false, params); + let params = JSON.parse(data); + return await GBVMService.callVM(script, min, null, params.pid, false, params); } }); diff --git a/packages/gpt.gblib/services/ChatServices.ts b/packages/gpt.gblib/services/ChatServices.ts index c0cbb672..e9437b1e 100644 --- a/packages/gpt.gblib/services/ChatServices.ts +++ b/packages/gpt.gblib/services/ChatServices.ts @@ -157,6 +157,9 @@ export class ChatServices { 'Default Content Language', GBConfigService.get('DEFAULT_CONTENT_LANGUAGE') ); + + + const tools = ""// TODO: add func list. const chatPrompt = ChatPromptTemplate.fromPromptMessages([ systemPrompt, @@ -171,8 +174,17 @@ export class ChatServices { QUESTION: """{input}""" + You have the following tools that you can invoke based on the user inquiry. + Tools: + + ${tools} + `), ]); + + + + const windowMemory = new BufferWindowMemory({ returnMessages: false, memoryKey: 'immediate_history',