UNPKG

universal_bot

Version:

Taking the principles of aiml - but allowing a dynamic and extendable *.js environment

512 lines (353 loc) 13.2 kB
"use strict"; var meta = require('debug')('intent'); var fs = require('fs'); var resolve = require('path').resolve; var Node = function(name) { this.name = name; this.weight = 0; this.in = []; this.out = []; this.aiml = ""; this.keywords = []; } var Intentions = function(file) { var self = this; this.nodes = []; this.find_by_value = function( type, value) { console.log("FIND " + self.nodes.length ); var list = []; for (var i = 0; i < self.nodes.length; i++) { var node = self.nodes[i]; if (node[type]) { if ( Array.isArray( node[type]) === true) { var arr = node[type]; for (var n = 0; n < arr.length; n++) { if (value === arr[n]) list.push( node ); } } } } if (list.length > 0) return list; else return null; } this.stream = function(arr, direction, target) { var found = false; var copy = arr.slice(0); var n = arr.length -1; var node = arr[n]; var additional = []; var dead = false; meta("Untersuchung des Knoten " + node.name + " -- Direction " + direction); if ( node[direction] ) { // meta("Anzahl Ausgänge: " + node[direction].length ); if (node[direction].length === 0) dead = true; for ( var i = 0; i < node[direction].length; i++) { var name = node[direction][i].name; if (name === target) { found = true; } } } if (! found && ! dead) { for ( var i = 0; i < node[direction].length; i++) { var item = node[direction][i]; var n = self.find( item.name ); // meta("Hier sollte ein neues Array angelegt werden"); var c = copy.slice(0); c.push( n ); additional.push( c ); } } return { dead: dead, additional: additional, found: found } } this.stream_iteration = function(direction, target ) { var temp = []; var deletable = []; var found = false; var ndx = -1; meta(" ITERATION ...................... " + self.iterator); for (var q = 0; q < self.metalist.length; q++) { var n = self.metalist[q]; var res = self.stream( n, direction, target ); if ( res.dead ) { deletable.push ( q ); } if (res.found === true) { meta("HIER GIT ES EINEN FUND"); found = true; ndx = q; } for (var p = 0; p < res.additional.length; p++) { var item = res.additional[p]; // meta( item ); temp.push( item ); } } if ( ! found) { self.iterator ++; self.metalist = []; for (var i = 0; i < temp.length; i++) { if ( ! deletable.includes( i) ) { self.metalist.push( temp[i] ); } } meta("Nach dem Löschen der Items: " + self.metalist.length ); if (self.iterator < 10) self.stream_iteration( direction, target ); } else { meta("ERFOLGREICH " + ndx); var n = self.metalist[ndx]; self.shortest = n; } } this.metalist = []; this.iterator = 0; this.shortest_trajectory = function( target) { self.shortest = null; var node = self.actual; self.metalist = []; self.iterator = 0; self.metalist.push( [ node ]); var list = self.stream_iteration("out", target) meta("====================================================="); if (self.shortest) meta ( self.shortest ); } this.find = function(name) { for (var i = 0; i < self.nodes.length; i++) { var node = self.nodes[i]; if (node.name === name) return node; } return null; } this.addNodes = function( list) { for (var i = 0; i < list.length; i++) { self.nodes.push( new Node(list[i])); } meta("Anzahl der Knoten " + self.nodes.length); } this.addRelation = function(source, target) { var s = self.find(source); if(s) { for (var n = 0; n < target.length; n++) { var t = self.find( target[n] ); if (t) { t.in.push({ name: s.name, weight: 0, }); s.out.push({ name: t.name, weight: 0, }); } } meta("Länge der Verbindungen " + s.out.length); } } this.calculateWeights = function() { for (var i = 0; i < self.nodes.length; i++) { var node = self.nodes[i]; for (var n = 0; n < node.out.length; n++) { var item = node.out[n]; item.weight = (1 / node.out.length).toFixed(2); item.weight = parseFloat( item.weight ); } for (var n = 0; n < node.in.length; n++) { var item = node.in[n]; item.weight = (1 / node.in.length).toFixed(2); item.weight = parseFloat( item.weight ); } } } this.writeFile = function () { self.calculateWeights(); var s = JSON.stringify( self.nodes, null, 4 ); fs.writeFile("lib/Markov.json", s); } this.get_element = function(list, value) { meta ( list ); var next = 0; var last = 0; var elem = null; var name = null; meta( value ); for (var i = 0; i < list.length; i++) { next += list[i].weight; if (value > last && value < next) { name = list[i].name; meta( name ); } last = next; } elem = self.find( name ); return elem; } this.next = function(name) { var node = self.find(name); if (node) { var r = Math.random(); var elem = self.get_element(node.out, r); if ( elem) meta( elem.name); return elem; } return null; } this.previous = function(name) { var node = self.find(name); if (node) { var r = Math.random(); var elem = self.get_element(node.in, r); if ( elem) return elem; } return null; } this.characterize = function( name, obj ) { var n = self.find( name ); if (n){ var x = Object.keys( obj ); for (var i = 0; i < x.length; i++) { var key = x[i]; n[key] = obj[key]; } } } // Die deutsche Version this.define_de = function() { self.addNodes( ['price', 'availability', 'registration', 'payment_mode', 'withdrawal', 'phone_call', 'further_info', 'info_text', 'plausibility', 'target_group', 'Martin Burckhardt', 'website' ]); self.addRelation("availability", ["price", "registration", "payment_mode", "target_group"]); self.addRelation("price", ["registration", "payment_mode", "withdrawal", "plausibility", "info_text" ]); self.addRelation("registration", ["payment_mode", "withdrawal", "plausibility", "info_text", "phone_call" ]); self.addRelation("plausibility", ["Martin Burckhardt"]); self.addRelation("Martin Burckhardt", ["website"]); self.characterize("price", { aiml: "HOW_MUCH", keywords: ["Preis", "Gebühren", "Summe", "Kosten"], excludes: ['NEGATION'] }) self.characterize("availability", { aiml: "AVAILABILITY", keywords: ["Plätze", "plätze", "verfügbar", "noch frei", "frei"], excludes: ['NEGATION'] }) self.characterize("payment_mode", { aiml: "PAYMENT_MODE", keywords: ["Kreditkarte", "Überweisung", "Bezahlung", "überweisen", "bezahlen", "bar"], }) self.characterize("withdrawal", { aiml: "WITHDRAWAL", keywords: ["Storno", "stornieren", "zurücktreten", "rückgängig"], }) self.characterize("website", { aiml: "PHONE", keywords: ["Website", "Webseite", "online", "einloggen", "log in", "anmelden", "Portal"], }) self.characterize("phone_call", { aiml: "PHONE", keywords: ["Telefon", "telefon", "telefonisch", "Telefonat", "persönlich", "am Telefon"], }) self.characterize("target_group", { aiml: "TARGET_GROUP", keywords: ["Zielgruppe", "zielgruppe", "für wen", "adressiert", "richtet sich"], }) self.characterize("further_info", { aiml: "PHONE", keywords: ["Informationen", "Download", "Beschreibung", "schriftlich", "Infomaterial", "infos"], }) self.characterize("plausibility", { aiml: "PHONE", keywords: ["realistisch", "zu komplex", "kompliziert", "Profis", "berufsmäßig"], }) self.characterize("Martin Burckhardt", { aiml: "MARTIN_BURCKHARDT", keywords: ["Martin Burckhardt", "Seminarleiter", "Leiter", "Wer ist"], }) self.calculateWeights(); meta("Länge der Knoten " + self.nodes.length) meta( self.nodes ); var s = JSON.stringify( self.nodes, null, 4); fs.writeFile("NITIntentions_DE.json", s); } this.define = function() { meta("sollte Intentionen definieren"); self.addNodes( ['price', 'registration', 'payment_mode', 'withdrawal', 'phone_call', 'further_info', 'info_text', 'plausibility', 'Martin Burckhardt', 'website' ]); self.addRelation("price", ["registration", "payment_mode", "withdrawal", "plausibility", "info_text" ]); self.addRelation("registration", ["payment_mode", "withdrawal", "plausibility", "info_text", "phone_call" ]); self.addRelation("plausibility", ["Martin Burckhardt"]); self.addRelation("Martin Burckhardt", ["website"]); self.characterize("price", { aiml: "HOW_MUCH", keywords: ["price", "how much", "pay"], excludes: ['NEGATION'] }) self.characterize("payment_mode", { aiml: "PAYMENT_MODE", keywords: ["credit card", "payment"] }) self.characterize("withdrawal", { aiml: "WITHDRAWAL", keywords: ["withdraw", "resign"] }) self.characterize("phone_call", { aiml: "PHONE", keywords: ["phone", "personally"] }) self.characterize("info_text", { aiml: "INFO", keywords: ["info", "pdf", "written"] }) self.characterize("plausibility", { aiml: "PLAUSIBILITY", keywords: ["realistic", "learning"] }) self.characterize("Martin Burckhardt", { aiml: "MARTIN_BURCKHARDT", keywords: ["leader", "lecturer"] }) self.calculateWeights(); meta("Länge der Knoten " + self.nodes.length) meta( self.nodes ); var s = JSON.stringify( self.nodes, null, 4); fs.writeFile("NITIntentions.json", s); } this.init = function() { // self.define_de(); if (file) { self.nodes = require( resolve( file) ); meta ("Anzahl der Knoten " + self.nodes.length); self.calculateWeights(); if (self.nodes.length > 0) self.actual = self.nodes[0]; // self.shortest_trajectory("website"); } else self.define(); } self.init(); } // var i = new Intentions(); module.exports = Intentions;