§
    ‰eîiu ã                   óö  — U d Z ddlZddlZddlZddlZddlZddlZddlmZ ddl	m
Z
 ddlmZmZmZmZmZ ddlmZ 	 ddlZn# e$ r dZY nw xY w ej        e¦  «        Zddd	d
dœZdddddddœZdZdZdZddddddddddddddddœZdZde de!fd„Z"dee!         fd„Z#	 dtde dee!         de!fd„Z$de de%fd „Z&de de%fd!„Z'de de%fd"„Z(d#d$gZ)d$Z*d%Z+d&d'gZ,d(Z-da.ee          e/d)<   de fd*„Z0d+Z1d,Z2de fd-„Z3d.e de%fd/„Z4de fd0„Z5d1e dz  de%fd2„Z6d1e dz  de%fd3„Z7d1e dz  de%fd4„Z8d1e dz  de9e          fd5„Z:dud6e d1e d7e;fd8„Z<d9e fd:„Z=deee ef                  fd;„Z>deee ef                  fd<„Z?dee          fd=„Z@d>ee ef         de%fd?„ZAd@dAœdBe dCe%dee ef         fdD„ZBd>ee ef         dee          fdE„ZCddFœdGe dBe dHe!dIee9         ddf
dJ„ZDdtd>eee ef                  dee          fdK„ZEdLe d>eee ef                  dee          fdM„ZFdee          fdN„ZGdee          fdO„ZHdPZIdQZJdRZKdSZL e
¦   «         dTz  ZMdeNfdU„ZOdeee ef                  fdV„ZPdeee ef                  fdW„ZQde de%fdX„ZRdvde dYe%de fdZ„ZSd[e de fd\„ZTd]ee         dee         fd^„ZUd_e dee e f         fd`„ZVdaedeee ef                  fdb„ZWdddcœddedee!dfeeX         defdg„ZYdhee ef         deee ef                  fdi„ZZdjedefdk„Z[	 dtdlee         d1e dz  deee         ee         f         fdm„Z\	 	 	 	 	 	 dwde dlee         d]eee                  dnee!         doeee ef                  dpee          dqe%dYe%dee!         d1e dz  dre%dee ef         fds„Z]dS )xuâ  Anthropic Messages API adapter for Hermes Agent.

Translates between Hermes's internal OpenAI-style message format and
Anthropic's Messages API. Follows the same pattern as the codex_responses
adapter â€” all provider-specific logic is isolated here.

Auth supports:
  - Regular API keys (sk-ant-api*) â†’ x-api-key header
  - OAuth setup-tokens (sk-ant-oat*) â†’ Bearer auth + beta header
  - Claude Code credentials (~/.claude.json or ~/.claude/.credentials.json) â†’ Bearer auth
é    N)ÚPath)Úget_hermes_home)ÚAnyÚDictÚListÚOptionalÚTuple)Únormalize_proxy_env_varsi }  i€>  é@  i   )ÚxhighÚhighÚmediumÚlowÚmaxr   r   r   r   )r   r   r   r   r   Úminimal)ú4-7ú4.7)z4-6z4.6r   r   i ô i ú  i    é   i   )zclaude-opus-4-7zclaude-opus-4-6zclaude-sonnet-4-6zclaude-opus-4-5zclaude-sonnet-4-5zclaude-haiku-4-5zclaude-opus-4zclaude-sonnet-4zclaude-3-7-sonnetzclaude-3-5-sonnetzclaude-3-5-haikuzclaude-3-opuszclaude-3-sonnetzclaude-3-haikuÚminimaxÚmodelÚreturnc                 óö   — |                       ¦   «                              dd¦  «        }d}t          }t                               ¦   «         D ]-\  }}||v r$t          |¦  «        t          |¦  «        k    r|}|}Œ.|S )aÔ  Look up the max output token limit for an Anthropic model.

    Uses substring matching against _ANTHROPIC_OUTPUT_LIMITS so date-stamped
    model IDs (claude-sonnet-4-5-20250929) and variant suffixes (:1m, :fast)
    resolve correctly.  Longest-prefix match wins to avoid e.g. "claude-3-5"
    matching before "claude-3-5-sonnet".

    Normalizes dots to hyphens so that model names like
    ``anthropic/claude-opus-4.6`` match the ``claude-opus-4-6`` table key.
    ú.Ú-Ú )ÚlowerÚreplaceÚ_ANTHROPIC_DEFAULT_OUTPUT_LIMITÚ_ANTHROPIC_OUTPUT_LIMITSÚitemsÚlen)r   ÚmÚbest_keyÚbest_valÚkeyÚvals         ú9/home/div/.hermes/hermes-agent/agent/anthropic_adapter.pyÚ_get_anthropic_max_outputr(   d   sy   € ð 	�Š‰Œ×Ò˜c 3Ñ'Ô'€AØ€HÝ.€HÝ,×2Ò2Ñ4Ô4ð ð ‰ˆˆSØ�!ˆ8ˆ8�˜C™œ¥3 x¡=¤=Ò0Ð0ØˆHØˆHøØ€Oó    c                 óú   — t          | t          ¦  «        rdS t          | t          t          f¦  «        sdS 	 ddl}|                     | ¦  «        sdS n# t          $ r Y dS w xY wt          | ¦  «        }|dk    r|ndS )añ  Return ``value`` floored to a positive int, or ``None`` if it is not a
    finite positive number. Ported from openclaw/openclaw#66664.

    Anthropic's Messages API rejects ``max_tokens`` values that are 0,
    negative, non-integer, or non-finite with HTTP 400. Python's ``or``
    idiom (``max_tokens or fallback``) correctly catches ``0`` but lets
    negative ints and fractional floats (``-1``, ``0.5``) through to the
    API, producing a user-visible failure instead of a local error.
    Nr   )Ú
isinstanceÚboolÚintÚfloatÚmathÚisfiniteÚ	Exception)Úvaluer/   Úflooreds      r'   Ú&_resolve_positive_anthropic_max_tokensr4   y   s¡   € õ �%�ÑÔð ØˆtÝ�e�c¥5˜\Ñ*Ô*ð ØˆtðØˆˆˆØ�}Š}˜UÑ#Ô#ð 	Ø�4ð	øåð ð ð Øˆtˆtðøøøå�%‰jŒj€GØ ’k�kˆ7ˆ7 tÐ+s   ·A Á
A!Á A!Úcontext_lengthc                 ó‚   — t          | ¦  «        }|�|S t          |¦  «        }|dk    r|S t          d|›d| ›d�¦  «        ‚)u‹  Resolve the ``max_tokens`` budget for an Anthropic Messages call.

    Prefers ``requested`` when it is a positive finite number; otherwise
    falls back to the model's output ceiling. Raises ``ValueError`` if no
    positive budget can be resolved (should not happen with current model
    table defaults, but guards against a future regression where
    ``_get_anthropic_max_output`` could return ``0``).

    Separately, callers apply a context-window clamp â€” this resolver does
    not, to keep the positive-value contract independent of endpoint
    specifics.

    Ported from openclaw/openclaw#66664 (resolveAnthropicMessagesMaxTokens).
    Nr   zJAnthropic Messages adapter requires a positive max_tokens value for model z; got z and no model default resolved.)r4   r(   Ú
ValueError)Ú	requestedr   r5   ÚresolvedÚfallbacks        r'   Ú&_resolve_anthropic_messages_max_tokensr;   “   ss   € õ& 6°iÑ@Ô@€HØÐØˆÝ(¨Ñ/Ô/€HØ�!‚|€|ØˆÝ
ð	MØð	Mð 	MØ )ð	Mð 	Mð 	Mñô ð r)   c                 óD   ‡ — t          ˆ fd„t          D ¦   «         ¦  «        S )zBReturn True for Claude 4.6+ models that support adaptive thinking.c              3   ó    •K  — | ]}|‰v V — Œ	d S ©N© ©Ú.0Úvr   s     €r'   ú	<genexpr>z._supports_adaptive_thinking.<locals>.<genexpr>´   s'   øè è € ÐAÐA˜aˆq�EˆzÐAÐAÐAÐAÐAÐAr)   )ÚanyÚ_ADAPTIVE_THINKING_SUBSTRINGS©r   s   `r'   Ú_supports_adaptive_thinkingrG   ²   s'   ø€ åÐAÐAÐAÐAÕ#@ÐAÑAÔAÑAÔAÐAr)   c                 óD   ‡ — t          ˆ fd„t          D ¦   «         ¦  «        S )uJ  Return True for models that accept the 'xhigh' adaptive effort level.

    Opus 4.7 introduced xhigh as a distinct level between high and max.
    Pre-4.7 adaptive models (Opus/Sonnet 4.6) only accept low/medium/high/max
    and reject xhigh with an HTTP 400. Callers should downgrade xhighâ†’max
    when this returns False.
    c              3   ó    •K  — | ]}|‰v V — Œ	d S r>   r?   r@   s     €r'   rC   z)_supports_xhigh_effort.<locals>.<genexpr>¿   s'   øè è € Ð<Ð<˜aˆq�EˆzÐ<Ð<Ð<Ð<Ð<Ð<r)   )rD   Ú_XHIGH_EFFORT_SUBSTRINGSrF   s   `r'   Ú_supports_xhigh_effortrK   ·   s)   ø€ õ Ð<Ð<Ð<Ð<Õ#;Ð<Ñ<Ô<Ñ<Ô<Ð<r)   c                 óD   ‡ — t          ˆ fd„t          D ¦   «         ¦  «        S )a9  Return True for models that 400 on any non-default temperature/top_p/top_k.

    Opus 4.7 explicitly rejects sampling parameters; later Claude releases are
    expected to follow suit.  Callers should omit these fields entirely rather
    than passing zero/default values (the API rejects anything non-null).
    c              3   ó    •K  — | ]}|‰v V — Œ	d S r>   r?   r@   s     €r'   rC   z+_forbids_sampling_params.<locals>.<genexpr>É   s'   øè è € ÐBÐB˜aˆq�EˆzÐBÐBÐBÐBÐBÐBr)   )rD   Ú_NO_SAMPLING_PARAMS_SUBSTRINGSrF   s   `r'   Ú_forbids_sampling_paramsrO   Â   s)   ø€ õ ÐBÐBÐBÐBÕ#AÐBÑBÔBÑBÔBÐBr)   zinterleaved-thinking-2025-05-14z&fine-grained-tool-streaming-2025-05-14zfast-mode-2026-02-01zclaude-code-20250219zoauth-2025-04-20z2.1.74Ú_claude_code_version_cachec                  ód  — ddl } dD ]£}	 |                      |dgddd¬¦  «        }|j        dk    rj|j                             ¦   «         rQ|j                             ¦   «                              ¦   «         d         }|r|d                              ¦   «         r|c S Œ”# t          $ r Y Œ w xY wt          S )a2  Detect the installed Claude Code version, fall back to a static constant.

    Anthropic's OAuth infrastructure validates the user-agent version and may
    reject requests with a version that's too old.  Detecting dynamically means
    users who keep Claude Code updated never hit stale-version 400s.
    r   N)Úclaudeúclaude-codez	--versionTé   ©Úcapture_outputÚtextÚtimeout)	Ú
subprocessÚrunÚ
returncodeÚstdoutÚstripÚsplitÚisdigitr1   Ú_CLAUDE_CODE_VERSION_FALLBACK)Ú_spÚcmdÚresultÚversions       r'   Ú_detect_claude_code_versionre   ï   sá   € ð ÐÐÐà(ð ð ˆð	Ø—W’WØ�kÐ"Ø#¨$¸ð ñ ô ˆFð Ô  AÒ%Ð%¨&¬-×*=Ò*=Ñ*?Ô*?Ð%à œ-×-Ò-Ñ/Ô/×5Ò5Ñ7Ô7¸Ô:�Øð #˜w qœz×1Ò1Ñ3Ô3ð #Ø"�N�N�NøøÝð 	ð 	ð 	ØˆDð	øøøå(Ð(s   ŠBBÂ
B(Â'B(z9You are Claude Code, Anthropic's official CLI for Claude.Úmcp_c                  ó:   — t           €t          ¦   «         a t           S )zKLazily detect the installed Claude Code version when OAuth headers need it.)rP   re   r?   r)   r'   Ú_get_claude_code_versionrh     s   € õ "Ð)Ý%@Ñ%BÔ%BÐ"Ý%Ð%r)   r%   c                 óÆ   — | sdS |                       d¦  «        rdS |                       d¦  «        rdS |                       d¦  «        rdS |                       d¦  «        rdS dS )uÍ  Check if the key is an Anthropic OAuth/setup token.

    Positively identifies Anthropic OAuth tokens by their key format:
    - ``sk-ant-`` prefix (but NOT ``sk-ant-api``) â†’ setup tokens, managed keys
    - ``eyJ`` prefix â†’ JWTs from the Anthropic OAuth flow
    - ``cc-`` prefix â†’ Claude Code OAuth access tokens (from CLAUDE_CODE_OAUTH_TOKEN)

    Non-Anthropic keys (MiniMax, Alibaba, etc.) don't match any pattern
    and correctly return False.
    Fz
