Files
Zos/Skills/@be/node_modules/jibo-action-system/lib/jibo-action-system.js

4396 lines
190 KiB
JavaScript

(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<r.length;o++)s(r[o]);return s})({1:[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_cai_utils_1 = require("jibo-cai-utils");
const Types_1 = require("../common/Types");
const log_1 = require("../common/log");
const DEFAULT_ACTION_TIMEOUT = jibo_cai_utils_1.TimeUtils.secondsToMs(30);
class Action {
constructor(parent, name, options = {}) {
this.name = name;
this.options = options;
this.status = Types_1.ActionStatus.NOT_RUNNING;
this.parent = parent;
this.options.driveEffects = this.options.driveEffects || new Map();
this.options.timeoutMs = (this.options.timeoutMs === undefined) ?
DEFAULT_ACTION_TIMEOUT :
this.options.timeoutMs;
this.log = log_1.log.createChild(`Action.${name}`);
}
cancelInternal() {
return __awaiter(this, void 0, void 0, function* () {
return Promise.resolve();
});
}
cancel() {
return __awaiter(this, void 0, void 0, function* () {
this._cancel(Types_1.ActionResult.CANCELED);
});
}
getDriveEffect(drive) {
return this.options.driveEffects.get(drive) || 0;
}
run() {
return __awaiter(this, void 0, void 0, function* () {
if (this.status === Types_1.ActionStatus.RUNNING) {
return Promise.reject('Action already running');
}
this.log.debug(`Action status: ${this.status}`);
this.status = Types_1.ActionStatus.RUNNING;
Action.active.push(this);
this.log.debug(`Active actions ${Action.active.length}: `, Action.active.map(a => 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 SECONDS_TO_HOLD_TOUCH = 1;
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;
}
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(SECONDS_TO_HOLD_TOUCH * 1000)
.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();
}
});
}
});
});
}
}
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");
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));
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}],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 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;
},{"./action":15,"./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",
kind: jibo_common_types_1.SensoryType.PERSON,
}));
});
T.getButtonField(`Reset Arrival Tracker's state machine`, WIN2).events.change.on(() => {
runtime.proactive.resetArrivalTrackerSM();
});
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(`Reset Rate Limiter`, WIN2).events.change.on(() => {
runtime.proactive.signalRateLimiterStatus.reset();
runtime.proactive.signalRateLimiterStatus.dispose();
runtime.proactive.signalRateLimiterStatus.createNextPartOfDayTimeout();
});
}
}
}
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 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: '<user input removed>'
};
}
}
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) {
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}],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 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 arrival_1 = require("./signals/firers/arrival");
const log_1 = require("./log");
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.signalHJStatus = new SignalHJStatus_1.SignalHJStatus(this.parent, "HJ Status Inhibiting Signal");
this.signalNoMatchStatus = new SignalNoMatchStatus_1.SignalNoMatchStatus(this.parent, "No Match Status Inhibiting Signal");
this.signalRateLimiterStatus = new SignalRateLimiterStatus_1.SignalRateLimiterStatus(this.parent, "Rate Limiter Status 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.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.debug(...log_1.formatText(log, "Evaluating trigger source: " + proactiveRequest.triggerSource + " with data: "), proactiveRequest.triggerData);
if (this.checkInhibitors()) {
log.debug(...log_1.formatText(log, "Passed all inhibitors", 'color : green'));
if (this.disableProactiveTrigger) {
log.debug(...log_1.formatText(log, "Sending trigger messsages to Jetstream have been disabled from package options", 'color : red'));
}
else {
this.sendTrigger(proactiveRequest);
this.signalRateLimiterStatus.addTriggerEvent();
}
}
else {
log.debug(...log_1.formatText(log, "Failed an inhibitor", 'color : red'));
}
}
checkInhibitors() {
return this.signalHJStatus.evaluate() &&
this.signalJiboStatus.evaluate() &&
this.signalSkillStatus.evaluate() &&
this.signalNoMatchStatus.evaluate() &&
this.signalRateLimiterStatus.evaluate();
}
sendTrigger(proactiveRequest) {
return __awaiter(this, void 0, void 0, function* () {
log.debug(...log_1.formatText(log, "Sending proactive trigger to jetstream"));
this.jetstreamTimeoutHandle = this.parent.jibo.timer.setTimeout(this.handleJetstreamTimeoutBind, OpportunityDetector.MAX_JETSTREAM_RESPONSE_TIMEOUT);
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,
};
}
const deltaTime = Date.now() - requestTimestamp;
log.debug(...log_1.formatText(log, `Got a successful jetstream response in ${deltaTime} milliseconds`, 'color:green'));
}
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} 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) {
log.debug(...log_1.formatText(log, `Got a successful skill switch response to ${skillName} in ${deltaTime} milliseconds`, 'color:green'));
}
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} milliseconds`);
}
this.lastProactiveResponse = null;
}
}
}
resetArrivalTrackerSM() {
this.arrivalTracker.emitResetEvent();
}
}
OpportunityDetector.MAX_JETSTREAM_RESPONSE_TIMEOUT = 2500;
OpportunityDetector.MAX_SKILLSWITCH_RESPONSE_TIMEOUT = 3000;
exports.OpportunityDetector = OpportunityDetector;
},{"../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/inhibitors/SignalHJStatus":75,"./signals/inhibitors/SignalJiboStatus":76,"./signals/inhibitors/SignalNoMatchStatus":77,"./signals/inhibitors/SignalRateLimiterStatus":78,"./signals/inhibitors/SignalSkillStatus":79}],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');
const maxNamespaceLength = 45;
function formatText(log, text, color = null) {
color = color || 'color: blue';
const namespacePad = Array(Math.max(0, maxNamespaceLength - log.namespace.length)).join(" ");
return [
`%c ${namespacePad} ${text}`,
color
];
}
exports.formatText = formatText;
},{"../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.handleVisibleFaceStartedBind = () => this.handleVisibleFaceStarted();
this.handleEntityTimeoutBind = () => this.handleEntityTimeout();
this.handleIDAcquiredBind = (data) => this.handleIDAcquired(data);
this.handleEntityTimeoutBind.isGlobalTimer = true;
}
static setFaceIDWaitTime(secondsToWait) {
log.debug(...log_1.formatText(log, "Changing face_id_wait_time variable to " + secondsToWait));
SignalFacePersisted.FACE_ID_WAIT_TIME = jibo_cai_utils_1.TimeUtils.secondsToMs(secondsToWait);
}
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(...log_1.formatText(log, "Got visible face, but already have a timeoutHandle"));
}
else {
this.parent.jibo.lps.identity.getVisibleFaces().forEach((entity) => {
log.debug(...log_1.formatText(log, "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);
}
}
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(...log_1.formatText(log, "Persisting face timeout expired. I found same ID " + entity.id));
matchedEntityID = entity.id;
return;
}
else {
log.debug(...log_1.formatText(log, "Persisting face timeout expired. I did not find ID " + entity.id));
}
});
}
else {
log.debug(...log_1.formatText(log, "Persisting face timeout expired. I have zero IDs"));
}
this.timeoutHandle = null;
this.currEntityIDs.clear();
if (matchedEntityID) {
this.facePersisted.emit(matchedEntityID);
}
}
handleIDAcquired(presence) {
if (this.timeoutHandle && presence.kind === jibo_common_types_1.SensoryType.PERSON) {
log.debug(...log_1.formatText(log, "FaceID finally occured. Clearing out persisting face timeout"));
this.parent.jibo.timer.clearTimeout(this.timeoutHandle);
this.timeoutHandle = null;
}
}
}
SignalFacePersisted.FACE_ID_WAIT_TIME = 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(...log_1.formatText(log, "ID acquired. By audio: " + presence.audioIdentified + ". By visual: " + presence.visualIdentified + ". By kind: " + presence.kind));
if (presence.kind === jibo_common_types_1.SensoryType.PERSON) {
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(...log_1.formatText(log, "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.lastUpdateTick = 0;
this.lastStateMachineTick = 0;
this.lastPrintoutTick = 0;
this.recentSoundDetected = false;
this.recentMotionDetected = false;
this.recentFaceDetected = false;
this.faceIDAcquiredListener = (entityID) => {
const sensor = Object.assign({}, SensorTypes.faceIDAcquiredSensor, { looperID: entityID });
this.emitHardEvidence(entityID, sensor);
};
this.facePersistedListener = (entityID) => this.emitHardEvidence(entityID, SensorTypes.facePersistedSensor);
this.hjHeardListener = (data) => this.emitModerateEvidence(data, SensorTypes.hjHeardSensor);
this.headTouchListener = (data) => this.emitModerateEvidence(data, SensorTypes.headTouchedSensor);
this.screenTouchListener = (data) => this.emitModerateEvidence(data, SensorTypes.screenTouchedSensor);
this.ambientAudioSpikeListener = (data) => this.emitSoftEvidence(data, SensorTypes.loudSoundSpikeSensor);
}
init() {
this.detector.signalIDAcquired.faceIDAcquired.on(this.faceIDAcquiredListener);
this.detector.signalFacePersisted.facePersisted.on(this.facePersistedListener);
this.parent.jibo.lps.identity.events.hjEvent.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.lps.identity.events.hjEvent.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 deltaUpdate = Date.now() - this.lastUpdateTick;
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;
}
if (this.parent.jibo.lps.getClosestVisualEntity()) {
this.recentMotionDetected = true;
}
if (this.parent.jibo.lps.identity.getVisibleFaces().size > 0) {
this.recentFaceDetected = true;
}
if (deltaSM >= 1000) {
if (this.sm.getCurrentState() === this.somebody) {
if (this.recentFaceDetected) {
this.modEvidenceEvent.emit(SensorTypes.visibleFaceSensor);
}
}
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.lastStateMachineTick = Date.now();
}
if (this.sm.getCurrentState() !== this.nobody && deltaPrintout >= 60000) {
const deltaTime = jibo_cai_utils_1.TimeUtils.msToMinutes(this.timerExpiryMs - Date.now());
log.debug(...log_1.formatText(log, `[${this.sm.getCurrentState().name}] ticktock: ${deltaTime.toFixed(2)} minutes; \t main update loop: ${Math.round(1 / deltaUpdate * 1000)} hz`));
this.lastPrintoutTick = Date.now();
}
this.lastUpdateTick = 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.softEvidenceEvent, this.possiblebody);
this.possiblebody.addInternalTransition('Internal Timeout', this.nobody);
this.possiblebody.addTypedEventTransition(this.resetEvent, this.nobody);
this.nobody.onEntry = (transition, result) => log.debug(...log_1.formatText(log, `[${this.nobody.name}] Enter`));
this.somebody.onEntry = (transition, sensor) => {
if (transition.getSourceState() === this.nobody) {
log.debug(...log_1.formatText(log, `[${this.somebody.name}] Entered from Nobody state; Sending new arrival proactive trigger.`, 'color:purple'));
const arrivalRequest = {
triggerSource: this.parent.jibo.jetstream.types.ProactiveTriggerSource.NEW_ARRIVAL,
triggerData: {
looperID: sensor.looperID,
}
};
this.detector.evaluate(arrivalRequest);
}
log.debug(...log_1.formatText(log, `[${this.somebody.name}] Enter with timeout of ${sensor.timeout} minutes from ${transition} Sensor: ${sensor.name}`));
this.createNewTimerTransition(sensor.timeout, this.somebody, this.possiblebody);
};
this.somebody.onExit = (transition) => {
this.clearTimer();
};
this.possiblebody.onEntry = (transition, sensor) => {
const timeout = sensor ? sensor.timeout : SensorTypes.SOFT_EVIDENCE_TIMEOUT_MINUTES;
const sensorInfo = sensor ? `Sensor: ${sensor.name}` : '';
log.debug(...log_1.formatText(log, `[${this.possiblebody.name}] Enter with timeout of ${timeout} minutes from ${transition} ${sensorInfo}`));
this.createNewTimerTransition(timeout, this.possiblebody, this.nobody);
};
this.possiblebody.onExit = (transition) => {
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);
}
}
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.HARD_EVIDENCE_TIMEOUT_MINUTES = 1;
exports.MODERATE_EVIDENCE_TIMEOUT_MINUTEES = 1;
exports.SOFT_EVIDENCE_TIMEOUT_MINUTES = 1;
exports.faceIDAcquiredSensor = {
name: "ID Acquired",
timeout: exports.HARD_EVIDENCE_TIMEOUT_MINUTES,
};
exports.facePersistedSensor = {
name: "Face Persisted",
timeout: exports.HARD_EVIDENCE_TIMEOUT_MINUTES,
};
exports.hjHeardSensor = {
name: "HJ Heard",
timeout: exports.MODERATE_EVIDENCE_TIMEOUT_MINUTEES,
};
exports.visibleFaceSensor = {
name: "Visible Face",
timeout: exports.MODERATE_EVIDENCE_TIMEOUT_MINUTEES,
};
exports.headTouchedSensor = {
name: "Jibo's Head Touched",
timeout: exports.MODERATE_EVIDENCE_TIMEOUT_MINUTEES,
};
exports.screenTouchedSensor = {
name: "Jibo's Screen Touched",
timeout: exports.MODERATE_EVIDENCE_TIMEOUT_MINUTEES,
};
exports.motionEntitySensor = {
name: "Motion Entity",
timeout: exports.SOFT_EVIDENCE_TIMEOUT_MINUTES,
};
exports.localizedSoundSensor = {
name: "Sound Localized",
timeout: exports.SOFT_EVIDENCE_TIMEOUT_MINUTES,
threshold: 0.3,
};
exports.loudSoundSpikeSensor = {
name: "Sound Loudness",
timeout: exports.SOFT_EVIDENCE_TIMEOUT_MINUTES,
};
},{}],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":80}],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);
}
evaluate() {
if (this.currState === HJState.NOT_IN_PROGRESS) {
log.debug(...log_1.formatText(log, "Passed: HJStatus is " + this.currState));
return true;
}
else {
log.debug(...log_1.formatText(log, "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);
log.debug(...log_1.formatText(log, "HJ heard. HJStatus is in state: " + this.currState));
}
handleHJExpiredTimeout() {
this.currState = HJState.NOT_IN_PROGRESS;
log.debug(...log_1.formatText(log, "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(...log_1.formatText(log, "Skill Change to " + newSkill + ". HJStatus is in state: " + this.currState));
if (this.timeoutHandle) {
log.debug(...log_1.formatText(log, "Skill switch occured. Clearing out timeout"));
this.parent.jibo.timer.clearTimeout(this.timeoutHandle);
this.timeoutHandle = null;
}
}
}
}
SignalHJStatus.HJ_EXPIRE_TIMEOUT = jibo_cai_utils_1.TimeUtils.secondsToMs(15);
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(...log_1.formatText(log, "Passed: Jibo is " + jiboState.circadian));
return true;
}
else {
log.debug(...log_1.formatText(log, "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 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(...log_1.formatText(log, `Passed: Last no-match was not recent: ${sinceLastNoMatch} ms is greater than ${SignalNoMatchStatus.RECENT_NO_MATCH_EXPIRY_MS} ms`));
return true;
}
else {
log.debug(...log_1.formatText(log, `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(...log_1.formatText(log, "Heard global no match"));
}
}
SignalNoMatchStatus.RECENT_NO_MATCH_EXPIRY_MS = jibo_cai_utils_1.TimeUtils.minutesToMs(5);
exports.SignalNoMatchStatus = SignalNoMatchStatus;
},{"../../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('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(...log_1.formatText(log, `Updated Daily budget: ${this.dailyTriggerBudget}`));
log.debug(...log_1.formatText(log, `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(...log_1.formatText(log, `Reset Daily budget: ${this.dailyTriggerBudget}`));
log.debug(...log_1.formatText(log, `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(...log_1.formatText(log, `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(...log_1.formatText(log, `${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(...log_1.formatText(log, `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(...log_1.formatText(log, "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(...log_1.formatText(log, `Rollovered PartOfDay budget: ${this.partOfDayTriggerBudget}`));
}
else {
log.debug(...log_1.formatText(log, "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(...log_1.formatText(log, `Passed: Last trigger was not recent: ${sinceLastTriggerMs} ms is greater than ${SignalRateLimiterStatus.RECENT_TRIGGER_EXPIRY_MS} ms`));
return true;
}
else {
log.debug(...log_1.formatText(log, `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(...log_1.formatText(log, `Passed: ${currPartOfDay.detail} ${currPartOfDay.basic} still has ${remainingBudget} triggers remaining`));
return true;
}
else {
log.debug(...log_1.formatText(log, `Failed: ${currPartOfDay.detail} ${currPartOfDay.basic} has ${remainingBudget} triggers remaining`));
return false;
}
}
evaluateDailyLimit() {
if (this.dailyTriggerBudget > 0) {
log.debug(...log_1.formatText(log, `Passed: Today still has ${this.dailyTriggerBudget} triggers remaining`));
return true;
}
else {
log.debug(...log_1.formatText(log, `Failed: Total has ${this.dailyTriggerBudget} triggers remaining`));
return false;
}
}
rolloverToRemainingPartsOfDay(triggers, startIndex) {
const totalTriggers = Math.round(SignalRateLimiterStatus.ROLLOVER_PROPORTION * triggers);
log.debug(...log_1.formatText(log, `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);
}
}
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}],79:[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(...log_1.formatText(log, "Passed: SkillStatus is " + skillState.skillName));
return true;
}
else {
log.debug(...log_1.formatText(log, "Failed: SkillStatus is " + skillState.skillName));
return false;
}
}
}
exports.SignalSkillStatus = SignalSkillStatus;
},{"../../../common/Utils":28,"../../log":63,"../InhibitingSignal":65}],80:[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"));
},{"./SignalHJStatus":75,"./SignalJiboStatus":76,"./SignalNoMatchStatus":77,"./SignalRateLimiterStatus":78,"./SignalSkillStatus":79}],81:[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}]},{},[81])(81)
});
//# sourceMappingURL=jibo-action-system.js.map