§
    øžyjïœ  ã                   ó
  — U d Z ddlZddlZddlZddlZddlZddlZddlm	Z	m
Z
mZmZmZmZ ddlmZ ddlmZmZ e	rddlmZ  ej        e¦  «        ZdZdZd	Zd
ZdZdZdZ G d„ de ¦  «        Z!de
de"de#de$fd„Z%dee#         fd„Z&	 	 	 dŠde#de#de#deee#e#f                  deee#e
f                  de"de
fd„Z'ddd d!d"d#d$d%d&d'd(œ
Z(d)e"de#fd*„Z)i a*ee#ee#e
f         f         e+d+<   d,Z, e-¦   «         a.e-e+d-<    ej/        ¦   «         Z0d‹d/„Z1de#de#fd0„Z2de#deee#e
f                  fd1„Z3de#d2ee#e
f         ddfd3„Z4de#dee#e
f         fd4„Z5de#dee#e
f         fd5„Z6d6d7œde#d8e7dee#e
f         fd9„Z8dŒd:„Z9de#d;e
de#fd<„Z:de#d=e#d;e
de#fd>„Z;de#d=e#d;e
de#fd?„Z<de#d@e#d;e
de#fdA„Z=de#d=e#d;e
de#fdB„Z>de#d=e#dCe#d;e
de#f
dD„Z?d�de#d=e#dFe#de"d;e
de#fdG„Z@	 	 dŽde#d@e#de"dIee#         dJee#         d;e
de#fdK„ZAde#d@e#d;e
de#fdL„ZBde#d@e#dMe#d;e
de#f
dN„ZCde#d@e#dMe#d;e
de#f
dO„ZDde#d@e#dMe#d;e
de#f
dP„ZE	 	 d�de#d@e#dRe#dMee#         dSe"d;e
de#fdT„ZFde#d=e#dCe#dUe#d;e
de#fdV„ZGde#d=e#dCe#dUe#d;e
de#fdW„ZHe:e;e<e=e>e?e@eAeBeCeDeEeFeGeHdXœZI eJh dY£¦  «        ZK eJeI L                    ¦   «         ¦  «        eKz
  ZMdZ„ eI N                    ¦   «         D ¦   «         ZOd[„ eI N                    ¦   «         D ¦   «         ZPg d\¢ZQeee#e#e#f                  e+d]<    eJd^d_h¦  «        ZRd=gd=gd=gd=dCgd=dFgd@gd@gd@gd@dMgd@dMgd@dMgd@dRgg d`¢g d`¢daœZSee#ee#         f         e+db<   deee#                  fdc„ZTd2ee#e
f         ddeee#                  dee#         fde„ZU	 	 d�dgee#         d2eee#e
f                  dhe#deee#e
f                  fdi„ZVdjee#e
f         dhe#deee#e
f                  fdk„ZWdeee#e
f                  fdl„ZXdeee#e
f                  fdm„ZYdeee#e
f                  fdn„ZZdodpdqdrdsdtdududvdwdxdyœZ[dze#de#de#fd{„Z\de7fd|„Z]	 	 	 	 	 	 	 	 	 	 	 d‘dze#d~ee#e
f         de#d=e#d@e#dCe#dUe#dMe#dFe#dRe#de"dIe#dJe#dSe"de#fd€„Z^dze#de#fd�„Z_dze#de#fd‚„Z`d}d}d}d}d}d}d}d}dHd}d}dQdƒœZad„„ Zb eV eceO L                    ¦   «         ¦  «        d…d6idf¬†¦  «        Zd eV eceP L                    ¦   «         ¦  «        d…d6id‡¬†¦  «        Ze ejf        dfdfed ebe_¦  «        e]dˆg¬‰¦  «          ejf        d‡d‡ee ebe`¦  «        e]dˆg¬‰¦  «         dS )’u‘  Discord server introspection and management tool.

Provides the agent with the ability to interact with Discord servers
when running on the Discord gateway. Uses Discord REST API directly
with the bot token â€” no dependency on the gateway adapter's client.

Only included in the hermes-discord toolset, so it has zero cost
for users on other platforms.

The schema exposed to the model is filtered by two gates:

1. Privileged intents detected from GET /applications/@me at schema
   build time. Actions that require an intent the bot doesn't have
   (search_members / member_info â†’ GUILD_MEMBERS intent) are hidden.
   fetch_messages is kept regardless of MESSAGE_CONTENT intent, but
   its description is annotated when the intent is missing.

2. User config allowlist at ``discord.server_actions``. If the user
   sets a comma-separated list (or YAML list) of action names, only
   those appear in the schema. Empty/unset means all intent-available
   actions are exposed.

Per-guild permissions (MANAGE_ROLES etc.) are NOT pre-checked â€” Discord
returns a 403 at call time and :func:`_enrich_403` maps it to
actionable guidance the model can relay to the user.
é    N)ÚTYPE_CHECKINGÚAnyÚDictÚListÚOptionalÚTuple)Ú
get_secret)ÚregistryÚ
tool_error)ÚPathzhttps://discord.com/api/v10i  @ i   i @  i €  i   i   c                   ó,   ‡ — e Zd ZdZdedefˆ fd„Zˆ xZS )ÚDiscordAPIErrorz%Raised when a Discord API call fails.ÚstatusÚbodyc                 ór   •— || _         || _        t          ¦   «                              d|› d|› �¦  «         d S )NzDiscord API error z: )r   r   ÚsuperÚ__init__)Úselfr   r   Ú	__class__s      €ú8/home/ragecks/.hermes/hermes-agent/tools/discord_tool.pyr   zDiscordAPIError.__init__=   s@   ø€ ØˆŒØˆŒ	Ý‰Œ×ÒÐ>¨fÐ>Ð>¸Ð>Ð>Ñ?Ô?Ð?Ð?Ð?ó    )Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚintÚstrr   Ú__classcell__)r   s   @r   r   r   ;   s]   ø€ € € € € Ø/Ð/ð@˜sð @¨#ð @ð @ð @ð @ð @ð @ð @ð @ð @ð @r   r   ÚsourceÚlimitÚlabelÚreturnc                óŠ   — |                       |dz   ¦  «        }t          |¦  «        |k    rt          dd|› d|› d�¦  «        ‚|S )Né   iö  zDiscord API z
 exceeded z bytes.)ÚreadÚlenr   )r   r    r!   r   s       r   Ú_read_limited_response_bodyr'   C   sQ   € Ø�;Š;�u˜q‘yÑ!Ô!€DÝ
ˆ4�y„y�5ÒÐÝ˜cÐ#Q°%Ð#QÐ#QÀ5Ð#QÐ#QÐ#QÑRÔRÐRØ€Kr   c                  óN   — t          dd¦  «        pd                     ¦   «         pdS )zDResolve the Discord bot token under the active profile secret scope.ÚDISCORD_BOT_TOKENÚ N)r	   Ústrip© r   r   Ú_get_bot_tokenr-   J   s)   € åÐ*¨BÑ/Ô/Ð5°2×<Ò<Ñ>Ô>ÐFÀ$ÐFr   é   ÚmethodÚpathÚtokenÚparamsr   Útimeoutc           	      óP  — t           › |› �}|r%|dt          j                             |¦  «        z   z  }d}|�'t	          j        |¦  «                             d¦  «        }t          j                             ||| d|› �dddœ¬¦  «        }	 t          j         	                    ||¬	¦  «        5 }	|	j
        d
k    r	 ddd¦  «         dS t          |	t          d¬¦  «        }
t	          j        |
                     d¦  «        ¦  «        cddd¦  «         S # 1 swxY w Y   dS # t          j        j        $ rv}d}	 t          |t"          d¬¦  «        }|                     dd¬¦  «        }n)# t$          $ r}|j        }Y d}~nd}~wt(          $ r Y nw xY wt%          |j        |¦  «        |‚d}~ww xY w)z'Make a request to the Discord REST API.ú?Núutf-8zBot zapplication/jsonz;Hermes-Agent (https://github.com/NousResearch/hermes-agent))ÚAuthorizationzContent-Typez
User-Agent)Údatar/   Úheaders©r3   éÌ   zresponse body)r!   r*   z
error bodyÚreplace)Úerrors)ÚDISCORD_API_BASEÚurllibÚparseÚ	urlencodeÚjsonÚdumpsÚencodeÚrequestÚRequestÚurlopenr   r'   Ú _DISCORD_RESPONSE_BODY_MAX_BYTESÚloadsÚdecodeÚerrorÚ	HTTPErrorÚ_DISCORD_ERROR_BODY_MAX_BYTESr   r   Ú	ExceptionÚcode)r/   r0   r1   r2   r   r3   Úurlr8   ÚreqÚrespÚresponse_bodyÚeÚ
error_bodyÚraw_error_bodyÚ	too_larges                  r   Ú_discord_requestrX   O   sZ  € õ Ð
%˜tÐ
%Ð
%€CØð 4Øˆs•V”\×+Ò+¨FÑ3Ô3Ñ3Ñ3ˆà€DØÐÝŒz˜$ÑÔ×&Ò& wÑ/Ô/ˆå
Œ.×
 Ò
 ØØØà+ E˜^˜^Ø.ØWð
