
    Ng                       d Z ddlmZ ddlZddlZddlZddlmZmZ ddl	m
Z
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mZmZ ddlmZmZ dd	lmZ dd
lmZm Z 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- ddl.m/Z/ ddl0m1Z1m2Z2 ddl3m4Z4m5Z5m6Z6 ddl7m8Z8m9Z9m:Z: ddl;m<Z< ddl=m>Z> ddl?m@Z@ ddlAmBZBmCZCmDZDmEZE  ejF        eG          ZHdZIdZJd5dZKed6d!            ZLe
d7d#            ZMd8d%ZNd9d)ZOd:d+ZPd;d/ZQd<d2ZR G d3 d4e          ZSdS )=zZhipuAI chat models wrapper.    )annotationsN)AsyncIteratorIterator)asynccontextmanagercontextmanager)
itemgetter)
AnyCallableDictListLiteralOptionalSequenceTupleTypeUnion)AsyncCallbackManagerForLLMRunCallbackManagerForLLMRun)LanguageModelInput)BaseChatModelagenerate_from_streamgenerate_from_stream)	AIMessageAIMessageChunkBaseMessageBaseMessageChunkChatMessageChatMessageChunkHumanMessageHumanMessageChunkSystemMessageSystemMessageChunkToolMessage)OutputParserLike)JsonOutputKeyToolsParserPydanticToolsParser)ChatGenerationChatGenerationChunk
ChatResult)RunnableRunnableMapRunnablePassthrough)BaseTool)get_from_dict_or_envconvert_to_openai_tool)	BaseModel
ConfigDictFieldmodel_validator   z5https://open.bigmodel.cn/api/paas/v4/chat/completionsobjr	   returnboolc                V    t          | t                    ot          | t                    S N)
isinstancetype
issubclassr1   )r6   s    c/var/www/html/ai-engine/env/lib/python3.11/site-packages/langchain_community/chat_models/zhipuai.py_is_pydantic_classr?   A   s!    c4  ?ZY%?%??    clientmethodstrurlkwargsr   c              +     K   ddl m}  | j        ||fi |5 } ||          V  ddd           dS # 1 swxY w Y   dS )zContext manager for connecting to an SSE stream.

    Args:
        client: The HTTP client.
        method: The HTTP method.
        url: The URL.
        kwargs: Additional keyword arguments.

    Yields:
        The event source.
    r   EventSourceN	httpx_sserH   streamrA   rB   rD   rE   rH   responses         r>   connect_sserN   E   s       &%%%%%	vs	-	-f	-	- $k(#####$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $s   377r   c                  K   ddl m}  | j        ||fi |4 d{V } ||          W V  ddd          d{V  dS # 1 d{V swxY w Y   dS )zAsync context manager for connecting to an SSE stream.

    Args:
        client: The HTTP client.
        method: The HTTP method.
        url: The URL.
        kwargs: Additional keyword arguments.

    Yields:
        The event source.
    r   rG   NrI   rL   s         r>   aconnect_sserP   X   s
      &%%%%%v}VS33F33 $ $ $ $ $ $ $xk(######$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $s   A  
A
A
api_keyc                   	 ddl }n# t          $ r t          d          w xY w	 |                     d          \  }}n%# t          $ r}t          d|            |d}~ww xY w|t	          t          t          j                    dz                      t          dz  z   t	          t          t          j                    dz                      d}|                    ||ddd	d
          S )zGets JWT token for ZhipuAI API.

    See 'https://open.bigmodel.cn/dev/api#nosdk'.

    Args:
        api_key: The API key for ZhipuAI API.

    Returns:
        The JWT token.
    r   Nz@jwt package not found, please install it with`pip install pyjwt`.zInvalid API key: i  )rQ   exp	timestampHS256SIGN)alg	sign_type)	algorithmheaders)	jwtImportErrorsplit
