
    @'hb                    8   d Z ddlm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mZmZmZ ddl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" 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/m0Z0m1Z1m2Z2m3Z3 ddl4m5Z5m6Z6 ddl7m8Z8 ddl9m:Z:m;Z;m<Z<m=Z= ddl>m?Z?m@Z@mAZA ddlBmCZCmDZDmEZE ddlFmGZG ddlHmIZImJZJmKZK ddlLmMZMmNZN ddlOmPZP ddlQmRZRmSZSmTZTmUZUmVZV ddlWmXZX ddlYmZZZ  G d de      Z[d!dZ\ G d de      Z]d"dZ^	 	 	 	 	 	 d#dZ_d$dZ`d%dZa	 	 	 	 d&d Zby)'zGroq Chat wrapper.    )annotationsN)
itemgetter)AnyAsyncIteratorCallableDictIteratorListLiteralMappingOptionalSequenceTupleType	TypedDictUnioncast)
deprecated)AsyncCallbackManagerForLLMRunCallbackManagerForLLMRun)LanguageModelInput)BaseChatModelLangSmithParamsagenerate_from_streamgenerate_from_stream)	AIMessageAIMessageChunkBaseMessageBaseMessageChunkChatMessageChatMessageChunkFunctionMessageFunctionMessageChunkHumanMessageHumanMessageChunkInvalidToolCallSystemMessageSystemMessageChunkToolCallToolMessageToolMessageChunk)JsonOutputParserPydanticOutputParser)OutputParserLike)JsonOutputKeyToolsParserPydanticToolsParsermake_invalid_tool_callparse_tool_call)ChatGenerationChatGenerationChunk
ChatResult)RunnableRunnableMapRunnablePassthrough)BaseTool)from_envget_pydantic_field_namessecret_from_env)convert_to_openai_functionconvert_to_openai_tool)is_basemodel_subclass)	BaseModel
ConfigDictField	SecretStrmodel_validator)Self)__version__c                      e Zd ZU dZ edd      Zded<    edd      Zded<    ed	      Zd
ed<   	 dZ	ded<   	  edd      Z
ded<   	  ee      Zded<   	  ed edd            Zded<   	  ed edd            Zded<   	  e 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.<   	 dZd/ed0<   dZd1ed2<   dZd3ed4<   	 dZd3ed5<   	  ed6      Z ed78      edTd9              Z ed:8      dUd;       Z e!dVd<       Z"edWd=       Z#e!dXd>       Z$	 dY	 	 	 	 	 dZd?Z%dd@	 	 	 	 	 	 	 d[ fdAZ&	 	 d\	 	 	 	 	 	 	 	 	 d]dBZ'	 	 d\	 	 	 	 	 	 	 	 	 d^dCZ(	 	 d\	 	 	 	 	 	 	 	 	 d_dDZ)	 	 d\	 	 	 	 	 	 	 	 	 d`dEZ*e!dadF       Z+dbdGZ,	 	 	 	 	 	 dcdHZ-dddIZ. e/dJdKdLM      	 dY	 	 	 	 	 	 	 de fdN       Z0ddO	 	 	 	 	 	 	 df fdPZ1	 dYdQd(dR	 	 	 	 	 	 	 	 	 dgdSZ2 xZ3S )hChatGroqu  `Groq` Chat large language models API.

    To use, you should have the
    environment variable ``GROQ_API_KEY`` set with your API key.

    Any parameters that are valid to be passed to the groq.create call
    can be passed in, even if not explicitly saved on this class.

    Setup:
        Install ``langchain-groq`` and set environment variable
        ``GROQ_API_KEY``.

        .. code-block:: bash

            pip install -U langchain-groq
            export GROQ_API_KEY="your-api-key"

    Key init args — completion params:
        model: str
            Name of Groq model to use. E.g. "llama-3.1-8b-instant".
        temperature: float
            Sampling temperature. Ranges from 0.0 to 1.0.
        max_tokens: Optional[int]
            Max number of tokens to generate.
        model_kwargs: Dict[str, Any]
            Holds any model parameters valid for create call not
            explicitly specified.

    Key init args — client params:
        timeout: Union[float, Tuple[float, float], Any, None]
            Timeout for requests.
        max_retries: int
            Max number of retries.
        api_key: Optional[str]
            Groq API key. If not passed in will be read from env var GROQ_API_KEY.
        base_url: Optional[str]
            Base URL path for API requests, leave blank if not using a proxy
            or service emulator.
        custom_get_token_ids: Optional[Callable[[str], List[int]]]
            Optional encoder to use for counting tokens.

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

    Instantiate:
        .. code-block:: python

            from langchain_groq import ChatGroq

            llm = ChatGroq(
                model="llama-3.1-8b-instant",
                temperature=0.0,
                max_retries=2,
                # other params...
            )

    Invoke:
        .. code-block:: python

            messages = [
                ("system", "You are a helpful translator. Translate the user
                sentence to French."),
                ("human", "I love programming."),
            ]
            llm.invoke(messages)

        .. code-block:: python

            AIMessage(content='The English sentence "I love programming" can
            be translated to French as "J'aime programmer". The word
            "programming" is translated as "programmer" in French.',
            response_metadata={'token_usage': {'completion_tokens': 38,
            'prompt_tokens': 28, 'total_tokens': 66, 'completion_time':
            0.057975474, 'prompt_time': 0.005366091, 'queue_time': None,
            'total_time': 0.063341565}, 'model_name': 'llama-3.1-8b-instant',
            'system_fingerprint': 'fp_c5f20b5bb1', 'finish_reason': 'stop',
            'logprobs': None}, id='run-ecc71d70-e10c-4b69-8b8c-b8027d95d4b8-0')

    Stream:
        .. code-block:: python

            for chunk in llm.stream(messages):
                print(chunk.text(), end="")

        .. code-block:: python

            content='' id='run-4e9f926b-73f5-483b-8ef5-09533d925853'
            content='The' id='run-4e9f926b-73f5-483b-8ef5-09533d925853'
            content=' English' id='run-4e9f926b-73f5-483b-8ef5-09533d925853'
            content=' sentence' id='run-4e9f926b-73f5-483b-8ef5-09533d925853'
            ...
            content=' program' id='run-4e9f926b-73f5-483b-8ef5-09533d925853'
            content='".' id='run-4e9f926b-73f5-483b-8ef5-09533d925853'
            content='' response_metadata={'finish_reason': 'stop'}
            id='run-4e9f926b-73f5-483b-8ef5-09533d925853

        .. code-block:: python

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

        .. code-block:: python

            AIMessageChunk(content='The English sentence "I love programming"
            can be translated to French as "J'aime programmer".
            Here's the breakdown of the sentence:

* "J'aime" is the
            French equivalent of "I love"
* "programmer" is the French
            infinitive for "to program"

So, the literal translation
            is "I love to program". However, in English we often omit the
            "to" when talking about activities we love, and the same applies
            to French. Therefore, "J'aime programmer" is the correct and
            natural way to express "I love programming" in French.',
            response_metadata={'finish_reason': 'stop'},
            id='run-a3c35ac4-0750-4d08-ac55-bfc63805de76')

    Async:
        .. code-block:: python

            await llm.ainvoke(messages)

        .. code-block:: python

           AIMessage(content='The English sentence "I love programming" can
           be translated to French as "J'aime programmer". The word
           "programming" is translated as "programmer" in French. I hope
           this helps! Let me know if you have any other questions.',
           response_metadata={'token_usage': {'completion_tokens': 53,
           'prompt_tokens': 28, 'total_tokens': 81, 'completion_time':
           0.083623752, 'prompt_time': 0.007365126, 'queue_time': None,
           'total_time': 0.090988878}, 'model_name': 'llama-3.1-8b-instant',
           'system_fingerprint': 'fp_c5f20b5bb1', 'finish_reason': 'stop',
           'logprobs': None}, id='run-897f3391-1bea-42e2-82e0-686e2367bcf8-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")

            model_with_tools = llm.bind_tools([GetWeather, GetPopulation])
            ai_msg = model_with_tools.invoke("What is the population of NY?")
            ai_msg.tool_calls

        .. code-block:: python

            [{'name': 'GetPopulation',
            'args': {'location': 'NY'},
            'id': 'call_bb8d'}]

        See ``ChatGroq.bind_tools()`` method for more.

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

        .. code-block:: python

            Joke(setup="Why don't cats play poker in the jungle?",
            punchline='Too many cheetahs!', rating=None)

        See ``ChatGroq.with_structured_output()`` for more.

    Response metadata
        .. code-block:: python

            ai_msg = llm.invoke(messages)
            ai_msg.response_metadata

        .. code-block:: python

            {'token_usage': {'completion_tokens': 70,
            'prompt_tokens': 28,
            'total_tokens': 98,
            'completion_time': 0.111956391,
            'prompt_time': 0.007518279,
            'queue_time': None,
            'total_time': 0.11947467},
            'model_name': 'llama-3.1-8b-instant',
            'system_fingerprint': 'fp_c5f20b5bb1',
            'finish_reason': 'stop',
            'logprobs': None}
    NT)defaultexcluder   clientasync_clientmodel)aliasstr
model_namegffffff?floattemperaturestop_sequences)rI   rN   zOptional[Union[List[str], str]]stop)default_factoryDict[str, Any]model_kwargsapi_keyGROQ_API_KEY)rI   )rN   rU   zOptional[SecretStr]groq_api_keybase_urlGROQ_API_BASEzOptional[str]groq_api_base
GROQ_PROXY
groq_proxytimeoutz,Union[float, Tuple[float, float], Any, None]request_timeout   intmax_retriesFbool	streaming   nzOptional[int]
max_tokenszUnion[Mapping[str, str], None]default_headersz!Union[Mapping[str, object], None]default_queryzUnion[Any, None]http_clienthttp_async_client)populate_by_namebefore)modec           
     `   t        |       }|j                  di       }t        |      D ]M  }||v rt        d| d      ||vst	        j
                  d| d| d| d       |j                  |      ||<   O |j                  |j                               }|rt        d| d	      ||d<   |S )
z>Build extra kwargs from additional params that were passed in.rW   zFound z supplied twice.z	WARNING! z/ is not default parameter.
                    zJ was transferred to model_kwargs.
                    Please confirm that z is what you intended.zParameters za should be specified explicitly. Instead they were passed in as part of `model_kwargs` parameter.)	r;   getlist
ValueErrorwarningswarnpopintersectionkeys)clsvaluesall_required_field_namesextra
field_nameinvalid_model_kwargss         a/home/kushmeetdev/Regenta/Chatbot/venv/lib/python3.12/site-packages/langchain_groq/chat_models.pybuild_extrazChatGroq.build_extrab  s     $<C#@ 

>2.v, 		;JU" 6*5E!FGG!99!* .L !))34JN
 %+JJz$:j!		;  8DDUZZ\R23 4S T 
 "'~    afterc                    | j                   dk  rt        d      | j                   dkD  r| j                  rt        d      | j                  dk(  rd| _        ddt         it        | j                  xs i       z  }| j                  r| j                  j                         nd| j                  | j                  | j                  || j                  d	}	 ddl}d
| j                  i}| j                  s- |j                   di ||j"                  j$                  | _        | j&                  s;d
| j(                  i} |j*                  di ||j"                  j$                  | _        | S # t,        $ r t-        d      w xY w)z?Validate that api key and python package exists in environment.rg   zn must be at least 1.zn must be 1 when streaming.r   g:0yE>z
User-Agentz
langchain/N)rX   r[   r`   rd   rj   rk   rl   zPCould not import groq python package. Please install it with `pip install groq`. )rh   rt   rf   rR   rF   dictrj   rZ   get_secret_valuer]   ra   rd   rk   groqrl   rK   GroqchatcompletionsrL   rm   	AsyncGroqImportError)selfrj   client_paramsr   sync_specificasync_specifics         r   validate_environmentzChatGroq.validate_environment}  s    66A:45566A:$..:;;q #D':k])CDt  &BH
 
 9=8I8I!!224t**++++.!//	)
	-:D<L<L,MM;;'dii #'4${{  $$2?AWAW1X$2DNN %#%'5%${{ !   	= 	s   BE( (E=c                
    ddiS )NrZ   rY   r   r   s    r   
lc_secretszChatGroq.lc_secrets  s    //r   c                     y)z9Return whether this model can be serialized by Langchain.Tr   )rz   s    r   is_lc_serializablezChatGroq.is_lc_serializable  s     r   c                     y)zReturn type of model.z	groq-chatr   r   s    r   	_llm_typezChatGroq._llm_type  s     r   c           	     V    | j                   d
d|i|}t        d| j                  d|j                  d| j                              }|j                  d| j
                        x}r||d<   |xs  |j                  dd      xs | j                  x}rt        |t              r|n|g|d	<   |S )z Get standard params for tracing.rT   r   r   rR   )ls_providerls_model_namels_model_typels_temperatureri   ls_max_tokensNls_stopr   )	_get_invocation_paramsr   rP   rr   rR   ri   rT   
