text: from {name}        """        for agent in self.agents:            agent.receive(name, message)        # increment time        self._step += 1    def step(self) -> tuple[str, str]:        # 1. choose the next speaker        speaker_idx = self.select_next_speaker(self._step, self.agents)        speaker = self.agents[speaker_idx]        # 2. next speaker sends message        message = speaker.send()        # 3. everyone receives message        for receiver in self.agents:            receiver.receive(speaker.name, message)        # 4. increment time        self._step += 1        return speaker.name, messageDirectorDialogueAgent classâ€‹The DirectorDialogueAgent is a privileged agent that chooses which of the other agents to speak next. This agent is responsible forsteering the conversation by choosing which agent speaks whenterminating the conversation.In order to implement such an agent, we need to solve several problems.First, to steer the conversation, the DirectorDialogueAgent needs to (1) reflect on what has been said, (2) choose the next agent, and (3) prompt the next agent to speak, all in a single message. While it may be possible to prompt an LLM to perform all three steps in the same call, this requires writing custom code to parse the outputted message to extract which next agent is chosen to speak. This is less reliable the