class_docstr: (In preview) A group chat class that contains the following data fields:
  - agents: a list of participating agents.
  - messages: a list of messages in the group chat.
  - max_round: the maximum number of rounds.
  - admin_name: the name of the admin agent if there is one. Default is "Admin".
      KeyBoardInterrupt will make the admin agent take over.
  - func_call_filter: whether to enforce function call filter. Default is True.
      When set to True and when a message is a function call suggestion,
      the next speaker will be chosen from an agent which contains the corresponding function name
      in its `function_map`.
  - speaker_selection_method: the method for selecting the next speaker. Default is "auto".
      Could be any of the following (case insensitive), will raise ValueError if not recognized:
      - "auto": the next speaker is selected automatically by LLM.
      - "manual": the next speaker is selected manually by user input.
      - "random": the next speaker is selected randomly.
      - "round_robin": the next speaker is selected in a round robin fashion, i.e., iterating in the same order as provided in `agents`.
  - allow_repeat_speaker: whether to allow the same speaker to speak consecutively. Default is True, in which case all speakers are allowed to speak consecutively. If allow_repeat_speaker is a list of Agents, then only those listed agents are allowed to repeat. If set to False, then no speakers are allowed to repeat.
class_docstr_tok: ["(","In","preview",")","A","group","chat","class","that","contains","the","following","data","fields",":","-","agents",":","a","list","of","participating","agents",".","-","messages",":","a","list","of","messages","in","the","group","chat",".","-","max_round",":","the","maximum","number","of","rounds",".","-","admin_name",":","the","name","of","the","admin","agent","if","there","is","one",".","Default","is","``","Admin","''",".","KeyBoardInterrupt","will","make","the","admin","agent","take","over",".","-","func_call_filter",":","whether","to","enforce","function","call","filter",".","Default","is","True",".","When","set","to","True","and","when","a","message","is","a","function","call","suggestion",",","the","next","speaker","will","be","chosen","from","an","agent","which","contains","the","corresponding","function","name","in","its","`","function_map","`",".","-","speaker_selection_method",":","the","method","for","selecting","the","next","speaker",".","Default","is","``","auto","''",".","Could","be","any","of","the","following","(","case","insensitive",")",",","will","raise","ValueError","if","not","recognized",":","-","``","auto","''",":","the","next","speaker","is","selected","automatically","by","LLM",".","-","``","manual","''",":","the","next","speaker","is","selected","manually","by","user","input",".","-","``","random","''",":","the","next","speaker","is","selected","randomly",".","-","``","round_robin","''",":","the","next","speaker","is","selected","in","a","round","robin","fashion",",","i.e.",",","iterating","in","the","same","order","as","provided","in","`","agents","`",".","-","allow_repeat_speaker",":","whether","to","allow","the","same","speaker","to","speak","consecutively",".","Default","is","True",",","in","which","case","all","speakers","are","allowed","to","speak","consecutively",".","If","allow_repeat_speaker","is","a","list","of","Agents",",","then","only","those","listed","agents","are","allowed","to","repeat",".","If","set","to","False",",","then","no","speakers","are","allowed","to","repeat","."]
docstr: Manually select the next speaker.
docstr_tok: ["Manually","select","the","next","speaker","."]
code: def manual_select_speaker(
      self, agents: Optional[List[Agent]] = None
  ) -> Union[Agent, None]:
      """Manually select the next speaker."""
      if agents is None:
          agents = self.agents
  
      print("Please select the next speaker from the following list:")
      _n_agents = len(agents)
      for i in range(_n_agents):
          print(f"{i+1}: {agents[i].name}")
      try_count = 0
      # Assume the user will enter a valid number within 3 tries, otherwise use auto selection to avoid blocking.
      while try_count <= 3:
          try_count += 1
          if try_count >= 3:
              print(
                  f"You have tried {try_count} times. The next speaker will be selected automatically."
              )
              break
          try:
              i = input(
                  "Enter the number of the next speaker (enter nothing or `q` to use auto selection): "
              )
              if i == "" or i == "q":
                  break
              i = int(i)
              if i > 0 and i <= _n_agents:
                  return agents[i - 1]
              else:
                  raise ValueError
          except ValueError:
              print(
                  f"Invalid input. Please enter a number between 1 and {_n_agents}."
              )
      return None
  
imports: import logging
  import random
  import re
  import sys
  from dataclasses import dataclass
  from typing import Dict, List, Optional, Union, Tuple
  from ..code_utils import content_str
  from .agent import Agent
  from .conversable_agent import ConversableAgent
label_desc: Use image node_id 8 for calling the GroupChat obj's underlying member method code with example usage: obj.manual_select_speaker(agents) and returns: None, agents