diff --git a/packages/admin.gbapp/dialogs/AdminDialog.ts b/packages/admin.gbapp/dialogs/AdminDialog.ts index 5a9acdaa..6d79d1a0 100644 --- a/packages/admin.gbapp/dialogs/AdminDialog.ts +++ b/packages/admin.gbapp/dialogs/AdminDialog.ts @@ -45,11 +45,11 @@ import { GBAdminService } from '../services/GBAdminService.js'; import { CollectionUtil } from 'pragmatismo-io-framework'; import { SecService } from '../../security.gbapp/services/SecService.js'; import { GBConfigService } from '../../core.gbapp/services/GBConfigService.js'; +import { GBServer } from '../../../src/app.js'; +import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js'; -/** - * Dialogs for administration tasks. - */ -export class AdminDialog extends IGBDialog { + +class AdminDialog extends IGBDialog { public static isIntentYes(locale, utterance) { return utterance.toLowerCase().match(Messages[locale].affirmative_sentences); } @@ -58,15 +58,7 @@ export class AdminDialog extends IGBDialog { return utterance.toLowerCase().match(Messages[locale].negative_sentences); } - /** - * Setup dialogs flows and define services call. - * - * @param bot The bot adapter. - * @param min The minimal bot instance data. - */ public static setup(min: GBMinInstance) { - // Setup services. - const importer = new GBImporter(min.core); const deployer = new GBDeployer(min.core, importer); @@ -75,6 +67,7 @@ export class AdminDialog extends IGBDialog { min.dialogs.add( new WaterfallDialog('/admin-auth', [ async step => { + min = GBServer.globals.minInstances.find(p => p.botId === min.botId); if (step.context.activity.channelId !== 'msteams' && process.env.ENABLE_AUTH) { return await step.beginDialog('/auth'); } else { @@ -82,12 +75,14 @@ export class AdminDialog extends IGBDialog { } }, async step => { + min = GBServer.globals.minInstances.find(p => p.botId === min.botId); const locale = step.context.activity.locale; const prompt = Messages[locale].authenticate; return await min.conversationalService.prompt(min, step, prompt); }, async step => { + min = GBServer.globals.minInstances.find(p => p.botId === min.botId); const locale = step.context.activity.locale; const sensitive = step.context.activity['originalText']; @@ -106,6 +101,7 @@ export class AdminDialog extends IGBDialog { min.dialogs.add( new WaterfallDialog('/admin', [ async step => { + min = GBServer.globals.minInstances.find(p => p.botId === min.botId); if (step.context.activity.channelId !== 'msteams' && process.env.ENABLE_AUTH) { return await step.beginDialog('/auth'); } else { @@ -113,12 +109,14 @@ export class AdminDialog extends IGBDialog { } }, async step => { + min = GBServer.globals.minInstances.find(p => p.botId === min.botId); const locale = step.context.activity.locale; const prompt = Messages[locale].authenticate; return await min.conversationalService.prompt(min, step, prompt); }, async step => { + min = GBServer.globals.minInstances.find(p => p.botId === min.botId); const locale = step.context.activity.locale; const sensitive = step.context.activity['originalText']; @@ -133,8 +131,8 @@ export class AdminDialog extends IGBDialog { } }, async step => { + min = GBServer.globals.minInstances.find(p => p.botId === min.botId); const locale: string = step.context.activity.locale; - // tslint:disable-next-line:no-unsafe-any const text: string = step.context.activity['originalText']; const cmdName = text.split(' ')[0]; @@ -166,6 +164,7 @@ export class AdminDialog extends IGBDialog { min.dialogs.add( new WaterfallDialog('/install', [ async step => { + min = GBServer.globals.minInstances.find(p => p.botId === min.botId); if (step.context.activity.channelId !== 'msteams' && process.env.ENABLE_AUTH) { return await step.beginDialog('/auth'); } else { @@ -173,6 +172,7 @@ export class AdminDialog extends IGBDialog { } }, async step => { + min = GBServer.globals.minInstances.find(p => p.botId === min.botId); step.activeDialog.state.options.args = (step.options as any).args; if (step.activeDialog.state.options.confirm) { return await step.next('sim'); @@ -182,10 +182,9 @@ export class AdminDialog extends IGBDialog { } }, async step => { + min = GBServer.globals.minInstances.find(p => p.botId === min.botId); const locale = step.context.activity.locale; - // If the user says yes, starts publishing. - if (AdminDialog.isIntentYes(locale, step.result)) { const list = min.core.getParam(min.instance, '.gbapp List', null); const items = list ? list.split(';') : []; @@ -208,10 +207,10 @@ export class AdminDialog extends IGBDialog { ]) ); - min.dialogs.add( new WaterfallDialog('/logs', [ async step => { + min = GBServer.globals.minInstances.find(p => p.botId === min.botId); if (step.context.activity.channelId !== 'msteams' && process.env.ENABLE_AUTH) { return await step.beginDialog('/auth'); } else { @@ -219,25 +218,26 @@ export class AdminDialog extends IGBDialog { } }, async step => { + min = GBServer.globals.minInstances.find(p => p.botId === min.botId); const logs = await min.core['getLatestLogs'](); await min.conversationalService.sendText(min, step, logs); return await step.replaceDialog('/ask', { isReturning: true }); } ])); - min.dialogs.add( new WaterfallDialog('/publish', [ async step => { + min = GBServer.globals.minInstances.find(p => p.botId === min.botId); if (step.context.activity.channelId !== 'msteams' && process.env.ENABLE_AUTH) { return await step.beginDialog('/auth'); } else { return await step.next(step.options); } }, - async step => { - step.activeDialog.state.options.confirm = true; // Feature removed. + min = GBServer.globals.minInstances.find(p => p.botId === min.botId); + step.activeDialog.state.options.confirm = true; if (step.activeDialog.state.options.confirm || process.env.ADMIN_OPEN_PUBLISH === 'true') { return await step.next('sim'); } else { @@ -246,10 +246,9 @@ export class AdminDialog extends IGBDialog { } }, async step => { + min = GBServer.globals.minInstances.find(p => p.botId === min.botId); const locale = step.context.activity.locale; - // If the user says yes, starts publishing. - if (AdminDialog.isIntentYes(locale, step.result)) { let from = step.context.activity.from.id; @@ -270,6 +269,7 @@ export class AdminDialog extends IGBDialog { } }, async step => { + min = GBServer.globals.minInstances.find(p => p.botId === min.botId); const locale = step.context.activity.locale; if (!step.result) { await min.conversationalService.sendText(min, step, Messages[locale].publish_must_be_admin); @@ -299,7 +299,6 @@ export class AdminDialog extends IGBDialog { packages.push(filename); } - await CollectionUtil.asyncForEach(packages, async packageName => { let cmd1; @@ -338,6 +337,14 @@ export class AdminDialog extends IGBDialog { await GBAdminService.deployPackageCommand(min, user, cmd1, deployer); + // .gbot updates severals keys in instantece, so min must be updated. + + const activeMin = GBServer.globals.minInstances.find(p=> p.botId === min.botId); + + if (activeMin){ + min = activeMin; + } + }); await min.conversationalService.sendText(min, step, `Training is finished.`); @@ -351,11 +358,6 @@ export class AdminDialog extends IGBDialog { ); } - /** - * Check if the specified phone can receive a message by running - * the /broadcast command with specific phone numbers. - * @param phone Phone number to check (eg.: +5521900002233) - */ public static canPublish(min: GBMinInstance, phone: string): Boolean { if (process.env.SECURITY_CAN_PUBLISH !== undefined) { let list = process.env.SECURITY_CAN_PUBLISH.split(';'); @@ -381,6 +383,7 @@ export class AdminDialog extends IGBDialog { min.dialogs.add( new WaterfallDialog('/setupSecurity', [ async step => { + min = GBServer.globals.minInstances.find(p => p.botId === min.botId); const tokenName = step.activeDialog.state.tokenName = step.options['args']; if (tokenName) { step.activeDialog.state.clientId = min.core.getParam(min.instance, `${tokenName} Client ID`, null), @@ -393,8 +396,8 @@ export class AdminDialog extends IGBDialog { return await step.next(step.options); } }, - async step => { + min = GBServer.globals.minInstances.find(p => p.botId === min.botId); if (step.activeDialog.state.tokenName) { return await step.next(step.options); } @@ -405,9 +408,10 @@ export class AdminDialog extends IGBDialog { return await min.conversationalService.prompt(min, step, prompt); }, async step => { + min = GBServer.globals.minInstances.find(p => p.botId === min.botId); if (step.activeDialog.state.tokenName) { return await step.next(step.options); - } + } step.activeDialog.state.authenticatorTenant = step.context.activity['originalText']; const locale = step.context.activity.locale; const prompt = Messages[locale].enter_authenticator_authority_host_url; @@ -415,7 +419,7 @@ export class AdminDialog extends IGBDialog { return await min.conversationalService.prompt(min, step, prompt); }, async step => { - + min = GBServer.globals.minInstances.find(p => p.botId === min.botId); step.activeDialog.state.authenticatorAuthorityHostUrl = step.context.activity['originalText']; const tokenName = step.activeDialog.state.tokenName; @@ -423,13 +427,12 @@ export class AdminDialog extends IGBDialog { if (!tokenName) { min.instance.authenticatorAuthorityHostUrl = step.activeDialog.state.authenticatorAuthorityHostUrl; min.instance.authenticatorTenant = step.activeDialog.state.authenticatorTenant; - - await min.adminService.updateSecurityInfo( - min.instance.instanceId, - tokenName ? step.activeDialog.state.tenant : step.activeDialog.state.authenticatorTenant, - tokenName ? step.activeDialog.state.host : step.activeDialog.state.authenticatorAuthorityHostUrl - ); + await min.adminService.updateSecurityInfo( + min.instance.instanceId, + tokenName ? step.activeDialog.state.tenant : step.activeDialog.state.authenticatorTenant, + tokenName ? step.activeDialog.state.host : step.activeDialog.state.authenticatorAuthorityHostUrl + ); } const locale = step.context.activity.locale; const buf = Buffer.alloc(16); @@ -455,3 +458,5 @@ export class AdminDialog extends IGBDialog { ); } } + +export { AdminDialog }; \ No newline at end of file diff --git a/packages/core.gbapp/services/GBCoreService.ts b/packages/core.gbapp/services/GBCoreService.ts index 4230dbcf..f6203429 100644 --- a/packages/core.gbapp/services/GBCoreService.ts +++ b/packages/core.gbapp/services/GBCoreService.ts @@ -927,8 +927,8 @@ await fs.writeFile('.env', env); const objUser = userManager.addUser(user, pass); const virtualPath = '/' + min.botId; - let path = GBUtil.getGBAIPath(min.botId, null); - const gbaiRoot = path.join(GBConfigService.get('STORAGE_LIBRARY'), path); + let path1 = GBUtil.getGBAIPath(min.botId, null); + const gbaiRoot = path.join(GBConfigService.get('STORAGE_LIBRARY'), path1); server.setFileSystem(virtualPath, new webdav.PhysicalFileSystem(gbaiRoot), successed => { GBLogEx.info(min.instance.instanceId, `WebDav online for ${min.botId}...`); diff --git a/packages/kb.gbapp/services/KBService.ts b/packages/kb.gbapp/services/KBService.ts index 4b904143..f19fbd4d 100644 --- a/packages/kb.gbapp/services/KBService.ts +++ b/packages/kb.gbapp/services/KBService.ts @@ -654,8 +654,19 @@ export class KBService implements IGBKBService { await this.playAudio(min, answer, channel, step, min.conversationalService); } else if (answer.startsWith('![')) { - const url = answer.match(/\((.*?)\)/)[1]; - await this.showImage(min, min.conversationalService, step, url, channel) + // Checks for text after the image markdown. + + const hasText = answer.split(/!\[.*?\]\(.*?\)(.*)/)[3]; + + if (hasText) { + await min.conversationalService.sendText(min, step, answer); + } + else{ + const urlMatch = answer.match(/!?\[.*?\]\((.*?)\)/); + const url = urlMatch ? urlMatch[1] : null; + await this.showImage(min, min.conversationalService, step, url, channel) + } + } else { await min.conversationalService.sendText(min, step, answer); } @@ -697,6 +708,7 @@ export class KBService implements IGBKBService { packageStorage: GuaribasPackage, instance: IGBInstance ): Promise { + // Imports subjects tree into database and return it. const subjectFile = urlJoin(localPath, 'subjects.json'); @@ -1126,7 +1138,7 @@ export class KBService implements IGBKBService { } files = await walkPromise(urlJoin(localPath, 'docs')); - + if (files[0]) { GBLogEx.info(min, `Add embeddings from .gbkb: ${files.length}}...`); await CollectionUtil.asyncForEach(files, async file => { @@ -1138,8 +1150,9 @@ export class KBService implements IGBKBService { await min['vectorStore'].addDocuments(flattenedDocuments); }); } - await min['vectorStore'].save(min['vectorStorePath']); - + if (min['vectorStore']) { + await min['vectorStore'].save(min['vectorStorePath']); + } } diff --git a/packages/llm.gblib/services/ChatServices.ts b/packages/llm.gblib/services/ChatServices.ts index f67f0c75..809b36c3 100644 --- a/packages/llm.gblib/services/ChatServices.ts +++ b/packages/llm.gblib/services/ChatServices.ts @@ -475,9 +475,9 @@ export class ChatServices { return chat_history; }, context: (async (output: string) => { - const c = await ChatServices.getRelevantContext(this['vectorStore'], output); + const c = await ChatServices.getRelevantContext(min['vectorStore'], output); return `${systemPrompt} \n ${c ? 'Use this context to answer:\n' + c : 'answer just with user question.'}`; - }).bind(min) + }) }, combineDocumentsPrompt, model, diff --git a/src/app.ts b/src/app.ts index d0daea0a..8da1d72b 100644 --- a/src/app.ts +++ b/src/app.ts @@ -365,7 +365,7 @@ export class GBServer { .readFile(path.join(swaggerUiAssetPath, 'swagger-initializer.js')) .toString() .replace('https://petstore.swagger.io/v2/swagger.json', `/${SWAGGER_FILE_NAME}`); - app.get(`${ENDPOINT}/swagger-initializer.js`, (req, res) => res.send(indexContent)); + app.get(`${ENDPOINT}/swagger-initializer.js`, (req, res) => res.send(indexContent) as any); // Serve the swagger-ui assets app.use(ENDPOINT, express.static(swaggerUiAssetPath));