JobEmployer.js

This bot plays the employer in a job-conditions negotiation  /* class=gwtchat.server.JavascriptBotUserWizard */

/* RESOURCES */

var turk = new AWSMechanicalTurkClient;

var humanSideName = "Candidate"; var computerSideName = "Employer";

var domain = new NegotiationDomain(wiki.get('JobCandidateDomain.xml'), 	humanSideName.toLowerCase, 	computerSideName.toLowerCase	);

var negotiator = new GeniusNegotiator(domain,	/*humanUtility =*/  wiki.get('Job'+humanSideName+'ShortTermUtilitySpace.xml'),		/* e.g. JobCandidateShortTermUtilitySpace.xml */	/*computerUtility =*/ wiki.get('Job'+computerSideName+'ShortTermUtilitySpace.xml'), 		/* e.g. JobEmployerShortTermUtilitySpace.xml */	/*computerAgentClassName = */ "agents.RandomIncreasingUtilAgent",	/*maxOffersByHuman = */ 10);

var YesNoCategorizer = Transformer.recall(wiki, 'YesNo.txt'); var NLU = Transformer.recall(wiki, 'Job'+humanSideName+'Negotiation.regexp'); /* e.g. JobCandidateNegotiation.regexp */ var NLG = Transformer.recall(wiki, 'Job'+computerSideName+'Negotiation.regexp'); /* e.g. JobEmployerNegotiation.regexp */

/* STATUS */ var previousIssue; // used for understanding. var currentIssue;      // used for generation. var agreedIssues = new DialogStateSlots(domain.getIssues);     // issues both sides agreed upon. var humanAgreedIssues = new DialogStateSlots(domain.getIssues); // issues the human agreed upon. var computerAgreedIssues = new DialogStateSlots(domain.getIssues); // issues the computer agreed upon.

/* Called once when a human enters the room */ function greethuman(chatter) { negotiator.startNegotiationSession; chat.say(domain.greeting(chatter.name)); chat.say("Say 'help' to learn more."); }

/* Called once when a WOZ enters the room */ function greetwizard(chatter) { chat.sayToWizard('Hi, '+chatter.name+'! It is great you are here. You will help me understand the human!'); }

/* Even elements are input patterns; Odd elements are the actions to run. */ var inputsAndActions = [ /^help/i, function(matches) { chat.say(help); },	//i, function(matches) { // question about matches[1] var issue = matches[1]; if (issue=='initial') tell("");       // reply with a counter-question about an arbitrary issue else if (issue=='agreement') tell("");       // reply with a counter-question about the same issue else if (issue=='final') tell("");       // reply with a counter-question about the same issue else tell("", issue);       // reply with a counter-question about the same issue },	//i, function(matches) { // demand about matches[1], to get matches[2] var issue = verifiedIssue(matches[1]);       if (!issue) return; var value = verifiedValue(matches[2],issue); if (!value) return; tell("");       // reply with an agreement. },	//i, function(matches) { // agree about matches[1], to get matches[2] var issue = verifiedIssue(matches[1]);       if (!issue) return; var value = verifiedValue(matches[2],issue); if (!value) return; tell("");       // reply with a demand (for symmetry). },	//i, function(matches) {    // disagree about matches[1] var issue = verifiedIssue(matches[1]); if (!issue) return; tell("");       // reply with a counter-question about the same issue },	//i, function(matches) { // "if you agree to matches[1], matches[2], I agree to matches[3], matches[4]" var issue1 = verifiedIssue(matches[1]); if (!issue1) return; var value1 = verifiedValue(matches[2],issue1); var issue2 = verifiedIssue(matches[3]); if (!issue2) return; var value2 = verifiedValue(matches[4],issue2); tell("");       // reply with an agreement. },	/^I commit\s*(.+)$/i, function(matches) { if (chat.getHumanChatter==null) chat.complain("Cannot submit without a user","",0.8); else chat.say(turk.submitForm(chat.getHumanChatter, matches[1])); },	/I want A and B/i, function(matches) { chat.say("Please talk about one issue at a time, because the computer cannot understand more than that"); },	/Garbage/i, function(matches) { }, ];

function help { return "We will negotiate several issues related to your job conditions. "+ "For each issue, there are several possible values, ordered from the best to the worst: "+ "\n"+ negotiator.humanUtilitySpaceHTML+ "\n"+ //" You can make at most "+negotiator.maxOffersByHuman+" offers.\n"+ "Try to get the best deal for the most important subjects!\n"+ " Please talk about one issue at a time, because the computer cannot understand more than that.\n"; }

function verifiedIssue(issue) { if (!domain.hasIssue(issue)) { chat.complain("'"+issue+"' is not one of the issues we negotiate. To view the valid issues, type 'help'."); return null; }	return issue; }

function verifiedValue(value,issue) { if (!domain.valueIsValidForIssue(value,issue)) { chat.complain("'"+value+"' is not one of the valid values for "+issue+". To view the valid values, type 'help'."); return null; }	return value; }

/* Called before the first meaningful utterance */ function understandBeforeFirst { currentIssue = null; // during understanding, we use previousIssue and set currentIssue }

/* Called for each meaningful utterance detected at the human's input */ function understand(intention, certainty) { // This is the NLU unit var intentionSemantics = NLU.transform(intention); // return a string <act:issue:value> chat.debug("NLU "+intentionSemantics); for (var i=0; i<inputsAndActions.length; i+=2) { if (matches = inputsAndActions[i].exec(intentionSemantics)) { inputsAndActions[i+1](matches); return; }	}	chat.complain("Sorry, I didn't understand you", "", certainty); };

function tell(intentionSemantics, issue) { // This is the NLG unit chat.debug("NLG "+intentionSemantics); chat.say(NLG.untransform(intentionSemantics)); if (issue) previousIssue = issue; }

/* Called after the last meaningful utterance */ function understandAfterLast { previousIssue = null; // during understanding, we use previousIssue and set currentIssue }

/* Create the input patterns that the WOZ will select from: */ var cachedInputPatterns = domain.inputPatterns; for (var i=0; i<inputsAndActions.length; i+=2) cachedInputPatterns.add(regexpToString(inputsAndActions[i])); function inputPatterns { return cachedInputPatterns; }

var cachedValuesWithoutInputPatterns = domain.valuesWithoutInputPatterns; cachedValuesWithoutInputPatterns.add("quality=useless"); cachedValuesWithoutInputPatterns.add("quality=poor"); cachedValuesWithoutInputPatterns.add("quality=moderate"); cachedValuesWithoutInputPatterns.add("quality=good"); cachedValuesWithoutInputPatterns.add("quality=excellent"); function valuesWithoutInputPatterns { return cachedValuesWithoutInputPatterns; }

function regexpToString(regexp) { var str = regexp.source.replace(/\(.*\)/, "").replace(/\\s[+*]/," "); //print("regexpToString "+str); if (str.charAt(0)=='^') str = str.substring(1,str.length); if (str.charAt(str.length-1)=='$') str = str.substring(0,str.length-1); return str; }