ó
    ýÞ j�±  ã                  ó�  • % S r SSKJr  SSKrSSKrSSKJrJrJrJ	r	  SSK
JrJrJrJrJr  SSKrSSKJr  SSKJr  SSKJrJr  SS	KJr  SS
KJrJr  SSKJr  SSKJ r J!r!J"r"J#r#  SSK$J%r%  SSK&J'r'J(r(  \(       a  SSKJ)r)  \RT                  " \+5      r,\" S\ S9r-\.\/\4   \0\-   -  \0-  r1S\2S'   \.\--  r3S\2S'   SS jr4 " S S\'5      r5g)zAzure OpenAI chat wrapper.é    )ÚannotationsN)ÚAsyncIteratorÚ	AwaitableÚCallableÚIterator)ÚTYPE_CHECKINGÚAnyÚLiteralÚ	TypeAliasÚTypeVar)ÚLanguageModelInput)ÚLangSmithParams)ÚChatGenerationChunkÚ
ChatResult)ÚRunnable)Úfrom_envÚsecret_from_env)Úis_basemodel_subclass)Ú	BaseModelÚFieldÚ	SecretStrÚmodel_validator)ÚSelf)ÚBaseChatOpenAIÚ_get_default_model_profile)ÚModelProfileÚ_BM)Úboundr   Ú_DictOrPydanticClassÚ_DictOrPydanticc                óF   • [        U [        5      =(       a    [        U 5      $ ©N)Ú
isinstanceÚtyper   )Úobjs    Ú\/var/www/html/gaurav/venv/lib/python3.13/site-packages/langchain_openai/chat_models/azure.pyÚ_is_pydantic_classr'   !   s   € Ü�cœ4Ó ×?Ô%:¸3Ó%?Ð?ó    c                  ó  ^ • \ rS rSr% Sr\" \" SSS9S9rS\S'    \" SS	S
9r	S\S'    \" S\" SSS9S9r
S\S'    \" S\" SS/SS9S9rS\S'    \" \" SSS9S9rS\S'    SrS\S'    SrS\S'    SrS\S'    \" \" SSS9S9rS\S '    S!rS"\S#'    \" SS$S
9rS\S%'    \" SS9rS&\S''    \" SS(S
9rS)\S*'    \SAS+ j5       r\SBS, j5       r\SCS- j5       r\" S.S/9SDS0 j5       rSES1 jr\SFU 4S2 jj5       r\SGS3 j5       r\SFS4 j5       r \SFU 4S5 jj5       r! SH     SIU 4S6 jjjr" SH     SJU 4S7 jjjr#SS8.       SKU 4S9 jjjr$SLU 4S: jjr%      SMU 4S; jjr& SHS<S=SS>.           SNU 4S? jjjjr'S@r(U =r)$ )OÚAzureChatOpenAIé%   uh0  Azure OpenAI chat model integration.

