Пример #1
0
        def _world_function():
            world_generator = utils.get_world_fn_attr(self._world_module,
                                                      overworld_name,
                                                      "generate_world")
            overworld = world_generator(self.opt, [overworld_agent])
            while not self.system_done:
                world_type = overworld.parley()
                if world_type is None:
                    time.sleep(0.5)
                    continue

                # perform onboarding
                onboard_type = onboard_map.get(world_type)
                if onboard_type:
                    onboard_id = 'onboard-{}-{}'.format(
                        overworld_agent.id, time.time())
                    agent = self.manager._create_agent(onboard_id,
                                                       overworld_agent.id)
                    agent_state.set_active_agent(agent)
                    agent_state.assign_agent_to_task(agent, onboard_id)
                    _, onboard_data = self._run_world(task, onboard_type,
                                                      [agent])
                    agent_state.onboard_data = onboard_data
                self.manager.add_agent_to_pool(agent_state, world_type)
                utils.print_and_log(logging.INFO,
                                    'onboarding/overworld complete')
                time.sleep(5)

                # sleep until agent returns from task world
                while agent_state.get_active_agent() != overworld_agent:
                    time.sleep(2)
                overworld.return_overworld()
            return world_type
Пример #2
0
 def _log_missing_agent(self, agent_id, assignment_id):
     """Log the occurence of a missing agent."""
     shared_utils.print_and_log(
         logging.WARN,
         'Expected to have an agent for {}_{}, yet none was found'.format(
             agent_id, assignment_id),
     )
Пример #3
0
        def _done_callback(fut):
            """Log and raise exception of task world, if there is one.

            Additionally, set active agent to overworld agent.
            """
            e = fut.exception()
            if e is not None:
                shared_utils.print_and_log(
                    logging.ERROR,
                    'World {} had error {}'.format(world_type, repr(e)),
                    should_print=True,
                )
                traceback.print_exc(file=sys.stdout)
                for agent in agents:
                    self.observe_message(
                        agent.id,
                        'Sorry, this world closed. Returning to overworld.')
            else:
                shared_utils.print_and_log(
                    logging.INFO,
                    'World {} had no error'.format(world_type),
                    should_print=True,
                )
            self.active_worlds[task_id] = None
            for agent in agents:
                agent_state = self.get_agent_state(agent.id)
                agent_state.set_active_agent(agent_state.get_overworld_agent())
Пример #4
0
    def shutdown(self):
        """Handle any client shutdown cleanup."""
        try:
            self.is_running = False
            self.world_runner.shutdown()
            if not self.bypass_server_setup:
                self.message_socket.keep_running = False
            self._expire_all_conversations()
        except BaseException as e:
            shared_utils.print_and_log(logging.ERROR, f'world ended in error: {e}')

        finally:
            if not self.bypass_server_setup:
                server_utils.delete_server(self.server_task_name, self.opt['local'])
Пример #5
0
    def setup_server(self):
        """
        Prepare the Messenger server for handling messages.
        """
        if self.bypass_server_setup:
            return

        shared_utils.print_and_log(
            logging.INFO,
            '\nYou are going to allow people on Facebook to be agents in '
            'ParlAI.\nDuring this process, Internet connection is required, '
            'and you should turn off your computer\'s auto-sleep '
            'feature.\n',
            should_print=True,
        )
        input('Please press Enter to continue... ')
        shared_utils.print_and_log(logging.NOTSET, '', True)

        if self.opt['local'] is True:
            shared_utils.print_and_log(
                logging.INFO,
                'In order to run the server locally, you will need '
                'to have a public HTTPS endpoint (SSL signed) running on '
                'the server you are currently excecuting ParlAI on. Enter '
                'that public URL hostname when prompted and ensure that the '
                'port being used by ParlAI (usually 3000) has external '
                'traffic routed to it.',
                should_print=True,
            )
            input('Please press Enter to continue... ')

        shared_utils.print_and_log(logging.INFO,
                                   'Setting up Messenger webhook...',
                                   should_print=True)

        # Setup the server with a task name related to the current task
        task_name = '{}-{}'.format('ParlAI-Messenger', self.opt['task'])
        self.server_task_name = ''.join(e for e in task_name.lower()
                                        if e.isalnum() or e == '-')
        self.server_url = server_utils.setup_server(self.server_task_name,
                                                    local=self.opt['local'])
        shared_utils.print_and_log(
            logging.INFO,
            'Webhook address: {}/webhook'.format(self.server_url),
            should_print=True,
        )
Пример #6
0
    def setup_socket(self):
        """Set up socket to start communicating to workers."""
        if not self.bypass_server_setup:
            shared_utils.print_and_log(logging.INFO,
                                       'Local: Setting up WebSocket...',
                                       should_print=True)

        self.app_token = self.get_app_token()
        self.message_sender = MessageSender(self.app_token)

        # Set up receive
        if not self.bypass_server_setup:
            socket_use_url = self.server_url
            self.message_socket = MessageSocket(socket_use_url, self.port,
                                                self._handle_webhook_event)
        shared_utils.print_and_log(logging.INFO,
                                   'done with websocket',
                                   should_print=True)
