Ë
    ´Œj9  ã                  óÆ   — d Z ddlmZ ddlmZmZ ddlmZ ddlm	Z	 ddl
mZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZmZ ddlmZ  eddd¬«       G d„ de«      «       Zy)zCUse a single chain to route an input to one of multiple llm chains.é    )Úannotations)ÚAnyÚOptional)Ú
deprecated)ÚBaseLanguageModel)ÚPromptTemplate)ÚConversationChain)ÚChain)ÚLLMChain)ÚMultiRouteChain)ÚLLMRouterChainÚRouterOutputParser)ÚMULTI_PROMPT_ROUTER_TEMPLATEz0.2.12z1.0z�Please see migration guide here for recommended implementation: https://python.langchain.com/docs/versions/migrating_chains/multi_prompt_chain/)ÚsinceÚremovalÚmessagec                  óJ   — e Zd ZdZedd„«       Ze	 d	 	 	 	 	 	 	 	 	 dd„«       Zy)ÚMultiPromptChaina›  A multi-route chain that uses an LLM router chain to choose amongst prompts.

    This class is deprecated. See below for a replacement, which offers several
    benefits, including streaming and batch support.

    Below is an example implementation:

        .. code-block:: python

            from operator import itemgetter
            from typing import Literal

            from langchain_core.output_parsers import StrOutputParser
            from langchain_core.prompts import ChatPromptTemplate
            from langchain_core.runnables import RunnableConfig
            from langchain_openai import ChatOpenAI
            from langgraph.graph import END, START, StateGraph
            from typing_extensions import TypedDict

            llm = ChatOpenAI(model="gpt-4o-mini")

            # Define the prompts we will route to
            prompt_1 = ChatPromptTemplate.from_messages(
                [
                    ("system", "You are an expert on animals."),
                    ("human", "{input}"),
                ]
            )
            prompt_2 = ChatPromptTemplate.from_messages(
                [
                    ("system", "You are an expert on vegetables."),
                    ("human", "{input}"),
                ]
            )

            # Construct the chains we will route to. These format the input query
            # into the respective prompt, run it through a chat model, and cast
            # the result to a string.
            chain_1 = prompt_1 | llm | StrOutputParser()
            chain_2 = prompt_2 | llm | StrOutputParser()


            # Next: define the chain that selects which branch to route to.
            # Here we will take advantage of tool-calling features to force
            # the output to select one of two desired branches.
            route_system = "Route the user's query to either the animal or vegetable expert."
            route_prompt = ChatPromptTemplate.from_messages(
                [
                    ("system", route_system),
                    ("human", "{input}"),
                ]
            )


            # Define schema for output:
            class RouteQuery(TypedDict):
                """Route query to destination expert."""

                destination: Literal["animal", "vegetable"]


            route_chain = route_prompt | llm.with_structured_output(RouteQuery)


            # For LangGraph, we will define the state of the graph to hold the query,
            # destination, and final answer.
            class State(TypedDict):
                query: str
                destination: RouteQuery
                answer: str


            # We define functions for each node, including routing the query:
            async def route_query(state: State, config: RunnableConfig):
                destination = await route_chain.ainvoke(state["query"], config)
                return {"destination": destination}


            # And one node for each prompt
            async def prompt_1(state: State, config: RunnableConfig):
                return {"answer": await chain_1.ainvoke(state["query"], config)}


            async def prompt_2(state: State, config: RunnableConfig):
                return {"answer": await chain_2.ainvoke(state["query"], config)}


            # We then define logic that selects the prompt based on the classification
            def select_node(state: State) -> Literal["prompt_1", "prompt_2"]:
                if state["destination"] == "animal":
                    return "prompt_1"
                else:
                    return "prompt_2"


            # Finally, assemble the multi-prompt chain. This is a sequence of two steps:
            # 1) Select "animal" or "vegetable" via the route_chain, and collect the answer
            # alongside the input query.
            # 2) Route the input query to chain_1 or chain_2, based on the
            # selection.
            graph = StateGraph(State)
            graph.add_node("route_query", route_query)
            graph.add_node("prompt_1", prompt_1)
            graph.add_node("prompt_2", prompt_2)

            graph.add_edge(START, "route_query")
            graph.add_conditional_edges("route_query", select_node)
            graph.add_edge("prompt_1", END)
            graph.add_edge("prompt_2", END)
            app = graph.compile()

            result = await app.ainvoke({"query": "what color are carrots"})
            print(result["destination"])
            print(result["answer"])
    c                ó   — dgS )NÚtext© )Úselfs    ún/var/www/html/Fitness-lenito-AI-main/venv/lib/python3.12/site-packages/langchain/chains/router/multi_prompt.pyÚoutput_keyszMultiPromptChain.output_keys�   s	   € àˆxˆó    Nc                óˆ  — |D �cg c]  }|d   › d|d   › �‘Œ }}dj                  |«      }t        j                  |¬«      }t        |dgt	        «       ¬«      }	t        j                  ||	«      }