ð 
ð	 !ñ 	ô 	€Cð9ÝŒ^×#Ò# C°Ð#Ñ9Ô9ð 	=¸TØŒ{˜cÒ!Ð!Øð	=ð 	=ð 	=ñ 	=ô 	=ð 	=ð 	=ð 	=õ 8ØÝ0Ø%ðñ ô ˆMõ
 ”:˜m×2Ò2°7Ñ;Ô;Ñ<Ô<ð	=ð 	=ð 	=ð 	=ñ 	=ô 	=ð 	=ð 	=ð 	=ð 	=ð 	=ð 	=øøøð 	=ð 	=ð 	=ð 	=ð 	=ð 	=øõ Œ<Ô!ð 9ð 9ð 9Øˆ
ð
	Ý8ØÝ-Ø"ðñ ô ˆNð
 (×.Ò.¨w¸yÐ.ÑIÔIˆJˆJøÝð 	(ð 	(ð 	(Ø"œˆJˆJˆJˆJˆJˆJøøøøÝð 	ð 	ð 	ØˆDð	øøøå˜aœf jÑ1Ô1°qÐ8øøøøð9øøøs~   Â	!D Â*DÂ7D Ã=DÄD ÄDÄD ÄDÄD ÄF%Ä/F Ä2.E!Å F Å!
FÅ+E7Å2F Å7FÆF ÆFÆF Æ F%ÚtextÚvoiceÚcategoryÚannouncementÚannouncement_threadÚpublic_threadÚprivate_threadÚstageÚforumÚmedia)
r   é   é   é   é
   é   é   é   r.   é   Útype_idc                 ó@   — t                                | d| › d�¦  «        S )Nzunknown(ú))Ú_CHANNEL_TYPE_NAMESÚget)rk   s    r   Ú_channel_type_namerp   —   s$   € Ý×"Ò" 7Ð,A°wÐ,AÐ,AÐ,AÑBÔBÐBr   Ú_capability_cachei€Q Ú_capability_bg_startedr   c                  ó.   — ddl m}   | ¦   «         dz  dz  S )Nr   ©Úget_hermes_homeÚcachezdiscord_capabilities.json)Úhermes_constantsru   rt   s    r   Ú_capability_disk_cache_pathrx   ®   s-   € à0Ð0Ð0Ð0Ð0Ð0àˆ?ÑÔ˜wÑ&Ð)DÑDÐDr   c                 óŽ   — ddl }|                     |                      d¦  «        ¦  «                             ¦   «         dd…         S )z0Stable non-reversible cache key for a bot token.r   Nr6   rj   )ÚhashlibÚsha256rD   Ú	hexdigest)r1   rz   s     r   Ú_token_cache_keyr}   µ   s>   € à€N€N€Nà�>Š>˜%Ÿ,š, wÑ/Ô/Ñ0Ô0×:Ò:Ñ<Ô<¸S¸b¸SÔAÐAr   c                 ó,  — ddl }	 t          ¦   «         }|                     dd¬¦  «        5 }t          j        |¦  «        }ddd¦  «         n# 1 swxY w Y   |                     t          | ¦  «        ¦  «        }t          |t          ¦  «        sdS |                      ¦   «         t          |                     dd¦  «        ¦  «        z
  t          k    rdS |                     d¦  «        }t          |t          ¦  «        rd|v r|S n# t          $ r Y nw xY wdS )	z;Return fresh disk-cached capabilities for *token*, or None.r   NÚrr6   ©ÚencodingÚtsÚcapsÚhas_members_intent)Útimerx   ÚopenrB   Úloadro   r}   Ú
isinstanceÚdictÚfloatÚ_CAPABILITY_DISK_TTL_SECONDSrN   )r1   r…   r0   Úfr8   Úentryrƒ   s          r   Ú_load_caps_from_diskrŽ   ¼   sN  € à€K€K€KðÝ*Ñ,Ô,ˆØ�YŠY�s WˆYÑ-Ô-ð 	 °Ý”9˜Q‘<”<ˆDð	 ð 	 ð 	 ñ 	 ô 	 ð 	 ð 	 ð 	 ð 	 ð 	 ð 	 øøøð 	 ð 	 ð 	 ð 	 à—’Õ)¨%Ñ0Ô0Ñ1Ô1ˆÝ˜%¥Ñ&Ô&ð 	Ø�4Ø�9Š9‰;Œ;�˜uŸyšy¨¨qÑ1Ô1Ñ2Ô2Ñ2Õ5QÒQÐQØ�4Ø�yŠy˜Ñ Ô ˆÝ�d�DÑ!Ô!ð 	Ð&:¸dÐ&BÐ&BØˆKøøÝð ð ð Øˆðøøøàˆ4sA   †%D «AÁ D ÁAÁD ÁAÁ:D ÂAD Ã/D Ä
DÄDrƒ   c                 óÄ  — dd l }	 t          ¦   «         }|j                             dd¬¦  «         	 |                     dd¬¦  «        5 }t          j        |¦  «        }d d d ¦  «         n# 1 swxY w Y   t          |t          ¦  «        si }n# t          $ r i }Y nw xY w||                      ¦   «         dœ|t          | ¦  «        <   |                     d¦  «        }|                     d	d¬¦  «        5 }t          j        ||¦  «         d d d ¦  «         n# 1 swxY w Y   |                     |¦  «         d S # t          $ r  t                               d
d¬¦  «         Y d S w xY w)Nr   T)ÚparentsÚexist_okr   r6   r€   )rƒ   r‚   z	.json.tmpÚwz*discord capability disk-cache write failed©Úexc_info)r…   rx   ÚparentÚmkdirr†   rB   r‡   rˆ   r‰   rN   r}   Úwith_suffixÚdumpr<   ÚloggerÚdebug)r1   rƒ   r…   r0   rŒ   r8   Útmps          r   Ú_save_caps_to_diskrœ   Ñ   sô  € Ø€K€K€KðRÝ*Ñ,Ô,ˆØŒ×Ò $°ÐÑ6Ô6Ð6ð	Ø—’˜3¨�Ñ1Ô1ð $°QÝ”y ‘|”|�ð$ð $ð $ñ $ô $ð $ð $ð $ð $ð $ð $øøøð $ð $ð $ð $å˜d¥DÑ)Ô)ð Ø�øøÝð 	ð 	ð 	ØˆDˆDˆDð	øøøà15¸T¿YºY¹[¼[Ð(IÐ(IˆÕ˜eÑ$Ô$Ñ%Ø×Ò˜{Ñ+Ô+ˆØ�XŠX�c GˆXÑ,Ô,ð 	°ÝŒI�d˜AÑÔÐð	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	øøøð 	ð 	ð 	ð 	à�Š�DÑÔÐÐÐøÝð Rð Rð RÝ�ŠÐAÈDˆÑQÔQÐQÐQÐQÐQðRøøøs}   †*D5 ±B ÁA)ÁB Á)A-Á-B Á0A-Á1B ÂD5 ÂBÂD5 ÂBÂAD5 Ã1DÄD5 ÄDÄD5 ÄDÄD5 Ä5&EÅEc                 ó€  ‡ — t                                ‰ ¦  «        }|�|S t          ‰ ¦  «        }|�|t           ‰ <   |S ddddœ}|t           ‰ <   t          5  ‰ t          vrIt                               ‰ ¦  «         d	ˆ fd„}t          j        |dd¬¦  «                             ¦   «          ddd¦  «         n# 1 swxY w Y   |S )
uX  Non-blocking capability lookup for schema builds.

    Resolution order:
      1. In-process memory cache (populated by a previous sync/bg detection).
      2. Fresh disk cache (populated by a previous process).
      3. Permissive default + fire-and-forget background detection that
         populates both caches for the next schema build / process.

    Rationale: ``_detect_capabilities`` makes a blocking HTTPS call to
    discord.com (measured ~2s, up to 5s on the timeout) and used to run
    inside ``get_tool_definitions`` â†’ ``AIAgent.__init__`` â€” i.e. on the
    critical path of the FIRST TOKEN of every cold process for any user
    with DISCORD_BOT_TOKEN set, on every platform.  The permissive default
    mirrors the existing detection-failure fallback: all actions exposed,
    call-time 403s mapped to guidance by ``_enrich_403``.
    NTF©r„   Úhas_message_contentÚdetectedr"   c                  óÐ   •— 	 t          ‰¦  «        } |                      d¦  «        rt          ‰| ¦  «         d S d S # t          $ r  t                               dd¬¦  «         Y d S w xY w)Nr    z.background discord capability detection failedTr“   )Ú_fetch_capabilitiesro   rœ   rN   r™   rš   )rƒ   r1   s    €r   Ú
