Browse Source

add cortex shot term memory

nico 7 years ago
parent
commit
1180341b3a

+ 111 - 0
kalliope/core/Cortex.py

@@ -0,0 +1,111 @@
+import logging
+
+import jinja2
+from kalliope.core.Utils.Utils import Utils
+
+from kalliope.core.Models import Singleton
+from six import with_metaclass
+
+logging.basicConfig()
+logger = logging.getLogger("kalliope")
+
+
+class Cortex(with_metaclass(Singleton, object)):
+    """
+    short-term memories of kalliope. Used to store object with a "key" "value"
+    """
+    # this dict cotain the short term memory of kalliope.
+    # all keys present in this dict has been saved from a user demand
+    memory = dict()
+    # this is a temp dict that allow us to store temporary parameters that as been loaded from the user order
+    # if the user want to a key from this dict, the key and its value will be added o the memory dict
+    temp = dict()
+
+    def __init__(self):
+        logger.debug("[Cortex] New memory created")
+
+    @classmethod
+    def get_memory(cls):
+        """
+        Get the current dict of parameters saved in memory
+        :return: dict memory
+        """
+        return cls.memory
+
+    @classmethod
+    def save(cls, key, value):
+        """
+        Save a new value in the memory
+        :param key: key to save
+        :param value: value to save into the key
+        """
+        if key in cls.memory:
+            logger.debug("[Cortex] key %s already present in memory with value %s. Will be overridden"
+                         % (key, cls.memory[key]))
+        logger.debug("[Cortex] key saved in memory. key: %s, value: %s" % (key, value))
+        cls.memory[key] = value
+
+    @classmethod
+    def get_from_key(cls, key):
+        try:
+            return cls.memory[key]
+        except KeyError:
+            logger.debug("[Cortex] key %s does not exist in memory" % key)
+            return None
+
+    @classmethod
+    def add_parameters_from_order(cls, dict_parameter):
+        logger.debug("[Cortex] place parameters in temp list: %s" % dict_parameter)
+        cls.temp.update(dict_parameter)
+
+    @classmethod
+    def get_parameters_from_order(cls):
+        """
+        return the current list of
+        :return:
+        """
+        return cls.temp
+
+    @classmethod
+    def clean_parameter_from_order(cls):
+        """
+        Clean the temps memory that store parameters loaded from vocal order
+        """
+        logger.debug("[Cortex] Clean temp memory")
+        cls.temp = dict()
+
+    @classmethod
+    def save_memory(cls, dict_parameter_to_save, neuron_parameters):
+        """
+        receive a dict of value send by the child neuron
+        save in kalliope memory all value
+
+        E.g
+        dict_parameter_to_save = {"my_key_to_save_in_memory": "{{ output_val_from_neuron }}"}
+        neuron_parameter = {"output_val_from_neuron": "this_is_a_value" }
+
+        then the cortex will save in memory the key "my_key_to_save_in_memory" and attach the value "this_is_a_value"
+
+        :param neuron_parameters: dict of parameter the neuron has processed and send to the neurone module to
+                be processed by the TTS engine
+        :param dict_parameter_to_save: a dict of key value the user want to save from the dict_neuron_parameter
+        """
+
+        if dict_parameter_to_save is not None:
+            logger.debug("[NeuronModule] save_memory - User want to save: %s" % dict_parameter_to_save)
+            logger.debug("[NeuronModule] save_memory - Available parameters in the neuron: %s" % neuron_parameters)
+            logger.debug("[NeuronModule] save_memory - Available parameters in orders: %s"
+                         % Cortex.get_parameters_from_order())
+
+            for dict_key_val in dict_parameter_to_save:
+                for key, value in dict_key_val.items():
+                    # ask the cortex to save in memory the target "key" if it was in parameters of the neuron
+                    if isinstance(neuron_parameters, dict):
+                        if Utils.is_containing_bracket(value):
+                            value = jinja2.Template(value).render(neuron_parameters)
+                        Cortex.save(key, value)
+
+                    # ask the cortex to save in memory the target "key" if it was in the order
+                    if Utils.is_containing_bracket(value):
+                        value = jinja2.Template(value).render(Cortex.get_parameters_from_order())
+                        Cortex.save(key, value)

