§
    ÷žyj´  ã                  ód  — U d Z ddlmZ ddlmZmZ ddlmZ ddlm	Z	 e G d„ d¦  «        ¦   «         Z
 ed¬	¦  «         G d
„ d¦  «        ¦   «         Z edddd¦  «         edddd¦  «         edddd¦  «         edddd¦  «         edddd¦  «         ed d!d"d#¦  «         ed$d%d&d'¦  «         ed(d)d*d+¦  «         ed,d-d.d/¦  «         ed0d1d2d3¦  «         ed4d5d6d7¦  «         ed8d9d:¦  «         ed;d<d=¦  «         ed>d?d@¦  «        fZdAedB<   dC„ eD ¦   «         ZdDedE<   dWdK„ZdXdM„ZdYdP„ZdQdRœdZdU„ZdVS )[uñ  Provider-agnostic billing/credit recovery links.

Maps a billing-classified failure onto a recovery link + label. *Detection*
is not done here â€” that is :mod:`agent.error_classifier`
(``FailoverReason.billing``), the single source of truth for "credit wall vs.
rate limit / auth / transport". The resulting :class:`BillingBlock` rides the
turn result and the gateway ``message.complete`` event so every surface (CLI,
TUI, desktop) renders one structured signal instead of re-parsing error text.
é    )Úannotations)ÚasdictÚ	dataclass)ÚOptional©Úbase_url_host_matchesc                  óX   — e Zd ZU dZded<   ded<   ded<   ded<   ded	<   ded
<   dd„ZdS )ÚBillingBlockum  Structured billing-wall descriptor shared across every surface.

    ``is_nous`` is the routing bit: Nous has a first-class in-app billing surface
    (desktop Settings â†’ Billing, TUI/CLI ``/topup``), so surfaces prefer that over
    ``billing_url``; third-party providers have no in-app flow, so ``billing_url``
    is the deep link the user actually needs.
    ÚstrÚproviderÚprovider_labelÚmodelúOptional[str]Úbilling_urlÚboolÚis_nousÚmessageÚreturnÚdictc                ó    — t          | ¦  «        S ©N)r   )Úselfs    ú9/home/ragecks/.hermes/hermes-agent/agent/billing_links.pyÚto_dictzBillingBlock.to_dict$   s   € Ý�d‰|Œ|Ðó    N)r   r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú__annotations__r   © r   r   r
   r
      sr   € € € € € € ðð ð €M€M�MØÐÐÑØ€J€J�JØÐÐÑØ€M€M�MØ€L€L�Lðð ð ð ð ð r   r
   T)Úfrozenc                  ó<   — e Zd ZU ded<   ded<   ded<   dZded<   dS )	Ú	_Providerr   ÚlabelÚurlztuple[str, ...]Úslugsr!   ÚhostsN)r   r   r   r    r(   r!   r   r   r$   r$   (   sA   € € € € € € à€J€J�JØ€H€H�HØÐÐÑØ€EÐÐÐÑÐÐr   r$   ÚOpenAIz9https://platform.openai.com/settings/organization/billing)Úopenai)zapi.openai.comÚ	Anthropicz.https://console.anthropic.com/settings/billing)Ú	anthropic)zapi.anthropic.comÚ
OpenRouterz&https://openrouter.ai/settings/credits)Ú
openrouter)zopenrouter.aiÚxAIz)https://console.x.ai/team/default/billing)Úxaiz	xai-oauth)zapi.x.aiÚDeepSeekz$https://platform.deepseek.com/top_up)Údeepseek)zapi.deepseek.comÚGroqz)https://console.groq.com/settings/billing)Úgroq)zapi.groq.comÚMistralz"https://console.mistral.ai/billing)Úmistral)zapi.mistral.aizTogether AIz(https://api.together.ai/settings/billing)Útogether)zapi.together.aizapi.together.xyzzFireworks AIz$https://fireworks.ai/account/billing)Ú	fireworks)zfireworks.aiÚ
Perplexityz&https://www.perplexity.ai/settings/api)Ú
perplexity)zperplexity.aiz	Google AIz'https://aistudio.google.com/app/billing)ÚgoogleÚgemini)z!generativelanguage.googleapis.comÚCoherez$https://dashboard.cohere.com/billing)ÚcoherezMoonshot AIz(https://platform.moonshot.ai/console/pay)ÚmoonshotÚNVIDIAz)https://build.nvidia.com/settings/billing)Únvidiaztuple[_Provider, ...]Ú
_PROVIDERSc                ó(   — i | ]}|j         D ]}||“ŒŒS r!   )r'   )Ú.0ÚpÚslugs      r   ú
<dictcomp>rG   F   s)   € Ð!RÐ!RÐ!R¨aÈ!Ì'Ð!RÐ!RÀ$ $¨Ð!RÐ!RÐ!RÐ!Rr   zdict[str, _Provider]Ú_BY_SLUGr   r   Úbase_urlr   r   c                óœ   — | pd                      ¦   «                              ¦   «         dk    rdS t          t          |pd¦  «        d¦  «        S )zBTrue when the failing route is the Nous-managed inference gateway.Ú ÚnousTzinference-api.nousresearch.com)ÚstripÚlowerr   r   )r   rI   s     r   Úis_nous_inference_routerO   I   sK   € àˆ�B×ÒÑÔ×%Ò%Ñ'Ô'¨6Ò1Ð1ØˆtÝ ¥ X ^°Ñ!4Ô!4Ð6VÑWÔWÐWr   r   c                 óH   — 	 ddl m}   | d¦  «        S # t          $ r Y dS w xY w)zZBest-effort Nous portal billing URL (text-surface fallback; Nous prefers the in-app flow).r   ©Únous_portal_billing_urlNz'https://portal.nousresearch.com/billing)Úhermes_cli.nous_accountrR   Ú	ExceptionrQ   s    r   Ú_nous_billing_urlrU   P   sN   € ð9ØCÐCÐCÐCÐCÐCà&Ð& tÑ,Ô,Ð,øÝð 9ð 9ð 9Ø8Ð8Ð8ð9øøøs   ‚ “
! !rF   útuple[str, Optional[str]]c                ó’  ‡— t                                | ¦  «        }|r|j        |j        fS t	          |pd¦  «        Št
          D ]2}t          ˆfd„|j        D ¦   «         ¦  «        r|j        |j        fc S Œ3|                      dd¦  «                             dd¦  «         	                    ¦   «          
                    ¦   «         pddfS )uS   Resolve ``(label, url)``: exact slug â†’ base_url host â†’ readable-label fallback.rK   c              3  ó8   •K  — | ]}t          ‰|¦  «        V — Œd S r   r   )rD   ÚhostÚbases     €r   ú	<genexpr>z)_resolve_provider_link.<locals>.<genexpr>b   s.   øè è € ÐEÐE°TÕ$ T¨4Ñ0Ô0ÐEÐEÐEÐEÐEÐEr   Ú_Ú Ú-zyour providerN)rH   Úgetr%   r&   r   rB   Úanyr(   ÚreplacerM   Útitle)rF   rI   ÚhitrE   rZ   s       @r   Ú_resolve_provider_linkrd   Z   sÔ   ø€ å
�,Š,�tÑ
Ô
€CØ
ð "ØŒy˜#œ'Ð!Ð!åˆxˆ~˜2ÑÔ€DÝð "ð "ˆÝÐEÐEÐEÐE¸Q¼WÐEÑEÔEÑEÔEð 	"Ø”7˜AœE�>Ð!Ð!Ð!ð	"ð �<Š<˜˜SÑ!Ô!×)Ò)¨#¨sÑ3Ô3×9Ò9Ñ;Ô;×AÒAÑCÔCÐVÀÐX\Ð\Ð\r   rK   )r   r   r   c                ó8  — | pd                      ¦   «                              ¦   «         }|pd                      ¦   «         }t          ||¦  «        r$t          |pdd|t	          ¦   «         d|pd¦  «        S t          ||¦  «        \  }}t          ||||d|pd¦  «        S )a  Build the billing descriptor for a billing-classified failure.

    ``message`` is the guidance already assembled by the agent loop
    (:func:`agent.conversation_loop._billing_or_entitlement_message`), carried
    through unchanged so every surface shows identical copy.
    rK   rL   zNous PortalTF)rM   rN   rO   r
   rU   rd   )r   rI   r   r   rF   r%   r&   s          r   Úbuild_billing_blockrf   h   s§   € ð ˆN˜×!Ò!Ñ#Ô#×)Ò)Ñ+Ô+€DØˆ[�b×ÒÑ!Ô!€Eå˜t XÑ.Ô.ð lÝ˜D˜N F¨M¸5ÕBSÑBUÔBUÐW[Ð]dÐ]jÐhjÑkÔkÐkå'¨¨hÑ7Ô7�J€Eˆ3Ý˜˜e U¨C°¸¸À2ÑFÔFÐFr   N)r   r   rI   r   r   r   )r   r   )rF   r   rI   r   r   rV   )
r   r   rI   r   r   r   r   r   r   r
   )r   Ú
__future__r   Údataclassesr   r   Útypingr   Úutilsr   r
   r$   rB   r    rH   rO   rU   rd   rf   r!   r   r   ú<module>rk      sÂ  ððð ð ð #Ð "Ð "Ð "Ð "Ð "à )Ð )Ð )Ð )Ð )Ð )Ð )Ð )Ø Ð Ð Ð Ð Ð à 'Ð 'Ð 'Ð 'Ð 'Ð 'ð ðð ð ð ð ñ ô ñ „ðð( €�$ÐÑÔð ð  ð  ð  ð  ñ  ô  ñ Ôð ð €IˆhÐSÐU`ÐbuÑvÔvØ€IˆkÐKÈ^Ð]sÑtÔtØ€IˆlÐDÀoÐWiÑjÔjØ€IˆeÐ@ÐBVÐXeÑfÔfØ€IˆjÐ@À-ÐQfÑgÔgØ€IˆfÐAÀ9ÐN_Ñ`Ô`Ø€IˆiÐ=¸|ÐM`ÑaÔaØ€IˆmÐGÈÐXñ  Aô  AØ€IˆnÐDÀnÐVgÑhÔhØ€IˆlÐDÀoÐWiÑjÔjØ€IˆkÐDÐFZð  ]Cñ  Dô  DØ€IˆhÐ>ÀÑLÔLØ€IˆmÐGÈÑWÔWØ€IˆhÐCÀ[ÑQÔQð%€
ð ð ð ñ ð" "SÐ!R°:Ð!RÑ!RÔ!R€Ð RÐ RÐ RÑ RðXð Xð Xð Xð9ð 9ð 9ð 9ð]ð ]ð ]ð ]ð& ðGð Gð Gð Gð Gð Gð Gð Gr   