
    `gj                        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y)z*Shared helpers for tool backend selection.    )annotationsN)Path)AnyDict)is_truthy_valuelocalauto>   r	   directmanagedFforce_freshc                    	 ddl m} | r
 |d      }n |       }|j                  sy|j                  S # t        $ r Y y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      M/root/.hermes/venv/lib/python3.12/site-packages/tools/tool_backend_helpers.pymanaged_nous_tools_enabledr      sI    H7DIL79L%%111 s   %4 4 	A A c               l    	 ddl m}m}  ||      } |||       }|r|S 	 |  dS # t        $ r Y w xY w)zHReturn account-aware guidance for an unavailable Nous Tool Gateway path.r   )&format_nous_portal_entitlement_messager   r   )
capabilityzY 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   ,   sa    	

 4L8!
 N 
 , 0 	0  s   ' 	33c                t    t        | xs t              j                         j                         }|xs t        S )z)Return a normalized browser provider key.)str_DEFAULT_BROWSER_PROVIDERstriplower)valueproviders     r    normalize_browser_cloud_providerr#   G   s0    5556<<>DDFH000    c                    t        | xs t              j                         j                         }|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   s8    u++,22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  j                         } t        t        j                  d      xr t        j                  d      xs |       S # t        t        f$ r d} Y Lw xY w)z?Return True when direct Modal credentials/config are available.z.modal.tomlFMODAL_TOKEN_IDMODAL_TOKEN_SECRET)r   homeexistsPermissionErrorOSErrorboolosgetenv)modal_file_existss    r   has_direct_modal_credentialsr7   Z   sp    "!YY[=8@@B 	#	$	H3G)H 	  W% "!"s   %A   A43A4)managed_enabledc                   t        |       }t        |       }|
t               }|dk(  xr | }|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(   
has_directmanaged_readymanaged_mode_blockedselected_backend)r)   r+   r   )
modal_moder;   r<   r8   r:   normalized_moder=   r>   s           r   resolve_modal_backend_staterA   f   s     'z2N*:6O46)#;O(;  )#(7M9t	H	$'18t(7M9[exko ) & 4, r$   c                 z    t        j                  dd      xs t        j                  dd      j                         S )zCPrefer the voice-tools key, but fall back to the normal OpenAI key.VOICE_TOOLS_OPENAI_KEY OPENAI_API_KEY)r4   r5   r    r$   r   resolve_openai_audio_api_keyrG      s3     			*B/ 	+99%r*egr$   c                    	 ddl m}  |       xs i j                  |       }t        |t              rt        |j                  d      d      S 	 y# t        $ r Y yw xY w)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.configrI   get
isinstancedictr   r   )config_sectionrI   sections      r   prefers_gatewayrR      sb    
1=&B++N;gt$"7;;}#=uMM %   s   AA 	AAc                     t        j                  d      } | 	 ddlm}  |d      } t        | xr | j                               S # t        $ r d} Y *w xY w)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)r4   r5   rL   rU   r   r3   r   )r!   rU   s     r   fal_key_is_configuredrV      sW     IIi E}	7!),E '%++-((  	E	s   A AA)r   r3   returnr3   )zthe Nous Tool Gateway)r   r   r   r3   rW   r   )r!   object | NonerW   r   )rW   r3   )
r?   rX   r;   r3   r<   r3   r8   zbool | NonerW   zDict[str, Any])rW   r   )rP   r   rW   r3   )__doc__
__future__r   r4   pathlibr   typingr   r   utilsr   r   r&   r'   r   r   r#   r)   r+   r7   rA   rG   rR   rV   rF   r$   r   <module>r^      s    0 " 	   ! $  2  7< 8 .   		61$
	" $($$ $ 	$
 !$ $N)r$   