sk-ant-apizsk-ant-TÚeyJzcc-©Ú
startswith)r%   s    r'   Ú_is_oauth_tokenrm     sz   € ð ð Øˆuà
‡~‚~�lÑ#Ô#ð Øˆuà
‡~‚~�iÑ Ô ð Øˆtà
‡~‚~�eÑÔð Øˆtà
‡~‚~�eÑÔð ØˆtØˆ5r)   c                 óL   — | sdS t          | ¦  «                             ¦   «         S )záNormalize SDK/base transport URL values to a plain string for inspection.

    Some client objects expose ``base_url`` as an ``httpx.URL`` instead of a raw
    string.  Provider/auth detection should accept either shape.
    r   )Ústrr]   ©Úbase_urls    r'   Ú_normalize_base_url_textrr   0  s)   € ð ð ØˆrÝˆx‰=Œ=×ÒÑ Ô Ð r)   rq   c                 ó†   — t          | ¦  «        }|sdS |                     d¦  «                             ¦   «         }d|v rdS dS )a#  Return True for non-Anthropic endpoints using the Anthropic Messages API.

    Third-party proxies (Azure AI Foundry, AWS Bedrock, self-hosted) authenticate
    with their own API keys via x-api-key, not Anthropic OAuth tokens. OAuth
    detection should be skipped for these endpoints.
    Fú/zanthropic.comT)rr   Úrstripr   ©rq   Ú
normalizeds     r'   Ú"_is_third_party_anthropic_endpointrx   ;  sR   € õ *¨(Ñ3Ô3€JØð ØˆuØ×"Ò" 3Ñ'Ô'×-Ò-Ñ/Ô/€JØ˜*Ð$Ð$ØˆuØˆ4r)   c                 óœ   — t          | ¦  «        }|sdS |                     d¦  «                             ¦   «                              d¦  «        S )zEReturn True for Kimi's /coding endpoint that requires claude-code UA.Frt   zhttps://api.kimi.com/coding©rr   ru   r   rl   rv   s     r'   Ú_is_kimi_coding_endpointr{   K  sK   € å)¨(Ñ3Ô3€JØð ØˆuØ×Ò˜SÑ!Ô!×'Ò'Ñ)Ô)×4Ò4Ð5RÑSÔSÐSr)   c                 ó    — t          | ¦  «        }|sdS |                     d¦  «                             ¦   «         }|                     d¦  «        S )a@  Return True for Anthropic-compatible providers that require Bearer auth.

    Some third-party /anthropic endpoints implement Anthropic's Messages API but
    require Authorization: Bearer *** of Anthropic's native x-api-key header.
    MiniMax's global and China Anthropic-compatible endpoints follow this pattern.
    Frt   )z https://api.minimax.io/anthropicz"https://api.minimaxi.com/anthropicrz   rv   s     r'   Ú_requires_bearer_authr}   S  sR   € õ *¨(Ñ3Ô3€JØð ØˆuØ×"Ò" 3Ñ'Ô'×-Ò-Ñ/Ô/€JØ× Ò Ð!kÑlÔlÐlr)   c                 óP   — t          | ¦  «        rd„ t          D ¦   «         S t          S )uf  Return the beta headers that are safe for the configured endpoint.

    MiniMax's Anthropic-compatible endpoints (Bearer-auth) reject requests
    that include Anthropic's ``fine-grained-tool-streaming`` beta â€” every
    tool-use message triggers a connection error.  Strip that beta for
    Bearer-auth endpoints while keeping all other betas intact.
    c                 ó(   — g | ]}|t           k    ¯|‘ŒS r?   )Ú_TOOL_STREAMING_BETA©rA   Úbs     r'   ú
<listcomp>z._common_betas_for_base_url.<locals>.<listcomp>j  s#   € ÐFÐFÐF�a¨AÕ1EÒ,EÐ,E�Ð,EÐ,EÐ,Er)   )r}   Ú_COMMON_BETASrp   s    r'   Ú_common_betas_for_base_urlr…   a  s/   € õ ˜XÑ&Ô&ð GØFÐF�=ÐFÑFÔFÐFÝÐr)   Úapi_keyrX   c                 óÈ  — t           €t          d¦  «        ‚t          ¦   «          ddlm} t          |¦  «        }t          |t          t          f¦  «        r|dk    r|nd}d |t          |¦  «        d¬¦  «        i}|rAd	| 	                    ¦   «         v }|r$d
|vr | 
                    d¦  «        |d<   d
di|d<   n||d<   t          |¦  «        }t          |¦  «        r(| |d<   ddi|rdd                     |¦  «        ini ¥|d<   nÎt          |¦  «        r"| |d<   |rdd                     |¦  «        i|d<   n�t          |¦  «        r"| |d<   |rdd                     |¦  «        i|d<   nlt!          | ¦  «        r<|t"          z   }	| |d<   d                     |	¦  «        dt%          ¦   «         › d�ddœ|d<   n!| |d<   |rdd                     |¦  «        i|d<   t          j        di |¤ŽS )a³  Create an Anthropic client, auto-detecting setup-tokens vs API keys.

    If *timeout* is provided it overrides the default 900s read timeout.  The
    connect timeout stays at 10s.  Callers pass this from the per-provider /
    per-model ``request_timeout_seconds`` config so Anthropic-native and
    Anthropic-compatible providers respect the same knob as OpenAI-wire
    providers.

    Returns an anthropic.Anthropic instance.
    NzpThe 'anthropic' package is required for the Anthropic provider. Install it with: pip install 'anthropic>=0.39.0'r   ©ÚTimeoutç      Œ@rX   ç      $@©rX   Úconnectz	azure.comzapi-versionrt   rq   z
2025-04-15Údefault_queryr†   ú
User-Agentzclaude-code/0.1.0úanthropic-betaÚ,Údefault_headersÚ
auth_tokenúclaude-cli/ú (external, cli)Úcli)r�   z
user-agentzx-appr?   )Ú_anthropic_sdkÚImportErrorr
   Úhttpxr‰   rr   r+   r-   r.   r   ru   r…   r{   Újoinr}   rx   rm   Ú_OAUTH_ONLY_BETASrh   Ú	Anthropic)
r†   rq   rX   r‰   Únormalized_base_urlÚ_read_timeoutÚkwargsÚ_is_azure_endpointÚcommon_betasÚ	all_betass
             r'   Úbuild_anthropic_clientr£   n  sž  € õ ÐÝð?ñ
ô 
ð 	
õ
 ÑÔÐàÐÐÐÐÐå2°8Ñ<Ô<ÐÝ *¨7µS½%°LÑ AÔ AÐ]ÀgÐPQÂkÀk�G�GÐX]€Mà�7�7¥5¨Ñ#7Ô#7ÀÐFÑFÔFð€Fð ð 
5ð
 )Ð,?×,EÒ,EÑ,GÔ,GÐGÐØð 	5 -Ð7JÐ"JÐ"JØ!4×!;Ò!;¸CÑ!@Ô!@ˆF�:ÑØ'4°lÐ&CˆF�?Ñ#Ð#à!4ˆF�:ÑÝ-Ð.AÑBÔB€Lå Ñ)Ô)ð *Sð $ˆˆyÑàÐ-ð%
à>JÐRÐ! 3§8¢8¨LÑ#9Ô#9Ð:Ð:ÐPRð%
ˆÐ Ñ!Ð!õ 
Ð2Ñ	3Ô	3ð !Sð  'ˆˆ|ÑØð 	SØ)9¸3¿8º8ÀLÑ;QÔ;QÐ(RˆFÐ$Ñ%øÝ	+¨HÑ	5Ô	5ð Sð
 $ˆˆyÑØð 	SØ)9¸3¿8º8ÀLÑ;QÔ;QÐ(RˆFÐ$Ñ%øÝ	˜Ñ	!Ô	!ð Sð !Õ#4Ñ4ˆ	Ø&ˆˆ|Ñà!Ÿhšh yÑ1Ô1ØTÕ(@Ñ(BÔ(BÐTÐTÐTØð%
ð %
ˆÐ Ñ!Ð!ð $ˆˆyÑØð 	SØ)9¸3¿8º8ÀLÑ;QÔ;QÐ(RˆFÐ$Ñ%åÔ#Ð-Ð- fÐ-Ð-Ð-r)   Úregionc                 óÄ   — t           €t          d¦  «        ‚t          t           d¦  «        st          d¦  «        ‚ddlm} t          j        |  |dd¬	¦  «        ¬
¦  «        S )uh  Create an AnthropicBedrock client for Bedrock Claude models.

    Uses the Anthropic SDK's native Bedrock adapter, which provides full
    Claude feature parity: prompt caching, thinking budgets, adaptive
    thinking, fast mode â€” features not available via the Converse API.

    Auth uses the boto3 default credential chain (IAM roles, SSO, env vars).
    NznThe 'anthropic' package is required for the Bedrock provider. Install it with: pip install 'anthropic>=0.39.0'ÚAnthropicBedrockzWanthropic.AnthropicBedrock not available. Upgrade with: pip install 'anthropic>=0.39.0'r   rˆ   rŠ   r‹   rŒ   )Ú
aws_regionrX   )r—   r˜   Úhasattrr™   r‰   r¦   )r¤   r‰   s     r'   Úbuild_anthropic_bedrock_clientr©   Ä  s�   € õ ÐÝð?ñ
ô 
ð 	
õ •>Ð#5Ñ6Ô6ð 
Ýð<ñ
ô 
ð 	
ð ÐÐÐÐÐåÔ*ØØ� ¨tÐ4Ñ4Ô4ðñ ô ð r)   c                  óÎ  — ddl } ddl} | j        ¦   «         dk    rdS 	  |j        g d¢ddd¬¦  «        }n2# t          |j        f$ r t                               d¦  «         Y dS w xY w|j        dk    rt                               d	¦  «         dS |j	         
                    ¦   «         }|sdS 	 t          j        |¦  «        }n0# t          j        $ r t                               d
¦  «         Y dS w xY w|                     d¦  «        }|r\t          |t           ¦  «        rG|                     dd¦  «        }|r/||                     dd¦  «        |                     dd¦  «        ddœS dS )a¿  Read Claude Code OAuth credentials from the macOS Keychain.

    Claude Code >=2.1.114 stores credentials in the macOS Keychain under the
    service name "Claude Code-credentials" rather than (or in addition to)
    the JSON file at ~/.claude/.credentials.json.

    The password field contains a JSON string with the same claudeAiOauth
    structure as the JSON file.

    Returns dict with {accessToken, refreshToken?, expiresAt?} or None.
    r   NÚDarwin)Úsecurityzfind-generic-passwordz-szClaude Code-credentialsz-wTrT   rU   z5Keychain: security command not available or timed outz6Keychain: no entry found for 'Claude Code-credentials'z/Keychain: credentials payload is not valid JSONÚclaudeAiOauthÚaccessTokenr   ÚrefreshTokenÚ	expiresAtÚmacos_keychain©r®   r¯   r°   Úsource)ÚplatformrY   ÚsystemrZ   ÚOSErrorÚTimeoutExpiredÚloggerÚdebugr[   r\   r]   ÚjsonÚloadsÚJSONDecodeErrorÚgetr+   Údict)r´   rY   rc   ÚrawÚdataÚ
