Example #1
0
  def test_it_should_have_a_unique_id(self):
    agt1 = Agent(self.interpreter)
    agt2 = Agent(self.interpreter)

    expect(agt1.id).to_not.be.none
    expect(agt1.id).to.be.a(str)
    expect(agt2.id).to_not.be.none
    expect(agt2.id).to.be.a(str)

    expect(agt1.id).to_not.equal(agt2.id)
Example #2
0
    def test_it_should_handle_a_parse_request(self):
        agt = Agent(Interpreter('test', 'fr'))
        agt.parse = MagicMock()
        f = Factory('test')
        f.create = MagicMock(return_value=agt)
        c = Channel('test')
        s = Server(f)
        s.on_parse(c, Parse('pod', 'john', 'hi there', a_meta='value'))

        agt.parse.assert_called_once_with('hi there', a_meta='value')
Example #3
0
def get_agent_for_user(user):
    agent = agents_by_user.get(user.id)

    if not agent:
        logging.info('Agent does not exist for "%s", creating it' % user.id)

        interpreter = SnipsInterpreter(user.profile.language[:2],
                                       CONFIG.getpath(CACHE_DIR))
        interpreter.fit_from_skill_data()

        agent = Agent(interpreter, uid=user.id)

        agents_by_user[user.id] = agent
    else:
        logging.info('Agent found matching this user!')

    user_settings = user.setting_set.all()
    user_settings_dict = {
        setting.name: setting.value
        for setting in user_settings
    }

    # Update agent meta with user settings
    agent.meta.update(user_settings_dict)

    return agent
Example #4
0
def instantiate_agent_prompt(sentence=None):  # pragma: no cover
    interpreter = instantiate_and_fit_interpreter()

    Prompt(Agent(interpreter,
                 transitions_graph_path=settings.getpath(
                     settings.SETTING_GRAPH_FILE),
                 **os.environ),
           parse_message=sentence).cmdloop()
Example #5
0
  def test_it_should_trigger_agent_created_hook_upon_creation(self):
    self.on_agent_created = MagicMock()
    self.on_agent_created.__name__ = 'on_agent_created'

    register(ON_AGENT_CREATED, self.on_agent_created)

    agt = Agent(self.interpreter, handlers=self.handlers)

    self.on_agent_created.assert_called_once_with(agt)
Example #6
0
  def setup(self):
    self.on_answer = MagicMock()
    self.on_ask = MagicMock()
    self.on_done = MagicMock()
    self.on_thinking = MagicMock()

    self.handlers = {
      'greet': on_greet,
      'get_forecast': on_get_forecast,
      'lights_on': on_lights_on,
      'block': on_block,
      'with_meta': on_with_meta,
      STATE_CANCEL: on_cancel,
      STATE_FALLBACK: on_fallback,
    }

    self.interpreter = Interpreter('test', 'en')
    self.interpreter.intents = list(self.handlers.keys()) + ['intent_without_handler']
    self.agent = Agent(self.interpreter, model=self, handlers=self.handlers)
Example #7
0
    def test_it_should_create_an_agent_if_needed(self):
        f = Factory('test')
        f.create = MagicMock(return_value=Agent(Interpreter('test', 'fr')))
        c = Channel('test')

        s = Server(f)
        s.on_ping(c, Ping('pod', 'john'))

        f.create.assert_called_once_with('john')

        s.on_ping(c, Ping('pod', 'john'))
        f.create.assert_called_once()
Example #8
0
    def test_it_should_handle_a_ping_request_and_answer_with_a_pong(self):
        f = Factory('test')
        f.create = MagicMock(return_value=Agent(Interpreter('test', 'fr')))
        c = Channel('test')
        c.send = MagicMock()

        s = Server(f)
        s.on_ping(c, Ping('pod', 'john'))

        c.send.assert_called_once()
        mes = c.send.call_args[0][0]
        expect(mes).to.be.a(Pong)
        expect(mes.device_identifier).to.equal('pod')
        expect(mes.user_identifier).to.equal('john')
        expect(mes.language).to.equal('fr')