isinstancers   )r   rT   kwargsparams	ls_paramsr   r   s          r   _get_ls_paramszChatGroq._get_ls_params  s     -,,A$A&A#// !::mT5E5EF	
	 #JJ|T__EE=E)6Io&Cfjj6C$))C7C.8$.G7gYIi r   )run_managerc               L    t        |   d||d|}|rd|v r
|d   ddik7  S |S )z=Determine if a given model call should hit the streaming API.)	async_apir   response_formattypejson_objectr   )super_should_stream)r   r   r   r   base_should_stream	__class__s        r   r   zChatGroq._should_stream  sP     #W3 
[
<B
 #4#>+,0GGG!!r   c                    | j                   r! | j                  |f||d|}t        |      S | j                  ||      \  }}i ||} | j                  j
                  dd|i|}| j                  |      S N)rT   r   messagesr   )rf   _streamr   _create_message_dictsrK   create_create_chat_result	r   r   rT   r   r   stream_itermessage_dictsr   responses	            r   	_generatezChatGroq._generate  s     >>&$,,#@FK (44 $ : :8T Jv


 &4;;%%G}GG''11r   c                   K   | j                   r) | j                  |f||d|}t        |       d {   S | j                  ||      \  }}i ||} | j                  j
                  dd|i| d {   }| j                  |      S 7 V7 wr   )rf   _astreamr   r   rL   r   r   r   s	            r   