Setup:
    Head to the Azure [OpenAI quickstart guide](https://learn.microsoft.com/en-us/azure/ai-foundry/openai/chatgpt-quickstart?tabs=keyless%2Ctypescript-keyless%2Cpython-new%2Ccommand-line&pivots=programming-language-python)
    to create your Azure OpenAI deployment.

    Then install `langchain-openai` and set environment variables
    `AZURE_OPENAI_API_KEY` and `AZURE_OPENAI_ENDPOINT`:

    ```bash
    pip install -U langchain-openai

    export AZURE_OPENAI_API_KEY="your-api-key"
    export AZURE_OPENAI_ENDPOINT="https://your-endpoint.openai.azure.com/"
    ```

Key init args â€” completion params:
    azure_deployment:
        Name of Azure OpenAI deployment to use.
    temperature:
        Sampling temperature.
    max_tokens:
        Max number of tokens to generate.
    logprobs:
        Whether to return logprobs.

Key init args â€” client params:
    api_version:
        Azure OpenAI REST API version to use (distinct from the version of the
        underlying model). [See more on the different versions.](https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#rest-api-versioning)
    timeout:
        Timeout for requests.
    max_retries:
        Max number of retries.
    organization:
        OpenAI organization ID. If not passed in will be read from env
        var `OPENAI_ORG_ID`.
    model:
        The name of the underlying OpenAI model. Used for tracing and token
        counting. Does not affect completion.
    model_version:
        The version of the underlying OpenAI model. Used for tracing and token
        counting. Does not affect completion. E.g., `'0125'`, `'0125-preview'`, etc.

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

Instantiate:
    ```python
    from langchain_openai import AzureChatOpenAI

    model = AzureChatOpenAI(
        azure_deployment="your-deployment",
        api_version="2024-05-01-preview",
        temperature=0,
        max_tokens=None,
        timeout=None,
        max_retries=2,
        # organization="...",
        # model="gpt-35-turbo",
        # model_version="0125",
        # other params...
    )
    ```

!!! note
    Any param which is not explicitly supported will be passed directly to the
    `openai.AzureOpenAI.chat.completions.create(...)` API every time to the model is
    invoked.

    For example:

    ```python
    from langchain_openai import AzureChatOpenAI
    import openai

    AzureChatOpenAI(..., logprobs=True).invoke(...)

    # results in underlying API call of:

    openai.AzureOpenAI(..).chat.completions.create(..., logprobs=True)

    # which is also equivalent to:

    AzureChatOpenAI(...).invoke(..., logprobs=True)
    ```

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

    ```python
    AIMessage(
        content="J'adore programmer.",
        usage_metadata={
            "input_tokens": 28,
            "output_tokens": 6,
            "total_tokens": 34,
        },
        response_metadata={
            "token_usage": {
                "completion_tokens": 6,
                "prompt_tokens": 28,
                "total_tokens": 34,
            },
            "model_name": "gpt-5.5",
            "system_fingerprint": "fp_7ec89fabc6",
            "prompt_filter_results": [
                {
                    "prompt_index": 0,
                    "content_filter_results": {
                        "hate": {"filtered": False, "severity": "safe"},
                        "self_harm": {"filtered": False, "severity": "safe"},
                        "sexual": {"filtered": False, "severity": "safe"},
                        "violence": {"filtered": False, "severity": "safe"},
                    },
                }
            ],
            "finish_reason": "stop",
            "logprobs": None,
            "content_filter_results": {
                "hate": {"filtered": False, "severity": "safe"},
                "self_harm": {"filtered": False, "severity": "safe"},
                "sexual": {"filtered": False, "severity": "safe"},
                "violence": {"filtered": False, "severity": "safe"},
            },
        },
        id="run-6d7a5282-0de0-4f27-9cc0-82a9db9a3ce9-0",
    )
    ```

Stream:
    ```python
    for chunk in model.stream(messages):
        print(chunk.text, end="")
    ```

    ```python
    AIMessageChunk(content="", id="run-a6f294d3-0700-4f6a-abc2-c6ef1178c37f")
    AIMessageChunk(content="J", id="run-a6f294d3-0700-4f6a-abc2-c6ef1178c37f")
    AIMessageChunk(content="'", id="run-a6f294d3-0700-4f6a-abc2-c6ef1178c37f")
    AIMessageChunk(content="ad", id="run-a6f294d3-0700-4f6a-abc2-c6ef1178c37f")
    AIMessageChunk(content="ore", id="run-a6f294d3-0700-4f6a-abc2-c6ef1178c37f")
    AIMessageChunk(content=" la", id="run-a6f294d3-0700-4f6a-abc2-c6ef1178c37f")
    AIMessageChunk(
        content=" programm", id="run-a6f294d3-0700-4f6a-abc2-c6ef1178c37f"
    )
    AIMessageChunk(content="ation", id="run-a6f294d3-0700-4f6a-abc2-c6ef1178c37f")
    AIMessageChunk(content=".", id="run-a6f294d3-0700-4f6a-abc2-c6ef1178c37f")
    AIMessageChunk(
        content="",
        response_metadata={
            "finish_reason": "stop",
            "model_name": "gpt-5.5",
            "system_fingerprint": "fp_811936bd4f",
        },
        id="run-a6f294d3-0700-4f6a-abc2-c6ef1178c37f",
    )
    ```

    ```python
    stream = model.stream(messages)
    full = next(stream)
    for chunk in stream:
        full += chunk
    full
    ```

    ```python
    AIMessageChunk(
        content="J'adore la programmation.",
        response_metadata={
            "finish_reason": "stop",
            "model_name": "gpt-5.5",
            "system_fingerprint": "fp_811936bd4f",
        },
        id="run-ba60e41c-9258-44b8-8f3a-2f10599643b3",
    )
    ```

Async:
    ```python
    await model.ainvoke(messages)

    # stream:
    # async for chunk in (await model.astream(messages))

    # batch:
    # await model.abatch([messages])
    ```

Tool calling:
    ```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 = model.bind_tools([GetWeather, GetPopulation])
    ai_msg = model_with_tools.invoke(
        "Which city is hotter today and which is bigger: LA or NY?"
    )
    ai_msg.tool_calls
    ```

    ```python
    [
        {
            "name": "GetWeather",
            "args": {"location": "Los Angeles, CA"},
            "id": "call_6XswGD5Pqk8Tt5atYr7tfenU",
        },
        {
            "name": "GetWeather",
            "args": {"location": "New York, NY"},
            "id": "call_ZVL15vA8Y7kXqOy3dtmQgeCi",
        },
        {
            "name": "GetPopulation",
            "args": {"location": "Los Angeles, CA"},
            "id": "call_49CFW8zqC9W7mh7hbMLSIrXw",
        },
        {
            "name": "GetPopulation",
            "args": {"location": "New York, NY"},
            "id": "call_6ghfKxV264jEfe1mRIkS3PE7",
        },
    ]
    ```

Structured output:
    ```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: int | None = Field(
            description="How funny the joke is, from 1 to 10"
        )


    structured_model = model.with_structured_output(Joke)
    structured_model.invoke("Tell me a joke about cats")
    ```

    ```python
    Joke(
        setup="Why was the cat sitting on the computer?",
        punchline="To keep an eye on the mouse!",
        rating=None,
    )
    ```

    See `AzureChatOpenAI.with_structured_output()` for more.

JSON mode:
    ```python
    json_model = model.bind(response_format={"type": "json_object"})
    ai_msg = json_model.invoke(
        "Return a JSON object with key 'random_ints' and a value of 10 random ints in [0-99]"
    )
    ai_msg.content
    ```

    ```python
    '\\n{\\n  "random_ints": [23, 87, 45, 12, 78, 34, 56, 90, 11, 67]\\n}'
    ```

Image input:
    ```python
    import base64
    import httpx
    from langchain_core.messages import HumanMessage

    image_url = "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg"
    image_data = base64.b64encode(httpx.get(image_url).content).decode("utf-8")
    message = HumanMessage(
        content=[
            {"type": "text", "text": "describe the weather in this image"},
            {
                "type": "image_url",
                "image_url": {"url": f"data:image/jpeg;base64,{image_data}"},
            },
        ]
    )
    ai_msg = model.invoke([message])
    ai_msg.content
    ```

    ```python
    "The weather in the image appears to be quite pleasant. The sky is mostly clear"
    ```

Token usage:
    ```python
    ai_msg = model.invoke(messages)
    ai_msg.usage_metadata
    ```

    ```python
    {"input_tokens": 28, "output_tokens": 5, "total_tokens": 33}
    ```
Logprobs:
    ```python
    logprobs_model = model.bind(logprobs=True)
    ai_msg = logprobs_model.invoke(messages)
    ai_msg.response_metadata["logprobs"]
    ```

    ```python
    {
        "content": [
            {
                "token": "J",
                "bytes": [74],
                "logprob": -4.9617593e-06,
                "top_logprobs": [],
            },
            {
                "token": "'adore",
                "bytes": [39, 97, 100, 111, 114, 101],
                "logprob": -0.25202933,
                "top_logprobs": [],
            },
            {
                "token": " la",
                "bytes": [32, 108, 97],
                "logprob": -0.20141791,
                "top_logprobs": [],
            },
            {
                "token": " programmation",
                "bytes": [
                    32,
                    112,
                    114,
                    111,
                    103,
                    114,
                    97,
                    109,
                    109,
                    97,
                    116,
                    105,
                    111,
                    110,
                ],
                "logprob": -1.9361265e-07,
                "top_logprobs": [],
            },
            {
                "token": ".",
                "bytes": [46],
                "logprob": -1.2233183e-05,
                "top_logprobs": [],
            },
        ]
    }
    ```

Response metadata
    ```python
    ai_msg = model.invoke(messages)
    ai_msg.response_metadata
    ```

    ```python
    {
        "token_usage": {
            "completion_tokens": 6,
            "prompt_tokens": 28,
            "total_tokens": 34,
        },
        "model_name": "gpt-35-turbo",
        "system_fingerprint": None,
        "prompt_filter_results": [
            {
                "prompt_index": 0,
                "content_filter_results": {
                    "hate": {"filtered": False, "severity": "safe"},
                    "self_harm": {"filtered": False, "severity": "safe"},
                    "sexual": {"filtered": False, "severity": "safe"},
                    "violence": {"filtered": False, "severity": "safe"},
                },
            }
        ],
        "finish_reason": "stop",
        "logprobs": None,
        "content_filter_results": {
            "hate": {"filtered": False, "severity": "safe"},
            "self_harm": {"filtered": False, "severity": "safe"},
            "sexual": {"filtered": False, "severity": "safe"},
            "violence": {"filtered": False, "severity": "safe"},
        },
    }
    ```
ÚAZURE_OPENAI_ENDPOINTN)Údefault)Údefault_factoryz
str | NoneÚazure_endpointÚazure_deployment)r-   ÚaliasÚdeployment_nameÚapi_versionÚOPENAI_API_VERSION)r1   r.   Úopenai_api_versionÚapi_keyÚAZURE_OPENAI_API_KEYÚOPENAI_API_KEYzSecretStr | NoneÚopenai_api_keyÚAZURE_OPENAI_AD_TOKENÚazure_ad_tokenzCallable[[], str] | NoneÚazure_ad_token_providerz#Callable[[], Awaitable[str]] | NoneÚazure_ad_async_token_providerÚ ÚstrÚmodel_versionÚOPENAI_API_TYPEÚazureÚopenai_api_typeTÚboolÚvalidate_base_urlÚmodelÚ
model_namezdict[str, Any] | NoneÚdisabled_paramsÚmax_completion_tokensz
int | NoneÚ
max_tokensc                ó
   • / SQ$ )zhGet the namespace of the LangChain object.