ValueErrorintroundtimeAPI_TOKEN_TTL_SECONDSencode)rQ   r\   idsecreterrpayloads         r>   _get_jwt_tokenri   m   s$   




 
 
 
Q
 
 	


A]]3''
FF A A A6W6677S@A 5t+,,--0E0LLty{{T12233 G ::f55	    s    !> 
A AA dctDict[str, Any]r   c                   |                      d          }|                      dd          }|dk    rt          |          S |dk    rt          |          S |dk    r0i }|                      dd           }|||d<   t          ||	          S |d
k    r6i }d| v r| d         |d<   t	          ||                      d          |          S t          ||          S )Nrolecontent systemrn   user	assistant
tool_callsrn   additional_kwargstoolnametool_call_id)rn   ry   rv   rm   rn   )getr!   r   r   r#   r   )rj   rm   rn   rv   rt   s        r>   _convert_dict_to_messager|      s   776??Dggi$$GxW----v~~G,,,,{WW\400
!.8l+<MNNNNv~~S==(+Ff%00/
 
 
 	

 D'2222r@   messagec                   t          | t                    r| j        | j        d}nt          | t                    rd| j        d}nt          | t
                    rd| j        d}nt          | t                    rd| j        d}nct          | t                    r1d| j        | j        | j	        p| j
                            d          d}nt          d| j        j         d	          |S )
zConvert a LangChain message to a dictionary.

    Args:
        message: The LangChain message.

    Returns:
        The dictionary.
    rz   rp   rr   rs   rw   rx   )rm   rn   ry   rx   zGot unknown type 'z'.)r;   r   rm   rn   r!   r   r   r#   ry   rx   rv   r{   	TypeError	__class____name__)r}   message_dicts     r>   _convert_message_to_dictr      s    ';'' M 'II	G]	+	+ M (W_EE	G\	*	* M &7?CC	GY	'	' 