_ageneratezChatGroq._agenerate  s      >>'$--#@FK /{;;; $ : :8T Jv


 2**11S=SFSS''11 < Ts"   1BB
A B4B5BBc              +  \  K   | j                  ||      \  }}i ||ddi}t        } | j                  j                  dd|i|D ]  }t	        |t
              s|j                         }t        |d         dk(  r5|d   d   }	t        ||      }
i }|	j                  d      x}r,||d<   | j                  |d<   |j                  d      x}r||d<   |	j                  d	      }|r||d	<   |
j                  }t        |
|xs d 
      }|r|j                  |j                  ||       |  y w)NstreamTr   choicesr   finish_reasonrP   system_fingerprintlogprobsmessagegeneration_info)chunkr   r   )r   r   rK   r   r   r   
model_dumplen_convert_chunk_to_message_chunkrr   rP   r   r4   on_llm_new_tokentextr   r   rT   r   r   r   r   default_chunk_classr   choicemessage_chunkr   r   r   r   generation_chunks                   r   r   zChatGroq._stream
  sh     !% : :8T Jv5F5f5h56D'T[[''II&I 	#EeT*((*5#$)9%a(F;ECVWM O &

? ;;};3@004-).3G)HH%H<NO$89zz*-H.6
+"/"9"92%7N$  ,,$))1AH -  #"3	#s   D*D,c                 K   | j                  ||      \  }}i ||ddi}t        } | j                  j                  dd|i| d {   2 3 d {   }t	        |t
              s|j                         }t        |d         dk(  r;|d   d   }	t        ||      }
i }|	j                  d      x}r,||d<   | j                  |d<   |j                  d      x}r||d<   |	j                  d	      }|r||d	<   |
j                  }t        |
|xs d 
      }|r&|j                  |j                  ||       d {    | 7 7 7 6 y w)Nr   Tr   r   r   r   rP   r   r   r   )tokenr   r   r   )r   r   rL   r   r   r   r   r   r   rr   rP   r   r4   r   r   r   s                   r   r   zChatGroq._astream1  s     !% : :8T Jv5F5f5h56D!9!2!2!9!9 "
""
&,"
 
 	# 	#% eT*((*5#$)9%a(F;ECVWM O &

? ;;};3@004-).3G)HH%H<NO$89zz*-H.6
+"/"9"92%7N$  !22*//*% 3   
 #";
 	#01
sI   AE		E
E	EEEC E	6E7E	EE	E	c                    | j                   | j                  | j                  | j                  | j                  d| j
                  }| j                  | j                  |d<   |S )z0Get the default parameters for calling Groq API.)rM   r   rh   rR   rT   ri   )rP   rf   rh   rR   rT   rW   ri   )r   r   s     r   _default_paramszChatGroq._default_params_  s_     __nn++II
 
 ??&#'??F< r   c                &   g }t        |t              s|j                         }|j                  di       }|d   D ]  }t	        |d         }|rRt        |t
              rB|j                  dd      }|j                  dd      }|||j                  d||z         d|_        t        |j                  d	      
      }d|v r|d   |d<   t        ||      }	|j                  |	        || j                  |j                  dd      d}
t        ||
      S )Nusager   r   prompt_tokensr   completion_tokenstotal_tokensinput_tokensoutput_tokensr   r   )r   r   r   r    )token_usagerP   r   )generations
llm_output)r   r   r   rr   _convert_dict_to_messager   usage_metadatar3   appendrP   r5   )r   r   r   r   resr   r   r   r   genr   s              r   r   zChatGroq._create_chat_resultn  s    (D)**,Hll7B/I& 	$C.s9~>Gz'9=*B +0CQ G$0%2$/OO&}(D%*& #1IJOS .1*o
+  /C s#'	$* '//"*,,/CR"H


 kjIIr   c                j    | j                   }|||d<   |D cg c]  }t        |       }}||fS c c}w )NrT   )r   _convert_message_to_dict)r   r   rT   r   mr   s         r   r   zChatGroq._create_message_dicts  sH     %%!F6N>FG1!4GGf$$ Hs   0c                    i }d }|D ]Q  }||d   }|1|j                         D ]  \  }}||v r|||xx   |z  cc<   |||<     |A|j                  d      }S || j                  d}|r||d<   |S )Nr   r   )r   rP   )itemsrr   rP   )	r   llm_outputsoverall_token_usager   outputr   kvcombineds	            r   _combine_llm_outputszChatGroq._combine_llm_outputs  s    $&!! 	FF~ /K&'--/ 3DAq//AM+A.!3.12+A.	3
 ")%+ZZ0D%E"	F $7dooV-?H)*r   z0.2.1z.langchain_groq.chat_models.ChatGroq.bind_toolsz1.0.0)sincealternativeremovalc                f   |D cg c]  }t        |       }}|t        |t              r|dvrd|in|}t        |t              rt	        |      dk7  rt        d      t        |t              r&|d   d   |d   k7  rt        d| d|d   d    d      i |d	|i}t        |   dd