_bg_detectz4_detect_capabilities_nonblocking.<locals>._bg_detect  sŠ   ø€ ðbÝ.¨uÑ5Ô5�DØ—x’x 
Ñ+Ô+ð 8Ý*¨5°$Ñ7Ô7Ð7Ð7Ð7ð8ð 8øå ð bð bð bÝ—L’LÐ!QÐ\`�LÑaÔaÐaÐaÐaÐaðbøøøs   ƒ4; »&A%Á$A%zdiscord-caps-detect)ÚtargetÚnameÚdaemon©r"   N)	rq   ro   rŽ   Ú_capability_bg_lockrr   ÚaddÚ	threadingÚThreadÚstart)r1   ÚcachedÚdiskÚcaps_defaultr£   s   `    r   Ú _detect_capabilities_nonblockingr°   ç   s;  ø€ õ" ×"Ò" 5Ñ)Ô)€FØÐØˆå Ñ&Ô&€DØÐØ#'Õ˜%Ñ Øˆð #Ø#Øðð €Lð
  ,Õ�eÑå	ð ð ØÕ.Ð.Ð.Ý"×&Ò& uÑ-Ô-Ð-ðbð bð bð bð bð bõ ÔØ!Ð(=Àdðñ ô çŠe‰gŒgˆgðð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð ð  Ðs   ÁAB3Â3B7Â:B7c                 ó|  — ddddœ}	 t          dd| d¬¦  «        }t          |                     dd	¦  «        pd	¦  «        }t          |t          t
          z  z  ¦  «        |d
<   t          |t          t          z  z  ¦  «        |d<   d|d<   n2# t          $ r%}t           
                    d|¦  «         Y d}~nd}~ww xY w|S )uµ   Fetch capabilities from GET /applications/@me. Pure network fetch â€”
    does NOT read or write the in-process cache (background detection must
    not mutate schemas mid-process).TFrž   ÚGETz/applications/@mere   r:   Úflagsr   r„   rŸ   r    z?Discord capability detection failed (%s); exposing all actions.N)rX   r   ro   ÚboolÚ_FLAG_GATEWAY_GUILD_MEMBERSÚ#_FLAG_GATEWAY_GUILD_MEMBERS_LIMITEDÚ_FLAG_GATEWAY_MESSAGE_CONTENTÚ%_FLAG_GATEWAY_MESSAGE_CONTENT_LIMITEDrN   r™   Úinfo)r1   rƒ   Úappr³   Úexcs        r   r¢   r¢     s  € ð
 #Ø#Øðð €Dð
Ý˜uÐ&9¸5È!ÐLÑLÔLˆÝ�C—G’G˜G QÑ'Ô'Ð,¨1Ñ-Ô-ˆÝ%)ØÕ0Õ3VÑVÑWñ&
ô &
ˆÐ!Ñ"õ '+ØÕ2Õ5ZÑZÑ[ñ'
ô '
ˆÐ"Ñ#ð  ˆˆZÑÐøÝð 
ð 
ð 
Ý�ŠØMÈsñ	
ô 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
øøøøð
øøøð
 €Ks   ˆBB
 Â

B9ÂB4Â4B9F)Úforcer¼   c                óh   — | t           v r|st           |          S t          | ¦  «        }|t           | <   |S )a›  Detect the bot's app-wide capabilities via GET /applications/@me.

    Returns a dict with keys:

    - ``has_members_intent``: GUILD_MEMBERS intent is enabled
    - ``has_message_content``: MESSAGE_CONTENT intent is enabled
    - ``detected``: detection succeeded (False means exposing everything
      and letting runtime errors handle it)

    Cached in a module-global. Pass ``force=True`` to re-fetch.
    )rq   r¢   )r1   r¼   rƒ   s      r   Ú_detect_capabilitiesr¾   ;  s=   € ð Õ!Ð!Ð!¨%Ð!Ý  Ô'Ð'å˜uÑ%Ô%€DØ#Õ�eÑØ€Kr   c                  óf   — i a t          5  t          ¦   «         addd¦  «         dS # 1 swxY w Y   dS )z%Test hook: clear the detection cache.N)rq   r¨   Úsetrr   r,   r   r   Ú_reset_capability_cacherÁ   P  s~   € ð ÐÝ	ð 'ð 'Ý!$¡¤Ðð'ð 'ð 'ñ 'ô 'ð 'ð 'ð 'ð 'ð 'ð 'ð 'øøøð 'ð 'ð 'ð 'ð 'ð 's   Š&¦*­*Ú_kwargsc           
      ó<  — t          dd| ¦  «        }g }|D ]c}|                     |d         |d         |                     d¦  «        |                     dd¦  «        |                     d¦  «        d	œ¦  «         Œdt          j        |t          |¦  «        d
œ¦  «        S )z'List all guilds the bot is a member of.r²   z/users/@me/guildsÚidr¥   ÚiconÚownerFÚpermissions)rÄ   r¥   rÅ   rÆ   rÇ   )ÚguildsÚcount)rX   Úappendro   rB   rC   r&   )r1   rÂ   rÈ   ÚresultÚgs        r   Ú_list_guildsrÍ   \  s¨   € å˜eÐ%8¸%Ñ@Ô@€FØ€FØð ð ˆØ�ŠØ�D”'Ø�f”IØ—E’E˜&‘M”MØ—U’U˜7 EÑ*Ô*ØŸ5š5 Ñ/Ô/ð
ð 
ñ 	ô 	ð 	ð 	õ Œ: µ#°f±+´+Ð>Ð>Ñ?Ô?Ð?r   Úguild_idc                 óâ  — t          dd|› �| ddi¬¦  «        }t          j        |d         |d         |                     d¦  «        |                     d	¦  «        |                     d
¦  «        |                     d¦  «        |                     d¦  «        |                     dg ¦  «        |                     d¦  «        |                     d¦  «        |                     d¦  «        dœ¦  «        S )z'Get detailed information about a guild.r²   ú/guilds/Úwith_countsÚtrue©r2   rÄ   r¥   ÚdescriptionrÅ   Úowner_idÚapproximate_member_countÚapproximate_presence_countÚfeaturesÚpremium_tierÚpremium_subscription_countÚverification_level)rÄ   r¥   rÔ   rÅ   rÕ   Úmember_countÚonline_countrØ   rÙ   rÚ   rÛ   ©rX   rB   rC   ro   )r1   rÎ   rÂ   rÌ   s       r   Ú_server_inforß   k  sÞ   € å˜Ð 5¨8Ð 5Ð 5°uÀmÐU[ÐE\Ð]Ñ]Ô]€AÝŒ:Ø�ŒgØ�&”	Ø—u’u˜]Ñ+Ô+Ø—’�f‘”Ø—E’E˜*Ñ%Ô%ØŸšÐ8Ñ9Ô9ØŸšÐ:Ñ;Ô;Ø—E’E˜* bÑ)Ô)ØŸš˜nÑ-Ô-Ø&'§e¢eÐ,HÑ&IÔ&IØŸešeÐ$8Ñ9Ô9ðð ñ ô ð r   c           
      ó  — t          dd|› d�| ¦  «        }i }g }|D ]>}|d         dk    r0|d         |d         |                     dd	¦  «        g d
œ||d         <   Œ?|D ]Ò}|d         dk    rŒ|d         |                     dd¦  «        t          |d         ¦  «        |                     dd	¦  «        |                     d¦  «        |                     dd¦  «        dœ}|                     d¦  «        }|r&||v r"||         d                              |¦  «         Œ½|                     |¦  «         ŒÓt	          |                     ¦   «         d„ ¬¦  «        }	|	D ]}
|
d                              d„ ¬¦  «         Œ |                     d„ ¬¦  «         g }|r|                     d|dœ¦  «         |	D ]/}
|                     |
d         |
d         dœ|
d         dœ¦  «         Œ0t          d„ |D ¦   «         ¦  «        }t          j	        ||dœ¦  «        S )z4List all channels in a guild, organized by category.r²   rÐ   z	/channelsÚtyperd   rÄ   r¥   Úpositionr   )rÄ   r¥   râ   Úchannelsr*   ÚtopicÚnsfwF)rÄ   r¥   rá   râ   rä   rå   Ú	parent_idrã   c                 ó   — | d         S ©Nrâ   r,   ©Úcs    r   ú<lambda>z _list_channels.<locals>.<lambda>¢  s
   € ¸A¸j¼M€ r   )Úkeyc                 ó   — | d         S rè   r,   ré   s    r   rë   z _list_channels.<locals>.<lambda>¤  s
   € ¨1¨Z¬=€ r   c                 ó   — | d         S rè   r,   ré   s    r   rë   z _list_channels.<locals>.<lambda>¥  s
   €  Q z¤]€ r   N)r[   rã   )rÄ   r¥   c              3   ó@   K  — | ]}t          |d          ¦  «        V — ŒdS )rã   N)r&   )Ú.0Úgroups     r   ú	<genexpr>z!_list_channels.<locals>.<genexpr>°  s/   è è € Ð;Ð;¨5•�E˜*Ô%Ñ&Ô&Ð;Ð;Ð;Ð;Ð;Ð;r   )Úchannel_groupsÚtotal_channels)
