+
    iHàj³  ã                  ót   € R t ^ RIHt ^ RIt^ RIt^ RIHtHtHt ^ RI	H
t
 R R ltR R lt ! R	 R
]
4      tR# )ay  Web Search Provider ABC.

The single plugin-facing surface every web provider (brave-free, ddgs, searxng,
exa, parallel, tavily, keenable, firecrawl) implements; registered via
``PluginContext.register_web_search_provider()`` and selected by
``web.search_backend`` / ``web.extract_backend`` / ``web.backend``.

Response shapes (legacy contract, the tool wrapper does not translate)::

    search:  {"success": True, "data": {"web": [{"title", "url", "description", "position"}, ...]}}
    extract: {"success": True, "data": [{"url", "title", "content", "raw_content", "metadata"}, ...]}
    failure: {"success": False, "error": str}
)ÚannotationsN)ÚAnyÚDictÚList)ÚProviderBasec               ó    € V ^8„  d   QhRRRR/# )é   ÚnameÚstrÚreturn© )Úformats   "Ú>/home/ubuntu/.hermes/hermes-agent/agent/web_search_provider.pyÚ__annotate__r      s   € ÷ ñ ˜3ð  3ñ ó    c                ó�  €  ^ RI Hp V! V 4      p\        4       w  rVVf%   V'       d   V'       g   ^ RIHp V! V RV : R24      hVf    V'       g   \        P                  ! V R4      pT;'       g    RP                  4       #   \         d:   p ^ RIHp M  \
         d    Rp Mi ; i\        Y44      '       d   h Rp Rp?L°Rp?ii ; i)uW  Config-aware env lookup (``os.environ`` first, then ``~/.hermes/.env``) so
credentials set through the config layer are visible in gateway sessions /
delegate children / subprocess runs. Stripped value, or ``""`` when unset.

Falls back to a bare ``os.getenv`` when the config module is unavailable (stripped installs, early
import contexts). See #40190. Never when a profile secret scope is bound: a scoped miss means the
served profile has no key, and ``os.environ`` holds the LAUNCH profile's â€” a routed profile without
an Exa/Parallel key must be refused, not search on another profile's key.
)Úget_env_value)ÚUnscopedSecretErrorNzget_provider_env(z%) called with no active profile scopeÚ r   )Úhermes_cli.configr   Ú	ExceptionÚagent.secret_scoper   ÚImportErrorÚ
isinstanceÚ_secret_scope_stateÚosÚgetenvÚstrip)r	   r   ÚvalÚexcr   Úscope_boundÚmultiplex_actives   &      r   Úget_provider_envr"      s´   € ðÝ3á˜DÓ!ˆô %8Ó$9Ñ!€KØ
‚{×'·Ý:á! $Ð*;¸D¹8ÐChÐ(iÓjÐjØ
‚{Ÿ;Ü�iŠi˜˜bÓ!ˆØ�IˆI�2×ÑÓÐøô ô ð	%Þ>øÜô 	%Ø"$Òð	%úä�c×/Ò/ØØ�ûðús5   ‚B ÂCÂBÂC ÂB$Â!C Â#B$Â$C Ã Cc               ó   € V ^8„  d   QhRR/# )r   r   ztuple[bool, bool]r   )r   s   "r   r   r   8   s   € ÷ Eñ EÐ.ñ Er   c                 óZ   €  ^ RI Hp Hp T ! 4       RJT! 4       3#   \         d    Ru # i ; i)é    ©Úcurrent_secret_scopeÚis_multiplex_activeN)FF)r   r'   r(   r   r&   s     r   r   r   8   s:   € ðßPñ  Ó!¨Ð-Ñ/BÓ/DÐDÐDøô ô ØÒðús   ‚ š*©*c                  ó„   € ] tR t^@tRt]P                  R R l4       tR R ltR R lt	R R	 lt
RR
 R lltR R ltRtR# )ÚWebSearchProviderzºAbstract base class for a web search/extract backend: implement :meth:`is_available`
and at least one of :meth:`search` / :meth:`extract`; the ``supports_*`` flags route each capability.c               ó   € V ^8„  d   QhRR/# ©r   r   Úboolr   )r   s   "r   r   ÚWebSearchProvider.__annotate__E   s   € ÷ mñ m˜dñ mr   c                ó   € R# )u²   True when this provider can service calls. Cheap check only (env var, importable
dep, instance URL) â€” NO network; runs at tool registration and on every ``hermes tools`` paint.Nr   ©Úselfs   &r   Úis_availableÚWebSearchProvider.is_availableD   s   ‚ r   c               ó   € V ^8„  d   QhRR/# r,   r   )r   s   "r   r   r.   I   s   € ÷ ñ  ñ r   c                ó   € R# )z0True if this provider implements :meth:`search`.Tr   r0   s   &r   Úsupports_searchÚ!WebSearchProvider.supports_searchI   s   € ár   c               ó   € V ^8„  d   QhRR/# r,   r   )r   s   "r   r   r.   M   s   € ÷ ñ  dñ r   c                ó   € R# )aH  True when this provider can serve calls WITHOUT credentials (public anonymous
free tiers such as Exa / Parallel MCP); used only when NO provider is configured or
keyed. Must never make :meth:`is_available` True, or the legacy preference walk would
route keyed users onto a higher-priority backend's free tier. Cheap, no network.Fr   r0   s   &r   Úis_keyless_availableÚ&WebSearchProvider.is_keyless_availableM   s   € ñ
 r   c               ó   € V ^8„  d   QhRR/# r,   r   )r   s   "r   r   r.   T   s   € ÷ ñ  $ñ r   c                ó   € R# )uw   True if this provider implements :meth:`extract` (sync or ``async def`` â€”
