Ë
    âß²j­Z  ã                  óÈ  — d Z ddlm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 ddlmZ ddlmZmZ ddlmZ ddlmZmZ dd	lmZ dd
lmZ dZd\  ZZZd\  ZZd\  Z Z! e"eee e!h«      Z#d\  Z$Z%dZ&d\  Z'Z(Z)d\  Z*Z+d\  Z,Z-Z.d\  Z/Z0d\  Z1Z2dCd„Z3dDd„Z4dEd„Z5ddddddœ	 	 	 	 	 	 	 	 	 dFd„Z6dGd„Z7dHd„Z8dId„Z9dJd „Z:dKd!„Z;dLd"„Z<dEd#„Z=dEd$„Z>dMd%„Z?dNdOd&„Z@dPd'„ZAdQd(„ZBdRd)„ZCdSd*„ZDdNdd+œdTd,„ZEdNdUd-„ZFdVd.„ZGdWdXd/„ZHdEd0„ZI G d1„ d2«      ZJ G d3„ d4«      ZK G d5„ d6«      ZL eL«       ZM G d7„ d8«      ZNdYd9„ZOdNdZd:„ZPd[d\d;„ZQd]d<„ZRddlSZSd=ZTd>ZUd^d_d?„ZV	 	 d`	 	 	 dad@„ZWdNdbdA„ZXdcdB„ZYy)duY  A2A protocol helpers â€” Agent Card, JSON-RPC framing, task store, conversation persistence.
Wire shape is A2A v1.0: SCREAMING_SNAKE_CASE states/roles; Parts and StreamResponse events are
discriminated by member presence (no ``kind``/``final``); SSE closure signals the terminal state.
Stdlib only. ``extract_text`` stays tolerant of v0.3 peers.é    )ÚannotationsN)ÚOrderedDictÚdefaultdictÚdeque)ÚFuture)ÚdatetimeÚtimezone)ÚPath)ÚAnyÚOptional)Úcoerce_port)Úget_hermes_homez1.0)ÚTASK_STATE_SUBMITTEDÚTASK_STATE_WORKINGÚTASK_STATE_INPUT_REQUIRED)ÚTASK_STATE_COMPLETEDÚTASK_STATE_FAILED)ÚTASK_STATE_CANCELEDÚTASK_STATE_REJECTED)Ú	ROLE_USERÚ
ROLE_AGENTz[INPUT_REQUIRED])iD€ÿÿi¦€ÿÿi§€ÿÿ)iÿ‚ÿÿiþ‚ÿÿ)iÎ‚ÿÿiÍ‚ÿÿiÌ‚ÿÿ)é   é   )é<   g      N@c                óB   — t        t        j                  | |«      |«      S ©N)Ú_coerce_intÚosÚgetenv)ÚnameÚdefaults     úC/home/ubuntu/.hermes/hermes-agent/plugins/platforms/a2a/protocol.pyÚ_env_intr#   -   s   € Ü”r—y‘y  wÓ/°Ó9Ð9ó    c                 óV   — t        dt        «      } t        dt        | t        «      «      S )NÚA2A_MAX_PINGPONG_TURNSé   )r#   Ú_DEFAULT_MAX_PINGPONGÚmaxÚminÚ_HARD_MAX_PINGPONG)Úvs    r"   Úmax_pingpong_turnsr-   1   s%   € ÜÐ)Ô+@ÓA€AÜˆq”#�aÔ+Ó,Ó-Ð-r$   c                 ór   — t        j                  t        j                  «      j	                  d«      dd dz   S )z=ISO 8601 UTC timestamp with millisecond precision (A2A v1.0).z%Y-%m-%dT%H:%M:%S.%fNéýÿÿÿÚZ)r   Únowr	   ÚutcÚstrftime© r$   r"   Únow_isor5   6   s-   € ä�<‰<œŸ™Ó%×.Ñ.Ð/EÓFÀsÈÐKÈcÑQÐQr$   FÚ )ÚskillsÚ	streamingÚpush_notificationsÚauth_requiredÚtenantc                óâ   — |dt         dœ|rd|ini ¥}| ||dt        j                  dd«      t        j                  dd«      xs |d	œ|g||d
d
dœdgdg|xs g dœ
}	|rddddœi|	d<   dg ig|	d<   |	S )z–A2A v1.0 Agent Card. ``tenant`` is the optional multi-tenancy routing key on
    AgentInterface; when present, clients MUST echo it in request params.ÚJSONRPC)ÚurlÚprotocolBindingÚprotocolVersionr;   z1.0.0ÚA2A_PROVIDER_ORGzHermes AgentÚA2A_PROVIDER_URLr6   )Úorganizationr>   F)r8   ÚpushNotificationsÚstateTransitionHistoryÚextendedAgentCardú
text/plain)
r    Údescriptionr>   ÚversionÚproviderÚsupportedInterfacesÚcapabilitiesÚdefaultInputModesÚdefaultOutputModesr7   ÚbearerÚhttp)ÚtypeÚschemeÚsecuritySchemesÚsecurity)ÚPROTOCOL_VERSIONr   r   )
r    r>   rH   r7   r8   r9   r:   r;   ÚifaceÚcards
             r"   Úbuild_agent_cardrX   ;   sÙ   € ð
 %(¸IÔZjñ  Vñ  FLÐpxð  {Añ  pBð  RTð  V€EàØ"ØØÜ%'§Y¡YÐ/AÀ>Ó%RÔ[]×[dÑ[dÐewÐy{Ó[|ò  \Dð  ADñ  EØ %˜wØ&/ÐFXØ38ÈuñVà*˜^ÀLÀ>Ð]cÒ]iÐgiñ
€Dñ Ø#+°fÈÑ-QÐ"RˆÐÑØ% r˜NÐ+ˆˆZÑØ€Kr$   c                ó,  — t        | t        «      st        | xs g «      D �ci c]  }|g “Œ } }t        | «      D ��cg c]5  }d|› �|d|› d�|g| |   xs g D �cg c]  }t	        |«      ‘Œ c}dd z   dœ‘Œ7 }}}|xs	 ddddgdœgS c c}w c c}w c c}}w )	zqA2A skill descriptors from toolset names or a toolset -> tool-names mapping (tool names
    become tags, max 10).ztoolset.zHermes 'z' capabilitiesNé
   )Úidr    rH   ÚtagsÚgeneralz$General-purpose conversational agent)Ú
