EmployerFullOffers.js

 /* class=gwtchat.server.JavascriptBotUserWizard */

var domain = new NegotiationDomain(wiki.get('JobCandidateDomain.xml'), 	/*humanSideName = */  "candidate", 	/*computerSideName =*/ "employer"	);

var negotiator = new GeniusNegotiator(domain,	/*humanUtility =*/  wiki.get('JobCandidateShortTermUtilitySpace.xml'), 	/*computerUtility =*/ wiki.get('JobEmployerShortTermUtilitySpace.xml'), 	/*computerAgentClassName = */ "agents.RandomIncreasingUtilAgent",	/*maxOffersByHuman = */ 10);

var slots = new DialogStateSlots(domain.getIssues);

var YesNoCategorizer = Transformer.recall(wiki, 'YesNo.txt');

/* Create the input patterns that the WOZ will select from: */ var cachedInputPatterns = domain.inputPatterns; cachedInputPatterns.add("yes"); cachedInputPatterns.add("no"); cachedInputPatterns.add("I want "); cachedInputPatterns.add("I don't care"); cachedInputPatterns.add("I agree"); cachedInputPatterns.add("I disagree"); cachedInputPatterns.add("I quit"); cachedInputPatterns.add("I commit"); function inputPatterns { return cachedInputPatterns; }

var cachedValuesWithoutInputPatterns = domain.valuesWithoutInputPatterns; function valuesWithoutInputPatterns { return cachedValuesWithoutInputPatterns; }

var humanIsFirst = true;