|i|S c c}w )a  Bind functions (and other objects) to this chat model.

        Model is compatible with OpenAI function-calling API.

        NOTE: Using bind_tools is recommended instead, as the `functions` and
            `function_call` request parameters are officially deprecated.

        Args:
            functions: A list of function definitions to bind to this chat model.
                Can be  a dictionary, pydantic model, or callable. Pydantic
                models and callables will be automatically converted to
                their schema dictionary representation.
            function_call: Which function to require the model to call.
                Must be the name of the single provided function or
                "auto" to automatically determine which function to call
                (if any).
            **kwargs: Any additional parameters to pass to
                :meth:`~langchain_groq.chat_models.ChatGroq.bind`.
        )autononenamerg   zGWhen specifying `function_call`, you must provide exactly one function.r   zFunction call z3 was specified, but the only provided function was .function_call	functionsr   )r=   r   rO   r   r   rt   r   bind)r   r   r   r   fnformatted_functionsr   s         r   bind_functionszChatGroq.bind_functions  s   B IRR"9"=RR$ mS1!)99 ' #	  -.37J3Kq3P   
 =$/'*62mF6KK $]O 4--@-CF-K,LAO  @??Fw| 
)

 	
- Ss   B.)tool_choicec               F   |D cg c]  }t        |       }}|q|ro|dk(  rd}t        |t              r|dvrdd|id}t        |t              r8t	        |      dkD  rt        dt	        |       d	      |d
   d   d   }dd|id}||d<   t        |   dd|i|S c c}w )aD  Bind tool-like objects to this chat model.

        Args:
            tools: A list of tool definitions to bind to this chat model.
                Supports any tool definition handled by
                :meth:`langchain_core.utils.function_calling.convert_to_openai_tool`.
            tool_choice: Which tool to require the model to call.
                Must be the name of the single provided function,
                "auto" to automatically determine which function to call
                with the option to not call any function, "any" to enforce that some
                function is called, or a dict of the form:
                {"type": "function", "function": {"name": <<tool_name>>}}.
            **kwargs: Any additional parameters to pass to the
                :class:`~langchain.runnable.Runnable` constructor.
        anyrequired)r   r   r  functionr   )r   r  rg   z>tool_choice can only be True when there is one tool. Received z tools.r   r  toolsr   )r>   r   rO   re   r   rt   r   r   )r   r  r  r   toolformatted_tools	tool_namer   s          r   
bind_toolszChatGroq.bind_tools  s    2 EJJD1$7JJ"{e#(+s+#??'1?TU+t,u:>$Xu:,g/  ,A.z:6B	&!' 3
 %0F=!w|</<V<<+ Ks   Bfunction_calling)methodinclude_rawc               ~   |j                  dd      }|rt        d|       t        |      }|dk(  rd}|dk(  rY|t        d      t        |      }|d   d   }| j	                  |g|d	di|d
      }	|rt        |gd      }
nUt        |d      }
nG|dk(  r3| j                  ddid	di|d
      }	|rt        |      n	t               }