rX   ro   rp   rÊ   ÚsortedÚvaluesÚsortÚsumrB   rC   )r1   rÎ   rÂ   rã   Ú
categoriesÚuncategorizedÚchr�   r•   Úsorted_catsÚcatrË   Útotals                r   Ú_list_channelsrÿ   }  s}  € å Ð'E°(Ð'EÐ'EÐ'EÀuÑMÔM€Hð 79€JØ*,€Mð ð ð ˆØˆfŒ:˜Š?ˆ?à˜”hØ˜6œ
ØŸFšF :¨qÑ1Ô1Øð	$ð $ˆJ�r˜$”xÑ øð ð (ð (ˆØˆfŒ:˜Š?ˆ?Øà�T”(Ø—F’F˜6 2Ñ&Ô&Ý& r¨&¤zÑ2Ô2ØŸš˜z¨1Ñ-Ô-Ø—V’V˜G‘_”_Ø—F’F˜6 5Ñ)Ô)ð
ð 
ˆð —’˜Ñ$Ô$ˆØð 	(�f 
Ð*Ð*Ø�vÔ˜zÔ*×1Ò1°%Ñ8Ô8Ð8Ð8à× Ò  Ñ'Ô'Ð'Ð'õ ˜×*Ò*Ñ,Ô,Ð2IÐ2IÐJÑJÔJ€KØð :ð :ˆØˆJŒ×ÒÐ!8Ð!8ÐÑ9Ô9Ð9Ð9Ø×ÒÐ2Ð2ÐÑ3Ô3Ð3à#%€FØð EØ�Š 4°]ÐCÐCÑDÔDÐDØð ð ˆØ�ŠØ" 4œy°#°f´+Ð>Ð>Ø˜Jœð
ð 
ñ 	ô 	ð 	ð 	õ
 Ð;Ð;°FÐ;Ñ;Ô;Ñ;Ô;€EÝŒ:¨À5ÐIÐIÑJÔJÐJr   Ú
channel_idc                 óÎ  — t          dd|› �| ¦  «        }t          j        |d         |                     d¦  «        t	          |d         ¦  «        |                     d¦  «        |                     d¦  «        |                     dd	¦  «        |                     d
¦  «        |                     d¦  «        |                     dd¦  «        |                     d¦  «        dœ
¦  «        S )z+Get detailed info about a specific channel.r²   ú
/channels/rÄ   r¥   rá   rÎ   rä   rå   Frâ   ræ   Úrate_limit_per_userr   Úlast_message_id)
rÄ   r¥   rá   rÎ   rä   rå   râ   ræ   r  r  )rX   rB   rC   ro   rp   )r1   r   rÂ   rû   s       r   Ú_channel_infor  ´  sÊ   € å	˜%Ð!:¨jÐ!:Ð!:¸EÑ	BÔ	B€BÝŒ:Ø�ŒhØ—’�v‘”Ý" 2 f¤:Ñ.Ô.Ø—F’F˜:Ñ&Ô&Ø—’˜‘”Ø—’�v˜uÑ%Ô%Ø—F’F˜:Ñ&Ô&Ø—V’V˜KÑ(Ô(Ø!ŸvšvÐ&;¸QÑ?Ô?ØŸ6š6Ð"3Ñ4Ô4ðð ñ ô ð r   c                 ó  — t          dd|› d�| ¦  «        }g }t          |d„ d¬¦  «        D ]¾}|                     |d         |d         |                     d	¦  «        rd
|                     d	d¦  «        d›�nd|                     dd¦  «        |                     dd¦  «        |                     dd¦  «        |                     d¦  «        |                     dd¦  «        dœ¦  «         Œ¿t	          j        |t          |¦  «        dœ¦  «        S )zList all roles in a guild.r²   rÐ   z/rolesc                 ó.   — |                       dd¦  «        S )Nrâ   r   ©ro   )r   s    r   rë   z_list_roles.<locals>.<lambda>É  s   € ¨¯ª¨z¸1Ñ)=Ô)=€ r   T)rì   ÚreverserÄ   r¥   Úcolorú#r   Ú06xNrâ   ÚmentionableFÚmanagedrÜ   Úhoist)rÄ   r¥   r
  râ   r  r  rÜ   r  )ÚrolesrÉ   )rX   rõ   rÊ   ro   rB   rC   r&   )r1   rÎ   rÂ   r  rË   r   s         r   Ú_list_rolesr  Å  s  € å˜UÐ$?¨xÐ$?Ð$?Ð$?ÀÑGÔG€EØ€FÝ�EÐ=Ð=ÀtÐLÑLÔLð 
ð 
ˆØ�ŠØ�D”'Ø�f”IØ45·E²E¸'±N´NÐLÐ0˜Ÿš˜w¨Ñ*Ô*Ð0Ð0Ð0Ð0ÈØŸš˜j¨!Ñ,Ô,ØŸ5š5 °Ñ6Ô6Ø—u’u˜Y¨Ñ.Ô.ØŸEšE .Ñ1Ô1Ø—U’U˜7 EÑ*Ô*ð	
ð 	
ñ 		ô 		ð 		ð 		õ Œ: µ°V±´Ð=Ð=Ñ>Ô>Ð>r   Úuser_idc                 óò  — t          dd|› d|› �| ¦  «        }|                     di ¦  «        }t          j        |                     d¦  «        |                     d¦  «        |                     d¦  «        |                     d¦  «        |                     d	¦  «        |                     d
d¦  «        |                     dg ¦  «        |                     d¦  «        |                     d¦  «        dœ	¦  «        S )z'Get info about a specific guild member.r²   rÐ   ú	/members/ÚuserrÄ   ÚusernameÚglobal_nameÚnickÚavatarÚbotFr  Ú	joined_atÚpremium_since)	r  r  Údisplay_nameÚnicknamer  r  r  r  r  )rX   ro   rB   rC   )r1   rÎ   r  rÂ   Úmr  s         r   Ú_member_infor   ×  sÜ   € å˜Ð G¨8Ð GÐ G¸gÐ GÐ GÈÑOÔO€AØ�5Š5�˜ÑÔ€DÝŒ:Ø—8’8˜D‘>”>Ø—H’H˜ZÑ(Ô(ØŸš Ñ/Ô/Ø—E’E˜&‘M”MØ—(’(˜8Ñ$Ô$Ø�xŠx˜˜uÑ%Ô%Ø—’�w Ñ#Ô#Ø—U’U˜;Ñ'Ô'ØŸš˜Ñ/Ô/ð
ð 
ñ 
ô 
ð 
r   é   Úqueryc                 óf  — 	 t          |¦  «        }n# t          t          f$ r d}Y nw xY w|t          t	          |d¦  «        ¦  «        dœ}t          dd|› d�| |¬¦  «        }g }|D ]¨}|                     di ¦  «        }	|                     |	                     d	¦  «        |	                     d
¦  «        |	                     d¦  «        |                     d¦  «        |	                     dd¦  «        |                     dg ¦  «        dœ¦  «         Œ©t          j	        |t          |¦  «        dœ¦  «        S )z!Search for guild members by name.r!  éd   )r"  r    r²   rÐ   z/members/searchrÓ   r  rÄ   r  r  r  r  Fr  )r  r  r  r  r  r  )ÚmembersrÉ   ©r   Ú	TypeErrorÚ
ValueErrorr   ÚminrX   ro   rÊ   rB   rC   r&   )
r1   rÎ   r"  r    rÂ   r2   r%  rË   r  r  s
             r   Ú_search_membersr*  è  sC  € ðÝ�E‘
”
ˆˆøÝ•zÐ"ð ð ð Øˆˆˆðøøøà¥s­3¨u°c©?¬?Ñ';Ô';Ð<Ð<€FÝ˜uÐ&J°Ð&JÐ&JÐ&JÈEÐZ`ÐaÑaÔa€GØ€FØð 	ð 	ˆØ�uŠu�V˜RÑ Ô ˆØ�ŠØ—x’x ‘~”~ØŸš Ñ,Ô,Ø ŸHšH ]Ñ3Ô3ØŸš˜f™œØ—8’8˜E 5Ñ)Ô)Ø—U’U˜7 BÑ'Ô'ð
ð 
ñ 	ô 	ð 	ð 	õ Œ: &µ3°v±;´;Ð?Ð?Ñ@Ô@Ð@ó   ‚ ’(§(é2   ÚbeforeÚafterc                 ó’  — 	 t          |¦  «        }n# t          t          f$ r d}Y nw xY wdt          t	          |d¦  «        ¦  «        i}|r||d<   |r||d<   t          dd|› d�| |¬	¦  «        }g }|D �]0}	|	                     d
i ¦  «        }
|                     |	d         |	                     dd¦  «        |
                     d¦  «        |
                     d¦  «        |
                     d¦  «        |
                     dd¦  «        dœ|	                     d¦  «        |	                     d¦  «        d„ |	                     dg ¦  «        D ¦   «         |	                     d¦  «        r d„ |	                     dg ¦  «        D ¦   «         ng |	                     dd¦  «        dœ¦  «         �Œ2t          j	        |t          |¦  «        dœ¦  «        S )z%Fetch recent messages from a channel.r,  r    r$  r-  r.  r²   r  z	/messagesrÓ   ÚauthorrÄ   Úcontentr*   r  r  r  F)rÄ   r  r  r  Ú	timestampÚedited_timestampc                 óŒ   — g | ]A}|                      d ¦  «        |                      d¦  «        |                      d¦  «        dœ‘ŒBS )ÚfilenamerP   Úsize)r5  rP   r6  r  )rð   Úas     r   ú
