new(all): Alpha Word Debugger for 3.0.

This commit is contained in:
rodrigorodriguez 2022-11-12 17:17:14 -03:00
parent c954786efb
commit 79f77b528d
5 changed files with 103 additions and 43 deletions

26
package-lock.json generated
View file

@ -1,12 +1,12 @@
{
"name": "botserver",
"version": "2.0.178",
"version": "3.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "botserver",
"version": "2.0.178",
"version": "3.0.0",
"license": "AGPL-3.0",
"dependencies": {
"@azure/cognitiveservices-computervision": "8.1.0",
@ -59,6 +59,8 @@
"google-libphonenumber": "3.2.21",
"googleapis": "75.0.0",
"ibm-watson": "6.1.1",
"indent": "^0.0.2",
"indent.js": "^0.3.5",
"js-beautify": "1.13.13",
"keyv": "^4.5.0",
"koa": "^2.13.4",
@ -16295,6 +16297,11 @@
"node": ">=0.8.19"
}
},
"node_modules/indent": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/indent/-/indent-0.0.2.tgz",
"integrity": "sha512-/F1w9/msSQCfXDTvEU8rKBObcv4cBN6m8hujC/zwVc8vOuf4b76AwBVGChbg+3o0M3kp1XDjoMDQR5Nh6SAHfA=="
},
"node_modules/indent-string": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
@ -16303,6 +16310,11 @@
"node": ">=8"
}
},
"node_modules/indent.js": {
"version": "0.3.5",
"resolved": "https://registry.npmjs.org/indent.js/-/indent.js-0.3.5.tgz",
"integrity": "sha512-wiTA5fEz0kc8tHzY6CSujl/k62WVNvTxAZzmPe5V7MYxRCeGGibPCIYWYBzPp/bcJh3CXUO/8qrTrO/x9s1i2Q=="
},
"node_modules/indexes-of": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz",
@ -47128,11 +47140,21 @@
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
"integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="
},
"indent": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/indent/-/indent-0.0.2.tgz",
"integrity": "sha512-/F1w9/msSQCfXDTvEU8rKBObcv4cBN6m8hujC/zwVc8vOuf4b76AwBVGChbg+3o0M3kp1XDjoMDQR5Nh6SAHfA=="
},
"indent-string": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
"integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg=="
},
"indent.js": {
"version": "0.3.5",
"resolved": "https://registry.npmjs.org/indent.js/-/indent.js-0.3.5.tgz",
"integrity": "sha512-wiTA5fEz0kc8tHzY6CSujl/k62WVNvTxAZzmPe5V7MYxRCeGGibPCIYWYBzPp/bcJh3CXUO/8qrTrO/x9s1i2Q=="
},
"indexes-of": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz",

View file

@ -99,6 +99,7 @@
"google-libphonenumber": "3.2.21",
"googleapis": "75.0.0",
"ibm-watson": "6.1.1",
"indent.js": "^0.3.5",
"js-beautify": "1.13.13",
"keyv": "^4.5.0",
"koa": "^2.13.4",

View file