nt        d| d      |r^t        j                  t        d      |
z  d       }t        j                  d       }|j                  |gd      }t        |	      |z  S |	|
z  S )a+  Model wrapper that returns outputs formatted to match the given schema.

        Args:
            schema:
                The output schema. Can be passed in as:
                    - an OpenAI function/tool schema,
                    - a JSON Schema,
                    - a TypedDict class (supported added in 0.1.9),
                    - or a Pydantic class.
                If ``schema`` is a Pydantic class then the model output will be a
                Pydantic instance of that class, and the model-generated fields will be
                validated by the Pydantic class. Otherwise the model output will be a
                dict and will not be validated. See :meth:`langchain_core.utils.function_calling.convert_to_openai_tool`
                for more on how to properly specify types and descriptions of
                schema fields when specifying a Pydantic or TypedDict class.

                .. versionchanged:: 0.1.9

                    Added support for TypedDict class.
            method:
                The method for steering model generation, either "function_calling"
                or "json_mode". If "function_calling" then the schema will be converted
                to an OpenAI function and the returned model will make use of the
                function-calling API. If "json_mode" then OpenAI's JSON mode will be
                used. Note that if using "json_mode" then you must include instructions
                for formatting the output into the desired schema into the model call.
            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 same inputs as a :class:`langchain_core.language_models.chat.BaseChatModel`.

            If ``include_raw`` is False and ``schema`` is a Pydantic class, Runnable outputs
            an instance of ``schema`` (i.e., a Pydantic object).

            Otherwise, if ``include_raw`` is False then Runnable outputs a dict.

            If ``include_raw`` is True, then Runnable outputs a dict with keys:
                - ``"raw"``: BaseMessage
                - ``"parsed"``: None if there was a parsing error, otherwise the type depends on the ``schema`` as described above.
                - ``"parsing_error"``: Optional[BaseException]

        Example: schema=Pydantic class, method="function_calling", include_raw=False:
            .. code-block:: python

                from typing import Optional

                from langchain_groq import ChatGroq
                from pydantic import BaseModel, Field


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

                    answer: str
                    # If we provide default values and/or descriptions for fields, these will be passed
                    # to the model. This is an important part of improving a model's ability to
                    # correctly return structured outputs.
                    justification: Optional[str] = Field(
                        default=None, description="A justification for the answer."
                    )


                llm = ChatGroq(model="llama-3.1-405b-reasoning", 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='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: schema=Pydantic class, method="function_calling", include_raw=True:
            .. code-block:: python

                from langchain_groq import ChatGroq
                from pydantic import BaseModel


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

                    answer: str
                    justification: str


                llm = ChatGroq(model="llama-3.1-405b-reasoning", 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_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: schema=TypedDict class, method="function_calling", include_raw=False:
            .. code-block:: python

                # IMPORTANT: If you are using Python <=3.8, you need to import Annotated
                # from typing_extensions, not from typing.
                from typing_extensions import Annotated, TypedDict

                from langchain_groq import ChatGroq


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

                    answer: str
                    justification: Annotated[
                        Optional[str], None, "A justification for the answer."
                    ]


                llm = ChatGroq(model="llama-3.1-405b-reasoning", temperature=0)
                structured_llm = llm.with_structured_output(AnswerWithJustification)

                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.'
                # }

        Example: schema=OpenAI function schema, method="function_calling", include_raw=False:
            .. code-block:: python

                from langchain_groq import ChatGroq

                oai_schema = {
                    'name': 'AnswerWithJustification',
                    'description': 'An answer to the user question along with justification for the answer.',
                    'parameters': {
                        'type': 'object',
                        'properties': {
                            'answer': {'type': 'string'},
                            'justification': {'description': 'A justification for the answer.', 'type': 'string'}
                        },
                       'required': ['answer']
                   }
               }

                llm = ChatGroq(model="llama-3.1-405b-reasoning", temperature=0)
                structured_llm = llm.with_structured_output(oai_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.'
                # }

        Example: schema=Pydantic class, method="json_mode", include_raw=True:
            .. code-block::

                from langchain_groq import ChatGroq
                from pydantic import BaseModel

                class AnswerWithJustification(BaseModel):
                    answer: str
                    justification: str

                llm = ChatGroq(model="llama-3.1-405b-reasoning", temperature=0)
                structured_llm = llm.with_structured_output(
                    AnswerWithJustification,
                    method="json_mode",
                    include_raw=True
                )

                structured_llm.invoke(
                    "Answer the following question. "
                    "Make sure to return a JSON blob with keys 'answer' and 'justification'.

"
                    "What's heavier a pound of bricks or a pound of feathers?"
                )
                # -> {
                #     'raw': AIMessage(content='{
    "answer": "They are both the same weight.",
    "justification": "Both a pound of bricks and a pound of feathers weigh one pound. The difference lies in the volume and density of the materials, not the weight." 
}'),
                #     'parsed': AnswerWithJustification(answer='They are both the same weight.', justification='Both a pound of bricks and a pound of feathers weigh one pound. The difference lies in the volume and density of the materials, not the weight.'),
                #     'parsing_error': None
                # }

        Example: schema=None, method="json_mode", include_raw=True:
            .. code-block::

                structured_llm = llm.with_structured_output(method="json_mode", include_raw=True)

                structured_llm.invoke(
                    "Answer the following question. "
                    "Make sure to return a JSON blob with keys 'answer' and 'justification'.

"
                    "What's heavier a pound of bricks or a pound of feathers?"
                )
                # -> {
                #     'raw': AIMessage(content='{
    "answer": "They are both the same weight.",
    "justification": "Both a pound of bricks and a pound of feathers weigh one pound. The difference lies in the volume and density of the materials, not the weight." 
}'),
                #     'parsed': {
                #         'answer': 'They are both the same weight.',
                #         'justification': 'Both a pound of bricks and a pound of feathers weigh one pound. The difference lies in the volume and density of the materials, not the weight.'
                #     },
                #     'parsing_error': None
                # }
        strictNzReceived unsupported arguments json_schemar  zJschema must be specified when method is 'function_calling'. Received None.r  r   r  )r   schema)r  ls_structured_output_formatT)r  first_tool_only)key_namer  	json_moder   r   )r   r  )pydantic_objectz\Unrecognized method argument. Expected one of 'function_calling' or 'json_mode'. Received: ''rawc                     y Nr   _s    r   <lambda>z1ChatGroq.with_structured_output.<locals>.<lambda>,      r   )parsedparsing_errorc                     y r  r   r  s    r   r  z1ChatGroq.with_structured_output.<locals>.<lambda>.  r   r   )r!  r"  )exception_key)r  )rw   rt   _is_pydantic_classr>   r  r0   r/   r   r-   r,   r8   assignr   with_fallbacksr7   )r   r  r  r  r   r  is_pydantic_schemaformatted_toolr  llmoutput_parserparser_assignparser_noneparser_with_fallbacks                 r   with_structured_outputzChatGroq.with_structured_output  s   | JJx&>vhGHH/7]" (F''~ %  4F;N&z26:I//%');<,- " C "2E!($(3
 !9&! {"))!' 7'5$-  C & %V<%'  ++1(!5 
 /66!%(=8M .44NKK#0#?#?_ $@ $  3'*>>>&&r   )r{   rV   returnr   )r0  rE   )r0  zDict[str, str])r0  re   )r0  rO   r  )rT   Optional[List[str]]r   r   r0  r   )r   re   r   zHOptional[Union[CallbackManagerForLLMRun, AsyncCallbackManagerForLLMRun]]r   r   r0  re   )NN)
r   List[BaseMessage]rT   r1  r   "Optional[CallbackManagerForLLMRun]r   r   r0  r5   )
r   r2  rT   r1  r   'Optional[AsyncCallbackManagerForLLMRun]r   r   r0  r5   )
r   r2  rT   r1  r   r3  r   r   r0  zIterator[ChatGenerationChunk])
r   r2  rT   r1  r   r4  r   r   r0  z"AsyncIterator[ChatGenerationChunk])r0  rV   )r   zUnion[dict, BaseModel]r0  r5   )r   r2  rT   r1  r0  z+Tuple[List[Dict[str, Any]], Dict[str, Any]])r   zList[Optional[dict]]r0  r   )r   DSequence[Union[Dict[str, Any], Type[BaseModel], Callable, BaseTool]]r   z<Optional[Union[_FunctionCall, str, Literal['auto', 'none']]]r   r   r0  )Runnable[LanguageModelInput, BaseMessage])r  r5  r  z@Optional[Union[dict, str, Literal['auto', 'any', 'none'], bool]]r   r   r0  r6  )
r  z&Optional[Union[Dict, Type[BaseModel]]]r  z(Literal['function_calling', 'json_mode']r  re   r   r   r0  z4Runnable[LanguageModelInput, Union[Dict, BaseModel]])4__name__
__module____qualname____doc__rB   rK   __annotations__rL   rP   rR   rT   r   rW   r<   rZ   r:   r]   r_   ra   rd   rf   rh   ri   rj   rk   rl   rm   rA   model_configrD   classmethodr   r   propertyr   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r/  __classcell__)r   s   @r   rH   rH   \   s@   Qf d3FC3dD9L#9'*J*K+,1$FV,WD
)W!#(#>L.>V(-QU)V)L%  N#((?D*Q$M=  !& t<!J  EJIEOA K<It/AsJA $J$/6:O3:7;M4; %)K!( *.'.S L (#  $2 '"* #*^ 0 0    
 +/':=	. " "
	" " 