i }|D ],  }|d   }|d   }t        |dg¬	«      }t        ||¬
«      }|||<   Œ. |xs t        |d¬«      } | d|
||dœ|¤ŽS c c}w )zCConvenience constructor for instantiating from destination prompts.Únamez: ÚdescriptionÚ
)ÚdestinationsÚinput)ÚtemplateÚinput_variablesÚoutput_parserÚprompt_template)r"   r#   )ÚllmÚpromptr   )r&   Ú
output_key)Úrouter_chainÚdestination_chainsÚdefault_chainr   )	Újoinr   Úformatr   r   r   Úfrom_llmr   r	   )Úclsr&   Úprompt_infosr+   ÚkwargsÚpr    Údestinations_strÚrouter_templateÚrouter_promptr)   r*   Úp_infor   r%   r'   ÚchainÚ_default_chains                     r   Úfrom_promptszMultiPromptChain.from_prompts”   s  € ñ EQÓQÁL¸q˜1˜V™9˜+ R¨¨-Ñ(8Ð'9Ò:ÀLˆÐQØŸ9™9 \Ó2ÐÜ6×=Ñ=Ø)ô
ˆô 'Ø$Ø$˜IÜ,Ó.ô
ˆô
 &×.Ñ.¨s°MÓBˆØÐÛ"ˆFØ˜&‘>ˆDØ$Ð%6Ñ7ˆOÜ#¨_ÈwÈiÔXˆFÜ ¨VÔ4ˆEØ',Ð˜tÒ$ð #ð 'ÒWÔ*;ÀÐPVÔ*WˆÙð 
Ø%Ø1Ø(ñ
ð ñ	
ð 	
ùò' Rs   …B?)Úreturnz	list[str])N)
r&   r   r0   zlist[dict[str, str]]r+   zOptional[Chain]r1   r   r:   r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__Úpropertyr   Úclassmethodr9   r   r   r   r   r      sf   „ ñrðh òó ðð ð
 *.ð	 
àð 
ð +ð 
ð 'ð	 
ð
 ð 
ð 
ò 
ó ñ 
r   r   N)r>   Ú
__future__r   Útypingr   r   Úlangchain_core._apir   Úlangchain_core.language_modelsr   Úlangchain_core.promptsr   Úlangchain.chainsr	   Úlangchain.chains.baser
   Úlangchain.chains.llmr   Úlangchain.chains.router.baser   Ú"langchain.chains.router.llm_routerr   r   Ú+langchain.chains.router.multi_prompt_promptr   r   r   r   r   Ú<module>rL      sX   ðÙ Iå "ç  å *Ý <Ý 1å .Ý 'Ý )Ý 8ß QÝ Tñ Ø
Øð	Zô	ôZ
�ó Z
óñZ
r   