}//compileRules(string parentId, List<Rule> rules) public Reply GetReply(string input, string lastfired, Hashtable vars, string prependOutput) { List <Match> matches = new List <Match>(); //do replacements, strip áccents is done in ReplaceOnInput if there are no input replacements string inputReplaced = TextToolbox.ReplaceOnInput(input, this.inputReplacements); //search the children and virtual children (links) of lastfired rule if (this.inputs.ContainsKey(lastfired)) { foreach (InputRecognizer ir in this.inputs[lastfired]) { //if the input recognizer is a capture, use the original input Match match = ir.Matches((ir.IsCapture ? input : inputReplaced), vars, this.csToolbox); if (match.ConfidenceFactor != 0.0) { //copy shortTermMemory vars to inputVars Hashtable inputVars = new Hashtable(); foreach (object key in vars.Keys) { inputVars[key] = vars[key]; } //captures the variables and adds them to the inputVars object ir.CaptureVars(input, inputVars); matches.Add(match); } } } if (matches.Count == 0 && this.inputs.ContainsKey("_root")) { //search all of the primaries foreach (InputRecognizer ir in this.inputs["_root"]) { //if the input recognizer is a capture, use the original input Match match = ir.Matches((ir.IsCapture ? input : inputReplaced), vars, this.csToolbox); if (match.ConfidenceFactor != 0.0) { //copy shortTermMemory vars to inputVars Hashtable inputVars = new Hashtable(); foreach (object key in vars.Keys) { inputVars[key] = vars[key]; } //captures the variables and adds them to the inputVars object ir.CaptureVars(input, inputVars); matches.Add(match); } } } if (matches.Count == 0) { return(null); } matches.Sort(); Match matchBest = (Match)matches[0]; //use the matching vars, but maintain the original object so that it persists vars.Clone(); foreach (object key in matchBest.Vars.Keys) { vars[key] = matchBest.Vars[key]; } //increment the usage count on the chosed InputRecognizer matchBest.InputRecognizer.IncUsageCount(); string ruleId = matchBest.InputRecognizer.RuleId; if (!this.outputs.ContainsKey(ruleId) || this.outputs[ruleId].Count == 0) { Reply noOutputFoundReply = new Reply("Rule contains no outputs.", "", "", ruleId, 0, this.knowledgeBaseItem); if (this.csToolbox.StandardNoOutputFoundDefined) { string noOutputFoundText = this.csToolbox.ExecuteOnNoOutputFound(vars, noOutputFoundReply); noOutputFoundReply.Text += this.DoTextReplacements(noOutputFoundText); noOutputFoundReply.AgentText += this.DoAgentTextReplacements(noOutputFoundText); } return(noOutputFoundReply); } List <Output> alOutputs = new List <Output>(); if (this.outputs.ContainsKey(ruleId)) { alOutputs = new List <Output>(this.outputs[ruleId]); } bool trueNonEmptyOutputConditionFound = false; //filter out outputs with false conditions for (int i = 0; i < alOutputs.Count; i++) { Output o = (Output)alOutputs[i]; if (!this.csToolbox.ExecuteCondition(o.Id, vars)) { alOutputs.RemoveAt(i); i--; } else if (o.Condition != null && o.Condition != "") { trueNonEmptyOutputConditionFound = true; } } if (alOutputs.Count == 0)//all outputs were removed { Reply noOutputFoundReply = new Reply("No true output found.", "", "", ruleId, 0, this.knowledgeBaseItem); if (this.csToolbox.StandardNoOutputFoundDefined) { string noOutputFoundText = this.csToolbox.ExecuteOnNoOutputFound(vars, noOutputFoundReply); noOutputFoundReply.Text += this.DoTextReplacements(noOutputFoundText); noOutputFoundReply.AgentText += this.DoAgentTextReplacements(noOutputFoundText); } return(noOutputFoundReply); } //filter out outputs with no conditions if there is an output which has a true condition if (trueNonEmptyOutputConditionFound) { for (int i = 0; i < alOutputs.Count; i++) { Output o = (Output)alOutputs[i]; if (o.Condition == null || o.Condition == "") { alOutputs.RemoveAt(i); i--; } } } //choose an output at random Output outputChosen = null; for (int i = 0; i < alOutputs.Count; i++) //the try again loop { outputChosen = ((Output)alOutputs[random.Next(alOutputs.Count)]); if (!this.recentOutputsByRule.ContainsKey(ruleId) || !this.recentOutputsByRule[ruleId].Contains(outputChosen.Id)) { break; } } //update the recent list for this rule if (alOutputs.Count > 1) { if (!this.recentOutputsByRule.ContainsKey(ruleId)) { this.recentOutputsByRule[ruleId] = new List <string>(alOutputs.Count - 1); } List <string> recent = this.recentOutputsByRule[ruleId]; int index = recent.IndexOf(outputChosen.Id); if (index != -1) { recent.RemoveAt(index); } else if (recent.Count == alOutputs.Count - 1) { recent.RemoveAt(0); } recent.Add(outputChosen.Id); } //replace vars and output synonyms string outputChosenText = prependOutput + outputChosen.Text; if (this.csToolbox.OutputExists(outputChosen.Id)) { outputChosenText = this.csToolbox.ExecuteOutput(outputChosen.Id, vars); } outputChosenText = TextToolbox.ReplaceVars(outputChosenText, vars); outputChosenText = TextToolbox.ReplaceOutputSynonyms(outputChosenText, this.synonyms); //execute c# code in the command field string outputChosenCmd = outputChosen.Cmd; if (this.csToolbox.OutputExists(outputChosen.Id + "_cmd")) { outputChosenCmd = this.csToolbox.ExecuteOutput(outputChosen.Id + "_cmd", vars); } string outputText = this.DoTextReplacements(outputChosenText); string agentText = this.DoAgentTextReplacements(outputChosenText); string outputCmd = TextToolbox.ReplaceVars(outputChosenCmd, vars); return(new Reply(outputText, agentText, outputCmd, matchBest.InputRecognizer.RuleId, matchBest.ConfidenceFactor, this.knowledgeBaseItem)); } //GetReply(string input, string lastfired)
public Reply GetReply(string input, State state) { logger.LogMessage("GetReply"); state.Vars["_input"] = input; state.Vars["_lastinput"] = state.Lastinput; state.Vars["_lastfired"] = state.Lastfired; state.Vars["_time"] = DateTime.Now.ToString("h:mm tt"); state.Vars["_time24"] = DateTime.Now.ToString("HH:mm"); state.Vars["_date"] = DateTime.Now.ToString("MMM. d, yyyy"); state.Vars["_month"] = DateTime.Now.ToString("MMMM"); state.Vars["_dayofmonth"] = DateTime.Now.ToString("d ").Trim(); state.Vars["_year"] = DateTime.Now.ToString("yyyy"); state.Vars["_dayofweek"] = DateTime.Now.ToString("dddd"); if (input.Length == 0) { input = "_blank"; } state.Lastinput = input; bool standardNoRuleFiredDefined = false; Reply noRuleFiredReply = new Reply("", "", "", "", 0.0, null); foreach (string stPath in state.CurrentKBs) { if (this.compiledKnowledgeBases.ContainsKey(stPath)) { logger.LogMessage("compiledKnowledgeBases(" + stPath + ")"); CompiledKnowledgeBase ckb = (CompiledKnowledgeBase)this.compiledKnowledgeBases[stPath]; string ckbOutput = ckb.CSToolbox.ExecuteOnBeforeRuleFired(state); //update our input var incase the Before Rule Fired changes it input = (string)state.Vars["_input"]; state.Lastinput = input; Reply reply = ckb.GetReply(input, state.Lastfired, state.Vars, ckbOutput); if (reply != null) { logger.LogMessage("reply != null"); ckbOutput = ckb.CSToolbox.ExecuteOnAfterRuleFired(state, reply); string outputText = ckb.DoTextReplacements(ckbOutput); string agentText = ckb.DoAgentTextReplacements(ckbOutput); reply.Text += outputText; reply.AgentText += agentText; state.Lastfired = reply.RuleId; state.Vars["_lastoutput"] = reply.Text; return(reply); } if (ckb.CSToolbox.StandardNoRuleFiredDefined) { logger.LogMessage("ckb.CSToolbox.StandardNoRuleFiredDefined"); standardNoRuleFiredDefined = true; //if this ckb has a no rule fired handler, fire it noRuleFiredReply.KBItem = ckb.KnowledgeBaseItem; string noReplyText = ckb.CSToolbox.ExecuteOnNoRuleFired(state, noRuleFiredReply); noRuleFiredReply.Text += ckb.DoTextReplacements(noReplyText); noRuleFiredReply.AgentText += ckb.DoAgentTextReplacements(noReplyText); } } } if (standardNoRuleFiredDefined) { return(noRuleFiredReply); } return(null); //if there's no reply, return null } //GetReply(string input)