isinstanceÚdictÚsetÚsortedÚstr)ÚtoolsetsÚtsr    Útr7   s        r"   Úskills_from_toolsetsrf   R   s×   € ô �h¤Ô%Ü%(¨ª°RÓ%8Ö9˜r�B˜‘FÐ9ˆÐ9ä[aÐbjÓ[k÷mØSWð   ˜vÐ&°ÀxÐPTÈvÐUcÐEdØ�v°(¸4±.Ò2FÀBÖ H¨A¤ Q¥Ò HÈÈ"Ð MÑMóOð m€Fñ màò  H˜Y°	ÐJpð  |Eð  {Fñ  Gð  Hð  Hùò :ùâ Hùóms   ¢
B¼BÁBÁ*BÂBc                ó   — d| |dœS )Nú2.0)Újsonrpcr[   Úresultr4   )Úreq_idrj   s     r"   Újsonrpc_resultrl   \   s   € Ø F°fÑ=Ð=r$   c                ó   — d| ||dœdœS )Nrh   )ÚcodeÚmessage)ri   r[   Úerrorr4   )rk   rn   ro   s      r"   Újsonrpc_errorrq   `   s   € Ø F¸dÈwÑ5WÑXÐXr$   c                óv   — t        | t        «      r&| j                  d«      r| j                  d«      rd| iS d| iS )zFv1.0 SendMessageResponse oneof: exactly one of ``task`` / ``message``.Ústatusr[   Útaskro   ©r^   r_   Úget)Úpayloads    r"   Úsend_message_responserx   d   s8   € ä�'œ4Ô  W§[¡[°Ô%:¸w¿{¹{È4Ô?PØ˜Ð Ð Ø�wÐÐr$   c                ó¶   — t        | t        «      rHt        | j                  d«      t        «      r| d   S t        | j                  d«      t        «      r| d   S | S )zGTask/Message inside a v1.0 response; legacy bare payloads pass through.rt   ro   ru   )rj   s    r"   Úunwrap_send_message_responserz   k   sL   € ä�&œ$ÔÜ�f—j‘j Ó(¬$Ô/Ø˜&‘>Ð!Ü�f—j‘j Ó+¬TÔ2Ø˜)Ñ$Ð$Ø€Mr$   c                ó
   — d| iS )z'v1.0 StreamResponse with a task member.rt   r4   )rt   s    r"   Ústream_taskr|   u   s   € à�Dˆ>Ðr$   c                 óJ   — dt        j                  «       j                  d d z   S )Nztask-é   ©ÚuuidÚuuid4Úhexr4   r$   r"   Únew_task_idrƒ   z   s    € Ø”T—Z‘Z“\×%Ñ% c rÐ*Ñ*Ð*r$   c                 óJ   — dt        j                  «       j                  d d z   S )Nzctx-r~   r   r4   r$   r"   Únew_context_idr…   ~   s    € Ø”D—J‘J“L×$Ñ$ S bÐ)Ñ)Ð)r$   c                ó   — | ddœS )z<v1.0 text Part (member-presence discriminated, no ``kind``).rG   )ÚtextÚ	mediaTyper4   )r‡   s    r"   Ú	text_partr‰   ‚   s   € à |Ñ4Ð4r$   c                ól   — | t        |«      gt        j                  «       j                  dœ}|r||d<   |S )z)A2A v1.0 Message with a single text Part.©ÚroleÚpartsÚ	messageIdÚ	contextId)r‰   r€   r�   r‚   )rŒ   r‡   Ú
context_idÚmsgs       r"   Útext_messager’   ‡   s7   € à#'´9¸T³?Ð2CÔRV×R\ÑR\ÓR^×RbÑRbÑc€CÙØ%ˆˆKÑØ€Jr$   c                ó>   — | rd| › d�nd}|› d|› �|rd|› d�z   S dz   S )Nz[file: ú]z[file]Ú z (ú)r6   r4   )ÚfnameÚbodyÚmtypeÚlabels       r"   Ú
_file_noter›   �   s<   € Ù"'ˆg�e�W˜AÑ¨X€EØˆW�A�d�VÐ± " U G¨1 Ñ?Ð?¸BÑ?Ð?r$   c                ó|   — 	 t        j                  | dt        ¬«      S # t        t        f$ r t        | «      cY S w xY w)NF)Úensure_asciir!   )ÚjsonÚdumpsrb   Ú	TypeErrorÚ
ValueError)Údatas    r"   Ú_json_or_strr£   ”   s8   € ðÜ�z‰z˜$¨U¼CÔ@Ð@øÜ”zÐ"ò Ü�4‹yÒðús   ‚ ž;º;c           
     óà  — | j                  d| «      }g }t        |t        «      r|j                  dg «      ng D �]  }t        |t        «      sŒt        |j                  d«      x}t        «      r|j	                  |«       ŒHt        |j                  d«      x}t        «      rk|ri|j	                  t        |j                  d«      xs |j                  d«      xs d||j                  d«      xs |j                  d	«      xs d«      «       ŒÔt        |j                  d
«      x}t        «      rft        |j                  d«      t        «      rG|j	                  t        |j                  d«      xs d|d   |j                  d	«      xs d«      «       �Œ[t        |j                  d«      t        «      rS|j	                  t        |j                  d«      xs dt        |d   «      › d�|j                  d«      xs d«      «       �ŒÍ|j                  d«      x}€�Œâ|j	                  d|j                  d«      xs d› dt        |«      › �«       �Œ dj                  |«      j                  «       S )zõConcatenated text from an A2A Message / Task-result / params payload. v1.0, v0.3
    (``kind``) and pre-0.3 (``type``) Parts all carry ``text``; file Parts render as
    URL/filename (raw base64 noted, not decoded); data Parts render their JSON.ro   r�   r‡   r>   Úfilenamer    r6   rˆ   ÚmimeTypeÚfileÚfileWithUriÚrawz bytes base64-encodedr¢   z[data (úapplication/jsonz)]
Ú
)
rv   r^   r_   rb   Úappendr›   Úlenr£   ÚjoinÚstrip)Úmessage_or_paramsr‘   ÚchunksÚpartÚtxtr>   Úv03r¢   s           r"   Úextract_textrµ   ›   s  € ð ×
Ñ
 	Ð+<Ó
=€CØ€FÜ(2°3¼Ô(=�—‘˜ Ô$À2ó kˆÜ˜$¤Ô%ØÜ˜TŸX™X fÓ-Ð-�c¬sÔ3Ø�M‰M˜#ÕÜ˜tŸx™x¨›Ð.˜´Ô4¹Ø�M‰Mœ* T§X¡X¨jÓ%9Ò%S¸T¿X¹XÀfÓ=MÒ%SÐQSÐUXØ%)§X¡X¨kÓ%:Ò%X¸d¿h¹hÀzÓ>RÒ%XÐVXóZõ [ä˜tŸx™x¨Ó/Ð/˜´Ô6¼:ÀcÇgÁgÈmÓF\Ô^aÔ;bØ�M‰Mœ* S§W¡W¨V£_Ò%:¸¸CÀÑ<NÐPS×PWÑPWÐXbÓPcÒPiÐgiÓjÖkÜ˜Ÿ™ ›¬Ô-Ø�M‰Mœ* T§X¡X¨jÓ%9Ò%?¸RÄCÈÈUÉÓDTÐCUÐUjÐAkØ%)§X¡X¨kÓ%:Ò%@¸bóBö Cà—h‘h˜vÓ&Ð&ˆdÒ3Ø�M‰M˜G D§H¡H¨[Ó$9Ò$OÐ=OÐ#PÐPTÔUaÐbfÓUgÐThÐiÖjðkð �9‰9�VÓ×"Ñ"Ó$Ð$r$   c                óÌ   — | j                  d«      xs i }t        |t        «      rt        |j                  d«      xs d«      ndxs t        | j                  d«      xs d«      S )zBv1.0 puts contextId inside the Message; tolerate legacy top-level.ro   r�   r6   )rv   r^   r_   rb   )Úparamsr‘   s     r"   Úextract_context_idr¸   ³   sW   € à
�*‰*�YÓ
Ò
% 2€CÜ/9¸#¼tÔ/DŒC�—‘˜Ó$Ò*¨Ô+È"ÒsÔQTÐU[×U_ÑU_Ð`kÓUlÒUrÐprÓQsÐsr$   ©Ú
created_atc               óÊ   — | ||t        «       dœdœ}|rOt        t        ||«      |d   d<   |t        k(  r/t	        j
                  «       j                  t        |«      gdœg|d<   |S )z¤A2A v1.0 Task. ``created_at`` is accepted but NOT serialized: the v1.0 Task proto has no
    createdAt and strict ProtoJSON parsers (a2a-sdk) reject unknown fields.©ÚstateÚ	timestamp)r[   r�   rs   rs   ro   ©Ú
artifactIdr�   Ú	artifacts)r5   r’   r   ÚSTATE_COMPLETEDr€   r�   r‚   r‰   )Útask_idr�   r½   Ú
agent_textrº   rt   s         r"   Ú
build_taskrÅ   ¹   sh   € ð #*¸
ÐX]ÔlsÓluÑNvÑw€DÙÜ$0´¸ZÈÓ$TˆˆX‰�yÑ!Ø”OÒ#Ü04·
±
³×0@Ñ0@ÌIÐV`ÓLaÐKbÑ!cÐ dˆD�ÑØ€Kr$   c                óX   — |t        «       dœ}|rt        t        ||«      |d<   d| ||dœiS )z/v1.0 StreamResponse with a statusUpdate member.r¼   ro   ÚstatusUpdate)ÚtaskIdr�   rs   )r5   r’   r   )rÃ   r�   r½   r‡   rs   s        r"   Ústatus_updaterÉ   Ä   s7   € à',¼7»9ÑE€FÙÜ(¬°T¸:ÓFˆˆyÑØ w¸ZÐSYÑZÐ[Ð[r$   c                óh   — t        j                  «       j                  t        |«      gdœ}d| ||dœiS )z2v1.0 StreamResponse with an artifactUpdate member.r¿   ÚartifactUpdate)rÈ   r�   Úartifact)r€   r�   r‚   r‰   )rÃ   r�   r‡   rÌ   s       r"   Úartifact_updaterÍ   Ì   s2   € ä"Ÿj™j›l×.Ñ.¼)ÀD»/Ð9JÑK€HØ¨¸zÐW_Ñ`ÐaÐar$   c                óX   — |�t        || «      n| }dt        j                  |d¬«      › d�S )u²   One StreamResponse as an SSE data frame. Â§9.4 requires a full JSON-RPC envelope (a2a-sdk
    breaks on bare StreamResponses); ``req_id=None`` is the legacy no-envelope fallback.zdata: F©r�   z

)rl   rž   rŸ   )rw   rk   Úenvelopes      r"   Ússe_datarÑ   Ò   s2   € ð 39Ð2DŒ~˜f gÔ.È'€HØ”D—J‘J˜x°eÔ<Ð=¸TÐBÐBr$   c                  ó   — y)u]   Stream-closure marker as an SSE *comment* â€” ``data: {}`` would make JSON-RPC clients parse.z: done

