
    hhĂ              	          d dl Z d dlZd dlZd dlmZ d dlmZmZmZm	Z	m
Z
mZmZmZmZmZmZmZ d dlmZmZ d dlmZ d dlmZ d dlmZmZmZmZmZmZm Z 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,m-Z-m.Z. d dl/m0Z0m1Z1m2Z2 d dl3m4Z4 d dl5m6Z6m7Z7 d dl8m9Z9 d dl:m;Z;m<Z< d dl=m>Z>m?Z?m@Z@mAZAmBZB  ejC        eD          ZEdedeFfdZGdeeHeeeHe	eef         f                  f         deHfdZIdeeHef         defdZJ G d de          ZKdS )    N)
itemgetter)AnyAsyncIteratorCallableDictIteratorListMappingOptionalSequenceTypeUnioncast)AsyncCallbackManagerForLLMRunCallbackManagerForLLMRun)LanguageModelInput)BaseChatModel)	AIMessageAIMessageChunkBaseMessageChatMessageFunctionMessageHumanMessageSystemMessageToolMessage)UsageMetadata)tool_call_chunk)OutputParserLike)JsonOutputKeyToolsParserPydanticToolsParser)ChatGenerationChatGenerationChunk
ChatResult)RunnableRunnableMapRunnablePassthrough)BaseTool)convert_to_secret_strget_from_dict_or_envconvert_to_openai_tool)
get_fieldsis_basemodel_subclass)	BaseModel
ConfigDictField	SecretStrmodel_validatormessagereturnc                 @   t          | t                    r| j        | j        d}nt          | t                    rd| j        d}nt          | t
                    r]d| j        d}t          | j                  dk    r:| j        d         }|d         t          j	        |d         d          d	|d
<   d|d<   nft          | t          t          f          r8dt          | j                  | j        p| j                            d          d}nt!          d|            |S )z@Convert a message to a dictionary that can be passed to the API.)rolecontentuser	assistantr   nameargsF)ensure_ascii)r:   	argumentsfunction_callNr7   function)r6   r7   r:   zGot unknown type )
isinstancer   r6   r7   r   r   len
tool_callsjsondumpsr   r   _create_tool_contentr:   additional_kwargsget	TypeError)r3   message_dict	tool_calls      s/var/www/FlaskApp/flask-venv/lib/python3.11/site-packages/langchain_community/chat_models/baidu_qianfan_endpoint.pyconvert_message_to_dictrL   <   s<    ';'' 7 'II	G\	*	* 7 &7?CC	GY	'	' 7 +HHw!""a''*1-I!&)!Z	&(9NNN- -L)
 '+L#	Go{;	<	< 7+GO<<LIG$=$A$A&$I$I
 
 5G55666    r7   c                 .   t          | t                    rk	 t          t          j        |           t                    r| S t          j        d| i          S # t          j        $ r t          j        d| i          cY S w xY wt          j        d| i          S )z$Convert tool content to dict scheme.tool_result)r@   strrC   loadsdictrD   JSONDecodeError)r7   s    rK   rE   rE   Y   s    '3 	4	8$*W--t44 <z='":;;;# 	8 	8 	8:}g677777	8 z='2333s   (A  A %A>=A>_dictc           	         |                      dd          pd}i }|                      d          r<dt          | d                   i}d|d         v r|d                             d           i |                      di           |}t          |                     dd          |d         |                     dd          |                     d	g           
          }|                     di           rU|                     di           |d<   d|                     di           t          t	          j                              dg|d<   t          ||          }|                     dd           x}rSt          |                     dd          |                     dd          |                     dd                    |_        |S )Nresult r>   thoughtsbodyfinish_reasonidobjectsearch_info)rZ   
