Ë
    âß²jN%  ã                  óº  — U d Z ddlmZ ddlZddlZddlmZ ddlmZmZ ddl	m
Z
mZmZmZmZmZmZ  ej"                  e«      Z ed¬«       G d	„ d
«      «       ZdZeD � ��ci c]  \  } }}|  e| ||«      “Œ c}}} Zded<    ee«      ZdZdZddd„Zdd„Zdd„Zd d!d„Zd d"d„Z d#d„Z!d d$d„Z"d%d„Z#d&d„Z$d d'd„Z%	 d 	 	 	 	 	 	 	 d(d„Z&	 d 	 	 	 	 	 	 	 d)d„Z'yc c}}} w )*zÉPlugin capability declarations + consent state.

Every capability id maps 1:1 to a trust gate that already exists on the enforcing surface; ids
without an enforcing gate are deliberately never minted.
é    )ÚannotationsN)Ú	dataclass)ÚdatetimeÚtimezone)ÚAnyÚDictÚIterableÚListÚMappingÚOptionalÚTupleT)Úfrozenc                  ó0   — e Zd ZU dZded<   ded<   ded<   y)ÚCapabilitySpecz9One declarable capability and the legacy gate it maps to.ÚstrÚidzTuple[str, ...]Úlegacy_pathÚdescriptionN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú__annotations__© ó    úC/home/ubuntu/.hermes/hermes-agent/hermes_cli/plugin_capabilities.pyr   r      s   … áCàƒGØ Ó ØÔr   r   ))ztools.override)Úallow_tool_overrideuv   Replace built-in tools (e.g. shell_exec, write_file) â€” an override can intercept everything routed through that tool)zllm.provider_override)ÚllmÚallow_provider_overridez^Run host-owned LLM calls against a provider other than your active one (uses your credentials))zllm.model_override)r   Úallow_model_overridezLChoose which model host-owned LLM calls use (spend follows the chosen model))zllm.agent_id_override)r   Úallow_agent_id_overridez/Attribute its LLM calls to a different agent id)zllm.profile_override)r   Úallow_profile_overridez,Run LLM calls under a different auth profile)zllm.task_override)r   Úallow_task_overridezDRoute its LLM calls through the host's built-in auxiliary task lanes)zgateway.platform_actions)Úallow_platform_actionszkAct on connected chat platforms as the gateway bot (add reactions, rename threads) via ctx.platform_actionszDict[str, CapabilitySpec]ÚCAPABILITY_REGISTRYÚgranted_capabilitiesÚcapabilities_consentc                óº  — | sg S t        | t        t        f«      s,t        j	                  d|t        | «      j                  «       g S g }| D ]�  }t        |t        «      st        j	                  d||«       Œ+|j                  «       }|t        vr5t        j	                  d||dj                  t        t        «      «      «       Œx||vsŒ}|j                  |«       Œ� |S )a  Normalize a manifest ``capabilities:`` value into known capability ids.

    Unknown ids are dropped with a warning: they can never be granted by this build, so hiding
    them from the consent screen is the fail-closed choice (the plugin must degrade gracefully).
    uF   Plugin %s: manifest 'capabilities' must be a list, got %s â€” ignoringz2Plugin %s: ignoring non-string capability entry %ru9   Plugin %s: unknown capability %r (known: %s) â€” ignoringz, )Ú
isinstanceÚlistÚtupleÚloggerÚwarningÚtyper   r   ÚstripÚVALID_CAPABILITY_IDSÚjoinÚsortedÚappend)ÚrawÚplugin_nameÚoutÚitemÚcaps        r   Úparse_declared_capabilitiesr9   :   sÈ   € ñ Øˆ	Ü�cœD¤%˜=Ô)Ü�‰ØTØœ˜c›×+Ñ+ô	-ð ˆ	Ø€CØò 
ˆÜ˜$¤Ô$Ü�N‰NÐOÐQ\Ð^bÔcØØ�j‰j‹lˆØÔ*Ñ*Ü�N‰NØKØ˜S $§)¡)¬FÔ3GÓ,HÓ"IõKð ˜Š^Ø�J‰J�s�Oð
ð €Jr   c                ód   — t         j                  | «      D �cg c]  }|t        v sŒ|‘Œ c}S c c}w )zODeduplicated (order-preserving) subset of *capabilities* with a registry entry.)ÚdictÚfromkeysr0   )ÚcapabilitiesÚcs     r   Ú_knownr?   V   s'   € ä—}‘} \Ó2ÖP�!°aÔ;OÒ6OŠAÒPÐPùÒPs   ˜-¦-c                ó¬   — dj                  t        t        | «      «      «      }t        j                  |j                  d«      «      j                  «       S )z?Deterministic sha256 over a capability set (order-insensitive).ú
zutf-8)r1   r2   ÚsetÚhashlibÚsha256ÚencodeÚ	hexdigest)r=   Úcanons     r   Úcapability_set_hashrH   [   s;   € à�I‰I”fœS Ó.Ó/Ó0€EÜ�>‰>˜%Ÿ,™, wÓ/Ó0×:Ñ:Ó<Ð<r   c                óî   — 	 |}|€ddl m}  |«       xs i }|j                  d«      xs i j                  d«      xs i j                  | «      xs i }t        |t        «      r|S i S # t
        $ r i cY S w xY w)u\   ``plugins.entries.<plugin_id>`` or ``{}`` â€” never raises (unreadable state = not granted).r   )Úload_configÚpluginsÚentries)Úhermes_cli.configrJ   Úgetr)   r;   Ú	Exception)Ú	plugin_idÚconfigÚcfgrJ   Úentrys        r   Ú_plugin_entryrT   c   s|   € ðØˆØˆ;Ý5Ù“-Ò% 2ˆCØ—'‘'˜)Ó$Ò*¨×/Ñ/°	Ó:Ò@¸b×EÑEÀiÓPÒVÐTVˆÜ" 5¬$Ô/ˆuÐ7°RÐ7øÜò ØŠ	ðús   ‚A!A& Á$A& Á&A4Á3A4c                óª   — t        | |«      j                  t        «      }t        |t        «      s
