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_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')
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
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()
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 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_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()
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')
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()
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)
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()
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')
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')