r4   r4   r$   r"   Ússe_donerÓ   Ù   s   € àr$   c                  ó,   — e Zd ZdZdZdd„Zdd„Zd	d„Zy)
ÚTurnTrackerzUCounts inbound turns per context_id; beyond max_pingpong_turns() the adapter rejects.i  c                óD   — i | _         t        j                  «       | _        y r   )Ú_turnsÚ	threadingÚLockÚ_lock©Úselfs    r"   Ú__init__zTurnTracker.__init__ã   s   € Ø46ˆŒÜ—^‘^Ó%ˆ�
r$   c                óz  — | j                   5  t        j                  «       }| j                  j                  «       D ��ci c]  \  }}||d   z
  | j                  k  sŒ||“Œ  c}}| _        | j                  j                  |d|f«      d   dz   }||f| j                  |<   |cddd«       S c c}}w # 1 sw Y   yxY w)z;Increment and return the turn count; prunes stale contexts.r'   r   N)rÚ   Útimer×   ÚitemsÚ_TTLrv   )rÜ   r�   r1   Úcidr,   Úcounts         r"   ÚtrackzTurnTracker.trackç   s¥   € à�Z‰Zñ 	Ü—)‘)“+ˆCØ04·±×0AÑ0AÓ0C×_¡f c¨1ÀsÈQÈqÉTÁzÐUY×U^ÑU^ÓG^˜3 ™6Ó_ˆDŒKØ—K‘K—O‘O J°°C°Ó9¸!Ñ<¸qÑ@ˆEØ',¨c lˆD�K‰K˜
