(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.jiboActionSystem = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o a.name)); let timeoutHandle; if (this.options.timeoutMs > 0) { const handler = () => this._cancel(Types_1.ActionResult.TIMEOUT); handler.isGlobalTimer = true; timeoutHandle = this.parent.jibo.timer.setTimeout(handler, this.options.timeoutMs); } const cleanup = () => { this.status = Types_1.ActionStatus.NOT_RUNNING; this._runResolve = null; if (timeoutHandle) { timeoutHandle.destroy(); } const ind = Action.active.indexOf(this); if (ind >= 0) { Action.active.splice(ind, 1); } }; return new Promise((resolve, reject) => { this._runResolve = resolve; this.runInternal().then(result => { this.status = Types_1.ActionStatus.NOT_RUNNING; this.log.debug('Completed with result: ', result); if (!this._isCanceling && this._runResolve) { this._runResolve(result); } }).catch(e => reject(e)); }).catch(e => { cleanup(); this.log.error('Error running: ', e); throw e; }).then(result => { cleanup(); return result; }); }); } runInternal() { return __awaiter(this, void 0, void 0, function* () { return Promise.resolve(Types_1.ActionResult.SUCCEEDED); }); } isEligible(state) { return true; } _cancel(result) { return __awaiter(this, void 0, void 0, function* () { if (!this._isCanceling && this._runResolve) { this._isCanceling = true; try { this.cancelInternal(); } catch (e) { this.log.error('Error canceling: ', e); } finally { this.status = Types_1.ActionStatus.NOT_RUNNING; this._isCanceling = false; if (this._runResolve) { this._runResolve(result); } } } }); } } Action.active = []; exports.Action = Action; },{"../common/Types":26,"../common/log":30,"jibo-cai-utils":undefined}],2:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const BasicPolicy_1 = require("./policies/BasicPolicy"); const MotivationGoal_1 = require("../goal/goals/MotivationGoal"); const Types_1 = require("../common/Types"); const _ = require("lodash/lodash.min"); const log_1 = require("./log"); const log = log_1.log.createChild('System'); class ActionSystem { constructor(parent) { this.parent = parent; this.actions = []; this.policy = new BasicPolicy_1.BasicPolicy(this.parent); } addAction(action) { log.debug(`adding action`, action.name); this.actions.push(action); } chooseAction(state, goal, eligibleActions) { const suggestedActionProvider = goal.options.action; if (suggestedActionProvider) { const suggestedAction = suggestedActionProvider(); if (suggestedAction.isEligible(state)) { return suggestedAction; } } const action = this.policy.selectAction(goal, state); if (action) { log.debug(`returning action`, action.name); return action; } if (!eligibleActions) { eligibleActions = this.actions.filter(a => a.isEligible(state)); log.debug(`eligible actions: `, eligibleActions.map(a => a.name)); } if (eligibleActions.length < 1) { log.debug(`no eligible actions`); } if (goal instanceof MotivationGoal_1.MotivationGoal) { let bestScore = 0; let bestActions = []; const dat = this.parent.motivations.drivesAboveThreshold(); for (let a of eligibleActions) { let score = 0; dat.forEach((d) => { score += a.getDriveEffect(Types_1.DriveName[d.name]) * d.value; }); if (score < bestScore) { bestActions = [a]; bestScore = score; } else if (Math.abs(score - bestScore) < 0.01) { bestActions.push(a); } } if (bestScore < 0) { return _.sample(bestActions); } } } } exports.ActionSystem = ActionSystem; },{"../common/Types":26,"../goal/goals/MotivationGoal":50,"./log":16,"./policies/BasicPolicy":17,"lodash/lodash.min":undefined}],3:[function(require,module,exports){ "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const Types_1 = require("../common/Types"); const log_1 = require("./log"); const log = log_1.log.createChild('GoalDrivenAction'); class GoalDrivenAction { constructor(goal, action, parent) { this.goal = goal; this.action = action; this.parent = parent; this.currentRunPromise = null; } run() { return __awaiter(this, void 0, void 0, function* () { const failed = () => { log.info(`Action: '${this.action.name}' failed'`); if (this.goal.attempts >= this.goal.options.maxAttempts) { this.goal.setFinishedStatus(Types_1.GoalFinishedStatus.FAILED); this.parent.goals.removeGoal(this.goal); } else { this.goal.setProgressStatus(Types_1.GoalProgressStatus.ATTEMPTED); } }; log.info(`Taking action: '${this.action.name}' to achieve goal '${this.goal.name}'`); this.goal.attempts++; this.currentRunPromise = this.action.run() .then(result => { log.info(`Completed action: '${this.action.name}' with result: '${result}'`); this.currentRunPromise = null; switch (result) { case Types_1.ActionResult.SUCCEEDED: this.goal.setFinishedStatus(Types_1.GoalFinishedStatus.SUCCEEDED); this.parent.motivations.applyMotivationalEffects(this.action); this.parent.goals.removeGoal(this.goal); break; case Types_1.ActionResult.TIMEOUT: case Types_1.ActionResult.CANCELED: case Types_1.ActionResult.FAILED: failed(); break; default: log.warn(`Action outcome '${result}' for action '${this.action.name}' unknown`); } return result; }).catch(error => { log.error(`Error running action ${this.action.name}: `, error); this.currentRunPromise = null; failed(); return Types_1.ActionResult.FAILED; }); return this.currentRunPromise; }); } } exports.GoalDrivenAction = GoalDrivenAction; },{"../common/Types":26,"./log":16}],4:[function(require,module,exports){ "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const Action_1 = require("../Action"); const Types_1 = require("../../common/Types"); const _ = require("lodash/lodash.min"); class AnimationAction extends Action_1.Action { constructor(parent, data, options, name = `Animation Action`) { super(parent, name, options); this.data = data; } runInternal() { return __awaiter(this, void 0, void 0, function* () { let anim; if (this.data.category) { const animRes = this.parent.jibo.animDB.query({ category: this.data.category, includeMeta: this.data.includeMeta || [], includeSomeMeta: this.data.includeSomeMeta || [], excludeMeta: this.data.excludeMeta || [] }); this.log.debug(`anims matching query: `, animRes.matching.map(a => a.name)); if (!animRes || animRes.matching.length === 0) { this.log.error(`Couldn't find animation with category:'${this.data.category} includeMeta:${this.data.includeMeta} includeSomeMeta:${this.data.includeSomeMeta} excludeMeta:${this.data.excludeMeta}.`); return Types_1.ActionResult.FAILED; } anim = _.sample(animRes.matching); } else if (this.data.name) { anim = this.parent.jibo.animDB.getAnimByName(this.data.name); if (!anim) { this.log.error(`No animation of name '${this.data.name}' found`); return Types_1.ActionResult.FAILED; } } else { this.log.error(`Invalid anim data`); return Types_1.ActionResult.FAILED; } const animConfig = { cache: this.parent.jibo.face.eye.CACHE_ID }; const Orientation = this.parent.jibo.animDB.Orientation; if (this.data.randomOrientation) { animConfig.orientation = (Math.random() > 0.5) ? Orientation.LEFT : Orientation.RIGHT; } if (this.data.muteAudio) { animConfig.mutes = { AUDIO: false, SCREEN: true, BODY: true }; } this.log.info(`AnimationAction playing animation of name: '${anim.name}', sampled from cat: '${this.data.category}', meta: '${this.data.includeMeta}'`); const playbackResult = anim.play(animConfig); this.instance = playbackResult.playback; yield playbackResult.result; this.instance = null; return Types_1.ActionResult.SUCCEEDED; }); } cancelInternal() { return __awaiter(this, void 0, void 0, function* () { if (this.instance) { this.instance.stop(); } }); } } exports.AnimationAction = AnimationAction; },{"../../common/Types":26,"../Action":1,"lodash/lodash.min":undefined}],5:[function(require,module,exports){ "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const Action_1 = require("../Action"); const Types_1 = require("../../common/Types"); class BasicLookat extends Action_1.Action { constructor(parent, location) { super(parent, 'Basic Lookat'); this.location = location; } cancelInternal() { return __awaiter(this, void 0, void 0, function* () { if (this._handle) { yield this._handle.cancel(); this._handle = null; } if (this._mode) { yield this._mode.release(); this._mode = null; } }); } runInternal() { return __awaiter(this, void 0, void 0, function* () { const expression = this.parent.jibo.expression; let result; try { this._mode = yield expression.pushAttentionMode(expression.AttentionMode.COMMAND); const pos = this.location; this._handle = yield expression.acquireTarget({ position: { x: pos.x, y: pos.y, z: Math.max(0.7, pos.z) } }); yield this._handle.promise; if (this._mode) { yield this._mode.release(); this._mode = null; } result = Types_1.ActionResult.SUCCEEDED; } catch (e) { this.log.error(`'${this.name}: error: '`, e); result = Types_1.ActionResult.FAILED; } this._handle = null; this.parent.events.oriented.emit(); return result; }); } } exports.BasicLookat = BasicLookat; },{"../../common/Types":26,"../Action":1}],6:[function(require,module,exports){ "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const Action_1 = require("../Action"); const Types_1 = require("../../common/Types"); class BeSkillSwitchAction extends Action_1.Action { constructor(parent, goalData) { super(parent, 'Be Skill Switch Action'); this.goalData = goalData; } runInternal() { return __awaiter(this, void 0, void 0, function* () { this.parent.currentSkillName = this.goalData.skillName; return Types_1.ActionResult.SUCCEEDED; }); } } exports.BeSkillSwitchAction = BeSkillSwitchAction; },{"../../common/Types":26,"../Action":1}],7:[function(require,module,exports){ "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const Action_1 = require("../Action"); const Types_1 = require("../../common/Types"); class EmitHeadPat extends Action_1.Action { constructor(parent, data) { super(parent, `Emit Head Pat Action`); this.data = data; } runInternal() { return __awaiter(this, void 0, void 0, function* () { this.parent.events.headPat.emit(this.data); return Types_1.ActionResult.SUCCEEDED; }); } } exports.EmitHeadPat = EmitHeadPat; },{"../../common/Types":26,"../Action":1}],8:[function(require,module,exports){ "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const Action_1 = require("../Action"); const jibo_state_machine_1 = require("jibo-state-machine"); const Types_1 = require("../../common/Types"); const EventWaiter_1 = require("../../common/EventWaiter"); const classes = require("./LookatClasses"); const jibo_common_types_1 = require("jibo-common-types"); const jibo_cai_utils_1 = require("jibo-cai-utils"); class HJOrient extends Action_1.Action { constructor(parent, location) { super(parent, 'HJOrient'); this.location = location; this.haveReceivedResult = false; this.sm = new jibo_state_machine_1.StateMachine(); this.doesVisibleFaceExist = new classes.ChooseOrientationPointState(this.sm, this.parent, classes.AngleCalculatorType.XY); this.attendToHJLocation = new classes.AttendToState(this.sm, this.parent, 'Attend to HJ location'); this.orientToInitialPerson = new classes.AttendToState(this.sm, this.parent, 'Orient to initial face'); this.haveReceivedResultState = new classes.HaveReceivedResultState(this); this.waitForFace = new classes.WaitForSignals(this); this.orientToFace = new classes.AttendToState(this.sm, this.parent, 'Orient to found face'); this.waitForResult = new classes.WaitForResults(this); this.done = new classes.DoneState(this.sm); this.sm.setInitial(this.doesVisibleFaceExist); this.doesVisibleFaceExist.installTransitions(this.orientToInitialPerson, this.attendToHJLocation); this.orientToInitialPerson.addDoneTransition(this.done); this.attendToHJLocation.addDoneTransition(this.haveReceivedResultState); this.haveReceivedResultState.installTransitions(this.done, this.waitForFace); this.waitForFace.installTransitions(this.done, this.orientToFace); this.orientToFace.addDoneTransition(this.waitForResult); this.waitForResult.addDoneTransition(this.done); } runInternal() { return __awaiter(this, void 0, void 0, function* () { const pmHandler = yield this.parent.jibo.expression.pushAttentionMode(jibo_common_types_1.AttentionMode.COMMAND); let altHJloc = undefined; const now = this.parent.dateProvider.getDate().getTime(); const hjDataMem = this.parent.memory.getHJData(); if (hjDataMem && hjDataMem.data.alternate && jibo_cai_utils_1.TimeUtils.msToSeconds(now - hjDataMem.time.getTime()) < 60) { altHJloc = hjDataMem.data.alternate.position; } let refPos = { hjloc: this.location }; if (altHJloc) { refPos['altHJloc'] = altHJloc; } this.doesVisibleFaceExist.setReferencePositions(refPos); this.resultWaiters = [ ['HJ Listen Complete', new EventWaiter_1.TypedEventWaiter(null, this.parent.jibo.jetstream.events.globalTurnResult).start()], ['HJ Listen Complete', new EventWaiter_1.TypedEventWaiter(null, this.parent.jibo.jetstream.events.hjOnly).start()] ]; this.haveReceivedResult = false; Promise.race(this.resultWaiters.map(e => { return e[1].promise.then(() => e); })).then((result) => { this.haveReceivedResult = true; this.log.info(`HJOrient: event waiter '${result[0]}'`); }); try { yield this.sm.start(); return Types_1.ActionResult.SUCCEEDED; } catch (e) { this.log.error('HJOrient state machine error: ', e); return Types_1.ActionResult.FAILED; } finally { this.log.debug(`${this.name} SM trace: `, this.sm.traceToString()); const trace = this.sm.getTrace(); this.log.info(`HJOrient time to face: `, this.computeTimeToFace(trace)); this.log.info(`HJOrient had initial face?: `, this.hadInitialFace(trace)); yield pmHandler.release(); this.resultWaiters.forEach(e => e[1].stop()); } }); } cancelInternal() { return __awaiter(this, void 0, void 0, function* () { this.log.warn(`'${this.name}' cancelled!`); this.sm.stop(); }); } computeTimeToFace(trace) { if (trace.length < 2) { return Number.POSITIVE_INFINITY; } for (let i = 1; i < trace.length; i++) { if (trace[i].transition.getDestinationState() === this.orientToInitialPerson || trace[i].transition.getDestinationState() === this.orientToFace) { return trace[i].timestamp - trace[0].timestamp; } } return Number.POSITIVE_INFINITY; } hadInitialFace(trace) { for (let i = 0; i < trace.length; i++) { if (trace[i].transition.getDestinationState() === this.orientToInitialPerson) { return true; } } return false; } } exports.HJOrient = HJOrient; },{"../../common/EventWaiter":23,"../../common/Types":26,"../Action":1,"./LookatClasses":10,"jibo-cai-utils":undefined,"jibo-common-types":undefined,"jibo-state-machine":undefined}],9:[function(require,module,exports){ "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const Action_1 = require("../Action"); const Types_1 = require("../../common/Types"); const SSWGoal_1 = require("../../goal/goals/SSWGoal"); const Utils_1 = require("../../common/Utils"); const jibo_cai_utils_1 = require("jibo-cai-utils"); const findRoot = require('find-root'); const ROOT = findRoot(__filename); const SOUNDS_ROOT = ROOT + '/resources/audio/'; const Sound = { ONTOUCH: SOUNDS_ROOT + `touch-on.m4a`, ONEXIT: SOUNDS_ROOT + `touch-off.m4a` }; const DEFAULT_MILLISECONDS_TO_HOLD_TOUCH = 1000; const TOUCH_RESET_TIME = 1000; class HeadTouch extends Action_1.Action { constructor(parent, shouldQuitSkill) { super(parent, 'HeadTouch'); this.shouldQuitSkill = shouldQuitSkill; this._canceled = false; this._lastTouchTime = -1; } static resetHoldToQuitTime() { HeadTouch.MILLISECONDS_TO_HOLD_TOUCH = DEFAULT_MILLISECONDS_TO_HOLD_TOUCH; } runInternal() { return __awaiter(this, void 0, void 0, function* () { const promises = []; const result = yield new Promise(resolve => { if (Date.now() - this._lastTouchTime > TOUCH_RESET_TIME) { promises.push(this._playSound(Sound.ONTOUCH)); } this._canceled = false; this.parent.jibo.system.events.touchOff.waitFor(HeadTouch.MILLISECONDS_TO_HOLD_TOUCH) .then((data) => { resolve(Types_1.ActionResult.FAILED); }).catch(timeout => { if (this._canceled) { resolve(Types_1.ActionResult.CANCELED); } else { promises.push(this._playSound(Sound.ONEXIT)); this.log.info("stopping listen jibo via touch"); this.parent.jibo.analytics.track('Listen Stop', { type: 'touch', status: 'done' }); this.parent.jibo.jetstream.cancelAnyTurn(); if (this.shouldQuitSkill) { this.parent.jibo.analytics.track('Global Stop', { type: 'touch', status: 'done' }); const sswGoal = new SSWGoal_1.SSWGoal(this.parent, { skillName: Utils_1.SkillNames.IDLE, skillOptions: {} }, `Hold Switch to Idle Goal`); sswGoal.events.finished.on((result) => { if (result === Types_1.GoalFinishedStatus.SUCCEEDED) { resolve(Types_1.ActionResult.SUCCEEDED); } else { resolve(Types_1.ActionResult.FAILED); } }); this.parent.goals.addGoal(sswGoal); } else { resolve(Types_1.ActionResult.SUCCEEDED); } } }); }); yield Promise.all(promises); return result; }); } cancelInternal() { return __awaiter(this, void 0, void 0, function* () { this._canceled = true; }); } _playSound(path) { return __awaiter(this, void 0, void 0, function* () { return new Promise((resolve, reject) => { if (!jibo_cai_utils_1.CacheUtils.initialized) { reject(new Error(`Global cache not initialized`)); return; } const sound = this.parent.jibo.loader.cached(path, jibo_cai_utils_1.CacheUtils.GlobalCacheName); if (sound) { sound.play(); resolve(); } else { this.parent.jibo.loader.load({ type: 'sound', id: path, cache: jibo_cai_utils_1.CacheUtils.GlobalCacheName, src: path, complete: (err, sound) => { if (err) { reject(err); return; } sound.play(); resolve(); } }); } }); }); } } HeadTouch.MILLISECONDS_TO_HOLD_TOUCH = 1000; exports.HeadTouch = HeadTouch; },{"../../common/Types":26,"../../common/Utils":28,"../../goal/goals/SSWGoal":51,"../Action":1,"find-root":undefined,"jibo-cai-utils":undefined}],10:[function(require,module,exports){ "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const jibo_state_machine_1 = require("jibo-state-machine"); const jibo_cai_utils_1 = require("jibo-cai-utils"); const jibo_common_types_1 = require("jibo-common-types"); const Utils_1 = require("../../common/Utils"); const log_1 = require("../log"); const _ = require("lodash/lodash.min"); const FACE_ANGLE_THRESH = Math.PI / 8; const AWAIT_TIMEOUT = 3; const EXPRESSION_TIMEOUT = 10 * 1000; const OWNER_IDENTIFIER = 'AttentionCommand'; var Outcome; (function (Outcome) { Outcome["Result"] = "Result"; Outcome["Face"] = "Face"; Outcome["Timeout"] = "Timeout"; Outcome["Motion"] = "Motion"; })(Outcome = exports.Outcome || (exports.Outcome = {})); function faceNearReference(position, actionRuntime, angleCalculator) { let bestAngle = Number.MAX_SAFE_INTEGER; let bestFace = null; actionRuntime.jibo.lps.identity.getVisibleFaces().forEach((face) => { if (face.in_fov) { const angle = angleCalculator(position, face.position); if (angle < bestAngle) { bestAngle = angle; bestFace = face; } } }); log_1.log.info(`Initial face: `, position, bestFace ? bestFace.id : null); if (bestFace && bestAngle < FACE_ANGLE_THRESH) { return { face: bestFace, angle: bestAngle }; } } function angleXY(point1, point2) { const p1 = { x: point1.x, y: point1.y, z: 0 }; const p2 = { x: point2.x, y: point2.y, z: 0 }; return angle3d(p1, p2); } function angle3d(point1, point2) { const dotProduct = point1.x * point2.x + point1.y * point2.y + point1.z * point2.z; const length1 = Math.sqrt(point1.x * point1.x + point1.y * point1.y + point1.z * point1.z); const length2 = Math.sqrt(point2.x * point2.x + point2.y * point2.y + point2.z * point2.z); if (length1 === 0 || length2 === 0) { return Math.PI; } else { return Math.acos(dotProduct / (length1 * length2)); } } var AngleCalculatorType; (function (AngleCalculatorType) { AngleCalculatorType[AngleCalculatorType["XY"] = 0] = "XY"; AngleCalculatorType[AngleCalculatorType["XYZ"] = 1] = "XYZ"; })(AngleCalculatorType = exports.AngleCalculatorType || (exports.AngleCalculatorType = {})); class YesNoState extends jibo_state_machine_1.State { constructor(sm, name, transitionNames = ['Yes', 'No']) { super(sm, name); this.transitionNames = transitionNames; } installTransitions(yesState, noState) { this._yesState = yesState; this._noState = noState; this.addInternalTransition(this.transitionNames[0], this._yesState); this.addInternalTransition(this.transitionNames[1], this._noState); } } exports.YesNoState = YesNoState; class AttendToState extends jibo_state_machine_1.State { constructor(sm, actionRuntime, name, floorZ = true) { super(sm, name); this.actionRuntime = actionRuntime; this.floorZ = floorZ; this.log = log_1.log.createChild('AttendToState'); this.onEntry = this._onEntry.bind(this); this.onStop = () => { if (this._handle) { const handle = this._handle; this._handle = null; return handle.cancel(); } else { return Promise.resolve(); } }; } overrideLocation(data) { return data; } _onEntry(transition, data) { return __awaiter(this, void 0, void 0, function* () { const jibo = this.actionRuntime.jibo; data = this.overrideLocation(data); if (!data || !((data.entity && data.entity.id) || (data.position && (data.position.x !== undefined)))) { this.log.error('Bad AttendTarget data in AttendToState. SM trace: ', this.sm.traceToString()); throw new Error(`${this.name}: Bad AttendTarget data ${JSON.stringify(data)}`); } let pos = null; if (data.position) { pos = { x: data.position.x, y: data.position.y, z: this.floorZ ? Math.max(-0.1, data.position.z) : data.position.z }; } try { this._handle = yield Utils_1.timeout(jibo.expression.acquireTarget({ position: pos, entity: data.entity }), EXPRESSION_TIMEOUT, { log: this.log, logMessage: 'jibo.expression.acquireTarget' }); if (!this._handle) { return jibo_common_types_1.ResultStatus.TIMEOUT; } return yield Utils_1.timeout(this._handle.promise, EXPRESSION_TIMEOUT, { log: this.log, logMessage: `acquireTarget.handle.promise`, timeoutValue: jibo_common_types_1.ResultStatus.TIMEOUT }); } catch (e) { throw e; } finally { this._handle = null; } }); } } exports.AttendToState = AttendToState; class FlowState extends jibo_state_machine_1.State { constructor(sm, actionRuntime, name, flow) { super(sm, name); this.actionRuntime = actionRuntime; this.flow = flow; this.log = log_1.log.createChild('FlowState'); this.onEntry = this._onEntry.bind(this); this.onStop = () => { if (this._flowHandle) { this._flowHandle.stop(); this._flowHandle = null; } }; } _onEntry(trans, data) { return __awaiter(this, void 0, void 0, function* () { const jibo = this.actionRuntime.jibo; if (!this.flow) { this.log.warn(`Skipping flow: '${this.name}'`); } else { this.log.info(`Playing flow: '${this.name}'`); const result = {}; const options = { result, assetPack: 'jibo/node_modules/jibo-action-system', enableLogging: false, }; try { yield jibo_cai_utils_1.PromiseUtils.promisify(h => { this._flowHandle = jibo.flow.run(this.flow, options, h); }); } catch (e) { throw e; } finally { this._flowHandle = null; } } return data; }); } } exports.FlowState = FlowState; class DoneState extends jibo_state_machine_1.State { constructor(sm, name = 'Done', data) { super(sm, name); this.onEntry = () => { this.sm.stop(data); }; } } exports.DoneState = DoneState; class PersonVisibleNearReferenceState extends YesNoState { constructor(sm, actionRuntime, angleCalculator) { super(sm, 'Is person visible?'); this.actionRuntime = actionRuntime; this.onEntry = () => { if (!this.referencePosition) { throw new Error(`${this.name}: Missing reference position`); } const calculator = angleCalculator === AngleCalculatorType.XY ? angleXY : angle3d; const face = faceNearReference(this.referencePosition, actionRuntime, calculator); if (face) { this.transitionTo(this._yesState, face.face); } else { this.transitionTo(this._noState, { position: this.referencePosition }); } }; } setReferencePosition(referencePosition) { this.referencePosition = referencePosition; } } exports.PersonVisibleNearReferenceState = PersonVisibleNearReferenceState; class ChooseOrientationPointState extends YesNoState { constructor(sm, actionRuntime, angleCalculator) { super(sm, 'Choose Orientation Point', ['faceState', 'hjLocState']); this.actionRuntime = actionRuntime; this.angleCalculator = angleCalculator; this.log = log_1.log.createChild('ReferenceLocationWithAlternate'); this.onEntry = () => { let faceState = this._yesState; let hjlocState = this._noState; if (!this.referencePositions) { throw new Error(`${this.name}: Missing reference positions`); } const calculator = this.angleCalculator === AngleCalculatorType.XY ? angleXY : angle3d; let hjface = faceNearReference(this.referencePositions.hjloc, this.actionRuntime, calculator); if (this.referencePositions.altHJloc) { this.log.debug(`have altHJloc`); let altHJface = faceNearReference(this.referencePositions.altHJloc, this.actionRuntime, calculator); if (!hjface && !altHJface) { this.log.debug(`no face at either location. take best guess--the HJ loc.`); return this.transitionTo(hjlocState, { position: this.referencePositions.hjloc }); } else if (hjface && altHJface) { this.log.debug(`both have faces. take the better match.`); if (altHJface.angle < hjface.angle) { this.log.debug(`altHJ angle is smaller`); return this.transitionTo(faceState, altHJface.face); } else { this.log.debug(`primary HJ angle is smaller`); return this.transitionTo(faceState, hjface.face); } } else { if (hjface) { this.log.debug(`only primary HJ loc has face.`); return this.transitionTo(faceState, hjface.face); } else { this.log.debug(`only altHJloc has face.`); return this.transitionTo(faceState, altHJface.face); } } } else { this.log.debug(`no altHJloc`); if (hjface) { this.log.debug(`found face near HJ`); return this.transitionTo(faceState, hjface.face); } else { this.log.debug(`no face near HJ, just using HJ location`); return this.transitionTo(hjlocState, { position: this.referencePositions.hjloc }); } } }; } setReferencePositions(referencePositions) { this.referencePositions = _.cloneDeep(referencePositions); } } exports.ChooseOrientationPointState = ChooseOrientationPointState; class ChooseOrientationPointBiasForMovementState extends YesNoState { constructor(sm, actionRuntime, angleCalculator) { super(sm, 'Choose Orientation Point', ['Found Face', 'No Face, use audio localization']); this.actionRuntime = actionRuntime; this.angleCalculator = angleCalculator; this.log = log_1.log.createChild('ReferenceLocationWithAlternate'); this.onEntry = () => { let faceState = this._yesState; let hjlocState = this._noState; if (!this.referencePositions) { throw new Error(`${this.name}: Missing reference positions`); } const calculator = this.angleCalculator === AngleCalculatorType.XY ? angleXY : angle3d; let hjface = faceNearReference(this.referencePositions.hjloc, this.actionRuntime, calculator); if (!hjface && !!this.referencePositions.altHJloc) { this.log.debug(`no face at primary hjloc and altHJloc exists, comparing angles`); let hjangle = calculator(this.actionRuntime.jibo.expression.features.head.direction, this.referencePositions.hjloc); let althjangle = calculator(this.actionRuntime.jibo.expression.features.head.direction, this.referencePositions.altHJloc); if (althjangle > hjangle) { this.log.debug(`altHJloc has higher angle, orienting there`); return this.transitionTo(hjlocState, { position: this.referencePositions.altHJloc }); } else { this.log.debug(`primary HJloc has higher angle, orienting there`); return this.transitionTo(hjlocState, { position: this.referencePositions.hjloc }); } } else if (hjface) { this.log.debug(`face exists near primary HJ loc, orienting to that`); return this.transitionTo(faceState, hjface.face); } else { this.log.debug(`no face, no altHJloc, orienting to primary HJloc`); return this.transitionTo(hjlocState, { position: this.referencePositions.hjloc }); } }; } setReferencePositions(referencePositions) { this.referencePositions = _.cloneDeep(referencePositions); } } exports.ChooseOrientationPointBiasForMovementState = ChooseOrientationPointBiasForMovementState; class WaitForResults extends jibo_state_machine_1.State { constructor(hjOrient) { super(hjOrient.sm, 'Waiting for results'); this.hjOrient = hjOrient; this.onEntry = () => { return Promise.race(this.hjOrient.resultWaiters.map(e => e[1].promise)); }; } } exports.WaitForResults = WaitForResults; class WaitForSignals extends jibo_state_machine_1.State { constructor(hjOrient) { super(hjOrient.sm, 'Waiting for face or signal'); this.hjOrient = hjOrient; this.onEntry = this._onEntry.bind(this); this.onExit = () => { if (this._attendHandle) { this._attendHandle.cancel(); this._attendHandle = null; } }; } installTransitions(rcvResults, faceFound) { this._rcvResults = rcvResults; this._faceFound = faceFound; this.addInternalTransition('Received results', this._rcvResults); this.addInternalTransition('Found face', this._faceFound); } _onEntry() { this.hjOrient.log.debug('HJOrient waiting for signals'); let promises = this.hjOrient.resultWaiters .map(e => e[1].promise.then(() => { this.hjOrient.log.debug(`result waiter resolved`); return { outcome: Outcome.Result }; })); promises.push(this.waitForFace()); Promise.race(promises).then((outcome) => { this.hjOrient.log.debug(`hjOrient got outcome`); if (outcome.outcome === Outcome.Face) { this.transitionTo(this._faceFound, outcome.data); } else if (outcome.outcome === Outcome.Result) { this.transitionTo(this._rcvResults); } else if (outcome.outcome === Outcome.Timeout) { this.hjOrient.log.warn(`Wait for signals timed out.`); this.transitionTo(this._rcvResults); } else { throw new Error(`Unknown outcome: '${outcome}'`); } }); } waitForFace() { return __awaiter(this, void 0, void 0, function* () { const jibo = this.hjOrient.parent.jibo; const awaitPromise = jibo.expression.awaitFace({ timeout: AWAIT_TIMEOUT }); this._attendHandle = yield Utils_1.timeout(awaitPromise, EXPRESSION_TIMEOUT, { log: this.hjOrient.log, logMessage: `jibo.expression.awaitFace` }); if (!this._attendHandle) { return { outcome: Outcome.Timeout }; } const face = yield Utils_1.timeout(this._attendHandle.promise, EXPRESSION_TIMEOUT, { log: this.hjOrient.log, logMessage: `awaitFace.attendHandle.promise` }); if (face && face.status === jibo_common_types_1.ResultStatus.SUCCEEDED) { return { outcome: Outcome.Face, data: face }; } else { return { outcome: Outcome.Timeout }; } }); } } exports.WaitForSignals = WaitForSignals; class HaveReceivedResultState extends YesNoState { constructor(hjOrient) { super(hjOrient.sm, 'Have received result'); this.hjOrient = hjOrient; this.onEntry = () => { if (this.hjOrient.haveReceivedResult) { this.transitionTo(this._yesState); } else { this.transitionTo(this._noState); } }; } } exports.HaveReceivedResultState = HaveReceivedResultState; const LIGHTING_QUALITY_THRESHOLD = 0.25; class LightingGoodState extends YesNoState { constructor(sm, actionRuntime) { super(sm, 'Is lighting good?'); this.actionRuntime = actionRuntime; this.log = log_1.log.createChild('LightingGoodState'); this.onEntry = () => { const lightQual = this.actionRuntime.jibo.lps.lightingQuality; this.log.info(`lighting quality: `, lightQual); if (lightQual >= LIGHTING_QUALITY_THRESHOLD) { this.transitionTo(this._yesState); } else { this.transitionTo(this._noState); } }; } } exports.LightingGoodState = LightingGoodState; class PickNextLocationState extends YesNoState { constructor(search) { super(search.sm, 'Is another search location available?'); this.onEntry = () => { if (search.searchCandidates.length) { const nextLoc = search.searchCandidates.shift(); this.transitionTo(this._yesState, nextLoc); } else { this.transitionTo(this._noState); } }; } } exports.PickNextLocationState = PickNextLocationState; class AwaitFaceState extends jibo_state_machine_1.State { constructor(parent, name, timeOut = -1) { super(parent.sm, name); this.parent = parent; this.timeOut = timeOut; this.onEntry = this._onEntry.bind(this); this.onExit = () => { if (this._faceHandle) { this._faceHandle.cancel(); this._faceHandle = null; } }; } installTransitions(faceFoundState, timeoutState, motionDetectedState) { this._faceFoundState = faceFoundState; this._timeoutState = timeoutState; this._motionDetectedState = motionDetectedState; this.addInternalTransition('Face found', this._faceFoundState); this.addInternalTransition('Timeout', this._timeoutState); this.addInternalTransition('Motion detected', this._motionDetectedState); } createMotionDetectionPromise() { return new Promise(resolve => { }); } _onEntry() { return __awaiter(this, void 0, void 0, function* () { const jibo = this.parent.parent.jibo; this._faceHandle = yield Utils_1.timeout(jibo.expression.awaitFace({ timeout: this.timeOut }), EXPRESSION_TIMEOUT, { log: this.parent.log, logMessage: `jibo.expression.awaitFace` }); let promises = []; if (this._faceHandle) { promises.push(Utils_1.timeout(this._faceHandle.promise, EXPRESSION_TIMEOUT, { log: this.parent.log, logMessage: `awaitFace.handle.promise` }) .then(face => { if (face && face.status === jibo_common_types_1.ResultStatus.SUCCEEDED) { return { outcome: Outcome.Face, data: face }; } else { return { outcome: Outcome.Timeout }; } }).catch((e) => { this.parent.log.error(`AwaitFace: `, e); return { outcome: Outcome.Timeout }; }).then((data) => { this._faceHandle = null; return data; })); } else { promises.push(Promise.resolve({ outcome: Outcome.Timeout })); } promises.push(this.createMotionDetectionPromise()); try { const outcome = yield Promise.race(promises); if (outcome.outcome === Outcome.Face) { this.transitionTo(this._faceFoundState, outcome.data); } else if (outcome.outcome === Outcome.Timeout) { this.transitionTo(this._timeoutState); } else if (outcome.outcome === Outcome.Motion) { this.transitionTo(this._motionDetectedState, outcome.data); } else { this.parent.log.error(`Await face, invalid outcome: `, outcome); this.transitionTo(this._timeoutState); } } catch (error) { this.parent.log.error(`Await face, error: `, error); this.transitionTo(this._timeoutState); } }); } } exports.AwaitFaceState = AwaitFaceState; class OrientToStandard extends jibo_state_machine_1.State { constructor(sm, actionRuntime) { super(sm, 'Orient to standard location'); this.onEntry = () => { return actionRuntime.jibo.expression.centerRobot({ requestor: OWNER_IDENTIFIER, centerGlobally: true }); }; } } exports.OrientToStandard = OrientToStandard; class AttendToFixedState extends AttendToState { constructor(sm, actionRuntime, name, standard) { super(sm, actionRuntime, name); this.standard = standard; } overrideLocation(data) { return this.standard; } } exports.AttendToFixedState = AttendToFixedState; },{"../../common/Utils":28,"../log":16,"jibo-cai-utils":undefined,"jibo-common-types":undefined,"jibo-state-machine":undefined,"lodash/lodash.min":undefined}],11:[function(require,module,exports){ "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const Action_1 = require("../Action"); const Types_1 = require("../../common/Types"); const HeadTouch_1 = require("./HeadTouch"); class SSWAction extends Action_1.Action { constructor(parent, skillName, skillData) { super(parent, `Skill Switch Action: '${skillName}'`); this.skillName = skillName; this.skillData = skillData; } runInternal() { return __awaiter(this, void 0, void 0, function* () { yield new Promise(resolve => process.nextTick(resolve)); HeadTouch_1.HeadTouch.resetHoldToQuitTime(); if (!this.parent.skillSwitcher) { this.log.error(`No installed skill switcher`); return Types_1.ActionResult.FAILED; } else { const status = yield this.parent.skillSwitcher(this.skillName, this.skillData); switch (status) { case Types_1.Status.SUCCEEDED: return Types_1.ActionResult.SUCCEEDED; case Types_1.Status.FAILED: return Types_1.ActionResult.FAILED; default: { this.log.error(`Unknown Skill Switch outcome: '${status}'`); return Types_1.ActionResult.FAILED; } } } }); } cancelInternal() { return __awaiter(this, void 0, void 0, function* () { return Promise.resolve(); }); } } exports.SSWAction = SSWAction; },{"../../common/Types":26,"../Action":1,"./HeadTouch":9}],12:[function(require,module,exports){ "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const Action_1 = require("../Action"); const jibo_state_machine_1 = require("jibo-state-machine"); const Types_1 = require("../../common/Types"); const classes = require("./LookatClasses"); const jibo_common_types_1 = require("jibo-common-types"); const AWAIT_FACE_TIMEOUT = 3; const Flows = { React1: null, React2: null, React3: null, React4: null, React5: null, }; class SearchAction extends Action_1.Action { constructor(parent, initialRefPosition) { super(parent, 'Search Action'); this.initialRefPosition = initialRefPosition; this.sm = new jibo_state_machine_1.StateMachine(); this.searchCandidates = []; this.isPersonVisible = new classes.PersonVisibleNearReferenceState(this.sm, this.parent, classes.AngleCalculatorType.XYZ); this.isLightingGood = new classes.LightingGoodState(this.sm, this.parent); this.attendToCandLoc = new classes.AttendToState(this.sm, this.parent, 'Attend to candidate location', false); this.attendToMotion = new classes.AttendToState(this.sm, this.parent, 'Attend to motion'); this.reactNoCandidates = new classes.FlowState(this.sm, this.parent, 'React to no more search candidates', Flows.React4); this.pickNextSearchCandidate = new classes.PickNextLocationState(this); this.reactMotionDetected = new classes.FlowState(this.sm, this.parent, 'React to motion detected', Flows.React5); this.reactFaceFound = new classes.FlowState(this.sm, this.parent, 'React to face found', Flows.React3); this.reactFaceNotFound = new classes.FlowState(this.sm, this.parent, 'React to face not found', Flows.React2); this.awaitFace = new classes.AwaitFaceState(this, 'Await face', AWAIT_FACE_TIMEOUT); this.reactBadLighting = new classes.FlowState(this.sm, this.parent, 'React to bad lighting', Flows.React1); this.attendToFace = new classes.AttendToState(this.sm, this.parent, 'Attend to face found'); this.doneSucceeded = new classes.DoneState(this.sm, 'Done - Success', Types_1.ActionResult.SUCCEEDED); this.doneFailed = new classes.DoneState(this.sm, 'Done - Failure', Types_1.ActionResult.FAILED); this.sm.setInitial(this.isPersonVisible); this.isPersonVisible.installTransitions(this.attendToFace, this.pickNextSearchCandidate); this.attendToFace.addDoneTransition(this.doneSucceeded); this.pickNextSearchCandidate.installTransitions(this.attendToCandLoc, this.reactNoCandidates); this.reactNoCandidates.addDoneTransition(this.doneFailed); this.attendToCandLoc.addDoneTransition(this.isLightingGood); this.isLightingGood.installTransitions(this.awaitFace, this.reactBadLighting); this.reactBadLighting.addDoneTransition(this.pickNextSearchCandidate); this.awaitFace.installTransitions(this.reactFaceFound, this.reactFaceNotFound, this.reactMotionDetected); this.reactMotionDetected.addDoneTransition(this.attendToMotion); this.attendToMotion.addDoneTransition(this.doneSucceeded); this.reactFaceNotFound.addDoneTransition(this.pickNextSearchCandidate); this.reactFaceFound.addDoneTransition(this.attendToFace); } runInternal() { return __awaiter(this, void 0, void 0, function* () { const pmHandler = yield this.parent.jibo.expression.pushAttentionMode(jibo_common_types_1.AttentionMode.COMMAND); let refPosition = this.initialRefPosition; if (!refPosition) { const features = this.parent.jibo.expression.features; refPosition = features.head.direction.clone().add(features.head.position); } this.isPersonVisible.setReferencePosition(refPosition); this.searchCandidates = []; const down = { x: refPosition.x, y: refPosition.y, z: 0.2 }; this.searchCandidates.push({ position: down }); this.searchCandidates.push({ position: refPosition }); this.log.debug(`Searching locations: `, this.searchCandidates); try { const res = yield this.sm.start(); return res ? res : Types_1.ActionResult.FAILED; } catch (e) { this.log.error('Search action state machine error: ', e); return Types_1.ActionResult.FAILED; } finally { this.log.debug(`'${this.name}' SM trace: `, this.sm.traceToString()); yield pmHandler.release(); } }); } cancelInternal() { return __awaiter(this, void 0, void 0, function* () { this.log.info(`'${this.name}' canceled`); this.sm.stop(); }); } } exports.SearchAction = SearchAction; },{"../../common/Types":26,"../Action":1,"./LookatClasses":10,"jibo-common-types":undefined,"jibo-state-machine":undefined}],13:[function(require,module,exports){ "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const Action_1 = require("../Action"); const Types_1 = require("../../common/Types"); const AnimationGoal_1 = require("../../goal/goals/AnimationGoal"); const OpenHatchData = { category: 'system-states', includeMeta: ['hatch-opened'] }; const CloseHatchData = { category: 'system-states', includeMeta: ['hatch-closed'] }; const PluggedData = { category: 'system-states', includeMeta: ['plugged'] }; const UnpluggedData = { category: 'system-states', includeMeta: ['unplugged'] }; const AxisFaultData = { category: 'system-states', includeMeta: ['back-drive'] }; const SnuggleAnimData = new Map(); SnuggleAnimData.set(Types_1.SnuggleType.HATCH_OPEN, OpenHatchData); SnuggleAnimData.set(Types_1.SnuggleType.HATCH_CLOSE, CloseHatchData); SnuggleAnimData.set(Types_1.SnuggleType.PLUG, PluggedData); SnuggleAnimData.set(Types_1.SnuggleType.UNPLUG, UnpluggedData); SnuggleAnimData.set(Types_1.SnuggleType.AXIS_FAULT, AxisFaultData); class Snuggle extends Action_1.Action { constructor(parent, type) { super(parent, `Snuggle`); this.type = type; } runInternal() { return __awaiter(this, void 0, void 0, function* () { return yield new Promise(resolve => { this.log.info("playing snuggle", this.type); const animGoal = new AnimationGoal_1.AnimationGoal(this.parent, SnuggleAnimData.get(this.type)); animGoal.events.finished.on((result) => { if (result === Types_1.GoalFinishedStatus.SUCCEEDED) { resolve(Types_1.ActionResult.SUCCEEDED); } else { resolve(Types_1.ActionResult.FAILED); } }); this.parent.goals.addGoal(animGoal); }); }); } } exports.Snuggle = Snuggle; },{"../../common/Types":26,"../../goal/goals/AnimationGoal":44,"../Action":1}],14:[function(require,module,exports){ "use strict"; function __export(m) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; } Object.defineProperty(exports, "__esModule", { value: true }); __export(require("./SSWAction")); __export(require("./AnimationAction")); __export(require("./BasicLookat")); __export(require("./SearchAction")); __export(require("./HJOrient")); __export(require("./BeSkillSwitchAction")); __export(require("./HeadTouch")); __export(require("./EmitHeadPat")); },{"./AnimationAction":4,"./BasicLookat":5,"./BeSkillSwitchAction":6,"./EmitHeadPat":7,"./HJOrient":8,"./HeadTouch":9,"./SSWAction":11,"./SearchAction":12}],15:[function(require,module,exports){ "use strict"; function __export(m) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; } Object.defineProperty(exports, "__esModule", { value: true }); __export(require("./Action")); __export(require("./ActionSystem")); __export(require("./GoalDrivenAction")); const actions = require("./actions"); exports.actions = actions; const policies = require("./policies"); exports.policies = policies; },{"./Action":1,"./ActionSystem":2,"./GoalDrivenAction":3,"./actions":14,"./policies":18}],16:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const jibo_log_1 = require("jibo-log"); exports.Log = jibo_log_1.Log; const log_1 = require("../common/log"); const log = log_1.log.createChild('Action'); exports.log = log; },{"../common/log":30,"jibo-log":undefined}],17:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const HJGoal_1 = require("../../goal/goals/HJGoal"); const FindPersonGoal_1 = require("../../goal/goals/FindPersonGoal"); const HJOnlyGoal_1 = require("../../goal/goals/HJOnlyGoal"); const BasicLookat_1 = require("../actions/BasicLookat"); const SearchAction_1 = require("../actions/SearchAction"); const HJOrient_1 = require("../actions/HJOrient"); const Utils_1 = require("../../common/Utils"); const SSWGoal_1 = require("../../goal/goals/SSWGoal"); const SSWAction_1 = require("../actions/SSWAction"); const AnimationAction_1 = require("../actions/AnimationAction"); const AnimationGoal_1 = require("../../goal/goals/AnimationGoal"); const HeadTouchGoal_1 = require("../../goal/goals/HeadTouchGoal"); const HeadTouch_1 = require("../actions/HeadTouch"); const SnuggleGoal_1 = require("../../goal/goals/SnuggleGoal"); const Snuggle_1 = require("../actions/Snuggle"); const BeSSWGoal_1 = require("../../goal/goals/BeSSWGoal"); const BeSkillSwitchAction_1 = require("../../action/actions/BeSkillSwitchAction"); const Types_1 = require("../../common/Types"); class BasicPolicy { constructor(parent) { this.parent = parent; } selectAction(goal, state) { if (goal instanceof HJGoal_1.HJGoal) { const hjGoal = goal; const pos = hjGoal.hjData.primary.position; if (state.skillName === Utils_1.SkillNames.IDLE) { return new HJOrient_1.HJOrient(this.parent, pos); } else { return new BasicLookat_1.BasicLookat(this.parent, pos); } } else if (goal instanceof BeSSWGoal_1.BeSSWGoal) { return new BeSkillSwitchAction_1.BeSkillSwitchAction(this.parent, goal.data); } else if (goal instanceof HJOnlyGoal_1.HJOnlyGoal) { const data = { nlu: { entities: { skill: Utils_1.SkillNames.GREETINGS, }, intent: 'heyJibo' } }; return new SSWAction_1.SSWAction(this.parent, Utils_1.SkillNames.GREETINGS, data); } else if (goal instanceof SSWGoal_1.SSWGoal) { const sswGoal = goal; return new SSWAction_1.SSWAction(this.parent, sswGoal.data.skillName, sswGoal.data.skillOptions); } else if (goal instanceof AnimationGoal_1.AnimationGoal) { const animGoal = goal; return new AnimationAction_1.AnimationAction(this.parent, animGoal.data); } else if (goal instanceof FindPersonGoal_1.FindPersonGoal) { return new SearchAction_1.SearchAction(this.parent); } else if (goal instanceof HeadTouchGoal_1.HeadTouchGoal) { const shouldQuitSkill = state.skillName !== Utils_1.SkillNames.IDLE; if (state.listenState === Types_1.ListenState.HJ_TRIGGERED_LISTEN) { return new HeadTouch_1.HeadTouch(this.parent, shouldQuitSkill); } else if (shouldQuitSkill) { return new HeadTouch_1.HeadTouch(this.parent, true); } else { this.parent.events.secondhandTouchStop.emit(goal.data); } } else if (goal instanceof SnuggleGoal_1.SnuggleGoal) { const snuggleGoal = goal; return new Snuggle_1.Snuggle(this.parent, snuggleGoal.type); } } } exports.BasicPolicy = BasicPolicy; },{"../../action/actions/BeSkillSwitchAction":6,"../../common/Types":26,"../../common/Utils":28,"../../goal/goals/AnimationGoal":44,"../../goal/goals/BeSSWGoal":45,"../../goal/goals/FindPersonGoal":46,"../../goal/goals/HJGoal":47,"../../goal/goals/HJOnlyGoal":48,"../../goal/goals/HeadTouchGoal":49,"../../goal/goals/SSWGoal":51,"../../goal/goals/SnuggleGoal":52,"../actions/AnimationAction":4,"../actions/BasicLookat":5,"../actions/HJOrient":8,"../actions/HeadTouch":9,"../actions/SSWAction":11,"../actions/SearchAction":12,"../actions/Snuggle":13}],18:[function(require,module,exports){ "use strict"; function __export(m) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; } Object.defineProperty(exports, "__esModule", { value: true }); __export(require("./BasicPolicy")); },{"./BasicPolicy":17}],19:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const ActionRuntime_1 = require("./common/ActionRuntime"); const ActionEvents_1 = require("./common/ActionEvents"); const HeadTouch_1 = require("./action/actions/HeadTouch"); const action_ns = require("./action"); const types = require("./common/Types"); exports.types = types; const goal_ns = require("./goal"); var goal; (function (goal) { goal.GoalEvents = goal_ns.GoalEvents; goal.Goal = goal_ns.Goal; })(goal = exports.goal || (exports.goal = {})); var action; (function (action) { action.Action = action_ns.Action; })(action = exports.action || (exports.action = {})); function init(options) { exports._runtime = new ActionRuntime_1.ActionRuntime(); exports.events = new ActionEvents_1.PublicActionEvents(exports._runtime.events); return exports._runtime.init(options); } exports.init = init; function getState() { const state = exports._runtime.createState(); return { partOfDay: state.partOfDay, circadianState: state.circadian, time: state.time, }; } exports.getState = getState; function setCurrentSkill(skillName) { exports._runtime.currentSkillName = skillName; } exports.setCurrentSkill = setCurrentSkill; function setCurrentCircadianState(state) { exports._runtime.currentCircadianState = state; } exports.setCurrentCircadianState = setCurrentCircadianState; function setSkillSwitchHandler(skillSwitcher) { exports._runtime.skillSwitcher = skillSwitcher; } exports.setSkillSwitchHandler = setSkillSwitchHandler; function getActiveGoalActions() { return exports._runtime.activeGoals.map(entry => { return [entry.goal, entry.action]; }); } exports.getActiveGoalActions = getActiveGoalActions; function addSkillSwitchGoal(data) { const goal = new goal_ns.goals.SSWGoal(exports._runtime, data); process.nextTick(() => exports._runtime.goals.addGoal(goal)); return goal; } exports.addSkillSwitchGoal = addSkillSwitchGoal; function addBeSkillSwitchGoal(data) { const goal = new goal_ns.goals.BeSSWGoal(exports._runtime, data); process.nextTick(() => exports._runtime.goals.addGoal(goal)); return goal; } exports.addBeSkillSwitchGoal = addBeSkillSwitchGoal; function addPlayAnimationGoal(data, priorityType) { const goal = new goal_ns.goals.AnimationGoal(exports._runtime, data, priorityType); process.nextTick(() => exports._runtime.goals.addGoal(goal)); return goal; } exports.addPlayAnimationGoal = addPlayAnimationGoal; function addFindPersonGoal() { const goal = new goal_ns.goals.FindPersonGoal(exports._runtime); process.nextTick(() => exports._runtime.goals.addGoal(goal)); return goal; } exports.addFindPersonGoal = addFindPersonGoal; function getMotivationalDriveValue(drive) { return exports._runtime.motivations.drives.get(drive).value; } exports.getMotivationalDriveValue = getMotivationalDriveValue; function applyMotivationalEffect(drive, effect) { exports._runtime.motivations.drives.get(drive).applyEffect(effect); } exports.applyMotivationalEffect = applyMotivationalEffect; function configure(configOptions) { exports._runtime.configure(configOptions); } exports.configure = configure; function checkEnvironmentContext() { return exports._runtime.proactive.checkEnvironmentInhibitors(); } exports.checkEnvironmentContext = checkEnvironmentContext; function setHoldHeadToQuitDuration(milliseconds) { if (milliseconds <= 0 || milliseconds >= 30000) { console.error(`Attempted to set HeadTouch.SECONDS_TO_HOLD_TOUCH to invalid value: ${milliseconds}. Ignoring.`); return; } HeadTouch_1.HeadTouch.MILLISECONDS_TO_HOLD_TOUCH = milliseconds; } exports.setHoldHeadToQuitDuration = setHoldHeadToQuitDuration; function resetHoldToQuitTime() { HeadTouch_1.HeadTouch.resetHoldToQuitTime(); } exports.resetHoldToQuitTime = resetHoldToQuitTime; },{"./action":15,"./action/actions/HeadTouch":9,"./common/ActionEvents":20,"./common/ActionRuntime":21,"./common/Types":26,"./goal":54}],20:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const jibo_typed_events_1 = require("jibo-typed-events"); class ActionEvents extends jibo_typed_events_1.EventContainer { constructor() { super(); this.oriented = new jibo_typed_events_1.Event(`Jibo has oriented towards target`); this.goalAdded = new jibo_typed_events_1.Event('Goal Created'); this.headPat = new jibo_typed_events_1.Event(`Jibo's head was touched in non-exit`); this.skillChange = new jibo_typed_events_1.Event(`Skill changed`); this.circadianChange = new jibo_typed_events_1.Event(`Circadian state changed`); this.secondhandTouchStop = new jibo_typed_events_1.Event('Head touch was not used by action system.'); } } exports.ActionEvents = ActionEvents; class PublicActionEvents extends jibo_typed_events_1.EventContainer { constructor(events) { super(); this.events = events; this.headPat = this.events.headPat; this.circadianChange = this.events.circadianChange; this.secondHandTouchStop = this.events.secondhandTouchStop; } } exports.PublicActionEvents = PublicActionEvents; },{"jibo-typed-events":undefined}],21:[function(require,module,exports){ "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const fs = require("fs"); const path = require("path"); const GoalSet_1 = require("../goal/GoalSet"); const Memory_1 = require("./Memory"); const motivation_1 = require("../motivation"); const ActionSystem_1 = require("../action/ActionSystem"); const GoalDrivenAction_1 = require("../action/GoalDrivenAction"); const Types_1 = require("../common/Types"); const _1 = require("."); const goalproviders_1 = require("../goal/goalproviders"); const DateProvider_1 = require("./DateProvider"); const OpportunityDetector_1 = require("../proactive/OpportunityDetector"); const jibo_cai_utils_1 = require("jibo-cai-utils"); const TunableDebug_1 = require("./TunableDebug"); const HeadTouchGoalProvider_1 = require("../goal/goalproviders/HeadTouchGoalProvider"); const log_1 = require("./log"); const findRoot = require('find-root'); const ROOT_PATH = findRoot(__dirname); let pegasusProactiveTrigger = false; let disableProactiveTrigger = false; try { const packageFile = fs.readFileSync(path.join(ROOT_PATH, 'package.json'), 'utf8'); const packageJson = JSON.parse(packageFile); if (packageJson.options) { pegasusProactiveTrigger = packageJson.options.pegasusProactiveTrigger; disableProactiveTrigger = packageJson.options.disableProactiveTrigger; } } catch (error) { throw new Error(`Error loading package.json in jibo-action-system for options: ${error.message}`); } class ActionRuntime { constructor() { this.goals = new GoalSet_1.GoalSet(this); this.actions = new ActionSystem_1.ActionSystem(this); this.motivations = new motivation_1.MotivationSystem(this); this.proactive = null; this.events = new _1.ActionEvents(); this.activeGoals = []; this.dateProvider = new DateProvider_1.DefaultDateProvider(); this.memory = new Memory_1.Memory(this); this.goalProviders = []; this._skillStartTime = this.dateProvider.getDate(); this._updater = new _1.Updater(); this.updateAll = () => this._updater.update(); } addGoalProvider(goalProvider) { this.goalProviders.push(goalProvider); } init(options) { return __awaiter(this, void 0, void 0, function* () { this._options = options; if (options.autoUpdate === undefined) { options.autoUpdate = true; } this.jibo = options.jibo; this.hjGoalProvider = new goalproviders_1.HJGoalProvider(this); this.addGoalProvider(this.hjGoalProvider); this.addGoalProvider(new goalproviders_1.HJNoMatchGoalProvider(this)); this.addGoalProvider(new goalproviders_1.HJOnlyGoalProvider(this)); this.addGoalProvider(new goalproviders_1.SnuggleGoalProvider(this)); this.addGoalProvider(new HeadTouchGoalProvider_1.HeadTouchGoalProvider(this)); if (pegasusProactiveTrigger) { log_1.log.info('Creating opportunity detector to provide proactive triggers'); this.proactive = new OpportunityDetector_1.OpportunityDetector(this); this.proactive.setDisableProactiveTrigger(disableProactiveTrigger); this.proactive.init(); } else { log_1.log.info('Creating goal provider to provide proactive greeting triggers'); this.proactiveGreetingGoalProvider = new goalproviders_1.ProactiveGreetingGoalProvider(this); this.proactiveGreetingGoalProvider.setDisableProactiveTrigger(disableProactiveTrigger); this.addGoalProvider(this.proactiveGreetingGoalProvider); } this.goalProviders.forEach(gp => gp.init()); this._updater.addUpdateable(() => this.motivations.update(), 1000); this._updater.addUpdateable(() => this.update(), 1000); if (pegasusProactiveTrigger) { this._updater.addUpdateable(() => this.proactive.update(), 100); } this.events.goalAdded.on((goal) => { this.handleIncomingGoal(goal); }); if (this._options.autoUpdate) { this.updateAll.isGlobalTimer = true; this.jibo.timer.on('update', this.updateAll); } this.setListenTrigger = () => { this.setListenState(Types_1.ListenState.HJ_TRIGGERED_LISTEN); }; this.setListenOff = () => { this.setListenState(Types_1.ListenState.NOT_LISTENING); }; this.jibo.jetstream.events.globalTurnStarted.on(this.setListenTrigger); this.jibo.jetstream.events.globalTurnResult.on(this.setListenOff); TunableDebug_1.TunableDebug.setup(this); }); } dispose() { if (this._options && this._options.autoUpdate) { this.jibo.timer.off('update', this.updateAll); } this.goalProviders.forEach(gp => gp.dispose()); this.goalProviders = []; this.jibo.jetstream.events.globalTurnStarted.removeListener(this.setListenTrigger); this.jibo.jetstream.events.globalTurnResult.removeListener(this.setListenOff); if (this.proactive) { this.proactive.dispose(); } this._updater.clear(); } configure(configOptions) { if (configOptions.hasOwnProperty('orientToHJ')) { this.hjGoalProvider.setListening(configOptions.orientToHJ); } } set currentSkillName(name) { const oldSkillName = this._currentSkillName; this._currentSkillName = name; if (oldSkillName !== name) { this._skillStartTime = this.dateProvider.getDate(); this.events.skillChange.emit([oldSkillName, this._currentSkillName]); } } set currentCircadianState(state) { this._currentCircadianState = state; log_1.log.debug(`Action system circadian state set to ${state}.`); } get currentSkillName() { return this._currentSkillName; } createState() { const now = this.dateProvider.getDate(); return { time: now, users: this.jibo.lps.identity.getPresentPersons(), skillName: this.currentSkillName, skillStartTime: this._skillStartTime, partOfDay: jibo_cai_utils_1.TimeUtils.getPartOfDay(now), circadian: this._currentCircadianState, listenState: this._currentListenState }; } update() { if (!this.activeGoals.length) { this.pursueNextGoal(); } } handleIncomingGoal(goal) { return __awaiter(this, void 0, void 0, function* () { log_1.log.info(`Incoming new goal '${goal.name}'`); const state = this.createState(); if (!goal.isEligible(state)) { log_1.log.info(`not currently eligible, in queue`); return; } if (!this.activeGoals.length) { this.pursueNextGoal(); } else { for (let i = 0; i < this.activeGoals.length; i++) { const entry = this.activeGoals[i]; if ((entry.goal.options.priority >= goal.options.priority) && !this.goals.goalParallelism.canBeAchievedInParallel(goal, entry.goal)) { log_1.log.info(`incoming goal is of lower priority and can not be performed in parallel with existing goal: '${entry.goal.name}', is queued`); return; } } let shouldBeCanceled = this.activeGoals.filter(entry => { return ((entry.goal.options.priority < goal.options.priority) && !this.goals.goalParallelism.canBeAchievedInParallel(goal, entry.goal)); }); if (shouldBeCanceled.length) { const goalNames = shouldBeCanceled.map(e => e.goal.name).join(', '); log_1.log.info(`Canceling following lower priority goals in favor of incoming one: '${goalNames}'`); yield Promise.all(shouldBeCanceled.map(e => this.cancelGoalDrivenAction(e))); } yield this.achieveGoal(state, goal); } }); } pursueNextGoal() { return __awaiter(this, void 0, void 0, function* () { const state = this.createState(); const goal = this.goals.chooseGoal(state); if (goal) { log_1.log.debug(`Selected goal to pursue '${goal.name}'`); return this.achieveGoal(state, goal); } }); } cancelGoalDrivenAction(current) { return __awaiter(this, void 0, void 0, function* () { current.goal.setFinishedStatus(Types_1.GoalFinishedStatus.CANCELED); yield current.action.cancel(); if (current.currentRunPromise) { yield current.currentRunPromise; } }); } achieveGoal(state, newGoal) { return __awaiter(this, void 0, void 0, function* () { const action = this.actions.chooseAction(state, newGoal); if (action) { log_1.log.debug(`attempting to achieve goal`, newGoal.name, `with action`, action.name); newGoal.setProgressStatus(Types_1.GoalProgressStatus.SELECTED); const goalDrivenAction = new GoalDrivenAction_1.GoalDrivenAction(newGoal, action, this); log_1.log.debug('created new goal driven action based on ', newGoal.name); this.activeGoals.push(goalDrivenAction); this.activeGoals.sort((a, b) => a.goal.options.priority - b.goal.options.priority); const postAction = () => { const ind = this.activeGoals.indexOf(goalDrivenAction); if (ind >= 0) { this.activeGoals.splice(ind, 1); } process.nextTick(() => { this.pursueNextGoal(); }); }; return goalDrivenAction.run() .then(result => { postAction(); return result; }).catch((e) => { postAction(); throw e; }); } else { newGoal.setProgressStatus(Types_1.GoalProgressStatus.INITIAL); return null; } }); } setListenState(listenState) { log_1.log.debug('Setting listen state to ', listenState); this._currentListenState = listenState; } } exports.ActionRuntime = ActionRuntime; },{".":29,"../action/ActionSystem":2,"../action/GoalDrivenAction":3,"../common/Types":26,"../goal/GoalSet":35,"../goal/goalproviders":42,"../goal/goalproviders/HeadTouchGoalProvider":39,"../motivation":60,"../proactive/OpportunityDetector":61,"./DateProvider":22,"./Memory":24,"./TunableDebug":25,"./log":30,"find-root":undefined,"fs":undefined,"jibo-cai-utils":undefined,"path":undefined}],22:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); class DefaultDateProvider { getDate() { return new Date(); } } exports.DefaultDateProvider = DefaultDateProvider; },{}],23:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function create(predicate, addListener, removeListener, timeout = -1) { let done = false; let eventHandler; let timeoutHandle = null; return { promise: new Promise((resolve, reject) => { if (timeout > 0) { timeoutHandle = setTimeout(() => { if (!done) { done = true; removeListener(eventHandler); timeoutHandle = null; reject('TIMEOUT'); } }, timeout); } eventHandler = (data) => { if (!predicate || predicate(data)) { if (!done) { done = true; removeListener(eventHandler); if (timeoutHandle) { clearTimeout(timeoutHandle); } resolve(data); } } }; addListener(eventHandler); }), stop: () => { if (!done) { done = true; removeListener(eventHandler); if (timeoutHandle) { clearTimeout(timeoutHandle); } } } }; } class EventWaiter { constructor(predicate, eventName, eventEmitter, timeout = -1) { this.predicate = predicate; this.eventName = eventName; this.eventEmitter = eventEmitter; this.timeout = timeout; } start() { return create(this.predicate, (handler) => this.eventEmitter.on(this.eventName, handler), (handler) => this.eventEmitter.removeListener(this.eventName, handler), this.timeout); } } exports.EventWaiter = EventWaiter; class TypedEventWaiter { constructor(predicate, event, timeout = -1) { this.predicate = predicate; this.event = event; this.timeout = timeout; } start() { return create(this.predicate, (handler) => this.event.on(handler), (handler) => this.event.removeListener(handler), this.timeout); } } exports.TypedEventWaiter = TypedEventWaiter; },{}],24:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); class Memory { constructor(parent) { this.parent = parent; this.map = new Map(); } getHJData() { return this.get('HJData'); } setHJData(data) { this.set('HJData', data); } set(key, data) { this.map.set(key, { time: this.parent.dateProvider.getDate(), data: data }); } get(key) { return this.map.get(key); } } exports.Memory = Memory; },{}],25:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const Types_1 = require("./Types"); const FindPersonGoal_1 = require("../goal/goals/FindPersonGoal"); const log_1 = require("./log"); const jibo_common_types_1 = require("jibo-common-types"); const log = log_1.log.createChild('Tunable'); let tunable = null; try { tunable = require('jibo-tunable'); } catch (e) { } class FakeDateProvider { constructor(hour, minute) { this.hour = hour; this.minute = minute; } getDate() { const d = new Date(); d.setHours(this.hour); d.setMinutes(this.minute); d.setSeconds(0); d.setMilliseconds(0); return d; } } const WIN = 'Action System'; const WIN2 = 'Proactivity Detector Window'; class TunableDebug { static setup(runtime) { if (tunable) { const T = tunable.Tunable; T.getButtonField(`Log status report`, WIN).events.change.on(() => { const state = runtime.createState(); log.info(`Action System status:`); log.info(`State: \n${JSON.stringify(state, null, 4)}`); log.info(`Active goals/actions (${runtime.activeGoals.length})`); runtime.activeGoals.forEach(g => { log.info(` - goal: '${g.goal.name}', action: '${g.action.name}'`); }); }); const originalDateProvider = runtime.dateProvider; T.getDropdownField('Fake time', ['disabled', '5:30 am', '7:00 am', '2:00 pm', '10:00 pm', '10:10 pm', '11:00 pm'], 0, WIN).events.change.on(data => { if (data === 'disabled') { runtime.dateProvider = originalDateProvider; } else { const [time, am_pm] = data.split(' '); const [hour, minute] = time.split(':'); runtime.dateProvider = new FakeDateProvider((am_pm === 'pm') ? Number(hour) + 12 : Number(hour), Number(minute)); } }); T.getButtonField(`Clear current goal / action`, WIN).events.change.on(() => { if (!runtime.activeGoals.length) { log.warn(`No current goal/action to clear`); } else { const name = runtime.activeGoals.map(a => a.action.name).join(', '); log.warn(`Canceling current action: ${name}`); runtime.activeGoals.forEach(a => a.action.cancel()); } }); T.getButtonField(`Create search goal`, WIN).events.change.on(() => { runtime.goals.addGoal(new FindPersonGoal_1.FindPersonGoal(runtime)); }); const driveDropdown = T.getDropdownField('Motivational drive', Object.keys(Types_1.DriveName), 0, WIN); T.getButtonField(`Saturate drive`, WIN).events.change.on(() => { const drive = runtime.motivations.drives.get(driveDropdown.current); drive._value = drive.threshold; }); T.getButtonField(`Force pro-active greeting`, WIN).events.change.on(() => { runtime.proactiveGreetingGoalProvider.triggerProactiveGreeting(); }); T.getButtonField("Send Fake Person ID", WIN2).events.change.on(() => { runtime.jibo.lps.identity.events.idAcquired.emit(new jibo_common_types_1.PresenceRecord({ name: "fake", identificationService: jibo_common_types_1.IdentificationService.LPS, identificationSource: jibo_common_types_1.IdentificationSource.FACE, ASRIdentified: false, LPSIdentified: true })); }); T.getButtonField(`Reset Arrival Tracker`, WIN2).events.change.on(() => { runtime.proactive.resetArrivalTrackerSM(); }); T.getButtonField(`Reset Rate Limiter`, WIN2).events.change.on(() => { runtime.proactive.signalRateLimiterStatus.reset(); runtime.proactive.signalRateLimiterStatus.dispose(); runtime.proactive.signalRateLimiterStatus.createNextPartOfDayTimeout(); }); T.getButtonField("Send Fake HJHeard", WIN2).events.change.on(() => { runtime.jibo.jetstream.events.hjHeard.emit(); }); T.getButtonField(`FastForward PartOfDay timeout`, WIN2).events.change.on(() => { runtime.jibo.timer.clearTimeout(runtime.proactive.signalRateLimiterStatus.timeoutHandle); runtime.proactive.signalRateLimiterStatus.timeoutCallback(); }); T.getButtonField(`Print active speaker`, WIN2).events.change.on(() => { log.info('Active speaker: ', runtime.jibo.lps.identity.getActiveSpeaker()); }); } } } exports.TunableDebug = TunableDebug; },{"../goal/goals/FindPersonGoal":46,"./Types":26,"./log":30,"jibo-common-types":undefined,"jibo-tunable":undefined}],26:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var GoalFinishedStatus; (function (GoalFinishedStatus) { GoalFinishedStatus["NOT_FINISHED"] = "NOT_FINISHED"; GoalFinishedStatus["SUCCEEDED"] = "SUCCEEDED"; GoalFinishedStatus["FAILED"] = "FAILED"; GoalFinishedStatus["CANCELED"] = "CANCELED"; GoalFinishedStatus["CULLED"] = "CULLED"; })(GoalFinishedStatus = exports.GoalFinishedStatus || (exports.GoalFinishedStatus = {})); var ListenState; (function (ListenState) { ListenState["HJ_TRIGGERED_LISTEN"] = "HJ_TRIGGERED_LISTEN"; ListenState["NOT_LISTENING"] = "NOT_LISTENING"; })(ListenState = exports.ListenState || (exports.ListenState = {})); var GoalProgressStatus; (function (GoalProgressStatus) { GoalProgressStatus["INITIAL"] = "INITIAL"; GoalProgressStatus["SELECTED"] = "SELECTED"; GoalProgressStatus["FINISHED"] = "FINISHED"; GoalProgressStatus["ATTEMPTED"] = "ATTEMPTED"; })(GoalProgressStatus = exports.GoalProgressStatus || (exports.GoalProgressStatus = {})); var ActionResult; (function (ActionResult) { ActionResult["SUCCEEDED"] = "SUCCEEDED"; ActionResult["FAILED"] = "FAILED"; ActionResult["CANCELED"] = "CANCELED"; ActionResult["TIMEOUT"] = "TIMEOUT"; })(ActionResult = exports.ActionResult || (exports.ActionResult = {})); var ActionStatus; (function (ActionStatus) { ActionStatus["RUNNING"] = "RUNNING"; ActionStatus["NOT_RUNNING"] = "NOT_RUNNING"; })(ActionStatus = exports.ActionStatus || (exports.ActionStatus = {})); var Status; (function (Status) { Status["SUCCEEDED"] = "SUCCEEDED"; Status["FAILED"] = "FAILED"; })(Status = exports.Status || (exports.Status = {})); var GoalPriorityType; (function (GoalPriorityType) { GoalPriorityType["REGULAR"] = "REGULAR"; GoalPriorityType["SINGLETON_KEEP_FIRST"] = "SINGLETON_KEEP_FIRST"; GoalPriorityType["SINGLETON_KEEP_LAST"] = "SINGLETON_KEEP_LAST"; })(GoalPriorityType = exports.GoalPriorityType || (exports.GoalPriorityType = {})); var DriveName; (function (DriveName) { DriveName["SOCIAL"] = "SOCIAL"; DriveName["PLAYFUL"] = "PLAYFUL"; DriveName["HELPFUL"] = "HELPFUL"; })(DriveName = exports.DriveName || (exports.DriveName = {})); var SnuggleType; (function (SnuggleType) { SnuggleType["HATCH_OPEN"] = "HATCH_OPEN"; SnuggleType["HATCH_CLOSE"] = "HATCH_CLOSE"; SnuggleType["PLUG"] = "PLUG"; SnuggleType["UNPLUG"] = "UNPLUG"; SnuggleType["AXIS_FAULT"] = "AXIS_FAULT"; })(SnuggleType = exports.SnuggleType || (exports.SnuggleType = {})); },{}],27:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); class Updater { constructor() { this.updateables = []; } clear() { this.updateables = []; } addUpdateable(update, intervalMs = -1) { this.updateables.push({ update, interval: intervalMs, last: -1 }); } update() { const now = Date.now(); for (let i = 0; i < this.updateables.length; i++) { const el = this.updateables[i]; if (el.interval === -1 || (now - el.last) > el.interval) { el.last = now; el.update(); } } } } exports.Updater = Updater; },{}],28:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SkillNames = { IDLE: '@be/idle', GREETINGS: '@be/greetings', SETTINGS: '@be/settings', CLOCK: '@be/clock', TUTORIAL: '@be/tutorial', FIRST_CONTACT: '@be/first-contact', SURPRISES: '@be/surprises', }; class SkillUtils { static isErrorSkill(skillData) { return skillData.nlu && skillData.nlu.entities.skill === exports.SkillNames.SETTINGS && skillData.nlu.entities.errorId; } static isAlarmTimerSkill(skillData) { return skillData.nlu && skillData.nlu.entities.skill === exports.SkillNames.CLOCK && ((skillData.nlu.entities.domain === 'alarm' && skillData.nlu.intent === 'finished') || (skillData.nlu.entities.domain === 'timer' && skillData.nlu.intent === 'finished')); } } exports.SkillUtils = SkillUtils; function constrainToBounds(value, min, max) { return Math.max(min, Math.min(max, value)); } exports.constrainToBounds = constrainToBounds; class DoubleMap { constructor() { this.map = new Map(); } set(key1, key2, value) { let second = this.map.get(key1); if (!second) { second = new Map(); this.map.set(key1, second); } second.set(key2, value); } get(key1, key2) { let second = this.map.get(key1); if (!second) { return undefined; } return second.get(key2); } } exports.DoubleMap = DoubleMap; function timeout(pr, timeoutTimeMs, options = {}) { return new Promise((resolve, reject) => { let timeout = setTimeout(() => { if (options.log) { let msg = `Timeout of ${timeoutTimeMs} ms occurred`; if (options.logMessage) { msg += `. ${options.logMessage}`; } options.log.warn(msg); } resolve(options.timeoutValue); }, timeoutTimeMs); pr.then((data) => { clearTimeout(timeout); resolve(data); }).catch(e => { clearTimeout(timeout); reject(e); }); }); } exports.timeout = timeout; },{}],29:[function(require,module,exports){ "use strict"; function __export(m) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; } Object.defineProperty(exports, "__esModule", { value: true }); __export(require("./Types")); __export(require("./ActionEvents")); __export(require("./ActionRuntime")); __export(require("./Utils")); __export(require("./DateProvider")); __export(require("./Updater")); },{"./ActionEvents":20,"./ActionRuntime":21,"./DateProvider":22,"./Types":26,"./Updater":27,"./Utils":28}],30:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const jibo_log_1 = require("jibo-log"); exports.Log = jibo_log_1.Log; const log = new jibo_log_1.Log('Jibo.Action'); exports.log = log; },{"jibo-log":undefined}],31:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const jibo_typed_events_1 = require("jibo-typed-events"); const GoalPriority_1 = require("./GoalPriority"); const Types_1 = require("../common/Types"); class GoalEvents extends jibo_typed_events_1.EventContainer { constructor() { super(); this.progressChange = new jibo_typed_events_1.Event('Goal progress change'); this.finished = new jibo_typed_events_1.Event('Goal finished'); } } exports.GoalEvents = GoalEvents; const DEFAULT_GOAL_OPTIONS = { priority: GoalPriority_1.GoalPriority.Default, priorityType: Types_1.GoalPriorityType.REGULAR, maxAttempts: 1 }; class Goal { constructor(parent, name, options = DEFAULT_GOAL_OPTIONS) { this.name = name; this.events = new GoalEvents(); this.attempts = 0; this._finishedStatus = Types_1.GoalFinishedStatus.NOT_FINISHED; this._progressStatus = Types_1.GoalProgressStatus.INITIAL; this.parent = parent; this.options = Object.assign({}, DEFAULT_GOAL_OPTIONS, options); this.created = parent.dateProvider.getDate(); } getProgressStatus() { return this._progressStatus; } setProgressStatus(status) { if (status !== this._progressStatus) { this._progressStatus = status; this.events.progressChange.emit(status); } } getFinishedStatus() { return this._finishedStatus; } setFinishedStatus(status) { const finishedStatusChanged = (status !== this._finishedStatus); this._finishedStatus = status; if (status !== Types_1.GoalFinishedStatus.NOT_FINISHED) { this.setProgressStatus(Types_1.GoalProgressStatus.FINISHED); } if (finishedStatusChanged) { this.events.finished.emit(status); } } isEligible(state) { if (this.options.criteria) { const criteria = this.options.criteria; if (criteria.startTime && state.time < criteria.startTime) { return false; } if (criteria.endTime && state.time > criteria.endTime) { return false; } if (criteria.currentSkill && state.skillName !== criteria.currentSkill) { return false; } if (criteria.personPresent) { if (state.users.map(u => u.id).indexOf(criteria.personPresent) === -1) { return false; } } } return true; } canBeCulled(state) { if (this.options.criteria) { const criteria = this.options.criteria; return (criteria.endTime && state.time > criteria.endTime); } return false; } } exports.Goal = Goal; },{"../common/Types":26,"./GoalPriority":33,"jibo-typed-events":undefined}],32:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const Utils_1 = require("../common/Utils"); class GoalParallelism { constructor() { this.allowedNormal = new Utils_1.DoubleMap(); this.allowedInverse = new Utils_1.DoubleMap(); } canBeAchievedInParallel(goalA, goalB) { let parallel = this.allowedNormal.get(goalA.constructor, goalB.constructor); if (parallel) { if (parallel.goalPredicate) { return parallel.goalPredicate(goalA, goalB); } else { return true; } } parallel = this.allowedInverse.get(goalB.constructor, goalA.constructor); if (parallel) { if (parallel.goalPredicate) { return parallel.goalPredicate(goalB, goalA); } else { return true; } } return false; } registerParallelGoalConstructors(goalConstructorA, goalConstructorB, predicate) { const goalParallel = { constructorA: goalConstructorA, constructorB: goalConstructorB, goalPredicate: predicate }; this.allowedNormal.set(goalConstructorA, goalConstructorB, goalParallel); this.allowedInverse.set(goalConstructorA, goalConstructorB, goalParallel); } } exports.GoalParallelism = GoalParallelism; },{"../common/Utils":28}],33:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.GoalPriority = { HeyJibo: 12, HeadTouch: 12, BeSkillSwitch: 11, SkillSwitch: 10, Animation: 9, Snuggle: 9, FindPerson: 8, HJOnly: 7, Default: 5, Circadian: 4, Proactive: 4, Motivation: 3 }; },{}],34:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const log_1 = require("./log"); class GoalProvider { constructor(parent, name) { this.name = name; this.parent = parent; this.log = log_1.log.createChild(`GoalProvider.${name}`); } provideGoal(goal) { goal.provider = this; this.parent.goals.addGoal(goal); } } exports.GoalProvider = GoalProvider; },{"./log":55}],35:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const Types_1 = require("../common/Types"); const GoalParallelism_1 = require("./GoalParallelism"); const BeSSWGoal_1 = require("./goals/BeSSWGoal"); const SSWGoal_1 = require("./goals/SSWGoal"); const HeadTouchGoal_1 = require("./goals/HeadTouchGoal"); const HJOnlyGoal_1 = require("./goals/HJOnlyGoal"); const log_1 = require("./log"); const HJGoal_1 = require("./goals/HJGoal"); const SnuggleGoal_1 = require("./goals/SnuggleGoal"); const AnimationGoal_1 = require("./goals/AnimationGoal"); const log = log_1.log.createChild('GoalSet'); class GoalSet { constructor(parent) { this.parent = parent; this.goalParallelism = new GoalParallelism_1.GoalParallelism(); this.goals = []; this.goalParallelism.registerParallelGoalConstructors(BeSSWGoal_1.BeSSWGoal, SSWGoal_1.SSWGoal, (beGoal, sswGoal) => { return (beGoal.data.skillName === sswGoal.data.skillName); }); this.goalParallelism.registerParallelGoalConstructors(BeSSWGoal_1.BeSSWGoal, HeadTouchGoal_1.HeadTouchGoal); this.goalParallelism.registerParallelGoalConstructors(HeadTouchGoal_1.HeadTouchGoal, SSWGoal_1.SSWGoal); this.goalParallelism.registerParallelGoalConstructors(BeSSWGoal_1.BeSSWGoal, HJOnlyGoal_1.HJOnlyGoal); this.goalParallelism.registerParallelGoalConstructors(SnuggleGoal_1.SnuggleGoal, AnimationGoal_1.AnimationGoal); this.goalParallelism.registerParallelGoalConstructors(HJGoal_1.HJGoal, HeadTouchGoal_1.HeadTouchGoal); } addGoal(goal) { log.debug('Adding goal: ', goal.name, ', nr of existing goals: ', this.goals.length); let toRemove = []; let shouldAdd = true; const considerRemovingGoal = (oldGoal) => { const active = this.parent.activeGoals.find(current => current.goal === oldGoal); if (active) { active.action.cancel(); } toRemove.push(oldGoal); }; if (goal.options.priorityType !== Types_1.GoalPriorityType.REGULAR) { log.debug('Singleton goal'); for (let i = 0; i < this.goals.length; i++) { const otherGoal = this.goals[i]; if (otherGoal.constructor === goal.constructor) { log.debug('Found goal of same type'); if (goal.options.priority > otherGoal.options.priority) { log.debug('Incoming is higher priority'); considerRemovingGoal(otherGoal); } else if (otherGoal.options.priority > goal.options.priority) { log.debug('Incoming is lower priority'); shouldAdd = false; } else if (goal.options.priorityType === Types_1.GoalPriorityType.SINGLETON_KEEP_FIRST) { log.debug('Priority type is SINGLETON_KEEP_FIRST'); shouldAdd = false; } else if (goal.options.priorityType === Types_1.GoalPriorityType.SINGLETON_KEEP_LAST) { log.debug('Priority type is SINGLETON_KEEP_LAST'); considerRemovingGoal(otherGoal); } } } } toRemove.forEach(g => { this.removeGoal(g); g.setFinishedStatus(Types_1.GoalFinishedStatus.CANCELED); }); if (shouldAdd) { this.goals.push(goal); this.parent.events.goalAdded.emit(goal); } else { goal.setFinishedStatus(Types_1.GoalFinishedStatus.CANCELED); } } chooseGoal(state) { if (this.goals.length === 0) { return null; } const eligibleGoals = []; const nextGoals = []; const canBeCulled = []; this.goals.forEach(goal => { if (goal.canBeCulled(state)) { canBeCulled.push(goal); } else { nextGoals.push(goal); if (goal.isEligible(state)) { eligibleGoals.push(goal); } } }); this.goals = nextGoals; canBeCulled.forEach(g => g.setFinishedStatus(Types_1.GoalFinishedStatus.CULLED)); if (eligibleGoals.length) { eligibleGoals.sort((a, b) => { const diff = b.options.priority - a.options.priority; if (diff === 0) { return (Math.random() > 0.5) ? -1 : 1; } else { return diff; } }); return eligibleGoals[0]; } else { return null; } } removeGoal(goal) { let index = this.goals.indexOf(goal); if (index > -1) { this.goals.splice(index, 1); } else { log.warn(`Trying to remove goal '${goal.name}' but didn't find it in goal list`); } } } exports.GoalSet = GoalSet; },{"../common/Types":26,"./GoalParallelism":32,"./goals/AnimationGoal":44,"./goals/BeSSWGoal":45,"./goals/HJGoal":47,"./goals/HJOnlyGoal":48,"./goals/HeadTouchGoal":49,"./goals/SSWGoal":51,"./goals/SnuggleGoal":52,"./log":55}],36:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const GoalProvider_1 = require("../GoalProvider"); const HJGoal_1 = require("../goals/HJGoal"); class HJGoalProvider extends GoalProvider_1.GoalProvider { constructor(parent) { super(parent, 'Hey Jibo Goal Provider'); this.listening = false; this.processHJBind = (data) => this.processHJ(data); } init() { this.setListening(true); } dispose() { this.setListening(false); } setListening(listen) { if (listen) { if (this.listening) { this.log.warn(`setListening(${listen}) called when listening is already ${this.listening}`); } else { this.log.info(`enabling listening for HJ event`); this.parent.jibo.lps.identity.events.hjEvent.on(this.processHJBind); this.listening = true; } } else { if (this.listening) { this.log.info(`disabling listening for HJ event`); this.parent.jibo.lps.identity.events.hjEvent.removeListener(this.processHJBind); this.listening = false; } else { this.log.warn(`setListening(${listen}) called when listening is already ${this.listening}`); } } } processHJ(hjData) { this.provideGoal(new HJGoal_1.HJGoal(this.parent, hjData)); this.parent.memory.setHJData(hjData); } } exports.HJGoalProvider = HJGoalProvider; },{"../GoalProvider":34,"../goals/HJGoal":47}],37:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const interfaces_1 = require("@jibo/interfaces"); const GoalProvider_1 = require("../GoalProvider"); const Utils_1 = require("../../common/Utils"); const SSWGoal_1 = require("../goals/SSWGoal"); class HJNoMatch { constructor(text) { this.text = text; this.intent = 'hjNomatch'; } toLog() { return { intent: this.intent, text: '' }; } } class HJNoMatchGoalProvider extends GoalProvider_1.GoalProvider { constructor(parent) { super(parent, 'HJNoMatch goal provider'); this.handleHJNoMatchBind = this.handleHJNoMatch.bind(this); } init() { this.parent.jibo.globalEvents.shared.noGlobalMatch.on(this.handleHJNoMatchBind); } dispose() { this.parent.jibo.globalEvents.shared.noGlobalMatch.off(this.handleHJNoMatchBind); } handleHJNoMatch(data) { if (this.parent.currentSkillName === Utils_1.SkillNames.IDLE && data.result.asr.annotation !== interfaces_1.asr.ASRAnnotation.GARBAGE) { this.provideGoal(new SSWGoal_1.SSWGoal(this.parent, { skillName: Utils_1.SkillNames.IDLE, skillOptions: new HJNoMatch(data.result.text), criteria: { currentSkill: Utils_1.SkillNames.IDLE } }, `HJNoMatch`)); } } } exports.HJNoMatchGoalProvider = HJNoMatchGoalProvider; },{"../../common/Utils":28,"../GoalProvider":34,"../goals/SSWGoal":51,"@jibo/interfaces":undefined}],38:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const GoalProvider_1 = require("../GoalProvider"); const HJOnlyGoal_1 = require("../goals/HJOnlyGoal"); const Utils_1 = require("../../common/Utils"); class HJOnlyGoalProvider extends GoalProvider_1.GoalProvider { constructor(parent) { super(parent, 'Hey Jibo Only Goal Provider'); this.handleHJOnlyBind = this.handleHJOnly.bind(this); } init() { this.parent.jibo.globalEvents.shared.hjOnly.on(this.handleHJOnlyBind); } dispose() { this.parent.jibo.globalEvents.shared.hjOnly.off(this.handleHJOnlyBind); } handleHJOnly(data) { const goal = new HJOnlyGoal_1.HJOnlyGoal(this.parent); goal.options.criteria = { currentSkill: Utils_1.SkillNames.IDLE, }; const state = this.parent.createState(); if (state.skillName === Utils_1.SkillNames.IDLE) { this.provideGoal(goal); } } } exports.HJOnlyGoalProvider = HJOnlyGoalProvider; },{"../../common/Utils":28,"../GoalProvider":34,"../goals/HJOnlyGoal":48}],39:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const GoalProvider_1 = require("../GoalProvider"); const HeadTouchGoal_1 = require("../goals/HeadTouchGoal"); class HeadTouchGoalProvider extends GoalProvider_1.GoalProvider { constructor(parent) { super(parent, 'Head Touch Goal Provider'); this.touchBind = this.handleHeadTouch.bind(this); } init() { this.parent.jibo.globalEvents.touchStop.on(this.touchBind); } dispose() { this.parent.jibo.globalEvents.touchStop.removeListener(this.touchBind); } handleHeadTouch(data) { const goal = new HeadTouchGoal_1.HeadTouchGoal(this.parent, data); this.provideGoal(goal); } } exports.HeadTouchGoalProvider = HeadTouchGoalProvider; },{"../GoalProvider":34,"../goals/HeadTouchGoal":49}],40:[function(require,module,exports){ "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const GoalProvider_1 = require("../GoalProvider"); const GoalPriority_1 = require("../GoalPriority"); const Types_1 = require("../../common/Types"); const Utils_1 = require("../../common/Utils"); const SSWGoal_1 = require("../goals/SSWGoal"); const jibo_cai_utils_1 = require("jibo-cai-utils"); const jibo_common_types_1 = require("jibo-common-types"); const jibo_cai_utils_2 = require("jibo-cai-utils"); const log_1 = require("./log"); const PROACTIVE_GREETINGS_MINIMUM_INTERVAL_MS = jibo_cai_utils_1.TimeUtils.secondsToMs(10); class ProactiveGreetingGoalProvider extends GoalProvider_1.GoalProvider { constructor(parent) { super(parent, 'Pro-active Greetings goal provider'); this.FACE_ID_WAIT_TIME = 5; this.handleVisibleFaceBind = this.handleVisibleFace.bind(this); this.handleHJHEardBind = this.handleHJHeard.bind(this); this.handleIdAcquiredBind = this.handleIdAcquired.bind(this); this.handleTimeoutBind = this.handleTimeout.bind(this); this.lastHJHeard = -1; this.timeoutHandle = null; this.timeoutStart = -1; this.lastProactiveOffered = -1; this.disableProactiveTrigger = false; this.log = log_1.log.createChild('ProactiveGreetingGoalProvider'); this.handleTimeoutBind.isGlobalTimer = true; } init() { this.parent.jibo.lps.identity.events.visibleFaceStarted.on(this.handleVisibleFaceBind); this.parent.jibo.jetstream.events.hjHeard.on(this.handleHJHEardBind); this.parent.jibo.lps.identity.events.idAcquired.on(this.handleIdAcquiredBind); } dispose() { this.parent.jibo.lps.identity.events.idAcquired.removeListener(this.handleIdAcquiredBind); this.parent.jibo.jetstream.events.hjHeard.removeListener(this.handleHJHEardBind); this.parent.jibo.lps.identity.events.visibleFaceStarted.removeListener(this.handleVisibleFaceBind); } setDisableProactiveTrigger(bool) { this.disableProactiveTrigger = bool; } handleHJHeard() { const now = this.parent.dateProvider.getDate(); this.lastHJHeard = now.getTime(); } handleVisibleFace() { if (this.timeoutHandle) { this.log.info('got visible face, but already have a timeoutHandle'); } else { this.log.info(`got visible face, setting ${this.FACE_ID_WAIT_TIME} sec timeout`); this.timeoutStart = Date.now(); this.timeoutHandle = this.parent.jibo.timer.setTimeout(this.handleTimeoutBind, jibo_cai_utils_1.TimeUtils.secondsToMs(this.FACE_ID_WAIT_TIME)); } } handleIdAcquired() { return __awaiter(this, void 0, void 0, function* () { const IDdPersons = this.parent.jibo.lps.identity.getPresentPersons().filter(person => (person.id && person.id !== "UNKNOWN" && person.id !== "NOT_TRAINED")); this.log.info(`ID acquired, cancelling timeout and evaluating to trigger greeting. IDs present: ${JSON.stringify(IDdPersons)}`); if (this.timeoutHandle) { this.log.info(`'Visible Face Started' timer ran for ${Date.now() - this.timeoutStart}ms before ID was acquired.`); this.parent.jibo.timer.clearTimeout(this.timeoutHandle); this.timeoutHandle = null; this.timeoutStart = -1; } yield this.triggerIfAllowed(); }); } handleTimeout() { return __awaiter(this, void 0, void 0, function* () { this.log.info('timeout expired'); this.timeoutHandle = null; if (this.parent.jibo.lps.identity.isAnyonePresent()) { this.log.info('person still present, evaluating to trigger greeting'); yield this.triggerIfAllowed(); } else { this.log.info('no one present, not triggering'); } }); } triggerIfAllowed() { return __awaiter(this, void 0, void 0, function* () { const conditionMet = yield this.triggerConditionsMet(); if (conditionMet) { this.log.info('conditions met, triggering proactive greeting'); this.lastProactiveOffered = this.parent.dateProvider.getDate().getTime(); if (this.disableProactiveTrigger) { this.log.warn('proactive greeting triggers have been disabled from package options'); } else { this.triggerProactiveGreeting(); } } else { this.log.info('conditions not met, not triggering greeting'); } }); } triggerConditionsMet() { return __awaiter(this, void 0, void 0, function* () { const state = this.parent.createState(); const now = this.parent.dateProvider.getDate(); const nowMs = now.getTime(); const msInSkill = nowMs - state.skillStartTime.getTime(); const msSinceHJ = nowMs - this.lastHJHeard; const msSinceLastGreeting = nowMs - this.lastProactiveOffered; let verbalGreetingNeeded = false; try { verbalGreetingNeeded = yield this.ungreetedPersonVisible(); } catch (error) { this.log.error("Call to ungreetedPersonVisible failed: ", error); } return (state.skillName === Utils_1.SkillNames.IDLE && jibo_cai_utils_1.TimeUtils.msToSeconds(msInSkill) > 60 && jibo_cai_utils_1.TimeUtils.msToSeconds(msSinceHJ) > 60 && msSinceLastGreeting > PROACTIVE_GREETINGS_MINIMUM_INTERVAL_MS && (state.circadian === jibo_common_types_1.CircadianState.ALERT || state.circadian === jibo_common_types_1.CircadianState.RELAXED) && verbalGreetingNeeded); }); } ungreetedPersonVisible() { return __awaiter(this, void 0, void 0, function* () { let eventDesc = { skillName: "@be/greetings", verbal: true }; const persons = this.parent.jibo.lps.identity.getVisiblePersons(); if (persons.length === 0) { this.log.info("No faces in fov."); return false; } const idPerson = persons.find(person => (person.id && person.id !== "UNKNOWN" && person.id !== "NOT_TRAINED")); if (idPerson) { eventDesc.personIDs = [idPerson.id]; } let timeSince = -1; try { timeSince = yield jibo_cai_utils_2.PromiseUtils.timeout(this.parent.jibo.im.getTimeSinceLast(eventDesc, this.parent.jibo.im.compareQueryFields), 5000); } catch (error) { this.log.warn("Could not get interaction memory result: ", error); } let socialDriveValue = this.parent.jibo.action.getMotivationalDriveValue(this.parent.jibo.action.types.DriveName.SOCIAL); let hours = 1 + (1.0 - socialDriveValue) * 2; let threshold = jibo_cai_utils_1.TimeUtils.hoursToMs(hours); const needsGreeting = timeSince > threshold; const numUnknown = persons.filter(person => (person.id && person.id === "UNKNOWN")).length; const numNotTrained = persons.filter(person => (person.id && person.id === "NOT_TRAINED")).length; const identified = persons.filter(person => (person.id && person.id !== "UNKNOWN" && person.id !== "NOT_TRAINED")); this.log.info(`Verbal proactive greeting needed: ${needsGreeting}. Visible users - ID'd:${JSON.stringify(identified)}, UNKNOWN:${numUnknown}, NOT_TRAINED:${numNotTrained}`); return needsGreeting; }); } triggerProactiveGreeting() { const goal = new SSWGoal_1.SSWGoal(this.parent, { skillName: Utils_1.SkillNames.GREETINGS, skillOptions: { nlu: { skill: Utils_1.SkillNames.GREETINGS, intent: 'proactiveGreeting' } }, criteria: { currentSkill: Utils_1.SkillNames.IDLE } }); goal.options.priority = GoalPriority_1.GoalPriority.Proactive; goal.options.priorityType = Types_1.GoalPriorityType.SINGLETON_KEEP_FIRST; this.provideGoal(goal); } } exports.ProactiveGreetingGoalProvider = ProactiveGreetingGoalProvider; },{"../../common/Types":26,"../../common/Utils":28,"../GoalPriority":33,"../GoalProvider":34,"../goals/SSWGoal":51,"./log":43,"jibo-cai-utils":undefined,"jibo-common-types":undefined}],41:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const GoalProvider_1 = require("../GoalProvider"); const SnuggleGoal_1 = require("../goals/SnuggleGoal"); const Types_1 = require("../../common/Types"); const Utils_1 = require("../../common/Utils"); class SnuggleGoalProvider extends GoalProvider_1.GoalProvider { constructor(parent) { super(parent, 'Snuggle Goal Provider'); this.hatchOpen = () => { this.performSnuggle(Types_1.SnuggleType.HATCH_OPEN); }; this.hatchClose = () => { this.performSnuggle(Types_1.SnuggleType.HATCH_CLOSE); }; this.pluggedIn = () => { this.performSnuggle(Types_1.SnuggleType.PLUG); }; this.unplugged = () => { this.performSnuggle(Types_1.SnuggleType.UNPLUG); }; this.axisFault = () => { this.performSnuggle(Types_1.SnuggleType.AXIS_FAULT); }; } init() { this.parent.jibo.system.events.hatchOpen.on(this.hatchOpen); this.parent.jibo.system.events.hatchClose.on(this.hatchClose); this.parent.jibo.system.events.pluggedIn.on(this.pluggedIn); this.parent.jibo.system.events.unplugged.on(this.unplugged); this.parent.jibo.system.events.axisFaultOn.on(this.axisFault); } dispose() { this.parent.jibo.system.events.hatchOpen.removeListener(this.hatchOpen); this.parent.jibo.system.events.hatchClose.removeListener(this.hatchClose); this.parent.jibo.system.events.pluggedIn.removeListener(this.pluggedIn); this.parent.jibo.system.events.unplugged.removeListener(this.unplugged); this.parent.jibo.system.events.axisFaultOn.removeListener(this.axisFault); } performSnuggle(type) { const state = this.parent.createState(); if ((state.skillName !== Utils_1.SkillNames.TUTORIAL) && (state.skillName !== Utils_1.SkillNames.FIRST_CONTACT)) { const goal = new SnuggleGoal_1.SnuggleGoal(this.parent, type); this.provideGoal(goal); } } } exports.SnuggleGoalProvider = SnuggleGoalProvider; },{"../../common/Types":26,"../../common/Utils":28,"../GoalProvider":34,"../goals/SnuggleGoal":52}],42:[function(require,module,exports){ "use strict"; function __export(m) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; } Object.defineProperty(exports, "__esModule", { value: true }); __export(require("./HJGoalProvider")); __export(require("./HJOnlyGoalProvider")); __export(require("./ProactiveGreetingGoalProvider")); __export(require("./HJNoMatchGoalProvider")); __export(require("./SnuggleGoalProvider")); },{"./HJGoalProvider":36,"./HJNoMatchGoalProvider":37,"./HJOnlyGoalProvider":38,"./ProactiveGreetingGoalProvider":40,"./SnuggleGoalProvider":41}],43:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const jibo_log_1 = require("jibo-log"); exports.Log = jibo_log_1.Log; const log_1 = require("../log"); const log = log_1.log.createChild('Provider'); exports.log = log; },{"../log":55,"jibo-log":undefined}],44:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const Goal_1 = require("../Goal"); const GoalPriority_1 = require("../GoalPriority"); class AnimationGoal extends Goal_1.Goal { constructor(parent, data, goalPriority) { super(parent, AnimationGoal.getName(data), { priority: GoalPriority_1.GoalPriority.Animation, criteria: data.criteria, priorityType: goalPriority }); this.data = data; } static getName(data) { let name = `Play Animation Goal [`; name += (data.category) ? `cat: ${data.category}]` : `name: ${data.name}]`; return name; } } exports.AnimationGoal = AnimationGoal; },{"../Goal":31,"../GoalPriority":33}],45:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const Goal_1 = require("../Goal"); const Types_1 = require("../../common/Types"); const GoalPriority_1 = require("../GoalPriority"); class BeSSWGoal extends Goal_1.Goal { constructor(parent, data, name = `Be Skill Switch Goal: '${data.skillName}'`) { super(parent, name, { priority: GoalPriority_1.GoalPriority.BeSkillSwitch, criteria: data.criteria, priorityType: Types_1.GoalPriorityType.SINGLETON_KEEP_LAST }); this.data = data; if (data.beSkillPreferences) { if (data.beSkillPreferences.cancelOrientOnStart) { this.options.priority = GoalPriority_1.GoalPriority.HeyJibo + 1; } } } } exports.BeSSWGoal = BeSSWGoal; },{"../../common/Types":26,"../Goal":31,"../GoalPriority":33}],46:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const Goal_1 = require("../Goal"); const GoalPriority_1 = require("../GoalPriority"); class FindPersonGoal extends Goal_1.Goal { constructor(parent) { super(parent, 'Find person goal', { priority: GoalPriority_1.GoalPriority.FindPerson, }); } } exports.FindPersonGoal = FindPersonGoal; },{"../Goal":31,"../GoalPriority":33}],47:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const Types_1 = require("../../common/Types"); const Goal_1 = require("../Goal"); const GoalPriority_1 = require("../GoalPriority"); class HJGoal extends Goal_1.Goal { constructor(parent, hjData) { super(parent, 'Hey Jibo', { priority: GoalPriority_1.GoalPriority.HeyJibo, priorityType: Types_1.GoalPriorityType.SINGLETON_KEEP_LAST }); this.hjData = hjData; } } exports.HJGoal = HJGoal; },{"../../common/Types":26,"../Goal":31,"../GoalPriority":33}],48:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const Goal_1 = require("../Goal"); const jibo_cai_utils_1 = require("jibo-cai-utils"); const GoalPriority_1 = require("../GoalPriority"); class HJOnlyGoal extends Goal_1.Goal { constructor(parent) { super(parent, 'Hey Jibo Only', { priority: GoalPriority_1.GoalPriority.HJOnly, }); } canBeCulled(state) { const seconds = jibo_cai_utils_1.TimeUtils.msToSeconds(this.parent.dateProvider.getDate().getTime() - this.created.getTime()); return super.canBeCulled(state) || (seconds > 10); } } exports.HJOnlyGoal = HJOnlyGoal; },{"../Goal":31,"../GoalPriority":33,"jibo-cai-utils":undefined}],49:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const Goal_1 = require("../Goal"); const GoalPriority_1 = require("../GoalPriority"); const jibo_cai_utils_1 = require("jibo-cai-utils"); const Types_1 = require("../../common/Types"); class HeadTouchGoal extends Goal_1.Goal { constructor(parent, data) { super(parent, 'Head Touch', { priority: GoalPriority_1.GoalPriority.HeadTouch, priorityType: Types_1.GoalPriorityType.SINGLETON_KEEP_FIRST, maxAttempts: 1 }); this.data = data; } canBeCulled(state) { const seconds = jibo_cai_utils_1.TimeUtils.msToSeconds(this.parent.dateProvider.getDate().getTime() - this.created.getTime()); return super.canBeCulled(state) || (seconds > 0.5); } } exports.HeadTouchGoal = HeadTouchGoal; },{"../../common/Types":26,"../Goal":31,"../GoalPriority":33,"jibo-cai-utils":undefined}],50:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const Goal_1 = require("../Goal"); const common_1 = require("../../common"); const GoalPriority_1 = require("../GoalPriority"); const Types_1 = require("../../common/Types"); class MotivationGoal extends Goal_1.Goal { constructor(parent) { super(parent, 'MotivationGoal', { priority: GoalPriority_1.GoalPriority.Motivation, priorityType: Types_1.GoalPriorityType.SINGLETON_KEEP_FIRST, maxAttempts: 1, }); } isEligible(state) { if (state.skillName !== common_1.SkillNames.IDLE) { return false; } return this.parent.motivations.drivesAboveThreshold().length > 0; } canBeCulled(state) { return !(this.parent.motivations.drivesAboveThreshold().length > 0); } } exports.MotivationGoal = MotivationGoal; },{"../../common":29,"../../common/Types":26,"../Goal":31,"../GoalPriority":33}],51:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const Goal_1 = require("../Goal"); const Types_1 = require("../../common/Types"); const GoalPriority_1 = require("../GoalPriority"); class SSWGoal extends Goal_1.Goal { constructor(parent, data, name = `Skill Launch: '${data.skillName}'`) { super(parent, name, { priority: GoalPriority_1.GoalPriority.SkillSwitch, criteria: data.criteria, priorityType: Types_1.GoalPriorityType.SINGLETON_KEEP_LAST }); this.data = data; } } exports.SSWGoal = SSWGoal; },{"../../common/Types":26,"../Goal":31,"../GoalPriority":33}],52:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const Types_1 = require("../../common/Types"); const Goal_1 = require("../Goal"); const GoalPriority_1 = require("../GoalPriority"); class SnuggleGoal extends Goal_1.Goal { constructor(parent, type) { super(parent, 'Snuggle', { priority: GoalPriority_1.GoalPriority.Snuggle, priorityType: Types_1.GoalPriorityType.SINGLETON_KEEP_LAST }); this.type = type; } } exports.SnuggleGoal = SnuggleGoal; },{"../../common/Types":26,"../Goal":31,"../GoalPriority":33}],53:[function(require,module,exports){ "use strict"; function __export(m) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; } Object.defineProperty(exports, "__esModule", { value: true }); __export(require("./HJGoal")); __export(require("./SSWGoal")); __export(require("./BeSSWGoal")); __export(require("./HJOnlyGoal")); __export(require("./AnimationGoal")); __export(require("./FindPersonGoal")); __export(require("./HeadTouchGoal")); __export(require("./SnuggleGoal")); },{"./AnimationGoal":44,"./BeSSWGoal":45,"./FindPersonGoal":46,"./HJGoal":47,"./HJOnlyGoal":48,"./HeadTouchGoal":49,"./SSWGoal":51,"./SnuggleGoal":52}],54:[function(require,module,exports){ "use strict"; function __export(m) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; } Object.defineProperty(exports, "__esModule", { value: true }); __export(require("./Goal")); __export(require("./GoalSet")); __export(require("./GoalProvider")); __export(require("./GoalPriority")); __export(require("./GoalParallelism")); const goalproviders = require("./goalproviders"); exports.goalproviders = goalproviders; const goals = require("./goals"); exports.goals = goals; },{"./Goal":31,"./GoalParallelism":32,"./GoalPriority":33,"./GoalProvider":34,"./GoalSet":35,"./goalproviders":42,"./goals":53}],55:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const jibo_log_1 = require("jibo-log"); exports.Log = jibo_log_1.Log; const log_1 = require("../common/log"); const log = log_1.log.createChild('Goal'); exports.log = log; },{"../common/log":30,"jibo-log":undefined}],56:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const Utils_1 = require("../common/Utils"); const jibo_cai_utils_1 = require("jibo-cai-utils"); class Drive { constructor(name, ratePerMin = 0, shouldCauseGoal = true) { this.name = name; this.shouldCauseGoal = shouldCauseGoal; this.ratePerMin = 0; this.threshold = 1; this._value = 0; if (ratePerMin < 0) { console.error(`invalid rate for drive ${name}: ${ratePerMin}. Setting to 0.`); ratePerMin = 0; } this.ratePerMin = ratePerMin; } get value() { return this._value; } update() { this.computeDriveIncrement(); } applyEffect(effect) { this._value = Utils_1.constrainToBounds(this.value + effect, 0, 1); } computeDriveIncrement() { if (!this.lastUpdate) { this.lastUpdate = Date.now(); } else { let now = Date.now(); let delta_t = now - this.lastUpdate; let delta_d = jibo_cai_utils_1.TimeUtils.msToMinutes(delta_t) * this.ratePerMin; this._value = Utils_1.constrainToBounds(this._value + delta_d, 0, 1); this.lastUpdate = now; } } } exports.Drive = Drive; },{"../common/Utils":28,"jibo-cai-utils":undefined}],57:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const MotivationGoal_1 = require("../goal/goals/MotivationGoal"); const GoalProvider_1 = require("../goal/GoalProvider"); const Types_1 = require("../common/Types"); const WakingDrive_1 = require("./drives/WakingDrive"); const log_1 = require("../common/log"); class MotivationGoalProvider extends GoalProvider_1.GoalProvider { constructor(parent) { super(parent, `Motivation`); } init() { } dispose() { } } exports.MotivationGoalProvider = MotivationGoalProvider; class MotivationSystem { constructor(parent) { this.parent = parent; this.drives = new Map(); this.drives.set(Types_1.DriveName.SOCIAL, new WakingDrive_1.WakingDrive(this.parent, Types_1.DriveName.SOCIAL, 1 / 120)); this.drives.set(Types_1.DriveName.PLAYFUL, new WakingDrive_1.WakingDrive(this.parent, Types_1.DriveName.PLAYFUL, 1 / 360, false)); this.goalProvider = new MotivationGoalProvider(parent); this.log = log_1.log.createChild('Motivation'); } update() { let makeGoal = false; this.drives.forEach((drive) => { drive.update(); if ((drive.value >= drive.threshold) && drive.shouldCauseGoal) { makeGoal = true; } }); if (makeGoal) { this.goalProvider.provideGoal(new MotivationGoal_1.MotivationGoal(this.parent)); } } applyMotivationalEffects(action) { action.options.driveEffects.forEach((dv, dn) => { this.parent.motivations.drives.get(dn).applyEffect(dv); }); } drivesAboveThreshold() { let aboveThreshold = new Array(); this.drives.forEach((d) => { if (d.value >= d.threshold) { aboveThreshold.push(d); } }); return aboveThreshold; } } exports.MotivationSystem = MotivationSystem; },{"../common/Types":26,"../common/log":30,"../goal/GoalProvider":34,"../goal/goals/MotivationGoal":50,"./drives/WakingDrive":58}],58:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const Drive_1 = require("../Drive"); const jibo_common_types_1 = require("jibo-common-types"); class WakingDrive extends Drive_1.Drive { constructor(parent, name, ratePerMin = 0, shouldCauseGoal = true) { super(name, ratePerMin, shouldCauseGoal); this.parent = parent; this.shouldCauseGoal = shouldCauseGoal; this._wakingRatePerMin = this.ratePerMin; } update() { let currentCircadianState = this.parent.createState().circadian; if (currentCircadianState === jibo_common_types_1.CircadianState.ALERT || currentCircadianState === jibo_common_types_1.CircadianState.RELAXED) { this.ratePerMin = this._wakingRatePerMin; } else { this.ratePerMin = 0; this._value = 0; } super.update(); } } exports.WakingDrive = WakingDrive; },{"../Drive":56,"jibo-common-types":undefined}],59:[function(require,module,exports){ "use strict"; function __export(m) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; } Object.defineProperty(exports, "__esModule", { value: true }); __export(require("./WakingDrive")); },{"./WakingDrive":58}],60:[function(require,module,exports){ "use strict"; function __export(m) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; } Object.defineProperty(exports, "__esModule", { value: true }); const drives = require("./drives"); exports.drives = drives; __export(require("./Drive")); __export(require("./MotivationSystem")); },{"./Drive":56,"./MotivationSystem":57,"./drives":59}],61:[function(require,module,exports){ "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const fs = require("fs"); const path = require("path"); const Utils_1 = require("../common/Utils"); const GoalPriority_1 = require("../goal/GoalPriority"); const GoalProvider_1 = require("../goal/GoalProvider"); const SSWGoal_1 = require("../goal/goals/SSWGoal"); const SignalHJStatus_1 = require("./signals/inhibitors/SignalHJStatus"); const SignalJiboStatus_1 = require("./signals/inhibitors/SignalJiboStatus"); const SignalSkillStatus_1 = require("./signals/inhibitors/SignalSkillStatus"); const SignalNoMatchStatus_1 = require("./signals/inhibitors/SignalNoMatchStatus"); const SignalRateLimiterStatus_1 = require("./signals/inhibitors/SignalRateLimiterStatus"); const SignalIDAcquired_1 = require("./signals/firers/SignalIDAcquired"); const SignalFacePersisted_1 = require("./signals/firers/SignalFacePersisted"); const SignalSurprise_1 = require("./signals/firers/SignalSurprise"); const inhibitors_1 = require("./signals/inhibitors"); const SignalLoudEnvironmentStatus_1 = require("./signals/inhibitors/SignalLoudEnvironmentStatus"); const arrival_1 = require("./signals/firers/arrival"); const log_1 = require("./log"); const SensorTypes = require("./signals/firers/arrival/SensorTypes"); const log = log_1.log.createChild('OpportunityDetector'); class OpportunityDetector extends GoalProvider_1.GoalProvider { constructor(parent) { super(parent, 'Proactive Opportunity Detector trigger provider'); this.signalIDAcquired = new SignalIDAcquired_1.SignalIDAcquired(this.parent, "ID Acquired Firing Signal", this); this.signalFacePersisted = new SignalFacePersisted_1.SignalFacePersisted(this.parent, "Face Persisted Firing Signal", this); this.signalSurprise = new SignalSurprise_1.SignalSurprise(this.parent, "Surprise Firing Signal", this); this.arrivalTracker = new arrival_1.ArrivalTracker(this.parent, "Arrival Tracker Firing Signal", this); this.signalJiboStatus = new SignalJiboStatus_1.SignalJiboStatus(this.parent, "Jibo Status Inhibiting Signal"); this.signalSkillStatus = new SignalSkillStatus_1.SignalSkillStatus(this.parent, "Skill Status Inhibiting Signal"); this.signalNoMatchStatus = new SignalNoMatchStatus_1.SignalNoMatchStatus(this.parent, "No Match Status Inhibiting Signal"); this.signalHJStatus = new SignalHJStatus_1.SignalHJStatus(this.parent, "HJ Status Inhibiting Signal"); this.signalRateLimiterStatus = new SignalRateLimiterStatus_1.SignalRateLimiterStatus(this.parent, "Rate Limiter Status Inhibiting Signal"); this.signalVADStatus = new inhibitors_1.SignalVADStatus(this.parent, "VAD Status Inhibiting Signal"); this.signalLoudEnvironmentStatus = new SignalLoudEnvironmentStatus_1.SignalLoudEnvironmentStatus(this.parent, "Audio Intensity Inhibiting Signal"); this.jetstreamTimeoutHandle = null; this.lastProactiveResponse = null; this.disableProactiveTrigger = false; this.podSignals = []; this.handleJetstreamTimeoutBind = () => this.handleJetstreamTimeout(); this.handleSkillRelaunchBind = (data) => this.handleSkillRelaunch(data); this.parent = parent; this.handleJetstreamTimeoutBind.isGlobalTimer = true; this.podSignals.push(this.signalJiboStatus); this.podSignals.push(this.signalSkillStatus); this.podSignals.push(this.signalHJStatus); this.podSignals.push(this.signalNoMatchStatus); this.podSignals.push(this.signalRateLimiterStatus); this.podSignals.push(this.signalVADStatus); this.podSignals.push(this.signalLoudEnvironmentStatus); this.podSignals.push(this.signalIDAcquired); this.podSignals.push(this.signalFacePersisted); this.podSignals.push(this.signalSurprise); this.podSignals.push(this.arrivalTracker); } init() { this.podSignals.forEach(ps => ps.init()); this.parent.jibo.globalEvents.skillRelaunch.on(this.handleSkillRelaunchBind); } dispose() { this.podSignals.forEach(ps => ps.dispose()); this.parent.jibo.globalEvents.skillRelaunch.removeListener(this.handleSkillRelaunchBind); } update() { this.arrivalTracker.update(); } triggerGreeting() { const goal = new SSWGoal_1.SSWGoal(this.parent, { skillName: Utils_1.SkillNames.GREETINGS, skillOptions: { nlu: { entities: { skill: Utils_1.SkillNames.GREETINGS, }, intent: 'proactiveGreeting' } }, criteria: { currentSkill: Utils_1.SkillNames.IDLE } }); goal.options.priority = GoalPriority_1.GoalPriority.Proactive; this.provideGoal(goal); } setDisableProactiveTrigger(disable) { this.disableProactiveTrigger = disable; } evaluate(proactiveRequest) { log.info("Evaluating trigger source: " + proactiveRequest.triggerSource + " with looperID: ", proactiveRequest.triggerData.looperID); if (this.checkInhibitors()) { log.info("Passed all inhibitors"); if (this.disableProactiveTrigger) { log.debug("Sending trigger messsages to Jetstream have been disabled from package options"); } else { this.sendTrigger(proactiveRequest); this.signalRateLimiterStatus.addTriggerEvent(); } } else { log.info("Failed an inhibitor"); } } checkEnvironmentInhibitors() { return this.signalVADStatus.evaluate() && this.signalLoudEnvironmentStatus.evaluate(); } checkInhibitors() { return this.signalHJStatus.evaluate() && this.signalJiboStatus.evaluate() && this.signalSkillStatus.evaluate() && this.signalNoMatchStatus.evaluate() && this.signalRateLimiterStatus.evaluate() && this.checkEnvironmentInhibitors(); } sendTrigger(proactiveRequest) { return __awaiter(this, void 0, void 0, function* () { log.info("Sending proactive trigger to jetstream"); this.jetstreamTimeoutHandle = this.parent.jibo.timer.setTimeout(this.handleJetstreamTimeoutBind, OpportunityDetector.MAX_JETSTREAM_RESPONSE_TIMEOUT_MS); try { const requestTimestamp = Date.now(); const proactiveSession = yield this.parent.jibo.jetstream.triggerProactive(proactiveRequest); const proactiveResponse = yield proactiveSession.promise; this.parent.jibo.timer.clearTimeout(this.jetstreamTimeoutHandle); this.jetstreamTimeoutHandle = null; if (proactiveResponse.match) { this.lastProactiveResponse = { skillName: proactiveResponse.match.skillID, timestamp: requestTimestamp, }; if (proactiveRequest.triggerData.looperID && proactiveRequest.triggerSource === this.parent.jibo.jetstream.types.ProactiveTriggerSource.NEW_ARRIVAL) { log.info(`Updating identity service active speaker to ${proactiveRequest.triggerData.looperID}`); this.parent.jibo.lps.identity.setActiveSpeaker({ speakers: [{ speaker: proactiveRequest.triggerData.looperID, score: 100, accepted: true, high_confidence: true, }], snr: 1 }, 'JCP'); } } const deltaTime = Date.now() - requestTimestamp; log.info(`Got a successful jetstream response in ${deltaTime} milliseconds`); } catch (err) { log.error(err.message); } }); } handleJetstreamTimeout() { log.warn(`A proactive trigger was sent but did not receive a response from jetstream within ${OpportunityDetector.MAX_JETSTREAM_RESPONSE_TIMEOUT_MS} milliseconds`); } handleSkillRelaunch(data) { if (this.lastProactiveResponse) { const skillName = data.match && data.match.skillID; const isProactive = data.match && data.match.isProactive; if (isProactive && this.lastProactiveResponse.skillName === skillName) { const deltaTime = Date.now() - this.lastProactiveResponse.timestamp; if (deltaTime < OpportunityDetector.MAX_SKILLSWITCH_RESPONSE_TIMEOUT_MS) { log.info(`Got a successful skill switch response to ${skillName} in ${deltaTime} milliseconds`); } else { log.warn(`Got a slow skill switch response to ${skillName} in ${deltaTime} milliseconds which exceeds our max response time of ${OpportunityDetector.MAX_SKILLSWITCH_RESPONSE_TIMEOUT_MS} milliseconds`); } this.lastProactiveResponse = null; } } } resetArrivalTrackerSM() { this.arrivalTracker.emitResetEvent(); } static Configure(configuration) { try { OpportunityDetector.MAX_JETSTREAM_RESPONSE_TIMEOUT_MS = configuration.MAX_JETSTREAM_RESPONSE_TIMEOUT_MS; OpportunityDetector.MAX_SKILLSWITCH_RESPONSE_TIMEOUT_MS = configuration.MAX_SKILLSWITCH_RESPONSE_TIMEOUT_MS; } catch (e) { log.error("Could not configure static variables based on configuration file: ", e); } } } OpportunityDetector.MAX_JETSTREAM_RESPONSE_TIMEOUT_MS = 2500; OpportunityDetector.MAX_SKILLSWITCH_RESPONSE_TIMEOUT_MS = 3000; exports.OpportunityDetector = OpportunityDetector; const findRoot = require('find-root'); const ROOT_PATH = findRoot(__dirname); try { const configFile = fs.readFileSync(path.join(ROOT_PATH, 'config/ProactiveConfiguration.json'), 'utf8'); const configJSON = JSON.parse(configFile); OpportunityDetector.Configure(configJSON.OpportunityDetector); arrival_1.ArrivalTracker.Configure(configJSON.ArrivalTracker); Object.assign(SensorTypes.faceIDAcquiredSensor, configJSON.SensorTypes.faceIDAcquiredSensor); Object.assign(SensorTypes.facePersistedSensor, configJSON.SensorTypes.facePersistedSensor); Object.assign(SensorTypes.hjHeardSensor, configJSON.SensorTypes.hjHeardSensor); Object.assign(SensorTypes.headTouchedSensor, configJSON.SensorTypes.headTouchedSensor); Object.assign(SensorTypes.motionEntitySensor, configJSON.SensorTypes.motionEntitySensor); Object.assign(SensorTypes.localizedSoundSensor, configJSON.SensorTypes.localizedSoundSensor); Object.assign(SensorTypes.loudSoundSpikeSensor, configJSON.SensorTypes.loudSoundSpikeSensor); Object.assign(SensorTypes.screenTouchedSensor, configJSON.SensorTypes.screenTouchedSensor); Object.assign(SensorTypes.heardVoicesSensor, configJSON.SensorTypes.heardVoicesSensor); Object.assign(SensorTypes.visibleFaceSensor, configJSON.SensorTypes.visibleFaceSensor); SignalFacePersisted_1.SignalFacePersisted.Configure(configJSON.Signals.SignalFacePersisted); SignalHJStatus_1.SignalHJStatus.Configure(configJSON.Signals.SignalHJStatus); SignalLoudEnvironmentStatus_1.SignalLoudEnvironmentStatus.Configure(configJSON.Signals.SignalLoudEnvironmentStatus); SignalNoMatchStatus_1.SignalNoMatchStatus.Configure(configJSON.Signals.SignalNoMatchStatus); SignalRateLimiterStatus_1.SignalRateLimiterStatus.Configure(configJSON.Signals.SignalRateLimiterStatus); inhibitors_1.SignalVADStatus.Configure(configJSON.Signals.SignalVADStatus); } catch (error) { console.error("Error loading ProactiveConfiguration.json in jibo-action-system for proactive configuration", error); } },{"../common/Utils":28,"../goal/GoalPriority":33,"../goal/GoalProvider":34,"../goal/goals/SSWGoal":51,"./log":63,"./signals/firers/SignalFacePersisted":67,"./signals/firers/SignalIDAcquired":68,"./signals/firers/SignalSurprise":69,"./signals/firers/arrival":72,"./signals/firers/arrival/SensorTypes":71,"./signals/inhibitors":82,"./signals/inhibitors/SignalHJStatus":75,"./signals/inhibitors/SignalJiboStatus":76,"./signals/inhibitors/SignalLoudEnvironmentStatus":77,"./signals/inhibitors/SignalNoMatchStatus":78,"./signals/inhibitors/SignalRateLimiterStatus":79,"./signals/inhibitors/SignalSkillStatus":80,"find-root":undefined,"fs":undefined,"path":undefined}],62:[function(require,module,exports){ "use strict"; function __export(m) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; } Object.defineProperty(exports, "__esModule", { value: true }); const signals = require("./signals"); exports.signals = signals; __export(require("./OpportunityDetector")); },{"./OpportunityDetector":61,"./signals":74}],63:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const log_1 = require("../common/log"); exports.log = log_1.log.createChild('Proactive'); },{"../common/log":30}],64:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const PODSignal_1 = require("./PODSignal"); class FiringSignal extends PODSignal_1.PODSignal { constructor(parent, name, detector) { super(parent, name); this.detector = detector; } } exports.FiringSignal = FiringSignal; },{"./PODSignal":66}],65:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const PODSignal_1 = require("./PODSignal"); class InhibitingSignal extends PODSignal_1.PODSignal { constructor(parent, name) { super(parent, name); } } exports.InhibitingSignal = InhibitingSignal; },{"./PODSignal":66}],66:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const jibo_typed_events_1 = require("jibo-typed-events"); class PODSignal extends jibo_typed_events_1.EventContainer { constructor(parent, name) { super(); this.parent = parent; this.name = name; } } exports.PODSignal = PODSignal; },{"jibo-typed-events":undefined}],67:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const jibo_common_types_1 = require("jibo-common-types"); const jibo_cai_utils_1 = require("jibo-cai-utils"); const jibo_typed_events_1 = require("jibo-typed-events"); const log_1 = require("../../log"); const FiringSignal_1 = require("../FiringSignal"); const log = log_1.log.createChild('SignalFacePersisted'); class SignalFacePersisted extends FiringSignal_1.FiringSignal { constructor(parent, name, detector) { super(parent, name, detector); this.facePersisted = new jibo_typed_events_1.Event("Face Persisted"); this.currEntityIDs = new Set(); this.timeoutHandle = null; this.timeoutStartMs = null; this.handleVisibleFaceStartedBind = () => this.handleVisibleFaceStarted(); this.handleEntityTimeoutBind = () => this.handleEntityTimeout(); this.handleIDAcquiredBind = (data) => this.handleIDAcquired(data); this.handleEntityTimeoutBind.isGlobalTimer = true; } init() { this.parent.jibo.lps.identity.events.idAcquired.on(this.handleIDAcquiredBind); this.parent.jibo.lps.identity.events.visibleFaceStarted.on(this.handleVisibleFaceStartedBind); } dispose() { this.parent.jibo.lps.identity.events.idAcquired.removeListener(this.handleIDAcquiredBind); this.parent.jibo.lps.identity.events.visibleFaceStarted.removeListener(this.handleVisibleFaceStartedBind); } handleVisibleFaceStarted() { if (this.timeoutHandle) { log.debug("Got visible face, but already have a timeoutHandle"); } else { this.parent.jibo.lps.identity.getVisibleFaces().forEach((entity) => { log.debug("Got visible face of entity ID " + entity.id); this.currEntityIDs.add(entity.id); }); this.timeoutHandle = this.parent.jibo.timer.setTimeout(this.handleEntityTimeoutBind, SignalFacePersisted.FACE_ID_WAIT_TIME_MS); this.timeoutStartMs = Date.now(); } } handleEntityTimeout() { let matchedEntityID = null; const visibleFaces = this.parent.jibo.lps.identity.getVisibleFaces(); if (visibleFaces.size) { visibleFaces.forEach((entity) => { if (this.currEntityIDs.has(entity.id)) { log.debug("Persisting face timeout expired. I found same ID " + entity.id); matchedEntityID = entity.id; return; } else { log.debug("Persisting face timeout expired. I did not find ID " + entity.id); } }); } else { log.debug("Persisting face timeout expired. I have zero IDs"); } this.timeoutHandle = null; this.timeoutStartMs = null; this.currEntityIDs.clear(); if (matchedEntityID) { const presentPersons = this.parent.jibo.lps.identity.getPresentPersons(); const personID = presentPersons.find(person => (person.entityId === matchedEntityID && person.id !== "UNKNOWN" && person.id !== "NOT_TRAINED")); const emitID = personID ? personID.id : null; log.info(`Persisting face entity ID ${matchedEntityID} has an identity of ${emitID}`); this.facePersisted.emit(emitID); } } handleIDAcquired(presence) { if (this.timeoutHandle && presence.identificationSource === jibo_common_types_1.IdentificationSource.FACE) { const deltaMs = jibo_cai_utils_1.TimeUtils.msToSeconds(Date.now() - this.timeoutStartMs); log.debug(`FaceID finally occured after ${deltaMs} seconds. Clearing out persisting face timeout`); this.parent.jibo.timer.clearTimeout(this.timeoutHandle); this.timeoutHandle = null; this.timeoutStartMs = null; } } static Configure(configuration) { try { SignalFacePersisted.FACE_ID_WAIT_TIME_MS = jibo_cai_utils_1.TimeUtils.secondsToMs(configuration.FACE_ID_WAIT_TIME_SECS); } catch (e) { log.error("Could not configure static variables based on configuration file: ", e); } } } SignalFacePersisted.FACE_ID_WAIT_TIME_MS = jibo_cai_utils_1.TimeUtils.secondsToMs(4.5); exports.SignalFacePersisted = SignalFacePersisted; },{"../../log":63,"../FiringSignal":64,"jibo-cai-utils":undefined,"jibo-common-types":undefined,"jibo-typed-events":undefined}],68:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const jibo_common_types_1 = require("jibo-common-types"); const jibo_typed_events_1 = require("jibo-typed-events"); const log_1 = require("../../log"); const FiringSignal_1 = require("../FiringSignal"); const log = log_1.log.createChild('SignalIDAcquired'); class SignalIDAcquired extends FiringSignal_1.FiringSignal { constructor() { super(...arguments); this.faceIDAcquired = new jibo_typed_events_1.Event("Face ID Acquired"); this.handleIDAcquiredBind = (data) => this.handleIDAcquired(data); } init() { this.parent.jibo.lps.identity.events.idAcquired.on(this.handleIDAcquiredBind); } dispose() { this.parent.jibo.lps.identity.events.idAcquired.removeListener(this.handleIDAcquiredBind); } handleIDAcquired(presence) { log.debug(`ID acquired ${presence.name}. By source: ${presence.identificationSource}`); if (presence.identificationSource === jibo_common_types_1.IdentificationSource.FACE) { this.faceIDAcquired.emit(presence.name); } } } exports.SignalIDAcquired = SignalIDAcquired; },{"../../log":63,"../FiringSignal":64,"jibo-common-types":undefined,"jibo-typed-events":undefined}],69:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const Utils_1 = require("../../../common/Utils"); const log_1 = require("../../log"); const FiringSignal_1 = require("../FiringSignal"); const log = log_1.log.createChild('SignalSurprise'); class SignalSurprise extends FiringSignal_1.FiringSignal { constructor() { super(...arguments); this.handleSkillChangeBind = (data) => this.handleSkillChange(data); } init() { this.parent.events.skillChange.on(this.handleSkillChangeBind); } dispose() { this.parent.events.skillChange.removeListener(this.handleSkillChangeBind); } handleSkillChange(skillChange) { const [oldSkill, newSkill] = skillChange; if (oldSkill === Utils_1.SkillNames.SURPRISES && newSkill === Utils_1.SkillNames.IDLE) { log.debug("Skipped surprise event. Sending surprise-type proactive trigger"); const speaker = this.parent.jibo.lps.identity.getActiveSpeaker(); const surpriseRequest = { triggerSource: this.parent.jibo.jetstream.types.ProactiveTriggerSource.SURPRISE, triggerData: { looperID: speaker ? speaker.idInfo.id : null, } }; this.detector.evaluate(surpriseRequest); } } } exports.SignalSurprise = SignalSurprise; },{"../../../common/Utils":28,"../../log":63,"../FiringSignal":64}],70:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const jibo_typed_events_1 = require("jibo-typed-events"); const jibo_state_machine_1 = require("jibo-state-machine"); const jibo_cai_utils_1 = require("jibo-cai-utils"); const log_1 = require("../../../log"); const FiringSignal_1 = require("../../FiringSignal"); const SensorTypes = require("./SensorTypes"); const log = log_1.log.createChild('ArrivalTracker'); class ArrivalTracker extends FiringSignal_1.FiringSignal { constructor() { super(...arguments); this.timer = null; this.timerExpiryMs = -1; this.lastStateMachineTick = 0; this.lastPrintoutTick = 0; this.recentSoundDetected = false; this.recentMotionDetected = false; this.recentFaceDetected = false; this.recentVoicesHeard = false; this.faceIDAcquiredListener = (entityID) => { const sensor = Object.assign({}, SensorTypes.faceIDAcquiredSensor, { looperID: entityID }); log.debug('Registered face ID acquired'); this.emitHardEvidence(entityID, sensor); }; this.facePersistedListener = (entityID) => { const sensor = Object.assign({}, SensorTypes.facePersistedSensor, { looperID: entityID }); log.debug('Registered face persisted'); this.emitHardEvidence(entityID, sensor); }; this.hjHeardListener = (data) => { log.debug('Registered HJ heard'); this.emitHardEvidence(data, SensorTypes.hjHeardSensor); }; this.headTouchListener = (data) => { log.debug('Registered head touch'); this.emitModerateEvidence(data, SensorTypes.headTouchedSensor); }; this.screenTouchListener = (data) => { log.debug('Registered screen touch'); this.emitModerateEvidence(data, SensorTypes.screenTouchedSensor); }; this.ambientAudioSpikeListener = (data) => { log.debug('Registered loud spike sound'); this.emitSoftEvidence(data, SensorTypes.loudSoundSpikeSensor); }; } init() { this.detector.signalIDAcquired.faceIDAcquired.on(this.faceIDAcquiredListener); this.detector.signalFacePersisted.facePersisted.on(this.facePersistedListener); this.parent.jibo.jetstream.events.hjHeard.on(this.hjHeardListener); this.parent.jibo.system.events.touchOn.on(this.headTouchListener); this.parent.jibo.globalEvents.shared.screenGesture.on(this.screenTouchListener); this.parent.jibo.lps.detector.ambientAudioSpike.trigger.on(this.ambientAudioSpikeListener); this.createAndStartStateMachine(); } dispose() { this.detector.signalIDAcquired.faceIDAcquired.removeListener(this.faceIDAcquiredListener); this.detector.signalFacePersisted.facePersisted.removeListener(this.facePersistedListener); this.parent.jibo.jetstream.events.hjHeard.removeListener(this.hjHeardListener); this.parent.jibo.system.events.touchOn.removeListener(this.headTouchListener); this.parent.jibo.globalEvents.shared.screenGesture.removeListener(this.screenTouchListener); this.parent.jibo.lps.detector.ambientAudioSpike.trigger.removeListener(this.ambientAudioSpikeListener); this.sm.stop(); } update() { const deltaSM = Date.now() - this.lastStateMachineTick; const deltaPrintout = Date.now() - this.lastPrintoutTick; const audibleEntity = this.parent.jibo.lps.getClosestAudibleEntity(); if (audibleEntity && audibleEntity.confidence >= SensorTypes.localizedSoundSensor.threshold) { this.recentSoundDetected = true; } const closestVisualEntity = this.parent.jibo.lps.getClosestVisualEntity(); if (closestVisualEntity && closestVisualEntity.description && closestVisualEntity.description === 'motion') { this.recentMotionDetected = true; } if (this.parent.jibo.lps.identity.getVisibleFaces().size > 0) { this.recentFaceDetected = true; } if (!this.detector.signalVADStatus.evaluate(true)) { this.recentVoicesHeard = true; } if (deltaSM >= ArrivalTracker.SM_UPDATE_PERIOD_MS) { if (this.sm.getCurrentState() === this.somebody) { if (this.recentFaceDetected) { this.modEvidenceEvent.emit(SensorTypes.visibleFaceSensor); } if (this.recentVoicesHeard) { this.modEvidenceEvent.emit(SensorTypes.heardVoicesSensor); } } else if (this.sm.getCurrentState() === this.possiblebody) { if (this.recentMotionDetected) { this.softEvidenceEvent.emit(SensorTypes.motionEntitySensor); } if (this.recentSoundDetected) { this.softEvidenceEvent.emit(SensorTypes.localizedSoundSensor); } } this.recentFaceDetected = false; this.recentMotionDetected = false; this.recentSoundDetected = false; this.recentVoicesHeard = false; this.lastStateMachineTick = Date.now(); } if (this.sm.getCurrentState() !== this.nobody && deltaPrintout >= ArrivalTracker.SM_LOG_PERIOD_MS) { const deltaTime = jibo_cai_utils_1.TimeUtils.msToMinutes(this.timerExpiryMs - Date.now()); log.debug(`[${this.sm.getCurrentState().name}] ticktock: ${deltaTime.toFixed(2)} minutes`); this.lastPrintoutTick = Date.now(); } } emitResetEvent() { this.resetEvent.emit(); } emitSoftEvidence(data, sensor) { this.softEvidenceEvent.emit(sensor); } emitModerateEvidence(data, sensor) { this.modEvidenceEvent.emit(sensor); } emitHardEvidence(entityID, sensor) { this.hardEvidenceEvent.emit(sensor); } createAndStartStateMachine() { this.createStateMachine(); return this.sm.start() .catch(error => { log.error(`Error in Arrival Tracker state machine on start:`, error); log.info(`Waiting to restart state machine...`); return jibo_cai_utils_1.TimeUtils.wait(1000); }).then(() => { log.info(`Restarting Arrival Tracker SM`); return this.createAndStartStateMachine(); }); } createStateMachine() { this.sm = new jibo_state_machine_1.StateMachine(); this.nobody = new jibo_state_machine_1.State(this.sm, 'Nobody'); this.somebody = new jibo_state_machine_1.State(this.sm, 'Somebody'); this.possiblebody = new jibo_state_machine_1.State(this.sm, 'Possiblebody'); this.hardEvidenceEvent = new jibo_typed_events_1.Event('Hard Evidence Event'); this.modEvidenceEvent = new jibo_typed_events_1.Event('Moderate Evidence Event'); this.softEvidenceEvent = new jibo_typed_events_1.Event('Soft Evidence Event'); this.resetEvent = new jibo_typed_events_1.Event('Reset Event'); this.nobody.addTypedEventTransition(this.hardEvidenceEvent, this.somebody); this.somebody.addTypedEventTransition(this.hardEvidenceEvent, this.somebody); this.somebody.addTypedEventTransition(this.modEvidenceEvent, this.somebody); this.somebody.addInternalTransition('Internal Timeout', this.possiblebody); this.somebody.addTypedEventTransition(this.resetEvent, this.nobody); this.possiblebody.addTypedEventTransition(this.hardEvidenceEvent, this.somebody); this.possiblebody.addTypedEventTransition(this.modEvidenceEvent, this.somebody); this.possiblebody.addTypedEventTransition(this.softEvidenceEvent, this.possiblebody); this.possiblebody.addInternalTransition('Internal Timeout', this.nobody); this.possiblebody.addTypedEventTransition(this.resetEvent, this.nobody); this.nobody.onEntry = (transition, result) => log.debug(`[${this.nobody.name}] Entered`); this.somebody.onEntry = (transition, sensor) => { if (transition.getSourceState() === this.nobody && sensor.name !== SensorTypes.hjHeardSensor.name) { log.debug(`[${this.somebody.name}] Entered from Nobody state; Sending new arrival proactive trigger.`); const arrivalRequest = { triggerSource: this.parent.jibo.jetstream.types.ProactiveTriggerSource.NEW_ARRIVAL, triggerData: { looperID: sensor.looperID, } }; this.detector.evaluate(arrivalRequest); } log.debug(`[${this.somebody.name}] Entered with timeout of ${sensor.timeoutMins} minutes from ${transition} Sensor: ${sensor.name}`); this.createNewTimerTransition(sensor.timeoutMins, this.somebody, this.possiblebody); }; this.somebody.onExit = (transition) => { if (transition.getSourceState() !== this.somebody) { this.clearTimer(); } }; this.possiblebody.onEntry = (transition, sensor) => { const timeout = sensor ? sensor.timeoutMins : ArrivalTracker.POSSIBLEBODY_TO_NOBODY_INTERNAL_TRANSITION_TIMEOUT_MINS; const sensorInfo = sensor ? `Sensor: ${sensor.name}` : ''; log.debug(`[${this.possiblebody.name}] Entered with timeout of ${timeout} minutes from ${transition} ${sensorInfo}`); this.createNewTimerTransition(timeout, this.possiblebody, this.nobody); }; this.possiblebody.onExit = (transition) => { if (transition.getSourceState() !== this.possiblebody) { this.clearTimer(); } }; this.sm.setInitial(this.nobody); } clearTimer() { if (this.timer) { clearTimeout(this.timer); this.timer = null; } this.timerExpiryMs = -1; } createNewTimerTransition(newTimeoutMinutes, from, next) { const newTimeoutMs = jibo_cai_utils_1.TimeUtils.minutesToMs(newTimeoutMinutes); if (this.timerExpiryMs > newTimeoutMs + Date.now()) { return; } this.clearTimer(); this.timerExpiryMs = newTimeoutMs + Date.now(); this.timer = setTimeout(() => { this.clearTimer(); if (this.sm.getCurrentState() === from) { from.transitionTo(next); } else { log.warn(`This should not have happened; Tried to transition from state: ${from} but current state is: ${this.sm.getCurrentState()}`); } }, newTimeoutMs); } static Configure(configuration) { try { ArrivalTracker.SM_UPDATE_PERIOD_MS = configuration.SM_UPDATE_PERIOD_MS; ArrivalTracker.SM_LOG_PERIOD_MS = configuration.SM_LOG_PERIOD_MS; ArrivalTracker.POSSIBLEBODY_TO_NOBODY_INTERNAL_TRANSITION_TIMEOUT_MINS = configuration.POSSIBLEBODY_TO_NOBODY_INTERNAL_TRANSITION_TIMEOUT_MINS; } catch (e) { log.error("Could not configure static variables based on configuration file: ", e); } } } ArrivalTracker.SM_UPDATE_PERIOD_MS = 1000; ArrivalTracker.SM_LOG_PERIOD_MS = 10000; ArrivalTracker.POSSIBLEBODY_TO_NOBODY_INTERNAL_TRANSITION_TIMEOUT_MINS = 3; exports.ArrivalTracker = ArrivalTracker; },{"../../../log":63,"../../FiringSignal":64,"./SensorTypes":71,"jibo-cai-utils":undefined,"jibo-state-machine":undefined,"jibo-typed-events":undefined}],71:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.faceIDAcquiredSensor = { name: "ID Acquired", timeoutMins: 4, }; exports.facePersistedSensor = { name: "Face Persisted", timeoutMins: 4, }; exports.hjHeardSensor = { name: "HJ Heard", timeoutMins: 2, }; exports.visibleFaceSensor = { name: "Visible Face", timeoutMins: 2, }; exports.headTouchedSensor = { name: "Jibo's Head Touched", timeoutMins: 2, }; exports.screenTouchedSensor = { name: "Jibo's Screen Touched", timeoutMins: 2, }; exports.heardVoicesSensor = { name: "Heard voices", timeoutMins: 2, }; exports.motionEntitySensor = { name: "Motion Entity", timeoutMins: 1, }; exports.localizedSoundSensor = { name: "Sound Localized", timeoutMins: 1, threshold: 0.25, }; exports.loudSoundSpikeSensor = { name: "Sound Spike", timeoutMins: 1, }; },{}],72:[function(require,module,exports){ "use strict"; function __export(m) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; } Object.defineProperty(exports, "__esModule", { value: true }); __export(require("./ArrivalTracker")); },{"./ArrivalTracker":70}],73:[function(require,module,exports){ "use strict"; function __export(m) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; } Object.defineProperty(exports, "__esModule", { value: true }); const arrival = require("./arrival"); exports.arrival = arrival; __export(require("./SignalIDAcquired")); __export(require("./SignalFacePersisted")); __export(require("./SignalSurprise")); },{"./SignalFacePersisted":67,"./SignalIDAcquired":68,"./SignalSurprise":69,"./arrival":72}],74:[function(require,module,exports){ "use strict"; function __export(m) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; } Object.defineProperty(exports, "__esModule", { value: true }); const firers = require("./firers"); exports.firers = firers; const inhibitors = require("./inhibitors"); exports.inhibitors = inhibitors; __export(require("./FiringSignal")); __export(require("./InhibitingSignal")); },{"./FiringSignal":64,"./InhibitingSignal":65,"./firers":73,"./inhibitors":82}],75:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const jibo_cai_utils_1 = require("jibo-cai-utils"); const log_1 = require("../../log"); const InhibitingSignal_1 = require("../InhibitingSignal"); var HJState; (function (HJState) { HJState["IN_PROGRESS"] = "IN_PROGRESS"; HJState["NOT_IN_PROGRESS"] = "NOT_IN_PROGRESS"; })(HJState = exports.HJState || (exports.HJState = {})); const log = log_1.log.createChild('SignalHJStatus'); class SignalHJStatus extends InhibitingSignal_1.InhibitingSignal { constructor(parent, name) { super(parent, name); this.currState = HJState.NOT_IN_PROGRESS; this.timeoutHandle = null; this.handleHJHeardBind = () => this.handleHJHeard(); this.handleHJExpiredTimeoutBind = () => this.handleHJExpiredTimeout(); this.handleSkillChangeBind = (data) => this.handleSkillChange(data); this.handleHJExpiredTimeoutBind.isGlobalTimer = true; } init() { this.parent.jibo.jetstream.events.hjHeard.on(this.handleHJHeardBind); this.parent.events.skillChange.on(this.handleSkillChangeBind); } dispose() { this.parent.jibo.jetstream.events.hjHeard.removeListener(this.handleHJHeardBind); this.parent.events.skillChange.removeListener(this.handleSkillChangeBind); } getState() { return this.currState; } evaluate() { if (this.currState === HJState.NOT_IN_PROGRESS) { log.debug("Passed: HJStatus is " + this.currState); return true; } else { log.info("Failed: HJStatus is " + this.currState); return false; } } reset() { this.currState = HJState.NOT_IN_PROGRESS; this.timeoutHandle = null; } handleHJHeard() { this.currState = HJState.IN_PROGRESS; this.timeoutHandle = this.parent.jibo.timer.setTimeout(this.handleHJExpiredTimeoutBind, SignalHJStatus.HJ_EXPIRE_TIMEOUT_MS); log.debug("HJ heard. HJStatus is in state: " + this.currState); } handleHJExpiredTimeout() { this.currState = HJState.NOT_IN_PROGRESS; log.debug("Timeout expired. HJStatus is in state: " + this.currState); } handleSkillChange(skillChange) { const [, newSkill] = skillChange; if (this.currState === HJState.IN_PROGRESS) { this.currState = HJState.NOT_IN_PROGRESS; log.debug("Skill Change to " + newSkill + ". HJStatus is in state: " + this.currState); if (this.timeoutHandle) { log.debug("Skill switch occured. Clearing out timeout"); this.parent.jibo.timer.clearTimeout(this.timeoutHandle); this.timeoutHandle = null; } } } static Configure(configuration) { try { SignalHJStatus.HJ_EXPIRE_TIMEOUT_MS = jibo_cai_utils_1.TimeUtils.secondsToMs(configuration.HJ_EXPIRE_TIMEOUT_SECS); } catch (e) { log.error("Could not configure static variables based on configuration file: ", e); } } } SignalHJStatus.HJ_EXPIRE_TIMEOUT_MS = jibo_cai_utils_1.TimeUtils.secondsToMs(27); exports.SignalHJStatus = SignalHJStatus; },{"../../log":63,"../InhibitingSignal":65,"jibo-cai-utils":undefined}],76:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const jibo_common_types_1 = require("jibo-common-types"); const log_1 = require("../../log"); const InhibitingSignal_1 = require("../InhibitingSignal"); const log = log_1.log.createChild('SignalJiboStatus'); class SignalJiboStatus extends InhibitingSignal_1.InhibitingSignal { init() { } dispose() { } evaluate() { const jiboState = this.parent.createState(); if (jiboState.circadian === jibo_common_types_1.CircadianState.ALERT || jiboState.circadian === jibo_common_types_1.CircadianState.RELAXED) { log.debug("Passed: Jibo is " + jiboState.circadian); return true; } else { log.info("Failed: Jibo is " + jiboState.circadian); return false; } } } exports.SignalJiboStatus = SignalJiboStatus; },{"../../log":63,"../InhibitingSignal":65,"jibo-common-types":undefined}],77:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const log_1 = require("../../log"); const InhibitingSignal_1 = require("../InhibitingSignal"); const jibo_cai_utils_1 = require("jibo-cai-utils"); const AUDIO_SIGNAL_RATE = 20; const log = log_1.log.createChild('SignalLoudEnvironmentStatus'); class SignalLoudEnvironmentStatus extends InhibitingSignal_1.InhibitingSignal { constructor() { super(...arguments); this.recentInhibitionStartTimeMs = null; this.audioIntensityStats = new jibo_cai_utils_1.AmbientStats("SignalLoudEnvironmentStats", { baselineSize: (SignalLoudEnvironmentStatus.BASELINE_PERIOD_SECS * AUDIO_SIGNAL_RATE), recentSize: (SignalLoudEnvironmentStatus.RECENT_PERIOD_SECS * AUDIO_SIGNAL_RATE), minimumRecentMean: SignalLoudEnvironmentStatus.MINIMUM_RECENT_MEAN_DB, divergenceSensitivity: SignalLoudEnvironmentStatus.DIVERGENCE_SENSITIVITY, }, log); this.inputEnergyHandlerBind = (inputEnergy) => this.inputEnergyHandler(inputEnergy); } inputEnergyHandler(inputEnergy) { this.audioIntensityStats.addSample(inputEnergy.db_rms); if (this.audioIntensityStats.buffersFilled() && this.audioIntensityStats.hasDeviatedFromBaseline()) { this.recentInhibitionStartTimeMs = Date.now(); } } init() { this.parent.jibo.system.events.inputEnergy.on(this.inputEnergyHandlerBind); } dispose() { this.parent.jibo.system.events.inputEnergy.off(this.inputEnergyHandlerBind); } evaluateRelativeLoudness() { if (!SignalLoudEnvironmentStatus.INHIBIT_ON_SPIKE) { return true; } let isRecentlyInhibited = false; let sinceInhibitionStartMs = -1; if (this.recentInhibitionStartTimeMs) { sinceInhibitionStartMs = Date.now() - this.recentInhibitionStartTimeMs; if (sinceInhibitionStartMs < SignalLoudEnvironmentStatus.RECENTLY_INHIBITED_DURATION_MS) { isRecentlyInhibited = true; } else { this.recentInhibitionStartTimeMs = null; } } if (isRecentlyInhibited) { log.info(`Failed: Relative noise spike was loud ${sinceInhibitionStartMs}ms ago (based on relative thresholds). BaselineAudioEnergy:${this.audioIntensityStats.getBaselineMean().toFixed(2)} RecentAudioEnergy:${this.audioIntensityStats.getRecentMean().toFixed(2)}. In skill ${this.parent.currentSkillName}.`); return false; } else { log.debug(`Passed: Relative noise spike is NOT too loud (based on relative thresholds). BaselineAudioEnergy:${this.audioIntensityStats.getBaselineMean().toFixed(2)} RecentAudioEnergy:${this.audioIntensityStats.getRecentMean().toFixed(2)}. In skill ${this.parent.currentSkillName}.`); return true; } } evaluateAbsoluteLoudness() { const baselineBelowThreshold = (this.audioIntensityStats.getBaselineMean() <= SignalLoudEnvironmentStatus.BASELINE_CEILING_DB); if (baselineBelowThreshold) { log.debug(`Passed: Environment baseline is NOT too loud (based on absolute thresholds). BaselineAudioEnergy:${this.audioIntensityStats.getBaselineMean().toFixed(2)} RecentAudioEnergy:${this.audioIntensityStats.getRecentMean().toFixed(2)}. In skill ${this.parent.currentSkillName}.`); } else { log.info(`Failed: Environment baseline is too loud (based on absolute thresholds). BaselineAudioEnergy:${this.audioIntensityStats.getBaselineMean().toFixed(2)} RecentAudioEnergy:${this.audioIntensityStats.getRecentMean().toFixed(2)}. In skill ${this.parent.currentSkillName}.`); } return baselineBelowThreshold; } evaluate() { if (!this.audioIntensityStats.buffersFilled()) { log.debug(`Passed: Stats are not ready. Not inhibiting until buffers are full.`); return true; } const relativeLoudnessPass = this.evaluateRelativeLoudness(); const absoluteLoudnessPass = this.evaluateAbsoluteLoudness(); const pass = absoluteLoudnessPass && relativeLoudnessPass; return pass; } static Configure(configuration) { try { SignalLoudEnvironmentStatus.BASELINE_CEILING_DB = configuration.BASELINE_CEILING_DB; SignalLoudEnvironmentStatus.RECENT_CEILING_DB = configuration.RECENT_CEILING_DB; SignalLoudEnvironmentStatus.BASELINE_PERIOD_SECS = configuration.BASELINE_PERIOD_SECS; SignalLoudEnvironmentStatus.RECENT_PERIOD_SECS = configuration.RECENT_PERIOD_SECS; SignalLoudEnvironmentStatus.MINIMUM_RECENT_MEAN_DB = configuration.MINIMUM_RECENT_MEAN_DB; SignalLoudEnvironmentStatus.DIVERGENCE_SENSITIVITY = configuration.DIVERGENCE_SENSITIVITY; SignalLoudEnvironmentStatus.RECENTLY_INHIBITED_DURATION_MS = jibo_cai_utils_1.TimeUtils.secondsToMs(configuration.RECENTLY_INHIBITED_DURATION_SECS); SignalLoudEnvironmentStatus.INHIBIT_ON_SPIKE = configuration.INHIBIT_ON_SPIKE; } catch (e) { log.error("Could not configure static variables based on configuration file: ", e); } } } SignalLoudEnvironmentStatus.BASELINE_CEILING_DB = -40.0; SignalLoudEnvironmentStatus.RECENT_CEILING_DB = -30.0; SignalLoudEnvironmentStatus.BASELINE_PERIOD_SECS = 60.0; SignalLoudEnvironmentStatus.RECENT_PERIOD_SECS = 10.0; SignalLoudEnvironmentStatus.MINIMUM_RECENT_MEAN_DB = -40; SignalLoudEnvironmentStatus.DIVERGENCE_SENSITIVITY = 1.4; SignalLoudEnvironmentStatus.RECENTLY_INHIBITED_DURATION_MS = 7500; SignalLoudEnvironmentStatus.INHIBIT_ON_SPIKE = true; exports.SignalLoudEnvironmentStatus = SignalLoudEnvironmentStatus; },{"../../log":63,"../InhibitingSignal":65,"jibo-cai-utils":undefined}],78:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const jibo_cai_utils_1 = require("jibo-cai-utils"); const log_1 = require("../../log"); const InhibitingSignal_1 = require("../InhibitingSignal"); const log = log_1.log.createChild('SignalNoMatchStatus'); class SignalNoMatchStatus extends InhibitingSignal_1.InhibitingSignal { constructor() { super(...arguments); this.lastNoMatchMs = -1; this.handleNoMatchBind = () => this.handleNoMatch(); } init() { this.parent.jibo.globalEvents.shared.noGlobalMatch.on(this.handleNoMatchBind); } dispose() { this.parent.jibo.globalEvents.shared.noGlobalMatch.removeListener(this.handleNoMatchBind); } evaluate() { const sinceLastNoMatch = this.parent.dateProvider.getDate().getTime() - this.lastNoMatchMs; if (sinceLastNoMatch > SignalNoMatchStatus.RECENT_NO_MATCH_EXPIRY_MS) { log.debug(`Passed: Last no-match was not recent: ${sinceLastNoMatch}ms is greater than ${SignalNoMatchStatus.RECENT_NO_MATCH_EXPIRY_MS}ms`); return true; } else { log.info(`Failed: Last no-match was too recent: ${sinceLastNoMatch}ms is less than ${SignalNoMatchStatus.RECENT_NO_MATCH_EXPIRY_MS}ms`); return false; } } handleNoMatch() { this.lastNoMatchMs = this.parent.dateProvider.getDate().getTime(); log.debug("Heard global no match"); } static Configure(configuration) { try { SignalNoMatchStatus.RECENT_NO_MATCH_EXPIRY_MS = jibo_cai_utils_1.TimeUtils.minutesToMs(configuration.RECENT_NO_MATCH_EXPIRY_MINS); } catch (e) { log.error("Could not configure static variables based on configuration file: ", e); } } } SignalNoMatchStatus.RECENT_NO_MATCH_EXPIRY_MS = jibo_cai_utils_1.TimeUtils.minutesToMs(5); exports.SignalNoMatchStatus = SignalNoMatchStatus; },{"../../log":63,"../InhibitingSignal":65,"jibo-cai-utils":undefined}],79:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const jibo_cai_utils_1 = require("jibo-cai-utils"); const log_1 = require("../../log"); const InhibitingSignal_1 = require("../InhibitingSignal"); const log = log_1.log.createChild('SignalRateLimiterStatus'); let partOfDayProperties = { 'MORNING': { 'EARLY': { index: 2, weight: { weekday: 0, weekend: 0 }, maxTriggers: null }, 'MID': { index: 3, weight: { weekday: 0.15, weekend: 0.14 }, maxTriggers: null }, 'LATE': { index: 4, weight: { weekday: 0.10, weekend: 0.14 }, maxTriggers: null }, }, 'AFTERNOON': { 'EARLY': { index: 5, weight: { weekday: 0.12, weekend: 0.16 }, maxTriggers: null }, 'MID': { index: 6, weight: { weekday: 0.13, weekend: 0.14 }, maxTriggers: null }, 'LATE': { index: 7, weight: { weekday: 0.17, weekend: 0.15 }, maxTriggers: null }, }, 'EVENING': { 'EARLY': { index: 8, weight: { weekday: 0.19, weekend: 0.15 }, maxTriggers: null }, 'MID': { index: 9, weight: { weekday: 0.08, weekend: 0.06 }, maxTriggers: null }, 'LATE': { index: 10, weight: { weekday: 0.06, weekend: 0.06 }, maxTriggers: null }, }, 'NIGHT': { 'EARLY': { index: 11, weight: { weekday: 0, weekend: 0 }, maxTriggers: null }, 'MID': { index: 0, weight: { weekday: 0, weekend: 0 }, maxTriggers: null }, 'LATE': { index: 1, weight: { weekday: 0, weekend: 0 }, maxTriggers: null }, } }; let weekdayWeightTotal = 0; let weekendWeightTotal = 0; jibo_cai_utils_1.PartOfDayTimes.forEach(partOfDayTime => { const { basic, detail } = partOfDayTime.pod; weekdayWeightTotal += partOfDayProperties[basic][detail].weight.weekday; weekendWeightTotal += partOfDayProperties[basic][detail].weight.weekend; }); const weekdayDiff = Math.abs(1.0 - weekdayWeightTotal); const weekendDiff = Math.abs(1.0 - weekendWeightTotal); if (weekdayDiff > Number.EPSILON || weekendDiff > Number.EPSILON) { throw new Error(`The sum of weights across the day does not sum to 1.0; Weekday: ${weekdayWeightTotal} Weekend: ${weekendWeightTotal}`); } class SignalRateLimiterStatus extends InhibitingSignal_1.InhibitingSignal { constructor() { super(...arguments); this.lastTriggerMs = -1; this.dailyTriggerBudget = SignalRateLimiterStatus.MAX_TRIGGERS_PER_DAY_LIMIT; this.partOfDayTriggerBudget = []; this.timeoutHandle = null; this.timeoutCallback = null; } init() { this.calcMaxTriggersPartOfDay(); this.reset(); this.createNextPartOfDayTimeout(); } dispose() { if (this.timeoutHandle) { this.parent.jibo.timer.clearTimeout(this.timeoutHandle); this.timeoutHandle = null; } } evaluate() { return this.evaluateTriggerRecency() && this.evaluatePartOfDayLimit() && this.evaluateDailyLimit(); } addTriggerEvent(timestampMs = Date.now()) { this.lastTriggerMs = timestampMs; this.dailyTriggerBudget -= 1; const currPartofDay = jibo_cai_utils_1.TimeUtils.getPartOfDay(new Date(timestampMs)); const currIndex = partOfDayProperties[currPartofDay.basic][currPartofDay.detail].index; this.partOfDayTriggerBudget[currIndex]--; log.debug(`Updated Daily budget: ${this.dailyTriggerBudget}`); log.debug(`Updated PartOfDay budget: ${this.partOfDayTriggerBudget}`); } reset() { this.lastTriggerMs = -1; this.dailyTriggerBudget = SignalRateLimiterStatus.MAX_TRIGGERS_PER_DAY_LIMIT; for (let i = 0; i < jibo_cai_utils_1.PartOfDayTimes.length; i++) { const { basic, detail } = jibo_cai_utils_1.PartOfDayTimes[i].pod; if (this.isWeekend()) { this.partOfDayTriggerBudget[i] = Math.round(partOfDayProperties[basic][detail].weight.weekend * SignalRateLimiterStatus.MAX_TRIGGERS_PER_DAY_LIMIT); } else { this.partOfDayTriggerBudget[i] = Math.round(partOfDayProperties[basic][detail].weight.weekday * SignalRateLimiterStatus.MAX_TRIGGERS_PER_DAY_LIMIT); } } const currPartOfDay = jibo_cai_utils_1.TimeUtils.getPartOfDay(new Date()); const currIndex = partOfDayProperties[currPartOfDay.basic][currPartOfDay.detail].index; for (let i = 0; i < currIndex; i++) { this.partOfDayTriggerBudget[i] = 0; } log.debug(`Reset Daily budget: ${this.dailyTriggerBudget}`); log.debug(`Reset PartOfDay budget: ${this.partOfDayTriggerBudget}`); } createNextPartOfDayTimeout() { const currPartOfDay = jibo_cai_utils_1.TimeUtils.getPartOfDay(new Date()); const currIndex = partOfDayProperties[currPartOfDay.basic][currPartOfDay.detail].index; const nextIndex = currIndex + 1 === jibo_cai_utils_1.PartOfDayTimes.length ? 0 : currIndex + 1; const nextPartOfDay = jibo_cai_utils_1.PartOfDayTimes[nextIndex].pod; const deltaMs = this.diffPartsOfDay(currPartOfDay, nextPartOfDay); this.timeoutCallback = () => this.updatePartOfDayLimiter(currPartOfDay, nextPartOfDay); this.timeoutCallback.isGlobalTimer = true; this.timeoutHandle = this.parent.jibo.timer.setTimeout(this.timeoutCallback, deltaMs); log.debug(`Created a timeout in ${Math.round(jibo_cai_utils_1.TimeUtils.msToMinutes(deltaMs))} minutes for ${nextPartOfDay.detail} ${nextPartOfDay.basic}`); } calcMaxTriggersPartOfDay() { for (let currIndex = 0; currIndex < jibo_cai_utils_1.PartOfDayTimes.length; currIndex++) { const nextIndex = currIndex + 1 === jibo_cai_utils_1.PartOfDayTimes.length ? 0 : currIndex + 1; const deltaMs = this.diffPartsOfDay(jibo_cai_utils_1.PartOfDayTimes[currIndex].pod, jibo_cai_utils_1.PartOfDayTimes[nextIndex].pod); const maxTriggers = Math.round(jibo_cai_utils_1.TimeUtils.msToHours(deltaMs) * SignalRateLimiterStatus.MAX_TRIGGERS_PER_HOUR_RATE); const { basic, detail } = jibo_cai_utils_1.PartOfDayTimes[currIndex].pod; partOfDayProperties[basic][detail].maxTriggers = maxTriggers; log.debug(`${detail} ${basic} has ${maxTriggers} max allowed triggers`); } } diffPartsOfDay(current, future) { const currIndex = partOfDayProperties[current.basic][current.detail].index; const futureIndex = partOfDayProperties[future.basic][future.detail].index; const currDatetime = new Date(); currDatetime.setHours(jibo_cai_utils_1.PartOfDayTimes[currIndex].time.hour); currDatetime.setMinutes(jibo_cai_utils_1.PartOfDayTimes[currIndex].time.minute); let futureDatetime = new Date(); if (futureIndex < currIndex) { futureDatetime.setDate(currDatetime.getDate() + 1); } else { futureDatetime.setDate(currDatetime.getDate()); } futureDatetime.setHours(jibo_cai_utils_1.PartOfDayTimes[futureIndex].time.hour); futureDatetime.setMinutes(jibo_cai_utils_1.PartOfDayTimes[futureIndex].time.minute); return futureDatetime.getTime() - currDatetime.getTime(); } updatePartOfDayLimiter(lastPartOfDay, currPartOfDay) { log.debug(`Received timeout. Transitioned from ${lastPartOfDay.detail} ${lastPartOfDay.basic} to ${currPartOfDay.detail} ${currPartOfDay.basic}.`); if (currPartOfDay.basic === jibo_cai_utils_1.PartOfDayBasic.NIGHT && currPartOfDay.detail === jibo_cai_utils_1.PartOfDayDetail.MID) { log.debug("Its midnight. Resetting all trigger rate limiters for the new day."); this.reset(); } else { const currIndex = partOfDayProperties[currPartOfDay.basic][currPartOfDay.detail].index; const lastIndex = partOfDayProperties[lastPartOfDay.basic][lastPartOfDay.detail].index; const remainingBudget = this.partOfDayTriggerBudget[lastIndex]; if (remainingBudget > 0) { this.partOfDayTriggerBudget[lastIndex] = 0; this.rolloverToRemainingPartsOfDay(remainingBudget, currIndex); log.debug(`Rollovered PartOfDay budget: ${this.partOfDayTriggerBudget}`); } else { log.debug("Zero budget to rollover"); } } this.timeoutHandle = null; this.timeoutCallback = null; this.createNextPartOfDayTimeout(); } evaluateTriggerRecency() { const sinceLastTriggerMs = Date.now() - this.lastTriggerMs; if (sinceLastTriggerMs > SignalRateLimiterStatus.RECENT_TRIGGER_EXPIRY_MS) { log.debug(`Passed: Last trigger was not recent: ${sinceLastTriggerMs}ms is greater than ${SignalRateLimiterStatus.RECENT_TRIGGER_EXPIRY_MS}ms`); return true; } else { log.info(`Failed: Last trigger was too recent: ${sinceLastTriggerMs}ms is less than or equal to ${SignalRateLimiterStatus.RECENT_TRIGGER_EXPIRY_MS}ms`); return false; } } evaluatePartOfDayLimit() { const currPartOfDay = jibo_cai_utils_1.TimeUtils.getPartOfDay(new Date()); const currIndex = partOfDayProperties[currPartOfDay.basic][currPartOfDay.detail].index; const remainingBudget = this.partOfDayTriggerBudget[currIndex]; if (remainingBudget > 0) { log.debug(`Passed: ${currPartOfDay.detail} ${currPartOfDay.basic} still has ${remainingBudget} triggers remaining`); return true; } else { log.info(`Failed: ${currPartOfDay.detail} ${currPartOfDay.basic} has ${remainingBudget} triggers remaining`); return false; } } evaluateDailyLimit() { if (this.dailyTriggerBudget > 0) { log.debug(`Passed: Today still has ${this.dailyTriggerBudget} triggers remaining`); return true; } else { log.info(`Failed: Total has ${this.dailyTriggerBudget} triggers remaining`); return false; } } rolloverToRemainingPartsOfDay(triggers, startIndex) { const totalTriggers = Math.round(SignalRateLimiterStatus.ROLLOVER_PROPORTION * triggers); log.debug(`Distributing ${SignalRateLimiterStatus.ROLLOVER_PROPORTION * 100}% of ${triggers} = ${totalTriggers} triggers to the remaining parts of day.`); let rollover = Array.apply(null, Array(jibo_cai_utils_1.PartOfDayTimes.length)).map(Number.prototype.valueOf, 0); let distributed = 0; for (let i = startIndex; i < jibo_cai_utils_1.PartOfDayTimes.length; i++) { const { basic, detail } = jibo_cai_utils_1.PartOfDayTimes[i].pod; if (this.isWeekend()) { rollover[i] = partOfDayProperties[basic][detail].weight.weekend * totalTriggers; } else { rollover[i] = partOfDayProperties[basic][detail].weight.weekday * totalTriggers; } distributed += rollover[i]; } if (distributed) { rollover = rollover.map(function (x) { return Math.round(x * totalTriggers / distributed); }); this.partOfDayTriggerBudget = this.partOfDayTriggerBudget.map(function (originalBudget, idx) { const { basic, detail } = jibo_cai_utils_1.PartOfDayTimes[idx].pod; const capBudget = partOfDayProperties[basic][detail].maxTriggers; return Math.min(originalBudget + rollover[idx], capBudget); }); } } isWeekend() { const dayOfWeek = new Date().getDay(); return (dayOfWeek === 6) || (dayOfWeek === 0); } static Configure(configuration) { try { SignalRateLimiterStatus.MAX_TRIGGERS_PER_DAY_LIMIT = configuration.MAX_TRIGGERS_PER_DAY_LIMIT; SignalRateLimiterStatus.MAX_TRIGGERS_PER_HOUR_RATE = configuration.MAX_TRIGGERS_PER_HOUR_RATE; SignalRateLimiterStatus.ROLLOVER_PROPORTION = configuration.ROLLOVER_PROPORTION; SignalRateLimiterStatus.RECENT_TRIGGER_EXPIRY_MS = configuration.RECENT_TRIGGER_EXPIRY_MS; } catch (e) { log.error("Could not configure static variables based on configuration file: ", e); } } } SignalRateLimiterStatus.MAX_TRIGGERS_PER_DAY_LIMIT = 50; SignalRateLimiterStatus.MAX_TRIGGERS_PER_HOUR_RATE = 10; SignalRateLimiterStatus.ROLLOVER_PROPORTION = 0.50; SignalRateLimiterStatus.RECENT_TRIGGER_EXPIRY_MS = 500; exports.SignalRateLimiterStatus = SignalRateLimiterStatus; },{"../../log":63,"../InhibitingSignal":65,"jibo-cai-utils":undefined}],80:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const Utils_1 = require("../../../common/Utils"); const log_1 = require("../../log"); const InhibitingSignal_1 = require("../InhibitingSignal"); const log = log_1.log.createChild('SignalSkillStatus'); class SignalSkillStatus extends InhibitingSignal_1.InhibitingSignal { init() { } dispose() { } evaluate() { const skillState = this.parent.createState(); if (skillState.skillName === Utils_1.SkillNames.IDLE) { log.debug("Passed: SkillStatus is " + skillState.skillName); return true; } else { log.info("Failed: SkillStatus is " + skillState.skillName); return false; } } } exports.SignalSkillStatus = SignalSkillStatus; },{"../../../common/Utils":28,"../../log":63,"../InhibitingSignal":65}],81:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const log_1 = require("../../log"); const InhibitingSignal_1 = require("../InhibitingSignal"); const jibo_cai_utils_1 = require("jibo-cai-utils"); const Utils_1 = require("../../../common/Utils"); const SignalHJStatus_1 = require("./SignalHJStatus"); const VAD_SIGNAL_RATE = 20; const log = log_1.log.createChild('SignalVADStatus'); class SignalVADStatus extends InhibitingSignal_1.InhibitingSignal { constructor() { super(...arguments); this.recentInhibitionStartTimeMs = null; this.vadStats = new jibo_cai_utils_1.AmbientStats("SignalVADStats", { baselineSize: (SignalVADStatus.BASELINE_PERIOD_SECS * VAD_SIGNAL_RATE), recentSize: (SignalVADStatus.RECENT_PERIOD_SECS * VAD_SIGNAL_RATE), }, log); this.vadHandlerBind = (vadMessage) => this.vadHandler(vadMessage); } vadHandler(vadMessage) { if (this.shouldSkipVADProcessing()) { this.vadStats.addSample(-1.0); return; } let total = 0; vadMessage.VADevents.forEach(event => { total += event.vad; }); total /= vadMessage.VADevents.length; this.vadStats.addSample(total); if (this.vadStats.buffersFilled() && (this.vadStats.getRecentMean() > SignalVADStatus.RECENT_THRESHOLD || this.vadStats.getBaselineMean() > SignalVADStatus.BASELINE_THRESHOLD)) { this.recentInhibitionStartTimeMs = Date.now(); } } shouldSkipVADProcessing() { const skillState = this.parent.createState(); return (skillState.skillName !== Utils_1.SkillNames.IDLE && skillState.skillName !== Utils_1.SkillNames.SURPRISES) || (this.parent.proactive.signalHJStatus.getState() === SignalHJStatus_1.HJState.IN_PROGRESS) || (this.parent.jibo.embodied.speech.isActive()); } init() { this.parent.jibo.jetstream.events.vad.on(this.vadHandlerBind); } dispose() { this.parent.jibo.jetstream.events.vad.off(this.vadHandlerBind); } evaluate(skipLogging) { if (!this.vadStats.buffersFilled()) { if (!skipLogging) { log.info(`Passed: Stats are not ready. Not inhibiting until buffers are full.`); } return true; } let isRecentlyInhibited = false; let sinceInhibitionStartMs = -1; if (this.recentInhibitionStartTimeMs) { sinceInhibitionStartMs = Date.now() - this.recentInhibitionStartTimeMs; if (sinceInhibitionStartMs < SignalVADStatus.RECENTLY_INHIBITED_DURATION_MS) { isRecentlyInhibited = true; } else { this.recentInhibitionStartTimeMs = null; } } const baseMean = this.vadStats.getBaselineMean().toFixed(2); const recentMean = this.vadStats.getRecentMean().toFixed(2); if (isRecentlyInhibited) { if (!skipLogging) { log.info(`Failed: Heard people talking ${sinceInhibitionStartMs}ms ago. baseline/recent: ${baseMean} / ${recentMean}. In skill ${this.parent.currentSkillName}.`); } return false; } else { if (!skipLogging) { log.debug(`Passed: Did not hear people talking. baseline/recent: ${baseMean} / ${recentMean}. No thresholds exceeded. In skill ${this.parent.currentSkillName}.`); } return true; } } static Configure(configuration) { try { SignalVADStatus.BASELINE_PERIOD_SECS = configuration.BASELINE_PERIOD_SECS; SignalVADStatus.RECENT_PERIOD_SECS = configuration.RECENT_PERIOD_SECS; SignalVADStatus.BASELINE_THRESHOLD = configuration.BASELINE_THRESHOLD; SignalVADStatus.RECENT_THRESHOLD = configuration.RECENT_THRESHOLD; SignalVADStatus.RECENTLY_INHIBITED_DURATION_MS = jibo_cai_utils_1.TimeUtils.secondsToMs(configuration.RECENTLY_INHIBITED_DURATION_SECS); } catch (e) { log.error("Could not configure static variables based on configuration file: ", e); } } } SignalVADStatus.BASELINE_PERIOD_SECS = 5.0; SignalVADStatus.RECENT_PERIOD_SECS = 0.1; SignalVADStatus.BASELINE_THRESHOLD = -0.3; SignalVADStatus.RECENT_THRESHOLD = 0.35; SignalVADStatus.RECENTLY_INHIBITED_DURATION_MS = 2000; exports.SignalVADStatus = SignalVADStatus; },{"../../../common/Utils":28,"../../log":63,"../InhibitingSignal":65,"./SignalHJStatus":75,"jibo-cai-utils":undefined}],82:[function(require,module,exports){ "use strict"; function __export(m) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; } Object.defineProperty(exports, "__esModule", { value: true }); __export(require("./SignalHJStatus")); __export(require("./SignalJiboStatus")); __export(require("./SignalSkillStatus")); __export(require("./SignalNoMatchStatus")); __export(require("./SignalRateLimiterStatus")); __export(require("./SignalVADStatus")); __export(require("./SignalLoudEnvironmentStatus")); },{"./SignalHJStatus":75,"./SignalJiboStatus":76,"./SignalLoudEnvironmentStatus":77,"./SignalNoMatchStatus":78,"./SignalRateLimiterStatus":79,"./SignalSkillStatus":80,"./SignalVADStatus":81}],83:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const action = require("./action"); exports.action = action; const motivation = require("./motivation"); exports.motivation = motivation; const common = require("./common"); exports.common = common; const goal = require("./goal"); exports.goal = goal; const proactive = require("./proactive"); exports.proactive = proactive; const api = require("./api"); exports.api = api; },{"./action":15,"./api":19,"./common":29,"./goal":54,"./motivation":60,"./proactive":62}]},{},[83])(83) }); //# sourceMappingURL=jibo-action-system.js.map