request_idr\   r]   r?   )typer?   r[   rB   )r7   rF   usageprompt_tokensr   completion_tokenstotal_tokens)input_tokensoutput_tokensrc   )	rG   rR   poprP   uuiduuid4r   r   usage_metadata)rT   r7   rF   msg_additional_kwargsretr`   s         rK   _convert_dict_to_messagerl   g   s   ii"%%+G+-yy!! ?,d53I.J.JK*?;;;o.22:>>> G599VR00F4EF '++OR@@$T* $$Xr22%))-<<	   _b11 

1B1F1FR2
 2
o.
 #-11/2FF$*,,'' /
l+ /  C
 "%%gt444u 
*?A66))$7;;>155
 
 
 JrM   c                       e Zd ZU dZ ee          Zeee	f         e
d<   	  ee          Zeee	f         e
d<   	 dZe	e
d<    edd          Zee         e
d	<   	  edd
          Zee         e
d<   	 dZee         e
d<   	  edd          Zee         e
d<   	 dZee         e
d<   	 dZee         e
d<   	 dZee         e
d<   	  ed          Zee         e
d<   	 dZee         e
d<   	  ed          Z ed          eded e	fd!                        Ze d eee	f         f fd"            Z!e d efd#            Z"e d eee	f         fd$            Z#d%e$e%         d&e	d eee	f         fd'Z&	 	 d4d%e$e%         d(ee$e                  d)ee'         d&e	d e(f
d*Z)	 	 d4d%e$e%         d(ee$e                  d)ee*         d&e	d e(f
d+Z+	 	 d4d%e$e%         d(ee$e                  d)ee'         d&e	d e,e-         f
d,Z.	 	 d4d%e$e%         d(ee$e                  d)ee*         d&e	d e/e-         f
d-Z0d.e1e2eee	f         e3e4         e5e6f                  d&e	d e7e8e%f         f fd/Z9dd0d1e2ee3e4         f         d2ed&e	d e7e8e2ee4f         f         fd3Z: xZ;S )5QianfanChatEndpointu  Baidu Qianfan chat model integration.

    Setup:
        Install ``qianfan`` and set environment variables ``QIANFAN_AK``, ``QIANFAN_SK``.

        .. code-block:: bash

            pip install qianfan
            export QIANFAN_AK="your-api-key"
            export QIANFAN_SK="your-secret_key"

    Key init args — completion params:
        model: str
            Name of Qianfan model to use.
        temperature: Optional[float]
            Sampling temperature.
        endpoint: Optional[str]
            Endpoint of the Qianfan LLM
        top_p: Optional[float]
            What probability mass to use.

    Key init args — client params:
        timeout: Optional[int]
            Timeout for requests.
        api_key: Optional[str]
            Qianfan API KEY. If not passed in will be read from env var QIANFAN_AK.
        secret_key: Optional[str]
            Qianfan SECRET KEY. If not passed in will be read from env var QIANFAN_SK.

    See full list of supported init args and their descriptions in the params section.

    Instantiate:
        .. code-block:: python

            from langchain_community.chat_models import QianfanChatEndpoint

            qianfan_chat = QianfanChatEndpoint(
                model="ERNIE-3.5-8K",
                temperature=0.2,
                timeout=30,
                # api_key="...",
                # secret_key="...",
                # top_p="...",
                # other params...
            )

    Invoke:
         .. code-block:: python

            messages = [
                ("system", "你是一名专业的翻译家，可以将用户的中文翻译为英文。"),
                ("human", "我喜欢编程。"),
            ]
            qianfan_chat.invoke(messages)

        .. code-block:: python

            AIMessage(content='I enjoy programming.', additional_kwargs={'finish_reason': 'normal', 'request_id': 'as-7848zeqn1c', 'object': 'chat.completion', 'search_info': []}, response_metadata={'token_usage': {'prompt_tokens': 16, 'completion_tokens': 4, 'total_tokens': 20}, 'model_name': 'ERNIE-3.5-8K', 'finish_reason': 'normal', 'id': 'as-7848zeqn1c', 'object': 'chat.completion', 'created': 1719153606, 'result': 'I enjoy programming.', 'is_truncated': False, 'need_clear_history': False, 'usage': {'prompt_tokens': 16, 'completion_tokens': 4, 'total_tokens': 20}}, id='run-4bca0c10-5043-456b-a5be-2f62a980f3f0-0')

    Stream:
        .. code-block:: python

            for chunk in qianfan_chat.stream(messages):
                print(chunk)

        .. code-block:: python

            content='I enjoy' response_metadata={'finish_reason': 'normal', 'request_id': 'as-yz0yz1w1rq', 'object': 'chat.completion', 'search_info': []} id='run-0fa9da50-003e-4a26-ba16-dbfe96249b8b' role='assistant'
            content=' programming.' response_metadata={'finish_reason': 'normal', 'request_id': 'as-yz0yz1w1rq', 'object': 'chat.completion', 'search_info': []} id='run-0fa9da50-003e-4a26-ba16-dbfe96249b8b' role='assistant'

        .. code-block:: python

            stream = chat.stream(messages)
            full = next(stream)
            for chunk in stream:
                full += chunk
            full

        .. code-block::

            AIMessageChunk(content='I enjoy programming.', response_metadata={'finish_reason': 'normalnormal', 'request_id': 'as-p63cnn3ppnas-p63cnn3ppn', 'object': 'chat.completionchat.completion', 'search_info': []}, id='run-09a8cbbd-5ded-4529-981d-5bc9d1206404')

    Async:
        .. code-block:: python

            await qianfan_chat.ainvoke(messages)

            # stream:
            # async for chunk in qianfan_chat.astream(messages):
            #    print(chunk)

            # batch:
            # await qianfan_chat.abatch([messages])

        .. code-block:: python

            [AIMessage(content='I enjoy programming.', additional_kwargs={'finish_reason': 'normal', 'request_id': 'as-mpqa8qa1qb', 'object': 'chat.completion', 'search_info': []}, response_metadata={'token_usage': {'prompt_tokens': 16, 'completion_tokens': 4, 'total_tokens': 20}, 'model_name': 'ERNIE-3.5-8K', 'finish_reason': 'normal', 'id': 'as-mpqa8qa1qb', 'object': 'chat.completion', 'created': 1719155120, 'result': 'I enjoy programming.', 'is_truncated': False, 'need_clear_history': False, 'usage': {'prompt_tokens': 16, 'completion_tokens': 4, 'total_tokens': 20}}, id='run-443b2231-08f9-4725-b807-b77d0507ad44-0')]

    Tool calling:
        .. code-block:: python

            from pydantic import BaseModel, Field


            class GetWeather(BaseModel):
                '''Get the current weather in a given location'''

                location: str = Field(
                    ..., description="The city and state, e.g. San Francisco, CA"
                )


            class GetPopulation(BaseModel):
                '''Get the current population in a given location'''

                location: str = Field(
                    ..., description="The city and state, e.g. San Francisco, CA"
                )

            chat_with_tools = qianfan_chat.bind_tools([GetWeather, GetPopulation])
            ai_msg = chat_with_tools.invoke(
                "Which city is hotter today and which is bigger: LA or NY?"
            )
            ai_msg.tool_calls

        .. code-block:: python

            [
                {
                    'name': 'GetWeather',
                    'args': {'location': 'Los Angeles, CA'},
                    'id': '533e5f63-a3dc-40f2-9d9c-22b1feee62e0'
                }
            ]

    Structured output:
        .. code-block:: python

            from typing import Optional

            from pydantic import BaseModel, Field


            class Joke(BaseModel):
                '''Joke to tell user.'''

                setup: str = Field(description="The setup of the joke")
                punchline: str = Field(description="The punchline to the joke")
                rating: Optional[int] = Field(description="How funny the joke is, from 1 to 10")


            structured_chat = qianfan_chat.with_structured_output(Joke)
            structured_chat.invoke("Tell me a joke about cats")

        .. code-block:: python

            Joke(
                setup='A cat is sitting in front of a mirror and sees another cat. What does the cat think?',
                punchline="The cat doesn't think it's another cat, it thinks it's another mirror.",
                rating=None
            )

    Response metadata
        .. code-block:: python

            ai_msg = qianfan_chat.invoke(messages)
            ai_msg.response_metadata

        .. code-block:: python
            {
                'token_usage': {
                    'prompt_tokens': 16,
                    'completion_tokens': 4,
                    'total_tokens': 20},
                    'model_name': 'ERNIE-3.5-8K',
                    'finish_reason': 'normal',
                    'id': 'as-qbzwtydqmi',
                    'object': 'chat.completion',
                    'created': 1719158153,
                    'result': 'I enjoy programming.',
                    'is_truncated': False,
                    'need_clear_history': False,
                    'usage': {
                        'prompt_tokens': 16,
                        'completion_tokens': 4,
                        'total_tokens': 20
                    }
            }

    )default_factoryinit_kwargsmodel_kwargsNclientapi_key)defaultalias
qianfan_ak
secret_key
qianfan_skF	streaming<   timeout)ru   request_timeoutg?top_pgffffff?temperature   penalty_scorert   modelendpointT)populate_by_namebefore)modevaluesr4   c                 J   t          t          |ddgdd                    |d<   t          t          |ddgdd                    |d<   d	 t          |                                           D             }|                    |           i |                    d
i           |                    d          |                    d          d}|d                                         dk    r|d                                         |d<   |d                                         dk    r|d                                         |d<   |                    d          |d         dk    r|d         |d<   	 dd l} |j        di ||d<   n# t          $ r t          d          w xY w|S )Nrv   rs   
QIANFAN_AKrW   r   rx   rw   
QIANFAN_SKc                 2    i | ]\  }}|j         ||j         S Nr   ).0r:   fields      rK   
<dictcomp>z<QianfanChatEndpoint.validate_environment.<locals>.<dictcomp>  s2     
 
 
e}( %-(((rM   rp   r   ry   )r   streamakskr   r   rr   zGqianfan package not found, please install it with `pip install qianfan` )
r(   r)   r,   itemsupdaterG   get_secret_valueqianfanChatCompletionImportError)clsr   default_valuesparamsr   s        rK   validate_environmentz(QianfanChatEndpoint.validate_environment  s
     5 y1<   
  
|
  5 |4lB   
  
|
 
)#4466
 
 

 	f%%%
jj++
#''00$((55
 
 

 ,0022b88!,/@@BBF4L,0022b88!,/@@BBF4Lz**6z*b00!/
!;F:	NNN5w5????F8 	 	 	(  	
 s   1F F c                 L    i | j         | j        dt                      j        S )N)r   r   )r   r   super_identifying_params)self	__class__s    rK   r   z'QianfanChatEndpoint._identifying_params  s0    
=4:>>
gg)
 	
rM   c                     dS )zReturn type of chat_model.zbaidu-qianfan-chatr   )r   s    rK   	_llm_typezQianfanChatEndpoint._llm_type  s
     $#rM   c                 r    | j         | j        | j        | j        | j        | j        | j        d}i || j        S )z3Get the default parameters for calling Qianfan API.)r   r   r   r|   r}   r~   r   )r   r   ry   r|   r}   r~   r   rq   )r   normal_paramss     rK   _default_paramsz#QianfanChatEndpoint._default_params  sK     Zn#3Z+!/
 
 6-54#455rM   messageskwargsc           	          dd |D             i}d t          |          D             D ]<}d|vrd|d<   |dxx         t          t          ||         j                  dz   z  cc<   =i || j        |S )a  
        Converts a list of messages into a dictionary containing the message content
        and default parameters.

        Args:
            messages (List[BaseMessage]): The list of messages.
            **kwargs (Any): Optional arguments to add additional parameters to the
            resulting dictionary.

        Returns:
            Dict[str, Any]: A dictionary containing the message content and default
            parameters.

        r   c                 V    g | ]&}t          |t                    t          |          'S r   )r@   r   rL   )r   ms     rK   
<listcomp>zBQianfanChatEndpoint._convert_prompt_msg_params.<locals>.<listcomp>  s@       !!]33'**  rM   c                 B    g | ]\  }}t          |t                    |S r   )r@   r   )r   ir   s      rK   r   zBQianfanChatEndpoint._convert_prompt_msg_params.<locals>.<listcomp>  s+    TTT1z!]7S7ST!TTTrM   systemrW   
)	enumerater   rP   r7   r   )r   r   r   messages_dictr   s        rK   _convert_prompt_msg_paramsz.QianfanChatEndpoint._convert_prompt_msg_params  s    (   !  )
 UT	( 3 3TTT 	M 	MA},,*,h'(###tC!1D'E'E'LL####

"
 
 	
rM   stoprun_managerc                 z   | j         rd}i }d} | j        |||fi |D ]B}|j        |j        n|}||j        z  }t	          |j        t                    r|j        j        }Ct          |i |          }	t          |	t          d                    }
t          |
g|pi | j        d          S  | j        |fi |}||d<    | j        j        di |}t!          |          }	t          |	d	di|                    d
i                     }
|                    di           }|| j        d}t          |
g|          S )a  Call out to an qianfan models endpoint for each generation with a prompt.
        Args:
            messages: The messages to pass into the model.
            stop: Optional list of stop words to use when generating.
        Returns:
            The string generated by the model.

        Example:
            .. code-block:: python
                response = qianfan_model.invoke("Tell me a joke.")
        rW   Nr7   rF   ri   r   rZ   r3   generation_infotoken_usage
model_namegenerations
llm_outputrZ   rY   r`   r   )ry   _streamr   textr@   r3   r   ri   r   r!   rR   r#   r   r   rr   dorl   rG   )r   r   r   r   r   
completionchat_generation_infori   chunklc_msggenr   response_payloadr   r   s                  rK   	_generatezQianfanChatEndpoint._generate  s   $ > 	J)+ 6:N%hkLLVLL B B ,8 ))- %
 ej(
em^<< B%*]%AN""$-  F
 ! $6 : : :  C  E#1#7R"&*     10DDVDDv)4;>33F33)*:;;"&&vr22
 
 
 '**7B77%0