Ñ#Ø÷	ñ 	ùã_÷	ð 	ús"   �2B1¿B+ÁB+Á"?B1Â+B1Â1B:c                ó~   — | j                   5  | j                  j                  |d «       d d d «       y # 1 sw Y   y xY wr   )rÚ   r×   Úpop)rÜ   r�   s     r"   ÚresetzTurnTracker.resetð   s0   € Ø�Z‰Zñ 	.Ø�K‰K�O‰O˜J¨Ô-÷	.÷ 	.ñ 	.ús   �3³<N©ÚreturnÚNone)r�   rb   ré   Úint)r�   rb   ré   rê   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__rá   rÝ   rä   rç   r4   r$   r"   rÕ   rÕ   Þ   s   „ Ù_à€Dó&óô.r$   rÕ   c                  ó    — e Zd ZdZdd„Zdd„Zy)ÚRateLimiterzFSliding-window request limiter, one bucket per authenticated identity.c                ó^   — t        t        «      | _        t        j                  «       | _        y r   )r   r   Ú_bucketsrØ   rÙ   rÚ   rÛ   s    r"   rÝ   zRateLimiter.__init__ø   s   € Ü1<¼UÓ1CˆŒÜ—^‘^Ó%ˆ�
r$   c                óz  — | j                   5  t        dt        dt        «      «      }t	        j                  «       }| j
                  |   }|r1||d   z
  t        kD  r"|j                  «        |r||d   z
  t        kD  rŒ"t        |«      |k\  r
	 d d d «       y|j                  |«       	 d d d «       y# 1 sw Y   y xY w)Nr'   ÚA2A_RATE_LIMITr   FT)
rÚ   r)   r#   Ú_RATE_LIMIT_DEFAULTrß   ró   Ú_RATE_WINDOWÚpopleftr­   r¬   )rÜ   ÚidentityÚlimitr1   Úbuckets        r"   ÚallowzRateLimiter.allowü   s¦   € Ø�Z‰Zñ 		Ü˜œ8Ð$4Ô6IÓJÓKˆEÜ—)‘)“+ˆCØ—]‘] 8Ñ,ˆFÙ˜S 6¨!¡9™_¬|Ò;Ø—‘Ô ñ ˜S 6¨!¡9™_¬|Ó;ä�6‹{˜eÒ#Ø÷		ð 		ð �M‰M˜#ÔØ÷		÷ 		ñ 		ús   �A0B1Á>B1ÂB1Â1B:Nrè   )rù   rb   ré   Úbool)rì   rí   rî   rï   rÝ   rü   r4   r$   r"   rñ   rñ   õ   s   „ ÙPó&ô
r$   rñ   c                  ó4   — e Zd ZdZdZdd„Zd	d„Zd
d„Zdd„Zy)ÚMetricszCounters for A2A operations (module singleton ``metrics`` shared by the inbound adapter
    and outbound tools; not persisted).)	Úinbound_totalÚoutbound_totalÚstreams_startedÚ	push_sentÚpush_failedÚtasks_completedÚtasks_failedÚanti_loop_triggersÚrate_limit_triggersc                ó”   — | j                   D ]  }t        | |d«       Œ t        j                  «       | _        t	        d¬«      | _        y )Nr   éd   )Úmaxlen)Ú	_COUNTERSÚsetattrrß   Ú_start_timer   Ú
_latencies)rÜ   r    s     r"   rÝ   zMetrics.__init__  s;   € Ø—N‘Nò 	#ˆDÜ�D˜$ Õ"ð	#äŸ9™9›;ˆÔÜ(-°SÔ(9ˆ�r$   c                ó:   — | j                   j                  |«       y r   )r  r¬   )rÜ   Úsecondss     r"   Úrecord_latencyzMetrics.record_latency  s   € Ø�‰×Ñ˜wÕ'r$   c                ót   — | j                   r+t        | j                   «      t        | j                   «      z  S dS )Ng        )r  Úsumr­   rÛ   s    r"   Úavg_latencyzMetrics.avg_latency  s+   € Ø>B¿oºoŒs�4—?‘?Ó#¤c¨$¯/©/Ó&:Ñ:ÐVÐSVÐVr$   c           	     óî   — dt        t        j                  «       | j                  z
  d«      i| j                  D �ci c]  }|t	        | |«      “Œ c}¥dt        | j                  «       dz  d«      i¥S c c}w )NÚuptime_secondsr'   Úavg_latency_msiè  )Úroundrß   r  r  Úgetattrr  )rÜ   Úns     r"   ÚsnapshotzMetrics.snapshot  sx   € Ø ¤%¬¯	©	«°d×6FÑ6FÑ(FÈÓ"Jð GÐlp×lzÑlzÖN{ÐghÈqÔRYÐZ^Ð`aÓRbÑObÒN{ð GØ ¤%¨×(8Ñ(8Ó(:¸TÑ(AÀ1Ó"EñGð 	GùÒN{s   »A2Nrè   )r  Úfloatré   rê   )ré   r  )ré   zdict[str, Any])	rì   rí   rî   rï   r  rÝ   r  r  r  r4   r$   r"   rÿ   rÿ   	  s%   „ ñ+ða€Ió:ó(óWôGr$   rÿ   c                  óú   — e Zd ZdZdZdd„Zeddd„«       Zddd„Zddd„Z	edd„«       Z
