diff --git a/Dockerfile b/Dockerfile index eb7d0678c27da7e0a114179fe8298ef21264f7dd..f616870286e3ab1b828eadbbe0df995e29273a80 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,7 +17,8 @@ ENV HUBOT_LANG='pt' \ RESPOND_TO_DM=true \ RESPOND_TO_LIVECHAT=true \ RESPOND_TO_EDITED=true \ - LISTEN_ON_ALL_PUBLIC=false + LISTEN_ON_ALL_PUBLIC=false \ + HUBOT_NATURAL_DEBUG_MODE=false RUN apk --update add --no-cache git python make g++ && \ addgroup -S hubotnat && adduser -S -g hubotnat hubotnat diff --git a/docker-compose.yml b/docker-compose.yml index bf83a8e7e2aef624728d4c4ecb86c33bf47ca362..7022056e90eb7572dd431efc3ea01b10444123ab 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -61,6 +61,7 @@ services: - ROCKETCHAT_ROOM=GENERAL - ROCKETCHAT_USER=botnat - ROCKETCHAT_PASSWORD=botnatpass + - HUBOT_NATURAL_DEBUG_MODE=true volumes: - ./scripts:/home/hubotnat/bot/scripts - ./training_data:/home/hubotnat/bot/training_data diff --git a/scripts/bot/index.coffee b/scripts/bot/index.coffee index 3ce78e3837a1531aa55d4322a6238aaafb38a4de..9641a7becbaf4a5bfa51ebb8cc1863aab0458346 100644 --- a/scripts/bot/index.coffee +++ b/scripts/bot/index.coffee @@ -1,19 +1,22 @@ fs = require 'fs' path = require 'path' natural = require 'natural' + lang = (process.env.HUBOT_LANG || 'en') if lang == "en" PorterStemmer = require path.join '..','..','node_modules','natural','lib','natural','stemmers','porter_stemmer.js' else PorterStemmer = require path.join '..','..','node_modules','natural','lib','natural','stemmers','porter_stemmer_' + lang + '.js' +debug_mode = ((process.env.HUBOT_NATURAL_DEBUG_MODE == 'true') || false) + config = {} events = {} nodes = {} error_count = 0 err_nodes = 0 -{regexEscape} = require path.join '..', 'lib', 'common.coffee' +{regexEscape, loadConfigfile} = require path.join '..', 'lib', 'common.coffee' eventsPath = path.join __dirname, '..', 'events' for event in fs.readdirSync(eventsPath).sort() @@ -138,8 +141,10 @@ clearErrors = (res) -> key = 'errors_'+res.envelope.room+'_'+res.envelope.user.id res.robot.brain.set(key, 0) -module.exports = (_config, robot) -> +module.exports = (_config, _configPath, robot) -> config = _config + configPath = _configPath + if not config.interactions?.length robot.logger.warning 'No interactions configured.' return @@ -147,20 +152,30 @@ module.exports = (_config, robot) -> robot.logger.warning 'No trust level configured.' return - console.log 'Processing interactions' - console.time 'Processing interactions (Done)' classifier = new natural.LogisticRegressionClassifier(PorterStemmer) - #console.log(config.interactions) - for interaction in config.interactions - {name, classifiers, event} = interaction - nodes[name] = new events[event] interaction - # count error nodes - if name.substr(0,5) == "error" - err_nodes++ - if interaction.level != 'context' - classifyInteraction interaction, classifier - classifier.train() - console.timeEnd 'Processing interactions (Done)' + + trainBot = (retrain = false) -> + console.log 'Processing interactions' + console.time 'Processing interactions (Done)' + + if retrain + nodes = {} + classifier = new natural.LogisticRegressionClassifier(PorterStemmer) + + for interaction in config.interactions + {name, classifiers, event} = interaction + nodes[name] = new events[event] interaction + # count error nodes + if name.substr(0,5) == "error" + err_nodes++ + if interaction.level != 'context' + classifyInteraction interaction, classifier + + classifier.train() + + console.timeEnd 'Processing interactions (Done)' + + trainBot() processMessage = (res, msg) -> context = getContext(res) @@ -226,9 +241,12 @@ module.exports = (_config, robot) -> currentNode = nodes[node_name or error_node_name] currentNode.process.call @, res, msg, subClassifications + if debug_mode + robot.respond /bottrain/i, (res) -> + config = loadConfigfile(configPath) + trainBot(true) + robot.hear /(.+)/i, (res) -> - # console.log(res) - #console.log(res.answer) res.sendWithNaturalDelay = sendWithNaturalDelay.bind(res) msg = res.match[0].replace res.robot.name+' ', '' msg = msg.replace(/^\s+/, '') diff --git a/scripts/index.coffee b/scripts/index.coffee index ef0c95925db86b8541e492d1faf16bac9bd82c0a..38bb40cc565fc2cb796d781727d51536ac28ba43 100644 --- a/scripts/index.coffee +++ b/scripts/index.coffee @@ -1,6 +1,6 @@ -fs = require 'fs' -yaml = require 'js-yaml' path = require 'path' + +{loadConfigfile} = require path.join path.join __dirname, 'lib', 'common.coffee' chatbot = require path.join __dirname, 'bot', 'index.coffee' hubotPath = module.parent.filename @@ -9,13 +9,10 @@ corpus = (process.env.HUBOT_CORPUS || 'corpus.yml') configPath = path.join hubotPath, 'training_data', corpus try - console.log("Loading corpus: " + configPath) - config = yaml.safeLoad fs.readFileSync configPath, 'utf8' + config = loadConfigfile configPath catch err - console.error "An error occurred while trying to load bot's config." - console.error err process.exit() -chatbot = chatbot.bind null, config +chatbot = chatbot.bind null, config, configPath module.exports = chatbot diff --git a/scripts/lib/common.coffee b/scripts/lib/common.coffee index baa3da2ed97552854c9fec95afda799e985fbf1a..63c178f82a9458fd005892544db5bae2ee3d633b 100644 --- a/scripts/lib/common.coffee +++ b/scripts/lib/common.coffee @@ -1,3 +1,6 @@ +fs = require 'fs' +yaml = require 'js-yaml' + common = {} common.applyVariable = (string, variable, value, regexFlags = 'i') -> @@ -21,4 +24,13 @@ common.regexEscape = (string) -> #http://stackoverflow.com/a/6969486 string.replace /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&" +common.loadConfigfile = (filepath) -> + try + console.log("Loading corpus: " + filepath) + return yaml.safeLoad fs.readFileSync filepath, 'utf8' + catch err + console.error "An error occurred while trying to load bot's config." + console.error err + throw "Error on loading YAML file " + filepath + module.exports = common diff --git a/training_data/corpus.yml b/training_data/corpus.yml index 9993e73555467633f2158561a53a271733510f17..1080c8bfb81b1763a4f777786a786bed1f2be8e4 100644 --- a/training_data/corpus.yml +++ b/training_data/corpus.yml @@ -156,7 +156,6 @@ interactions: trust: .8 interactions: - get-programacao - - cancela-programacao # error: # - erro-trilha event: respond