classRouterQueryEngine(BaseQueryEngine):""" Router query engine. Selects one out of several candidate query engines to execute a query. Args: selector (BaseSelector): A selector that chooses one out of many options based on each candidate's metadata and query. query_engine_tools (Sequence[QueryEngineTool]): A sequence of candidate query engines. They must be wrapped as tools to expose metadata to the selector. summarizer (Optional[TreeSummarize]): Tree summarizer to summarize sub-results. """def__init__(self,selector:BaseSelector,query_engine_tools:Sequence[QueryEngineTool],llm:Optional[LLM]=None,summarizer:Optional[TreeSummarize]=None,verbose:bool=False,)->None:self._llm=llmorSettings.llmself._selector=selectorself._query_engines=[x.query_engineforxinquery_engine_tools]self._metadatas=[x.metadataforxinquery_engine_tools]self._summarizer=summarizerorTreeSummarize(llm=self._llm,summary_template=DEFAULT_TREE_SUMMARIZE_PROMPT_SEL,)self._verbose=verbosesuper().__init__(callback_manager=Settings.callback_manager)def_get_prompt_modules(self)->PromptMixinType:"""Get prompt sub-modules."""# NOTE: don't include tools for nowreturn{"summarizer":self._summarizer,"selector":self._selector}@classmethoddeffrom_defaults(cls,query_engine_tools:Sequence[QueryEngineTool],llm:Optional[LLM]=None,selector:Optional[BaseSelector]=None,summarizer:Optional[TreeSummarize]=None,select_multi:bool=False,**kwargs:Any,)->"RouterQueryEngine":llm=llmorSettings.llmselector=selectororget_selector_from_llm(llm,is_multi=select_multi)assertselectorisnotNonereturncls(selector,query_engine_tools,llm=llm,summarizer=summarizer,**kwargs,)def_query(self,query_bundle:QueryBundle)->RESPONSE_TYPE:withself.callback_manager.event(CBEventType.QUERY,payload={EventPayload.QUERY_STR:query_bundle.query_str})asquery_event:result=self._selector.select(self._metadatas,query_bundle)iflen(result.inds)>1:responses=[]fori,engine_indinenumerate(result.inds):log_str=(f"Selecting query engine {engine_ind}: {result.reasons[i]}.")logger.info(log_str)ifself._verbose:print_text(log_str+"\n",color="pink")selected_query_engine=self._query_engines[engine_ind]responses.append(selected_query_engine.query(query_bundle))iflen(responses)>1:final_response=combine_responses(self._summarizer,responses,query_bundle)else:final_response=responses[0]else:try:selected_query_engine=self._query_engines[result.ind]log_str=f"Selecting query engine {result.ind}: {result.reason}."logger.info(log_str)ifself._verbose:print_text(log_str+"\n",color="pink")exceptValueErrorase:raiseValueError("Failed to select query engine")fromefinal_response=selected_query_engine.query(query_bundle)# add selected resultfinal_response.metadata=final_response.metadataor{}final_response.metadata["selector_result"]=resultquery_event.on_end(payload={EventPayload.RESPONSE:final_response})returnfinal_responseasyncdef_aquery(self,query_bundle:QueryBundle)->RESPONSE_TYPE:withself.callback_manager.event(CBEventType.QUERY,payload={EventPayload.QUERY_STR:query_bundle.query_str})asquery_event:result=awaitself._selector.aselect(self._metadatas,query_bundle)iflen(result.inds)>1:tasks=[]fori,engine_indinenumerate(result.inds):log_str=(f"Selecting query engine {engine_ind}: {result.reasons[i]}.")logger.info(log_str)ifself._verbose:print_text(log_str+"\n",color="pink")selected_query_engine=self._query_engines[engine_ind]tasks.append(selected_query_engine.aquery(query_bundle))responses=run_async_tasks(tasks)iflen(responses)>1:final_response=awaitacombine_responses(self._summarizer,responses,query_bundle)else:final_response=responses[0]else:try:selected_query_engine=self._query_engines[result.ind]log_str=f"Selecting query engine {result.ind}: {result.reason}."logger.info(log_str)ifself._verbose:print_text(log_str+"\n",color="pink")exceptValueErrorase:raiseValueError("Failed to select query engine")fromefinal_response=awaitselected_query_engine.aquery(query_bundle)# add selected resultfinal_response.metadata=final_response.metadataor{}final_response.metadata["selector_result"]=resultquery_event.on_end(payload={EventPayload.RESPONSE:final_response})returnfinal_response