ddd„Zd d	„Zdd!d
„Zddd„Zdd"d„Zdd#d„Zd$d„Zddd„Zd%d&d„Zdd'd„Z	 	 d(	 	 	 	 	 d)d„Zd*ddœd+d„Zdd„Zed,d-d„«       Zy).Ú	TaskStorez¥In-memory A2A tasks, kept after completion for tasks/get. Records carry agent slug +
    tenant; readers pass a scope and get not-found outside it (spec authz rule).iô  c                ób   — t        «       | _        i | _        t        j                  «       | _        y r   )r   Ú_tasksÚ	_watchersrØ   rÙ   rÚ   rÛ   s    r"   rÝ   zTaskStore.__init__*  s    € Ü:E»-ˆŒØ24ˆŒÜ—^‘^Ó%ˆ�
r$   c                ól   — |xr | j                  dd«      |k7  xs |xr | j                  dd«      |k7   S )NÚ
agent_slugr6   r;   ©rv   )Úrecr$  r;   s      r"   Ú	_in_scopezTaskStore._in_scope/  sA   € àÒK C§G¡G¨L¸"Ó$=ÀÑ$KÒ|ÐQWÒQ{Ð\_×\cÑ\cÐdlÐnpÓ\qÐu{Ñ\{Ð}Ð}r$   c                ój   — | j                   j                  |«      }|r| j                  |||«      r|S dS )z7Live record if visible in scope. Caller holds the lock.N)r!  rv   r'  ©rÜ   rÃ   r$  r;   r&  s        r"   Ú_scopedzTaskStore._scoped3  s0   € à�k‰k�o‰o˜gÓ&ˆÙ˜dŸn™n¨S°*¸fÔEˆsÐOÈ4ÐOr$   c                ó€   — | j                  |||«      }|r)|j                  d«      r|r|j                  d«      |k(  r|S y)z^Scoped record that has a push config (matching ``config_id`` if given). Caller holds the lock.Úpush_urlÚpush_config_idN)r*  rv   ©rÜ   rÃ   Ú	config_idr$  r;   r&  s         r"   Ú	_push_reczTaskStore._push_rec8  s>   € à�l‰l˜7 J°Ó7ˆÙ�3—7‘7˜:Ô&±	¸S¿W¹WÐEUÓ=VÐZcÒ=cØˆJØr$   c                ó†   — | j                  d«      xs d| d   | j                  dd«      d| j                  d«      xs didœS )Nr-  r6   rÃ   Úcreated_isor>   r,  )ÚconfigIdrÈ   Ú	createdAtÚpushNotificationConfigr%  )r&  s    r"   Ú_push_config_viewzTaskStore._push_config_view?  sO   € àŸG™GÐ$4Ó5Ò;¸ÀsÈ9Á~Ø ŸW™W ]°BÓ7ÐTYÐ[^×[bÑ[bÐcmÓ[nÒ[tÐrtÐSuñwð 	wr$   c                óô   — ||||xs d|xs dt         dt        j                  «       t        «       dddœ}| j                  5  || j                  |<   d d d «       t        |«      S # 1 sw Y   t        |«      S xY w)Nr6   )rÃ   r�   Úpeerr$  r;   r½   Úreplyrº   r2  r,  r-  )ÚSTATE_SUBMITTEDrß   r5   rÚ   r!  r_   )rÜ   rÃ   r�   r8  r$  r;   r&  s          r"   ÚcreatezTaskStore.createD  s�   € Ø!°ÀTÐYcÒYiÐgiÐu{ò  vBð  @BÜ'°"ÄDÇIÁIÃKÔ`gÓ`iÐwyð  NPñQˆà�Z‰Zñ 	'Ø#&ˆD�K‰K˜Ñ ÷	'ä�C‹yÐ÷	'ä�C‹yÐús   ÁA$Á$A7c                ó    — | j                   5  | j                  j                  |«      x}r|d   t        vr||d<   d d d «       y # 1 sw Y   y xY w)Nr½   )rÚ   r!  rv   ÚTERMINAL_STATES)rÜ   rÃ   r½   r&  s       r"   Ú	set_statezTaskStore.set_stateK  sJ   € Ø�Z‰Zñ 	%Ø—{‘{—‘ wÓ/Ð/�Ð/°S¸±\ÌÑ5XØ$��G‘÷	%÷ 	%ñ 	%ús   �.AÁAc                ó   — | j                   5  | j                  |||«      x}s
	 ddd«       y|dt        j                  «       j                  dd z   c|d<   |d<   | j                  |«      cddd«       S # 1 sw Y   yxY w)zEAttach a push notification config; returns the stored config or None.Nzcfg-é   r,  r-  )rÚ   r*  r€   r�   r‚   r6  )rÜ   rÃ   r>   r$  r;   r&  s         r"   Úset_push_configzTaskStore.set_push_configP  sƒ   € à�Z‰Zñ 	/ØŸ<™<¨°¸VÓDÐD�CÐDØ÷	/ð 	/ð 69¸&Ä4Ç:Á:Ã<×CSÑCSÐTWÐUWÐCXÑ:XÐ2ˆC�
‰O˜SÐ!1Ñ2Ø×)Ñ)¨#Ó.÷		/÷ 	/ò 	/ús   �A4­=A4Á4A=c                ó˜   — | j                   5  | j                  ||||«      x}r| j                  |«      nd cd d d «       S # 1 sw Y   y xY wr   )rÚ   r0  r6  r.  s         r"   Úget_push_configzTaskStore.get_push_configX  sO   € Ø�Z‰Zñ 	|Ø:>¿.¹.ÈÐR[Ð]gÐioÓ:pÐ3p°3Ð3p�4×)Ñ)¨#Ô.Ðw{÷	|÷ 	|ò 	|ús   �)A Á A	c                ó8   — | j                  |d||«      }|r|gS g S )Nr6   )rC  )rÜ   rÃ   r$  r;   Úcfgs        r"   Úlist_push_configszTaskStore.list_push_configs\  s'   € Ø×"Ñ" 7¨B°
¸FÓCˆÙ�ˆuÐ# Ð#r$   c                óŽ   — | j                   5  | j                  ||||«      }|r
dx|d<   |d<   |d ucd d d «       S # 1 sw Y   y xY w)Nr6   r,  r-  )rÚ   r0  r.  s         r"   Údelete_push_configzTaskStore.delete_push_config`  sP   € Ø�Z‰Zñ 	#Ø—.‘. ¨)°ZÀÓHˆCÙØ:<Ð<��J‘ #Ð&6Ñ"7Ø˜d�?÷		#÷ 	#ò 	#ús	   �$;»Ac                ó¢   — | j                   5  | j                  j                  |«      }|r|d   dc}|d<   |rndcd d d «       S # 1 sw Y   y xY w)Nr,  r6   )rÚ   r!  rv   )rÜ   rÃ   r&  r>   s       r"   Úpop_push_urlzTaskStore.pop_push_urlg  sN   € Ø�Z‰Zñ 	&Ø—+‘+—/‘/ 'Ó*ˆCÙØ'*¨:¡¸Ð$��S˜‘_Ù‘3 2÷		&÷ 	&ò 	&ús   �.AÁAc                óŠ   — | j                   5  | j                  |||«      x}rt        |«      nd cd d d «       S # 1 sw Y   y xY wr   )rÚ   r*  r_   r)  s        r"   rv   zTaskStore.getn  sC   € Ø�Z‰Zñ 	]Ø(,¯©°W¸jÈ&Ó(QÐ!Q Ð!Q”4˜”9ÐX\÷	]÷ 	]ò 	]ús	   �"9¹Ac                ó¼  — | j                   5  | j                  j                  |«      }|r|d   t        v r
	 ddd«       y|j	                  ||t        j
                  «       ¬«       | j                  j                  |g «      }| j                  «        t        |«      }ddd«       D ]&  }|j                  «       rŒ|j                  ||f«       Œ( S # 1 sw Y   Œ6xY w)z2Transition a task to a terminal state. Idempotent.r½   N)r½   r9  Úcompleted_at)rÚ   r!  rv   r=  Úupdaterß   r"  ræ   Ú_trim_lockedr_   ÚdoneÚ
set_result)rÜ   rÃ   r½   r9  r&  ÚwatchersÚoutÚfuts           r"   ÚcompletezTaskStore.completer  sÁ   € à�Z‰Zñ 	Ø—+‘+—/‘/ 'Ó*ˆCÙ˜#˜g™,¬/Ñ9Ø÷	ð 	ð �J‰J˜U¨%¼d¿i¹i»kˆJÔJØ—~‘~×)Ñ)¨'°2Ó6ˆHØ×ÑÔÜ�s“)ˆC÷	ð ò 	/ˆCØ—8‘8•:Ø—‘  u˜~Õ.ð	/ð ˆ
÷	ð 	ús   �*CÁ ACÃCc                óV  — | j                   5  | j                  |||«      x}s
	 d d d «       y t        «       }|d   t        v r'|j	                  |d   |j                  dd«      f«       n+| j                  j                  |g «      j                  |«       |cd d d «       S # 1 sw Y   y xY w)Nr½   r9  r6   )	rÚ   r*  r   r=  rQ  rv   r"  Ú
setdefaultr¬   )rÜ   rÃ   r$  r;   r&  rT  s         r"   ÚwatchzTaskStore.watch�  sš   € Ø�Z‰Zñ 	ØŸ<™<¨°¸VÓDÐD�CÐDØ÷	ð 	ô !›(ˆCØ�7‰|œÑ.Ø—‘  G¡¨c¯g©g°g¸rÓ.BÐCÕDà—‘×)Ñ)¨'°2Ó6×=Ñ=¸cÔBØ÷	÷ 	ò 	ús   �B­A(BÂB(c           	     ó®  — t        dt        t        |xs d«      d«      «      }| j                  5  t	        | j
                  j                  «       «      D �cg c]4  }| j                  |||«      r|r|d   |k(  r|r|d   |k(  rt        |«      ‘Œ6 }	}ddd«       t        	«      }
|	|||z    }||z   |
k  r||z   nd}|r|||
fS ||fS c c}w # 1 sw Y   Œ;xY w)z�Filtered task page (newest first) as ``(records, next_offset)``, or
        ``(records, next_offset, total)`` with ``with_total`` (v1.0 ListTasks totalSize).r'   é2   r
  r�   r½   Nr   )
r)   r*   rë   rÚ   Úreversedr!  Úvaluesr'  r_   r­   )rÜ   r�   r½   Ú	page_sizeÚoffsetr$  r;   Ú
with_totalÚrÚrecsÚtotalÚpageÚnext_offsets                r"   ÚlistzTaskStore.listŒ  sø   € ô ˜œ3œs 9¢?°Ó3°SÓ9Ó:ˆ	Ø�Z‰Zñ 	rÜ%-¨d¯k©k×.@Ñ.@Ó.BÓ%Cö r Ø—~‘~ a¨°VÔ<Ù'¨1¨\©?¸jÒ+HÑSXÐ\]Ð^eÑ\fÐjoÒ\oô ˜•Gð rˆDð r÷	rô �D“	ˆØ�F˜6 IÑ-Ð.ˆØ,2°YÑ,>ÀÒ,F�f˜yÒ(ÈAˆÙ-7��k 5Ð)ÐP¸dÀKÐ=PÐPùòr÷	rð 	rús   °&CÁ9CÂCÃCÃCN)Úexcludec               óv  — |xs
 t        «       }| j                  5  | j                  j                  «       D ��cg c]3  \  }}||vr*|d   t        vrt        j
                  «       |d   z
  |kD  r|‘Œ5 }}}d d d «       D �cg c]  }| j                  |t        d«      sŒ|‘Œ c}S c c}}w # 1 sw Y   Œ7xY wc c}w )Nr½   rº   u%   [task orphaned â€” no reply produced])r`   rÚ   r!  rà   r=  rß   rU  ÚSTATE_FAILED)rÜ   Útimeout_secondsrf  ÚexcludedÚtidr&  Ústales          r"   Úfail_orphanszTaskStore.fail_orphansš  s·   € ØÒ#œc›eˆØ�Z‰Zñ 	LØ)-¯©×):Ñ):Ó)<÷ L™X˜S #Ø 8Ñ+°°G±ÄOÑ0SÜŸ™› s¨<Ñ'8Ñ8¸?ÒJò ð LˆEñ L÷	Lð  %Ör˜¨¯©°c¼<ÐIpÕ(q’ÒrÐrùóL÷	Lð 	Lüò ss(   ›B*¹8B$Á1B*Â B6ÂB6Â$B*Â*B3c                ó  — | j                   j                  «       D ��cg c]  \  }}|d   t        v sŒ|‘Œ }}}|d t        dt	        |«      | j
                  z
  «       D ]  }| j                   j                  |d «       Œ  y c c}}w )Nr½   r   )r!  rà   r=  r)   r­   Ú_MAX_TERMINALræ   )rÜ   rk  r&  Úterminals       r"   rO  zTaskStore._trim_locked¢  sv   € Ø(,¯©×(9Ñ(9Ó(;×_™H˜C ¸sÀ7¹|ÌÒ?^’CÐ_ˆÑ_ØÐGœS ¤C¨£M°D×4FÑ4FÑ$FÓGÐHò 	'ˆCØ�K‰K�O‰O˜C Õ&ñ	'ùó `s
   žB ²B c           
     ó    — t        | d   | d   | d   | j                  dd«      | j                  dd«      ¬«      }|s|j                  dd	«       |S )