Returns:
    `["langchain", "chat_models", "azure_openai"]`
)Ú	langchainÚchat_modelsÚazure_openai© ©Úclss    r&   Úget_lc_namespaceÚ AzureChatOpenAI.get_lc_namespaceA  s
   € ò <Ð;r(   c                ó   • SSS.$ )z0Get the mapping of secret environment variables.r7   r:   )r9   r;   rO   ©Úselfs    r&   Ú
lc_secretsÚAzureChatOpenAI.lc_secretsJ  s   € ð 5Ø5ñ
ð 	
r(   c                ó   • g)z0Check if the class is serializable in langchain.TrO   rP   s    r&   Úis_lc_serializableÚ"AzureChatOpenAI.is_lc_serializableR  s   € ð r(   Úafter)Úmodec                ó,  ^ • T R                   b  T R                   S:  a  Sn[        U5      eT R                   b.  T R                   S:”  a  T R                  (       a  Sn[        U5      eT R                  c+  T R                  (       a  T R                  S:X  a  O	SS0T l        T R
                  =(       d3    [        R                  " S5      =(       d    [        R                  " S5      T l        [        U 4S	 jS
 5       5      (       a  ST l	        T R                  nU(       aB  T R                  (       a1  SU;  a  Sn[        U5      eT R                  (       a  Sn[        U5      eT R                  T R                  T R                  T R                  (       a  T R                  R!                  5       OST R"                  (       a  T R"                  R!                  5       OST R$                  T R
                  T R                  T R&                  SS0T R(                  =(       d    0 ET R*                  S.nT R"                  (       d"  T R$                  (       d  T R,                  (       a  SUS'   T R.                  b  T R.                  US'   T R0                  (       dƒ  T R,                  (       a"  T R"                  (       d  T R$                  (       aP  ST R2                  0n[4        R6                  " S0 UDUD6T l        T R8                  R:                  R<                  T l        T R>                  (       dp  ST R@                  0nT R,                  (       a  T R,                  US'   [4        RB                  " S0 UDUD6T l"        T RD                  R:                  R<                  T l        T $ )z?Validate that api key and python package exists in environment.Né   zn must be at least 1.zn must be 1 when streaming.zgpt-4oÚparallel_tool_callsÚOPENAI_ORG_IDÚOPENAI_ORGANIZATIONc              3  ó@   >#   • U H  n[        TUS 5      S L v •  M     g 7fr"   )Úgetattr)Ú.0ÚkeyrV   s     €r&   Ú	<genexpr>Ú7AzureChatOpenAI.validate_environment.<locals>.<genexpr>p  s*   øé € ð 
ñ�ô �D˜#˜tÓ$¨Õ,òùs   ƒ)
Ústream_usageÚopenai_proxyÚopenai_api_baseÚbase_urlÚclientÚroot_clientÚasync_clientÚroot_async_clientÚhttp_clientÚhttp_async_clientTz/openaiz„As of openai>=1.0.0, Azure endpoints should be specified via the `azure_endpoint` param not `openai_api_base` (or alias `base_url`).aÓ  As of openai>=1.0.0, if `azure_deployment` (or alias `deployment_name`) is specified then `base_url` (or alias `openai_api_base`) should not be. If specifying `azure_deployment`/`deployment_name` then use `azure_endpoint` instead of `base_url`.

For example, you could specify:

azure_endpoint="https://xxx.openai.azure.com/", azure_deployment="my-deployment"

Or you can equivalently specify:

base_url="https://xxx.openai.azure.com/openai/deployments/my-deployment"z
User-Agentz%langchain-partner-python-azure-openai)r3   r/   r0   r6   r;   r<   Úorganizationrl   ÚtimeoutÚdefault_headersÚdefault_queryr6   Úmax_retriesrq   r<   rO   )#ÚnÚ
ValueErrorÚ	streamingrH   rG   Úopenai_organizationÚosÚgetenvÚallri   rk   rE   r2   r5   r/   r9   Úget_secret_valuer;   r<   Úrequest_timeoutru   rv   r=   rw   rm   rq   ÚopenaiÚAzureOpenAIrn   ÚchatÚcompletionsro   rr   ÚAsyncAzureOpenAIrp   )rV   Úmsgrk   Úclient_paramsÚsync_specificÚasync_specifics   `     r&   Úvalidate_environmentÚ$AzureChatOpenAI.validate_environmentW  s  ø€ ð �6‰6Ñ $§&¡&¨1£*Ø)ˆCÜ˜S“/Ð!Ø�6‰6Ñ $§&¡&¨1£*°··Ø/ˆCÜ˜S“/Ð!à×ÑÑ'à�� 4§?¡?°hÓ#>Øà(=¸tÐ'D�Ô$ð ×$Ñ$÷ 0Ü�yŠy˜Ó)÷0ä�yŠyÐ.Ó/ð 	Ô ô ô 
ñó
÷ 
ñ 
ð !%ˆDÔð ×.Ñ.ˆÞ˜t×5×5Ø Ó/ð-ð ô
 ! “oÐ%Ø×#×#ð	_ð ô ! “oÐ%à×2Ñ2Ø"×1Ñ1Ø $× 4Ñ 4à:>×:M×:M�×#Ñ#×4Ñ4Ô6ÐSWð ;?×:M×:M�×#Ñ#×4Ñ4Ô6ÐSWà'+×'CÑ'CØ ×4Ñ4Ø×,Ñ,Ø×+Ñ+àÐEð à×'Ñ'×-¨2ð ð "×/Ñ/ñ%
ˆð* ××Ø×+×+Ø×1×1à'+ˆM˜)Ñ$Ø×ÑÑ'Ø+/×+;Ñ+;ˆM˜-Ñ(à�{�{Ø×2×2Ø×"×"Ø×+×+à*¨D×,<Ñ,<Ð=ˆMÜ%×1Ò1ÑS°MÐSÀ]ÑSˆDÔØ×*Ñ*×/Ñ/×;Ñ;ˆDŒKØ× × Ø+¨T×-CÑ-CÐDˆNà×1×1à×6Ñ6ð Ð7Ñ8ô &,×%<Ò%<ñ &Øð&à ñ&ˆDÔ"ð !%× 6Ñ 6× ;Ñ ;× GÑ GˆDÔØˆr(   c                óÂ   • U R                   b'  [        U R                   5      =(       d    S =n(       a  U$ U R                  b  [        U R                  5      =(       d    S $ g r"   )rG   r   r2   )rV   Úprofiles     r&   Ú_resolve_model_profileÚ&AzureChatOpenAI._resolve_model_profileÎ  sO   € Ø�O‰OÑ'Ü1°$·/±/ÓB×JÀdÐJˆGÕJàˆNØ×ÑÑ+Ü-¨d×.BÑ.BÓC×KÀtÐKØr(   c                ó4   >• SU R                   0[        TU ]  E$ )zGet the identifying parameters.r0   )r2   ÚsuperÚ_identifying_params)rV   Ú	__class__s    €r&   r’   Ú#AzureChatOpenAI._identifying_params×  s'   ø€ ð  × 4Ñ 4ð
ä‰gÑ)ð
ð 	
r(   c                ó   • g)Nzazure-openai-chatrO   rU   s    r&   Ú	_llm_typeÚAzureChatOpenAI._llm_typeß  s   € à"r(   c                ó4   • U R                   U R                  S.$ )z'Get the attributes relevant to tracing.©rC   r5   r™   rU   s    r&   Úlc_attributesÚAzureChatOpenAI.lc_attributesã  s    € ð  $×3Ñ3Ø"&×"9Ñ"9ñ
ð 	
r(   c                óP   >• [         TU ]  nSU;   a  UR                  S5      US'   U$ )z8Get the default parameters for calling Azure OpenAI API.rJ   rI   )r‘   Ú_default_paramsÚpop)rV   Úparamsr“   s     €r&   r�   ÚAzureChatOpenAI._default_paramsë  s0   ø€ ô ‘Ñ(ˆØ˜6Ó!Ø.4¯j©j¸Ó.FˆFÐ*Ñ+àˆr(   c                ó„  >• [         TU ]  " SSU0UD6nSUS'   SU;   a   U$ U R                  (       am  U R                  (       aJ  U R                  U R                  ;  a0  U R                  S-   U R                  R	                  S5      -   US'   U$ U R                  US'    U$ U R
                  (       a  U R
                  US'   U$ )z,Get the parameters used to invoke the model.ÚstoprB   Úls_providerrF   Ú-Úls_model_namerO   )r‘   Ú_get_ls_paramsrG   r@   Úlstripr2   )rV   r¢   ÚkwargsrŸ   r“   s       €r&   r¦   ÚAzureChatOpenAI._get_ls_paramsô  sÅ   ø€ ô ‘Ò'Ñ<¨TÐ<°VÑ<ˆØ 'ˆˆ}ÑØ�fÓàð ˆð �_�_Ø×!×! d×&8Ñ&8ÀÇÁÓ&Oà—O‘O cÑ)¨D×,>Ñ,>×,EÑ,EÀcÓ,JÑJð �Ñ'ð ˆð +/¯/©/��Ò'ð ˆð ×!×!Ø&*×&:Ñ&:ˆF�?Ñ#Øˆr(   c                óŽ  >• [         T	U ]  X5      n[        U[        5      (       d  UR	                  SS9nUS    H&  nUR                  SS 5      S:X  d  M  Sn[        U5      e   SU;   aO  US   nU R                  (       a  U SU R                   3nUR                  =(       d    0 Ul        XcR                  S	'   S
U;   a,  UR                  =(       d    0 Ul        US
   UR                  S
'   [        UR                  US   SS9 H>  u  pxUR                  =(       d    0 Ul        UR                  S0 5      UR                  S'   M@     U$ )NF)ÚwarningsÚchoicesÚfinish_reasonÚcontent_filterzKAzure has not provided the response due to a content filter being triggeredrF   r¤   rG   Úprompt_filter_results)ÚstrictÚcontent_filter_results)r‘   Ú_create_chat_resultr#   ÚdictÚ
model_dumpÚgetry   r@   Ú
llm_outputÚzipÚgenerationsÚgeneration_info)
rV   Úresponser¹   Úchat_resultÚresr†   rF   Úchat_genÚresponse_choicer“   s
            €r&   r²   Ú#AzureChatOpenAI._create_chat_result  s[  ø€ ô
 ‘gÑ1°(ÓLˆä˜(¤D×)Ñ)à×*Ñ*°EÐ*Ð:ˆHØ˜IÔ&ˆCØ�w‰w�¨Ó-Ð1AÕAð&ð ô ! “oÐ%ñ 'ð �hÓØ˜WÑ%ˆEØ×!×!Ø ˜'  4×#5Ñ#5Ð"6Ð7�à%0×%;Ñ%;×%A¸rˆKÔ"Ø38×"Ñ" <Ñ0Ø" hÓ.Ø%0×%;Ñ%;×%A¸rˆKÔ"Ø>FØ'ñ?ˆK×"Ñ"Ð#:Ñ;ô *-Ø×#Ñ# X¨iÑ%8Àô*
Ñ%ˆHð (0×'?Ñ'?×'EÀ2ˆHÔ$ØAP×ATÑATØ(¨"óBˆH×$Ñ$Ð%=Ó>ñ	*
ð Ðr(   )r¢   c               óÆ   >• [         TU ]  " U4SU0UD6nU R                  U5      (       a6  UR                  S5      (       d   U R                  (       a  U R                  US'   U$ )zGGet the request payload, using deployment name for Azure Responses API.r¢   rF   )r‘   Ú_get_request_payloadÚ_use_responses_apirµ   r2   )rV   Úinput_r¢   r¨   Úpayloadr“   s        €r&   rÁ   Ú$AzureChatOpenAI._get_request_payload0  s^   ø€ ô ‘'Ò.¨vÑK¸DÐKÀFÑKˆð ×#Ñ# G×,Ñ,Ø—K‘K ×(Ñ(Ø×$×$à#×3Ñ3ˆG�GÑàˆr(   c                óŒ   >• U R                  0 UEU R                  E5      (       a  [        TU ]  " U0 UD6$ [        TU ]  " U0 UD6$ )ú+Route to Chat Completions or Responses API.)rÂ   Úmodel_kwargsr‘   Ú_stream_responsesÚ_stream)rV   Úargsr¨   r“   s      €r&   rÊ   ÚAzureChatOpenAI._streamD  sN   ø€ à×"Ñ"Ð#B fÐ#B°×0AÑ0AÐ#B×CÑCÜ‘7Ò,¨dÐ=°fÑ=Ð=Ü‰wŠ Ð/¨Ñ/Ð/r(   c               óä   >#   • U R                  0 UEU R                  E5      (       a   [        TU ]  " U0 UD6  Sh  v•N nU7v •  M  [        TU ]  " U0 UD6  Sh  v•N nU7v •  M   N+
 g N
 g7f)rÇ   N)rÂ   rÈ   r‘   Ú_astream_responsesÚ_astream)rV   rË   r¨   Úchunkr“   s       €r&   rÏ   ÚAzureChatOpenAI._astreamJ  sv   øé € ð ×"Ñ"Ð#B fÐ#B°×0AÑ0AÐ#B×CÑCÜ$™wÒ9¸4ÐJÀ6ÒJ÷ �eØ•ä$™wÒ/°Ð@¸Ò@÷ �eØ•ñ	ÑJñÑ@ùsJ   ƒ5A0¸A*¼A(½A*Á A0ÁA.ÁA,ÁA.Á A0Á(A*Á*A0Á,A.Á.A0Újson_schemaF©ÚmethodÚinclude_rawr°   c               ó,   >• [         TU ]  " U4X#US.UD6$ )aß0  Model wrapper that returns outputs formatted to match the given schema.

Args:
    schema: The output schema. Can be passed in as:

        - A JSON Schema,
        - A `TypedDict` class,
        - A Pydantic class,
        - Or an OpenAI function/tool schema.

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

    method: The method for steering model generation, one of:

        - `'json_schema'`:
            Uses OpenAI's [Structured Output API](https://platform.openai.com/docs/guides/structured-outputs).
            Supported only by models listed in OpenAI's Structured Output API
            documentation.
        - `'function_calling'`:
            Uses OpenAI's tool-calling (formerly called function calling)
            [API](https://platform.openai.com/docs/guides/function-calling)
        - `'json_mode'`:
            Uses OpenAI's [JSON mode](https://platform.openai.com/docs/guides/structured-outputs/json-mode).
            Note that if using JSON mode then you must include instructions for
            formatting the output into the desired schema into the model call

        Learn more about the differences between the methods and which models
        support which methods [here](https://platform.openai.com/docs/guides/structured-outputs/function-calling-vs-response-format).

    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'`.
    strict:

        - True:
            Model output is guaranteed to exactly match the schema.
            The input schema will also be validated according to the [supported schemas](https://platform.openai.com/docs/guides/structured-outputs/supported-schemas?api-mode=responses#supported-schemas).
        - False:
            Input schema will not be validated and model output will not be
            validated.
        - None:
            `strict` argument will not be passed to the model.

        If schema is specified via TypedDict or JSON schema, `strict` is not
        enabled by default. Pass `strict=True` to enable it.

        !!! note
            `strict` can only be non-null if `method` is `'json_schema'`
            or `'function_calling'`.
    kwargs: Additional keyword args are passed through to the model.

Returns:
    A `Runnable` that takes same inputs as a
        `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'`: `BaseException | None`

!!! warning "Behavior changed in `langchain-openai` 0.3.0"

    `method` default changed from "function_calling" to "json_schema".

!!! warning "Behavior changed in `langchain-openai` 0.3.12"

    Support for `tools` added.

!!! warning "Behavior changed in `langchain-openai` 0.3.21"

    Pass `kwargs` through to the model.

??? note "Example: `schema=Pydantic` class, `method='json_schema'`, `include_raw=False`, `strict=True`"

    Note, OpenAI has a number of restrictions on what types of schemas can be
    provided if `strict` = True. When using Pydantic, our model cannot
    specify any Field metadata (like min/max constraints) and fields cannot
    have default values.

    See all constraints [here](https://platform.openai.com/docs/guides/structured-outputs/supported-schemas).

    ```python
    from typing import Optional

    from langchain_openai import AzureChatOpenAI
    from pydantic import BaseModel, Field


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

        answer: str
        justification: str | None = Field(
            default=..., description="A justification for the answer."
        )


    model = AzureChatOpenAI(
        azure_deployment="...", model="gpt-5.5", temperature=0
    )
    structured_model = model.with_structured_output(AnswerWithJustification)

    structured_model.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.'
    # )
    ```

??? note "Example: `schema=Pydantic` class, `method='function_calling'`, `include_raw=False`, `strict=False`"

    ```python
    from typing import Optional

    from langchain_openai import AzureChatOpenAI
    from pydantic import BaseModel, Field


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

        answer: str
        justification: str | None = Field(
            default=..., description="A justification for the answer."
        )


    model = AzureChatOpenAI(
        azure_deployment="...", model="gpt-5.5", temperature=0
    )
    structured_model = model.with_structured_output(
        AnswerWithJustification, method="function_calling"
    )

    structured_model.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.'
    # )
    ```

??? note "Example: `schema=Pydantic` class, `method='json_schema'`, `include_raw=True`"

    ```python
    from langchain_openai import AzureChatOpenAI
    from pydantic import BaseModel


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

        answer: str
        justification: str


    model = AzureChatOpenAI(
        azure_deployment="...", model="gpt-5.5", temperature=0
    )
    structured_model = model.with_structured_output(
        AnswerWithJustification, include_raw=True
    )

    structured_model.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
    # }
    ```

??? note "Example: `schema=TypedDict` class, `method='json_schema'`, `include_raw=False`, `strict=False`"

    ```python
    from typing_extensions import Annotated, TypedDict

    from langchain_openai import AzureChatOpenAI


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

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


    model = AzureChatOpenAI(
        azure_deployment="...", model="gpt-5.5", temperature=0
    )
    structured_model = model.with_structured_output(AnswerWithJustification)

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

??? note "Example: `schema=OpenAI` function schema, `method='json_schema'`, `include_raw=False`"

    ```python
    from langchain_openai import AzureChatOpenAI

    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']
        }

        model = AzureChatOpenAI(
            azure_deployment="...",
            model="gpt-5.5",
            temperature=0,
        )
        structured_model = model.with_structured_output(oai_schema)

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

??? note "Example: `schema=Pydantic` class, `method='json_mode'`, `include_raw=True`"

    ```python
    from langchain_openai import AzureChatOpenAI
    from pydantic import BaseModel


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


    model = AzureChatOpenAI(
        azure_deployment="...",
        model="gpt-5.5",
        temperature=0,
    )
    structured_model = model.with_structured_output(
        AnswerWithJustification, method="json_mode", include_raw=True
    )

    structured_model.invoke(
        "Answer the following question. "
        "Make sure to return a JSON blob with keys 'answer' and 'justification'.\\n\\n"
        "What's heavier a pound of bricks or a pound of feathers?"
    )
    # -> {
    #     'raw': AIMessage(content='{\\n    "answer": "They are both the same weight.",\\n    "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." \\n}'),
    #     '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
    # }
    ```

??? note "Example: `schema=None`, `method='json_mode'`, `include_raw=True`"

    ```python
    structured_model = model.with_structured_output(
        method="json_mode", include_raw=True
    )

    structured_model.invoke(
        "Answer the following question. "
        "Make sure to return a JSON blob with keys 'answer' and 'justification'.\\n\\n"
        "What's heavier a pound of bricks or a pound of feathers?"
    )
    # -> {
    #     'raw': AIMessage(content='{\\n    "answer": "They are both the same weight.",\\n    "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." \\n}'),
    #     '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
    # }
    ```

rÓ   )r‘   Úwith_structured_output)rV   ÚschemarÔ   rÕ   r°   r¨   r“   s         €r&   r×   Ú&AzureChatOpenAI.with_structured_outputU  s-   ø€ ôR
 ‰wÒ-Øð
Ø!À6ñ
ØMSñ
ð 	
r(   )ro   rm   rH   r{   rp   rn   ri   )Úreturnz	list[str])rÚ   zdict[str, str])rÚ   rD   )rÚ   r   )rÚ   zModelProfile | None)rÚ   zdict[str, Any])rÚ   r?   r"   )r¢   úlist[str] | Noner¨   r	   rÚ   r   )rº   zdict | openai.BaseModelr¹   zdict | NonerÚ   r   )rÃ   r   r¢   rÛ   r¨   r	   rÚ   r³   )rË   r	   r¨   r	   rÚ   zIterator[ChatGenerationChunk])rË   r	   r¨   r	   rÚ   z"AsyncIterator[ChatGenerationChunk])rØ   z_DictOrPydanticClass | NonerÔ   z7Literal['function_calling', 'json_mode', 'json_schema']rÕ   rD   r°   zbool | Noner¨   r	   rÚ   z-Runnable[LanguageModelInput, _DictOrPydantic])*Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r   r   r/   Ú__annotations__r2   r5   r   r9   r;   r<   r=   r@   rC   rE   rG   rH   rJ   ÚclassmethodrR   ÚpropertyrW   rZ   r   rŠ   rŽ   r’   r–   rš   r�   r¦   r²   rÁ   rÊ   rÏ   r×   Ú__static_attributes__Ú__classcell__)r“   s   @r&   r*   r*   %   s,  ø‡ ñhñT "'Ù Ð!8À$ÑGñ"€N�Jó ðñ #(°Ð<NÑ"O€O�ZÓOðñ &+ØÙ Ð!5¸tÑDñ&Ð˜
ó ð Tñ (-ØÙ'Ø#Ð%5Ð6Àñ
ñ(€NÐ$ó ð VÙ',Ù'Ð(?ÈÑNñ(€NÐ$ó ðð 9=ÐÐ5Ó<ðð JNÐ!Ð#FÓMðð
 €M�3Óð
ñ #(Ù Ð!2¸GÑDñ#€O�Zó ð .à"Ð�tÓ"ðñ #¨4°wÑ?€J�
Ó?ðñ .3¸4Ñ-@€OÐ*Ó@ðñ* #¨4Ð7NÑO€J�
ÓOØ/àó<ó ð<ð ó
ó ð
ð óó ðñ ˜'Ñ"ótó #ðtôlð ö
ó ð
ð ó#ó ð#ð ó
ó ð
ð öó ðð (,ðØ$ðØ7:ðà	÷ð ð. (,ð&à)ð&ð %ð&ð 
÷	&ð &ðX "&ñ	à"ðð ð	ð
 ðð 
÷ð ÷(0ð	Øð	Ø$'ð	à	+÷	ð /3ðK
ð KXØ!Ø"ñK
à+ðK
ð Hð	K
ð
 ðK
ð ðK
ð ðK
ð 
7÷K
÷ K
r(   r*   )r%   r	   rÚ   rD   )6rà   Ú
__future__r   Úloggingr|   Úcollections.abcr   r   r   r   Útypingr   r	   r
   r   r   r�   Úlangchain_core.language_modelsr   Ú*langchain_core.language_models.chat_modelsr   Úlangchain_core.outputsr   r   Úlangchain_core.runnablesr   Úlangchain_core.utilsr   r   Úlangchain_core.utils.pydanticr   Úpydanticr   r   r   r   Útyping_extensionsr   Ú!langchain_openai.chat_models.baser   r   r   Ú	getLoggerrÜ   Úloggerr   r³   r?   r$   r   rá   r    r'   r*   rO   r(   r&   Ú<module>rõ      s¥   ðÚ  å "ã Û 	ß HÓ Hß BÕ Bã Ý =Ý Fß BÝ -ß :Ý ?ß AÓ AÝ "ç XæÝ;à	×	Ò	˜8Ó	$€ñ ˆe˜9Ñ%€Ø"& s¨C x¡.°4¸±9Ñ"<¸tÑ"CÐ �iÓ CØ! C™Z€�Ó 'ô@ô{
�nõ {
r(   