+
    lHàj -  ã                  óÈ   € R t ^ RIHt ^ RIt^ RIHt ^RIHt R tR R lt	R R	 lt
R
 R ltRR/R R lltR R ltR R ltR R ltR R ltR R ltR R ltR R ltR# )a¾  Billing / usage / subscription serializers for the TUI RPC surface.

STRUCTURED envelopes (result.ok / result.error) rather than JSON-RPC errors, so
rpc() always resolves and the client branches on the typed billing code.
Data-building lives in agent/billing_view.py + hermes_cli/nous_billing.py.
Bodies are rebound onto server.py's globals at install time (method_ctx.bind_module),
so tests may still monkeypatch e.g. ``server._usage_payload``.
)ÚannotationsN)ÚOptional)Úbind_modulec                ó$   € V f   R# \        V 4      # )u5   Decimal/number â†’ wire string (None passes through).N)Ústr)Úvalues   &Ú=/home/ubuntu/.hermes/hermes-agent/tui_gateway/billing_view.pyÚ	_wire_strr	      s   € à’=ˆ4Ð0¤c¨%£jÐ0ó    c               ó   € V ^8„  d   QhRR/# ©é   ÚreturnÚdict© )Úformats   "r   Ú__annotate__r      s   € ÷ 4ñ 4 Tñ 4r
   c                ó¾  a € ^ RI HpHpHpHp VRVRVR/p\        V 3R lVP                  4        4       R4      pVf9   \        S RR4      p\        S V4      '       d   RMRpV'       d   \        V4      MTpR	R
RTR\        S 4      R\        S RR4      R\        S RR4      R\        S R/ 4      ;'       g    / R\        S RR4      R\        S RR4      R\        S RR4      /	# )zFMap a BillingError into the result.error envelope the TUI branches on.)ÚBillingRemoteSpendingRevokedÚBillingScopeRequiredÚBillingSessionRevokedÚBillingTransientÚremote_spending_revokedÚsession_revokedÚinsufficient_scopec              3  óT   <"  € T F  w  r\        SV4      '       g   K  Vx € K  	  R # 5i©N)Ú
isinstance)Ú.0ÚclsÚkÚexcs   &  €r   Ú	<genexpr>Ú+_serialize_billing_error.<locals>.<genexpr>   s   øé € ÐG¡‘v�s´*¸SÀ#×2F—’£ùs   ƒ(ž
(NÚerrorÚrate_limitedÚokFÚmessageÚ
portal_urlÚretry_afterÚpayloadÚactorÚcodeÚrecovery)
Úhermes_cli.nous_billingr   r   r   r   ÚnextÚitemsÚgetattrr   r   )	r!   r   r   r   r   ÚtypedÚkindr$   Úfallbacks	   f        r   Ú_serialize_billing_errorr5      së   ø€ ÷eó eà)Ð+DØ"Ð$5Ð7KÐMaðc€EäÔG §¡¤ÓGÈÓN€DØ‚|Ü˜˜W dÓ+ˆÜ%/°Ð5E×%FÒ%F‘>ÈGˆß"Œs�5Œz¨ˆàˆe�W˜d I¬s°3«xØ”g˜c <°Ó6Ø”w˜s M°4Ó8Ø”7˜3 	¨2Ó.×4Ð4°"à”˜˜g tÓ,¨f´g¸cÀ6È4Ó6PØ”G˜C ¨TÓ2ð4ð 4r
   c               ó   € V ^8„  d   QhRR/# ©r   r   zdict | Noner   )r   s   "r   r   r   ,   s   € ÷ Yñ Y [ñ Yr
   c           
     ó*  € V f   R # V P                   R8X  d5   RRRV P                  RV P                  RV P                  RV P                  /# V P                   R8X  d   RRRV P
                  RV P                  /# RR	R
V P                  RV P                  /# )NÚcardr3   ÚbrandÚlast4ÚwalletÚresolved_viaÚlinkÚemailÚunknownÚraw_kind)r3   r:   r;   r<   r=   r?   rA   )Úpms   &r   Ú_serialize_payment_methodrC   ,   sŒ   € ð 
‚zÙØ	‡w�w�&Ôà�F˜G R§X¡X¨w¸¿¹À(ÈBÏIÉIØ˜BŸO™Oð
ð 	
ð 
‡w�w�&ÔØ˜ ¨¯©°>À2Ç?Á?ÐSÐSØ�I˜z¨2¯;©;¸ÈÏÉÐXÐXr
   c               ó   € V ^8„  d   QhRR/# r7   r   )r   s   "r   r   r   ;   s   € ÷ Oñ O°ñ Or
   c                óð  € V f   R # R pV P                   e„   RV P                   P                  /pV P                   P                  R8X  dQ   VP                  V P                   P                  V P                   P                  V P                   P
                  R7       RV P                  R\        V P                  4      RV! V P                  4      R\        V P                  4      RV! V P                  4      R	V/# )
Nr3   Údistinct)Úpayment_method_idr:   r;   ÚenabledÚthreshold_usdÚthreshold_displayÚreload_to_usdÚreload_to_displayr9   )
r9   r3   ÚupdaterG   r:   r;   rH   r	   rI   rK   )ÚarÚformat_moneyÚcard_outs   && r   Ú_serialize_auto_reloadrQ   ;   sÇ   € Ø	‚zÙØ€HØ	‡w�wÒØ˜BŸG™GŸL™LÐ)ˆØ�7‰7�<‰<˜:Ô%Ø�O‰O¨b¯g©g×.GÑ.GÈrÏwÉwÏ}É}Ø"$§'¡'§-¡-ð ô 1ð 	�2—:‘:˜´	¸"×:JÑ:JÓ0KØ™\¨"×*:Ñ*:Ó;Øœ 2×#3Ñ#3Ó4Ø™\¨"×*:Ñ*:Ó;¸VÀXð	Oð Or
   Úfree_tier_accountFc               ó    € V ^8„  d   QhRRRR/# )r   rR   Úboolr   r   r   )r   s   "r   r   r   K   s   € ÷ '2ñ '2¸$ð '2È4ñ '2r
   c               ó:  € ^ RI Hp ^ RIHp R;rEV P                  eq   RV P                  P
                  RV P                  P                  RV P                  P                  RV P                  P                  RV P                  P                  /pV P                  ei   V P                  pR	\        VP                  4      R
V! VP                  4      R\        VP                  4      RV! VP                  4      RVP                  /p/ RRbRV P                  bR\!        V4      bRV'       d   TMRbRV P"                  bRV P$                  bRV P&                  bRV P(                  bRV P*                  bRV P,                  bR\        V P.                  4      bRV! V P.                  4      bRV P0                  bRV P2                   Uu. uF  p\        V4      NK  	  upbRV P2                   Uu. uF
  qr! V4      NK  	  upbR\        V P4                  4      bR\        V P6                  4      bR VR!\9        V P:                  4      R"VR#\=        V P>                  V4      R$\A        V R$R4      R%V PB                  R&V PD                  R'\G        V 4      R(\I        V 4      /	C# u upi u upi ))uÓ   Serialize a BillingState for the wire (Decimals â†’ strings, money-safe). ``free_tier_account`` marks the
Nous free tier: no account, no balance, nothing to pay; the renderer branches on it before
``logged_in``.©rO   )ÚGUEST_MODELNr:   r;   ÚmaskedÚdisplayr=   Ú	limit_usdÚlimit_displayÚspent_this_month_usdÚspent_displayÚis_default_ceilingr&   TÚ	logged_inrR   Úfree_tier_modelÚorg_nameÚorg_slugÚroleÚis_adminÚcan_change_planÚ
can_chargeÚbalance_usdÚbalance_displayÚcli_billing_enabledÚcharge_presetsÚcharge_presets_displayÚmin_usdÚmax_usdr9   Úpayment_methodÚmonthly_capÚauto_reloadÚkeep_going_on_creditsr(   r$   ÚusageÚ
plan_usage)%Úagent.billing_viewrO   Úhermes_cli.anon_authrW   r9   r:   r;   rX   rY   r=   ro   r	   rZ   r\   r^   r_   rT   ra   rb   rc   rd   re   rf   rg   ri   rj   rl   rm   rC   rn   rQ   rp   r1   r(   r$   Ú_usage_payloadÚ_plan_usage_payload)ÚstaterR   rO   rW   r9   ÚmcÚmÚps   &$      r   Ú_serialize_billing_stater|   K   s«  € õ 0Ý0àÐ€DØ‡z�zÒà�U—Z‘Z×%Ñ% w°·
±
×0@Ñ0@À(ÈEÏJÉJ×L]ÑL]à�u—z‘z×)Ñ)¨>¸5¿:¹:×;RÑ;RðTˆð ×ÑÒ$Ø×ÑˆØœ9 Q§[¡[Ó1°?ÁLÐQR×Q\ÑQ\ÓD]Ø$¤i°×0FÑ0FÓ&GØ™|¨A×,BÑ,BÓCØ" A×$8Ñ$8ð:ˆð2Øˆdð2Ø §¡ð2àœTÐ"3Ó4ð2à6G×XiÉÐosð2ð 	�E—N‘Nð2ð 	�E—N‘Nð	2ð %+¨E¯J©Jð	2ð 9CÀEÇNÁNð	2ð
 	˜5×0Ñ0ð2ð
 3?À×@PÑ@Pð2ð 	”y ×!2Ñ!2Ó3ð2ð 	™<¨×(9Ñ(9Ó:ð2ð 	˜u×8Ñ8ð2ð 	°×1EÒ1EÓFÑ1E¨Aœ9 Qž<Ñ1EÑFð2ð 	!¸E×<PÒ<PÓ"QÑ<P°q <°¦?Ñ<PÑ"Qð2ð 	”9˜UŸ]™]Ó+ð2ð .7¼	À%Ç-Á-Ó8Pð2ð 	�Ð&Ô(AÀ%×BVÑBVÓ(WØ�r˜=Ô*@À×ARÑARÐT`Ó*aØ¤¨Ð0GÈÓ!NØ�e×&Ñ&¨°·±à” Ó&ð 	Ô)¨%Ó0ñ)2ð 2ùò GùÚ"Qs   ÇJÇ'Jc               ó   € V ^8„  d   QhRR/# ©r   r   zOptional[dict]r   )r   s   "r   r   r   u   s   € ÷ ñ  .ñ r
   c                óR  € \        V RR4      '       g   R#  ^ RIHp ^ RIHp V! RR7      pVe   V! \        VRR4      4      f   R# ^ R	IHp V! RR
7      pVe   VP                  4       # R#   \         d0    \        P                  ! \        4      P                  RRR7        R# i ; i)a—  ``ModelOptionProvider.plan_usage``-shaped block (usage-window gauges; None for every other account)
for the billing/subscription states. Window plans only: the plan shape comes from the snapshot
``_usage_payload`` just cached (no round trip), and any other account (or no snapshot) returns None
without a lookup, exactly like main. ``warm=True`` refreshes an expired snapshot for window plans. Never raises.r_   FN)Ú_window_seed_fields)Úcached_nous_portal_account_infoT)Úany_ageÚusage_window)Únous_picker_usage)ÚwarmzPlan usage payload unavailable)Úexc_info)r1   Úagent.credits_trackerr€   Úhermes_cli.nous_accountr�   Úhermes_cli.model_picker_usager„   Ú
to_payloadÚ	ExceptionÚloggingÚ	getLoggerÚ__name__Údebug)rx   r€   r�   Úsnapshotr„   rr   s   &     r   rw   rw   u   s¡   € ô
 �5˜+ u×-Ò-ÙðÝ=ÝKÙ2¸4Ô@ˆØÒÑ2´7¸8À^ÐUYÓ3ZÓ[ÒcÙÝCÙ! tÔ,ˆØ%*Ò%6ˆu×ÑÓ!Ð@¸DÐ@øÜô Ü×Òœ(Ó#×)Ñ)Ð*JÐUYÐ)ÔZÚðús   —.A, Á"A, Á*A, Á,6B&Â%B&c               ó   € V ^8„  d   QhRR/# r   r   )r   s   "r   r   r   Š   s   € ÷ $ñ $˜Tñ $r
   c                óˆ   € \        V RR4      '       g   RR/#  ^ RIHp \        V! 4       4      #   \         d    RR/u # i ; i)zWShared usage model for the /topup + /subscription bars: only when logged in, fail-open.r_   FÚ	available)Úbuild_usage_model)r1   Úagent.billing_usager”   Ú_serialize_usage_modelr‹   )rx   r”   s   & r   rv   rv   Š   sM   € ä�5˜+ u×-Ò-Ø˜UÐ#Ð#ð$Ý9Ü%Ñ&7Ó&9Ó:Ð:øÜô $Ø˜UÐ#Ò#ð$ús   ™/ ¯AÁ Ac               ó   € V ^8„  d   QhRR/# r~   r   )r   s   "r   r   r   •   s   € ÷ Fñ F ñ Fr
   c                óÒ   € V f   R# ^ RI Hp RV P                  RV! V P                  4      RV! V P                  4      RV! V P
                  4      RV P                  RV P                  /# )	uI   Serialize a UsageBar (dollar magnitudes â†’ display strings + fractions).N)Ú_fmt_usdr3   Úremaining_displayÚtotal_displayr]   Úpct_usedÚfill_fraction)r•   r™   r3   Úremaining_usdÚ	total_usdÚ	spent_usdrœ   r�   )Úbarr™   s   & r   Ú_serialize_usage_barr¢   •   s`   € à
‚{ÙÝ,à�—‘Ð-©x¸×8IÑ8IÓ/JØ™ #§-¡-Ó0°/Á8ÈCÏMÉMÓCZØ�C—L‘L /°3×3DÑ3DðFð Fr
   c               ó   € V ^8„  d   QhRR/# r   r   )r   s   "r   r   r       s   € ÷ <ñ < Tñ <r
   c                óÔ  a€ ^ RI HoHp V e   \        V RR4      '       g   RRRR/# V3R lpRRRRRV P                  R	V P
                  R
V P                  R\        V RR4      ;'       g    V! V P                  4      RV! V P                  4      RV! V P                  4      RV! V P                  4      RV P                  R\        V P                  4      R\        V P                  4      /# )uS   Serialize a UsageModel for the wire â€” the shared two-bar dollar view (fail-open).)r™   Úformat_renewsNr“   Fr&   Tc                ó    <€ V f   R # S! V 4      # r   r   )r   r™   s   &€r   Ú_usdÚ$_serialize_usage_model.<locals>._usd¦   s   ø€ Ø’}ˆtÐ9©(°5«/Ð9r
   ÚstatusÚ	plan_nameÚ	renews_atÚrenews_displayÚsubscription_remaining_displayÚtopup_remaining_displayÚtotal_spendable_displayÚ	has_topupÚplan_barÚ	topup_bar)r•   r™   r¥   r1   r©   rª   r«   Úsubscription_remaining_usdÚtopup_remaining_usdÚtotal_spendable_usdr°   r¢   r±   r²   )Úmodelr¥   r§   r™   s   &  @r   r–   r–       sÔ   ø€ ç;Ø‚}œG E¨;¸×>Ò>Ø�d˜K¨Ð/Ð/õ:ð 	ˆd�K  x°·±¸{ÈEÏOÉOØ�U—_‘_Øœ' %Ð)9¸4Ó@×bÐbÁMÐRW×RaÑRaÓDbØ(©$¨u×/OÑ/OÓ*PØ!¡4¨×(AÑ(AÓ#BØ!¡4¨×(AÑ(AÓ#BØ�U—_‘_ jÔ2FÀuÇ~Á~Ó2VØÔ)¨%¯/©/Ó:ð<ð <r
   c               ó   € V ^8„  d   QhRR/# r   r   )r   s   "r   r   r   ³   s   € ÷ "2ñ "2¨Dñ "2r
   c                ó´  € ^ RI Hp ^ RIHp RpV P                  e±   V P                  pRVP
                  RVP                  R\        VP                  4      R\        VP                  4      RVP                  R	VP                  R
VP                  RV! VP                  4      RVP                  RVP                  RV! VP                  4      /pV P                   Uu. uFh  pRVP
                  RVP                   RVP"                  RV! VP$                  4      R\        VP                  4      RVP&                  RVP(                  /NKj  	  ppRRRV P*                  RV P,                  RV P.                  RV P0                  RV P2                  RV P4                  RV P6                  RVRVRV P8                  R V P:                  R!\=        V 4      R"\?        V 4      /# u upi )#uB   Serialize a SubscriptionState for the wire (Decimals â†’ strings).)r¥   rV   NÚtier_idÚ	tier_nameÚmonthly_creditsÚcredits_remainingÚcycle_ends_atÚpending_downgrade_tier_nameÚpending_downgrade_atÚpending_downgrade_displayÚcancel_at_period_endÚcancellation_effective_atÚcancellation_effective_displayÚnameÚ
tier_orderÚdollars_per_month_displayÚ
is_currentÚ
is_enabledr&   Tr_   rd   re   ra   Úorg_idrc   ÚcontextÚcurrentÚtiersr(   r$   rr   rs   ) r•   r¥   rt   rO   rË   r¹   rº   r	   r»   r¼   r½   r¾   r¿   rÁ   rÂ   rÌ   rÄ   rÅ   Údollars_per_monthrÇ   rÈ   r_   rd   re   ra   rÉ   rc   rÊ   r(   r$   rv   rw   )rx   r¥   rO   rË   ÚcÚtrÌ   s   &      r   Ú_serialize_subscription_staterÐ   ³   s¬  € å1Ý/à€GØ‡}�}Ò Ø�M‰Mˆà�q—y‘y +¨q¯{©{Øœy¨×):Ñ):Ó;Ø¤¨1×+>Ñ+>Ó!?ÀÐRS×RaÑRaØ)¨1×+HÑ+HØ" A×$:Ñ$:Ø'©°q×7MÑ7MÓ)NØ" A×$:Ñ$:Ø'¨×)DÑ)DØ,©m¸A×<WÑ<WÓ.Xð	Zˆð  —’óñ
 ˆAð	 
�A—I‘I˜v q§v¡v¨|¸Q¿\¹\Ø	$¡l°1×3FÑ3FÓ&GØ	œI a×&7Ñ&7Ó8¸,ÈÏÉØ	�q—|‘|ó	%ñ ð 
ð ð 	ˆd�K §¡°*¸e¿n¹nØ˜5×0Ñ0°*¸e¿n¹nØ�%—,‘,Ø�—
‘
˜I u§}¡}°iÀÈ'ÐSXØ�e×&Ñ&¨°·±ð 	” Ó&ØÔ)¨%Ó0ð	2ð 	2ùòs   ÃA.Gc               ó   € V ^8„  d   QhRR/# r   r   )r   s   "r   r   r   Ø   s   € ÷ Xñ X¨$ñ Xr
   c                óô   € RRRV P                   RV P                  RV P                  RV P                  RV P                  RV P
                  R	\        V P                  4      R
V P                  RV P                  /
# )uH   Serialize a SubscriptionChangePreview for the wire (Decimal â†’ string).r&   TÚeffectÚreasonÚcurrent_tier_idÚcurrent_tier_nameÚtarget_tier_idÚtarget_tier_nameÚmonthly_credits_deltaÚamount_due_now_centsÚeffective_at)
rÓ   rÔ   rÕ   rÖ   r×   rØ   r	   rÙ   rÚ   rÛ   )r{   s   &r   Ú_serialize_subscription_previewrÜ   Ø   st   € ð 	ˆd�H˜aŸh™h¨°!·(±(Ø˜1×,Ñ,Ð.AÀ1×CVÑCVØ˜!×*Ñ*Ð,>À×@RÑ@RØ¤¨1×+BÑ+BÓ!CØ × 6Ñ 6¸ÈÏÉðXð Xr
   c               ó   € V ^8„  d   QhRR/# )r   r   ÚNoner   )r   s   "r   r   r   â   s   € ÷ 0ñ 0˜ñ 0r
   c                ó2   € \        \        4       V RR7       R# )zJPublish this module's serializers onto ``server``, rebound to its globals.)ÚskipN)Ú_)r   Úglobals)Úservers   &r   Úregisterrä   â   s   € ä”“	˜6¨×/r
   )Ú__doc__Ú
__future__r   rŒ   Útypingr   Ú
method_ctxr   r	   r5   rC   rQ   r|   rw   rv   r¢   r–   rÐ   rÜ   rä   r   r
   r   Ú<module>ré      sa   ðñõ #ã Ý å #ò1õ
4õ*YõOð '2À÷ '2õTõ*$õFõ<õ&"2õJX÷0r
   