All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.freedomotic.core.FreeFormCommandsInterpreter Maven / Gradle / Ivy

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.freedomotic.core;

import com.freedomotic.bus.BusConsumer;
import com.freedomotic.bus.BusMessagesListener;
import com.freedomotic.bus.BusService;
import com.freedomotic.events.GenericEvent;
import com.freedomotic.exceptions.NoResultsException;
import com.freedomotic.exceptions.VariableResolutionException;
import com.freedomotic.nlp.Nlp;
import com.freedomotic.nlp.NlpCommand;
import com.freedomotic.reactions.Command;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.inject.Inject;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.ObjectMessage;

/**
 * Listen for free-form (natural language) text commands on channel
 * "app.commands.interpreter.nlp" and using NLP tools execute
 * the most similar command that the framework has in memory. For example a
 * speech recognition utility may return a free-form text that can be
 * interpreted by this module as an executable command. Another example is a
 * chat bot that executes text commands.
 *
 * It expects a command with the following properties
 * 
    *
  • text = A_STRING
  • *
* * It replies back if the received command cannot be interpreted, so you can send * the command and expect a reply in a given timeout. Read the see section for more info. * * @see BusService#send(com.freedomotic.reactions.Command) * @author enrico */ public class FreeFormCommandsInterpreter implements BusConsumer { private static final Logger LOG = Logger.getLogger(FreeFormCommandsInterpreter.class.getName()); private static final String MESSAGING_CHANNEL = "app.commands.interpreter.nlp"; private BusMessagesListener listener; // Dependencies private final NlpCommand nlpCommands; private final BusService busService; @Inject public FreeFormCommandsInterpreter(NlpCommand nlpCommands, BusService busService) { this.nlpCommands = nlpCommands; this.busService = busService; register(); } /** * Register one or more channels to listen to */ private void register() { listener = new BusMessagesListener(this, busService); listener.consumeCommandFrom(getMessagingChannel()); } public String getMessagingChannel() { return MESSAGING_CHANNEL; } @Override public void onMessage(ObjectMessage message) { Object jmsObject = null; Destination replyChannel = null; String correlationId = null; try { jmsObject = message.getObject(); // Save some data for reply replyChannel = message.getJMSReplyTo(); correlationId = message.getJMSCorrelationID(); } catch (JMSException ex) { LOG.log(Level.SEVERE, null, ex); } if (jmsObject instanceof Command) { // Get the free-form text form the received command Command command = (Command) jmsObject; String text = command.getProperty("text"); // Use NLP to find the most similar Command using the given free-form text Command mostSimilar = null; try { mostSimilar = findMostSimilarCommand(text); } catch (NoResultsException ex) { LOG.log(Level.WARNING, "The given natural language text ''{0}'' cannot be recognized as a valid framework command", text); command.setExecuted(false); busService.reply(command, replyChannel, correlationId); } // Generate an almost empty event used to resolve commands properites (eg: current time and date) GenericEvent event = new GenericEvent(this); Resolver resolver = new Resolver(); resolver.addContext("event.", event.getPayload()); // Try to resolve the commands properties against the created event Command resolvedCommand = null; try { resolvedCommand = resolver.resolve(mostSimilar); } catch (CloneNotSupportedException | VariableResolutionException ex) { Logger.getLogger(FreeFormCommandsInterpreter.class.getName()).log(Level.SEVERE, null, ex); } // Schedule the command for execution busService.send(resolvedCommand); } } protected Command findMostSimilarCommand(String phrase) throws NoResultsException { // Compute the commands ranking List> ranking = nlpCommands.computeSimilarity(phrase, 10); // Avoid returning a command with zero similarity if (ranking.isEmpty() || ranking.get(0).getSimilarity() <= 0) { throw new NoResultsException("No command is similar enough to '" + phrase + "'"); } // Get the most similar command (it is in the top of the list) return ranking.get(0).getElement(); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy