new(gpt.gblib): PDF opener.
This commit is contained in:
		
							parent
							
								
									51107fcd76
								
							
						
					
					
						commit
						4342c6d3e5
					
				
					 4 changed files with 171 additions and 34 deletions
				
			
		| 
						 | 
					@ -33,6 +33,7 @@ import GBMarkdownPlayer from './players/GBMarkdownPlayer.js';
 | 
				
			||||||
import GBImagePlayer from './players/GBImagePlayer.js';
 | 
					import GBImagePlayer from './players/GBImagePlayer.js';
 | 
				
			||||||
import GBVideoPlayer from './players/GBVideoPlayer.js';
 | 
					import GBVideoPlayer from './players/GBVideoPlayer.js';
 | 
				
			||||||
import GBUrlPlayer from './players/GBUrlPlayer.js';
 | 
					import GBUrlPlayer from './players/GBUrlPlayer.js';
 | 
				
			||||||
 | 
					import GBMultiUrlPlayer from './players/GBMultiUrlPlayer.js';
 | 
				
			||||||
import GBLoginPlayer from './players/GBLoginPlayer.js';
 | 
					import GBLoginPlayer from './players/GBLoginPlayer.js';
 | 
				
			||||||
import GBBulletPlayer from './players/GBBulletPlayer.js';
 | 
					import GBBulletPlayer from './players/GBBulletPlayer.js';
 | 
				
			||||||
import SidebarMenu from './components/SidebarMenu.js';
 | 
					import SidebarMenu from './components/SidebarMenu.js';
 | 
				
			||||||