<listcomp>z#_fetch_messages.<locals>.<listcomp>  sS   € ð ð ð àð ŸUšU :Ñ.Ô.°q·u²u¸U±|´|ÈQÏUÊUÐSYÉ]Ì]Ð[Ð[ðð ð r   ÚattachmentsÚ	reactionsc                 óŽ   — g | ]B}|                      d i ¦  «                              d¦  «        |                      dd¦  «        dœ‘ŒCS )Úemojir¥   rÉ   r   )r<  rÉ   r  )rð   r   s     r   r8  z#_fetch_messages.<locals>.<listcomp>   s[   € ð ð ð àð Ÿ%š% ¨Ñ,Ô,×0Ò0°Ñ8Ô8À1Ç5Â5ÈÐRSÑCTÔCTÐUÐUðð ð r   Úpinned)rÄ   r1  r0  r2  r3  r9  r:  r=  )ÚmessagesrÉ   r&  )r1   r   r    r-  r.  rÂ   r2   r>  rË   Úmsgr0  s              r   Ú_fetch_messagesr@  þ  s  € ðÝ�E‘
”
ˆˆøÝ•zÐ"ð ð ð Øˆˆˆðøøøà%¥s­3¨u°c©?¬?Ñ';Ô';Ð<€FØð "Ø!ˆˆxÑØð  Øˆˆw‰Ý Ð'I°JÐ'IÐ'IÐ'IÈ5ÐY_Ð`Ñ`Ô`€HØ€FØð ñ ˆØ—’˜ 2Ñ&Ô&ˆØ�ŠØ�d”)Ø—w’w˜y¨"Ñ-Ô-à—j’j Ñ&Ô&Ø"ŸJšJ zÑ2Ô2Ø &§
¢
¨=Ñ 9Ô 9Ø—z’z %¨Ñ/Ô/ð	ð ð Ÿš Ñ-Ô-Ø #§¢Ð(:Ñ ;Ô ;ðð àŸš °Ñ3Ô3ðñ ô ð —’˜Ñ%Ô%ð.ð ð àŸš ¨bÑ1Ô1ðñ ô ð ð ,.Ø—g’g˜h¨Ñ.Ô.ð'
ð 
ñ 	ô 	ð 	ñ 	õ* Œ: 6µC¸±K´KÐ@Ð@ÑAÔAÐAr+  c           	      ór  — t          dd|› d�| ¦  «        }g }|D ]z}|                     di ¦  «        }|                     |d         |                     dd¦  «        dd	…         |                     d
¦  «        |                     d¦  «        dœ¦  «         Œ{t          j        |t          |¦  «        dœ¦  «        S )z"List pinned messages in a channel.r²   r  z/pinsr0  rÄ   r1  r*   NéÈ   r  r2  )rÄ   r1  r0  r2  )Úpinned_messagesrÉ   )rX   ro   rÊ   rB   rC   r&   )r1   r   rÂ   r>  rË   r?  r0  s          r   Ú
_list_pinsrD  )  sÊ   € å Ð'E°JÐ'EÐ'EÐ'EÀuÑMÔM€HØ€FØð ð ˆØ—’˜ 2Ñ&Ô&ˆØ�ŠØ�d”)Ø—w’w˜y¨"Ñ-Ô-¨d¨s¨dÔ3Ø—j’j Ñ,Ô,ØŸš Ñ-Ô-ð	
ð 
ñ 	ô 	ð 	ð 	õ Œ:¨&½3¸v¹;¼;ÐGÐGÑHÔHÐHr   Ú
message_idc                 óf   — t          dd|› d|› �| ¦  «         t          j        dd|› d�dœ¦  «        S )zPin a message in a channel.ÚPUTr  ú/pins/TúMessage z pinned.©ÚsuccessÚmessage©rX   rB   rC   ©r1   r   rE  rÂ   s       r   Ú_pin_messagerO  8  sI   € å�UÐG¨ÐGÐG¸:ÐGÐGÈÑOÔOÐOÝŒ: $Ð3R¸jÐ3RÐ3RÐ3RÐSÐSÑTÔTÐTr   c                 óf   — t          dd|› d|› �| ¦  «         t          j        dd|› d�dœ¦  «        S )zUnpin a message from a channel.ÚDELETEr  rH  TrI  z
 unpinned.rJ  rM  rN  s       r   Ú_unpin_messagerR  >  sI   € å�XÐJ¨JÐJÐJ¸jÐJÐJÈEÑRÔRÐRÝŒ: $Ð3T¸jÐ3TÐ3TÐ3TÐUÐUÑVÔVÐVr   c                 óf   — t          dd|› d|› �| ¦  «         t          j        dd|› d�dœ¦  «        S )z*Delete a message from a channel or thread.rQ  r  ú
/messages/TrI  z	 deleted.rJ  rM  rN  s       r   Ú_delete_messagerU  D  sJ   € å�XÐN¨JÐNÐNÀ*ÐNÐNÐPUÑVÔVÐVÝŒ: $Ð3S¸jÐ3SÐ3SÐ3SÐTÐTÑUÔUÐUr   é   r¥   Úauto_archive_durationc                 óÄ   — |rd|› d|› d�}||dœ}nd|› d�}||ddœ}t          d|| |¬¦  «        }t          j        d	|d
         |                     d¦  «        dœ¦  «        S )zCreate a thread in a channel.r  rT  z/threads)r¥   rW  rg   )r¥   rW  rá   ÚPOST)r   TrÄ   r¥   )rK  Ú	thread_idr¥   rÞ   )	r1   r   r¥   rE  rW  rÂ   r0   r   Úthreads	            r   Ú_create_threadr\  J  s®   € ð ð 
àF˜JÐFÐF°*ÐFÐFÐFˆàØ%:ð 
ð  
ˆˆð 1˜JÐ0Ð0Ð0ˆàØ%:Øð
ð 
ˆõ
 ˜f d¨E¸Ð=Ñ=Ô=€FÝŒ:ØØ˜D”\Ø—
’
˜6Ñ"Ô"ðð ñ ô ð r   Úrole_idc           	      ór   — t          dd|› d|› d|› �| ¦  «         t          j        dd|› d|› d�d	œ¦  «        S )
zAdd a role to a guild member.rG  rÐ   r  ú/roles/TúRole z added to user ú.rJ  rM  ©r1   rÎ   r  r]  rÂ   s        r   Ú	_add_rolerc  h  s[   € å�UÐS xÐSÐS¸'ÐSÐSÈ'ÐSÐSÐUZÑ[Ô[Ð[ÝŒ: $Ð3]¸7Ð3]Ð3]ÐSZÐ3]Ð3]Ð3]Ð^Ð^Ñ_Ô_Ð_r   c           	      ór   — t          dd|› d|› d|› �| ¦  «         t          j        dd|› d|› d�d	œ¦  «        S )
z"Remove a role from a guild member.rQ  rÐ   r  r_  Tr`  z removed from user ra  rJ  rM  rb  s        r   Ú_remove_rolere  n  s[   € å�XÐV¨(ÐVÐV¸WÐVÐVÈWÐVÐVÐX]Ñ^Ô^Ð^ÝŒ: $Ð3a¸7Ð3aÐ3aÐW^Ð3aÐ3aÐ3aÐbÐbÑcÔcÐcr   )Úlist_guildsÚserver_infoÚlist_channelsÚchannel_infoÚ
list_rolesÚmember_infoÚsearch_membersÚfetch_messagesÚ	list_pinsÚpin_messageÚunpin_messageÚdelete_messageÚcreate_threadÚadd_roleÚremove_role>   rr  rm  rl  c                 ó,   — i | ]\  }}|t           v ¯||“ŒS r,   )Ú_CORE_ACTION_NAMES©rð   ÚkÚvs      r   ú
<dictcomp>rz  �  s)   € ÐNÐNÐN™$˜!˜Q°aÕ;MÐ6MÐ6M��AÐ6MÐ6MÐ6Mr   c                 ó,   — i | ]\  }}|t           v ¯||“ŒS r,   )Ú_ADMIN_ACTION_NAMESrw  s      r   rz  rz  Ž  s)   € ÐPÐPÐP™4˜1˜a°qÕ<OÐ7OÐ7O�!�QÐ7OÐ7OÐ7Or   ))rf  z()zlist servers the bot is in)rg  ú
(guild_id)zserver details + member counts)rh  r}  z all channels grouped by category)ri  ú(channel_id)zsingle channel details)rj  r}  zroles sorted by position)rk  z(guild_id, user_id)zlookup a specific member)rl  z(guild_id, query)zfind members by name prefix)rm  r~  z1recent messages; optional before/after snowflakes)rn  r~  zpinned messages in a channel)ro  ú(channel_id, message_id)zpin a message)rp  r  zunpin a message)rq  r  zdelete a message)rr  z(channel_id, name)z2create a public thread; optional message_id anchor)rs  ú(guild_id, user_id, role_id)zassign a role)rt  r€  zremove a roleÚ_ACTION_MANIFESTrk  rl  )rÎ   r  r]  )rg  rh  rj  rk  rl  ri  rm  rn  ro  rp  rq  rr  rs  rt  Ú_REQUIRED_PARAMSc                  óø  — 	 ddl m}   | ¦   «         }n3# t          $ r&}t                               d|¦  «         Y d}~dS d}~ww xY w|                     d¦  «        pi                      d¦  «        }|�|dk    rdS t          |t          ¦  «        r d„ |                     d	¦  «        D ¦   «         }nXt          |t          t          f¦  «        rd
„ |D ¦   «         }n/t                               dt          |¦  «        j        ¦  «         dS d„ |D ¦   «         }d„ |D ¦   «         }|rYt                               dd                     |¦  «        d                     t                               ¦   «         ¦  «        ¦  «         |S )a/  Read ``discord.server_actions`` from user config.

    Returns a list of allowed action names, or ``None`` if the user
    hasn't restricted the set (default: all actions allowed).

    Accepts either a comma-separated string or a YAML list.
    Unknown action names are dropped with a log warning.
    r   )Úload_configz:discord: could not load config (%s); allowing all actions.NÚdiscordÚserver_actionsr*   c                 ó^   — g | ]*}|                      ¦   «         ¯|                      ¦   «         ‘Œ+S r,   )r+   ©rð   Úns     r   r8  z0_load_allowed_actions_config.<locals>.<listcomp>Ô  s-   € Ð@Ð@Ð@˜q°a·g²g±i´iÐ@�—’‘”Ð@Ð@Ð@r   Ú,c                 ó’   — g | ]D}t          |¦  «                             ¦   «         ¯#t          |¦  «                             ¦   «         ‘ŒES r,   )r   r+   rˆ  s     r   r8  z0_load_allowed_actions_config.<locals>.<listcomp>Ö  s9   € Ð?Ð?Ð? Aµ°A±´·²±´Ð?•�Q‘”—’‘”Ð?Ð?Ð?r   z5discord.server_actions: unexpected type %s; ignoring.c                 ó$   — g | ]}|t           v ¯|‘ŒS r,   ©Ú_ACTIONSrˆ  s     r   r8  z0_load_allowed_actions_config.<locals>.<listcomp>Ý  s   € Ð/Ð/Ð/�1 ¥h  ˆQ   r   c                 ó$   — g | ]}|t           v¯|‘ŒS r,   r�  rˆ  s     r   r8  z0_load_allowed_actions_config.<locals>.<listcomp>Þ  s"   € Ð5Ð5Ð5�Q 1­HÐ#4Ð#4ˆqÐ#4Ð#4Ð#4r   z@discord.server_actions: unknown action(s) ignored: %s. Known: %sú, )Úhermes_cli.configr„  rN   r™   rš   ro   rˆ   r   ÚsplitÚlistÚtupleÚwarningrá   r   ÚjoinrŽ  Úkeys)r„  Úcfgr»   ÚrawÚnamesÚvalidÚinvalids          r   Ú_load_allowed_actions_configr�  ¿  s�  € ðØ1Ð1Ð1Ð1Ð1Ð1Øˆk‰mŒmˆˆøÝð ð ð Ý�ŠÐQÐSVÑWÔWÐWØˆtˆtˆtˆtˆtøøøøðøøøð �7Š7�9ÑÔÐ# ×