t        «       S t        t        d„ |D «       «      «      S )z9The set of capabilities the user has granted this plugin.c              3  ó^   K  — | ]%  }t        |t        «      sŒ|j                  «       –— Œ' y ­w©N)r)   r   r/   ©Ú.0r>   s     r   ú	<genexpr>z'granted_capabilities.<locals>.<genexpr>u   s   è ø€ ÒI¨!´jÀÄCÕ6H˜AŸG™GŸIÑIùs   ‚-˜-)rT   rN   ÚGRANTED_KEYr)   r*   Ú	frozensetr?   )rP   rQ   r4   s      r   r&   r&   p   sA   € ä
˜	 6Ó
*×
.Ñ
.¬{Ó
;€CÜ�cœ4Ô Ü‹{ÐÜ”VÑI¨sÔIÓIÓJÐJr   c                ó„   — | }|j                   D ]%  }t        |t        «      s y|j                  |«      }Œ' t	        |«      S )z>True when the deprecated ``allow_*`` key for *spec* is truthy.F)r   r)   r   rN   Úbool)rS   ÚspecÚnodeÚparts       r   Ú_legacy_gate_setrb   x   sB   € à€DØ× Ñ ò ˆÜ˜$¤Ô(ÙØ�x‰x˜‹~‰ðô �‹:Ðr   c                óX  — t         j                  |«      }|€t        j                  d|| «       yt	        | |«      }|t        | dd| |iii¬«      v rd\  }}n6t        ||«      r%dd| › d	d	j                  |j                  «      › d
�}}nd\  }}t        j                  d| ||rdnd|«       |S )z»Canonical check: is *capability* live for *plugin_id*? True via ``granted_capabilities`` OR
    the deprecated-but-honored legacy ``allow_*`` key. Unknown ids / unreadable state -> False.u9   capability check for unknown id %r (plugin %s) â€” deniedFrK   rL   )rQ   )Tr&   Tzlegacy key plugins.entries.ú.z (deprecated))Fznot grantedzecapability_check plugin=%s capability=%s decision=%s checked_by=plugin_capability_granted evidence=%sÚallowÚdeny)