M +HH	G[	)	) M#0LIG$=$A$A&$I$I	
 
 KW->-GKKKLLLr@   default_classType[BaseMessageChunk]r   c                   |                      d          }|                      dd          }i }|                      dd           }|||d<   |dk    s|t          k    rt          |          S |dk    s|t          k    rt          |          S |dk    s|t          k    rt          ||	          S |s|t          k    rt	          ||
          S  ||          S )Nrm   rn   ro   rt   rp   rq   rr   rs   ru   )rn   rm   )r{   r"   r    r   r   )rj   r   rm   rn   rv   rt   s         r>   _convert_delta_to_message_chunkr      s     776??Dggi$$Gt,,J*4,'x=,>>>!'2222v~~*;;; 1111{m~==gARSSSS <} 000d;;;;=))))r@   rh   Nonec                    |                      d          }|                      d          }|!t          dt          d|                    | d<   |#t          dt          d|                    | d<   dS dS )zTruncate temperature and top_p parameters between [0.01, 0.99].

    ZhipuAI only support temperature / top_p between (0, 1) open interval,
    so we truncate them to [0.01, 0.99].
    temperaturetop_pNg{Gz?gGz?)r{   maxmin)rh   r   r   s      r>   _truncate_paramsr      s|     ++m,,KKK  E!$T3t[+A+A!B!BtSu%5%566 r@   c                      e Zd ZU dZedMd            ZedNd            ZedOd            ZedPd
            Z	edOd            Z
 edd          Zded<   	  edd          Zded<   	  edd          Zded<   	 dZded<   	 dZded<   	 dZded<   	 dZded<   	  ed !          Z ed"#          edQd&                        ZdRd,ZdSd0Z	 	 	 dTdUd6Z	 	 dVdWd8Z	 	 	 dTdXd:Z	 	 dVdYd<Zdd=dZdCZ	 d[dDddEd\dLZdS )]ChatZhipuAIu  ZhipuAI chat model integration.

    Setup:
        Install ``PyJWT`` and set environment variable ``ZHIPUAI_API_KEY``

        .. code-block:: bash

            pip install pyjwt
            export ZHIPUAI_API_KEY="your-api-key"

    Key init args — completion params:
        model: Optional[str]
            Name of ZhipuAI model to use.
        temperature: float
            Sampling temperature.
        max_tokens: Optional[int]
            Max number of tokens to generate.

    Key init args — client params:
        api_key: Optional[str]
            ZhipuAI API key. If not passed in will be read from env var ZHIPUAI_API_KEY.
        api_base: Optional[str]
            Base URL for API requests.

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

    Instantiate:
        .. code-block:: python

            from langchain_community.chat_models import ChatZhipuAI

            zhipuai_chat = ChatZhipuAI(
                temperature=0.5,
                api_key="your-api-key",
                model="glm-4",
                # api_base="...",
                # other params...
            )

    Invoke:
        .. code-block:: python

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

        .. code-block:: python

            AIMessage(content='I enjoy programming.', response_metadata={'token_usage': {'completion_tokens': 6, 'prompt_tokens': 23, 'total_tokens': 29}, 'model_name': 'glm-4', 'finish_reason': 'stop'}, id='run-c5d9af91-55c6-470e-9545-02b2fa0d7f9d-0')

    Stream:
        .. code-block:: python

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

        .. code-block:: python

            content='I' id='run-4df71729-618f-4e2b-a4ff-884682723082'
            content=' enjoy' id='run-4df71729-618f-4e2b-a4ff-884682723082'
            content=' programming' id='run-4df71729-618f-4e2b-a4ff-884682723082'
            content='.' id='run-4df71729-618f-4e2b-a4ff-884682723082'
            content='' response_metadata={'finish_reason': 'stop'} id='run-4df71729-618f-4e2b-a4ff-884682723082'

        .. code-block:: python

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

        .. code-block::

            AIMessageChunk(content='I enjoy programming.', response_metadata={'finish_reason': 'stop'}, id='run-20b05040-a0b4-4715-8fdc-b39dba9bfb53')

    Async:
        .. code-block:: python

            await zhipuai_chat.ainvoke(messages)

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

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

        .. code-block:: python

            [AIMessage(content='I enjoy programming.', response_metadata={'token_usage': {'completion_tokens': 6, 'prompt_tokens': 23, 'total_tokens': 29}, 'model_name': 'glm-4', 'finish_reason': 'stop'}, id='run-ba06af9d-4baa-40b2-9298-be9c62aa0849-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 = zhipuai_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': 'call_202408222146464ea49ec8731145a9',
                    'type': 'tool_call'
                }
            ]

    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 = zhipuai_chat.with_structured_output(Joke)
            structured_chat.invoke("Tell me a joke about cats")

        .. code-block:: python

            Joke(setup='What do cats like to eat for breakfast?', punchline='Mice Krispies!', rating=None)

    Response metadata
        .. code-block:: python

            ai_msg = zhipuai_chat.invoke(messages)
            ai_msg.response_metadata

        .. code-block:: python

            {'token_usage': {'completion_tokens': 6,
              'prompt_tokens': 23,
              'total_tokens': 29},
              'model_name': 'glm-4',
              'finish_reason': 'stop'}

    r7   Dict[str, str]c                
    ddiS )Nzhipuai_api_keyZHIPUAI_API_KEY selfs    r>   
lc_secretszChatZhipuAI.lc_secrets  s    !#455r@   	List[str]c                
    g dS )z*Get the namespace of the langchain object.)	langchainchat_modelszhipuair   )clss    r>   get_lc_namespacezChatZhipuAI.get_lc_namespace  s     7666r@   rk   c                ,    i }| j         r
| j         |d<   |S )Nzhipuai_api_base)r   )r   
attributess     r>   lc_attributeszChatZhipuAI.lc_attributes  s'    %'
  	C-1-BJ)*r@   rC   c                    dS )zReturn the type of chat model.zzhipuai-chatr   r   s    r>   	_llm_typezChatZhipuAI._llm_type  s	     ~r@   c                R    | j         | j        | j        d}| j        
| j        |d<   |S )z2Get the default parameters for calling OpenAI API.)modelrK   r   N
max_tokens)
model_name	streamingr   r   )r   paramss     r>   _default_paramszChatZhipuAI._default_params  s;     _n+
 

 ?&#'?F< r@   NrQ   )defaultaliaszOptional[str]r   api_baser   zglm-4r   r   gffffff?floatr   gffffff?r   Fr8   r   zOptional[int]r   T)populate_by_namebefore)modevaluesr	   c                h    t          |ddgd          |d<   t          |ddt                    |d<   |S )Nr   rQ   r   r   ZHIPUAI_API_BASE)r   )r.   r   )r   r   s     r>   validate_environmentz ChatZhipuAI.validate_environment  sV     %9&	24E%
 %
 ! &:&(:DT&
 &
 &
!" r@   messagesList[BaseMessage]stopOptional[List[str]]+Tuple[List[Dict[str, Any]], Dict[str, Any]]c                >    | j         }|||d<   d |D             }||fS )Nr   c                ,    g | ]}t          |          S r   )r   ).0ms     r>   
<listcomp>z5ChatZhipuAI._create_message_dicts.<locals>.<listcomp>  s!    GGG1!44GGGr@   )r   )r   r   r   r   message_dictss        r>   _create_message_dictsz!ChatZhipuAI._create_message_dicts  s9     %!F6NGGhGGGf$$r@   rM   Union[dict, BaseModel]r)   c                   g }t          |t                    s|                                }|d         D ]^}t          |d                   }t          |                    d                    }|                    t          ||                     _|                    di           }|| j        d}t          ||          S )	Nchoicesr}   finish_reason)r   r}   generation_infousage)token_usager   )generations
llm_output)r;   dictr|   r{   appendr'   r   r)   )r   rM   r   resr}   r   r   r   s           r>   _create_chat_resultzChatZhipuAI._create_chat_result  s    (D)) 	'}}HI& 	 	C.s9~>>G"1I1IJJJOwPPP    ll7B//&/
 

 kjIIIIr@   run_manager"Optional[CallbackManagerForLLMRun]rK   Optional[bool]rE   c                0   ||n| j         }|r  | j        |f||d|}t          |          S | j        t	          d          |                     ||          \  }}	i |	||dd}
t          |
           t          | j                  dd}ddl}|	                    |d	
          5 }|
                    | j        |
          }|                                 ddd           n# 1 swxY w Y   |                     |                                          S )zGenerate a chat response.Nr   r   Did not find zhipuai_api_key.Fr   rK   application/jsonAuthorizationAcceptr   <   r[   timeoutjson)r   _streamr   r   r_   r   r   ri   httpxClientpostr   raise_for_statusr   r   r   r   r   r   rK   rE   should_streamstream_iterr   r   rh   r[   r   rA   rM   s                  r>   	_generatezChatZhipuAI._generate  s    #)"4$. 	5&$,# @F K (444'<=== $ : :8T J Jv


 &	
 
 
 	!!!+D,@AA(
 
 	\\'2\66 	(&{{4#8w{GGH%%'''	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( ''888s   )1C&&C*-C*Iterator[ChatGenerationChunk]c              +    K   | j         t          d          | j        t          d          |                     ||          \  }}i |||dd}t	          |           t          | j                   dd}t          }	ddl}