oauth_dataÚaccess_tokens          r'   Ú+_read_claude_code_credentials_from_keychainrÃ   ß  sÄ  € ð €O€O€OØÐÐÐà€x„ÑÔ˜HÒ$Ð$Øˆtðà�”ðð ð ð  ØØð
ñ 
ô 
ˆˆøõ �ZÔ.Ð/ð ð ð Ý�ŠÐLÑMÔMÐMØˆtˆtðøøøð Ô˜AÒÐÝ�ŠÐMÑNÔNÐNØˆtà
Œ-×
Ò
Ñ
Ô
€CØð ØˆtðÝŒz˜#‰ŒˆˆøÝÔð ð ð Ý�ŠÐFÑGÔGÐGØˆtˆtðøøøð —’˜/Ñ*Ô*€JØð •j ­TÑ2Ô2ð Ø!—~’~ m°RÑ8Ô8ˆØð 	à+Ø *§¢¨~¸rÑ BÔ BØ'Ÿ^š^¨K¸Ñ;Ô;Ø*ð	ð ð ð ˆ4s!   Ÿ6 ¶+A%Á$A%Â-C Ã)C/Ã.C/c                  óF  — t          ¦   «         } | r| S t          j        ¦   «         dz  dz  }|                     ¦   «         rá	 t	          j        |                     d¬¦  «        ¦  «        }|                     d¦  «        }|r\t          |t          ¦  «        rG|                     dd¦  «        }|r/||                     dd¦  «        |                     d	d
¦  «        ddœS nD# t          j
        t          t          f$ r%}t                               d|¦  «         Y d}~nd}~ww xY wdS )u4  Read refreshable Claude Code OAuth credentials.

    Checks two sources in order:
      1. macOS Keychain (Darwin only) â€” "Claude Code-credentials" entry
      2. ~/.claude/.credentials.json file

    This intentionally excludes ~/.claude.json primaryApiKey. Opencode's
    subscription flow is OAuth/setup-token based with refreshable credentials,
    and native direct Anthropic provider usage should follow that path rather
    than auto-detecting Claude's first-party managed key.

    Returns dict with {accessToken, refreshToken?, expiresAt?} or None.
    ú.claudeú.credentials.jsonúutf-8©Úencodingr­   r®   r   r¯   r°   r   Úclaude_code_credentials_filer²   z.Failed to read ~/.claude/.credentials.json: %sN)rÃ   r   ÚhomeÚexistsrº   r»   Ú	read_textr½   r+   r¾   r¼   r¶   ÚIOErrorr¸   r¹   )Úkc_credsÚ	cred_pathrÀ   rÁ   rÂ   Úes         r'   Úread_claude_code_credentialsrÒ     sF  € õ ;Ñ<Ô<€HØð Øˆõ ”	‘”˜iÑ'Ð*=Ñ=€IØ×ÒÑÔð Nð	NÝ”:˜i×1Ò1¸7Ð1ÑCÔCÑDÔDˆDØŸš /Ñ2Ô2ˆJØð �j¨µTÑ:Ô:ð Ø)Ÿ~š~¨m¸RÑ@Ô@�Øð à'3Ø(2¯ª°~ÀrÑ(JÔ(JØ%/§^¢^°KÀÑ%CÔ%CØ"@ð	ð ð øøõ Ô$¥g­wÐ7ð 	Nð 	Nð 	NÝ�LŠLÐIÈ1ÑMÔMÐMÐMÐMÐMÐMÐMøøøøð	Nøøøð ˆ4s   ÁBC ÃDÃ9DÄDc                  óÜ  — t          j        ¦   «         dz  } |                      ¦   «         rÁ	 t          j        |                      d¬¦  «        ¦  «        }|                     dd¦  «        }t          |t          ¦  «        r(| 	                    ¦   «         r| 	                    ¦   «         S nD# t          j
        t          t          f$ r%}t                               d|¦  «         Y d}~nd}~ww xY wdS )zJRead Claude's native managed key from ~/.claude.json for diagnostics only.z.claude.jsonrÇ   rÈ   ÚprimaryApiKeyr   z!Failed to read ~/.claude.json: %sN)r   rË   rÌ   rº   r»   rÍ   r½   r+   ro   r]   r¼   r¶   rÎ   r¸   r¹   )Úclaude_jsonrÀ   Úprimary_keyrÑ   s       r'   Úread_claude_managed_keyr×   C  sî   € å”)‘+”+ Ñ.€KØ×ÒÑÔð Að	AÝ”:˜k×3Ò3¸WÐ3ÑEÔEÑFÔFˆDØŸ(š( ?°BÑ7Ô7ˆKÝ˜+¥sÑ+Ô+ð +°×0AÒ0AÑ0CÔ0Cð +Ø"×(Ò(Ñ*Ô*Ð*øøÝÔ$¥g­wÐ7ð 	Að 	Að 	AÝ�LŠLÐ<¸aÑ@Ô@Ð@Ð@Ð@Ð@Ð@Ð@øøøøð	Aøøøàˆ4s   ¬A:B( Â(C)ÃC$Ã$C)Úcredsc                 óØ   — ddl }|                      dd¦  «        }|s"t          |                      d¦  «        ¦  «        S t          |                      ¦   «         dz  ¦  «        }||dz
  k     S )zACheck if Claude Code credentials have a non-expired access token.r   Nr°   r®   éè  i`ê  )Útimer½   r,   r-   )rØ   rÛ   Ú
expires_atÚnow_mss       r'   Úis_claude_code_token_validrÞ   Q  sl   € à€K€K€Kà—’˜;¨Ñ*Ô*€JØð .å�E—I’I˜mÑ,Ô,Ñ-Ô-Ð-õ �—’‘”˜tÑ#Ñ$Ô$€Fà�Z &Ñ(Ò)Ð)r)   F©Úuse_jsonÚrefresh_tokenrà   c          	      óì  — ddl }ddl}ddl}| st          d¦  «        ‚d}|r-t	          j        d| |dœ¦  «                             ¦   «         }d}n2|j                             d| |dœ¦  «                             ¦   «         }d}d	d
g}d}|D �]X}	|j	         
                    |	||dt          ¦   «         › d�dœd¬¦  «        }
	 |j	                             |
d¬¦  «        5 }t	          j        |                     ¦   «                              ¦   «         ¦  «        }ddd¦  «         n# 1 swxY w Y   n5# t           $ r(}|}t"                               d|	|¦  «         Y d}~ŒÏd}~ww xY w|                     dd¦  «        }|st          d¦  «        ‚|                     d| ¦  «        }|                     dd¦  «        }||t)          |                      ¦   «         dz  ¦  «        |dz  z   dœc S |�|‚t          d¦  «        ‚)zIRefresh an Anthropic OAuth token without mutating local credential files.r   Nzrefresh_token is requiredú$9d1c250a-e61b-44d9-88ed-5944d1962f5erá   )Ú
grant_typerá   Ú	client_idúapplication/jsonz!application/x-www-form-urlencodedz*https://platform.claude.com/v1/oauth/tokenú,https://console.anthropic.com/v1/oauth/tokenr”   r•   ©zContent-Typer�   ÚPOST©rÀ   ÚheadersÚmethodé
   ©rX   z(Anthropic token refresh failed at %s: %srÂ   r   z3Anthropic refresh response was missing access_tokenÚ
expires_iné  rÚ   ©rÂ   rá   Úexpires_at_mszAnthropic token refresh failed)rÛ   Úurllib.parseÚurllib.requestr7   rº   ÚdumpsÚencodeÚparseÚ	urlencodeÚrequestÚRequestrh   Úurlopenr»   ÚreadÚdecoder1   r¸   r¹   r½   r-   )rá   rà   rÛ   Úurllibrå   rÀ   Úcontent_typeÚtoken_endpointsÚ
last_errorÚendpointÚreqÚresprc   ÚexcrÂ   Únext_refreshrï   s                    r'   Úrefresh_anthropic_oauth_purer  `  s¼  € à€K€K€KØÐÐÐØÐÐÐàð 6ÝÐ4Ñ5Ô5Ð5à6€IØð ;ÝŒzØ)Ø*Ø"ð
ð 
ñ ô ÷ Š6‰8Œ8ð	 	ð
 *ˆˆàŒ|×%Ò%Ø)Ø*Ø"ð'
ð '
ñ ô ÷ Š6‰8Œ8ð	 	ð
 ;ˆð 	5Ø6ð€Oð €JØ#ð 
ñ 
ˆØŒn×$Ò$ØØà ,ØXÕ,DÑ,FÔ,FÐXÐXÐXðð ð ð %ñ 
ô 
ˆð	Ø”×'Ò'¨°RÐ'Ñ8Ô8ð :¸DÝœ D§I¢I¡K¤K×$6Ò$6Ñ$8Ô$8Ñ9Ô9�ð:ð :ð :ñ :ô :ð :ð :ð :ð :ð :ð :øøøð :ð :ð :ð :øøåð 	ð 	ð 	ØˆJÝ�LŠLÐCÀXÈsÑSÔSÐSØˆHˆHˆHˆHøøøøð	øøøð
 —z’z .°"Ñ5Ô5ˆØð 	TÝÐRÑSÔSÐSØ—z’z /°=ÑAÔAˆØ—Z’Z ¨dÑ3Ô3ˆ
à(Ø)Ý  §¢¡¤¨tÑ!3Ñ4Ô4¸
ÀTÑ8IÑJð
ð 
ð 	
ð 	
ð 	
ð ÐØÐÝ
Ð5Ñ
6Ô
6Ð6s<   Â>D+Ã9DÄD+ÄD#	Ä#D+Ä&D#	Ä'D+Ä+
EÄ5EÅEc                 ó~  — |                       dd¦  «        }|st                               d¦  «         dS 	 t          |d¬¦  «        }t	          |d         |d         |d	         ¦  «         t                               d
¦  «         |d         S # t
          $ r&}t                               d|¦  «         Y d}~dS d}~ww xY w)z6Attempt to refresh an expired Claude Code OAuth token.r¯   r   u-   No refresh token available â€” cannot refreshNFrß   rÂ   rá   rò   z.Successfully refreshed Claude Code OAuth tokenz'Failed to refresh Claude Code token: %s)r½   r¸   r¹   r  Ú_write_claude_code_credentialsr1   )rØ   rá   Ú	refreshedrÑ   s       r'   Ú_refresh_oauth_tokenr     s×   € à—I’I˜n¨bÑ1Ô1€MØð Ý�ŠÐDÑEÔEÐEØˆtðÝ0°ÈÐOÑOÔOˆ	Ý&Ø�nÔ%Ø�oÔ&Ø�oÔ&ñ	
ô 	
ð 	
õ
 	�ŠÐEÑFÔFÐFØ˜Ô(Ð(øÝð ð ð Ý�ŠÐ>ÀÑBÔBÐBØˆtˆtˆtˆtˆtøøøøðøøøs   ¶AB Â
B<ÂB7Â7B<)ÚscopesrÂ   rò   r  c                óš  — t          j        ¦   «         dz  dz  }	 i }|                     ¦   «         r(t          j        |                     d¬¦  «        ¦  «        }| ||dœ}|�||d<   nd|v rd|d         v r|d         d         |d<   ||d<   |j                             d	d	¬
¦  «         |                     d¦  «        }| 	                    t          j
        |d¬¦  «        d¬¦  «         |                     |¦  «         |                     d¦  «         dS # t          t          f$ r&}t                               d|¦  «         Y d}~dS d}~ww xY w)aq  Write refreshed credentials back to ~/.claude/.credentials.json.

    The optional *scopes* list (e.g. ``["user:inference", "user:profile", ...]``)
    is persisted so that Claude Code's own auth check recognises the credential
    as valid.  Claude Code >=2.1.81 gates on the presence of ``"user:inference"``
    in the stored scopes before it will use the token.
    rÅ   rÆ   rÇ   rÈ   )r®   r¯   r°   Nr  r­   T)ÚparentsÚexist_okz.tmpé   )Úindenti€  z)Failed to write refreshed credentials: %s)r   rË   rÌ   rº   r»   rÍ   ÚparentÚmkdirÚwith_suffixÚ
write_textrõ   r   Úchmodr¶   rÎ   r¸   r¹   )	rÂ   rá   rò   r  rÐ   ÚexistingrÁ   Ú	_tmp_credrÑ   s	            r'   r	  r	  µ  s’  € õ ”	‘”˜iÑ'Ð*=Ñ=€IðEàˆØ×ÒÑÔð 	IÝ”z )×"5Ò"5¸wÐ"5Ñ"GÔ"GÑHÔHˆHð (Ø)Ø&ð&
ð &
ˆ
ð
 ÐØ#)ˆJ�xÑ Ð Ø Ð(Ð(¨X¸À/Ô9RÐ-RÐ-Rð $,¨OÔ#<¸XÔ#FˆJ�xÑ à$.ˆ�Ñ!àÔ×Ò t°dÐÑ;Ô;Ð;Ø×)Ò)¨&Ñ1Ô1ˆ	Ø×Ò�TœZ¨¸Ð;Ñ;Ô;ÀgÐÑNÔNÐNØ×Ò˜)Ñ$Ô$Ð$à�Š˜ÑÔÐÐÐøÝ•WÐð Eð Eð EÝ�ŠÐ@À!ÑDÔDÐDÐDÐDÐDÐDÐDÐDøøøøðEøøøs   ›C6D ÄE