(Ò
(Ð)9Ñ
:Ô
:€CØ
€{�c˜R’i�iØˆtå�#•sÑÔð Ø@Ð@ C§I¢I¨c¡N¤NÐ@Ñ@Ô@ˆˆÝ	�C�$¥˜Ñ	'Ô	'ð Ø?Ð?¨Ð?Ñ?Ô?ˆˆå�ŠØCÅTÈ#ÁYÄYÔEWñ	
ô 	
ð 	
ð ˆtà/Ð/˜Ð/Ñ/Ô/€EØ5Ð5˜%Ð5Ñ5Ô5€GØð 
Ý�Šðà�IŠI�gÑÔ §	¢	­(¯-ª-©/¬/Ñ :Ô :ñ	
ô 	
ð 	
ð
 €Ls   ‚ “
A�>¾AÚ	allowlistc                 ó–   — g }t           D ]>}|                      dd¦  «        s
|t          v rŒ"|�||vrŒ)|                     |¦  «         Œ?|S )zCompute the visible action list from intents + config allowlist.

    Preserves the canonical order from :data:`_ACTIONS`.
    r„   T)rŽ  ro   Ú_INTENT_GATED_MEMBERSrÊ   )rƒ   rž  Úactionsr¥   s       r   Ú_available_actionsr¢  è  sj   € ð €GÝð ð ˆà�xŠxÐ,¨dÑ3Ô3ð 	¸Õ@UÐ8UÐ8UØàÐ  T°Ð%:Ð%:ØØ�Š�tÑÔÐÐØ€Nr   r…  r¡  Ú	tool_namec                 óð  ‡ — |pi }‰ sdS ˆ fd„t           D ¦   «         }d                     |¦  «        }d}ddht          ‰ ¦  «        z  }|rT|                     d¦  «        r?|                     d¦  «        d	u r(d
                     t	          |¦  «        ¦  «        }d|› d�}|dk    r	d|› d|› �}nd|› d|› �}d‰ dœdddœdddœdddœdddœdddœdddœdddœddddd œdd!dœdd"dœdg d#¢d$d%œd&œ}	||d'|	d(gd)œd*œS )+u±   Build the tool schema for the given filtered action list.

    Returns ``None`` when *actions* is empty â€” callers should drop the
    tool from registration in that case.
    Nc                 ó4   •— g | ]\  }}}|‰v ¯
d |› |› d|› �‘ŒS )z  u     â€” r,   )rð   r¥   ÚsigÚdescr¡  s       €r   r8  z!_build_schema.<locals>.<listcomp>  sE   ø€ ð ð ð áˆD�#�tØ�7ˆ?ˆ?ð 	%ˆTÐ$�3Ð$Ð$˜dÐ$Ð$àˆ?ˆ?r   Ú
r*   rm  rn  r    rŸ   Fz and zA

NOTE: Bot does NOT have the MESSAGE_CONTENT privileged intent. z÷ will return message metadata (author, timestamps, attachments, reactions, pin state) but `content` will be empty for messages not sent as a direct mention to the bot or in DMs. Enable the intent in the Discord Developer Portal to see all content.Údiscord_adminz>Manage a Discord server via the REST API.

Available actions:
zÃ

Call list_guilds first to discover guild_ids, then list_channels for channel_ids. Runtime errors will tell you if the bot lacks a specific per-guild permission (e.g. MANAGE_ROLES for add_role).z>Read and participate in a Discord server.

Available actions:
zr

Use the channel_id from the current conversation context. Use search_members to look up user IDs by name prefix.Ústring)rá   ÚenumzDiscord server (guild) ID.)rá   rÔ   zDiscord channel ID.zDiscord user ID.zDiscord role ID.zDiscord message ID.z2Member name prefix to search for (search_members).z New thread name (create_thread).Úintegerr$   r$  zDMax results (default 50). Applies to fetch_messages, search_members.)rá   ÚminimumÚmaximumrÔ   z5Snowflake ID for reverse pagination (fetch_messages).z5Snowflake ID for forward pagination (fetch_messages).)é<   rV  ià  i`'  zAThread archive duration in minutes (create_thread, default 1440).)rá   r«  rÔ   ©ÚactionrÎ   r   r  r]  rE  r"  r¥   r    r-  r.  rW  Úobjectr±  )rá   Ú
propertiesÚrequired)r¥   rÔ   Ú
parameters)r�  r–  rÀ   ro   rõ   )
r¡  rƒ   r£  Úmanifest_linesÚmanifest_blockÚcontent_noteÚaffected_actionsrš  rÔ   r³  s
   `         r   Ú_build_schemarº     sZ  ø€ ð ˆ:�2€DØð Øˆtðð ð ð å/ðñ ô €Nð
 —Y’Y˜~Ñ.Ô.€Nà€LØ(¨+Ð6½¸W¹¼ÑEÐØð 
˜DŸHšH ZÑ0Ô0ð 
°T·X²XÐ>SÑ5TÔ5TÐX]Ð5]Ð5]Ø—’�VÐ$4Ñ5Ô5Ñ6Ô6ˆðTØðTð Tð Tð 	ð �OÒ#Ð#ðàðð ð ðð ð 	ˆðàðð ð
 ðð ð 	ð Øð
