code: import json
  from typing import Dict, List
  
  import llama_index.query_engine
  from llama_index import ServiceContext, QueryBundle
  from llama_index.callbacks import CBEventType, LlamaDebugHandler, CallbackManager
  from llama_index.indices.base import BaseIndex
  from llama_index.indices.query.base import BaseQueryEngine
  from llama_index.llms.base import LLM
  from llama_index.prompts.mixin import PromptMixinType
  from llama_index.response.schema import RESPONSE_TYPE, Response
  from llama_index.selectors import LLMSingleSelector
  from llama_index.tools import QueryEngineTool
  
  from common.config import DEBUG, LLM_CACHE_ENABLED
  from common.llm import llm_predict, create_llm
  from common.prompt import CH_SINGLE_SELECT_PROMPT_TMPL
  from common.utils import ObjectEncoder
  from query_todo.query_engine import load_indices
  from query_todo.compose import create_compose_query_engine
  
  
  class EchoNameEngine(BaseQueryEngine):
      def __init__(self, name: str, callback_manager: CallbackManager = None):
          self.name = name
          super().__init__(callback_manager)
  
      async def _aquery(self, query_bundle: QueryBundle) -> RESPONSE_TYPE:
          pass
  
      def _get_prompt_modules(self) -> PromptMixinType:
          return {}
  
      def _query(self, query_bundle: QueryBundle) -> RESPONSE_TYPE:
          return Response(f"我是{self.name}")
  
  
  class LlmQueryEngine(BaseQueryEngine):
  
      def __init__(self, llm: LLM, callback_manager: CallbackManager):
          self.llm = llm
          super().__init__(callback_manager=callback_manager)
  
      def _get_prompt_modules(self) -> PromptMixinType:
          return {}
  
      def _query(self, query_bundle: QueryBundle) -> RESPONSE_TYPE:
          return Response(llm_predict(self.llm, query_bundle.query_str))
  
      async def _aquery(self, query_bundle: QueryBundle) -> RESPONSE_TYPE:
          pass
  
  
  def create_route_query_engine(query_engines: List[BaseQueryEngine], descriptions: List[str],
                                service_context: ServiceContext = None):
      assert len(query_engines) == len(descriptions)
      # TODO
      # 根据传入的多个query_engines和descriptions创建 RouteQueryEngine，实现query engine 的路由
      # https://docs.llamaindex.ai/en/stable/module_guides/querying/router/root.html#using-as-a-query-engine
      raise NotImplementedError
  
  
  class Chatter:
  
      def __init__(self):
          if DEBUG:
              debug_handler = LlamaDebugHandler()
              cb_manager = CallbackManager([debug_handler])
          else:
              debug_handler = None
              cb_manager = CallbackManager()
          llm = create_llm(cb_manager, LLM_CACHE_ENABLED)
          service_context = ServiceContext.from_defaults(
              llm=llm,
              callback_manager=cb_manager
          )
          self.cb_manager = cb_manager
          self.city_indices: Dict[str, List[BaseIndex]] = load_indices(service_context)
          self.service_context = service_context
          self.llm = llm
          self.debug_handler = debug_handler
          self.query_engine = self.create_query_engine()
  
      def create_query_engine(self):
          index_query_engine = create_compose_query_engine(self.city_indices, self.service_context)
          index_summary = f"提供 {', '.join(self.city_indices.keys())} 这几个城市的相关信息"
          llm_query_engine = LlmQueryEngine(llm=self.llm, callback_manager=self.cb_manager)
          llm_summary = f"提供其他所有信息"
          # 实现意图识别，把不同的query路由到不同的query_engine上，实现聊天和城市信息查询两个功能的分流
          # https://docs.llamaindex.ai/en/stable/module_guides/querying/router/root.html#using-as-a-query-engine
          raise NotImplementedError
  
      def _print_and_flush_debug_info(self):
          if self.debug_handler:
              for event in self.debug_handler.get_events():
                  if event.event_type in (CBEventType.LLM, CBEventType.RETRIEVE):
                      print(
                          f"[DebugInfo] event_type={event.event_type}, content={json.dumps(event.payload, ensure_ascii=False, cls=ObjectEncoder)}")
              self.debug_handler.flush_event_logs()
  
      def chat(self, query):
          response = self.query_engine.query(query)
          self._print_and_flush_debug_info()
          return response
  
apis: llama_index.callbacks.LlamaDebugHandler llama_index.response.schema.Response llama_index.ServiceContext.from_defaults llama_index.callbacks.CallbackManager
extract_api: [((1298, 1324), 'llama_index.response.schema.Response', 'Response', (['f"""我是{self.name}"""'], {}), "(f'我是{self.name}')\n", (1306, 1324), False, 'from llama_index.response.schema import RESPONSE_TYPE, Response\n'), ((2530, 2571), 'common.llm.create_llm', 'create_llm', (['cb_manager', 'LLM_CACHE_ENABLED'], {}), '(cb_manager, LLM_CACHE_ENABLED)\n', (2540, 2571), False, 'from common.llm import llm_predict, create_llm\n'), ((2598, 2664), 'llama_index.ServiceContext.from_defaults', 'ServiceContext.from_defaults', ([], {'llm': 'llm', 'callback_manager': 'cb_manager'}), '(llm=llm, callback_manager=cb_manager)\n', (2626, 2664), False, 'from llama_index import ServiceContext, QueryBundle\n'), ((2792, 2821), 'query_todo.query_engine.load_indices', 'load_indices', (['service_context'], {}), '(service_context)\n', (2804, 2821), False, 'from query_todo.query_engine import load_indices\n'), ((3055, 3123), 'query_todo.compose.create_compose_query_engine', 'create_compose_query_engine', (['self.city_indices', 'self.service_context'], {}), '(self.city_indices, self.service_context)\n', (3082, 3123), False, 'from query_todo.compose import create_compose_query_engine\n'), ((1683, 1728), 'common.llm.llm_predict', 'llm_predict', (['self.llm', 'query_bundle.query_str'], {}), '(self.llm, query_bundle.query_str)\n', (1694, 1728), False, 'from common.llm import llm_predict, create_llm\n'), ((2348, 2367), 'llama_index.callbacks.LlamaDebugHandler', 'LlamaDebugHandler', ([], {}), '()\n', (2365, 2367), False, 'from llama_index.callbacks import CBEventType, LlamaDebugHandler, CallbackManager\n'), ((2393, 2425), 'llama_index.callbacks.CallbackManager', 'CallbackManager', (['[debug_handler]'], {}), '([debug_handler])\n', (2408, 2425), False, 'from llama_index.callbacks import CBEventType, LlamaDebugHandler, CallbackManager\n'), ((2498, 2515), 'llama_index.callbacks.CallbackManager', 'CallbackManager', ([], {}), '()\n', (2513, 2515), False, 'from llama_index.callbacks import CBEventType, LlamaDebugHandler, CallbackManager\n'), ((3855, 3919), 'json.dumps', 'json.dumps', (['event.payload'], {'ensure_ascii': '(False)', 'cls': 'ObjectEncoder'}), '(event.payload, ensure_ascii=False, cls=ObjectEncoder)\n', (3865, 3919), False, 'import json\n')]