|
                    |d	
          5 }t          |d| j        |          5 }|
                                D ]}t          j        |j                  }t          |d                   dk    r5|d         d         }|                    dd          }|                    dd          }t!          |d         |	          }|                    dd          }||||dnd}t#          ||          }|r|                    |j        |           |V  | nddd           n# 1 swxY w Y   ddd           dS # 1 swxY w Y   dS )z#Stream the chat response in chunks.Nr   Did not find zhipu_api_base.Tr   r   r   r   r   r   POSTr   r   r   r   ro   deltar   r   r   r   r   chunk)r   r_   r   r   r   ri   r   r   r   rN   iter_sser   loadsdatalenr{   r   r(   on_llm_new_tokentextr   r   r   r   rE   r   r   rh   r[   default_chunk_classr   rA   event_sourcesser   choicer   r   r   r   s                       r>   r   zChatZhipuAI._stream2  s      '<=== (;<<< $ : :8T J JvQVQvQ=DQQQ!!!+D,@AA(
 

 -\\'2\66 !	& 5G    '0022  C Jsx00E5+,,11 "9-a0F!IIgt44E!&7B!7!7J;w)< E %+JJ$E$EM )4	 .;+0*4   " $ 0 %  E # N#44UZu4MMMKKK$0 1?                             !	 !	 !	 !	 !	 !	 !	 !	 !	 !	 !	 !	 !	 !	 !	 !	 !	 !	s7   G
4C2F2&G
2F6	6G
9F6	:G

GG'Optional[AsyncCallbackManagerForLLMRun]c                p  K   ||n| j         }|r& | j        |f||d|}t          |           d {V S | j        t	          d          |                     ||          \  }}	i |	||dd}
t          |
           t          | j                  dd}dd l}|	                    |d	          4 d {V }|
                    | j        |

           d {V }|                                 d d d           d {V  n# 1 d {V swxY w Y   |                     |                                          S )Nr   r   Fr   r   r   r   r   r   r   )r   _astreamr   r   r_   r   r   ri   r   AsyncClientr   r   r   r   r   r   s                  r>   
_ageneratezChatZhipuAI._ageneratel  s&      #)"4$. 	<'$-# @F K /{;;;;;;;;;'<=== $ : :8T J Jv


 &	
 
 
 	!!!+D,@AA(
 
 	$$Wb$AA 	( 	( 	( 	( 	( 	( 	(V#[[)>W[MMMMMMMMH%%'''	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( ''888s   77D  
D
D
"AsyncIterator[ChatGenerationChunk]c                 K   | j         t          d          | j        t          d          |                     ||          \  }}i |||dd}t	          |           t          | j                   dd}t          }	dd l}
|
                    |d	          4 d {V }t          |d
| j        |          4 d {V 	 }|
                                2 3 d {V }t          j        |j                  }t          |d                   dk    r:|d         d         }|                    dd           }|                    dd          }t!          |d         |	          }|                    dd           }||||dnd }t#          ||          }|r"|                    |j        |           d {V  |W V  | n6 	 d d d           d {V  n# 1 d {V swxY w Y   d d d           d {V  d S # 1 d {V swxY w Y   d S )Nr   r   Tr   r   r   r   r   r   r   r   r   r   r   ro   r   r   r   r   r   )r   r_   r   r   r   ri   r   r   r  rP   	aiter_sser   r   r   r   r{   r   r(   r   r   r   s                       r>   r   zChatZhipuAI._astream  s      '<=== (;<<< $ : :8T J JvQVQvQ=DQQQ!!!+D,@AA(
 

 -$$Wb$AA !	 !	 !	 !	 !	 !	 !	V# 5G                  !-!7!7!9!9       # Jsx00E5+,,11 "9-a0F!IIgt44E!&7B!7!7J;w)< E %+JJ$E$EM )4	 .;+0*4   " $ 0 %  E # T)::5:U:SSSSSSSSSKKKK$0 19 ":!9                                                     !	 !	 !	 !	 !	 !	 !	 !	 !	 !	 !	 !	 !	 !	 !	 !	 !	 !	 !	 !	 !	 !	 !	 !	 !	 !	 !	 !	 !	 !	sC   !G7GF?C$GG7
G	G7 G	!G77
HHtool_choicetoolsDSequence[Union[Dict[str, Any], Type[BaseModel], Callable, BaseTool]]r  @Optional[Union[dict, str, Literal['auto', 'any', 'none'], bool]])Runnable[LanguageModelInput, BaseMessage]c                   | j         dk    rt          d          d |D             }|r|dk    rt          d          |r|dk    r||d<    | j        dd|i|S )	a=  Bind tool-like objects to this chat model.
        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.
            tool_choice: Currently this can only be auto for this chat model.
            **kwargs: Any additional parameters to pass to the
                :class:`~langchain.runnable.Runnable` constructor.
        zglm-4vz.glm-4v currently does not support tool callingc                ,    g | ]}t          |          S r   r/   )r   rw   s     r>   r   z*ChatZhipuAI.bind_tools.<locals>.<listcomp>  s!    JJJD1$77JJJr@   autoz6ChatZhipuAI currently only supports `auto` tool choicer  r  r   )r   r_   bind)r   r  r  rE   formatted_toolss        r>   