function understandWithoutContext(intention, certainty) { var matches, issueAndValue;

if ((issueAndValue = domain.issueAndValue(intention, currentIssue)) !=null) { var issueName = issueAndValue.getKey; var value = issueAndValue.getValue; if (issueName!=null) { if (domain.valueIsValidForIssue(value, issueName)) { understandThatUserWants(issueName, value, certainty); } else { chat.complain(misunderstandingValueForIssue(issueName, value),         questionAboutCurrentIssue, certainty); }   } else { chat.complain(misunderstandingValue(value),       questionAboutCurrentIssue, certainty); }

} else if (matches = /i want (.*)/i.exec(intention)) { // wrong value var value = matches[1]; if (currentIssue) { if (domain.valueIsValidForIssue(value, currentIssue)) { understandThatUserWants(currentIssue, value, certainty); } else { chat.complain(misunderstandingValueForIssue(currentIssue, value),         questionAboutCurrentIssue, certainty); }   } else { chat.complain(misunderstandingValue(value),       questionAboutCurrentIssue, certainty); } }

else if (matches = /i don.t care about (.*)/i.exec(intention)) { var issueName = matches[1]; // I don't care about X => X    if (domain.hasIssue(issueName)) { understandThatUserWants(issueName, null, certainty); } else { chat.complain(misunderstandingIssue(issueName),       questionAboutCurrentIssue, certainty); } }

else if (/i agree/i.exec(intention)) { if (negotiator.getLastBidByComputer==null) { chat.complain("What exactly do you agree to? I didn't offer you anything! ","",certainty); } else { if (certainty>=0.9) { negotiator.humanAccepts; endNegotiation(negotiator.getLastBidByComputer); } else { ask(null, explicitConfirmationAccept(negotiator.getLastBidByComputer),		  /*yes=*/ intention,		   /*no=*/  slots.hasCurrentSlot? domain.questionAbout(slots.getCurrentSlot): "So, what do you want to change? "); }   }  }

else if (/i disagree/i.exec(intention)) { negotiator.humanRejects; }

else if (/i quit/i.exec(intention)) { if (certainty>=0.9) { negotiator.humanQuits; endNegotiation(null); } else { ask(null, confirmQuit,		/*yes=*/ intention,		/*no=*/ slots.hasCurrentSlot? domain.questionAbout(slots.getCurrentSlot): "So, what do you want to change? "); } }

else if (/i commit/i.exec(intention)) { if (negotiator.maxOffersByHuman<=0) { chat.say(noMoreOffers); } else { var bid = negotiator.bidFromFilledSlots(slots.getFilledSlots); if (certainty>=0.9) { chat.say(implicitConfirmationOffer(bid)); negotiator.humanOffers(bid); chat.say("You have "+negotiator.maxOffersByHuman+" offers left."); } else { ask(null, explicitConfirmationOffer(bid),         /*yes=*/ intention,          /*no=*/  "So, what do you want to change? "); }   }  }

else if (/restart/i.exec(intention)) { greethuman(/*name=*/"", /*chatterid (ignored)=*/0); }

else if (/i don.t care/i.exec(intention)) { if (slots.hasCurrentSlot) { understandThatUserWants(slots.getCurrentSlot, null, certainty); } else { chat.complain("Don't care about what? ","",certainty); } }

else if (/^yes\b/i.exec(intention) || /^no\b/i.exec(intention)) { chat.complain("Why do you say "+intention+"? I didn't ask you anything! ","",certainty);

} else { /* assume that the user said what he wants, with a lower certainty: */ if (domain.valueIsValidForIssue(intention, currentIssue)) { understandThatUserWants(currentIssue, intention, certainty); } else { var issueName = domain.issueByValue(intention.toLowerCase); if (issueName!=null) { understandThatUserWants(issueName, intention, certainty-0.2); } else { chat.complain(misunderstanding,        (lastQuestion==null? questionAboutCurrentIssue: lastQuestion), certainty); }   }  } }

understandInContext = understandWithoutContext; // initially there is no context

function understandThatUserWants(slot, value, certainty) { if (slot==undefined) { java.lang.System.err.println("undefined slot: understandThatUserWants("+slot+","+ value+","+ certainty+")"); return; }

if (negotiator.maxOffersByHuman<=0) { chat.say(noMoreOffers); return; }

if (certainty>=0.8) { slots.fillSlot(slot, value); newSlotFilled = true; if (certainty>=0.9) { chat.say(minimalConfirmation); } else { nextImplicitConfirmations.push(domain.confirmationAbout(slot, value)); } } else { slots.setCurrentSlot(slot); currentIssue = slot; var question = explicitConfirmation(slot, value); nextQuestion = question;

understandInContext = function(intention, certainty) { if (/^yes\b/.exec(intention)) { understandThatUserWants(slot, value, 0.95); } else if (/^no\b/.exec(intention)) { chat.say("OK, so "+questionAboutCurrentIssue); } else { // the human didn't answer the question, but said something else: lastQuestion = question; understandWithoutContext(intention, certainty); }	} }

//print ("currentslot="+slots.getCurrentSlot+"\n"); }

/* Called once when a human enters the room */ function greethuman(chatter) { negotiator.startNegotiationSession; slots.clear;

chat.say(domain.greeting(chatter.name)+   " \nWe will negotiate several issues, ordered from the most important to the least important "+    "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");

if (humanIsFirst) { negotiator.setHumanTurn; chat.say("You will be the first to say what you want. "+questionAboutCurrentIssue); } else { negotiator.setComputerTurn; chat.say("I will make the first offer. "); getComputerActionFromNegotiationAgent; } }

/* 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 user!'); }

var newSlotFilled = false; var nextImplicitConfirmations = [];

/* Called before the first meaningful utterance */ function understandBeforeFirst { newSlotFilled = false; nextImplicitConfirmations = []; nextQuestion = null; }

/* Called for each meaningful utterance detected at the human's input */ function understand(intention, certainty) { lastQuestion = null; //intention = substituter.substitute(intention); // simple text substitutions

var yesNo = YesNoCategorizer.bestTag(intention); if (yesNo=='yes' || yesNo=='no') intention = yesNo;

if (!understandInContext) print("ERROR: Null function understandInContext!\n"); else { var understandInCurrentContext = understandInContext; understandInContext = understandWithoutContext;  // forget the context after using it    understandInCurrentContext(intention, certainty); // understand the intention in the current context } }

/* Called after the last meaningful utterance */ function understandAfterLast { if (newSlotFilled) { if (slots.allSlotsFilled) { understand("I commit", 0.6); // commit bid with a low certainty. to let the user confirm/change. } else { nextQuestion = questionAboutCurrentIssue; }	}

var nextConfirmationText = ''; if (nextImplicitConfirmations.length>0) { nextConfirmationText += 'I see, '; for (i=0; i0) nextConfirmationText += " and "; nextConfirmationText += nextImplicitConfirmations[i]; }		nextConfirmationText += ". "; }

if (nextQuestion) nextConfirmationText += nextQuestion; chat.say(nextConfirmationText);

if (negotiator.isComputerTurn) getComputerActionFromNegotiationAgent; }

function displayname { return "Boss"; }

function color { return "#480";  }

/* * QUESTIONS AND CONFIRMATION TEXTS */

var currentIssue=null; function questionAboutCurrentIssue { slots.setCurrentSlotIfEmpty; currentIssue = slots.getCurrentSlot; return domain.questionAbout(currentIssue); }

function explicitConfirmation(issue, value) { return "So, "+ domain.confirmationAbout(issue, value) + "? "; }

function minimalConfirmation { return "I see. "; }

function explicitConfirmationOffer(bid) { return "So, your offer is "+bid+"? "; } function implicitConfirmationOffer(bid) { return "Well, Let me think about it. "; }

function explicitConfirmationAccept(bid) { return "So, do you agree to my offer: "+bid+"? "; }

function confirmQuit { return "Do you really want to quit? "; }

function noMoreOffers { return "Sorry, you cannot make any more offers! Either agree to my offer or quit.";}

/* * MISUNDERSTANDING TEXTS */

function misunderstanding { return "I didn't understand you. "; } function misunderstandingValue(value) { return value+" is not a valid value. "; } function misunderstandingIssue(issue) { return issue+" is not one of the issues we negotiate about. "; } function misunderstandingValueForIssue(issueName, value) { return value+" is not a valid value for "+issueName+". Valid values are: "+domain.valuesByIssue(issueName); }

function getComputerActionFromNegotiationAgent { var computerAction = negotiator.computerAgentAction; if (computerAction!=null) { if (negotiator.actionIsAccept(computerAction)) { if (negotiator.getLastBidByHuman == null) { // ERROR: accept without offer! chat.complain("My braincells are probably sick. I accepted your offer but you didn't make any offer!","",0.5); } else { endNegotiation(negotiator.getLastBidByHuman); }		} else if (negotiator.actionIsReject(computerAction)) { chat.say("I disagree to your offer. "); } else if (negotiator.actionIsEndNegotiation(computerAction)) { chat.say("I had enough of this negotiation. I quit. "); endNegotiation(null); } else if (negotiator.actionIsOffer(computerAction)) { chat.say("My offer is: " + computerAction.getBid.toString); } else { chat.say("I say: " + computerAction.toString); }	}	negotiator.setHumanTurn; }

function endNegotiation(finalBid) { var utility = negotiator.humanUtility(finalBid); var maxUtility = negotiator.getHumanMaxUtility; if (finalBid==null) { chat.say("Sorry, we couldn't reach an agreement. "); } else { chat.say("Great! We agreed on "+finalBid+". "); }

relativeUtility = Math.round(utility/maxUtility*100); if (utility > 1) { chat.say("The value of your offer is "+utility+" out of "+maxUtility+", so your score is "+relativeUtility+"%. "); } else { chat.say("The value of your offer is "+relativeUtility+"% of the maximum possible value. "); } }

var lastQuestion = null; var nextQuestion = null; function ask(issue, question, humanIntentionToConfirm, questionIfHumanRejects) { nextQuestion = question; understandInContext = function(intention, certainty) { if (/^yes\b/.exec(intention)) { if (issue!=null) currentIssue = issue; understandWithoutContext(humanIntentionToConfirm, 0.95); } else if (/^no\b/.exec(intention)) { if (issue!=null) currentIssue = issue; chat.say(questionIfHumanRejects); } else { // the human didn't answer the question, but said something else: lastQuestion = question; understandWithoutContext(intention, certainty); }	} }