Пример #7
0
 def _done_callback(fut):
     e = fut.exception()
     if e is not None:
         shared_utils.print_and_log(
             logging.ERROR,
             'World {} had error {}'.format(task_id, repr(e)),
             should_print=True,
         )
         if self.debug:
             raise e
     else:
         self.observe_message(agent_id, 'See you later!')
         for world_type in self.agent_pool:
             agent_state = self.get_agent_state(agent_id)
             if agent_state in self.agent_pool[world_type]:
                 self.agent_pool[world_type].remove(agent_state)
                 self.remove_agent_from_pool(agent_state,
                                             world_type=world_type)
         del self.messenger_agent_states[agent_id]
         del self.agent_id_to_overworld_future[agent_id]
Пример #8
0
    def setup_socket(self):
        """
        Set up socket to start communicating to workers.
        """
        if not self.bypass_server_setup:
            shared_utils.print_and_log(logging.INFO,
                                       'Local: Setting up WebSocket...',
                                       should_print=True)

        self.app_token = self.get_app_token()
        self.sender = MessageSender(self.app_token)

        # Set up receive
        if not self.bypass_server_setup:
            socket_use_url = self.server_url
            if self.opt['local']:  # skip some hops for local stuff
                socket_use_url = 'https://localhost'
            self.socket = ChatServiceMessageSocket(socket_use_url, self.port,
                                                   self._handle_webhook_event)
        shared_utils.print_and_log(logging.INFO,
                                   'done with websocket',
                                   should_print=True)
Пример #9
0
 def _world_fn():
     utils.print_and_log(logging.INFO,
                         'Starting task {}...'.format(task_name))
     return self._run_world(task, world_name, agents)
Пример #10
0
 def _log(self, text):
     if self.debug:
         time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
         utils.print_and_log(logging.INFO,
                             "{} DEBUG: {}".format(time, text))
Пример #11
0
    def _manager_loop_fn(self):
        """An iteration of the manager's main loop to launch worlds.
        """
        def _done_callback(fut):
            """Log and raise exception of task world, if there is one.

            Additionally, set active agent to overworld agent.
            """
            e = fut.exception()
            if e is not None:
                shared_utils.print_and_log(
                    logging.ERROR,
                    'World {} had error {}'.format(world_type, repr(e)),
                    should_print=True,
                )
                traceback.print_exc(file=sys.stdout)
                for agent in agents:
                    self.observe_message(
                        agent.id,
                        'Sorry, this world closed. Returning to overworld.')
            else:
                shared_utils.print_and_log(
                    logging.INFO,
                    'World {} had no error'.format(world_type),
                    should_print=True,
                )
            self.active_worlds[task_id] = None
            for agent in agents:
                agent_state = self.get_agent_state(agent.id)
                agent_state.set_active_agent(agent_state.get_overworld_agent())

        with self.agent_pool_change_condition:
            valid_pools = self._get_unique_pool()
            for world_type, agent_pool in valid_pools.items():
                # check if agent has exceeded max time in pool
                world_config = self.task_configs[world_type]
                if world_config.max_time_in_pool is not None:
                    self.check_timeout_in_pool(world_type, agent_pool,
                                               world_config.max_time_in_pool)

                needed_agents = self.max_agents_for[world_type]
                if len(agent_pool) >= needed_agents:
                    shared_utils.print_and_log(logging.INFO,
                                               'starting pool',
                                               should_print=True)
                    # enough agents in pool to start new conversation
                    self.conversation_index += 1
                    task_id = 't_{}'.format(self.conversation_index)

                    # Add the required number of valid agents to the conv
                    agent_states = [w for w in agent_pool[:needed_agents]]
                    agents = []
                    for state in agent_states:
                        agent = self._create_agent(task_id, state.get_id())
                        agent.onboard_data = state.onboard_data
                        state.assign_agent_to_task(agent, task_id)
                        state.set_active_agent(agent)
                        agents.append(agent)
                        # reset wait message state
                        state.stored_data['seen_wait_message'] = False
                    assign_role_function = shared_utils.get_assign_roles_fn(
                        self.world_module, self.taskworld_map[world_type])
                    if assign_role_function is None:
                        assign_role_function = shared_utils.default_assign_roles_fn
                    assign_role_function(agents)
                    # Allow task creator to filter out workers and run
                    # versions of the task that require fewer agents
                    for a in agents:
                        # Remove selected workers from the agent pool
                        self.remove_agent_from_pool(
                            self.get_agent_state(a.id),
                            world_type=world_type,
                            mark_removed=False,
                        )
                    for a in agents:
                        partner_list = agents.copy()
                        partner_list.remove(a)
                        a.message_partners = partner_list
                    # launch task world.
                    future = self.world_runner.launch_task_world(
                        task_id, self.taskworld_map[world_type], agents)
                    future.add_done_callback(_done_callback)
                    self.active_worlds[task_id] = future
Пример #12
0
 def _log_debug(self, text):
     time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
     shared_utils.print_and_log(logging.DEBUG, f'{time}: {text}', should_print=True)