r%   rN   r,   ÚdebugrT   r&   rb   r1   r   Úinfo)rP   Ú
capabilityrQ   r_   rS   ÚallowedÚevidences          r   Úplugin_capability_grantedrl   ‚   sÉ   € ô ×"Ñ" :Ó.€DØ€|Ü�‰ÐPÐR\Ð^gÔhØÜ˜) VÓ,€EØÔ)¨)¸YÈÐU^Ð`eÐTfÐHgÐ<hÔiÑiØ8Ñˆ‘Ü	˜% Ô	&Ø Ð$?À	¸{È!ÈCÏHÉHÐUY×UeÑUeÓLfÐKgÐgtÐ"u�‰à0Ñˆ�Ü
‡K�KØoØ�:©'™w°v¸xôIð €Nr   c                óX   — | j                  |i «      }t        |t        «      si }|| |<   |S )zA``parent[key]`` as a dict, replacing any non-dict value in place.)Ú
setdefaultr)   r;   )ÚparentÚkeyÚchilds      r   Ú_child_dictrr   ˜   s1   € à×Ñ˜c 2Ó&€EÜ�eœTÔ"ØˆØˆˆs‰Ø€Lr   c                óÊ  — ddl m}m}  |«       }t        t        t        |d«      d«      | «      }|j	                  t
        «      }t        |t        «      rt        |«      ng t        |«      z   }t        t        d„ |D «       «      «      |t
        <   t        t        |«      «      t        j                  t        j                  «      j                  d¬«      dœ|t         <   |t
           D ]2  }	t"        |	   j$                  �^ }
}|}|
D ]  }t        ||«      }Œ d	||<   Œ4  ||«       t&        j)                  d
| dj+                  |t
           «      xs d|t            d   dd «       y)a  Persist a consent decision: ``granted_capabilities`` (union with prior grants), the consent
    record (hash of the declared set the user saw + UTC timestamp), and the legacy ``allow_*`` key
    for each grant so existing enforcement sites keep working unchanged.r   )rJ   Úsave_configrK   rL   c              3  óB   K  — | ]  }t        |t        «      sŒ|–— Œ y ­wrW   )r)   r   rX   s     r   rZ   z!record_consent.<locals>.<genexpr>ª   s   è ø€ Ò&O¨Q¼JÀqÌ#Õ<N¤qÑ&Oùs   ‚˜Úseconds)Útimespec)ÚhashÚ
granted_atTz8capability_consent plugin=%s granted=%s declared_hash=%sú,z(none)rx   Né   )rM   rJ   rt   rr   rN   r[   r)   r*   r?   r2   rH   r   Únowr   ÚutcÚ	isoformatÚCONSENT_KEYr%   r   r,   rh   r1   )rP   ÚgrantedÚdeclaredrJ   rt   rQ   rS   ÚpreviousÚmergedr8   ÚparentsÚleafr`   ra   s                 r   Úrecord_consentr†   ¡   s=  € ÷ ;Ù‹]€FÜœ¤K°¸	Ó$BÀIÓNÐPYÓZ€EØ�y‰yœÓ%€HÜ *¨8´TÔ :Œd�8ŒnÀÄfÈWÃoÑU€FÜ¤Ñ&O°&Ô&OÓ OÓP€EŒ+Ñä#¤F¨8Ó$4Ó5Ü—l‘l¤8§<¡<Ó0×:Ñ:ÀIÐ:ÓNñ€EŒ+Ñð
 ”[Ñ!ò ˆÜ,¨SÑ1×=Ñ=‰ˆ�$ØˆØò 	+ˆDÜ˜t TÓ*‰Dð	+àˆˆTŠ
ðñ �ÔÜ
‡K�KØBÀIØ�‰�”{Ñ#Ó$Ò0¨°%¼Ñ2DÀVÑ2LÈSÈbÐ2QõSr   c                ó²   — t        | |«      j                  t        «      }t        |t        «      r|j                  d«      nd}t        |t
        «      r|r|S dS )z<Return the stored consent hash, or None when absent/corrupt.rx   N)rT   rN   r   r)   r;   r   )rP   rQ   ÚconsentÚhs       r   Úconsent_hashrŠ   ½   sH   € ä˜I vÓ.×2Ñ2´;Ó?€GÜ)¨'´4Ô8ˆ�‰�FÔ¸d€AÜ˜1œcÔ"¡qˆ1Ð2¨dÐ2r   c                ó`   — t        | |«      }t        |«      D �cg c]	  }||vsŒ|‘Œ c}S c c}w )zŸDeclared-but-ungranted capabilities: everything at first consent, only the additions on an
    update re-consent (they must be re-consented before going live).)r&   r?   )rP   r�   rQ   r€   r>   s        r   Úpending_capabilitiesrŒ   Ä   s0   € ô
 # 9¨fÓ5€GÜ˜hÓ'Ö<�!¨1°GÒ+;ŠAÒ<Ð<ùÒ<s   š	+¤+c                óT   — t        | |«      }|du xs |t        t        |«      «      k7  S )zXTrue when the declared set differs from what the user consented to (or never consented).N)rŠ   rH   r?   )rP   r�   rQ   Ústoreds       r   Údeclared_set_changedr�   Í   s/   € ô ˜) VÓ,€FØ�Tˆ>ÒL˜VÔ':¼6À(Ó;KÓ'LÑLÐLr   )ú?)r4   r   r5   r   Úreturnú	List[str])r=   úIterable[str]r‘   r’   )r=   r“   r‘   r   rW   )rP   r   rQ   úOptional[Mapping[str, Any]]r‘   r;   )rP   r   rQ   r”   r‘   r\   )rS   zMapping[str, Any]r_   r   r‘   r^   )rP   r   ri   r   rQ   r”   r‘   r^   )ro   r;   rp   r   r‘   r;   )rP   r   r€   r“   r�   r“   r‘   ÚNone)rP   r   rQ   r”   r‘   zOptional[str])rP   r   r�   r“   rQ   r”   r‘   r’   )rP   r   r�   r“   rQ   r”   r‘   r^   )(r   Ú
__future__r   rC   ÚloggingÚdataclassesr   r   r   Útypingr   r   r	   r
   r   r   r   Ú	getLoggerr   r,   r   Ú_CAPABILITY_ROWSr%   r   r\   r0   r[   r   r9   r?   rH   rT   r&   rb   rl   rr   r†   rŠ   rŒ   r�   )ÚcidÚpathÚdescs   000r   ú<module>rŸ      sJ  ðòõ #ã Û Ý !ß 'ß F× FÑ Fà	ˆ×	Ñ	˜8Ó	$€ñ �$Ô÷ð ó ððBÐ ð* AQ÷2ð 2Ù-<¨S°$¸€C‰˜˜T 4Ó	(Ñ(ô2Ð Ð.ó ñ !Ð!4Ó5Ð ð %€Ø$€ôó8Qó
=ô
ôKóôó,óSô83ð TXð=Øð=Ø+ð=Ø5Pð=àó=ð TXðMØðMØ+ðMØ5PðMà	ôMùô{2s   Á"C