ð 
ð
 Ø7ð
ð 
ð
 Ø0ð
ð 
ð
 Ø-ð
ð 
ð
 Ø-ð
ð 
ð
 Ø0ð
ð 
ð
 ØOð
ð 
ð
 Ø=ð
ð 
ð
 ØØØað	
ð 
ð ØRð
ð 
ð
 ØRð
ð 
ð
 Ø+Ð+Ð+Ø^ð"
ð "
ð_4"ð 4"€Jðn Ø"àØ$Ø!˜
ð
ð 
ðð ð r   Úaction_subsetc                 óÆ   ‡ — t          ¦   «         }|sdS t          |¦  «        }t          ¦   «         }ˆ fd„t          ||¦  «        D ¦   «         }|sdS t	          |||¬¦  «        S )zHBuild a dynamic schema for *action_subset* filtered by intents + config.Nc                 ó   •— g | ]}|‰v ¯|‘Œ	S r,   r,   )rð   r7  r»  s     €r   r8  z'_get_dynamic_schema.<locals>.<listcomp>�  s#   ø€ ÐTÐTÐT�QÀÀmÐASÐASˆqÐASÐASÐASr   )r£  )r-   r°   r�  r¢  rº  )r»  r£  r1   rƒ   rž  r¡  s   `     r   Ú_get_dynamic_schemar¾  w  s{   ø€ õ
 ÑÔ€EØð ØˆtÝ+¨EÑ2Ô2€DÝ,Ñ.Ô.€IØTÐTÐTÐTÕ,¨T°9Ñ=Ô=ÐTÑTÔT€GØð ØˆtÝ˜ $°)Ð<Ñ<Ô<Ð<r   c                  ó,   — t          t          d¦  «        S ©Nr…  )r¾  Ú_CORE_ACTIONSr,   r   r   Úget_dynamic_schema_corerÂ  ‡  s   € Ý�}¨iÑ8Ô8Ð8r   c                  ó,   — t          t          d¦  «        S )Nr©  )r¾  Ú_ADMIN_ACTIONSr,   r   r   Úget_dynamic_schema_adminrÅ  ‹  s   € Ý�~¨Ñ?Ô?Ð?r   c                  ó   — t          ¦   «         S )u0   Backward-compat wrapper â€” returns core schema.)rÂ  r,   r   r   Úget_dynamic_schemarÇ  �  s   € å"Ñ$Ô$Ð$r   z˜Bot lacks MANAGE_MESSAGES permission in this channel. Ask the server admin to grant the bot a role that has MANAGE_MESSAGES, or a per-channel overwrite.z5Bot lacks MANAGE_MESSAGES permission in this channel.zYBot lacks MANAGE_MESSAGES permission in this channel, or cannot view the channel/message.zCBot lacks CREATE_PUBLIC_THREADS in this channel, or cannot view it.z­Either the bot lacks MANAGE_ROLES, or the target role sits higher than the bot's highest role. Roles can only be assigned below the bot's own position in the role hierarchy.z^Either the bot lacks MANAGE_ROLES, or the target role sits higher than the bot's highest role.zLBot cannot view this channel (missing VIEW_CHANNEL or READ_MESSAGE_HISTORY).z4Bot cannot view this channel (missing VIEW_CHANNEL).u|   Likely missing the Server Members privileged intent â€” enable it in the Discord Developer Portal under your bot's settings.z]Bot cannot see this guild member (missing Server Members intent or insufficient permissions).)ro  rp  rq  rr  rs  rt  rm  rn  ri  rl  rk  r±  c                 ól   — t                                | ¦  «        }d| › d�}|r|› d|› d|› d�S |› d|› d�S )z?Return a user-friendly guidance string for a 403 on ``action``.z Discord API 403 (forbidden) on 'z'.Ú z (Raw: rm   )Ú_ACTION_403_HINTro   )r±  r   ÚhintÚbases       r   Ú_enrich_403rÍ  Ä  sc   € å×Ò Ñ'Ô'€DØ8¨fÐ8Ð8Ð8€DØð .ØÐ-Ð-˜Ð-Ð- dÐ-Ð-Ð-Ð-ØÐ"Ð"˜4Ð"Ð"Ð"Ð"r   c                  ó8   — t          t          ¦   «         ¦  «        S )z>Tool is available only when a Discord bot token is configured.)r´   r-   r,   r   r   Úcheck_discord_tool_requirementsrÏ  Ñ  s   € å•Ñ Ô Ñ!Ô!Ð!r   r*   Úvalid_actionsÚ
tool_labelc                 óÀ  ‡— t          ¦   «         }|st          d¦  «        S |                     | ¦  «        }|s3t          d| › �t          |                     ¦   «         ¦  «        ¬¦  «        S t          ¦   «         }|�0| |vr,t          d| › d|rd                     |¦  «        nd› �¦  «        S |||||||	d	œŠˆfd
„t                               | g ¦  «        D ¦   «         }|r(t          d| › dd                     |¦  «        › �¦  «        S 	  |||||||||	|
|||¬¦  «        S # t          $ ru}t           
                    d|| |¦  «         |j        dk    r't          t          | |j        ¦  «        ¦  «        cY d}~S t          t          |¦  «        ¦  «        cY d}~S d}~wt          $ r8}t                               d|| ¦  «         t          d|› �¦  «        cY d}~S d}~ww xY w)z,Shared handler logic for both discord tools.z!DISCORD_BOT_TOKEN not configured.zUnknown action: )Úavailable_actionsNzAction 'z;' is disabled by config (discord.server_actions). Allowed: r�  z<none>)rÎ   r   r  r]  rE  r"  r¥   c                 ó>   •— g | ]}‰                      |¦  «        °|‘ŒS r,   r  )rð   ÚpÚ
local_varss     €r   r8  z'_run_discord_action.<locals>.<listcomp>
  s+   ø€ ÐTÐTÐT�QÀ*Ç.Â.ÐQRÑBSÔBSÐTˆqÐTÐTÐTr   z!Missing required parameters for 'z': )r1   rÎ   r   r  r]  rE  r"  r¥   r    r-  r.  rW  z'Discord API error in %s action '%s': %si“  z"Unexpected error in %s action '%s'zUnexpected error: )r-   r   ro   r“  r—  r�  r–  r‚  r   r™   r•  r   rÍ  r   r   rN   Ú	exception)r±  rÐ  rÑ  rÎ   r   r  r]  rE  r"  r¥   r    r-  r.  rW  r1   Ú	action_fnrž  ÚmissingrT   rÖ  s                      @r   Ú_run_discord_actionrÚ  Ú  s•  ø€ õ" ÑÔ€EØð ?ÝÐ=Ñ>Ô>Ð>à×!Ò! &Ñ)Ô)€IØð 