"* %):>	2#2 "2 8	2
 2 
2. %)?C	2#2 "2 =	2
 2 
20 %):>	%##%# "%# 8	%#
 %# 
'%#T %)?C	)##)# ")# =	)#
 )# 
,)#\  J@%)%1D%	4%* D 5
W5

5
 5
 
35

5
z .=S.=
	.= .= 
3.=d :>\' <N!\'6\' 9	\'
 \' \' 
>\'r   rH   c                <    t        | t              xr t        |       S r  )r   r   r?   )objs    r   r%  r%  7  s    c4 ?%:3%??r   c                      e Zd ZU ded<   y)_FunctionCallrO   r   N)r7  r8  r9  r;  r   r   r   rC  rC  ;  s    
Ir   rC  c                   t        | t              r| j                  | j                  d}nt        | t              rd| j                  d}nat        | t
              rd| j                  d}d| j                  v r| j                  d   |d<   |d   dk(  rd|d<   | j                  s| j                  rK| j                  D cg c]  }t        |       c}| j                  D cg c]  }t        |       c}z   |d<   nd| j                  v r| j                  d   |d<   |d   dk(  rd|d<   nt        | t              rd	| j                  d}ndt        | t              rd
| j                  | j                  d}n9t        | t              rd| j                  | j                  d}nt!        d|        d| j                  v r| j                  d   |d<   |S c c}w c c}w )zConvert a LangChain message to a dictionary.

    Args:
        message: The LangChain message.

    Returns:
        The dictionary.
    )rolecontentuser	assistantr   rF  r   N