Ä$EÅE
c                 ó  — | pt          ¦   «         } | r1t          | ¦  «        r"t                               d¦  «         | d         S | rGt                               d¦  «         t	          | ¦  «        }|r|S t                               d¦  «         dS )zHResolve a token from Claude Code credential files, refreshing if needed.z-Using Claude Code credentials (auto-detected)r®   u6   Claude Code credentials expired â€” attempting refreshuF   Token refresh failed â€” re-run 'claude setup-token' to reauthenticateN)rÒ   rÞ   r¸   r¹   r  )rØ   r
  s     r'   Ú+_resolve_claude_code_token_from_credentialsr  â  s˜   € àÐ3Õ1Ñ3Ô3€EØð $Õ+¨EÑ2Ô2ð $Ý�ŠÐDÑEÔEÐEØ�]Ô#Ð#Øð _Ý�ŠÐMÑNÔNÐNÝ(¨Ñ/Ô/ˆ	Øð 	ØÐÝ�ŠÐ]Ñ^Ô^Ð^Øˆ4r)   Ú	env_tokenc                 óê   — | r$t          | ¦  «        rt          |t          ¦  «        sdS |                     d¦  «        sdS t	          |¦  «        }|r"|| k    rt
                               d¦  «         |S dS )a‘  Prefer Claude Code creds when a persisted env OAuth token would shadow refresh.

    Hermes historically persisted setup tokens into ANTHROPIC_TOKEN. That makes
    later refresh impossible because the static env token wins before we ever
    inspect Claude Code's refreshable credential file. If we have a refreshable
    Claude Code credential record, prefer it over the static env OAuth token.
    Nr¯   zYPreferring Claude Code credential file over static env OAuth token so refresh can proceed)rm   r+   r¾   r½   r  r¸   r¹   )r  rØ   r9   s      r'   Ú%_prefer_refreshable_claude_code_tokenr  ñ  s�   € ð ð �O¨IÑ6Ô6ð ½jÈÕPTÑ>UÔ>Uð ØˆtØ�9Š9�^Ñ$Ô$ð Øˆtå:¸5ÑAÔA€HØð �H 	Ò)Ð)Ý�ŠØgñ	
ô 	
ð 	
ð ˆØˆ4r)   c                  óš  — t          ¦   «         } t          j        dd¦  «                             ¦   «         }|rt	          || ¦  «        }|r|S |S t          j        dd¦  «                             ¦   «         }|rt	          || ¦  «        }|r|S |S t          | ¦  «        }|r|S t          j        dd¦  «                             ¦   «         }|r|S dS )uÉ  Resolve an Anthropic token from all available sources.

    Priority:
      1. ANTHROPIC_TOKEN env var (OAuth/setup token saved by Hermes)
      2. CLAUDE_CODE_OAUTH_TOKEN env var
      3. Claude Code credentials (~/.claude.json or ~/.claude/.credentials.json)
         â€” with automatic refresh if expired and a refresh token is available
      4. ANTHROPIC_API_KEY env var (regular API key, or legacy fallback)

    Returns the token string or None.
    ÚANTHROPIC_TOKENr   ÚCLAUDE_CODE_OAUTH_TOKENÚANTHROPIC_API_KEYN)rÒ   ÚosÚgetenvr]   r  r  )rØ   ÚtokenÚ	preferredÚcc_tokenÚresolved_claude_tokenr†   s         r'   Úresolve_anthropic_tokenr(    sô   € õ )Ñ*Ô*€Eõ ŒIÐ'¨Ñ,Ô,×2Ò2Ñ4Ô4€EØð Ý9¸%ÀÑGÔGˆ	Øð 	ØÐØˆõ ŒyÐ2°BÑ7Ô7×=Ò=Ñ?Ô?€HØð Ý9¸(ÀEÑJÔJˆ	Øð 	ØÐØˆõ HÈÑNÔNÐØð %Ø$Ð$õ ŒiÐ+¨RÑ0Ô0×6Ò6Ñ8Ô8€GØð Øˆàˆ4r)   c                  ól  — ddl } ddl}|                      d¦  «        }|st          d¦  «        ‚	  |j        |dg¦  «         n# t
          t          f$ r Y dS w xY wt          ¦   «         }|rt          |¦  «        r|d         S dD ]/}t          j
        |d¦  «                             ¦   «         }|r|c S Œ0dS )	a˜  Run 'claude setup-token' interactively and return the resulting token.

    Checks multiple sources after the subprocess completes:
      1. Claude Code credential files (may be written by the subprocess)
      2. CLAUDE_CODE_OAUTH_TOKEN / ANTHROPIC_TOKEN env vars

    Returns the token string, or None if no credentials were obtained.
    Raises FileNotFoundError if the 'claude' CLI is not installed.
    r   NrR   z\The 'claude' CLI is not installed. Install it with: npm install -g @anthropic-ai/claude-codezsetup-tokenr®   )r   r  r   )ÚshutilrY   ÚwhichÚFileNotFoundErrorrZ   ÚKeyboardInterruptÚEOFErrorrÒ   rÞ   r"  r#  r]   )r*  rY   Úclaude_pathrØ   Úenv_varr&   s         r'   Úrun_oauth_setup_tokenr1  3  s  € ð €M€M€MØÐÐÐà—,’,˜xÑ(Ô(€KØð 
ÝðHñ
ô 
ð 	
ðØˆ
Œ˜ ]Ð3Ñ4Ô4Ð4Ð4øÝ�xÐ(ð ð ð Øˆtˆtðøøøõ )Ñ*Ô*€EØð $Õ+¨EÑ2Ô2ð $Ø�]Ô#Ð#ð Bð ð ˆÝŒi˜ Ñ$Ô$×*Ò*Ñ,Ô,ˆØð 	ØˆJˆJˆJð	ð ˆ4s   °A ÁAÁArã   rç   z1https://console.anthropic.com/oauth/code/callbackz.org:create_api_key user:profile user:inferencez.anthropic_oauth.jsonc                  óž  — ddl } ddl}ddl}|                      |                     d¦  «        ¦  «                             d¦  «                             ¦   «         }|                      |                     |                     ¦   «         ¦  «         	                    ¦   «         ¦  «                             d¦  «                             ¦   «         }||fS )z6Generate PKCE code_verifier and code_challenge (S256).r   Né    ó   =)
Úbase64ÚhashlibÚsecretsÚurlsafe_b64encodeÚtoken_bytesru   rý   Úsha256rö   Údigest)r5  r6  r7  ÚverifierÚ	challenges        r'   Ú_generate_pkcer>  f  sµ   € à€M€M€MØ€N€N€NØ€N€N€Nà×'Ò'¨×(;Ò(;¸BÑ(?Ô(?Ñ@Ô@×GÒGÈÑMÔM×TÒTÑVÔV€HØ×(Ò(Ø�Š�x—’Ñ(Ô(Ñ)Ô)×0Ò0Ñ2Ô2ñô ç‚fˆT�l„l—6’6‘8”8ð ð �YÐÐr)   c            	      ó¨  — ddl } ddl}t          ¦   «         \  }}dt          dt          t
          |d|dœ}ddlm} d ||¦  «        › �}t          ¦   «          t          d	¦  «         t          ¦   «          t          d
¦  «         t          d¦  «         t          d¦  «         t          d¦  «         t          ¦   «          t          d|› �¦  «         t          ¦   «          	 | 	                    |¦  «         t          d¦  «         n# t          $ r Y nw xY wt          ¦   «          t          d¦  «         t          ¦   «          	 t          d¦  «                             ¦   «         }n# t          t          f$ r Y dS w xY w|st          d¦  «         dS |                     d¦  «        }|d         }	t!          |¦  «        dk    r|d         nd}
	 ddl}t%          j        dt          |	|
t          |dœ¦  «                             ¦   «         }|j                             t.          |ddt1          ¦   «         › d�dœd¬¦  «        }|j                             |d¬¦  «        5 }t%          j        |                     ¦   «                              ¦   «         ¦  «        }ddd¦  «         n# 1 swxY w Y   n*# t          $ r}t          d |› �¦  «         Y d}~dS d}~ww xY w|                     d!d¦  «        }|                     d"d¦  «        }|                     d#d$¦  «        }|st          d%¦  «         dS t=          |                       ¦   «         d&z  ¦  «        |d&z  z   }|||d'œS )(z>Run Hermes-native OAuth PKCE flow and return credential state.r   NÚtrueÚcodeÚS256)rA  rå   Úresponse_typeÚredirect_uriÚscopeÚcode_challengeÚcode_challenge_methodÚstate)rø   z"https://claude.ai/oauth/authorize?z7Authorize Hermes with your Claude Pro/Max subscription.uc   â•­â”€ Claude Pro/Max Authorization â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â•®u9   â”‚                                                   â”‚u9   â”‚  Open this link in your browser:                  â”‚uŸ   â•°â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â•¯z  z   (Browser opened automatically)z5After authorizing, you'll see a code. Paste it below.zAuthorization code: zNo code entered.ú#é   r   Úauthorization_code)rä   rå   rA  rH  rD  Úcode_verifierræ   r”   r•   rè   ré   rê   é   rî   zToken exchange failed: rÂ   rá   rï   rð   zNo access token in response.rÚ   rñ   )rÛ   Ú
webbrowserr>  Ú_OAUTH_CLIENT_IDÚ_OAUTH_REDIRECT_URIÚ_OAUTH_SCOPESró   rø   ÚprintÚopenr1   Úinputr]   r-  r.  r^   r!   rô   rº   rõ   rö   rù   rú   Ú_OAUTH_TOKEN_URLrh   rû   r»   rü   rý   r½   r-   )rÛ   rN  r<  r=  Úparamsrø   Úauth_urlÚ	auth_codeÚsplitsrA  rH  rþ   Úexchange_datar  r  rc   rÑ   rÂ   rá   rï   rò   s                        r'   Úrun_hermes_oauth_login_purer[  s  s  € à€K€K€KØÐÐÐå(Ñ*Ô*Ñ€Hˆið Ý%ØÝ+ÝØ#Ø!'Øð	ð 	€Fð 'Ð&Ð&Ð&Ð&Ð&àG°I°I¸fÑ4EÔ4EÐGÐG€Hå	�G„G€GÝ	Ð
CÑDÔDÐDÝ	�G„G€GÝ	Ð
oÑpÔpÐpÝ	Ð
EÑFÔFÐFÝ	Ð
EÑFÔFÐFÝ	ð  lñ  mô  mð  mÝ	�G„G€GÝ	ˆ/ˆxˆ/ˆ/ÑÔÐÝ	�G„G€GðØ�Š˜Ñ!Ô!Ð!ÝÐ0Ñ1Ô1Ð1Ð1øÝð ð ð Øˆðøøøõ 
�G„G€GÝ	Ð
AÑBÔBÐBÝ	�G„G€GðÝÐ0Ñ1Ô1×7Ò7Ñ9Ô9ˆ	ˆ	øÝ�xÐ(ð ð ð Øˆtˆtðøøøð ð ÝÐ Ñ!Ô!Ð!Øˆtà�_Š_˜SÑ!Ô!€FØ�!Œ9€DÝ˜V™œ qš˜ˆF�1ŒIˆI¨b€EðØÐÐÐåœ
Ø.Ý)ØØÝ/Ø%ð$
ð $
ñ ô ÷ Š6‰8Œ8ð 	ð Œn×$Ò$ÝØà 2ØXÕ,DÑ,FÔ,FÐXÐXÐXðð ð ð %ñ 
ô 
ˆð Œ^×#Ò# C°Ð#Ñ4Ô4ð 	6¸Ý”Z §	¢	¡¤× 2Ò 2Ñ 4Ô 4Ñ5Ô5ˆFð	6ð 	6ð 	6ñ 	6ô 	6ð 	6ð 	6ð 	6ð 	6ð 	6ð 	6øøøð 	6ð 	6ð 	6ð 	6øøåð ð ð ÝÐ+¨Ð+Ð+Ñ,Ô,Ð,Øˆtˆtˆtˆtˆtøøøøðøøøð —:’:˜n¨bÑ1Ô1€LØ—J’J˜°Ñ3Ô3€MØ—’˜L¨$Ñ/Ô/€Jàð ÝÐ,Ñ-Ô-Ð-Øˆtå˜Ÿ	š	™œ dÑ*Ñ+Ô+¨z¸DÑ/@ÑA€Mà$Ø&Ø&ðð ð sa   Ã$D Ä
DÄDÄ?!E! Å!E6Å5E6ÇBJ% É9JÊJ% ÊJÊJ% Ê JÊ!J% Ê%
KÊ/KËKc                  óL  — t                                ¦   «         rŠ	 t          j        t                                d¬¦  «        ¦  «        } |                      d¦  «        r| S nD# t          j        t          t          f$ r%}t           
                    d|¦  «         Y d}~nd}~ww xY wdS )zKRead Hermes-managed OAuth credentials from ~/.hermes/.anthropic_oauth.json.rÇ   rÈ   r®   z+Failed to read Hermes OAuth credentials: %sN)Ú_HERMES_OAUTH_FILErÌ   rº   r»   rÍ   r½   r¼   r¶   rÎ   r¸   r¹   )rÀ   rÑ   s     r'   Úread_hermes_oauth_credentialsr^  Õ  s²   € å× Ò Ñ"Ô"ð Kð	KÝ”:Õ0×:Ò:ÀGÐ:ÑLÔLÑMÔMˆDØ�xŠx˜Ñ&Ô&ð Ø�ðøåÔ$¥g­wÐ7ð 	Kð 	Kð 	KÝ�LŠLÐFÈÑJÔJÐJÐJÐJÐJÐJÐJøøøøð	Køøøàˆ4s   ›AA  Á B!Á<BÂB!c                 ó˜   ‡— |                       ¦   «         Št          ˆfd„dD ¦   «         ¦  «        rdS ‰                     d¦  «        rdS dS )at  Detect AWS Bedrock model IDs that use dots as namespace separators.

    Bedrock model IDs come in two forms:
    - Bare:    ``anthropic.claude-opus-4-7``
    - Regional (inference profiles): ``us.anthropic.claude-sonnet-4-5-v1:0``

    In both cases the dots separate namespace components, not version
    numbers, and must be preserved verbatim for the Bedrock API.
    c              3   óB   •K  — | ]}‰                      |¦  «        V — Œd S r>   rk   )rA   Úpr   s     €r'   rC   z'_is_bedrock_model_id.<locals>.<genexpr>ò  s1   øè è € Ð