@ -45,6 +45,7 @@ const Koa = require('koa');
import * as koaBody from "koa-body"
import { SystemKeywords } from './services/SystemKeywords';
import { WebAutomationKeywords } from './services/WebAutomationKeywords';
import { DebuggerService } from './services/DebuggerService';
const app = new Koa()
/**
@ -80,14 +81,17 @@ export class GBBasicPackage implements IGBPackage {
public async loadBot(min: GBMinInstance): Promise<void> {
const dk = new DialogKeywords(min, null, null);
const wa = new WebAutomationKeywords(min, null, dk);
const sys = new SystemKeywords(min, null, dk, wa)
const sys = new SystemKeywords(min, null, dk, wa);
const dbg = new DebuggerService(min, null, dk);
dk.wa = wa;
wa.sys = sys;
const dialogRouter = createServerRouter(`/api/v2/${min.botId}/dialog`, dk);
const waRouter = createServerRouter(`/api/v2/${min.botId}/webautomation`, wa );
const sysRouter = createServerRouter(`/api/v2/${min.botId}/system`, sys);
const dbgRouter = createServerRouter(`/api/v2/${min.botId}/debugger`, dbg);
app.use(dialogRouter.routes());
app.use(sysRouter.routes());
app.use(waRouter.routes());
app.use(dbgRouter.routes());
}
}

View file

@ -89,7 +89,10 @@ export class DebuggerService {
*/
maxLines: number = 2000;
pageMap = {};
debugMap = {};
conversationsMap = {};
scopeMap = {};
watermarkMap = {};
/**
* When creating this keyword facade,a bot instance is
@ -109,7 +112,7 @@ export class DebuggerService {
private client;
public async setBreakPoint({ botId, botApiKey, line }) {
public async setBreakpoint({ botId, botApiKey, line }) {
const client = GBServer.globals.debuggers[botId];
@ -126,7 +129,7 @@ export class DebuggerService {
const { breakpointId } = await await client.Debugger.setBreakpoint({
location: {
scriptId,
lineNumber: 6 - 1 // (zero-based)
lineNumber: line - 1
}
});
}
@ -135,37 +138,64 @@ export class DebuggerService {
}
public async continue({ botId, botApiKey, force }) {
public async continueRun({ botId, botApiKey, force }) {
const client = GBServer.globals.debuggers[botId];
client.Debugger.resume();
}
public async stopDebug({ botId, botApiKey, force }) {
public async stop({ botId, botApiKey, force }) {
const client = GBServer.globals.debuggers[botId];
client.close();
}
public async stepOver({ botId, botApiKey, force }) {
public async stepOver({ botId, botApiKey }) {
const client = GBServer.globals.debuggers[botId];
client.stepOver();
}
public async getExecutionContext({ botId, botApiKey, force }) {
const client = GBServer.globals.debuggers[botId];
const conversationId = this.conversationsMap[botId];
public async startDebug({ botId, botApiKey, scriptName }) {
const response = await client.Conversations.Conversations_GetActivities({
conversationId: conversationId,
watermark: this.watermarkMap[botId]
});
this.watermarkMap[botId] = response.obj.watermark;
let activities = response.obj.activites;
let messages = [];
if (activities && activities.length) {
activities = activities.filter(m => m.from.id === botId && m.type === 'message');
if (activities.length) {
activities.forEach(activity => {
messages.push({ text: activity.text });
GBLog.info(`GBDEBUG: SND TO WORD ${activity.text}`);
});
}
}
return { state:this.debugMap[botId].state, messages, scope: this.scopeMap[botId] };
}
// TODO : Map this.
let webchatKey = null;
public async run({ botId, botApiKey, scriptName }) {
this.debugMap[botId] = { state: 1 };
let min: GBMinInstance = GBServer.globals.minInstances.filter(
p => p.instance.botId === botId
)[0];
this.client = await new Swagger({
spec: JSON.parse(fs.readFileSync('directline-3.0.json', 'utf8')), usePromise: true
});
this.client.clientAuthorizations.add(
'AuthorizationBotConnector',
new Swagger.ApiKeyAuthorization('Authorization', `Bearer ${webchatKey}`, 'header')
new Swagger.ApiKeyAuthorization('Authorization', `Bearer ${min.instance.webchatKey}`, 'header')
);
const response = await this.client.Conversations.Conversations_StartConversation();
const conversationId = response.obj.conversationId;
this.conversationsMap[botId] = conversationId;
GBServer.globals.debugConversationId = conversationId;
this.client.Conversations.Conversations_PostActivity({
@ -184,21 +214,24 @@ export class DebuggerService {
// Setup debugger.
const client = GBServer.globals.debuggers[botId];
client.Debugger.paused(({ callFrames, reason, hitBreakpoints }) => {
if (hitBreakpoints.length>1)
{
GBLog.info(`.gbdialog break at line ${callFrames[0].location.lineNumber + 1}`); // (zero-based)
const frame = callFrames[0];
if (hitBreakpoints.length > 1) {
GBLog.info(`.gbdialog break at line ${frame.location.lineNumber + 1}`); // (zero-based)
const scope = `${frame.scopeChain[0].name} ${frame.scopeChain[0].object}`;
this.scopeMap[botId] = scope;
}
else (reason === ''){
GBLog.info(`.gbdialog ${reason} at line ${callFrames[0].location.lineNumber + 1}`); // (zero-based)
else if (reason === ''){
GBLog.info(`.gbdialog ${reason} at line ${frame.location.lineNumber + 1}`); // (zero-based)
}
});
await client.Runtime.runIfWaitingForDebugger();
await client.Debugger.enable();
await client.Debugger.setPauseOnExceptions('all');
}
}

View file

@ -49,7 +49,7 @@ const textract = require('textract');
const walkPromise = require('walk-promise');
const child_process = require('child_process');
const Path = require('path');
const indent = require('indent.js');
/**
* @fileoverview Decision was to priorize security(isolation) and debugging,
* over a beautiful BASIC transpiler (to be done).
@ -200,9 +200,12 @@ export class GBVMService extends GBService {
}
} while (include);
const vbsCode = await this.convertGBASICToVBS(min, basicCode);
const [vbsCode, jsonMap] = await this.convertGBASICToVBS(min, basicCode);
const vbsFile = `${filename}.compiled`;
const mapFile = `${filename}.map`;
fs.writeFileSync(vbsFile, vbsCode);
fs.writeFileSync(mapFile, JSON.stringify(jsonMap));
// Converts VBS into TS.
@ -226,7 +229,6 @@ export class GBVMService extends GBService {
code.replace(/^.*exports.*$/gm, '');
code = `
return (async () => {
require('isomorphic-fetch');
const rest = require ('typescript-rest-rpc/lib/client');
@ -272,14 +274,10 @@ export class GBVMService extends GBService {
})();
`;
// Finds all hear calls.
const parsedCode = beautify(code, { indent_size: 2, space_in_empty_paren: true, preserve_newlines: true, wrap_line_length: 240 });
fs.writeFileSync(jsfile, parsedCode);
min.sandBoxMap[mainName.toLowerCase().trim()] = parsedCode;
GBLog.info(`[GBVMService] Finished loading of ${filename}, JavaScript from Word: \n ${parsedCode}`);
code = indent.js(code, {tabString: '\t'});
fs.writeFileSync(jsfile, code);
min.sandBoxMap[mainName.toLowerCase().trim()] = code;
GBLog.info(`[GBVMService] Finished loading of ${filename}, JavaScript from Word: \n ${code}`);
}
}
@ -363,22 +361,24 @@ export class GBVMService extends GBService {
`;
var matchingLines = [];
var allLines = code.split("\n");
const keywords = this.getKeywords();
const offset = 37;
const jsonMap = {};
for (var i = 0; i < allLines.length; i++) {
if (allLines[i].match(pattern)) {
matchingLines.push(i);
for (var j = 0; j < keywords.length; j++) {
allLines[i] = allLines[i].replace(keywords[j][0], keywords[j][1]);
// Add additional lines returned from replacement.
let add = allLines[i].split(/\r\n|\r|\n/).length;
jsonMap[i] = (offset + i) + (add ? add : 0);
}
}
return matchingLines;
code = `${code}\n%>`;
return code;
code = `${allLines.join('\n')}\n%>`;
return [code, jsonMap];
}
private getKeywords() {
@ -513,7 +513,7 @@ export class GBVMService extends GBService {
}];
keywords[i++] = [/^\s*(wait)\s*(\d+)/gim, ($0, $1, $2) => {
return `await sys.wait({seconds:${$2})`;
return `await sys.wait({seconds:${$2}})`;
}];
keywords[i++] = [/^\s*(get stock for )(.*)/gim, ($0, $1, $2) => {