Example #9
0
    def test_it_should_answer_on_the_last_used_channel(self):
        f = Factory('test')
        f.create = MagicMock(return_value=Agent(Interpreter('test', 'fr')))

        c1 = Channel('test1')
        c1.send = MagicMock()
        c2 = Channel('test2')
        c2.send = MagicMock()

        s = Server(f)
        s.on_parse(c1, Parse('pod', 'john', 'hello there'))

        c1.send.assert_called_once()
        c2.send.assert_not_called()

        c1.send.reset_mock()

        s.on_parse(c2, Parse('pod', 'john', "What's up?"))
        c1.send.assert_not_called()
        c2.send.assert_called_once()
Example #10
0
    def create(self, uid: str) -> Agent:
        cache_dir, conf_path = get_config_directories_path(
            self._directory, uid)
        meta = {}

        if os.path.isfile(conf_path):
            store = SettingsStore()
            store.load_from_file(conf_path)
            meta = store.to_dict()
            self._logger.info('Using settings from "%s"', conf_path)
        else:
            cache_dir = self._default_cache_dir
            self._logger.warning(
                'Could not find a pytlas.ini file in "%s", using the default one',
                conf_path)

        interpreter = SnipsInterpreter(meta.get(
            to_env_key(DEFAULT_SECTION, LANGUAGE_KEY), DEFAULT_LANGUAGE),
                                       cache_directory=cache_dir)
        interpreter.fit_from_skill_data()
        return Agent(interpreter, **meta)
Example #11
0
def instantiate_agent_prompt(sentence=None):  # pragma: no cover
    interpreter = instantiate_and_fit_interpreter()

    Prompt(Agent(interpreter,
                 transitions_graph_path=CONFIG.getpath(GRAPH_FILE)),
           parse_message=sentence).cmdloop()
Example #12
0
if __name__ == '__main__':

    # The last piece is the `Interpreter`. This is the part responsible for human
    # language parsing. It parses raw human sentences into something more useful for
    # the program.

    interpreter = SnipsInterpreter('en',
                                   cache_directory=os.path.join(
                                       os.path.dirname(__file__), 'cache'))

    # Train the interpreter using training data register with the `training` decorator
    # or `pytlas.training.register` function.

    interpreter.fit_from_skill_data()

    # The `Agent` uses the model given to call appropriate lifecycle hooks.

    agent = Agent(interpreter, model=Client())

    # With this next line, this is what happenned:
    #
    # - The message is parsed by the `SnipsInterpreter`
    # - A 'lights_on' intents is retrieved and contains 'kitchen' and 'bedroom' as the 'room' slot values
    # - Since the `Agent` is asleep, it will transition to the 'lights_on' state immediately
    # - Transitioning to this state call the appropriate handler (at the beginning of this file)
    # - 'Turning lights on in kitchen, bedroom' is printed to the terminal by the `Client.on_answer` defined above
    # - `done` is called by the skill so the agent transitions back to the 'asleep' state

    agent.parse('turn the lights on in kitchen and bedroom please')