PÐ
P 1ˆ5×Ò˜AÑÔÐ
PÐ
PÐ
PÐ
PÐ
PÐ
Pr)   )zglobal.zus.zeu.zap.zjp.Tz
anthropic.F)r   rD   rl   )r   r   s    @r'   Ú_is_bedrock_model_idrb  æ  s]   ø€ ð �KŠK‰MŒM€Eå
Ð
PÐ
PÐ
PÐ
PÐ(OÐ
PÑ
PÔ
PÑPÔPð Øˆtà×Ò˜Ñ%Ô%ð ØˆtØˆ5r)   Úpreserve_dotsc                 óØ   — |                       ¦   «         }|                     d¦  «        r| t          d¦  «        d…         } |s't          | ¦  «        r| S |                      dd¦  «        } | S )u  Normalize a model name for the Anthropic API.

    - Strips 'anthropic/' prefix (OpenRouter format, case-insensitive)
    - Converts dots to hyphens in version numbers (OpenRouter uses dots,
      Anthropic uses hyphens: claude-opus-4.6 â†’ claude-opus-4-6), unless
      preserve_dots is True (e.g. for Alibaba/DashScope: qwen3.5-plus).
    - Preserves Bedrock model IDs (``anthropic.claude-opus-4-7``) and
      regional inference profiles (``us.anthropic.claude-*``) whose dots
      are namespace separators, not version separators.
    z
anthropic/Nr   r   )r   rl   r!   rb  r   )r   rc  r   s      r'   Únormalize_model_namere  ú  sx   € ð �KŠK‰MŒM€EØ×Ò˜Ñ%Ô%ð *Ø•c˜,Ñ'Ô'Ð(Ð(Ô)ˆØð (õ   Ñ&Ô&ð 	ØˆLð —’˜c 3Ñ'Ô'ˆØ€Lr)   Útool_idc                 óH   — ddl }| sdS |                     dd| ¦  «        }|pdS )z­Sanitize a tool call ID for the Anthropic API.

    Anthropic requires IDs matching [a-zA-Z0-9_-]. Replace invalid
    characters with underscores and ensure non-empty.
    r   NÚtool_0z[^a-zA-Z0-9_-]Ú_)ÚreÚsub)rf  rj  Ú	sanitizeds      r'   Ú_sanitize_tool_idrm    s;   € ð €I€I€IØð ØˆxØ—’Ð(¨#¨wÑ7Ô7€IØÐ ˜Ð r)   Útoolsc                 óø   — | sg S g }| D ]p}|                      di ¦  «        }|                     |                      dd¦  «        |                      dd¦  «        |                      ddi dœ¦  «        dœ¦  «         Œq|S )	z4Convert OpenAI tool definitions to Anthropic format.ÚfunctionÚnamer   ÚdescriptionÚ
parametersÚobject)ÚtypeÚ
properties)rq  rr  Úinput_schema)r½   Úappend)rn  rc   ÚtÚfns       r'   Úconvert_tools_to_anthropicr{  !  sž   € àð Øˆ	Ø€FØð ð ˆØ�UŠU�:˜rÑ"Ô"ˆØ�ŠØ—F’F˜6 2Ñ&Ô&ØŸ6š6 -°Ñ4Ô4ØŸFšF <¸(ÐRTÐ1UÐ1UÑVÔVð
ð 
ñ 	ô 	ð 	ð 	ð
 €Mr)   Úurlc                 óª  — t          | pd¦  «                             ¦   «         } | sdddœS |                      d¦  «        r�|                      d¦  «        \  }}}d}|                     d¦  «        rZ|t	          d¦  «        d…                              dd	¦  «        d
                              ¦   «         }|                     d¦  «        r|}d||dœS d| dœS )zGConvert an OpenAI-style image URL/data URL into Anthropic image source.r   r|  )ru  r|  zdata:r‘   z
image/jpegNú;rJ  r   zimage/r5  )ru  Ú
media_typerÀ   )ro   r]   rl   Ú	partitionr!   r^   )r|  Úheaderri  rÀ   r  Ú	mime_parts         r'   Ú_image_source_from_openai_urlrƒ  0  sñ   € å
ˆcˆi�R‰.Œ.×
Ò
Ñ
 Ô
 €CØð *Ø bÐ)Ð)Ð)à
‡~‚~�gÑÔð 
ØŸ-š-¨Ñ,Ô,‰ˆ��4Ø!ˆ
Ø×Ò˜WÑ%Ô%ð 	'Ø�s 7™|œ|˜}˜}Ô-×3Ò3°C¸Ñ;Ô;¸AÔ>×DÒDÑFÔFˆIØ×#Ò# HÑ-Ô-ð 'Ø&�
àØ$Øð
ð 
ð 	
ð  #Ð&Ð&Ð&r)   Úpartc                 ór  — | €dS t          | t          ¦  «        rd| dœS t          | t          ¦  «        sdt          | ¦  «        dœS |                      d¦  «        }|dk    rd|                      dd¦  «        dœ}nx|dv re|                      di ¦  «        }t          |t          ¦  «        r|                     d	d¦  «        nt          |pd¦  «        }d
t	          |¦  «        dœ}nt          | ¦  «        }t          |                      d¦  «        t          ¦  «        rd|vrt          | d         ¦  «        |d<   |S )z?Convert a single OpenAI-style content part to Anthropic format.NrW   ©ru  rW   ru  Ú
input_textr   >   Ú	image_urlÚinput_imagerˆ  r|  Úimage)ru  r³   Úcache_control)r+   ro   r¾   r½   rƒ  )r„  ÚptypeÚblockÚimage_valuer|  s        r'   Ú"_convert_content_part_to_anthropicr�  F  sG  € à€|ØˆtÝ�$�ÑÔð .Ø¨Ð-Ð-Ð-Ý�d�DÑ!Ô!ð 3Ø­¨D©	¬	Ð2Ð2Ð2à�HŠH�VÑÔ€Eà�ÒÐØ)/¸¿ºÀ&È"Ñ9MÔ9MÐ NÐ NˆˆØ	Ð.Ð	.Ð	.Ø—h’h˜{¨BÑ/Ô/ˆÝ,6°{ÅDÑ,IÔ,IÐeˆk�oŠo˜e RÑ(Ô(Ð(ÍsÐS^ÐSdÐbdÑOeÔOeˆØ Õ,IÈ#Ñ,NÔ,NÐOÐOˆˆå�T‘
”
ˆå�$—(’(˜?Ñ+Ô+­TÑ2Ô2ð =°ÈeÐ7SÐ7SÝ!% d¨?Ô&;Ñ!<Ô!<ˆˆoÑØ€Lr)   ©Ú_depthÚ_pathr2   r‘  r’  c                ó¨  ‡‡— d}‰|k    rt          | ¦  «        S ‰€t          ¦   «         Št          | ¦  «        }|‰v rt          | ¦  «        S t          | d¦  «        rS‰                     |¦  «         t          |                      ¦   «         ‰dz   ‰¬¦  «        }‰                     |¦  «         |S t          | t          ¦  «        rM‰                     |¦  «         ˆˆfd„|  
                    ¦   «         D ¦   «         }‰                     |¦  «         |S t          | t          t          f¦  «        r;‰                     |¦  «         ˆˆfd„| D ¦   «         }‰                     |¦  «         |S t          | d¦  «        rZ‰                     |¦  «         ˆˆfd	„t          | ¦  «         
                    ¦   «         D ¦   «         }‰                     |¦  «         |S | S )
a|  Recursively convert SDK objects to plain Python data structures.

    Guards against circular references (``_path`` tracks ``id()`` of objects
    on the *current* recursion path) and runaway depth (capped at 20 levels).
    Uses path-based tracking so shared (but non-cyclic) objects referenced by
    multiple siblings are converted correctly rather than being stringified.
    é   NÚ
model_dumprJ  r�  c                 óB   •— i | ]\  }}|t          |‰d z   ‰¬¦  «        “ŒS ©rJ  r�  ©Ú_to_plain_data©rA   ÚkrB   r‘  r’  s      €€r'   ú
<dictcomp>z"_to_plain_data.<locals>.<dictcomp>y  s2   ø€ ÐaÐaÐaÉ4È1Èa�!•^ A¨f°q©jÀÐFÑFÔFÐaÐaÐar)   c                 ó:   •— g | ]}t          |‰d z   ‰¬¦  «        ‘ŒS r—  r˜  )rA   rB   r‘  r’  s     €€r'   rƒ   z"_to_plain_data.<locals>.<listcomp>~  s,   ø€ ÐSÐSÐSÈ•. ¨6°A©:¸UÐCÑCÔCÐSÐSÐSr)   Ú__dict__c                 ól   •— i | ]0\  }}|                      d ¦  «        °|t          |‰dz   ‰¬¦  «        “Œ1S )ri  rJ  r�  )rl   r™  rš  s      €€r'   rœ  z"_to_plain_data.<locals>.<dictcomp>ƒ  sT   ø€ ð 
ð 
ð 
á��1Ø—<’< Ñ$Ô$ð
Ø�~˜a¨°©
¸%Ð@Ñ@Ô@ð
ð 
ð 
r)   )ro   ÚsetÚidr¨   Úaddr™  r•  Údiscardr+   r¾   r    ÚlistÚtupleÚvars)r2   r‘  r’  Ú
_MAX_DEPTHÚobj_idrc   s    ``   r'   r™  r™  _  sï  øø€ ð €JØ�
ÒÐÝ�5‰zŒzÐà€}Ý‘”ˆå�‰YŒY€FØ�€€Ý�5‰zŒzÐåˆu�lÑ#Ô#ð Ø�	Š	�&ÑÔÐÝ × 0Ò 0Ñ 2Ô 2¸6ÀA¹:ÈUÐSÑSÔSˆØ�Š�fÑÔÐØˆÝ�%�ÑÔð Ø�	Š	�&ÑÔÐØaÐaÐaÐaÐaÐSX×S^ÒS^ÑS`ÔS`ÐaÑaÔaˆØ�Š�fÑÔÐØˆÝ�%�$¥˜Ñ'Ô'ð Ø�	Š	�&ÑÔÐØSÐSÐSÐSÐSÈUÐSÑSÔSˆØ�Š�fÑÔÐØˆÝˆu�jÑ!Ô!ð Ø�	Š	�&ÑÔÐð
ð 
ð 
ð 
ð 
å˜U™œ×)Ò)Ñ+Ô+ð
ñ 
ô 
ˆð
 	�Š�fÑÔÐØˆØ€Lr)   Úmessagec                 ó‚  — |                       d¦  «        }t          |t          ¦  «        sg S g }|D ]�}t          |t          ¦  «        sŒt	          |                      dd¦  «        pd¦  «                             ¦   «                              ¦   «         }|dvrŒf|                     t          j	        |¦  «        ¦  «         ŒŽ|S )zEReturn Anthropic thinking blocks previously preserved on the message.Úreasoning_detailsru  r   >   ÚthinkingÚredacted_thinking)
r½   r+   r¤  r¾   ro   r]   r   rx  ÚcopyÚdeepcopy)r©  Úraw_detailsÚ	preservedÚdetailÚ
block_types        r'   Ú"_extract_preserved_thinking_blocksr´  �  sÂ   € à—+’+Ð1Ñ2Ô2€KÝ�k¥4Ñ(Ô(ð Øˆ	à&(€IØð 0ð 0ˆÝ˜&¥$Ñ'Ô'ð 	ØÝ˜Ÿš F¨BÑ/Ô/Ð5°2Ñ6Ô6×<Ò<Ñ>Ô>×DÒDÑFÔFˆ
ØÐ>Ð>Ð>ØØ×Ò�œ vÑ.Ô.Ñ/Ô/Ð/Ð/ØÐr)   Úcontentc                 óŽ   — t          | t          ¦  «        s| S g }| D ](}t          |¦  «        }|�|                     |¦  «         Œ)|S )zCConvert OpenAI-style multimodal content arrays to Anthropic blocks.)r+   r¤  r�  rx  )rµ  Ú	convertedr„  r�  s       r'   Ú_convert_content_to_anthropicr¸  ž  s[   € å�g�tÑ$Ô$ð Øˆà€IØð $ð $ˆÝ2°4Ñ8Ô8ˆØÐØ×Ò˜UÑ#Ô#Ð#øØÐr)   Úmessagesc                 ó�  ‡#‡$‡%— d}g }| D �]Ž}|                      dd¦  «        }|                      dd¦  «        }|dk    r`t          |t          ¦  «        rHt          d„ |D ¦   «         ¦  «        }|rd„ |D ¦   «         }n"d	                     d
„ |D ¦   «         ¦  «        }n|}Œ•|dk    �rt          |¦  «        }|rtt          |t          ¦  «        r:t          |¦  «        }	t          |	t          ¦  «        r|                     |	¦  «         n%|                     dt          |¦  «        dœ¦  «         |                      dg ¦  «        D ]à}
|
rt          |
t          ¦  «        sŒ|
                      di ¦  «        }|                      dd¦  «        }	 t          |t          ¦  «        rt          j        |¦  «        n|}n# t          j        t          f$ r i }Y nw xY w|                     dt          |
                      dd¦  «        ¦  «        |                      dd¦  «        |dœ¦  «         Œá|                      d¦  «        }t          d„ |D ¦   «         ¦  «        }t          |t          ¦  «        r|s|                     dd|dœ¦  «         |p|}|r|dk    rdddœg}|                     d|dœ¦  «         �Œ¢|dk    �rAt          |t          ¦  «        r|nt          j        |¦  «        }|sd}dt          |                      d d¦  «        ¦  «        |d!œ}t          |                      d"¦  «        t          ¦  «        rt          |d"         ¦  «        |d"<   |rŽ|d#         d         dk    r|t          |d#         d         t          ¦  «        r[|d#         d         rM|d#         d         d                               d$¦  «        dk    r"|d#         d                              |¦  «         n|                     d|gdœ¦  «         �Œêt          |t          ¦  «        rJt          |¦  «        }|rt%          d%„ |D ¦   «         ¦  «        rdd&dœg}|                     d|dœ¦  «         �ŒI|r)t          |t          ¦  «        r|                     ¦   «         sd&}|                     d|dœ¦  «         �Œ�t)          ¦   «         Š$|D ]u}|d         dk    rgt          |d         t          ¦  «        rL|d         D ]C}|                      d$¦  «        dk    r(‰$                     |                      d'¦  «        ¦  «         ŒDŒv|D ]Q}|d         dk    rCt          |d         t          ¦  «        r(ˆ$fd(„|d         D ¦   «         |d<   |d         s	dd)dœg|d<   ŒRt)          ¦   «         Š%|D ]u}|d         dk    rgt          |d         t          ¦  «        rL|d         D ]C}|                      d$¦  «        dk    r(‰%                     |                      d¦  «        ¦  «         ŒDŒv|D ]Q}|d         dk    rCt          |d         t          ¦  «        r(ˆ%fd*„|d         D ¦   «         |d<   |d         s	dd+dœg|d<   ŒRg }|D �]}|�rø|d#         d         |d         k    �rß|d         dk    rÐ|d#         d         }|d         }t          |t          ¦  «        r't          |t          ¦  «        r|d	z   |z   |d#         d<   Œ}t          |t          ¦  «        r$t          |t          ¦  «        r||z   |d#         d<   Œ¶t          |t          ¦  «        rd|dœg}t          |t          ¦  «        rd|dœg}||z   |d#         d<   Œût          |d         t          ¦  «        rd,„ |d         D ¦   «         |d<   |d#         d         }|d         }t          |t          ¦  «        r%t          |t          ¦  «        r||z   |d#         d<   �Œ{t          |t          ¦  «        r(t          |t          ¦  «        r|d	z   |z   |d#         d<   �Œ¸t          |t          ¦  «        rd|dœg}t          |t          ¦  «        rd|dœg}||z   |d#         d<   �Œþ|                     |¦  «         �Œ|}t-          d-¦  «        Š#t/          |¦  «        }t1          |¦  «        }d}t3          t5          |¦  «        d.z
  d#d#¦  «        D ]%}||                               d¦  «        dk    r|} nŒ&t7          |¦  «        D �]T\  }}|                      d¦  «        dk    s(t          |                      d¦  «        t          ¦  «        sŒH|rœg }|d         D ]„} t          | t          ¦  «        r|                       d$¦  «        ‰#vr|                     | ¦  «         ŒD|                       d/¦  «        s|                       d0¦  «        rŒo|                     | ¦  «         Œ…|pdddœg|d<   �n!|s||k    r ˆ#fd1„|d         D ¦   «         }!|!pdd2dœg|d<   nùg }|d         D ]ã} t          | t          ¦  «        r|                       d$¦  «        ‰#vr|                     | ¦  «         ŒD|                       d$¦  «        d3k    r+|                       d0¦  «        r|                     | ¦  «         Œˆ|                       d/¦  «        r|                     | ¦  «         Œ³|                       dd¦  «        }"|"r|                     d|"dœ¦  «         Œä|pdddœg|d<   |d         D ]D} t          | t          ¦  «        r-|                       d$¦  «        ‰#v r|                      d"d¦  «         ŒE�ŒV||fS )4uE  Convert OpenAI-format messages to Anthropic format.

    Returns (system_prompt, anthropic_messages).
    System messages are extracted since Anthropic takes them as a separate param.
    system_prompt is a string or list of content blocks (when cache_control present).

    When *base_url* is provided and points to a third-party Anthropic-compatible
    endpoint, all thinking block signatures are stripped.  Signatures are
    Anthropic-proprietary â€” third-party endpoints cannot validate them and will
    reject them with HTTP 400 "Invalid signature in thinking block".
    NÚroleÚuserrµ  r   rµ   c              3   ój   K  — | ].}t          |t          ¦  «        ¯|                     d ¦  «        V — Œ/dS )r‹  N©r+   r¾   r½   ©rA   ra  s     r'   rC   z0convert_messages_to_anthropic.<locals>.<genexpr>Ä  sQ   è è € ð  ð  Ø/0½zÈ!ÍTÑ?RÔ?Rð Ø—E’E˜/Ñ*Ô*ð ð  ð  ð  ð  ð  r)   c                 ó<   — g | ]}t          |t          ¦  «        ¯|‘ŒS r?   )r+   r¾   r¿  s     r'   rƒ   z1convert_messages_to_anthropic.<locals>.<listcomp>È  s'   € ÐHÐHÐH AµJ¸qÅ$Ñ4GÔ4GÐH˜aÐHÐHÐHr)   Ú
c              3   óX   K  — | ]%}|                      d ¦  «        dk    ¯|d         V — Œ&dS )ru  rW   N©r½   r¿  s     r'   rC   z0convert_messages_to_anthropic.<locals>.<genexpr>Ê  sC   è è € ð 'ð 'Ø&'°a·e²e¸F±m´mÀvÒ6MÐ6M˜˜&œ	Ð6MÐ6MÐ6MÐ6Mð'ð 'r)   Ú	assistantrW   r†  Ú
tool_callsrp  Ú	argumentsz{}Útool_user¡  rq  )ru  r¡  rq  rT  Úreasoning_contentc              3   ón   K  — | ]0}t          |t          ¦  «        o|                     d ¦  «        dv V — Œ1dS )ru  ©r¬  r­  Nr¾  r�   s     r'   rC   z0convert_messages_to_anthropic.<locals>.<genexpr>ü  sU   è è € ð (ð (àõ ˜1�dÑ#Ô#ÐZ¨¯ª¨f©¬Ð9ZÐ(Zð(ð (ð (ð (ð (ð (r)   r   r¬  )ru  r¬  z(empty))r»  rµ  Útoolz(no output)Útool_resultÚtool_call_id)ru  Útool_use_idrµ  r‹  éÿÿÿÿru  c              3   óÊ   K  — | ]^}t          |t          ¦  «        rG|                     d ¦  «        dk    ¯0|                     dd¦  «                             ¦   «         dk    V — Œ_dS )ru  rW   r   N)r+   r¾   r½   r]   r�   s     r'   rC   z0convert_messages_to_anthropic.<locals>.<genexpr>&  sv   è è € ð +ð +àÝ˜a¥Ñ&Ô&ð+ð ,-¯5ª5°©=¬=¸FÒ+BÐ+Bð —’�f˜bÑ!Ô!×'Ò'Ñ)Ô)¨RÒ/à+BÐ+BÐ+BÐ+Bð+ð +r)   z(empty message)rÎ  c                 ót   •— g | ]4}|                      d ¦  «        dk    s|                      d¦  «        ‰v ¯2|‘Œ5S )ru  rÇ  r¡  rÃ  )rA   r‚   Útool_result_idss     €r'   rƒ   z1convert_messages_to_anthropic.<locals>.<listcomp><  sL   ø€ ð ð ð àØ—5’5˜‘=”= JÒ.Ð.°!·%²%¸±+´+ÀÐ2PÐ2Pð à2PÐ2PÐ2Pr)   z(tool call removed)c                 ót   •— g | ]4}|                      d ¦  «        dk    s|                      d¦  «        ‰v ¯2|‘Œ5S )ru  rÌ  rÎ  rÃ  )rA   r‚   Útool_use_idss     €r'   rƒ   z1convert_messages_to_anthropic.<locals>.<listcomp>P  sN   ø€ ð ð ð àØ—5’5˜‘=”= MÒ1Ð1°Q·U²U¸=Ñ5IÔ5IÈ\Ð5YÐ5Yð à5YÐ5YÐ5Yr)   z(tool result removed)c                 ój   — g | ]0}t          |t          ¦  «        r|                     d ¦  «        dv °.|‘Œ1S )ru  rÊ  r¾  r�   s     r'   rƒ   z1convert_messages_to_anthropic.<locals>.<listcomp>q  sJ   € ð $ð $ð $ØÝ *¨1­dÑ 3Ô 3ð$à89¿º¸f¹¼ÐIjÐ8jÐ8jð Ø8jÐ8jÐ8jr)   rÊ  rJ  Ú	signaturerÀ   c                 ól   •— g | ]0}t          |t          ¦  «        r|                     d ¦  «        ‰v °.|‘Œ1S )ru  r¾  )rA   r‚   Ú_THINKING_TYPESs     €r'   rƒ   z1convert_messages_to_anthropic.<locals>.<listcomp>¿  sJ   ø€ ð ð ð ØÝ" 1¥dÑ+Ô+ðà01·²°f±´ÀÐ0PÐ0Pð Ø0PÐ0PÐ0Pr)   z(thinking elided)r­  )r½   r+   r¤  rD   rš   r´  r¸  Úextendrx  ro   r¾   rº   r»   r¼   r7   rm  Úinsertrõ   Úallr]   r   r¢  Ú	frozensetrx   r{   Úranger!   Ú	enumerateÚpop)&r¹  rq   rµ   rc   r"   r»  rµ  Ú	has_cacheÚblocksÚconverted_contentÚtcrz  ÚargsÚparsed_argsrÈ  Ú_already_has_thinkingÚ	effectiveÚresult_contentrÌ  Úconverted_blocksr�  ÚfixedÚprev_contentÚcurr_contentÚprev_blocksÚcurr_blocksÚ_is_third_partyÚ_is_kimiÚlast_assistant_idxÚiÚidxÚnew_contentr‚   ÚstrippedÚthinking_textrØ  rÒ  rÔ  s&                                      @@@r'   Úconvert_messages_to_anthropicr÷  «  sj  øøø€ ð €FØ€Fàð t@ñ t@ˆØ�uŠu�V˜VÑ$Ô$ˆØ—%’%˜	 2Ñ&Ô&ˆà�8ÒÐÝ˜'¥4Ñ(Ô(ð !åð  ð  Ø4;ð ñ  ô  ñ ô �	ð ð ØHÐH¨ÐHÑHÔH�F�Fà!ŸYšYð 'ð 'Ø+2ð'ñ 'ô 'ñ ô �F�Fð !�Øà�;ÒÑÝ7¸Ñ:Ô:ˆFØð JÝ˜g¥tÑ,Ô,ð JÝ(EÀgÑ(NÔ(NÐ%Ý!Ð"3µTÑ:Ô:ð 9ØŸšÐ&7Ñ8Ô8Ð8øà—M’M¨6½3¸w¹<¼<Ð"HÐ"HÑIÔIÐIØ—e’e˜L¨"Ñ-Ô-ð ð �Øð ¥¨BµÑ!5Ô!5ð ØØ—V’V˜J¨Ñ+Ô+�Ø—v’v˜k¨4Ñ0Ô0�ð%Ý6@ÀÅsÑ6KÔ6KÐ"U¥$¤*¨TÑ"2Ô"2Ð"2ÐQU�K�KøÝÔ,­jÐ9ð %ð %ð %Ø"$�K�K�Kð%øøøà—’Ø&Ý+¨B¯FªF°4¸Ñ,<Ô,<Ñ=Ô=ØŸFšF 6¨2Ñ.Ô.Ø(ð	ð ñ ô ð ð ð0 !"§¢Ð&9Ñ :Ô :ÐÝ$'ð (ð (àð(ñ (ô (ñ %ô %Ð!õ Ð+­SÑ1Ô1ð VÐ:Oð VØ—’˜a¨*ÐBSÐ!TÐ!TÑUÔUÐUàÐ) 'ˆIØð B 	¨R¢ Ø&,°iÐ@Ð@ÐA�	Ø�MŠM ;¸9ÐEÐEÑFÔFÐFÙà�6Š>‰>å(2°7½CÑ(@Ô(@ÐY˜W˜WÅdÄjÐQXÑFYÔFYˆNØ!ð /Ø!.�à%Ý0°·²°~ÀrÑ1JÔ1JÑKÔKØ)ðð ˆKõ
 ˜!Ÿ%š% Ñ0Ô0µ$Ñ7Ô7ð HÝ/3°A°oÔ4FÑ/GÔ/G�˜OÑ,ð ð	Jà˜2”J˜vÔ&¨&Ò0Ð0Ý˜v bœz¨)Ô4µdÑ;Ô;ð 1à˜2”J˜yÔ)ð 1ð ˜2”J˜yÔ)¨!Ô,×0Ò0°Ñ8Ô8¸MÒIÐIà�r”
˜9Ô%×,Ò,¨[Ñ9Ô9Ð9Ð9à—’ v¸;¸-ÐHÐHÑIÔIÐIÙõ �g�tÑ$Ô$ð 	@Ý<¸WÑEÔEÐà#ð Q¥sð +ð +à)ð+ñ +ô +ñ (ô (ð Qð
 .4Ð=NÐ$OÐ$OÐ#PÐ Ø�MŠM 6Ð6FÐGÐGÑHÔHÐHÑHð ð ,�z¨'µ3Ñ7Ô7ð ,ÀÇÂÁÄð ,Ø+�Ø�MŠM 6°gÐ>Ð>Ñ?Ô?Ð?Ñ?õ ‘e”e€OØð Bð BˆØˆVŒ9˜ÒÐ¥:¨a°	¬l½DÑ#AÔ#AÐØ˜9œð Bð B�Ø—9’9˜VÑ$Ô$¨Ò5Ð5Ø#×'Ò'¨¯	ª	°-Ñ(@Ô(@ÑAÔAÐAøøØð Qð QˆØˆVŒ9˜Ò#Ð#­
°1°Y´<ÅÑ(FÔ(FÐ#ðð ð ð à˜9œðñ ô ˆAˆi‰Lð
 �Y”<ð QØ)/Ð9NÐ OÐ OÐP��)‘øõ ‘5”5€LØð 6ð 6ˆØˆVŒ9˜Ò#Ð#­
°1°Y´<ÅÑ(FÔ(FÐ#Ø˜9œð 6ð 6�Ø—9’9˜VÑ$Ô$¨
Ò2Ð2Ø ×$Ò$ U§Y¢Y¨t¡_¤_Ñ5Ô5Ð5øøØð Sð SˆØˆVŒ9˜ÒÐ¥:¨a°	¬l½DÑ#AÔ#AÐðð ð ð à˜9œðñ ô ˆAˆi‰Lð
 �Y”<ð SØ)/Ð9PÐ QÐ QÐR��)‘øð €EØð )ñ )ˆØñ (	�U˜2”Y˜vÔ&¨!¨F¬)Ò3Ñ3Ø�Œy˜FÒ"Ð"à$ Rœy¨Ô3�Ø  œ|�Ý˜l­CÑ0Ô0ð 
GµZÀÍcÑ5RÔ5Rð 
GØ+7¸$Ñ+>ÀÑ+M�E˜"”I˜iÑ(Ð(Ý ­dÑ3Ô3ð G½
À<ÕQUÑ8VÔ8Vð GØ+7¸,Ñ+F�E˜"”I˜iÑ(Ð(õ " ,µÑ4Ô4ð PØ17ÀÐ(NÐ(NÐ'O˜Ý! ,µÑ4Ô4ð PØ17ÀÐ(NÐ(NÐ'O˜Ø+7¸,Ñ+F�E˜"”I˜iÑ(Ð(õ ˜a 	œl­DÑ1Ô1ð ð$ð $Ø#$ Y¤<ð$ñ $ô $�A�i‘Lð $ Bœi¨	Ô2�Ø 	œl�Ý˜k­4Ñ0Ô0ð 
EµZÀÍTÑ5RÔ5Rð 
EØ+6¸Ñ+D�E˜"”I˜iÑ(Ñ(Ý ­SÑ1Ô1ð EµjÀÍcÑ6RÔ6Rð EØ+6¸Ñ+=ÀÑ+K�E˜"”I˜iÑ(Ñ(õ " +­sÑ3Ô3ð NØ06ÀÐ'LÐ'LÐ&M˜Ý! +­sÑ3Ô3ð NØ06ÀÐ'LÐ'LÐ&M˜Ø+6¸Ñ+D�E˜"”I˜iÑ(Ñ(à�LŠL˜‰OŒOˆO‰OØ€Fõ.  Ð AÑBÔB€OÝ8¸ÑBÔB€OÝ'¨Ñ1Ô1€HàÐÝ•3�v‘;”; ‘? B¨Ñ+Ô+ð ð ˆØ�!Œ9�=Š=˜Ñ Ô  KÒ/Ð/Ø!"ÐØˆEð 0õ ˜FÑ#Ô#ð ;-ñ ;-‰ˆˆQØ�5Š5�‰=Œ=˜KÒ'Ð'­z¸!¿%º%À	Ñ:JÔ:JÍDÑ/QÔ/QÐ'Øàð 1	Pð ˆKØ�y”\ð 	&ð 	&�Ý! !¥TÑ*Ô*ð ¨a¯eªe°F©m¬mÀ?Ð.RÐ.RØ×&Ò& qÑ)Ô)Ð)ØØ—5’5˜Ñ%Ô%ð ¨¯ª¨v©¬ð àð ×"Ò" 1Ñ%Ô%Ð%Ð%Ø&ÐO°FÀIÐ+NÐ+NÐ*OˆAˆi‰L‰LØð 	P Ð'9Ò 9Ð 9ðð ð ð Ø˜Yœ<ðñ ô ˆHð $ÐV°ÐATÐ(UÐ(UÐ'VˆAˆi‰LˆLð
 ˆKØ�y”\ð Tð T�Ý! !¥TÑ*Ô*ð ¨a¯eªe°F©m¬mÀ?Ð.RÐ.RØ×&Ò& qÑ)Ô)Ð)ØØ—5’5˜‘=”=Ð$7Ò7Ð7à—u’u˜V‘}”}ð .Ø#×*Ò*¨1Ñ-Ô-Ð-øà—U’U˜;Ñ'Ô'ð Tà×&Ò& qÑ)Ô)Ð)Ð)ð %&§E¢E¨*°bÑ$9Ô$9�MØ$ð TØ#×*Ò*°FÀMÐ+RÐ+RÑSÔSÐSøØ&ÐO°FÀIÐ+NÐ+NÐ*OˆAˆi‰Lð �9”ð 	-ð 	-ˆAÝ˜!�TÑ"Ô"ð - q§u¢u¨V¡}¤}¸Ð'GÐ'GØ—’�o tÑ,Ô,Ð,øñ	-ð �6ˆ>Ðs   Æ+F4Æ4GÇGÚ
max_tokensÚreasoning_configÚtool_choiceÚis_oauthÚ	fast_modec                 óê  — t          ||	¬¦  «        \  }}|rt          |¦  «        ng }t          | |¬¦  «        } t          || |¬¦  «        }|r||k    rt	          |dz
  d¦  «        }|�rÄdt
          dœ}t          |t          ¦  «        r|g|z   }n"t          |t          ¦  «        r
|r|d|dœg}n|g}|D ]£}t          |t          ¦  «        rŒ| 
                    d¦  «        dk    rs| 
                    dd¦  «        }|                     d	d
¦  «        }|                     dd
¦  «        }|                     dd¦  «        }|                     dd¦  «        }||d<   Œ¤|r|D ]}d|v rt          |d         z   |d<   Œ|D ]µ}| 
                    d¦  «        }t          |t          ¦  «        r‰|D ]†}t          |t          ¦  «        ro| 
                    d¦  «        dk    r8d|v r4|d                              t          ¦  «        st          |d         z   |d<   Œh| 
                    d¦  «        dk    rd|v r	 Œ‡Œ¶| ||dœ}|r||d<   |r]||d<   |dk    s|€ddi|d<   nH|dk    rddi|d<   n:|dk    r|                     dd¦  «         nt          |t          ¦  «        rd|dœ|d<   t          |	¦  «        }|�rt          |t          ¦  «        ró|sñ| 
                    d ¦  «        d!urÚd"|                      ¦   «         vrÄt          | 
                    d#d$¦  «        ¦  «                             ¦   «         }t"           
                    |d%¦  «        }t%          | ¦  «        rBd&d'd(œ|d)<   t&           
                    |d$¦  «        }|d*k    rt)          | ¦  «        sd+}d#|i|d,<   n#d |d-œ|d)<   d|d.<   t	          ||d/z   ¦  «        |d0<   t+          | ¦  «        rd1D ]}|                     |d¦  «         Œ|
r”t-          |	¦  «        s…d2|                     d3i ¦  «        d4<   t          t1          |	¦  «        ¦  «        }|r|                     t4          ¦  «         |                     t8          ¦  «         d5d6                     |¦  «        i|d7<   |S )8uZ  Build kwargs for anthropic.messages.create().

    Naming note â€” two distinct concepts, easily confused:
      max_tokens     = OUTPUT token cap for a single response.
                       Anthropic's API calls this "max_tokens" but it only
                       limits the *output*.  Anthropic's own native SDK
                       renamed it "max_output_tokens" for clarity.
      context_length = TOTAL context window (input tokens + output tokens).
                       The API enforces: input_tokens + max_tokens â‰¤ context_length.
                       Stored on the ContextCompressor; reduced on overflow errors.

    When *max_tokens* is None the model's native output ceiling is used
    (e.g. 128K for Opus 4.6, 64K for Sonnet 4.6).

    When *context_length* is provided and the model's native output ceiling
    exceeds it (e.g. a local endpoint with an 8K window), the output cap is
    clamped to context_length âˆ’ 1.  This only kicks in for unusually small
    context windows; for full-size models the native output cap is always
    smaller than the context window so no clamping happens.
    NOTE: this clamping does not account for prompt size â€” if the prompt is
    large, Anthropic may still reject the request.  The caller must detect
    "max_tokens too large given prompt" errors and retry with a smaller cap
    (see parse_available_output_tokens_from_error + _ephemeral_max_output_tokens).

    When *is_oauth* is True, applies Claude Code compatibility transforms:
    system prompt prefix, tool name prefixing, and prompt sanitization.

    When *preserve_dots* is True, model name dots are not converted to hyphens
    (for Alibaba/DashScope anthropic-compatible endpoints: qwen3.5-plus).

    When *base_url* points to a third-party Anthropic-compatible endpoint,
    thinking block signatures are stripped (they are Anthropic-proprietary).

    When *fast_mode* is True, adds ``extra_body["speed"] = "fast"`` and the
    fast-mode beta header for ~2.5x faster output throughput on Opus 4.6.
    Currently only supported on native Anthropic endpoints (not third-party
    compatible ones).
    rp   )rc  )r5   rJ  rW   r†  ru  r   zHermes AgentzClaude CodezHermes agentzhermes-agentrS   zNous Researchrœ   rq  rµ  rÇ  rÌ  rÎ  )r   r¹  rø  rµ   rn  ÚautoNrú  ÚrequiredrD   ÚnonerË  )ru  rq  ÚenabledFÚhaikuÚeffortr   r   ÚadaptiveÚ
summarized)ru  Údisplayr¬  r   r   Úoutput_config)ru  Úbudget_tokensÚtemperaturer   rø  )r	  Útop_pÚtop_kÚfastÚ
extra_bodyÚspeedr�   r‘   Úextra_headers)r÷  r{  re  r;   r   Ú_CLAUDE_CODE_SYSTEM_PREFIXr+   r¤  ro   r¾   r½   r   Ú_MCP_TOOL_PREFIXrl   rß  r{   r   ÚTHINKING_BUDGETrG   ÚADAPTIVE_EFFORT_MAPrK   rO   rx   Ú
setdefaultr…   rÙ  r›   rx  Ú_FAST_MODE_BETArš   )r   r¹  rn  rø  rù  rú  rû  rc  r5   rq   rü  rµ   Úanthropic_messagesÚanthropic_toolsÚeffective_max_tokensÚcc_blockr�  rW   rË  Úmsgrµ  rŸ   Ú_is_kimi_codingr  ÚbudgetÚadaptive_effortÚ_sampling_keyÚbetass                               r'   Úbuild_anthropic_kwargsr   å  s{  € õf "?¸xÐRZÐ![Ñ![Ô![Ñ€FÐØ;@ÐHÕ0°Ñ7Ô7Ð7Àb€Oå  °mÐDÑDÔD€Eõ
 BØ�E¨.ðñ ô Ðð ð :Ð.°Ò?Ð?Ý" >°AÑ#5°qÑ9Ô9Ðð ñ %!à"Õ,FÐGÐGˆÝ�f�dÑ#Ô#ð 	 Ø�Z &Ñ(ˆFˆFÝ˜¥Ñ$Ô$ð 	 ¨ð 	 Ø¨¸Ð @Ð @ÐAˆFˆFà�ZˆFð ð 	%ð 	%ˆEÝ˜%¥Ñ&Ô&ð %¨5¯9ª9°VÑ+<Ô+<ÀÒ+FÐ+FØ—y’y ¨Ñ,Ô,�Ø—|’| N°MÑBÔB�Ø—|’| N°MÑBÔB�Ø—|’| N°MÑBÔB�Ø—|’| O°[ÑAÔA�Ø $��f‘øð ð 	CØ'ð Cð C�Ø˜T�>�>Ý#3°d¸6´lÑ#B�D˜‘Løð &ð 		!ð 		!ˆCØ—g’g˜iÑ(Ô(ˆGÝ˜'¥4Ñ(Ô(ð !Ø$ð !ð !�EÝ! %­Ñ.Ô.ð !Ø Ÿ9š9 VÑ,Ô,°
Ò:Ð:¸vÈ¸¸Ø#(¨¤=×#;Ò#;Õ<LÑ#MÔ#Mð QÝ0@À5ÈÄ=Ñ0P  f¡øØ"ŸYšY vÑ.Ô.°-Ò?Ð?ÀMÐUZÐDZÐDZØ øøð Ø&Ø*ðð €Fð ð "Ø!ˆˆxÑàð JØ)ˆˆw‰à˜&Ò Ð  KÐ$7Ø%+¨VÐ$4ˆF�=Ñ!Ð!Ø˜JÒ&Ð&Ø%+¨U OˆF�=Ñ!Ð!Ø˜FÒ"Ð"à�JŠJ�w Ñ%Ô%Ð%Ð%Ý˜¥SÑ)Ô)ð 	Jà-3¸[Ð$IÐ$IˆF�=Ñ!õ2 /¨xÑ8Ô8€OØñ P�JÐ'7½Ñ>Ô>ð PÀð PØ×Ò 	Ñ*Ô*°%Ð7Ð7¸GÈ5Ï;Ê;É=Ì=Ð<XÐ<XÝÐ)×-Ò-¨h¸ÑAÔAÑBÔB×HÒHÑJÔJˆFÝ$×(Ò(¨°Ñ6Ô6ˆFÝ*¨5Ñ1Ô1ð Pà&Ø+ð&ð &��zÑ"õ #6×"9Ò"9¸&À(Ñ"KÔ"K�ð # gÒ-Ð-Õ6LÈUÑ6SÔ6SÐ-Ø&+�Oà˜oð+��Ñ'Ð'ð /8È&Ð%QÐ%Q��zÑ"à()��}Ñ%Ý'*Ð+?ÀÈ$ÁÑ'OÔ'O��|Ñ$õ   Ñ&Ô&ð ,Ø>ð 	,ð 	,ˆMØ�JŠJ�} dÑ+Ô+Ð+Ð+ð ð FÕ;¸HÑEÔEð FØ7=ˆ×Ò˜,¨Ñ+Ô+¨GÑ4õ Õ/°Ñ9Ô9Ñ:Ô:ˆØð 	,Ø�LŠLÕ*Ñ+Ô+Ð+Ø�Š•_Ñ%Ô%Ð%Ø#3°S·X²X¸e±_´_Ð"EˆˆÑà€Mr)   r>   )NN)F)NFFNNF)^Ú__doc__r®  rº   Úloggingr"  r´   rY   Úpathlibr   Úhermes_constantsr   Útypingr   r   r   r   r	   Úutilsr
   Ú	anthropicr—   r˜   Ú	getLoggerÚ__name__r¸   r  r  rJ   rE   rN   r   r   ro   r-   r(   r4   r;   r,   rG   rK   rO   r„   r€   r  r›   r`   rP   Ú__annotations__re   r  r  rh   rm   rr   rx   r{   r}   r¤  r…   r.   r£   r©   rÃ   rÒ   r×   rÞ   r  r  r	  r  r  r(  r1  rO  rU  rP  rQ  r]  r¥  r>  r[  r^  rb  re  rm  r{  rƒ  r�  r   r™  r´  r¸  r÷  r   r?   r)   r'   ú<module>r+     sì	  ðð
ð 
ð 
ð €€€Ø €€€Ø €€€Ø 	€	€	€	Ø €€€Ø Ð Ð Ð Ø Ð Ð Ð Ð Ð à ,Ð ,Ð ,Ð ,Ð ,Ð ,Ø 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ø *Ð *Ð *Ð *Ð *Ð *ðØ&Ð&Ð&Ð&Ð&øØð ð ð Ø€N€N€Nðøøøð 
ˆÔ	˜8Ñ	$Ô	$€à!¨5¸DÈÐNÐN€ð ØØØØØðð Ð ð *Ð ð
 !=Ð ð "0Ð ð !à Ø à Ø Ø à Ø à à Ø à Ø Ø à!ð/ð Ð ð8 #*Ð ð Sð ¨Sð ð ð ð ð*,°X¸c´]ð ,ð ,ð ,ð ,ð: %)ðð àðð ˜S”Mðð 	ð	ð ð ð ð>B sð B¨tð Bð Bð Bð Bð
= #ð =¨$ð =ð =ð =ð =ðC Cð C¨Dð Cð Cð Cð Cð" &Ø,ð€ð @Ð ð
 )€ð
 ØðÐ ð !)Ð Ø,0Ð ˜H SœMÐ 0Ð 0Ñ 0ð) Sð )ð )ð )ð )ð2 YÐ ØÐ ð& #ð &ð &ð &ð &ð˜ð  ð ð ð ð ð8!¨#ð !ð !ð !ð !ð°°t±ð Àð ð ð ð ð T s¨T¡zð T°dð Tð Tð Tð Tðm C¨$¡Jð m°4ð mð mð mð mð
¨¨t©ð 
¸¸S¼	ð 
ð 
ð 
ð 
ðS.ð S. Cð S.°3ð S.Èð S.ð S.ð S.ð S.ðl¨3ð ð ð ð ð69°X¸dÀ3ÈÀ8¼nÔ5Mð 9ð 9ð 9ð 9ðx% h¨t°C¸°H¬~Ô&>ð %ð %ð %ð %ðP ¨#¤ð ð ð ð ð* d¨3°¨8¤nð *¸ð *ð *ð *ð *ð JOð =7ð =7ð =7°ð =7À$ð =7ÐSWÐX[Ð]`ÐX`ÔSað =7ð =7ð =7ð =7ð@  S¨# X¤ð °8¸C´=ð ð ð ð ð4 "ð*Eð *Eð *EØð*Eàð*Eð ð*Eð
 �TŒNð*Eð 
ð*Eð *Eð *Eð *EðZð °xÀÀSÈ#ÀXÄÔ7Oð Ð[cÐdgÔ[hð ð ð ð ð°Sð ÀÈ$ÈsÐTWÈxÌ.ÔAYð Ð^fÐgjÔ^kð ð ð ð ð,) ¨#¤ð )ð )ð )ð )ðX%˜x¨œ}ð %ð %ð %ð %ðX :Ð ØAÐ ØIÐ Ø@€Ø$�_Ñ&Ô&Ð)@Ñ@Ð ð
˜ð 
ð 
ð 
ð 
ð_ X¨d°3¸°8¬nÔ%=ð _ð _ð _ð _ðD	 x°°S¸#°X´Ô'?ð 	ð 	ð 	ð 	ð" ð ¨ð ð ð ð ð(ð  ð °Dð ÀSð ð ð ð ð4
!˜sð 
! sð 
!ð 
!ð 
!ð 
!ð d¨4¤jð °T¸$´Zð ð ð ð ð' sð '¨t°C¸°H¬~ð 'ð 'ð 'ð 'ð,¨Sð °X¸dÀ3ÈÀ8¼nÔ5Mð ð ð ð ð2 12È$ð +ð +ð +˜#ð +¨#ð +¸(À3¼-ð +ÐSVð +ð +ð +ð +ð\°°S¸#°X´ð À4ÈÈSÐRUÈXÌÔCWð ð ð ð ð"
¨3ð 
°3ð 
ð 
ð 
ð 
ð  ðwð wØ�4Œjðwà�D‰jðwð ˆ8�CŒ=˜$˜tœ*Ð$Ô%ðwð wð wð wð@
 "&ØØØ$(ØØðLð LØðLà�4ŒjðLð �D˜”JÔðLð ˜”ð	Lð
 ˜t C¨ Hœ~Ô.ðLð ˜#”ðLð ðLð ðLð ˜S”MðLð �D‰jðLð ðLð 
ˆ#ˆsˆ(„^ðLð Lð Lð Lð Lð Ls   ½A ÁAÁA