ÝØ'˜vÐ'Ð'Ý" =×#5Ò#5Ñ#7Ô#7Ñ8Ô8ð
ñ 
ô 
ð 	
õ -Ñ.Ô.€IØÐ ¨yÐ!8Ð!8ÝðJ�vð Jð JØ09ÐG˜Ÿ	š	 )Ñ,Ô,Ð,¸xðJð Jñ
ô 
ð 	
ð Ø ØØØ ØØðð €Jð UÐTÐTÐTÕ*×.Ò.¨v°rÑ:Ô:ÐTÑTÔT€GØð 
ÝØO°ÐOÐO¸4¿9º9ÀWÑ;MÔ;MÐOÐOñ
ô 
ð 	
ð4ØˆyØØØ!ØØØ!ØØØØØØ"7ð
ñ 
ô 
ð 	
øõ ð "ð "ð "Ý�ŠÐ@À*ÈfÐVWÑXÔXÐXØŒ8�sŠ?ˆ?Ý�k¨&°!´&Ñ9Ô9Ñ:Ô:Ð:Ð:Ð:Ð:Ð:Ð:Ý�#˜a™&œ&Ñ!Ô!Ð!Ð!Ð!Ð!Ð!Ð!øøøøÝð 4ð 4ð 4Ý×ÒÐ=¸zÈ6ÑRÔRÐRÝÐ2¨qÐ2Ð2Ñ3Ô3Ð3Ð3Ð3Ð3Ð3Ð3øøøøð4øøøs=   ÄD Ä
GÄ(A	FÅ1GÅ7FÆGÆGÆ%-GÇGÇGc                 ó*   — t          | t          dfi |¤ŽS )zNExecute a core Discord action (fetch_messages, search_members, create_thread).r…  )rÚ  rÁ  ©r±  Úkwargss     r   Údiscord_corerÞ  )  s   € å˜v¥}°iÐJÐJÀ6ÐJÐJÐJr   c                 ó*   — t          | t          dfi |¤ŽS )z3Execute a Discord admin action (server management).r©  )rÚ  rÄ  rÜ  s     r   Údiscord_admin_handlerrà  .  s   € å˜v¥~°ÐQÐQÈ&ÐQÐQÐQr   r°  c                 ó   ‡ — ˆ fd„S )zBCreate a registry-compatible handler lambda for a discord handler.c                 ó\   •‡ —  ‰di ˆ fd„t                                ¦   «         D ¦   «         ¤ŽS )Nc                 óD   •— i | ]\  }}|‰                      ||¦  «        “ŒS r,   r  )rð   rx  ry  Úargss      €r   rz  z3_make_handler.<locals>.<lambda>.<locals>.<dictcomp>A  s+   ø€ Ð
CÐ
CÐ
C¡  Aˆ1ˆd�hŠh�q˜!‰nŒnÐ
CÐ
CÐ
Cr   r,   )Ú_HANDLER_DEFAULTSÚitems)rä  ÚkwÚ
handler_fns   ` €r   rë   z_make_handler.<locals>.<lambda>@  sB   øø€ ˜j˜jð ð Ø
CÐ
CÐ
CÐ
CÕ):×)@Ò)@Ñ)BÔ)BÐ
CÑ
CÔ
Cðð € r   r,   )rè  s   `r   Ú_make_handlerré  >  s   ø€ ðð ð ð ð r   r    )rƒ   r£  r©  r)   )r¥   ÚtoolsetÚschemaÚhandlerÚcheck_fnÚrequires_env)NNr.   )r"   r   r§   )r!  )r,  NN)NrV  rÀ  )r*   r*   r*   r*   r*   r*   r*   r,  r*   r*   rV  )gr   rB   Úloggingrª   Úurllib.errorr?   Úurllib.parseÚurllib.requestÚtypingr   r   r   r   r   r   Úagent.secret_scoper	   Útools.registryr
   r   Úpathlibr   Ú	getLoggerr   r™   r>   rH   rM   rµ   r¶   r·   r¸   rN   r   r   r   Úbytesr'   r-   rX   rn   rp   rq   Ú__annotations__r‹   rÀ   rr   ÚLockr¨   rx   r}   rŽ   rœ   r°   r¢   r´   r¾   rÁ   rÍ   rß   rÿ   r  r  r   r*  r@  rD  rO  rR  rU  r\  rc  re  rŽ  Ú	frozensetrv  r—  r|  ræ  rÁ  rÄ  r�  r   r‚  r�  r¢  rº  r¾  rÂ  rÅ  rÇ  rÊ  rÍ  rÏ  rÚ  rÞ  rà  rå  ré  r“  Ú_STATIC_CORE_SCHEMAÚ_STATIC_ADMIN_SCHEMAÚregisterr,   r   r   ú<module>rÿ     s  ððð ð ð6 €€€Ø €€€Ø Ð Ð Ð Ø Ð Ð Ð Ø Ð Ð Ð Ø Ð Ð Ð Ø BÐ BÐ BÐ BÐ BÐ BÐ BÐ BÐ BÐ BÐ BÐ BÐ BÐ BÐ BÐ Bà )Ð )Ð )Ð )Ð )Ð )Ø /Ð /Ð /Ð /Ð /Ð /Ð /Ð /àð ØÐÐÐÐÐà	ˆÔ	˜8Ñ	$Ô	$€à0Ð Ø#2Ð  Ø )Ð ð &Ð Ø&-Ð #Ø 'Ð Ø(/Ð %ð@ð @ð @ð @ð @�iñ @ô @ð @ð¨ð °Cð À3ð È5ð ð ð ð ðG˜ œð Gð Gð Gð Gð (,Ø%)Øð39ð 39Øð39à
ð39ð ð39ð �T˜#˜s˜(”^Ô$ð	39ð
 �4˜˜S˜”>Ô
"ð39ð ð39ð 	ð39ð 39ð 39ð 39ðv ØØØØØØØØØðð Ð ðC ð C¨ð Cð Cð Cð Cð 02Ð �4˜˜T # s (œ^Ð+Ô,Ð 1Ð 1Ñ 1ð  )Ð ð "˜c™eœeÐ ˜Ð #Ð #Ñ #Ø$�i”nÑ&Ô&Ð ðEð Eð Eð EðB˜Cð B Cð Bð Bð Bð Bð ð ¨°°c¸3°h´Ô(@ð ð ð ð ð*R˜cð R¨¨c°3¨h¬ð R¸Dð Rð Rð Rð Rð,5¨Cð 5°D¸¸c¸´Nð 5ð 5ð 5ð 5ðp˜sð  t¨C°¨H¤~ð ð ð ð ð8 7<ð ð ð  ð ¨tð ÀÀSÈ#ÀXÄð ð ð ð ð*'ð 'ð 'ð 'ð@˜ð @¨ð @°ð @ð @ð @ð @ð˜ð  sð °sð ¸sð ð ð ð ð$4K˜#ð 4K¨ð 4K¸ð 4KÀð 4Kð 4Kð 4Kð 4Kðn˜ð ¨#ð ¸#ð À#ð ð ð ð ð"?�sð ? cð ?°cð ?¸cð ?ð ?ð ?ð ?ð$˜ð  sð °Sð ÀSð ÈSð ð ð ð ð"Að A˜3ð A¨#ð A°cð AÀ#ð AÐWZð AÐ_bð Að Að Að Að. /1Ø9=ð(Bð (BØð(BØð(BØ(+ð(Bà�SŒMð(Bà)1°#¬ð(Bð ð(Bð 	ð	(Bð (Bð (Bð (BðVI�cð I sð I°sð I¸sð Ið Ið Ið IðU˜ð U¨ð U¸#ð UÈ#ð UÐRUð Uð Uð Uð UðW˜#ð W¨3ð W¸Cð WÈCð WÐTWð Wð Wð Wð WðV˜3ð V¨Cð V¸Sð VÈSð VÐUXð Vð Vð Vð Vð !%Ø!%ðð ØðØðØ'*ðà˜”ðð ðð ð	ð
 	ðð ð ð ð<`�Sð ` Cð `°#ð `Àð `ÐPSð `ÐX[ð `ð `ð `ð `ðd˜ð d sð d°Sð dÀ3ð dÐSVð dÐ[^ð dð dð dð dð  ØØ#Ø!ØØØ%Ø%ØØØ#Ø%Ø#ØØðð €ð$ �YÐTÐTÐTÑUÔUÐ Ø�i §¢¡¤Ñ0Ô0Ð3EÑEÐ àNÐN (§.¢.Ñ"2Ô"2ÐNÑNÔN€ØPÐP 8§>¢>Ñ#3Ô#3ÐPÑPÔP€ð
0ð 0ð 0Ð �$�u˜S # s˜]Ô+Ô,ð ð ñ ð& "˜	 =Ð2BÐ"CÑDÔDÐ ð �<Ø �\Ø�,Ø 	Ð*Ø! 7Ð+Ø!�NØ#�nØ�Ø  ,Ð/Ø" LÐ1Ø# \Ð2Ø" FÐ+Ø2Ð2Ð2Ø5Ð5Ð5ð*ð *Ð �$�s˜D œI�~Ô&ð ð ñ ð,& h¨t°C¬yÔ&9ð &ð &ð &ð &ðRØ
ˆs�CˆxŒ.ðà˜˜Sœ	Ô"ðð 
ˆ#„Yðð ð ð ð4 &*Øðtð tØ�#ŒYðtà
�4˜˜S˜”>Ô
"ðtð ðtð ˆd�3˜�8ŒnÔð	tð tð tð tðn=Ø˜˜S˜”>ð=àð=ð ˆd�3˜�8ŒnÔð=ð =ð =ð =ð 9 ¨$¨s°C¨x¬.Ô!9ð 9ð 9ð 9ð 9ð@ (¨4°°S°¬>Ô":ð @ð @ð @ð @ð%˜H T¨#¨s¨(¤^Ô4ð %ð %ð %ð %ð	&ð
 	@ð 	dð 	Nð	4ð
	'ð 	Wð 	Wð 	?ð	>ð	%ðM)ð )Ð ðX#˜ð # 3ð #¨3ð #ð #ð #ð #ð"¨ð "ð "ð "ð "ð ØØØØØØØØØØ!%ðL4ð L4ØðL4à˜˜S˜”>ðL4ð ðL4ð ð	L4ð
 ðL4ð ðL4ð ðL4ð ðL4ð ðL4ð ðL4ð ðL4ð ðL4ð ðL4ð ðL4ð 	ðL4ð L4ð L4ð L4ð^K˜ð K¨3ð Kð Kð Kð Kð
R #ð R°Cð Rð Rð Rð Rð ˜b°¸rØ ¨b¸"Ø˜2¨ÀTðð Ð ðð ð ð $�mØ€Dˆ×	Ò	Ñ	Ô	ÑÔ j°%Ð%8ÀIðñ ô Ð ð %�}Ø€Dˆ×	Ò	Ñ	Ô	ÑÔ z°5Ð&9À_ðñ ô Ð ð €Ô Ø	ØØØˆM˜,Ñ'Ô'Ø,Ø%Ð&ðñ ô ð ð €Ô Ø	ØØØˆMÐ/Ñ0Ô0Ø,Ø%Ð&ðñ ô ð ð ð r   