§
    ™Štj³  ã                  óä   — d 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 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d¬¦  «         G d„ de¦  «        ¦   «         ZdS )zCUse a single chain to route an input to one of multiple llm chains.é    )Úannotations)ÚAny)Ú
deprecated)ÚBaseLanguageModel)ÚPromptTemplate)Úoverride)ÚConversationChain)ÚChain)ÚLLMChain)ÚMultiRouteChain)ÚLLMRouterChainÚRouterOutputParser)ÚMULTI_PROMPT_ROUTER_TEMPLATEz0.2.12z2.0.0zlangchain.agents.create_agentz˜Build routing logic with `create_agent` (e.g. with subagents or prompt-selection middleware). See https://docs.langchain.com/oss/python/langchain/agents)ÚsinceÚremovalÚalternativeÚaddendumc                  óV   — e Zd ZdZeedd„¦   «         ¦   «         Ze	 ddd„¦   «         ZdS )ÚMultiPromptChainam  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:

        ```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

        model = 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 | model | StrOutputParser()
        chain_2 = prompt_2 | model | 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 | model.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"])

        ```
    Úreturnú	list[str]c                ó   — dgS )NÚtext© )Úselfs    új/var/www/html/CA-Chatbot/venv/lib/python3.11/site-packages/langchain_classic/chains/router/multi_prompt.pyÚoutput_keyszMultiPromptChain.output_keysš   s   € ð ˆxˆó    NÚllmr   Úprompt_infosúlist[dict[str, str]]Údefault_chainúChain | NoneÚkwargsr   c                ó’  — d„ |D ¦   «         }d                      |¦  «        }t          j        |¬¦  «        }t          |dgt	          ¦   «         ¬¦  «        }t          j        ||¦  «        }	i }
|D ]:}|d         }|d         }t          |dg¬¦  «        }t          ||¬	¦  «        }||
|<   Œ;|pt          |d
¬¦  «        } | d|	|
|dœ|¤ŽS )zCConvenience constructor for instantiating from destination prompts.c                ó4   — g | ]}|d          › d|d         › �‘ŒS )Únamez: Údescriptionr   )Ú.0Úps     r   ú
<listcomp>z1MultiPromptChain.from_prompts.<locals>.<listcomp>¨   s/   € ÐQÐQÐQ¸q˜1˜Vœ9Ð:Ð:¨¨-Ô(8Ð:Ð:ÐQÐQÐQr   ú
)ÚdestinationsÚinput)ÚtemplateÚinput_variablesÚoutput_parserr'   Úprompt_template)r/   r0   )r   Úpromptr   )r   Ú
output_key)Úrouter_chainÚdestination_chainsr"   r   )	Újoinr   Úformatr   r   r   Úfrom_llmr   r	   )Úclsr   r    r"   r$   r-   Údestinations_strÚrouter_templateÚrouter_promptr5   r6   Úp_infor'   r2   r3   ÚchainÚ_default_chains                    r   Úfrom_promptszMultiPromptChain.from_promptsŸ   s&  € ð RÐQÀLÐQÑQÔQˆØŸ9š9 \Ñ2Ô2ÐÝ6Ô=Ø)ð
ñ 
ô 
ˆõ 'Ø$Ø$˜IÝ,Ñ.Ô.ð
ñ 
ô 
ˆõ
 &Ô.¨s°MÑBÔBˆØÐØ"ð 	-ð 	-ˆFØ˜&”>ˆDØ$Ð%6Ô7ˆOÝ#¨_ÈwÈiÐXÑXÔXˆFÝ ¨VÐ4Ñ4Ô4ˆEØ',Ð˜tÑ$Ð$Ø&ÐWÕ*;ÀÐPVÐ*WÑ*WÔ*WˆØˆsð 
Ø%Ø1Ø(ð
ð 
ð ð	
ð 
ð 	
r   )r   r   )N)
r   r   r    r!   r"   r#   r$   r   r   r   )	Ú__name__Ú
__module__Ú__qualname__Ú__doc__Úpropertyr   r   ÚclassmethodrA   r   r   r   r   r      su   € € € € € ðtð tðl Øðð ð ñ „Xñ „Xðð ð
 '+ð	 
ð  
ð  
ð  
ñ „[ð 
ð  
ð  
r   r   N)rE   Ú
__future__r   Útypingr   Úlangchain_core._apir   Úlangchain_core.language_modelsr   Úlangchain_core.promptsr   Útyping_extensionsr   Úlangchain_classic.chainsr	   Úlangchain_classic.chains.baser
   Úlangchain_classic.chains.llmr   Ú$langchain_classic.chains.router.baser   Ú*langchain_classic.chains.router.llm_routerr   r   Ú3langchain_classic.chains.router.multi_prompt_promptr   r   r   r   r   ú<module>rT      sr  ðØ IÐ Ià "Ð "Ð "Ð "Ð "Ð "à Ð Ð Ð Ð Ð à *Ð *Ð *Ð *Ð *Ð *Ø <Ð <Ð <Ð <Ð <Ð <Ø 1Ð 1Ð 1Ð 1Ð 1Ð 1Ø &Ð &Ð &Ð &Ð &Ð &à 6Ð 6Ð 6Ð 6Ð 6Ð 6Ø /Ð /Ð /Ð /Ð /Ð /Ø 1Ð 1Ð 1Ð 1Ð 1Ð 1Ø @Ð @Ð @Ð @Ð @Ð @ðð ð ð ð ð ð ð ðð ð ð ð ð ð
 €Ø
ØØ/ð	Að	ñ 	ô 	ð]
ð ]
ð ]
ð ]
ð ]
�ñ ]
ô ]
ñ	ô 	ð]
ð ]
ð ]
r   