docs: def get_agents(self, addr=True, agent_cls=None, as_coro=False):
          """Get agents from the slave environments.
  
          :param bool addr:
              If ``True``, returns only addresses of the agents, otherwise
              returns a :class:`Proxy` object for each agent.
  
          :param agent_cls:
              If specified, returns only agents that are members of that
              particular class.
  
          :param bool as_coro:
              If ``True``, returns a coroutine, otherwise runs the method in
              an event loop.
  
          :returns:
              A coroutine or list of :class:`Proxy` objects or addresses as
              specified by the input parameters.
  
          Slave environment managers are excluded from the returned list by
          default. Essentially, this method calls each slave environment
          manager's :meth:`creamas.mp.EnvManager.get_agents` asynchronously.
  
          .. note::
  
              Calling each slave environment's manager might be costly in some
              situations. Therefore, it is advisable to store the returned agent
              list if the agent sets in the slave environments are not bound to
              change.
          """
          async def slave_task(mgr_addr, addr=True, agent_cls=None):
              r_manager = await self.env.connect(mgr_addr, timeout=TIMEOUT)
              return await r_manager.get_agents(addr=addr, agent_cls=agent_cls)
  
          tasks = create_tasks(slave_task, self.addrs, addr, agent_cls)
          return run_or_coro(tasks, as_coro)