bind_toolszChatZhipuAI.bind_tools  s    & ?h&&MNNNJJEJJJ 	0;&00UVVV 	0[F22$/F=!ty999&999r@   function_calling)rB   include_rawschema&Optional[Union[Dict, Type[BaseModel]]]rB   (Literal['function_calling', 'json_mode']r  4Runnable[LanguageModelInput, Union[Dict, BaseModel]]c               .   |rt          d|           t          |          }|dk    rk|t          d          t          |          d         d         }|                     |gd          }|rt	          |gd	
          }n%t          |d	          }nt          d| 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.
            method: The method for steering model generation, either "function_calling"
                or "json_mode". ZhipuAI only supports "function_calling" which
                converts the schema to a OpenAI function and the model will make use of the
                function-calling API.
            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_community.chat_models import ChatZhipuAI
                from pydantic import BaseModel

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

                llm = ChatZhipuAI(temperature=0)
                structured_llm = llm.with_structured_output(AnswerWithJustification)

                structured_llm.invoke("What weighs more a pound of bricks or a pound of feathers")
                # -> AnswerWithJustification(
                #     answer='A pound of bricks and a pound of feathers weigh the same.'
                #     justification="Both a pound of bricks and a pound of feathers have been defined to have the same weight. The 'pound' is a unit of weight, so any two things that are described as weighing a pound will weigh the same."
                # )

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

                from langchain_community.chat_models import ChatZhipuAI
                from pydantic import BaseModel

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

                llm = ChatZhipuAI(temperature=0)
                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_01htjn3cspevxbqc1d7nkk8wab', 'function': {'arguments': '{"answer": "A pound of bricks and a pound of feathers weigh the same.", "justification": "Both a pound of bricks and a pound of feathers have been defined to have the same weight. The 'pound' is a unit of weight, so any two things that are described as weighing a pound will weigh the same.", "unit": "pounds"}', 'name': 'AnswerWithJustification'}, 'type': 'function'}]}, id='run-456beee6-65f6-4e80-88af-a6065480822c-0'),
                #     'parsed': AnswerWithJustification(answer='A pound of bricks and a pound of feathers weigh the same.', justification="Both a pound of bricks and a pound of feathers have been defined to have the same weight. The 'pound' is a unit of weight, so any two things that are described as weighing a pound will weigh the same."),
                #     'parsing_error': None
                # }

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

                from langchain_community.chat_models import ChatZhipuAI
                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 = ChatZhipuAI(temperature=0)
                structured_llm = llm.with_structured_output(dict_schema)

                structured_llm.invoke("What weighs more a pound of bricks or a pound of feathers")
                # -> {
                #     'answer': 'A pound of bricks and a pound of feathers weigh the same.',
                #     'justification': "Both a pound of bricks and a pound of feathers have been defined to have the same weight. The 'pound' is a unit of weight, so any two things that are described as weighing a pound will weigh the same.", 'unit': 'pounds'}
                # }

        zReceived unsupported arguments r  NzJschema must be specified when method is 'function_calling'. Received None.functionrx   r  r  T)r  first_tool_only)key_namer  zVUnrecognized method argument. Expected 'function_calling'.
                Received: ''rawc                    d S r:   r   _s    r>   <lambda>z4ChatZhipuAI.with_structured_output.<locals>.<lambda>n  s    RV r@   )parsedparsing_errorc                    d S r:   r   r  s    r>   r!  z4ChatZhipuAI.with_structured_output.<locals>.<lambda>p  s    d r@   )r"  r#  )exception_key)r  )r_   r?   r0   r  r&   r%   r,   assignr   with_fallbacksr+   )r   r  rB   r  rE   is_pydantic_schema	tool_namellmoutput_parserparser_assignparser_noneparser_with_fallbacks               r>   with_structured_outputz"ChatZhipuAI.with_structured_output  s   X  	IGvGGHHH/77'''~ %   /v66zB6JI//6(/??C! 2E!($(3 3 3
 !9&! ! ! ("( ( (  
  
	'/6!%((=8  M .4NNKKKK#0#?#?_ $@ $ $  3'''*>>>&&r@   )r7   r   )r7   r   )r7   rk   )r7   rC   )r   rk   r7   r	   )r   r   r   r   r7   r   )rM   r   r7   r)   )NNN)r   r   r   r   r   r   rK   r   rE   r	   r7   r)   )NN)