z+Render a stored record as an A2A v1.0 Task.rÃ   r�   r½   r9  r6   r2  r¹   rÁ   N)rÅ   rv   ræ   )r&  Úinclude_artifactsrt   s      r"   Úto_taskzTaskStore.to_task§  sU   € ô ˜#˜i™.¨#¨lÑ*;¸SÀ¹\È3Ï7É7ÐSZÐ\^ÓK_Ø%(§W¡W¨]¸BÓ%?ôAˆá Ø�H‰H�[ $Ô'Øˆr$   rè   )r6   r6   )r&  r_   r$  rb   r;   rb   ré   rý   )rÃ   rb   r$  rb   r;   rb   ré   úOptional[dict])r6   r6   r6   )
rÃ   rb   r/  rb   r$  rb   r;   rb   ré   rt  )r&  r_   ré   r_   )rÃ   rb   r�   rb   r8  rb   r$  rb   r;   rb   ré   r_   )rÃ   rb   r½   rb   ré   rê   )
rÃ   rb   r>   rb   r$  rb   r;   rb   ré   rt  )rÃ   rb   r$  rb   r;   rb   ré   ú
list[dict])
rÃ   rb   r/  rb   r$  rb   r;   rb   ré   rý   )rÃ   rb   ré   rb   ©r6   )rÃ   rb   r½   rb   r9  rb   ré   rt  )rÃ   rb   r$  rb   r;   rb   ré   zOptional[Future])r6   r6   rZ  r   r6   r6   F)r�   rb   r½   rb   r]  rë   r^  rë   r$  rb   r;   rb   r_  rý   )i,  )ri  r  rf  zset[str] | Noneré   ú	list[str])T)r&  r_   rr  rý   ré   r_   )rì   rí   rî   rï   ro  rÝ   Ústaticmethodr'  r*  r0  r6  r;  r>  rA  rC  rF  rH  rJ  rv   rU  rX  re  rm  rO  rs  r4   r$   r"   r  r  $  sÒ   „ ñTð €Mó&ð
 ó~ó ð~ôPô
ð òwó ðwôó%ô
/ô|ô$ô#ó&ô]ôô	ð ^_ØHMðQØðQØ+.ðQØAEóQðsÐW[õ só'ð
 óó ñr$   r  c                óh   — dj                  d„ | xs dD «       «      xs d}t        «       dz  |› d�z  S )Nr6   c              3  óJ   K  — | ]  }|j                  «       s|d v sŒ|–— Œ y­w)z-_N)Úisalnum)Ú.0Úcs     r"   ú	<genexpr>z_conv_path.<locals>.<genexpr>²  s   è ø€ ÒT˜¸1¿9¹9¼;È!ÈtÊ)”1ÑTùs   ‚#œ#r!   Úa2a_conversationsz.jsonl)r®   r   )r�   Úsafes     r"   Ú
_conv_pathr�  ±  s;   € Ø�7‰7ÑT˜zÒ6¨YÔTÓTÒaÐXa€DÜÓÐ2Ñ2¸°v¸V°_ÑDÐDr$   c           
     óD  — 	 t        | «      }|j                  j                  dd¬«       |j                  dd¬«      5 }|j	                  t        j                  t        j                  «       |||dœd¬«      d	z   «       d
d
d
«       y
# 1 sw Y   y
xY w# t        $ r Y y
w xY w)zKAppend one message to the context's on-disk conversation log. Never raises.T)ÚparentsÚexist_okÚaúutf-8©Úencoding)rd   rŒ   r‡   rÃ   FrÏ   r«   N)	r�  ÚparentÚmkdirÚopenÚwriterž   rŸ   rß   Ú	Exception)r�   rŒ   r‡   rÃ   ÚpathÚfhs         r"   Úpersist_messager�  ¶  s•   € ðÜ˜*Ó%ˆØ�‰×Ñ $°ÐÔ6Ø�Y‰Y�s WˆYÓ-ð 	A°Ø�H‰H”T—Z‘Z¤t§y¡y£{¸DÈ$Ð[bÑ cÐrwÔxÐ{Ñô  A÷	A÷ 	Añ 	Aûäò Ùðús/   ‚;B ½ABÁ>B ÂBÂB ÂB Â	BÂBc                óZ  — 	 t        | «      j                  d¬«      j                  «       }g }|D ]K  }|j	                  «       sŒ	 t        j                  |«      }t        |t        «      sŒ;|j                  |«       ŒM || d S # t        $ r g cY S w xY w# t
        j                  $ r Y Œzw xY w)zFLast *limit* messages for a context (empty list if none / unreadable).r†  r‡  N)r�  Ú	read_textÚ
