SynapseLauncher.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. import logging
  2. from kalliope.core.Models.LIFOBuffer import LIFOBuffer
  3. from kalliope.core.Models.MatchedSynapse import MatchedSynapse
  4. from kalliope.core.NeuronLauncher import NeuronLauncher
  5. from kalliope.core.NeuronParameterLoader import NeuronParameterLoader
  6. from kalliope.core.OrderAnalyser import OrderAnalyser
  7. logging.basicConfig()
  8. logger = logging.getLogger("kalliope")
  9. class SynapseNameNotFound(Exception):
  10. """
  11. The Synapse has not been found
  12. .. seealso: Synapse
  13. """
  14. pass
  15. class SynapseLauncher(object):
  16. def __init__(self):
  17. pass
  18. @classmethod
  19. def start_synapse(cls, name, brain=None):
  20. """
  21. Start a synapse by it's name
  22. :param name: Name (Unique ID) of the synapse to launch
  23. :param brain: Brain instance
  24. """
  25. # check if we have found and launched the synapse
  26. synapse = brain.get_synapse_by_name(synapse_name=name)
  27. if not synapse:
  28. raise SynapseNameNotFound("The synapse name \"%s\" does not exist in the brain file" % name)
  29. else:
  30. return cls._run_synapse(synapse=synapse)
  31. @classmethod
  32. def _run_synapse(cls, synapse):
  33. """
  34. Start all neurons in the synapse
  35. :param synapse: Synapse for which we run neurons
  36. :return:
  37. """
  38. for neuron in synapse.neurons:
  39. instantiated_neuron = NeuronLauncher.start_neuron(neuron)
  40. # add the generated message to the synapse
  41. synapse.answers.append(instantiated_neuron.tts_message)
  42. return synapse
  43. @classmethod
  44. def run_matching_synapse_or_default(cls, order_to_process, brain, settings):
  45. """
  46. This method will run all synapse that match the given order "order_to_process"
  47. :param order_to_process: The text order to process in the order analyser
  48. :param brain: Brain instance
  49. :param settings: Settings instance
  50. :return: Return a list of launched synapse
  51. """
  52. no_synapse_match = False
  53. # create a list of launched synapse to return
  54. launched_synapses = list()
  55. if order_to_process is not None: # maybe we have received a null audio from STT engine
  56. launched_synapses_tuple = OrderAnalyser.get_matching_synapse(order=order_to_process, brain=brain)
  57. # oa contains the list Named tuple of synapse to run with the associated order that has matched
  58. # for each synapse, get neurons, et for each neuron, get parameters
  59. if not launched_synapses_tuple:
  60. no_synapse_match = True
  61. else:
  62. # the order match one or more synapses
  63. for tuple_el in launched_synapses_tuple:
  64. logger.debug("[SynapseLauncher] Get parameter for %s " % tuple_el.synapse.name)
  65. parameters = NeuronParameterLoader.get_parameters(synapse_order=tuple_el.order,
  66. user_order=order_to_process)
  67. # start the neuron list
  68. instantiated_neuron_list = NeuronLauncher.start_neuron_list(neuron_list=tuple_el.synapse.neurons,
  69. parameters_dict=parameters)
  70. # add generated tts messages to the returned synapse
  71. for neuron in instantiated_neuron_list:
  72. tuple_el.synapse.answers.append(neuron.tts_message)
  73. launched_synapses.append(tuple_el.synapse)
  74. else:
  75. no_synapse_match = True
  76. if no_synapse_match: # then run the default synapse
  77. if settings.default_synapse is not None:
  78. logger.debug("[SynapseLauncher] No matching Synapse-> running default synapse ")
  79. synapses = SynapseLauncher.start_synapse(name=settings.default_synapse,
  80. brain=brain)
  81. launched_synapses.append(synapses)
  82. # return the launched synapse list
  83. return launched_synapses
  84. @classmethod
  85. def run_matching_synapse_from_order(cls, order_to_process, brain, settings, is_api_call=False):
  86. """
  87. :param order_to_process: the spoken order sent by the user
  88. :param brain: Brain object
  89. :param settings: Settings object
  90. :param is_api_call: if True, the current call come from the API. This info must be known by launched Neuron
  91. :return: list of matched synapse
  92. """
  93. # get our single ton LIFO
  94. lifo_buffer = LIFOBuffer()
  95. # if the LIFO is not empty, so, the current order is passed to the current processing synapse as an answer
  96. if len(lifo_buffer.lifo_list) > 0:
  97. # the LIFO is not empty, this is an answer to a previous call
  98. return lifo_buffer.execute(answer=order_to_process)
  99. else:
  100. # the LIFO is empty, this is a new call
  101. # get a tuple of (synapse, order) that match in the brain
  102. synapses_to_launch_tuple = OrderAnalyser.get_matching_synapse(order=order_to_process, brain=brain)
  103. # we transform the tuple in a MatchedSynapse list
  104. list_synapse_to_process = list()
  105. for tuple_el in synapses_to_launch_tuple:
  106. new_matching_synapse = MatchedSynapse(matched_synapse=tuple_el.synapse,
  107. matched_order=tuple_el.order,
  108. user_order=order_to_process)
  109. list_synapse_to_process.append(new_matching_synapse)
  110. lifo_buffer.add_synapse_list_to_lifo(list_synapse_to_process)
  111. lifo_buffer.api_response.user_order = order_to_process
  112. return lifo_buffer.execute()