
    j                        d Z ddlmZ ddlZddlmZ ddlmZmZ ddl	m
Z
 dZdZh d	Zd
dd&dZ	 d'd
dd(dZd)dZd)dZd)dZd*dZddd+d!Zd,d"Zd-d$Zd*d%ZdS ).z*Shared helpers for tool backend selection.    )annotationsN)Path)AnyDict)is_truthy_valuelocalauto>   r	   directmanagedFforce_freshr   boolreturnc                    	 ddl m} | r |d          }n
 |            }|j        sdS |j        S # t          $ r Y dS w xY w)u  Return True when the user is entitled to the Nous Tool Gateway.

    Entitlement is paid Nous Portal service access OR a live free tool pool
    (``tool_gateway_entitled``). Per-category coverage (the pool funds image but
    not video, etc.) is narrowed by callers via ``tool_gateway_entitled_for``;
    this coarse gate only answers "is any managed tool usable at all".

    Tool Gateway availability fails closed on unknown/error entitlement.  We
    intentionally catch all exceptions and return False — never block startup.
    ``force_fresh=True`` is for interactive configuration flows that should
    reflect a just-purchased subscription, credits, or pool grant immediately.
    r   )get_nous_portal_account_infoTr   F)hermes_cli.nous_accountr   	logged_intool_gateway_entitled	Exception)r   r   account_infos      ?/home/ubuntu/.hermes/hermes-agent/tools/tool_backend_helpers.pymanaged_nous_tools_enabledr      s    HHHHHH 	:77DIIILL7799L% 	511   uus   &1 1 
??the Nous Tool Gateway
capabilitystrc               z    	 ddl m}m}  ||          } |||           }|r|S n# t          $ r Y nw xY w|  dS )zHReturn account-aware guidance for an unavailable Nous Tool Gateway path.r   )&format_nous_portal_entitlement_messager   r   )r   zY is unavailable. Run `hermes model` to refresh your Nous Portal login and billing status.)r   r   r   r   )r   r   r   r   r   messages         r   %nous_tool_gateway_unavailable_messager   ,   s    	
 	
 	
 	
 	
 	
 	
 	

 43LLL88!
 
 
  	N	     	0 	0 	0s   $( 
55valueobject | Nonec                    t          | pt                                                                                    }|pt          S )z)Return a normalized browser provider key.)r   _DEFAULT_BROWSER_PROVIDERstriplower)r    providers     r    normalize_browser_cloud_providerr'   G   s9    55566<<>>DDFFH000    c                    t          | pt                                                                                    }|t          v r|S t          S )z=Return the requested modal mode when valid, else the default.)r   _DEFAULT_MODAL_MODEr$   r%   _VALID_MODAL_MODES)r    modes     r   coerce_modal_moder-   M   sD    u++,,2244::<<D!!!r(   c                     t          |           S )z)Return a normalized modal execution mode.)r-   )r    s    r   normalize_modal_moder/   U   s    U###r(   c                     	 t          j                    dz                                  } n# t          t          f$ r d} Y nw xY wt          t          j        d          rt          j        d          p|           S )z?Return True when direct Modal credentials/config are available.z.modal.tomlFMODAL_TOKEN_IDMODAL_TOKEN_SECRET)r   homeexistsPermissionErrorOSErrorr   osgetenv)modal_file_existss    r   has_direct_modal_credentialsr:   Z   s    "!Y[[=8@@BBW% " " "!"	#	$	$	H3G)H)H 	  s   (+ A A)managed_enabled
modal_mode
has_directmanaged_readyr;   bool | NoneDict[str, Any]c                   t          |           }t          |           }|t                      }|dk    o| }|dk    r	|r|rdnd}n|dk    r|rdnd}n|r|rdn|rdnd}||||||dS )zResolve direct vs managed Modal backend selection.

    Semantics:
    - ``direct`` means direct-only
    - ``managed`` means managed-only
    - ``auto`` prefers managed when available, then falls back to direct
    Nr   r
   )requested_moder,   r=   r>   managed_mode_blockedselected_backend)r-   r/   r   )r<   r=   r>   r;   rB   normalized_moderC   rD   s           r   resolve_modal_backend_staterF   f   s     'z22N*:66O466)#;O(;  )##(7SMS99t	H	$	$'1;88t(7oMo99[eOoxxko ) & 4,  r(   c                 z    t          j        dd          pt          j        dd                                          S )zCPrefer the voice-tools key, but fall back to the normal OpenAI key.VOICE_TOOLS_OPENAI_KEY OPENAI_API_KEY)r7   r8   r$    r(   r   resolve_openai_audio_api_keyrL      s7     		*B// 	+9%r**eggr(   config_sectionc                    	 ddl m}  |            pi                     |           }t          |t                    r$t          |                    d          d          S n# t          $ r Y nw xY wdS )zReturn True when the user opted into the Tool Gateway for this tool.

    Reads ``<section>.use_gateway`` from config.yaml.  Never raises.
    r   )load_configuse_gatewayF)default)hermes_cli.configrO   get
isinstancedictr   r   )rM   rO   sections      r   prefers_gatewayrW      s    
111111;==&B++N;;gt$$ 	N"7;;}#=#=uMMMM	N   5s   AA! !
A.-A.c                     t          j        d          } | %	 ddlm}  |d          } n# t          $ r d} Y nw xY wt          | o|                                           S )a+  Return True when FAL_KEY is set to a non-whitespace value.

    Consults both ``os.environ`` and ``~/.hermes/.env`` (via
    ``hermes_cli.config.get_env_value`` when available) so tool-side
    checks and CLI setup-time checks agree.  A whitespace-only value
    is treated as unset everywhere.
    FAL_KEYNr   )get_env_value)r7   r8   rR   rZ   r   r   r$   )r    rZ   s     r   fal_key_is_configuredr[      s     Ii  E}	777777!M),,EE 	 	 	EEE	'%++--(((s   * 99)r   r   r   r   )r   )r   r   r   r   r   r   )r    r!   r   r   )r   r   )
r<   r!   r=   r   r>   r   r;   r?   r   r@   )r   r   )rM   r   r   r   )__doc__
__future__r   r7   pathlibr   typingr   r   utilsr   r#   r*   r+   r   r   r'   r-   r/   r:   rF   rL   rW   r[   rK   r(   r   <module>ra      s   0 0 " " " " " " 				               ! ! ! ! ! ! $  222  7<      8 .      61 1 1 1   $ $ $ $
	 	 	 	" $($ $ $ $ $ $N      ) ) ) ) ) )r(   