KK
se
CCCCrM   c                   K   | j         rd}i }d } | j        |||fi |2 3 d {V }|j        |j        n|}||j        z  }t	          |j        t                    r|j        j        }H6 t          |i |          }	t          |	t          d                    }
t          |
g|pi | j        d          S  | j        |fi |}||d<    | j        j        di | d {V }t!          |          }	g }t          |	ddi|                    d	i                     }
|                    |
           |                    d
i           }|| j        d}t          ||          S )NrW   r   r   r   r   r   r   rZ   rY   r`   r   )ry   _astreamr   r   r@   r3   r   ri   r   r!   rR   r#   r   r   rr   adorl   rG   append)r   r   r   r   r   r   r   ri   r   r   r   r   r   r   r   r   s                   rK   
_ageneratezQianfanChatEndpoint._agenerate3  s       > 	J)+ 6:N,t}Xt[SSFSS 	B 	B 	B 	B 	B 	B 	Be ,8 ))- %
 ej(
em^<< B%*]%AN  T ""$-  F
 ! $6 : : :  C  E#1#7R"&*     10DDVDDv!0!:!:6!:!:::::::)*:;;"&&vr22
 
 
 	3&**7B77%0
KK
kjIIIIs   A(c              +     K    | j         |fi |}||d<   d|d<    | j        j        di |D ]}|rt          |          }|j                            di           }t          |d         t          |j        d||j	        d |j
        D                       |j        	          }	|r|                    |	j        |	
           |	V  d S )Nr   Tr   r>   rV   r9   c           	      |    g | ]9}t          |d          t          j        |d                   |d         d          :S r:   r;   r[   N)r:   r;   r[   indexr   rC   rD   r   tcs     rK   r   z/QianfanChatEndpoint._stream.<locals>.<listcomp>  [     * * * !# ,%'Z%)Z6
%;%;#%d8&*	  * * *rM   r7   r6   rF   ri   tool_call_chunksr   r3   r   r   r   )r   rr   r   rl   rF   rG   r"   r   r7   ri   rB   on_llm_new_tokenr   
r   r   r   r   r   r   resmsgrF   r   s
             rK   r   zQianfanChatEndpoint._streamj  s&      10DDVDDvx!4;>++F++ 	 	C .s33$'$9$=$=or$R$R!+X* #(*;'*'9* * '*n* * *   %($9#  &  J0050III3	 	rM   c                  K    | j         |fi |}||d<   d|d<    | j        j        di | d {V 2 3 d {V }|rt          |          }|j                            di           }t          |d         t          |j        d||j	        d |j
        D                       |j        	          }	|r"|                    |	j        |	
           d {V  |	W V  6 d S )Nr   Tr   r>   rV   r9   c           	      |    g | ]9}t          |d          t          j        |d                   |d         d          :S r   r   r   s     rK   r   z0QianfanChatEndpoint._astream.<locals>.<listcomp>  r   rM   r   r   r   r   )r   rr   r   rl   rF   rG   r"   r   r7   ri   rB   r   r   r   s
             rK   r   zQianfanChatEndpoint._astream  sf      10DDVDDvx.t{8888888888 	 	 	 	 	 	 	# .s33$'$9$=$=or$R$R!+X* #(*;'*'9* * '*n* * *   %($9#  &  P%66uz6OOOOOOOOO3 988s   Ctoolsc                 R    d |D             } t                      j        dd|i|S )a3  Bind tool-like objects to this chat model.

        Assumes model is compatible with OpenAI tool-calling API.

        Args:
            tools: A list of tool definitions to bind to this chat model.
                Can be  a dictionary, pydantic model, callable, or BaseTool. Pydantic
                models, callables, and BaseTools will be automatically converted to
                their schema dictionary representation.
            **kwargs: Any additional parameters to pass to the
                :class:`~langchain.runnable.Runnable` constructor.
        c                 8    g | ]}t          |          d          S )r?   r*   )r   tools     rK   r   z2QianfanChatEndpoint.bind_tools.<locals>.<listcomp>  s&    VVV1$77
CVVVrM   	functionsr   )r   bind)r   r   r   formatted_toolsr   s       rK   
bind_toolszQianfanChatEndpoint.bind_tools  s;    $ WVPUVVVuww|@@o@@@@rM   )include_rawschemar   c                   |rt          d|           t          |t                    ot          |          }|                     |g          }|rt          |gd          }n,t          |          d         d         }t          |d          }|rht          j	        t          d          |z  d 	          }t          j	        d
           }	|                    |	gd          }
t          |          |
z  S ||z  S )a*  Model wrapper that returns outputs formatted to match the given schema.

        Args:
            schema: The output schema as a dict or a Pydantic class. If a Pydantic class
                then the model output will be an object of that class. If a dict then
                the model output will be a dict. With a Pydantic class the returned
                attributes will be validated, whereas with a dict they will not be. If
                `method` is "function_calling" and `schema` is a dict, then the dict
                must match the OpenAI function-calling spec.
            include_raw: If False then only the parsed structured output is returned. If
                an error occurs during model output parsing it will be raised. If True
                then both the raw model response (a BaseMessage) and the parsed model
                response will be returned. If an error occurs during output parsing it
                will be caught and returned as well. The final output is always a dict
                with keys "raw", "parsed", and "parsing_error".

        Returns:
            A Runnable that takes any ChatModel input and returns as output:

                If include_raw is True then a dict with keys:
                    raw: BaseMessage
                    parsed: Optional[_DictOrPydantic]
                    parsing_error: Optional[BaseException]

                If include_raw is False then just _DictOrPydantic is returned,
                where _DictOrPydantic depends on the schema:

                If schema is a Pydantic class then _DictOrPydantic is the Pydantic
                    class.

                If schema is a dict then _DictOrPydantic is a dict.

        Example: Function-calling, Pydantic schema (method="function_calling", include_raw=False):
            .. code-block:: python

                from langchain_mistralai import QianfanChatEndpoint
                from pydantic import BaseModel

                class AnswerWithJustification(BaseModel):
                    '''An answer to the user question along with justification for the answer.'''
                    answer: str
                    justification: str

                llm = QianfanChatEndpoint(endpoint="ernie-3.5-8k-0329")
                structured_llm = llm.with_structured_output(AnswerWithJustification)

                structured_llm.invoke("What weighs more a pound of bricks or a pound of feathers")

                # -> AnswerWithJustification(
                #     answer='They weigh the same',
                #     justification='Both a pound of bricks and a pound of feathers weigh one pound. The weight is the same, but the volume or density of the objects may differ.'
                # )

        Example: Function-calling, Pydantic schema (method="function_calling", include_raw=True):
            .. code-block:: python

                from langchain_mistralai import QianfanChatEndpoint
                from pydantic import BaseModel

                class AnswerWithJustification(BaseModel):
                    '''An answer to the user question along with justification for the answer.'''
                    answer: str
                    justification: str

                llm = QianfanChatEndpoint(endpoint="ernie-3.5-8k-0329")
                structured_llm = llm.with_structured_output(AnswerWithJustification, include_raw=True)

                structured_llm.invoke("What weighs more a pound of bricks or a pound of feathers")
                # -> {
                #     'raw': AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_Ao02pnFYXD6GN1yzc0uXPsvF', 'function': {'arguments': '{"answer":"They weigh the same.","justification":"Both a pound of bricks and a pound of feathers weigh one pound. The weight is the same, but the volume or density of the objects may differ."}', 'name': 'AnswerWithJustification'}, 'type': 'function'}]}),
                #     'parsed': AnswerWithJustification(answer='They weigh the same.', justification='Both a pound of bricks and a pound of feathers weigh one pound. The weight is the same, but the volume or density of the objects may differ.'),
                #     'parsing_error': None
                # }

        Example: Function-calling, dict schema (method="function_calling", include_raw=False):
            .. code-block:: python

                from langchain_mistralai import QianfanChatEndpoint
                from pydantic import BaseModel
                from langchain_core.utils.function_calling import convert_to_openai_tool

                class AnswerWithJustification(BaseModel):
                    '''An answer to the user question along with justification for the answer.'''
                    answer: str
                    justification: str

                dict_schema = convert_to_openai_tool(AnswerWithJustification)
                llm = QianfanChatEndpoint(endpoint="ernie-3.5-8k-0329")
                structured_llm = llm.with_structured_output(dict_schema)

                structured_llm.invoke("What weighs more a pound of bricks or a pound of feathers")
                # -> {
                #     'answer': 'They weigh the same',
                #     'justification': 'Both a pound of bricks and a pound of feathers weigh one pound. The weight is the same, but the volume and density of the two substances differ.'
                # }

        zReceived unsupported arguments T)r   first_tool_onlyr?   r:   )key_namer   rawc                     d S r   r   _s    rK   <lambda>z<QianfanChatEndpoint.with_structured_output.<locals>.<lambda>B  s    RV rM   )parsedparsing_errorc                     d S r   r   r   s    rK   r   z<QianfanChatEndpoint.with_structured_output.<locals>.<lambda>D  s    d rM   )r   r   )exception_key)r   )
ValueErrorr@   r_   r-   r   r    r+   r   r&   assignr   with_fallbacksr%   )r   r   r   r   is_pydantic_schemallmoutput_parserr   parser_assignparser_noneparser_with_fallbacks              rK   with_structured_outputz*QianfanChatEndpoint.with_structured_output  sB   P  	IGvGGHHH'55W:OPV:W:Woovh'' 		.Ah $/ / /MM
 .f55jA&IH4!4  M  
	'/6!%((=8  M .4NNKKKK#0#?#?_ $@ $ $  3'''*>>>&&rM   )NN)<__name__
__module____qualname____doc__r0   rR   rp   r   rP   r   __annotations__rq   rr   rv   r   r1   rx   ry   boolr|   intr}   floatr~   r   r   r   r/   model_configr2   classmethodr   propertyr   r   r   r	   r   r   r   r#   r   r   r   r   r"   r   r   r   r   r   r   r.   r   r'   r$   r   r   r  __classcell__)r   s   @rK   rn   rn      su        } }~ #(%"="="=Kc3h===@ $)5#>#>#>L$sCx.>>>8FC ',eD	&J&J&JJ#JJJ&+eD&M&M&MJ#MMM %Ix~%%%/%*U2Y%?%?%?OXc]???0 E8E?   '#'K%'''+%&M8E?&&& !5...E8C=... #Hhsm"""E:  L _(###)$ )3 ) ) ) [ $#)V 
T#s(^ 
 
 
 
 
 X
 $3 $ $ $ X$ 6c3h 6 6 6 X6#
{##
 #
 
c3h	#
 #
 #
 #
P %):>	=D =D{#=D tCy!=D 67	=D
 =D 
=D =D =D =DD %)?C	5J 5J{#5J tCy!5J ;<	5J
 5J 
5J 5J 5J 5Jt %):>	# #{## tCy!# 67	#
 # 
%	&# # # #P %)?C	# #{## tCy!# ;<	#
 # 
*	+# # # #JAd38nd9oxQRSA A 
$k1	2	A A A A A A2 "	A' A' A'dDO+,A' 	A'
 A' 
$eD)O&<<	=A' A' A' A' A' A' A' A'rM   rn   )LrC   loggingrg   operatorr   typingr   r   r   r   r   r	   r
   r   r   r   r   r   langchain_core.callbacksr   r   langchain_core.language_modelsr   *langchain_core.language_models.chat_modelsr   langchain_core.messagesr   r   r   r   r   r   r   r   langchain_core.messages.air   langchain_core.messages.toolr   "langchain_core.output_parsers.baser   *langchain_core.output_parsers.openai_toolsr   r    langchain_core.outputsr!   r"   r#   langchain_core.runnablesr$   r%   r&   langchain_core.toolsr'   langchain_core.utilsr(   r)   %langchain_core.utils.function_callingr+   langchain_core.utils.pydanticr,   r-   pydanticr.   r/   r0   r1   r2   	getLoggerr  loggerrR   rL   rP   rE   rl   rn   r   rM   rK   <module>r#     s                                              > = = = = = D D D D D D	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 5 4 4 4 4 4 8 8 8 8 8 8 ? ? ? ? ? ?        S R R R R R R R R R O O O O O O O O O O ) ) ) ) ) ) L L L L L L L L H H H H H H K K K K K K K K              
	8	$	$[ T    :4%T%T#s(^8K2L-M(M"N 4SV 4 4 4 4/GCH$5 /) / / / /dq
' q
' q
' q
' q
'- q
' q
' q
' q
' q
'rM   