Skip to content

Latest commit

 

History

History
220 lines (182 loc) · 7.19 KB

wozgraph.md

File metadata and controls

220 lines (182 loc) · 7.19 KB

WozGraph

ask nodes (prompts)

  • avoid using question marks (?). They confuse the ESML engine and trigger random animations.
  • when using an ask node, Jibo (the robot) will render the given prompt via TTS and then use cloud NLU to process the spoken answer (the user's utterance). If the NLU results contain a valid intent, outgoing links from the ask node will be analyzed. If an outgoing link is labeled with the NLU intent (i.e. launchItsMe) the node pointed to by that link will be executed automatically. For example:

node(type:ask, name: Init Game) -[gameCommand]-> node(type:esml, name: Good)

node(type:ask, name: Init Game)

name: Init
scriptName: initGame
prompt: OK. Let's get started ${player.name}, ${game.setting}, ${game.prompt}
context: gameCommands
  • Note: the context property is passed to dialogflow (google NLU). In this case, the gameCommands context lets dialogflow know that the utterance's intent should be a game command. The NLU entity will indicate which command was uttered (i.e. continue or quit).
  • If the resulting NLU intent is gameCommand the next node will be executed automatically.

scripts

From GraphEditor: executeNode - handling of the scriptContext property

/** script execution **/
// if the node has a valid scriptName property, execute that script
// if the node has a valid scriptContext property, execute the script using that data as context
// otherwise execute the script using the active robot's stateData as context ()
let scriptName: string = node.properties.has('scriptName');
let scriptContext: any = node.properties.has('scriptContext');
let scriptData: any;
if (scriptContext) {
    try {
        scriptData = jsonic(scriptContext);
    } catch (err) {
        console.log(`GraphEditor: executeNode: error: `, err);
    }
}
executeScriptWithName(scriptName: string, robot?: Robot): any {
    let result: any = undefined;
    if (this.activeGraph) {
        let scriptConfig: ScriptConfig = this.activeGraph.scriptConfig;
        console.log(`GraphModel: executeScriptWithName: scriptConfig:`, scriptConfig);
        let savedScript: SavedScript | undefined = scriptConfig.getSavedScriptWithName(scriptName);
        if (savedScript) {
            result = this.executeScript(savedScript, robot);
        } else {
            console.log(`executeScriptWithName: error: no script found with name: ${scriptName}`);
        }
    }
    return result;
}
executeScript(activeScript: SavedScript, robot?: Robot, data?: any): any {
    console.log(`GraphModel: executeScript:`, activeScript, robot, data);
    let output: any = undefined;
    if (robot) {
        output = this.evaluateScriptWithData(activeScript.script, robot.stateData);
    } else {
        if (!data) {
            data = this._globalStateData;
        }
        output = this.evaluateScriptWithData(activeScript.script, data);
    }
    console.log(`GraphModel: executeScript: output:`, output);
    return output;
}
evaluateScriptWithData(scriptText: string, scriptData: any): string {
    let scriptDataSandbox:any;
    scriptDataSandbox = this.getSandbox(scriptData);
    try { //do a safe eval on the condition
        return vm.runInContext(scriptText, scriptDataSandbox);
    } catch (e) {
        console.log(`evaluateScriptWithData: error evaluating: ${scriptText}: ${scriptData} - error: ${e.message}`);
        return '';
    }
}
getSandbox(promptData:any): any {
    return vm.createContext(promptData);
}

script examples

name: initGame
script:
if (!initialized) {
  var game = {};
  game.setting = "You are at the entrance to a mysterious valley";
  game.prompt = "Will you continue or quit";
  if (!player) {
    var player = {name: "", inventory: []};
  }
  var initialized = true;
}
name: getPlayer
script:
if (!player) {
  var player = {name: "", inventory: []};
}
if (user && user != "Someone") {
  player.name = user;
}
name: getGameCommand
script:
if (gameCommand) {
  game.command = gameCommand;
} else {
  game.command = "";
}

usage

node(type:launch) -[launchItsMe]-> node(type: esml, name: Greeting)

node(type: esml, name: Greeting)

name: Greeting
scriptName: getPlayer
prompt: Hi ${player.name}. Would you like to play a game

robotCommand scripts

if (!robotCommand) {
  var robotCommand = {type: "", data: {}};
}
if (!imageUrl) {
  var imageUrl = "http://cookstreetvillageactivitycentre.com/wp-content/uploads/2017/12/Morning-Yoga.jpg";
}
robotCommand = {type:"image", data:{ name:"image",url:imageUrl}}
if (!robotCommand) {
  var robotCommand = {type: "", data: {}};
}
robotCommand = {type:"eye", data:{}}

ESML nodes - special OK 'intent'

When TTS/ESML nodes have an outgoing OK intent, the connected node is automatically exeuted.

name: Greeting
scriptName: getPlayer
prompt: Hi ${player.name}. It's nice to see you.

scriptContext example

Note: when executed, the script uses the scriptContext and returns a context with robotCommand defined as {type:"image", data:{ name:"image",url:imageUrl}}. So, robotCommand gets sent to the robot.

name: script command
scriptName: yogaImage
scriptContext: {imageUrl:http://robocommander.io/img/RoboCommander.png}

yogaImage script

if (!robotCommand) {
  var robotCommand = {type: "", data: {}};
}
if (!imageUrl) {
  var imageUrl = "http://cookstreetvillageactivitycentre.com/wp-content/uploads/2017/12/Morning-Yoga.jpg";
}
robotCommand = {type:"image", data:{ name:"image",url:imageUrl}}