r   r   r   r   r   r   rE   r	   r7   r   )r   r   r   r   r   r   rK   r   rE   r	   r7   r)   )
r   r   r   r   r   r   rE   r	   r7   r  )r  r	  r  r
  rE   r	   r7   r  r:   )
r  r  rB   r  r  r8   rE   r	   r7   r  ) r   
__module____qualname____doc__propertyr   classmethodr   r   r   r   r3   r   __annotations__r   r   r   r   r   r   r2   model_configr4   r   r   r   r   r   r  r   r  r/  r   r@   r>   r   r      s        i iV 6 6 6 X6 7 7 7 [7    X    X 	 	 	 X	 &+U4y%I%I%IOIIIIP&+eD
&K&K&KKKKK !&gW E E EJEEEE
 K E I/ $J$$$$/:  L _(###   [ $#% % % %J J J J( %):>!%#9 #9 #9 #9 #9P %):>	8 8 8 8 8z %)?C!%"9 "9 "9 "9 "9N %)?C	7 7 7 7 7~ : : : : : :> :>P' <N!P' P' P' P' P' P' P' P'r@   r   )r6   r	   r7   r8   )
rA   r	   rB   rC   rD   rC   rE   r	   r7   r   )
rA   r	   rB   rC   rD   rC   rE   r	   r7   r   )rQ   rC   r7   rC   )rj   rk   r7   r   )r}   r   r7   rk   )rj   rk   r   r   r7   r   )rh   rk   r7   r   )Tr2  
__future__r   r   loggingrb   collections.abcr   r   
contextlibr   r   operatorr   typingr	   r
   r   r   r   r   r   r   r   r   langchain_core.callbacksr   r   langchain_core.language_modelsr   *langchain_core.language_models.chat_modelsr   r   r   langchain_core.messagesr   r   r   r   r   r   r   r    r!   r"   r#   "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.   %langchain_core.utils.function_callingr0   pydanticr1   r2   r3   r4   	getLoggerr   loggerrc   r   r?   rN   rP   ri   r|   r   r   r   r   r   r@   r>   <module>rK     s   " " " " " " " "    3 3 3 3 3 3 3 3 : : : : : : : :                                     > = = = = =         
                          @ ? ? ? ? ?        S R R R R R R R R R O O O O O O O O O O ) ) ) ) ) ) 5 5 5 5 5 5 H H H H H H B B B B B B B B B B B B		8	$	$ J @ @ @ @ $ $ $ $$ $ $ $ $(" " " "J3 3 3 32   <* * * **7 7 7 7J
' J
' J
' J
' J
'- J
' J
' J
' J
' J
'r@   