| 
						 | 
					@ -255,7 +256,17 @@ class GBUIApp extends React.Component {
 | 
				
			||||||
            />
 | 
					            />
 | 
				
			||||||
          );
 | 
					          );
 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
        case 'image':
 | 
					        case 'multiurl':
 | 
				
			||||||
 | 
					            playerComponent = (
 | 
				
			||||||
 | 
					              <GBMultiUrlPlayer
 | 
				
			||||||
 | 
					                app={this}
 | 
				
			||||||
 | 
					                ref={player => {
 | 
				
			||||||
 | 
					                  this.player = player;
 | 
				
			||||||
 | 
					                }}
 | 
				
			||||||
 | 
					              />
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 'image':
 | 
				
			||||||
          playerComponent = (
 | 
					          playerComponent = (
 | 
				
			||||||
            <GBImagePlayer
 | 
					            <GBImagePlayer
 | 
				
			||||||
              app={this}
 | 
					              app={this}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										91
									
								
								packages/default.gbui/src/players/GBMultiUrlPlayer.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								packages/default.gbui/src/players/GBMultiUrlPlayer.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,91 @@
 | 
				
			||||||
 | 
					/*****************************************************************************\
 | 
				
			||||||
 | 
					|  █████  █████ ██    █ █████ █████   ████  ██      ████   █████ █████  ███ ® |
 | 
				
			||||||
 | 
					| ██      █     ███   █ █     ██  ██ ██  ██ ██      ██  █ ██   ██  █   █      |
 | 
				
			||||||
 | 
					| ██  ███ ████  █ ██  █ ████  █████  ██████ ██      ████   █   █   █    ██    |
 | 
				
			||||||
 | 
					| ██   ██ █     █  ██ █ █     ██  ██ ██  ██ ██      ██  █ ██   ██  █      █   |
 | 
				
			||||||
 | 
					|  █████  █████ █   ███ █████ ██  ██ ██  ██ █████   ████   █████   █   ███    |
 | 
				
			||||||
 | 
					|                                                                             |
 | 
				
			||||||
 | 
					| General Bots Copyright (c) pragmatismo.com.br. All rights reserved.         |
 | 
				
			||||||
 | 
					| Licensed under the AGPL-3.0.                                                |
 | 
				
			||||||
 | 
					|                                                                             |
 | 
				
			||||||
 | 
					| According to our dual licensing model, this program can be used either      |
 | 
				
			||||||
 | 
					| under the terms of the GNU Affero General Public License, version 3,        |
 | 
				
			||||||
 | 
					| or under a proprietary license.                                             |
 | 
				
			||||||
 | 
					|                                                                             |
 | 
				
			||||||
 | 
					| The texts of the GNU Affero General Public License with an additional       |
 | 
				
			||||||
 | 
					| permission and of our proprietary license can be found at and               |
 | 
				
			||||||
 | 
					| in the LICENSE file you have received along with this program.              |
 | 
				
			||||||
 | 
					|                                                                             |
 | 
				
			||||||
 | 
					| This program is distributed in the hope that it will be useful,             |
 | 
				
			||||||
 | 
					| but WITHOUT ANY WARRANTY; without even the implied warranty of              |
 | 
				
			||||||
 | 
					| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the                |
 | 
				
			||||||
 | 
					| GNU Affero General Public License for more details.                         |
 | 
				
			||||||
 | 
					|                                                                             |
 | 
				
			||||||
 | 
					| "General Bots" is a registered trademark of pragmatismo.com.br.             |
 | 
				
			||||||
 | 
					| The licensing of the program under the AGPLv3 does not imply a              |
 | 
				
			||||||
 | 
					| trademark license. Therefore any rights, title and interest in              |
 | 
				
			||||||
 | 
					| our trademarks remain entirely with us.                                     |
 | 
				
			||||||
 | 
					|                                                                             |
 | 
				
			||||||
 | 
					\*****************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import React, { Component } from 'react';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class RenderItem extends Component {
 | 
				
			||||||
 | 
					  send(item) {
 | 
				
			||||||
 | 
					    setTimeout(() => {
 | 
				
			||||||
 | 
					      window.botConnection.postActivity({
 | 
				
			||||||
 | 
					        type: 'event',
 | 
				
			||||||
 | 
					        name: 'answerEvent',
 | 
				
			||||||
 | 
					        data: item.questionId,
 | 
				
			||||||
 | 
					        locale: 'en-us',
 | 
				
			||||||
 | 
					        textFormat: 'plain',
 | 
				
			||||||
 | 
					        timestamp: new Date().toISOString(),
 | 
				
			||||||
 | 
					        from: window.user
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    }, 400);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  render() {
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					      <div className="gb-video-player-wrapper">
 | 
				
			||||||
 | 
					        {this.props.list.map(item => (
 | 
				
			||||||
 | 
					          <iframe
 | 
				
			||||||
 | 
					            title="Video"
 | 
				
			||||||
 | 
					            ref="video"
 | 
				
			||||||
 | 
					            className="gb-video-react-player"
 | 
				
			||||||
 | 
					            src={item.url}
 | 
				
			||||||
 | 
					            width="100%"
 | 
				
			||||||
 | 
					            height="100%"
 | 
				
			||||||
 | 
					          />
 | 
				
			||||||
 | 
					        ))}
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class GBMultiUrlPlayer extends Component {
 | 
				
			||||||
 | 
					  constructor() {
 | 
				
			||||||
 | 
					    super();
 | 
				
			||||||
 | 
					    this.state = {
 | 
				
			||||||
 | 
					      list: []
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  play(data) {
 | 
				
			||||||
 | 
					    this.setState({ list: data });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  stop() {
 | 
				
			||||||
 | 
					    this.setState({ list: [] });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  render() {
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					      <div className="gb-bullet-player" ref={i => (this.playerText = i)}>
 | 
				
			||||||
 | 
					        <RenderItem app={this.props.app} list={this.state.list} ref={i => (this.playerList = i)} />
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default GBMultiUrlPlayer;
 | 
				
			||||||
| 
						 | 
					@ -130,18 +130,37 @@ export class GBLLMOutputParser extends
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let res;
 | 
					    let res;
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
 | 
					      GBLogEx.info(this.min, result);
 | 
				
			||||||
      result = result.replace(/\\n/g, '');
 | 
					      result = result.replace(/\\n/g, '');
 | 
				
			||||||
      res = JSON.parse(result);
 | 
					      res = JSON.parse(result);
 | 
				
			||||||
    } catch {
 | 
					    } catch {
 | 
				
			||||||
      return result;
 | 
					      return result;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let { file, page, text } = res;
 | 
					    let { sources, text } = res;
 | 
				
			||||||
    const { url } = await ChatServices.pdfPageAsImage(this.min, file, page);
 | 
					    
 | 
				
			||||||
    text = `
 | 
					    await CollectionUtil.asyncForEach(sources, async (source) => {
 | 
				
			||||||
      ${text}`;
 | 
					      let found = false;
 | 
				
			||||||
 | 
					      if (source) {
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        const gbaiName = DialogKeywords.getGBAIPath(this.min.botId, 'gbkb');
 | 
				
			||||||
 | 
					        const localName = Path.join('work', gbaiName, 'docs', source.file);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return {text, file, page};
 | 
					        if (localName) {
 | 
				
			||||||
 | 
					          const { url } = await ChatServices.pdfPageAsImage(this.min, localName, source.page);
 | 
				
			||||||
 | 
					          text = `
 | 
				
			||||||
 | 
					          ${text}`;
 | 
				
			||||||
 | 
					          found = true;
 | 
				
			||||||
 | 
					          source.file = localName;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (found) {
 | 
				
			||||||
 | 
					        GBLogEx.info(this.min, `File not found referenced in other .pdf: ${source.file}`);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return { text, sources };
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -149,13 +168,10 @@ export class ChatServices {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public static async pdfPageAsImage(min, filename, pageNumber) {
 | 
					  public static async pdfPageAsImage(min, filename, pageNumber) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const gbaiName = DialogKeywords.getGBAIPath(min.botId, 'gbkb');
 | 
					 | 
				
			||||||
    const localName = Path.join('work', gbaiName, 'docs', filename);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Converts the PDF to PNG.
 | 
					    // Converts the PDF to PNG.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    GBLogEx.info(min, `Converting ${filename}, page: ${pageNumber}...`);
 | 
					    GBLogEx.info(min, `Converting ${filename}, page: ${pageNumber}...`);
 | 
				
			||||||
    const pngPages: PngPageOutput[] = await pdfToPng(localName, {
 | 
					    const pngPages: PngPageOutput[] = await pdfToPng(filename, {
 | 
				
			||||||
      disableFontFace: true,
 | 
					      disableFontFace: true,
 | 
				
			||||||
      useSystemFonts: true,
 | 
					      useSystemFonts: true,
 | 
				
			||||||
      viewportScale: 2.0,
 | 
					      viewportScale: 2.0,
 | 
				
			||||||
| 
						 | 
					@ -187,19 +203,27 @@ export class ChatServices {
 | 
				
			||||||
      return '';
 | 
					      return '';
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const documents = await vectorStore.similaritySearch(sanitizedQuestion, numDocuments);
 | 
					    let documents = await vectorStore.similaritySearch(sanitizedQuestion, numDocuments);
 | 
				
			||||||
 | 
					    const uniqueDocuments = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (const document of documents) {
 | 
				
			||||||
 | 
					      if (!uniqueDocuments[document.metadata.source]) {
 | 
				
			||||||
 | 
					        uniqueDocuments[document.metadata.source] = document;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let output = '';
 | 
					    let output = '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    await CollectionUtil.asyncForEach(documents, async (doc) => {
 | 
					    for(const filePaths of Object.keys(uniqueDocuments)) {
 | 
				
			||||||
 | 
					      const doc = uniqueDocuments[filePaths];
 | 
				
			||||||
      const metadata = doc.metadata;
 | 
					      const metadata = doc.metadata;
 | 
				
			||||||
      const filename = Path.basename(metadata.source);
 | 
					      const filename = Path.basename(metadata.source);
 | 
				
			||||||
      const page = await ChatServices.findPageForText(doc.metadata.source,
 | 
					      const page = await ChatServices.findPageForText(metadata.source,
 | 
				
			||||||
        doc.pageContent);
 | 
					        doc.pageContent);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      output = `${output}\n\n\n\nThe following context is coming from ${filename} at page: ${page}, 
 | 
					      output = `${output}\n\n\n\nThe following context is coming from ${filename} at page: ${page}, 
 | 
				
			||||||
      memorize this block among document information and return when you are refering this part of content:\n\n\n\n ${doc.pageContent} \n\n\n\n.`;
 | 
					      memorize this block among document information and return when you are refering this part of content:\n\n\n\n ${doc.pageContent} \n\n\n\n.`;
 | 
				
			||||||
    });
 | 
					    }
 | 
				
			||||||
    return output;
 | 
					    return output;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -217,7 +241,7 @@ export class ChatServices {
 | 
				
			||||||
      if (text.includes(searchText)) return i;
 | 
					      if (text.includes(searchText)) return i;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return -1; 
 | 
					    return -1;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
| 
						 | 
					@ -314,12 +338,13 @@ export class ChatServices {
 | 
				
			||||||
        \n\n{context}\n\n
 | 
					        \n\n{context}\n\n
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        And based on \n\n{chat_history}\n\n
 | 
					        And based on \n\n{chat_history}\n\n
 | 
				
			||||||
        rephrase the response to the user using the aforementioned context. If you're unsure of the answer, utilize any relevant context provided to answer the question effectively. Don´t output MD images tags url previously shown.
 | 
					        rephrase the response to the user using the aforementioned context. If you're unsure of the answer, 
 | 
				
			||||||
 | 
					        utilize any relevant context provided to answer the question effectively. Don´t output MD images tags url previously shown.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        VERY IMPORTANT: ALWAYS return VALID standard JSON with the folowing structure: 'text' as answer, 
 | 
					        VERY IMPORTANT: ALWAYS return VALID standard JSON with the folowing structure: 'text' as answer, 
 | 
				
			||||||
          'file' indicating the PDF filename and 'page' indicating the page number. 
 | 
					          sources as an array of ('file' indicating the PDF filename and 'page' indicating the page number) listing all segmented context. 
 | 
				
			||||||
        Example JSON format: "text": "this is the answer, anything LLM output as text answer shoud be here.", 
 | 
					        Example JSON format: "text": "this is the answer, anything LLM output as text answer shoud be here.", 
 | 
				
			||||||
          "file": "filename.pdf", "page": 3,
 | 
					          "sources": [{{"file": "filename.pdf", "page": 3}}, {{"file": "filename2.pdf", "page": 1}}],
 | 
				
			||||||
         return valid JSON with brackets. Avoid explaining the context directly
 | 
					         return valid JSON with brackets. Avoid explaining the context directly
 | 
				
			||||||
          to the user; instead, refer to the document source. 
 | 
					          to the user; instead, refer to the document source. 
 | 
				
			||||||
          
 | 
					          
 | 
				
			||||||
| 
						 | 
					@ -384,7 +409,7 @@ export class ChatServices {
 | 
				
			||||||
      new StringOutputParser()
 | 
					      new StringOutputParser()
 | 
				
			||||||
    ]);
 | 
					    ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let result;
 | 
					    let result, sources;
 | 
				
			||||||
    let text, file, page;
 | 
					    let text, file, page;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -401,8 +426,9 @@ export class ChatServices {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else if (LLMMode === "document") {
 | 
					    else if (LLMMode === "document") {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      const {text, file, page} = await combineDocumentsChain.invoke(question);
 | 
					      const res = await combineDocumentsChain.invoke(question);
 | 
				
			||||||
      result = text;
 | 
					      result = res.text;
 | 
				
			||||||
 | 
					      sources = res.sources;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    } else if (LLMMode === "function") {
 | 
					    } else if (LLMMode === "function") {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -429,7 +455,7 @@ export class ChatServices {
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    GBLog.info(`GPT Result: ${result.toString()}`);
 | 
					    GBLog.info(`GPT Result: ${result.toString()}`);
 | 
				
			||||||
    return { answer: result.toString(), file, questionId: 0, page };
 | 
					    return { answer: result.toString(), sources, questionId: 0, page };
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private static getToolsAsText(tools) {
 | 
					  private static getToolsAsText(tools) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -49,6 +49,7 @@ import { GBDeployer } from '../../core.gbapp/services/GBDeployer.js';
 | 
				
			||||||
import urlJoin from 'url-join';
 | 
					import urlJoin from 'url-join';
 | 
				
			||||||
import { SystemKeywords } from '../../basic.gblib/services/SystemKeywords.js';
 | 
					import { SystemKeywords } from '../../basic.gblib/services/SystemKeywords.js';
 | 
				
			||||||
import { DialogKeywords } from '../../basic.gblib/services/DialogKeywords.js';
 | 
					import { DialogKeywords } from '../../basic.gblib/services/DialogKeywords.js';
 | 
				
			||||||
 | 
					import Path from 'path';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Dialog arguments.
 | 
					 * Dialog arguments.
 | 
				
			||||||
| 
						 | 
					@ -233,21 +234,29 @@ export class AskDialog extends IGBDialog {
 | 
				
			||||||
          return;
 | 
					          return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const results:any = await service.ask(min, user, step, step.context.activity['pid'], text, searchScore, null /* user.subjects */);
 | 
					        const results: any = await service.ask(min, user, step, step.context.activity['pid'], text, searchScore, null /* user.subjects */);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // If there is some result, answer immediately.
 | 
					        // If there is some result, answer immediately.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (results !== undefined && results.answer !== undefined) {
 | 
					        if (results !== undefined && results.answer !== undefined) {
 | 
				
			||||||
 | 
					          let urls = [];
 | 
				
			||||||
 | 
					          if (results.sources) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          if (results.file){
 | 
					            for (const key in results.sources) {
 | 
				
			||||||
            const path = DialogKeywords.getGBAIPath(min.botId, `gbkb`);
 | 
					              const source = results.sources[key];
 | 
				
			||||||
            const url = urlJoin('kb', path, 'docs', results.file);
 | 
					              const path = DialogKeywords.getGBAIPath(min.botId, `gbkb`);
 | 
				
			||||||
      
 | 
					              let url = urlJoin('kb', path, 'docs', Path.basename(source.file));
 | 
				
			||||||
            await min.conversationalService.sendEvent(
 | 
					              url = `${url}#page=${source.page}&toolbar=0&messages=0&statusbar=0&navpanes=0`;
 | 
				
			||||||
              min, step,  'play', {
 | 
					              urls.push({ url: url });
 | 
				
			||||||
                playerType: 'url',
 | 
					            }
 | 
				
			||||||
                data: `${url}#page=${results.page}&toolbar=0&messages=0&statusbar=0&navpanes=0`
 | 
					
 | 
				
			||||||
 | 
					            if (urls.length > 0) {
 | 
				
			||||||
 | 
					              await min.conversationalService.sendEvent(
 | 
				
			||||||
 | 
					                min, step, 'play', {
 | 
				
			||||||
 | 
					                playerType: 'multiurl',
 | 
				
			||||||
 | 
					                data: urls
 | 
				
			||||||
              });
 | 
					              });
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          // Sends the answer to all outputs, including projector.
 | 
					          // Sends the answer to all outputs, including projector.
 | 
				
			||||||
| 
						 | 
					@ -266,7 +275,7 @@ export class AskDialog extends IGBDialog {
 | 
				
			||||||
        const message = min.core.getParam<string>(min.instance, 'Not Found Message', Messages[locale].did_not_find);
 | 
					        const message = min.core.getParam<string>(min.instance, 'Not Found Message', Messages[locale].did_not_find);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        await min.conversationalService.sendText(min, step, message);
 | 
					        await min.conversationalService.sendText(min, step, message);
 | 
				
			||||||
        
 | 
					
 | 
				
			||||||
        return await step.replaceDialog('/ask', { isReturning: true });
 | 
					        return await step.replaceDialog('/ask', { isReturning: true });
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
| 
						 | 
					@ -287,7 +296,7 @@ export class AskDialog extends IGBDialog {
 | 
				
			||||||
      return await step.replaceDialog('/ask', { isReturning: true });
 | 
					      return await step.replaceDialog('/ask', { isReturning: true });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					
 | 
				
			||||||
  private static getChannel(step): string {
 | 
					  private static getChannel(step): string {
 | 
				
			||||||
    return !isNaN(step.context.activity['mobile']) ? 'whatsapp' : step.context.activity.channelId;
 | 
					    return !isNaN(step.context.activity['mobile']) ? 'whatsapp' : step.context.activity.channelId;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue