
    ,jb                    ,   U d Z ddlmZ ddlmZ ddlmZ ddlmZm	Z	m
Z
mZ ddlmZmZ ddlmZmZmZ ddlmZ dd	lmZ dd
lmZmZmZmZmZmZmZ ddiZddddddddZ de!d<   d`dZ" ed           G d d                      Z# ed           G d d                       Z$dad#Z%dbd&Z&dcd'Z'dcd(Z(ddd*Z)ddd+Z*ddd,Z+dcd-Z,ded9Z-	 dfd;d<dgd?Z.d:d;d@dhdDZ/dEdFdGdHdIdJdKZ0didMZ1dNdOdOdPdQdRdKZ2dKZ3	 dfd;d<djdTZ4dkdWZ5dd<dldXZ6dYd:dZdmd^Z7dnd_Z8d:S )oz8Helpers for Nous subscription managed-tool capabilities.    )annotations)	dataclass)Path)DictIterableOptionalSet)get_env_valueload_config)NousPortalAccountInfo&format_nous_portal_entitlement_messageget_nous_portal_account_info)is_managed_tool_gateway_ready)is_truthy_value)fal_key_is_configuredhas_direct_modal_credentialsmanaged_nous_tools_enabled normalize_browser_cloud_providernormalize_modal_moderesolve_modal_backend_stateresolve_openai_audio_api_keycliz
hermes-cli	firecrawlfal	fal-videoopenai-audiobrowser-usemodalweb	image_gen	video_genttssttbrowserr   zDict[str, str]!MANAGED_FEATURE_COVERAGE_CATEGORYsectionobjectreturnboolc                x    t          | t                    sdS t          |                     d          d          S )zCReturn True when a config section explicitly opts into the gateway.Fuse_gateway)default)
isinstancedictr   get)r'   s    A/home/ubuntu/.hermes/hermes-agent/hermes_cli/nous_subscription.py_uses_gatewayr2   2   s8    gt$$ u7;;}55uEEEE    T)frozenc                  |    e Zd ZU ded<   ded<   ded<   ded<   ded<   ded<   ded	<   ded
<   dZded<   dZded<   dS )NousFeatureStatestrkeylabelr*   included_by_default	availableactivemanaged_by_nousdirect_overridetoolset_enabled current_providerFexplicit_configuredN)__name__
__module____qualname____annotations__rA   rB    r3   r1   r6   r6   9   s         HHHJJJOOOLLL %%%%%%%r3   r6   c                      e Zd ZU ded<   ded<   ded<   ded<   dZded	<   edd            Zedd            Zedd            Zedd            Z	edd            Z
edd            Zedd            ZddZdS )NousSubscriptionFeaturesr*   
subscribednous_auth_presentprovider_is_nouszDict[str, NousFeatureState]featuresNzOptional[NousPortalAccountInfo]account_infor)   r6   c                    | j         d         S )Nr    rM   selfs    r1   r    zNousSubscriptionFeatures.webO       }U##r3   c                    | j         d         S )Nr!   rP   rQ   s    r1   r!   z"NousSubscriptionFeatures.image_genS       }[))r3   c                    | j         d         S )Nr#   rP   rQ   s    r1   r#   zNousSubscriptionFeatures.ttsW   rS   r3   c                    | j         d         S )Nr$   rP   rQ   s    r1   r$   zNousSubscriptionFeatures.stt[   rS   r3   c                    | j         d         S )Nr%   rP   rQ   s    r1   r%   z NousSubscriptionFeatures.browser_   s    }Y''r3   c                    | j         d         S )Nr"   rP   rQ   s    r1   r"   z"NousSubscriptionFeatures.video_genc   rU   r3   c                    | j         d         S )Nr   rP   rQ   s    r1   r   zNousSubscriptionFeatures.modalg   s    }W%%r3   Iterable[NousFeatureState]c              #  6   K   d}|D ]}| j         |         V  d S )Nr   rP   )rR   orderedr8   s      r1   itemszNousSubscriptionFeatures.itemsk   s:      U 	% 	%C-$$$$$	% 	%r3   )r)   r6   )r)   r[   )rC   rD   rE   rF   rN   propertyr    r!   r#   r$   r%   r"   r   r^   rG   r3   r1   rI   rI   G   sI        ))))48L8888$ $ $ X$ * * * X* $ $ $ X$ $ $ $ X$ ( ( ( X( * * * X* & & & X&% % % % % %r3   rI   configDict[str, object]c                    |                      d          }t          |t                    rt          |          S t          |t                    r*|                                rd|                                iS i S )Nmodelr-   )r0   r.   r/   r7   strip)r`   	model_cfgs     r1   _model_config_dictrf   q   sn    

7##I)T"" I)S!! .ioo&7&7 .9??,,--Ir3   toolset_keyr7   c                   ddl m} |                     d          }t          |t                    r|sdt
          d         gi}t           ||                    }|sdS |                                D ]\  }}t          |t                    rt          |          }n!t
                              |          }|r|gng }|st
                              |          }|r|g}t                      }	|D ]I}
t          |
t                    r|
s	 |	
                     ||
                     :# t          $ r Y Fw xY w|r|                    |	          r dS dS )Nr   )resolve_toolsetplatform_toolsetsr   FT)toolsetsri   r0   r.   r/   _DEFAULT_PLATFORM_TOOLSETSsetr^   listr7   update	Exceptionissubset)r`   rg   ri   rj   target_toolsplatformraw_toolsetstoolset_namesdefault_toolsetavailable_toolstoolset_names              r1   _toolset_enabledry   z   s   ((((((

#677'.. I6G I"%?%F$GH{3344L u"3"9"9";";  ,lD)) 	I ..MM8<<XFFO1@H_--bM 	28<<XFFO 2!0 1$'EE) 	 	LlC00  &&|'D'DEEEE     	L11/BB 	445s   
D))
D65D6c                     dd l } |                     d          }t          t                    j        j        dz  dz  dz  }t          |p|                                          S )Nr   zagent-browsernode_modulesz.bin)shutilwhichr   __file__parentr*   exists)r|   agent_browser_bin	local_bins      r1   _has_agent_browserr      sb    MMM_55X$~5>P  !7Y%5%5%7%7888r3   c                     t                      sdS 	 ddlm} m} n# t          $ r Y dS w xY w |            rdS  |             S )u  Return True when the *local* browser backend would actually start.

    The ``agent-browser`` CLI being present is necessary but not sufficient for
    local mode: agent-browser also needs a Chromium build on disk (without one
    it hangs on first use until the command timeout fires), unless the
    Lightpanda engine is selected — text-only navigation needs no Chromium.

    This mirrors the local-mode tail of
    :func:`tools.browser_tool.check_browser_requirements`, so the setup/status
    surfaces advertise local browser readiness only when the runtime would
    actually run it. Cloud providers (Browserbase, Browser Use, Firecrawl) host
    their own Chromium and therefore gate on :func:`_has_agent_browser` alone.
    Fr   _chromium_installed_using_lightpanda_engineT)r   tools.browser_toolr   r   rp   r   s     r1   _local_browser_runnabler      s      uTTTTTTTTT    tt  !! t   s    
))rA   c                F    dddddd}|                     | pd| pd          S )NBrowserbasezBrowser Use	FirecrawlCamofoxzLocal browser)browserbaser   r   camofoxlocalr   r0   rA   mappings     r1   _browser_labelr      s?    $$   G ;;'274D4WXXXr3   c                H    ddddddd}|                     | pd| pd          S )	N
OpenAI TTS
ElevenLabszEdge TTSzxAI TTSzMistral Voxtral TTSNeuTTS)openai
elevenlabsedgexaimistralneuttsr   r   r   s     r1   
_tts_labelr      sB    "( G ;;'163C3QzRRRr3   c                D    ddddd}|                     | pd| pd          S )NzOpenAI WhisperzGroq WhisperzMistral Voxtral TranscribezLocal faster-whisper)r   groqr   r   r   r   r   s     r1   
_stt_labelr      s=    "/'	 G ;;'274D4^H^___r3   c                 r    t          d          rdS 	 ddlm}  t          |           S # t          $ r Y dS w xY w)a2  Whether a local STT backend could serve transcription right now.

    True when faster-whisper is importable or a custom local STT command
    is configured. Used both for feature detection and to stop
    ``apply_nous_managed_defaults`` from flipping a working local setup
    to the managed gateway.
    HERMES_LOCAL_STT_COMMANDTr   _HAS_FASTER_WHISPERF)r
   tools.transcription_toolsr   r*   rp   r   s    r1   _local_stt_backend_availabler      sb     /00 tAAAAAA'(((   uus   ( 
66browser_tool_enabledbrowser_providerbrowser_provider_explicitbrowser_local_availablebrowser_local_runnabledirect_camofoxdirect_browserbasedirect_browser_usedirect_firecrawlmanaged_browser_availabletuple[str, bool, bool, bool]c        
           |rddt          |           dfS |r|pd}
|
dk    r(t          |o|          }t          | o|          }|
||dfS |
dk    rB|	p|}t          |o|          }t          | o|o|	o|           }t          | o|          }|
|||fS |
dk    r(t          |o|          }t          | o|          }|
||dfS |
dk    r|
dddfS d}
t          |          }t          | o|          }|
||dfS |	s|r<t          |          }t          | o|o|	o|           }t          | o|          }d|||fS |r&t          |          }t          | o|          }d||dfS t          |          }t          | o|          }d||dfS )u9  Resolve browser availability using the same precedence as runtime.

    ``browser_local_available`` means "the agent-browser CLI is present" — the
    only local requirement for cloud providers, which host their own Chromium.
    ``browser_local_runnable`` additionally requires a usable local Chromium
    build (or the Lightpanda engine), mirroring the local-mode tail of
    :func:`tools.browser_tool.check_browser_requirements`. Local mode must gate
    on the latter, or setup/status advertise a browser that fails on first use
    when Chromium is missing.
    r   TFr   r   r   r   )r*   )r   r   r   r   r   r   r   r   r   r   rA   r;   r<   provider_availablemanageds                  r1   _resolve_browser_feature_stater      sa   .  B$%9 : :EAA  :+6w},,4K9KLLI.<9==F#Y==},,!:!P>P4K9KLLI$ +++-+ +*	 G .<9==F#Y??{**4I9IJJI.<9==F#Y==y((#UE588"/00	*8y99FE99  	9$6 	9011	  ''')' '&	
 
 *8y99i88 7011	*8y99i66+,,I&4955FIvu,,r3   NFforce_freshOptional[Dict[str, object]]r   c                 ^ | t                      pi } t          |           } t          |           }t          |                    d          pd                                                                          dk    }	 |rt          d          ^nt                      ^n# t          $ r d ^Y nw xY wt          ^o^j
        o^j                  }t          ^o^j
                  }dN^fd
}|p|}t          | d          }t          | d          }	t          | d          }
t          | d          }t          | d          }t          | d          }t          |                     d          t                    r|                     d          ni }t          |                     d          t                    r|                     d          ni }t          |                     d          t                    r|                     d          ni }t          |                     d          t                    r|                     d          ni }t          |                     d          t                    r|                     d          ni }t          |                    d          pd                                                                          }t          |                    d          pd                                                                          }t          |                    d          pd                                                                          }t          |                    d          pd                                                                          }t          |                    d          pd                                                                          }d|v }t          |r|                    d          nd           }t          |                    d          pd                                                                          }t          |                    d                    }t!          |          }t!          |          }t!          |          }t!          |          }t          |                     d          t                    r|                     d          ni } t!          |           }!t          |                     d          t                    r|                     d          ni }"t!          |"          }#t          t#          d                    }$t          t#          d          pt#          d                    }%t          t#          d                    }&t          t#          d                    }'t          t#          d                    }(t%                      })|)}*t          t'                                }+t          t#          d                    },t          t#          d                     }-t          t#          d!          ot#          d"                    }.t          t#          d#                    }/t)                      }0t          t'                                }1t          t#          d$                    }2t          t#          d%                    }3	 d&d'lm}4 t          |4          pt          t#          d(                    }5n,# t          $ r t          t#          d(                    }5Y nw xY w|rd)}%d)}$d)}&d)}'|!rd)})|#rd)}*|rd)}+d)},|rd)}1d)}2d)}3d)}5|rd)}/d)}.|o|ot/          d*          o
 |d*          }6|o|ot/          d+          o
 |d,          }7|o|ot/          d+          o
 |d-          }8|o|ot/          d.          o
 |d.          }9|9}:|o|ot/          d/          o
 |d/          };|o|ot/          d0          o
 |d0          }<t1          ||0|<|1          }=|d*k    o|6o|% }>t          |oQ|>pO|d2k    o|$pG|d*k    o|%p?|d3k    o|&p7|d4k    o|'p/|d5k    o|(p'|d5k    o|(p|d2k    o|$p|d*k    o|%p|d3k    o|&p|d4k    o|'          }?t          |6p	|$p|%p|&p|'p|(          }@|	o|7o|) }At          |	o|Ap|)          }Bt          |7p|)          }C|
o|8o|* }Dt          |
o|Dp|*          }Et          |8p|*          }F|pd}G|o
|Gd6k    o|9o|+ }Ht          |Gd7v p3|Gd6k    o|9p|+p)|Gd8k    o|,p!|Gd9k    ot          t#          d%                              }It          |o|I          }J|pd}K|Kd6k    o|:o|1 }Lt          |Kdk    r|5p|Kd6k    o|:p|1p|Kd:k    o|2p|Kd9k    o|3          }M|M}Nt3                      }Ot5                      }Pt7          ||||O|P|-|.|/|%|;;
  
        \  }Q}R}S}T|d0k    rd)}Ud}Vt          |          }Wd)}Xn|=d<         d=k    r#t          |          }Ud}Vt          |          }Wd)}Xn~|=d<         d>k    r#d)}Ud}Vt          |          }Wt          |          }XnO|d=k    rd)}Ut          |<          }Vd)}Wd)}Xn3|d>k    rd)}Ut          |0          }Vd)}Wd)}Xnd)}Ut          |<p|0          }Vd)}Wd)}Xd)}Y|                     d          }Zt          |Zt                    rd|Zv r|d?v}Yd)}[|                     d          }\t          |\t                    rd|\v r|d@v}[t9          ddAd|@|?|>|?o|> ||p|pdt          |p|          B
  
        t9          ddCd|C|B|A|Bo|A |	|)rdDn|ArdEnd|)B
  
        t9          ddFd)|F|E|D|Eo|D |
|*rdDn|DrdEnd|*B
  
        t9          ddGd|I|J|H|Jo|H |t;          |G          |YB
  
        t9          ddHd|M|N|L|No|L dt=          |K          |[B
  
        t9          ddId|R|S|T|So|T |t?          |Q          |B
  
        t9          d0dJd)|V|W|U|d0k    o|X||d0k    rdKn|pd|d0k    B
  
        dL}]tA          ||||]^M          S )ONproviderr@   nousTr   categoryr7   r)   r*   c                L    t          o                    |                     S N)r*   tool_gateway_entitled_for)r   rN   s    r1   _entitled_forz5get_nous_subscription_features.<locals>._entitled_for`  s$    LU\%K%KH%U%UVVVr3   r    r!   r"   r#   r%   terminalr$   backendsearch_backendextract_backendr   r   cloud_provider
modal_modeEXA_API_KEYFIRECRAWL_API_KEYFIRECRAWL_API_URLPARALLEL_API_KEYTAVILY_API_KEYSEARXNG_URLELEVENLABS_API_KEYCAMOFOX_URLBROWSERBASE_API_KEYBROWSERBASE_PROJECT_IDBROWSER_USE_API_KEYGROQ_API_KEYMISTRAL_API_KEYr   r   r   Fr   z	fal-queuer   r   r   r   r   )
has_directmanaged_readymanaged_enabledexaparalleltavilysearxngr   >   r   r   r   r   r   )
r   r   r   r   r   r   r   r   r   r   selected_backendr   direct>   r@   r   >   r@   r   z	Web tools)
r8   r9   r:   r;   r<   r=   r>   r?   rA   rB   zImage generationFALzNous SubscriptionzVideo generationr   zSpeech-to-textzBrowser automationzModal executionModalr   )rJ   rK   rL   rM   rN   )r   r7   r)   r*   )!r   r/   rf   r7   r0   rd   lowerr   rp   r*   	logged_intool_gateway_entitledry   r.   r   r   r2   r
   r   r   r   r   r   r   r   r   r   r   r6   r   r   r   rI   )_r`   r   re   rL   managed_tools_flagrK   r   rJ   web_tool_enabledimage_tool_enabledvideo_tool_enabledtts_tool_enabledr   modal_tool_enabledweb_cfgtts_cfgstt_cfgbrowser_cfgterminal_cfgweb_backendweb_search_backendweb_extract_backendtts_providerstt_providerr   r   terminal_backendr   web_use_gatewaytts_use_gatewaystt_use_gatewaybrowser_use_gatewayimage_gen_cfgimage_use_gatewayvideo_gen_cfgvideo_use_gateway
direct_exar   direct_paralleldirect_tavilydirect_searxng
direct_faldirect_fal_videodirect_openai_ttsdirect_elevenlabsr   r   r   direct_modaldirect_openai_sttdirect_groq_sttdirect_mistral_sttr   local_stt_availablemanaged_web_availablemanaged_image_availablemanaged_video_availablemanaged_tts_availablemanaged_stt_availabler   managed_modal_availablemodal_stateweb_managed
web_activeweb_availableimage_managedimage_activeimage_availablevideo_managedvideo_activevideo_availabletts_current_providertts_managedtts_available
tts_activestt_current_providerstt_managedstt_available
stt_activer   r   browser_current_providerbrowser_availablebrowser_activebrowser_managedmodal_managedmodal_availablemodal_activemodal_direct_overridetts_explicit_configuredraw_tts_cfgstt_explicit_configuredraw_stt_cfgrM   rN   s_                                                                                                 @r1   get_nous_subscription_featuresr.  C  s   
 ~$"&\\F"6**I9==44:;;AACCIIKKvU 	:7DIIILL799L     	/"	/. 
 \Dl.DEEW W W W W W!6%6J'66)&+>>)&+>>'66+FI>>)&*==#-fjj.?.?#F#FNfjjBG#-fjj.?.?#F#FNfjjBG#-fjj.?.?#F#FNfjjBG+5fjj6K6KT+R+RZ&**Y'''XZK-7

:8N8NPT-U-U]6::j)))[]Lgkk),,23399;;AACCK W[[)9::@bAAGGIIOOQQgkk*;<<BCCIIKKQQSSw{{:..8&99??AAGGIIL
 w{{:..9'::@@BBHHJJL 0K ?7-FP()))D  	LY''273399;;AACC  &&& J $G,,O#G,,O#G,,O'44/9&**[:Q:QSW/X/X`FJJ{+++^`M%m44/9&**[:Q:QSW/X/X`FJJ{+++^`M%m44mM2233JM*=>>d-PcBdBdee=);<<==O'78899M-6677N&((J!9;;<<]+?@@AA-6677Nm,ABBn}UmGnGnoom,ABBCC/11L 9;;<<=8899Om,=>>??NAAAAAA"#677 
4455<
 <
  N N N"=1K#L#LMMN   
 
 !  "!! $!"# #"" 	 	'	')+66	' M+&&	  	 	!	!)+66	! M%  	  	 	'	')+66	' M+&&	  	 	*	*).99	* M.))	  2 	)	))-88	) M-((	  	 	#	#)'22	# M'""	  .-*	  K ,_1F_O_K_K 	
 Bu$3B{*?/?B z)=oB x'9M	B
 y(;^B #i/BNB #e+:
B #k1F6FB #j0D_B #h.@= J$ uu/?u?uVcugu M 'U+BU:~M*L0KMML2@jAAO&[+B[K[G[M*R0QAQSSL2F6FGGO'16 	" H,	"!	" "!	   22 	Z H,]2G2\K\	Z L0F5F	Z !I-X$}EV7W7W2X2X	 M &8=99J (27( 	"!	"!! 
 		(	@-@ 	F H,]2G2\K\	F F*>	F !I-D2D	 M J022466 	'1)"; 75%--)";	 	 	  7"".// %	'	(I	5	5/00.// %	'	(H	4	4.// $%7 8 8	y	 	 677 %	x		|,, %6F,GG %#**U##K+t$$ C{)B)B".l"B $**U##K+t$$ D{)B)B".m"C   $#'&:{?,(D,>D" $[%F4F G G
 
 
 &$ $%)(>->.&0dUUm7c7J7Jac *
 
 
 &$ %%)(>->.&6jUUTa=i=P=Pgi 0
 
 
   $#'&:{?,'(<== 7
 
 
  " $#'&:{? !'(<== 7
 
 
 $& $'!+*B?/B0+,DEE 9
 
 
 "# %%),7Q<Q.(8G(C(CWWIYId]d 0G ;
 
 
YX XHt $+)!   s$   ?!B! !B0/B01\8 8&]! ]!)enabled_toolsetsr   r/  Optional[Iterable[str]]set[str]c                  t          | |          }|j        r|j        j        r|j        j        st	                      S |j        st	                      S t	          |pd          }t	                      }|                     d          }t          |t                    si }|| d<   |                     d          }t          |t                    si }|| d<   |                     d          }t          |t                    si }|| d<   |                     d          }	t          |	t                    si }	|	| d<   d|v rb|j	        j
        sVt          d          sGt          d          s8t          d	          s)t          d
          sd|d<   |                    d           d|v rC|j        j
        s7t                      s)t          d          sd|d<   |                    d           |j        j
        sut!                      sgt                      sYt          d          sJt          d          s;|j        4|j                            d          rd|d<   |                    d           d|v rD|j        j
        s8t          d          s)t          d          sd|	d<   |                    d           d|v rYt'                      sK|                     d          }
t          |
t                    si }
|
| d<   d|
d<   |                    d           d|v rxt'                      sj|j                            d          rP|                     d          }t          |t                    si }|| d<   d|d<   d|d<   |                    d           |S )Nr   rG   r    r#   r$   r%   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r!   Tr,   r"   r   r   )r.  rN   r   r   rm   rL   r0   r.   r/   r    rB   r
   addr#   r   r$   r   r   r%   r   )r`   r/  r   rM   selected_toolsetschangedr   r   r   r   	image_cfg	video_cfgs               r1   apply_nous_managed_defaultsr8    s    .f+NNNH!+ !7
 uu$ uu,233GjjGgt$$  ujjGgt$$  ujjGgt$$  u**Y''Kk4(( ('y!!!(,*J!()) ")** " ,-- " ,--	 " )	E!!!(,*J!$&& "-.. " '
E L,,.. )**	
 ^,, .// !-!;;NKK . '
E%%%h.>.R%+,, &.// & )6$%I'''0E0G0G'JJ{++	)T** 	,I"+F;#'	- K   
 	(((%'' 	)!;;KHH 	) JJ{++	)T** 	,I"+F; %	*#'	- K   Nr3   z Web search & extract (Firecrawl)zImage generation (FAL)zVideo generation (FAL)zText-to-speech (OpenAI TTS)zSpeech-to-text (OpenAI Whisper)z Browser automation (Browser Use)r    r!   r"   r#   r$   r%   Dict[str, bool]c            
     
   t                      } t          t          d          p;t          d          p,t          d          pt          d          pt          d                    | | t          t                      pt          d                    t          t                      pt          d          pt          d                    t          t          d	          pt          d
          ot          d                    dS )z4Return a dict of tool_key -> has_direct_credentials.r   r   r   r   r   r   r   r   r   r   r   r9  )r   r*   r
   r   )
fal_directs    r1   _get_gateway_direct_credentialsr=  \  s   &((J-.. ,011,/00, -.., ]++
 
  (** 3122
 
 (** 0^,,0.//
 

 /00 b344`G_9`9`
 
/  r3   z!Firecrawl/Exa/Parallel/Tavily keyzFAL keyzOpenAI/ElevenLabs keyzOpenAI/Groq/Mistral keyzBrowser Use/Browserbase key&tuple[list[str], list[str], list[str]]c          
        	 t          |          }n# t          $ r g g g fcY S w xY w|r|j        r|j        sg g g fS | t	                      pi } |                     d          }t          |t                    rLt          |                    d          pd          	                                
                                dk    rg g g fS t                      }t          |                     d                    t          |                     d                    t          |                     d	                    t          |                     d
                    t          |                     d                    t          |                     d                    d}g }g }g }t          D ]}	|                    t          |	                   s#|                    |	          r|                    |	           N|                    |	          r|                    |	           y|                    |	           |||fS )az  Return (unconfigured, has_direct, already_managed) tool key lists.

    - unconfigured: tools with no direct credentials (easy switch)
    - has_direct: tools where the user has their own API keys
    - already_managed: tools already routed through the gateway

    All lists are empty when the user is not a paid Nous subscriber or
    is not using Nous as their provider.
    r   Nrc   r   r@   r   r    r!   r"   r#   r$   r%   r9  )r   rp   r   r   r   r0   r.   r/   r7   rd   r   r=  r2   _ALL_GATEWAY_KEYSr   r&   append)
r`   r   rN   re   r   opted_inunconfiguredr   already_managedr8   s
             r1   get_gateway_eligible_toolsrE    sP   "3LLL   2rz \3 8Z 2rz~$" 

7##Ii&& #immJ.G.G.M2*N*N*T*T*V*V*\*\*^*^bh*h*h2rz,..F VZZ..//"6::k#:#:;;"6::k#:#:;;VZZ..//VZZ..// I!6!677 H !LJ!#O  % % 55-c2
 
 	 << 	%""3''''ZZ__ 	%c""""$$$$_44s    %%	tool_keys	list[str]c                   t                      }|                     d          }t          |t                    si }|| d<   |                     d          }t          |t                    si }|| d<   |                     d          }t          |t                    si }|| d<   |                     d          }t          |t                    si }|| d<   d|v rd|d<   d|d<   |                    d           d|v rd	|d
<   d|d<   |                    d           d|v rd	|d
<   d|d<   |                    d           d|v rd|d<   d|d<   |                    d           d|v rK|                     d          }t          |t                    si }|| d<   d|d<   |                    d           d|v rP|                     d          }t          |t                    si }|| d<   d|d
<   d|d<   |                    d           |S )zApply Tool Gateway config for the given tool keys.

    Sets ``use_gateway: true`` in each tool's config section so the
    runtime prefers the gateway even when direct API keys are present.

    Returns the set of tools that were actually changed.
    r    r#   r$   r%   r   r   Tr,   r   r   r   r   r!   r"   r   )rm   r0   r.   r/   r3  )	r`   rF  r5  r   r   r   r   r6  r7  s	            r1   apply_gateway_defaultsrI    sX    GjjGgt$$  ujjGgt$$  ujjGgt$$  u**Y''Kk4(( ('y	(	!%E	&
!%E	&
!%EI(5$%%)M"IiJJ{++	)T** 	,I"+F;#'	- K   iJJ{++	)T** 	,I"+F; %	*#'	- K   Nr3   c                  t          | |          \  }}}|s|st                      S 	 ddlm} n# t          $ r t                      cY S w xY w	 t          d          }n# t          $ r d}Y nw xY wt          |o|j        duo|j        duo|j        j	                  }|rdnd}t          |          t          |          z   d	 |D             }	|	d
 |D             z  }	t          t          t          |                              }
|rd}nd}	  |||	|
          }n1# t          t          t          t           f$ r t                      cY S w xY wfd|D             }|st                      S t#          | |          }|rSddlm}  ||            t)          |          D ]2}t*                              ||          }t/          d| d|            3|S )a<  If eligible tools exist, prompt the user (per tool) to enable the Tool
    Gateway.

    "Pool enabled" is the trigger: a user with a live free tool pool (or paid
    access) is shown a per-tool checklist of the covered managed backends and
    picks which to route through the gateway. The free pool funds web/image/
    tts/browser but not video, so the checklist only lists covered tools (the
    coverage filter lives in get_gateway_eligible_tools).

    Returns the set of tools that were enabled, or empty set if the user
    declined or no tools were eligible.
    r   r   )prompt_checklistFNTzfree tool poolzNous subscriptionc                (    g | ]}t           |         S rG   )_GATEWAY_TOOL_LABELS.0ks     r1   
<listcomp>z.prompt_enable_tool_gateway.<locals>.<listcomp>D  s    GGGQ-a0GGGr3   c                H    g | ]}t           |          d t          |           S )u    — keep using your )rM  _GATEWAY_DIRECT_LABELSrN  s     r1   rQ  z.prompt_enable_tool_gateway.<locals>.<listcomp>E  sB         "TT9OPQ9RTT  r3   u6   Your free Nous tool pool — pick the tools to enable:uN   Your Nous subscription includes the Tool Gateway — pick the tools to enable:c                Z    g | ]'}d |cxk    rt                    k     n n|         (S )r   )len)rO  i
offer_keyss     r1   rQ  z.prompt_enable_tool_gateway.<locals>.<listcomp>X  sD    QQQQQ8P8P8P8PZ8P8P8P8P8P:a=8P8P8Pr3   )save_configu     ✓ z: enabled via )rE  rm   hermes_cli.setuprK  rp   r   r*   paid_service_accesstool_accessenabledrn   rangerU  KeyboardInterruptEOFErrorOSError
SystemExitrI  hermes_cli.configrX  sortedrM  r0   print)r`   r   rC  r   rD  rK  rN   	pool_onlysource_labellabelspre_selectedtitle
chosen_idxchosen_keysr5  rX  r8   r9   rW  s                     @r1   prompt_enable_tool_gatewayrl    s   " 1K1 1 1-L*o  
 uu5555555   uu
3FFF    	-,D8	-$D0	- $,	 I (1I##6IL
 !..j1A1AAJGG,GGGF
     F c,//0011L 
H( 	
%%eV\BB

x*=   uu RQQQ*QQQK uu$V[99G @111111F'?? 	@ 	@C(,,S#66E>5>>>>????Ns3   1 AAA! !A0/A0D +EEzthe Nous Tool Gateway
capabilitycoverage_categoryrn  ro  Optional[str]c                   dfd}	 t          d          }n# t          $ r d}Y nw xY w ||          rdS ||j        s6t          |           sdS 	 t          d          }n# t          $ r d}Y nw xY w ||          rdS t	          || 	          }|r)|                                D ]}t          d
|            dS )u;  Make sure the user is entitled to the Nous Tool Gateway, logging in if
    needed.

    Used by ``hermes tools`` when a user selects a Nous-managed Tool Gateway
    backend (e.g. "Firecrawl (Nous Portal)").  Unlike ``hermes model``'s Nous
    login, this:

    - does NOT change the inference provider (``model.provider`` is untouched),
    - does NOT run model selection, and
    - does NOT offer the bulk "enable for all tools" Tool Gateway prompt.

    It only performs the Nous Portal device-code OAuth (when the user isn't
    already logged in) and refreshes entitlement, so the caller can enable the
    single tool the user picked.

    Entitlement is satisfied by paid service access OR a live free tool pool.
    When ``coverage_category`` is given (e.g. ``"fal"`` for image gen), the pool
    must cover that category specifically — so a pool user selecting video
    (``"fal-video"``, not pool-funded) is correctly denied.

    Returns ``True`` when the account is entitled after the flow, ``False``
    otherwise (declined login, login failed, or no entitlement).
    r)   r*   c                H    | dS |                                S | j        S )NF)r   r   )accountro  s    r1   	_entitledz,ensure_nous_portal_access.<locals>._entitled  s1    ?5(445FGGG,,r3   Tr   N)rn  Frm    r)   r*   )r   rp   r   _run_nous_portal_login_onlyr   
splitlinesrd  )rn  ro  rt  infomessagelines    `    r1   ensure_nous_portal_accessr|  l  sG   :- - - - - -+===   y t |4>|*jAAA 	5	/DAAADD 	 	 	DDD	 y t
 57H  G  &&(( 	 	D+t++5s    ))A& &A54A5c                   	 ddl m}m}m}m}m}m}m}m}m	}	 n*# t          $ r}
t          d|
            Y d}
~
dS d}
~
ww xY wt                       t          d|  d           	 t          d                                                                          }n&# t          t           f$ r t                       Y dS w xY w|d	vrt          d
           dS 	  |            5   |                                d          }ddd           n# 1 swxY w Y   d} |            }|r^	 t          d                                                                          }n# t          t           f$ r d}Y nw xY w|d	v r |d          }|
 |            } |            5   |            } ||d|           |r||d<   n|                    dd            ||           ddd           n# 1 swxY w Y    |	|            |             t          d           dS # t           $ r t          d           Y dS t&          $ r Y dS t          $ r}
t          d|
            Y d}
~
dS d}
~
ww xY w)zRun the Nous Portal device-code OAuth and persist credentials only.

    No model selection, no provider switch, no Tool Gateway bulk prompt.
    Returns ``True`` on a successful login, ``False`` if the user declined or
    the flow failed.
    r   )	_auth_store_lock_load_auth_store_nous_device_code_login_read_shared_nous_state_save_auth_store_save_provider_state_sync_nous_pool_from_auth_store_try_import_shared_nous_state_write_shared_nous_statez%  Could not start Nous Portal login: NFru  z requires a Nous Portal login.z$  Log in to Nous Portal now? [Y/n]: >   r@   yyesz  Skipped Nous Portal login.active_providerz=  Found existing Nous OAuth credentials. Import them? [Y/n]: r  g      .@)timeout_secondsr   z  Nous Portal login successful.Tz
  Login cancelled.z  Nous Portal login failed: )hermes_cli.authr~  r  r  r  r  r  r  r  r  rp   rd  inputrd   r   r_  r^  r0   popra  )rn  r~  r  r  r  r  r  r  r  r  excproceedprior_active_provider
auth_stateshared	do_import
auth_stores                    r1   rw  rw    s)   
	
 
	
 
	
 
	
 
	
 
	
 
	
 
	
 
	
 
	
 
	
 
	
 
	
 
	
 
	
 
	
 
	
 
	
 
	
 
	
 
	
 
	
 
	
    ;c;;<<<uuuuu 
GGG	
9z
9
9
9:::>??EEGGMMOO'(   uu &&&,---u-  	N 	N$4$4$6$6$:$:;L$M$M!	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 
((** 	Q !S %''%%'' 	 /0      			 ,,,::4PPP
0022J 		) 		)))++J  VZ@@@ % 80E
,--0$777Z(((		) 		) 		) 		) 		) 		) 		) 		) 		) 		) 		) 		) 		) 		) 		) 	! ,,,'')))/000t   $%%%uu    uu   2S22333uuuuus    
A ;A %3B B<;B<
H D	=H 	DH DH #3E H E-*H ,E--)H AG#H #G''H *G'+'H I"0	I"<	I"II")r'   r(   r)   r*   )r`   ra   r)   ra   )r`   ra   rg   r7   r)   r*   rv  )rA   r7   r)   r7   )r   r*   r   r7   r   r*   r   r*   r   r*   r   r*   r   r*   r   r*   r   r*   r   r*   r)   r   r   )r`   r   r   r*   r)   rI   )r`   ra   r/  r0  r   r*   r)   r1  )r)   r:  )r`   r   r   r*   r)   r>  )r`   ra   rF  rG  r)   r1  )r`   ra   r   r*   r)   r1  )rn  r7   ro  rp  r)   r*   )rn  r7   r)   r*   )9__doc__
__future__r   dataclassesr   pathlibr   typingr   r   r   r	   rb  r
   r   hermes_cli.nous_accountr   r   r   tools.managed_tool_gatewayr   utilsr   tools.tool_backend_helpersr   r   r   r   r   r   r   rl   r&   rF   r2   r6   rI   rf   ry   r   r   r   r   r   r   r   r.  r8  rM  r=  rS  r@  rE  rI  rl  r|  rw  rG   r3   r1   <module>r     sj   > > > " " " " " " ! ! ! ! ! !       0 0 0 0 0 0 0 0 0 0 0 0 8 8 8 8 8 8 8 8         
 E D D D D D ! ! ! ! ! !                  
<   
5 
5 ! 
 
 
 
F F F F $
& 
& 
& 
& 
& 
& 
& 
& $&% &% &% &% &% &% &% &%R   " " " "J9 9 9 9! ! ! !6Y Y Y Y	S 	S 	S 	S` ` ` `   $I- I- I- I-Z +/U U U U U U U| 15	m m m m m mj .))(,1     D /"$,   O  +/@5 @5 @5 @5 @5 @5 @5FF F F FX O O O O O Or .'+A A A A A AHO O O O O Or3   