tool_callssystemr  )rE  rF  r   r	  )rE  rF  tool_call_idzGot unknown type r   )r   r    rE  rF  r$   r   additional_kwargsrI  invalid_tool_calls_lc_tool_call_to_groq_tool_call'_lc_invalid_tool_call_to_groq_tool_callr'   r"   r   r*   rK  	TypeError)r   message_dicttcs      r   r   r   B  s    ';' 'I	G\	* &7??C	GY	' +Hg777,3,E,Eo,VL)I&",*.Y'!;!;>E>P>P*8:/3* "44 8;*L& W666)0)B)B<)PL&I&",*.Y'	G]	+ (W__E	G_	-LL

 
G[	)#00
 +G9566***&88@V;*s   ?G!Gc                `   | d   d   }|d   }t        t        |j                  d            }t        t        |j                  d      xs d      }i }|j                  d      r!t        |d         }d|v r
|d   d|d<   ||d<   |j                  d	      r|d	   |d	<   |d
k(  s	|t        k(  rt	        |      S |dk(  s	|t
        k(  rt| j                  d      xs i j                  d      x}r>|j                  dd      }	|j                  dd      }
|	|
|j                  d|	|
z         d}nd }t        |||      S |dk(  s	|t        k(  rt        |      S |dk(  s	|t        k(  rt        ||d         S |dk(  s	|t        k(  rt        ||d         S |s	|t        k(  rt        ||      S  ||      S )Nr   r   deltarE  rF  r   r   r   rI  rG  rF  rH  x_groqr   r   r   r   r   )rF  rL  r   rJ  r  rF  r   r	  rK  )rF  rK  rF  rE  )
r   rO   rr   r   r%   r   r(   r#   r+   r!   )r   default_classr   _dictrE  rF  rL  r   r   r   r   r   s               r   r   r   x  s    9a F7OEUYYv&'D3		),23G yy!U?34]"}V'<'D$&M&!-:/*yy*/*=,'v~*;; 11		 ?YYx(.B33G<<5< 99_a8L!II&91=M ,!. %		.,:V WN "N/)
 	

 
	].@@!'22		}0DD#G%-HH	=,<<eN>STT	"22d;;W--r   c           
     x   | j                  d      }| j                  d      }|dk(  rt        | j                  dd            S |dk(  r| j                  dd      xs d}i }| j                  d      x}rt        |      |d<   g }g }| j                  d	      x}r)||d	<   |D ]  }		 |j                  t	        |	d
             ! t        |||||      S |dk(  rt        | j                  dd            S |dk(  r,t        | j                  dd      | j                  d            S |dk(  r;i }d| v r| d   |d<   t        | j                  dd      | j                  d      |      S t        | j                  dd      |      S # t
        $ r/}
|j                  t        |	t        |
                   Y d}
~
d}
~
ww xY w)zConvert a dictionary to a LangChain message.

    Args:
        _dict: The dictionary.

    Returns:
        The LangChain message.
    idrE  rG  rF  r   rU  rH  r   rI  T)	return_idN)rF  r\  rL  rI  rM  rJ  r  r   rW  r	  rK  )rF  rK  rL  rX  )rr   r$   r   r   r2   	Exceptionr1   rO   r   r'   r"   r*   r    )rZ  id_rE  rF  rL  r   rI  rM  raw_tool_callsraw_tool_calles              r   r   r     s    ))D/C99VDv~EIIi$<==		))Ir*0b"$!IIo66=615m1Do.
"YY|44>4.<l+!/ %%omt&TU /!1
 	
 
	UYYy"%=>>		uyyB'?eiiPVFWXX	U?(-ff%IIi,>2/
 	
 599Y#;$GG3 ! &--.}c!fE s   $F	F9
$F44F9c                L    d| d   | d   t        j                  | d         ddS Nr  r\  r   args)r   	arguments)r   r\  r  )jsondumps)	tool_calls    r   rN  rN    s4    of%If$56
 r   c                &    d| d   | d   | d   ddS rd  r   )invalid_tool_calls    r   rO  rO    s.     %%f-*62
 r   )rA  r   r0  re   )r   r   r0  r   )r   Mapping[str, Any]rY  zType[BaseMessageChunk]r0  r   )rZ  rl  r0  r   )ri  r)   r0  r   )rk  r&   r0  r   )cr:  
__future__r   rg  ru   operatorr   typingr   r   r   r   r	   r
   r   r   r   r   r   r   r   r   r   langchain_core._apir   langchain_core.callbacksr   r   langchain_core.language_modelsr   *langchain_core.language_models.chat_modelsr   r   r   r   langchain_core.messagesr   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   langchain_core.output_parsersr,   r-   "langchain_core.output_parsers.baser.   *langchain_core.output_parsers.openai_toolsr/   r0   r1   r2   langchain_core.outputsr3   r4   r5   langchain_core.runnablesr6   r7   r8   langchain_core.toolsr9   langchain_core.utilsr:   r;   r<   %langchain_core.utils.function_callingr=   r>   langchain_core.utils.pydanticr?   pydanticr@   rA   rB   rC   rD   typing_extensionsrE   langchain_groq.versionrF   rH   r%  rC  r   r   r   rN  rO  r   r   r   <module>r     s    "       $ + >     $ @  S R O O ) 
 @  # .X'} X'v@I 3l+.+.-C+.+.\2Hj
&
	
r   