classRouterRetriever(BaseRetriever):"""Router retriever. Selects one (or multiple) out of several candidate retrievers to execute a query. Args: selector (BaseSelector): A selector that chooses one out of many options based on each candidate's metadata and query. retriever_tools (Sequence[RetrieverTool]): A sequence of candidate retrievers. They must be wrapped as tools to expose metadata to the selector. """def__init__(self,selector:BaseSelector,retriever_tools:Sequence[RetrieverTool],llm:Optional[LLM]=None,objects:Optional[List[IndexNode]]=None,object_map:Optional[dict]=None,verbose:bool=False,)->None:self._llm=llmorSettings.llmself._selector=selectorself._retrievers:List[BaseRetriever]=[x.retrieverforxinretriever_tools]self._metadatas=[x.metadataforxinretriever_tools]super().__init__(callback_manager=Settings.callback_manager,object_map=object_map,objects=objects,verbose=verbose,)def_get_prompt_modules(self)->PromptMixinType:"""Get prompt sub-modules."""# NOTE: don't include tools for nowreturn{"selector":self._selector}@classmethoddeffrom_defaults(cls,retriever_tools:Sequence[RetrieverTool],llm:Optional[LLM]=None,selector:Optional[BaseSelector]=None,select_multi:bool=False,)->"RouterRetriever":llm=llmorSettings.llmselector=selectororget_selector_from_llm(llm,is_multi=select_multi)returncls(selector,retriever_tools,llm=llm,)def_retrieve(self,query_bundle:QueryBundle)->List[NodeWithScore]:withself.callback_manager.event(CBEventType.RETRIEVE,payload={EventPayload.QUERY_STR:query_bundle.query_str},)asquery_event:result=self._selector.select(self._metadatas,query_bundle)iflen(result.inds)>1:retrieved_results={}fori,engine_indinenumerate(result.inds):logger.info(f"Selecting retriever {engine_ind}: "f"{result.reasons[i]}.")selected_retriever=self._retrievers[engine_ind]cur_results=selected_retriever.retrieve(query_bundle)retrieved_results.update({n.node.node_id:nfornincur_results})else:try:selected_retriever=self._retrievers[result.ind]logger.info(f"Selecting retriever {result.ind}: {result.reason}.")exceptValueErrorase:raiseValueError("Failed to select retriever")fromecur_results=selected_retriever.retrieve(query_bundle)retrieved_results={n.node.node_id:nfornincur_results}query_event.on_end(payload={EventPayload.NODES:retrieved_results.values()})returnlist(retrieved_results.values())asyncdef_aretrieve(self,query_bundle:QueryBundle)->List[NodeWithScore]:withself.callback_manager.event(CBEventType.RETRIEVE,payload={EventPayload.QUERY_STR:query_bundle.query_str},)asquery_event:result=awaitself._selector.aselect(self._metadatas,query_bundle)iflen(result.inds)>1:retrieved_results={}tasks=[]fori,engine_indinenumerate(result.inds):logger.info(f"Selecting retriever {engine_ind}: "f"{result.reasons[i]}.")selected_retriever=self._retrievers[engine_ind]tasks.append(selected_retriever.aretrieve(query_bundle))results_of_results=awaitasyncio.gather(*tasks)cur_results=[itemforsublistinresults_of_resultsforiteminsublist]retrieved_results.update({n.node.node_id:nfornincur_results})else:try:selected_retriever=self._retrievers[result.ind]logger.info(f"Selecting retriever {result.ind}: {result.reason}.")exceptValueErrorase:raiseValueError("Failed to select retriever")fromecur_results=awaitselected_retriever.aretrieve(query_bundle)retrieved_results={n.node.node_id:nfornincur_results}query_event.on_end(payload={EventPayload.NODES:retrieved_results.values()})returnlist(retrieved_results.values())