ó
    ýÞ j_  ã                  ó°  • % S r SSKJr  SSKrSSKrSSKrSSKJrJr  SSK	J
r
  SSKJrJrJr  SSKJrJr  SSKJr  SS	KJrJr  \(       a  SS
KJr  SSKJr  SSKJr  SSKJrJr  \R@                  " \!5      r"Sr#Sr$Sr% Sr&Sr'Sr( Sr)Sq*\+" SS15      r,S(S jr-S)S jr.S*S jr/S+S jr0S,S jr1Sr2 SSSS.r3S \4S!'     " S" S#\5      r5 " S$ S%5      r6/ r7S&\4S''   g)-aØ  `_ChatOpenAICodex`: experimental OAuth-backed chat model.

Wraps `ChatOpenAI` to target the ChatGPT codex backend
(`https://chatgpt.com/backend-api/codex`) and supplies refresh-aware
`Authorization` and `ChatGPT-Account-Id` headers from a
`_ChatGPTOAuthTokenProvider`.

The standard `ChatOpenAI` (API-key) flow is untouched.

!!! warning "Experimental and unofficial"

    `_ChatOpenAICodex` is not an official OpenAI API integration. Use it only
    where your OpenAI account, workspace, plan, and applicable OpenAI terms
    permit ChatGPT-authenticated Codex access. You are responsible for ensuring
    your implementation complies with OpenAI's terms, usage policies, account
    restrictions, rate limits, and safeguards.
é    )ÚannotationsN)ÚTYPE_CHECKINGÚAny)ÚLangSmithParams)ÚBaseMessageÚChatMessageÚSystemMessage)ÚFieldÚmodel_validator)Ú
ChatOpenAI)Ú_ChatGPTOAuthTokenProviderÚ_FileChatGPTOAuthTokenProvider)ÚAsyncIterator)ÚAsyncCallbackManagerForLLMRun)ÚLanguageModelInput)ÚChatGenerationChunkÚ
ChatResultz%https://chatgpt.com/backend-api/codexÚ
originatorÚ	langchainÚLANGCHAIN_CODEX_ORIGINATORzChatGPT-Account-IdÚ_codex_headersat  `_ChatOpenAICodex` is experimental and unofficial. It uses ChatGPT subscription OAuth against Codex endpoints and must only be used where permitted by your OpenAI account, workspace, plan, and applicable OpenAI terms and policies. You are responsible for implementing and operating it responsibly, including respecting OpenAI's usage policies, rate limits, and safeguards.FÚsystemÚ	developerc                 ób   • [         R                  R                  [        5      =(       d    [        $ )zGResolve the `originator` header default, honoring the env-var override.)ÚosÚenvironÚgetÚORIGINATOR_ENV_VARÚORIGINATOR_VALUE© ó    Ú\/var/www/html/gaurav/venv/lib/python3.13/site-packages/langchain_openai/chat_models/codex.pyÚ_default_originatorr#   O   s   € ä�:‰:�>‰>Ô,Ó-×AÔ1AÐAr!   c                 ó\   • [         (       a  gSq [        R                  " [        [        SS9  g)zAWarn once that `_ChatOpenAICodex` is experimental and unofficial.NTé   )Ú
stacklevel)Ú_experimental_warning_emittedÚwarningsÚwarnÚEXPERIMENTAL_UNOFFICIAL_WARNINGÚUserWarningr    r!   r"   Ú_warn_experimental_unofficialr,   T   s$   € ÷ %Ò$ØØ$(Ð!Ü‡M‚MÔ1´;È1ÓMr!   c                óú  • [        U [        5      (       a  g[        U [        5      (       a  [        U 5      $ [        U [        [
        45      (       aª  U  H£  n[        U[        5      (       a  [        U5      (       a    g[        U[        5      (       a  UR                  S5      [        ;   a    g[        U[
        5      (       d  Mq  U(       d  Mz  [        US   [        5      (       d  M”  US   [        ;   d  M£    g   gg)aQ  Return `True` if `input_` *could* contain a system-role message.

Cheap structural probe used to skip the full `_convert_input` pipeline
when there is no chance the lift logic will fire. False positives only
cost an extra conversion; false negatives would silently skip the lift,
so the probe is biased toward `True` for unknown shapes.
FTÚroler   )	Ú
isinstanceÚstrr   Ú_is_instruction_messageÚlistÚtupleÚdictr   Ú_INSTRUCTION_ROLES)Úinput_Úitems     r"   Ú_maybe_has_system_messagesr8   ]   s¾   € ô �&œ#×ÑØÜ�&œ+×&Ñ&Ü& vÓ.Ð.Ü�&œ4¤˜-×(Ñ(ÛˆDÜ˜$¤×,Ñ,Ô1HÈ×1NÑ1NÙÜ˜$¤×%Ñ%¨$¯(©(°6Ó*:Ô>PÓ*PÙä˜4¤×'Ó'ß�DÜ˜t A™w¬×,Ó,Ø˜‘GÔ1Õ1áñ ð àr!   c                ó„   • [        U [        5      =(       d*    [        U [        5      =(       a    U R                  [        ;   $ ©N)r/   r	   r   r.   r5   )Úmessages    r"   r1   r1   {   s/   € Ü�gœ}Ó-÷ Ü�7œKÓ(×O¨W¯\©\Ô=OÑ-Oðr!   c           	     óò  • / n[        U 5       GHU  u  p#[        U5      R                  nUR                  n[	        U[
        5      (       a  UR                  U5        MO  [	        U[        5      (       d+  SU SU S[        U5      R                  < S3n[        U5      e/ n[        U5       H•  u  p‰[	        U	[        5      (       a  U	R                  S5      S:w  a  SU SU SU S3n[        U5      eU	R                  SS	5      n
[	        U
[
        5      (       d  SU SU S
U S3n[        U5      eUR                  U
5        M—     UR                  S	R                  U5      5        GMX     SR                  U5      $ )aÕ  Join system/developer message content into a single `instructions` string.

Codex rejects system-role entries in the input list, so their content
is lifted into the top-level `instructions` field. Content that uses
list-of-content-blocks form is accepted only when every block is
`{"type": "text", ...}`; anything else cannot be flattened into the
string-typed `instructions` field.

Raises:
    ValueError: A system/developer message carries a non-text content block.
Ú`z` at index z has unsupported content type zH; only `str` and list-of-text-blocks are accepted by `_ChatOpenAICodex`.ÚtypeÚtextz/ contains a non-text content block at position uê    (Codex `instructions` is a string field â€” only `{"type": "text", "text": "..."}` blocks can be lifted into it). Move the non-text content to a `HumanMessage`, or pass plain instructions via the constructor or `instructions=` kwarg.Ú z has a text block at position z whose `text` is not a string.z

)Ú	enumerater>   Ú__name__Úcontentr/   r0   Úappendr2   Ú
ValueErrorr4   r   Újoin)Úsystem_messagesÚpartsÚindexr;   Úmessage_namerC   ÚmsgÚ
text_partsÚblock_indexÚblockÚ
text_values              r"   Ú_flatten_system_message_contentrP   �   sˆ  € ð €EÜ# O×4‰ˆÜ˜G“}×-Ñ-ˆØ—/‘/ˆÜ�gœs×#Ñ#Ø�L‰L˜Ô!ÙÜ˜'¤4×(Ñ(à�L�> ¨U¨Gð 4Ü˜W›×.Ñ.Ñ1ð 2JðJð ô
 ˜S“/Ð!Ø "ˆ
Ü"+¨GÖ"4ÑˆKÜ˜e¤T×*Ñ*¨e¯i©i¸Ó.?À6Ó.Ià˜�~ [°°ð 8:Ø:E¸ð G<ð<ð ô ! “oÐ%ØŸ™ 6¨2Ó.ˆJÜ˜j¬#×.Ñ.à˜�~ [°°ð 8#Ø#. -ð 0ðð ô
 ! “oÐ%Ø×Ñ˜jÖ)ñ) #5ð* 	�‰�R—W‘W˜ZÓ(×)ñG 5ðH �;‰;�uÓÐr!   z:You are ChatGPT, a large language model trained by OpenAI.T)Úuse_responses_apiÚstoreÚ	streamingúdict[str, Any]Ú_FORCED_VALUESc                  ó~  ^ • \ rS rSr% Sr\" SSS9rS\S'    \" \S9r	S	\S
'    \" \
S9rS\S'    \" SS9\SS j5       5       rSS jrSS jr      SS jrSS.       S U 4S jjjr  S!         S"U 4S jjjr  S!         S#U 4S jjjr S$     S%U 4S jjjr\S&S j5       r\S'S j5       rSrU =r$ )(Ú_ChatOpenAICodexéÝ   uŸ	  Experimental `ChatOpenAI` variant authed by ChatGPT OAuth.

This integration is unofficial and should only be used where your OpenAI
account, workspace, plan, and applicable OpenAI terms permit
ChatGPT-authenticated Codex access. Users are responsible for implementing
and operating it in compliance with OpenAI's terms, usage policies, account
restrictions, rate limits, and safeguards.

Routes requests to `https://chatgpt.com/backend-api/codex` and forces
the wire-level fields the Codex backend requires
(`use_responses_api=True`, `store=False`, `streaming=True`). These
values are forced â€” passing a conflicting value to the constructor
raises. `output_version` (a client-side `AIMessage` projection) is
not forced; pick whichever projection you want. Authorization and
`ChatGPT-Account-Id` headers are taken from `token_provider` on every
request so a freshly-refreshed access token is always used.

Example:
    ```python
    from langchain_openai.chat_models.codex import _ChatOpenAICodex
    from langchain_openai.chatgpt_oauth import login_chatgpt

    # One-time setup. The returned provider writes to the default store
    # at `~/.langchain/chatgpt-auth.json`, which `_ChatOpenAICodex` also
    # reads from by default â€” so subsequent constructions need no
    # explicit `token_provider`.
    login_chatgpt()
    model = _ChatOpenAICodex(
        model="gpt-5.5",
        instructions="You are a senior Python reviewer. Be terse.",
    )
    response = model.invoke("hello")
    ```

!!! tip "Override `instructions`"

    The Codex backend requires a top-level `instructions` value on every
    request. A generic default keeps zero-config use working, but most
    callers should override it via the constructor (above) or per call
    (`model.invoke(..., instructions=...)`). See the field's docstring
    for the full resolution rules.

!!! note

    Token storage is handled by `_FileChatGPTOAuthTokenProvider`, which
    defaults to `~/.langchain/chatgpt-auth.json` so it does not collide
    with the Codex CLI / VS Code session at `~/.codex/auth.json`.

!!! note "Always streams over the wire"

    The Codex backend only accepts streaming requests, so `streaming=True`
    is forced. `invoke` still returns a single aggregated `AIMessage` â€”
    chunks are collected internally â€” but the underlying HTTP request is
    a stream either way. Expect every call to show up as a streamed
    request in network logs and LangSmith traces.
NT)ÚdefaultÚexcluder   Útoken_provider)Údefault_factoryú
str | Noner   )rY   r0   ÚinstructionsÚbefore)Úmodec           
     ó¤  • [        5         [        U[        5      (       d  U$ [        R	                  5        H>  u  p#UR                  U5      nUb!  XC:w  a  SU SU< SU SU< S3	n[        U5      eX1U'   M@     S HI  nUR                  U5      nUb*  U[        :w  a   SU S[        < SU SU< S3	n[        U5      e[        X'   MK     UR                  S5      nUc  [        R                  " 5       nXaS'   [        U[        5      (       d  Sn[        U5      eS	 H&  nUR                  U5      c  M  S
U S3n[        U5      e   [        U5      US'   U$ )z?Apply Codex-specific defaults before the parent validator runs.z`_ChatOpenAICodex` requires `Ú=z`; got `z2`. Use `ChatOpenAI` if you need to customize this.)Úbase_urlÚopenai_api_basez?`. Use `ChatOpenAI` if you need to target a different endpoint.r[   zJ`token_provider` must implement the `_ChatGPTOAuthTokenProvider` protocol.)Úapi_keyÚopenai_api_keyzS`_ChatOpenAICodex` manages authentication via `token_provider`; drop the explicit `z8=`. Use `ChatOpenAI` if you want API-key authentication.re   )r,   r/   r4   rU   Úitemsr   rE   ÚCHATGPT_CODEX_BASE_URLr   Úfrom_default_storer   Ú	TypeErrorÚ_SyncTokenCallable)ÚclsÚvaluesÚkeyÚforcedÚsuppliedrK   Úproviders          r"   Ú_apply_codex_defaultsÚ&_ChatOpenAICodex._apply_codex_defaultsZ  sœ  € ô 	&Ô'Ü˜&¤$×'Ñ'ØˆMÜ)×/Ñ/Ö1‰KˆCØ—z‘z #“ˆHØÑ#¨Ó(:à3°C°5¸¸&¹ð DØ˜5  (¡ð ..ð.ð ô
 ! “oÐ%Ø �3‹Kñ 2ó 3ˆCØ—z‘z #“ˆHØÑ#¨Ô4JÓ(Jà3°C°5¸Ô:PÑ9Sð TØ˜5  (¡ð .3ð3ð ô
 ! “oÐ%Ü0ˆF‹Kñ 3ð —:‘:Ð.Ó/ˆØÑÜ5×HÒHÓJˆHØ'/Ð#Ñ$Ü˜(Ô$>×?Ñ?ð9ð ô ˜C“.Ð ó 1ˆCØ�z‰z˜#‹Ó*ð<Ø<?¸5ð AGðGð ô
 ! “oÐ%ñ 1ô /¨xÓ8ˆˆyÑØˆr!   c                ól   • U R                   R                  5       nU R                  UR                  5      $ r:   )r[   Ú	get_tokenÚ_build_headersÚ
account_id)ÚselfÚtokens     r"   Ú_codex_headers_syncÚ$_ChatOpenAICodex._codex_headers_sync˜  s-   € Ø×#Ñ#×-Ñ-Ó/ˆØ×"Ñ" 5×#3Ñ#3Ó4Ð4r!   c                óh   • 0 nU(       a  X[         '   U R                  b  U R                  U[        '   U$ r:   )ÚACCOUNT_ID_HEADERr   ÚORIGINATOR_HEADER)rx   rw   Úheaderss      r"   rv   Ú_ChatOpenAICodex._build_headersœ  s1   € Ø"$ˆÞØ)3Ô%Ñ&Ø�?‰?Ñ&Ø)-¯©ˆGÔ%Ñ&Øˆr!   c                ó\   • U(       d  U$ 0 UEUR                  S5      =(       d    0 EnX1S'   U$ )NÚextra_headers)r   )rx   Úpayloadr   Úmergeds       r"   Ú_merge_codex_headersÚ%_ChatOpenAICodex._merge_codex_headers¤  s6   € ö
 ØˆNØD�GÐD §¡¨OÓ <× BÀÐDˆØ#)�Ñ Øˆr!   )Ústopc               ó~  >• UR                  [        S5      nUn[        U5      (       a±  U R                  U5      R	                  5       nU Vs/ sH  n[        U5      (       d  M  UPM     nnU(       ah  U Vs/ sH  n[        U5      (       a  M  UPM     n	n[        U5      n
UR                  S5      nUb   [        R                  S[        U
5      5        OX£S'   U	n[        TU ]0  " U4SU0UD6nUR                  S5      c  U R                  US'   Ub  UOU R                  5       nU R                  XÍ5      $ s  snf s  snf )uê  Build the request payload and attach Codex auth headers.

Lifts any `SystemMessage` content out of the input list into the
top-level `instructions` field, since Codex rejects `SystemMessage`
chat turns. See the `instructions` field docstring for the
precedence rules.

Fast path: when the input can't carry a `SystemMessage`, skip the
local conversion and delegate `input_` straight to super â€” that
way `_convert_input` only runs once (inside super) instead of once
here and again there.
Nr^   z³Both `instructions=` and a `SystemMessage` were provided; the explicit `instructions=` kwarg wins and the `SystemMessage` content is discarded for this call. Discarded length: %d.r‡   )ÚpopÚ_CODEX_HEADERS_KWARGr8   Ú_convert_inputÚto_messagesr1   rP   r   ÚloggerÚwarningÚlenÚsuperÚ_get_request_payloadr^   rz   r…   )rx   r6   r‡   ÚkwargsÚcodex_headersÚpayload_inputÚmessagesÚmrG   Ú
non_systemÚliftedÚexplicitrƒ   r   Ú	__class__s                 €r"   r‘   Ú%_ChatOpenAICodex._get_request_payload¯  s3  ø€ ð& Ÿ
™
Ô#7¸Ó>ˆØ,2ˆÜ% f×-Ñ-Ø×*Ñ*¨6Ó2×>Ñ>Ó@ˆHÙ*2ÓQ©( QÔ6MÈa×6PŸq©(ˆOÐQÞÙ)1ÓT© AÔ9PÐQR×9SŸa©�
ÐTÜ8¸ÓI�Ø!Ÿ:™: nÓ5�ØÑ'Ü—N‘Nð;ô ˜F›õð .4˜>Ñ*Ø *�ä‘'Ò.¨}ÑRÀ4ÐRÈ6ÑRˆð
 �;‰;�~Ó&Ñ.Ø&*×&7Ñ&7ˆG�NÑ#ð +Ñ6‰M¸D×<TÑ<TÓ<Vð 	ð ×(Ñ(¨Ó:Ð:ùòC RùâTs   ÁD5Á$D5Á7D:ÂD:c              ‹  óÒ   >#   • U R                   R                  5       I S h  v•N nU R                  UR                  5      U[        '   [
        TU ]  " U4X#S.UD6I S h  v•N $  NA N7f©N)r‡   Úrun_manager)r[   Ú
aget_tokenrv   rw   rŠ   r�   Ú
_agenerate)rx   r•   r‡   rž   r’   ry   rš   s         €r"   r    Ú_ChatOpenAICodex._agenerateé  so   øé € ð ×)Ñ)×4Ñ4Ó6×6ˆØ'+×':Ñ':¸5×;KÑ;KÓ'LˆÔ#Ñ$Ü‘WÒ'Øð
Øñ
Ø<Bñ
÷ 
ð 	
ñ 7ñ
ùs!   ƒA'¡A#¢<A'ÁA%ÁA'Á%A'c               óæ   >#   • U R                   R                  5       I S h  v•N nU R                  UR                  5      U[        '   [
        TU ]  " U4X#S.UD6  S h  v•N nU7v •  M   NI N
 g 7fr�   )r[   rŸ   rv   rw   rŠ   r�   Ú_astream)rx   r•   r‡   rž   r’   ry   Úchunkrš   s          €r"   r£   Ú_ChatOpenAICodex._astreamû  sx   øé € ð ×)Ñ)×4Ñ4Ó6×6ˆØ'+×':Ñ':¸5×;KÑ;KÓ'LˆÔ#Ñ$Ü ™7Ò+Øð
Øñ
Ø<Bò
÷ 	�%ð �Kñ 7ñ	ñ 
ùs3   ƒA1¡A+¢9A1ÁA/ÁA-Á A/Á#	A1Á-A/Á/A1c                ó6   >• [         TU ]  " SSU0UD6nSUS'   U$ )Nr‡   zopenai-codexÚls_providerr    )r�   Ú_get_ls_params)rx   r‡   r’   Úparamsrš   s       €r"   r¨   Ú_ChatOpenAICodex._get_ls_params  s+   ø€ ô ‘Ò'Ñ<¨TÐ<°VÑ<ˆØ .ˆˆ}ÑØˆr!   c                ó   • g)Nzopenai-codex-chatr    ©rx   s    r"   Ú	_llm_typeÚ_ChatOpenAICodex._llm_type  s   € à"r!   c                ó   • g)zE`_ChatOpenAICodex` is not serializable (holds a live token provider).Fr    )rl   s    r"   Úis_lc_serializableÚ#_ChatOpenAICodex.is_lc_serializable  s   € ð r!   r    )rm   rT   ÚreturnrT   )r²   údict[str, str])rw   r]   r²   r³   )rƒ   rT   r   r³   r²   rT   )r6   r   r‡   úlist[str] | Noner’   r   r²   r4   )NN)
r•   úlist[BaseMessage]r‡   r´   rž   ú$AsyncCallbackManagerForLLMRun | Noner’   r   r²   r   )
r•   rµ   r‡   r´   rž   r¶   r’   r   r²   z"AsyncIterator[ChatGenerationChunk]r:   )r‡   r´   r’   r   r²   r   ©r²   r0   )r²   Úbool)rB   Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r
   r[   Ú__annotations__r#   r   ÚDEFAULT_INSTRUCTIONSr^   r   Úclassmethodrr   rz   rv   r…   r‘   r    r£   r¨   Úpropertyr­   r°   Ú__static_attributes__Ú__classcell__)rš   s   @r"   rW   rW   Ý   s¢  ø‡ ñ7ñr  ¨°dÑ;€N�CÓ;ðñ #Ð3FÑG€J�
ÓGðñ& Ð&:Ñ;€L�#Ó;ð$ñL ˜(Ñ#Øó:ó ó $ð:ôx5ôð	Ø%ð	Ø0>ð	à	ô	ð "&ñ	8;à"ð8;ð ð	8;ð
 ð8;ð 
÷8;ð 8;ðz "&Ø<@ð	
à#ð
ð ð
ð :ð	
ð
 ð
ð 
÷
ð 
ð* "&Ø<@ð	à#ðð ðð :ð	ð
 ðð 
,÷ð ð" (,ðØ$ðØ7:ðà	÷ð ð ó#ó ð#ð óó ör!   rW   c                  ó0   • \ rS rSrSrSrSS jrSS jrSrg)	rk   i  a  Sync callable wrapper around a token provider for the OpenAI SDK.

The OpenAI Python SDK accepts a callable returning a string for `api_key`.
Wrapping the provider lets the SDK fetch a freshly-refreshed access token
on every request without exposing the provider's other methods.
©Ú	_providerc                ó   • Xl         g r:   rÄ   )rx   rq   s     r"   Ú__init__Ú_SyncTokenCallable.__init__&  s   € Ø!�r!   c                ó6   • U R                   R                  5       $ r:   )rÅ   Úget_access_tokenr¬   s    r"   Ú__call__Ú_SyncTokenCallable.__call__)  s   € Ø�~‰~×.Ñ.Ó0Ð0r!   N)rq   r   r²   ÚNoner·   )	rB   r¹   rº   r»   r¼   Ú	__slots__rÇ   rË   rÁ   r    r!   r"   rk   rk     s   † ñð €Iô"÷1r!   rk   z	list[str]Ú__all__r·   )r²   rÍ   )r6   r   r²   r¸   )r;   r   r²   r¸   )rG   rµ   r²   r0   )8r¼   Ú
__future__r   Úloggingr   r(   Útypingr   r   Ú*langchain_core.language_models.chat_modelsr   Úlangchain_core.messagesr   r   r	   Úpydanticr
   r   Ú!langchain_openai.chat_models.baser   Úlangchain_openai.chatgpt_oauthr   r   Úcollections.abcr   Úlangchain_core.callbacksr   Úlangchain_core.language_modelsr   Úlangchain_core.outputsr   r   Ú	getLoggerrB   r�   rh   r~   r   r   r}   rŠ   r*   r'   Ú	frozensetr5   r#   r,   r8   r1   rP   r¾   rU   r½   rW   rk   rÏ   r    r!   r"   Ú<module>rÞ      s  ðòõ$ #ã Û 	Û ß %å Fß KÑ Kß +å 8÷ö
 Ý-åFÝAßFð 
×	Ò	˜8Ó	$€ð AÐ Ø Ð ØÐ ðð 2Ð Ø(Ð Ø'Ð ððð  ð !&Ð Ù ¨+Ð6Ó7Ð ôBô
Nôô<ô1ðh TÐ ðð ØØñ"€�ó ð
ô6|�zô |÷~	1ñ 1ð" €ˆÔ r!   