Example #13
0
class TestAgent:
  """For those tests, the interpreter.parse is always mocked because there is no interpreter
  such as snips. It only tests transitions and state management.
  """

  def setup(self):
    self.on_answer = MagicMock()
    self.on_ask = MagicMock()
    self.on_done = MagicMock()
    self.on_thinking = MagicMock()

    self.handlers = {
      'greet': on_greet,
      'get_forecast': on_get_forecast,
      'lights_on': on_lights_on,
      'block': on_block,
      'with_meta': on_with_meta,
      STATE_CANCEL: on_cancel,
      STATE_FALLBACK: on_fallback,
    }

    self.interpreter = Interpreter('test', 'en')
    self.interpreter.intents = list(self.handlers.keys()) + ['intent_without_handler']
    self.agent = Agent(self.interpreter, model=self, handlers=self.handlers)

  def test_it_should_have_a_unique_id(self):
    agt1 = Agent(self.interpreter)
    agt2 = Agent(self.interpreter)

    expect(agt1.id).to_not.be.none
    expect(agt1.id).to.be.a(str)
    expect(agt2.id).to_not.be.none
    expect(agt2.id).to.be.a(str)

    expect(agt1.id).to_not.equal(agt2.id)

  def test_it_should_trigger_agent_created_hook_upon_creation(self):
    self.on_agent_created = MagicMock()
    self.on_agent_created.__name__ = 'on_agent_created'

    register(ON_AGENT_CREATED, self.on_agent_created)

    agt = Agent(self.interpreter, handlers=self.handlers)

    self.on_agent_created.assert_called_once_with(agt)

  def test_it_should_queue_string_as_intent(self):
    self.agent.queue_intent('greet')

    expect(last_request.intent.name).to.equal('greet')
    self.on_answer.assert_called_once_with('Hello you!', None, raw_text='Hello you!')
    self.on_done.assert_called_once_with(True)
    expect(self.agent.state).to.equal(STATE_ASLEEP)

  def test_it_should_queue_string_and_kwargs_as_intent_with_slot_values(self):
    self.agent.queue_intent('greet', name='Julien')

    self.on_answer.assert_called_once()
    self.on_done.assert_called_once_with(True)
    
    expect(last_request.intent.name).to.equal('greet')
    expect(last_request.intent.slots).to.have.length_of(1)
    expect(last_request.intent.slot('name').first().value).to.equal('Julien')
    expect(self.agent.state).to.equal(STATE_ASLEEP)

  def test_it_should_trigger_intent(self):
    self.agent.queue_intent(Intent('greet'))

    expect(last_request.intent.name).to.equal('greet')
    self.on_answer.assert_called_once_with('Hello you!', None, raw_text='Hello you!')
    self.on_done.assert_called_once_with(True)
    self.on_thinking.assert_called_once()
    expect(self.agent.state).to.equal(STATE_ASLEEP)

  def test_it_should_handle_simple_intent(self):
    self.interpreter.parse = MagicMock(return_value=[Intent('greet')])

    self.agent.parse('hello')

    self.on_answer.assert_called_once_with('Hello you!', None, raw_text='Hello you!')
    self.on_done.assert_called_once_with(True)
    expect(self.agent.state).to.equal(STATE_ASLEEP)

  def test_it_should_have_cards(self):
    self.interpreter.parse = MagicMock(return_value=[Intent('get_forecast', date='tomorrow', city='rouen')])

    self.agent.parse('will it rain in rouen tomorrow')

    self.on_answer.assert_called_once()

    call_args = self.on_answer.call_args[0]
    expect(call_args).to.have.length_of(2)
    expect(call_args[0]).to.equal('Looking in rouen for tomorrow')
    expect(call_args[1]).to.be.a(list)
    expect(call_args[1]).to.have.length_of(1)
    expect(call_args[1][0].header).to.equal('rouen')
    expect(call_args[1][0].text).to.equal('tomorrow')

  def test_it_should_handle_multiple_intents(self):
    self.interpreter.parse = MagicMock(return_value=[
      Intent('greet'), 
      Intent('block'), 
      Intent('lights_on', room='kitchen'),
    ])

    self.agent.parse('hello, can you turn the lights on in kitchen')

    self.on_answer.assert_called_once_with('Hello you!', None, raw_text='Hello you!')
    self.on_done.assert_called_once_with(True)
    expect(self.on_thinking.call_count).to.equal(2) # One for greet, the other for block

    greet_id = last_request.id

    expect(self.agent.state).to.equal('block')

    # Since the block intent does not call it to test it more easily, call the agent.done now to process the next intent
    self.agent.done()

    self.on_answer.assert_called_with('Turning lights on in kitchen', None, raw_text='Turning lights on in kitchen')

    expect(self.on_done.call_count).to.equal(3)
    expect(self.on_thinking.call_count).to.equal(3)
    expect(last_request.id).to_not.equal(greet_id)
    expect(self.agent.state).to.equal(STATE_ASLEEP)

  def test_it_should_add_parse_meta_to_intent_meta(self):
    greet_intent = Intent('greet')
    lights_intent = Intent('lights_on', room='kitchen')

    self.interpreter.parse = MagicMock(return_value=[
      greet_intent,
      lights_intent,
    ])

    self.agent.parse('hello, can you turn the lights on in kitchen', latitude=49.44, longitude=1.09)

    expect(greet_intent.meta).to.equal({ 'latitude': 49.44, 'longitude': 1.09 })
    expect(lights_intent.meta).to.equal({ 'latitude': 49.44, 'longitude': 1.09 })
    expect(last_request.intent.meta).to.equal({ 'latitude': 49.44, 'longitude': 1.09 })
  
  def test_it_should_do_nothing_and_returns_to_the_asleep_state_when_no_handler_was_found(self):
    self.interpreter.parse = MagicMock(return_value=[Intent('intent_without_handler')])

    self.agent.parse('an intent without a handler')

    self.on_done.assert_called_once_with(False)
    expect(self.agent.state).to.equal(STATE_ASLEEP)

  def test_it_should_be_in_the_ask_state_when_a_skill_ask_for_slot(self):
    self.interpreter.parse = MagicMock(return_value=[Intent('get_forecast')])

    self.agent.parse('will it be sunny')

    initial_request_id = last_request.id

    self.on_ask.assert_called_once_with('date', 'When?', None, raw_text='When?')
    self.on_done.assert_called_once_with(True)
    self.on_answer.assert_not_called()
    expect(self.agent.state).to.equal(STATE_ASK)

    self.agent.parse('tomorrow')

    expect(last_request.intent.slot('date').first().value).to.equal('tomorrow')
    self.on_ask.assert_any_call('city', 'Where?', None, raw_text='Where?')
    expect(self.on_done.call_count).to.equal(2)
    self.on_answer.assert_not_called()
    expect(self.agent.state).to.equal(STATE_ASK)

    self.agent.parse('rouen')

    expect(last_request.intent.slot('city').first().value).to.equal('rouen')
    self.on_answer.assert_called_once()
    expect(self.on_answer.call_args[0][0]).to.equal('Looking in rouen for tomorrow')
    expect(self.agent.state).to.equal(STATE_ASLEEP)
    expect(self.on_done.call_count).to.equal(3)
    expect(last_request.id).to.equal(initial_request_id)

  def test_it_should_match_on_choices_when_asking_with_choices(self):
    self.interpreter.parse = MagicMock(return_value=[Intent('lights_on')])

    self.agent.parse('turn the lights on')

    self.on_ask.assert_called_once_with('room', 'Which ones?', ['kitchen', 'living room', 'bedroom'], raw_text='Which ones?')
    expect(self.agent.state).to.equal(STATE_ASK)

    self.agent.parse('in the living room')

    self.on_answer.assert_called_with('Turning lights on in living room', None, raw_text='Turning lights on in living room')
    expect(self.on_done.call_count).to.equal(2)

  def test_it_should_cancel_intent_when_cancel_is_caught(self):
    self.interpreter.parse = MagicMock(return_value=[Intent('lights_on')])

    self.agent.parse('turn the lights on')

    expect(self.agent.state).to.equal(STATE_ASK)

    self.interpreter.parse = MagicMock(return_value=[Intent(STATE_CANCEL)])

    self.agent.parse('cancel')

    self.on_answer.assert_called_once_with('Cancelled', None, raw_text='Cancelled')
    expect(self.agent.state).to.equal(STATE_ASLEEP)

  def test_it_should_pass_ask_meta_to_the_handler(self):
    self.interpreter.parse = MagicMock(return_value=[Intent('with_meta')])

    self.agent.parse('trigger with_meta handler')

    self.on_ask.assert_called_once_with('name', 'Whom?', None, raw_text='Whom?', special_meta='something')

  def test_it_should_pass_answer_meta_to_the_handler(self):
    self.interpreter.parse = MagicMock(return_value=[Intent('with_meta', name='Julien')])

    self.agent.parse('trigger with_meta handler')

    self.on_answer.assert_called_once_with('Hello **Julien**', None, raw_text='Hello Julien', trigger_listening=True)

  def test_it_should_call_the_fallback_intent_when_no_matching_intent_could_be_found(self):
    self.agent.parse('should go in fallback')

    self.on_answer.assert_called_once_with('Searching for should go in fallback', None, raw_text='Searching for should go in fallback')
    self.on_done.assert_called_once_with(False)
    expect(self.agent.state).to.equal(STATE_ASLEEP)
    expect(last_request.intent.name).to.equal(STATE_FALLBACK)
    expect(last_request.intent.slots).to.have.length_of(1)
    expect(last_request.intent.slot('text').first().value).to.equal('should go in fallback')

  def test_it_should_handle_interpreter_changes_with_build(self):
    expect(self.agent._machine.states).to_not.contain('something_else')

    self.interpreter.intents.append('something_else')

    self.agent.build()

    expect(self.agent._machine.states).to.contain('something_else')