splitlinesr�  r¯   rž   ÚloadsÚJSONDecodeErrorr^   r_   r¬   )r�   rú   ÚlinesrS  ÚlineÚentrys         r"   Úload_conversationr™  Á  s±   € ðÜ˜:Ó&×0Ñ0¸'Ð0ÓB×MÑMÓOˆð €CØò "ˆØ�:‰:�<ðÜŸ
™
 4Ó(�ô ˜%¤Õ&Ø—
‘
˜5Õ!ð"ð �ˆvˆwˆ<Ðøô ò ØŠ	ðûô ×'Ñ'ò Ùðús#   ‚)B ÁBÂBÂBÂB*Â)B*c                 óZ   — t        d„ t        «       dz  j                  d«      D «       «      S )z.Context-ids that have persisted conversations.c              3  ó4   K  — | ]  }|j                   –— Œ y ­wr   )Ústem)r|  Úps     r"   r~  z%list_conversations.<locals>.<genexpr>Õ  s   è ø€ Ò\˜Q�!—&•&Ñ\ùs   ‚r  z*.jsonl)ra   r   Úglobr4   r$   r"   Úlist_conversationsrŸ  Ó  s(   € äÑ\¤?Ó#4Ð7JÑ#J×"PÑ"PÐQZÓ"[Ô\Ó\Ð\r$   iý‚ÿÿÚTASK_STATE_AUTH_REQUIREDc                ó   — | |dœS )z<Build a v1.0 data Part (structured data, no ``kind`` field).)r¢   rˆ   r4   )r¢   Ú
media_types     r"   Ú	data_partr£  â  s   € à zÑ2Ð2r$   c                ó<   — d|i}|r||d<   | r| |d<   |S |r||d<   |S )uµ   Build a v1.0 file Part.

    Either ``url`` (file reference) or ``raw`` (base64-encoded bytes) must be
    provided. Discrimination is by member presence â€” no ``kind`` field.
    rˆ   r¥   r>   r©   r4   )r>   r©   r¥   r¢  r²   s        r"   Ú	file_partr¥  æ  sA   € ð (¨Ð4€DÙØ#ˆˆZÑÙ
ØˆˆU‰ð €Kñ 
ØˆˆU‰Ø€Kr$   c                óX   — | |t        j                  «       j                  dœ}|r||d<   |S )zBBuild an A2A v1.0 Message with arbitrary Parts (text, file, data).r‹   r�   r   )rŒ   r�   r�   r‘   s       r"   Úmessage_with_partsr§  ö  s4   € ð ØÜ—Z‘Z“\×%Ñ%ñ€Cñ
 Ø%ˆˆKÑØ€Jr$   c                ó
   — d| iS )z*v1.0 StreamResponse with a message member.ro   r4   )ro   s    r"   Ústream_messager©    s   € à�wÐÐr$   )r    rb   r!   rë   ré   rë   )ré   rë   )ré   rb   )r    rb   r>   rb   rH   rb   r7   zOptional[list[dict]]r8   rý   r9   rý   r:   rý   r;   rb   ré   r_   )rc   z)'list[str] | dict[str, list[str]] | None'ré   ru  )rk   r   rj   r   ré   r_   )rk   r   rn   rë   ro   rb   ré   r_   )rw   r_   ré   r_   )rj   r   ré   r   )rt   r_   ré   r_   )r‡   rb   ré   r_   rv  )rŒ   rb   r‡   rb   r�   rb   ré   r_   )r—   rb   r˜   rb   r™   rb   ré   rb   )r¢   r   ré   rb   )r°   r_   ré   rb   )r·   r_   ré   rb   )rÃ   rb   r�   rb   r½   rb   rÄ   rb   rº   rb   ré   r_   )
rÃ   rb   r�   rb   r½   rb   r‡   rb   ré   r_   )rÃ   rb   r�   rb   r‡   rb   ré   r_   r   )rw   r_   rk   r   ré   rb   )r�   rb   ré   r
   )
r�   rb   rŒ   rb   r‡   rb   rÃ   rb   ré   rê   )rZ  )r�   rb   rú   rë   ré   ru  )ré   rw  )rª   )r¢   r   r¢  rb   ré   r_   )r6   r6   r6   zapplication/octet-stream)
r>   rb   r©   rb   r¥   rb   r¢  rb   ré   r_   )rŒ   rb   r�   ru  r�   rb   ré   r_   )ro   r_   ré   r_   )Zrï   Ú
__future__r   rž   r   rØ   rß   r€   Úcollectionsr   r   r   Úconcurrent.futuresr   r   r	   Úpathlibr
   Útypingr   r   Úgateway.platforms._sharedr   r   Úhermes_constantsr   rU   r:  ÚSTATE_WORKINGÚSTATE_INPUT_REQUIREDrÂ   rh  ÚSTATE_CANCELEDÚSTATE_REJECTEDÚ	frozensetr=  r   r   ÚINPUT_REQUIRED_MARKERÚ	ERR_PARSEÚERR_INVALID_PARAMSÚERR_METHOD_NOT_FOUNDÚERR_TASK_NOT_FOUNDÚERR_TASK_NOT_CANCELABLEÚERR_UNAUTHORIZEDÚERR_RATE_LIMITEDÚERR_UNTRUSTED_PEERr(   r+   rö   r÷   r#   r-   r5   rX   rf   rl   rq   rx   rz   r|   rƒ   r…   r‰   r’   r›   r£   rµ   r¸   rÅ   rÉ   rÍ   rÑ   rÓ   rÕ   rñ   rÿ   Úmetricsr  r�  r�  r™  rŸ  ÚcopyÚERR_PUSH_NOT_SUPPORTEDÚSTATE_AUTH_REQUIREDr£  r¥  r§  r©  r4   r$   r"   ú<module>rÃ     s  ðñ?õ
 #ã Û 	Û Û Û ß 7Ñ 7Ý %ß 'Ý ß  å @Ý ,àÐ ð 8AÑ 4€�Ð 4Ø KÑ €�Ø!MÑ €�Ù˜_¨l¸NÈNÐ[Ó\€Ø1Ñ €	ˆ:ð +Ð ð 7MÑ 3€	ÐÐ3Ø.<Ñ +Ð Ð+Ø9OÑ 6Ð Ð"Ð$6ð -2Ñ )Ð Ð)Ø$,Ñ !Ð �\ó:ó.ó
Rð
 _cØ',ÈÐfkØ#%ñØ $ðØBFðØ_cðà ðà*.óó.Hó>óYó óóó
+ó*ó5ô
ó@ó
ó%ó0tðÐegõ ô\óbôCó÷
.ñ .÷.ñ ÷(Gñ Gñ0 ‹)€÷Jñ JóZEô
ôó$]ó àÐ à0Ð ô3ð =?Ø :ðØðØ?Cóô 	ô r$   