the dispatcher awaits coroutine functions).Fr   r0   s   &r   Úsupports_extractÚ"WebSearchProvider.supports_extractT   s   € ñ r   c               ó$   € V ^8„  d   QhRRRRRR/# )r   Úqueryr
   ÚlimitÚintr   zdict[str, Any]r   )r   s   "r   r   r.   Y   s!   € ÷ 
ñ 
˜Cð 
¨ð 
°Nñ 
r   c                ó2   € \        V P                   R24      h)z>Execute a web search. Callers gate on :meth:`supports_search`.z3 does not support search (override supports_search)©ÚNotImplementedErrorr	   )r1   rA   rB   s   &&&r   ÚsearchÚWebSearchProvider.searchY   s   € ä!Ø�y‰yˆkÐLÐMó
ð 	
r   c               ó$   € V ^8„  d   QhRRRRRR/# )r   Úurlsz	list[str]Úkwargsr   r   r   )r   s   "r   r   r.   _   s!   € ÷ 
ñ 
˜Ið 
°ð 
¸ñ 
r   c                ó2   € \        V P                   R24      h)a  Extract content from URLs (callers gate on :meth:`supports_extract`); may be ``async def``.
Returns ``[{"url", "title", "content", "raw_content", "metadata"?, "error"?}, ...]`` (``error``
only on per-URL failure). Ignore unknown ``kwargs`` (``format``, ``include_raw``, ``max_chars``).z5 does not support extract (override supports_extract)rE   )r1   rJ   rK   s   &&,r   ÚextractÚWebSearchProvider.extract_   s    € ô "Ø�y‰yˆkÐNÐOó
ð 	
r   r   N)é   )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__ÚabcÚabstractmethodr2   r6   r:   r>   rG   rM   Ú__static_attributes__r   r   r   r*   r*   @   sB   † ñmð 	×Ñômó ðmõõõ÷

÷
ñ 
r   r*   )rT   Ú
__future__r   rU   r   Útypingr   r   r   Úagent.provider_baser   r"   r   r*   r   r   r   Ú<module>r[      s6   ðñõ #ã 
Û 	ß "Ñ "å ,õõ@Eô%
˜ö %
r   