+ 8 - 1
kalliope/core/NeuronLauncher.py

@@ -4,6 +4,7 @@ import jinja2
 import six
 
 from kalliope.core.ConfigurationManager.SettingLoader import SettingLoader
+from kalliope.core.Cortex import Cortex
 from kalliope.core.Utils.Utils import Utils
 
 logging.basicConfig()
@@ -66,6 +67,11 @@ class NeuronLauncher:
         :param loaded_parameters: dict of parameters
         """
         logger.debug("[NeuronLauncher] replacing brackets from %s, using %s" % (neuron_parameters, loaded_parameters))
+        # add variables from the short term memory to the list of loaded parameters that can be used in a template
+        # the final dict is added into a key "kalliope_memory" to not override existing keys loaded form the order
+        memory_dict = dict()
+        memory_dict["kalliope_memory"] = Cortex.get_memory()
+        loaded_parameters.update(memory_dict)
         if isinstance(neuron_parameters, str) or isinstance(neuron_parameters, six.text_type):
             # replace bracket parameter only if the str contains brackets
             if Utils.is_containing_bracket(neuron_parameters):
@@ -84,7 +90,8 @@ class NeuronLauncher:
         if isinstance(neuron_parameters, dict):
             returned_dict = dict()
             for key, value in neuron_parameters.items():
-                if key in "say_template" or key in "file_template":  # those keys are reserved for the TTS.
+                # following keys are reserved for the TTS
+                if key in "say_template" or key in "file_template" or key in "kalliope_memory":
                     returned_dict[key] = value
                 else:
                     returned_dict[key] = cls._replace_brackets_by_loaded_parameter(value, loaded_parameters)

+ 9 - 3
kalliope/core/NeuronModule.py

@@ -2,15 +2,16 @@
 import logging
 import random
 import sys
-import six
 
+import six
 from jinja2 import Template
 
-from kalliope.core.SynapseLauncher import SynapseLauncher
 from kalliope.core import OrderListener
 from kalliope.core.ConfigurationManager import SettingLoader, BrainLoader
+from kalliope.core.Cortex import Cortex
 from kalliope.core.Models.MatchedSynapse import MatchedSynapse
 from kalliope.core.OrderAnalyser import OrderAnalyser
+from kalliope.core.SynapseLauncher import SynapseLauncher
 from kalliope.core.Utils.RpiUtils import RpiUtils
 from kalliope.core.Utils.Utils import Utils
 
@@ -104,6 +105,8 @@ class NeuronModule(object):
         self.is_waiting_for_answer = False
         # the synapse name to add the the buffer
         self.pending_synapse = None
+        # a dict of parameters the user ask to save in short term memory
+        self.kalliope_memory = kwargs.get('kalliope_memory', None)
 
     def __str__(self):
         retuned_string = ""
@@ -138,6 +141,9 @@ class NeuronModule(object):
 
         tts_message = None
 
+        # we can save parameters in memory
+        Cortex.save_memory(self.kalliope_memory, message)
+
         if isinstance(message, str) or isinstance(message, six.text_type):
             logger.debug("[NeuronModule] message is string")
             tts_message = message
@@ -186,7 +192,7 @@ class NeuronModule(object):
         .. raises:: TemplateFileNotFoundException
         """
         returned_message = None
-
+        print(message_dict)
         # the user chooses a say_template option
         if self.say_template is not None:
             returned_message = self._get_say_template(self.say_template, message_dict)

+ 3 - 0
kalliope/core/NeuronParameterLoader.py

@@ -1,3 +1,4 @@
+from kalliope.core.Cortex import Cortex
 from kalliope.core.Utils import Utils
 
 import logging
@@ -17,6 +18,8 @@ class NeuronParameterLoader(object):
         if Utils.is_containing_bracket(synapse_order):
             params = cls._associate_order_params_to_values(user_order, synapse_order)
             logger.debug("Parameters for order: %s" % params)
+            # we place the dict of parameters load from order into a cache in Cortex so the user can save it later
+            Cortex.add_parameters_from_order(params)
         return params
 
     @classmethod