Ë
    ãß²j ’  ã                  óþ  — U 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Zd dlm	Z	m
Z
 d dlmZmZmZmZmZ d dlmZmZmZ d dlmZ d dlmZmZmZmZ d dlmZmZ d d	lm Z m!Z! d d
l"m#Z#  ejH                  e%«      Z&dZ'dZ(dZ)dBd„Z*dBd„Z+dCd„Z,dDd„Z- G d„ d«      Z.dEd„Z/dFd„Z0dGd„Z1e	 G d„ d«      «       Z2 G d„ d«      Z3i Z4de5d<   dHd„Z6i Z7de5d<   dIdJd „Z8d!d"d#œZ9dKd$„Z:dLd%„Z;dMd&„Z<dNd'„Z=dOd(„Z>dPdQd)„Z?dRdSd*„Z@dTd+„ZAdUd,„ZBdUd-„ZCdVd.„ZDdUd/„ZEdWd0„ZF	 	 	 	 dUd1„ZGdXd2„ZHdUd3„ZIdUd4„ZJdYd5„ZKdYd6„ZLdYd7„ZMdUd8„ZNeBeCeNd9œZOeNeEeId9œZPeBeEeId9œZQeKeLeMd9œZReBeJeId9œZSdZd:„ZTd[d;„ZUd<ZVd\d=„ZWd]d>„ZXd^d?„ZYddd@œ	 	 	 	 	 	 	 	 	 	 	 	 	 d_dA„ZZy)`é    )ÚannotationsN)Ú	dataclassÚfield)ÚAnyÚCallableÚDictÚListÚOptional)ÚActorÚSettleReasonÚTargetState)Úoperation_session_key)ÚConnectionOperationÚDetachedOperationÚIllegalTransitionÚTarget)ÚKindÚrun_operation)Úhosted_namesÚmisrouted_to_mcp_error)Ú
tool_errorç      >@uÝ  Settled once; do not re-ask on your own for any target the user skipped or that timed out, but a later request from the USER for that same app is not a re-ask â€” run it. Connected targets' tools are available now through tool_describe/tool_call and are named under tools_listing. A target with discovery_error is authorized but its tools are unavailable; retry discovery with manage_connections using that target's authorize or install action without asking for consent again.uQ  No connection card is drawn for this turn. Show any connect_url to the user so they open it in a browser, then ask them to say when they are done. Connected targets' tools are available now through tool_describe/tool_call and are named under tools_listing. A target with discovery_error is authorized but its tools are unavailable; retry discovery with manage_connections using that target's authorize or install action without asking for consent again. Do not re-ask on your own for skipped or timed-out targets, but a later request from the USER for that same app is not a re-ask â€” run it.c                 ó<   — ddl m}  t        d„  | «       D «       «      S )Nr   ©Úlist_catalogc              3  ó4   K  — | ]  }|j                   –— Œ y ­w©N)Úname)Ú.0Úes     ú9/home/ubuntu/.hermes/hermes-agent/tools/connectors/mcp.pyú	<genexpr>z!_catalog_names.<locals>.<genexpr>0   s   è ø€ Ò1˜Q�!—&•&Ñ1ùs   ‚)Úhermes_cli.mcp_catalogr   Úsortedr   s    r!   Ú_catalog_namesr%   -   s   € Ý3äÑ1¡,£.Ô1Ó1Ð1ó    c                 ó.   — ddl m}  t         | «       «      S )Nr   ©Úinstalled_servers)r#   r)   r$   r(   s    r!   Ú_configured_namesr*   3   s   € Ý8äÑ#Ó%Ó&Ð&r&   c           
     óÚ  ‡ — 	 t        «       }t        «       }‰ dk(  rt        |«      n
t        |«      }|D �cg c]	  }||vsŒ|‘Œ }}|sy |D �cg c]  }||vsŒ||vsŒ|‘Œ }}|rFt	        «       xs
 t        «       }	|D �cg c]	  }||	v sŒ|‘Œ }
}|
rdj                  ˆ fd„|
D «       «      S ‰ dk(  rGddj                  |«      › ddj                  |«      xs d› d	�|rd
dj                  |«      › d	�z   S dz   S d‰ › ddj                  |«      › d‰ › ddj                  |«      xs d› d	�	|rddj                  |«      › d	�z   S dz   S # t        $ r}d|› �cY d }~S d }~ww xY wc c}w c c}w c c}w )Nz could not read the MCP catalog: ÚinstallÚ c              3  ó6   •K  — | ]  }t        ‰|«      –— Œ y ­wr   )r   )r   r   Úactions     €r!   r"   z%validate_mcp_names.<locals>.<genexpr>H   s   øè ø€ ÒWÀTÔ2°6¸4×@ÑWùs   ƒz#unknown MCP server(s) for install: ú, z*. Install works for catalog entries only: z(empty catalog)ú.z, Already configured (use enable/authorize): Ú zunknown MCP server(s) for z: z. z+ works for servers already in mcp_servers: z(none configured)z" Catalog entries you can install: )r%   r*   Ú	ExceptionÚsetr   Újoin)r/   ÚnamesÚcatalogÚ
configuredÚexcÚallowedÚnÚunknownÚforeignÚhostedÚ	misrouteds   `          r!   Úvalidate_mcp_namesr@   9   sÍ  ø€ ð8Ü Ó"ˆÜ&Ó(ˆ
ð %¨	Ò1Œc�'Œl´s¸:³€GØÖ4�Q 1¨GÒ#3ŠqÐ4€GÐ4ÙØØ!ÖN�Q Q¨gÒ%5¸!À:Ò:MŠqÐN€GÐNÙÜ“Ò(¤3£5ˆØ 'Ö7˜1¨1°ª;’QÐ7ˆ	Ð7ÙØ—8‘8ÓWÈYÔWÓWÐWØ�Òà1°$·)±)¸GÓ2DÐ1Eð F%Ø%)§Y¡Y¨wÓ%7Ò%LÐ;LÐ$MÈQðPáZdÐ=¸d¿i¹iÈ
Ó>SÐ=TÐTUÐVñnð	
ð kmñnð	
ð % V H¨B¨t¯y©y¸Ó/AÐ.BÀ"ÀVÀHð M#Ø#'§9¡9¨ZÓ#8Ò#OÐ<OÐ"PÐPQð	SáIPÐ/°·	±	¸'Ó0BÐ/CÀ1ÐEñ	Zðð WYñ	Zðøô% ò 8Ø1°#°Ð7Õ7ûð8üò 5ùò Oùò 8sF   ƒE ¶	EÁ EÁ	E#ÁE#ÁE#Á>	E(ÂE(Å	EÅEÅEÅEc                óD   — ddl m}  || «      }|€t        d| › d�«      ‚|S )Nr   ©Ú	get_entryzno catalog entry 'ú')r#   rC   Ú
ValueError©r   rC   Úentrys      r!   Ú_catalog_entryrH   [   s-   € Ý0á�d‹O€EØ€}ÜÐ-¨d¨V°1Ð5Ó6Ð6Ø€Lr&   c                  ó@   — e Zd ZdZd	d„Zd
d„Zdd„Zdd„Zdd„Zdd„Z	y)Ú_CatalogBackendzSThe real work behind an MCP target. One object so a caller can pass another one in.c           	     ó*  — ddl m} t        |«      j                  j                  xs g D �cg c]\  } ||j
                  «      sH|j
                  |j                  |j                  |j                  |j                  rdn|j                  dœ‘Œ^ c}S c c}w )zBThe credentials the catalog entry declares that have no value yet.r   )Úget_env_valuer2   )r   ÚpromptÚrequiredÚsecretÚdefault)
Úhermes_cli.configrL   rH   ÚauthÚenvr   rM   rN   rO   rP   )Úselfr   rL   Úspecs       r!   Úrequired_envz_CatalogBackend.required_envg   sz   € å3ô ,¨DÓ1×6Ñ6×:Ñ:Ò@¸böcàÉÐW[×W`ÑW`ÔIað Ÿ™¨d¯k©kÀtÇ}Á}ØŸ;™;¸¿º±2È$Ï,É,óXò cð 	cùò cs   ¬A!Bc                ó4   — ddl m} |j                  |d ¬«      S )Nr   ©Ú	mcp_oauth)Úclient_redirect_uri)Útools.connectorsrY   Ústart)rT   r   rY   s      r!   Ústart_oauthz_CatalogBackend.start_oautho   s   € Ý.ð �‰˜t¸ˆÓ>Ð>r&   c                óh   — t        |«      j                  }|j                  dk(  xr |j                   S )z­A catalog entry whose own OAuth the card must run. Provider-mediated OAuth is not one:
        its token comes from ``hermes auth <provider>``, so the plain probe covers it.Úoauth)rH   rR   ÚtypeÚprovider)rT   r   rR   s      r!   Úinstalls_with_oauthz#_CatalogBackend.installs_with_oauthu   s/   € ô ˜dÓ#×(Ñ(ˆØ�y‰y˜GÑ#Ò9¨D¯M©MÐ(9Ð9r&   c                óˆ   ‡— ddl m} ddlm} t	        |«      }t        ||‰«       |j                  | ||«      ‰ˆfd„¬«      S )z³Install an OAuth entry through the card's flow. The configuration is built in memory and
        lands, together with the setup values, only when ``initialize`` accepts the token.r   )Úcard_install_configrX   c                 ó   •— t        ‰ «      S r   )Ú	_save_env)rS   s   €r!   ú<lambda>z5_CatalogBackend.start_install_oauth.<locals>.<lambda>„   s   ø€ ´¸3³€ r&   )ÚcfgrS   Ú	on_commit)r#   rd   r[   rY   rH   Ú_check_declaredr\   )rT   r   rS   rd   rY   rG   s     `   r!   Ústart_install_oauthz#_CatalogBackend.start_install_oauth{   sH   ø€ õ 	?Ý.ä˜tÓ$ˆÜ˜˜e SÔ)Ø�‰˜tÑ)<¸UÓ)CÈÛ)?ð ó Að 	Ar&   c                ó²  — ddl m}m}m} ddlm}m} ddlm}m	}	 t        |«      }
t        ||
|«        ||
«      }|
j                  j                  xs g D �ch c]  }|j                  sŒ|j                  ’Œ }}|j!                  «       D ]  \  }}||vsŒ|sŒ ||||«      }Œ  |i t#         |«       xs i «      ¥|¥«      }	  |||«      xs g D �cg c]  }t%        |d   «      ‘Œ }} ||«        |	||«      st'        d|› d�«      ‚t)        |j!                  «       D ��ci c]  \  }}||v sŒ||“Œ c}}«       |S c c}w c c}w #  ||«       w xY wc c}}w )zÑProbe the entry's in-memory configuration with ephemeral credentials; save both only
        after the server answered. A failure writes nothing, so a failed reinstall keeps the
        previous configuration.r   )Úcurrent_secret_scopeÚreset_secret_scopeÚset_secret_scope)Ú_inline_non_secret_valuerd   )Ú_probe_single_serverÚ_save_mcp_serverrD   z5' was rejected: suspicious command/args configuration)Úagent.secret_scoperm   rn   ro   r#   rp   rd   Úhermes_cli.mcp_configrq   rr   rH   rj   rR   rS   rO   r   ÚitemsÚdictÚstrÚRuntimeErrorrf   )rT   r   rS   rm   rn   ro   rp   rd   rq   rr   rG   rh   rU   Úsecret_namesÚkeyÚvalueÚtokenÚtoolÚtoolsÚkÚvs                        r!   r,   z_CatalogBackend.install†   sQ  € ÷ 	bÑaßXßPä˜tÓ$ˆÜ˜˜e SÔ)Ù! %Ó(ˆð 05¯z©z¯~©~Ò/CÀÖT dÈÏË˜Ÿ	›	ÐTˆÐTØŸ)™)›+ò 	@‰JˆC�Ø˜,Ò&ª5Ù.¨s°C¸Ó?‘ð	@ñ !Ð!N¤DÑ)=Ó)?Ò)EÀ2Ó$FÐ!NÈ#Ð!NÓOˆð	&Ù/CÀDÈ#Ó/NÒ/TÐRTÖV d”S˜˜a™•\ÐVˆEÐVá˜uÔ%Ù  cÔ*Ü  4 &Ð(]Ð^Ó_Ð_Ü C§I¡I£K×E™D˜A˜q°1¸Ò3D�1�a‘4ÓEÔFØˆùò Uùò Wøá˜uÕ%üó Fs6   ÁD<Á)D<ÃE ÃEÃ&E Ä E
Ä-E
ÅE Å
Ec                ó&  — ddl m}m} ddlm}  |d«      5   |«       }|j                  d«      }t        |t        «      rt        |j                  |«      t        «      st        d|› d�«      ‚d||   d	<    ||«       ddd«       y# 1 sw Y   yxY w)
zöFlip ``enabled`` under the scope and lock the dashboard's toggle route uses
        (``PUT /api/mcp/servers/{name}/enabled``): the two read-modify-write paths run in one
        process, so an unserialised write here drops whichever landed first.r   )Úload_configÚsave_config)Úconfig_write_scopeNÚmcp_serversrD   z ' is not a configured MCP serverTÚenabled)	rQ   r‚   rƒ   Úhermes_cli.web_routers._commonr„   ÚgetÚ
isinstancerv   rE   )rT   r   r‚   rƒ   r„   ÚconfigÚserverss          r!   Úenablez_CatalogBackend.enable¡   s„   € ÷ 	?ÝEá Ó%ñ 	 Ù “]ˆFØ—j‘j Ó/ˆGÜ˜g¤tÔ,´J¸w¿{¹{È4Ó?PÔRVÔ4WÜ  1 T FÐ*JÐ!KÓLÐLØ'+ˆG�D‰M˜)Ñ$Ù˜Ô÷	 ÷ 	 ñ 	 ús   —A'BÂBN)r   rw   ÚreturnúList[Dict[str, Any]])r   rw   r�   r   )r   rw   r�   Úbool)r   rw   rS   úDict[str, str]r�   r   )r   rw   rS   r�   r�   ú	List[str])r   rw   r�   ÚNone)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__rV   r]   rb   rk   r,   rŒ   © r&   r!   rJ   rJ   d   s%   „ Ù]ócó?ó:ó	Aóô6 r&   rJ   c                óÄ   — ddl m} |j                  j                  xs g D �ch c]  }|j                  ’Œ }}|D ]  }||vrt        d| › d|› �«      ‚ ||«       Œ! yc c}w )z“Configuring one MCP is not a general env-writing primitive: refuse the whole map before the
    first write if any key is undeclared or unwritable.r   )Úvalidate_env_var_name_for_writerD   z,' does not declare the environment variable N)rQ   r™   rR   rS   r   rE   )r   rG   rS   r™   rU   Údeclaredrz   s          r!   rj   rj   ±   sk   € õ Bà',§z¡z§~¡~Ò';¸Ö=˜d�—	“	Ð=€HÐ=Øò -ˆØ�hÑÜ˜q  Ð&RÐSVÐRWÐXÓYÐYÙ'¨Õ,ñ-ùò >s   £Ac                óX   — ddl m} | j                  «       D ]  \  }}|sŒ	 |||«       Œ y )Nr   )Úsave_env_value)rQ   rœ   ru   )rS   rœ   rz   r{   s       r!   rf   rf   ½   s+   € Ý0à—i‘i“kò '‰
ˆˆUÚÙ˜3 Õ&ñ'r&   c                 ó   — t        «       S r   )rJ   r—   r&   r!   Ú_default_backendrž   Å   s   € ÜÓÐr&   c                  óz   — e Zd ZU dZdZded<    eej                  ¬«      Z	ded<    ee
¬«      Zded	<   d
Zded<   y)Ú_WorkzWOne target's work in flight: an OAuth attempt the watcher polls, or a worker's outcome.Nr   Úattempt)Údefault_factoryzthreading.EventÚdoner‘   r~   r2   rw   Úerror)r“   r”   r•   r–   r¡   Ú__annotations__r   Ú	threadingÚEventr£   Úlistr~   r¤   r—   r&   r!   r    r    Î   s:   … áaà€GˆSÓÙ!°)·/±/ÔB€Dˆ/ÓBÙ¨TÔ2€Eˆ9Ó2Ø€Eˆ3„Or&   r    c                  óR   — e Zd ZdZd
d„Z	 d	 	 	 dd„Zdd„Zdd„Zdd„Zdd„Z	dd	„Z
y)Ú_Runnerz6The backend plus the work for one operation's targets.c                óJ   — || _         || _        d | _        i | _        i | _        y r   )r/   ÚbackendÚop_idÚworkÚapproved_env)rT   r/   r¬   s      r!   Ú__init__z_Runner.__init__Û   s(   € ØˆŒØˆŒØ$(ˆŒ
Ø&(ˆŒ	ð
 8:ˆÕr&   Nc                ó<   —  || j                      | |||xs i «       y r   )r/   )rT   ÚtableÚ	operationÚtargetrS   s        r!   Úrunz_Runner.runæ   s   € àˆˆd�k‰kÑ˜4 ¨F°C²I¸2Õ>r&   c           	     ó”  ‡ ‡‡‡‡— ‰j                   r,t        j                  d‰ j                  ‰j                  «       yt        «       Š‰‰ j                  ‰j                  <   dˆˆˆ ˆˆfd„}t        j                  t        j                  «       j                  |fdd‰ j                  › d‰j                  › �¬«      j                  «        y)	zRRun one blocking backend call on a worker thread; ``observe`` reports its outcome.z3mcp %s %s: not started, the operation settled firstNc                 ó˜  •— g } d}	  ‰«       xs g D �cg c]  }t        |«      ‘Œ } }‰j                  r,t        j                  d‰j                  ‰j                  «       y | |c‰_        ‰_	        ‰j                  j                  «        ‰j                  j                  «        y c c}w # t        $ r}t        |‰‰«      }Y d }~Œœd }~ww xY w)Nr2   z7mcp %s %s: outcome dropped, the operation settled first)rw   r3   Ú_detailÚsettledÚloggerÚdebugr/   r   r~   r¤   r£   r4   Úwake)	r~   r¤   r   r9   Úcallr³   rT   r´   r®   s	       €€€€€r!   Úbodyz_Runner.spawn.<locals>.bodyò   s©   ø€ Ø!ˆEØˆEð3Ù04³²¸"Ö> tœ˜T�Ð>�Ð>ð × Ò ä—‘ÐVØ!Ÿ[™[¨&¯+©+ô7àØ%*¨EÐ"ˆDŒJ˜œ
Ø�I‰I�M‰MŒOØ�N‰N×ÑÕ ùò ?øÜò 3Ü  T¨6Ó2•ûð3ús'   ‡B) ”B$¦B) Â$B) Â)	C	Â2CÃC	Túmcp-Ú-©r´   ÚargsÚdaemonr   ©r�   r’   )r¹   rº   r»   r/   r   r    r®   r¦   ÚThreadÚcontextvarsÚcopy_contextrµ   r\   )rT   r³   r´   r½   r¾   r®   s   ```` @r!   Úspawnz_Runner.spawnê   s™   ü€ à×ÒÜ�L‰LÐNÐPT×P[ÑP[Ð]c×]hÑ]hÔiØÜ‹wˆØ!%ˆ�	‰	�&—+‘+Ñ÷	!ñ 	!ô$ 	×Ñ¤× 8Ñ 8Ó :× >Ñ >ÀdÀWÐUYØ $ T§[¡[ M°°6·;±;°-Ð@ô	BßBGÁ%Å'r&   c                ó  — | t         |j                  <   |j                  | _        || _        | j                  dk(  r*t	        |j
                  «      dkD  r| j                  |«       y |j
                  D ]  }| j                  t        ||«       Œ y )NÚ	authorizeé   )	Ú_RUNNERSr­   r³   r/   ÚlenÚtargetsÚ_prepare_togetherrµ   Ú_PREPARE©rT   r³   r´   s      r!   Úpreparez_Runner.prepare  sv   € Ø$(Œ�—‘Ñ!Ø—_‘_ˆŒ
Ø"ˆŒØ�;‰;˜+Ò%¬#¨i×.?Ñ.?Ó*@À1Ò*DØ×"Ñ" 9Ô-ØØ×'Ñ'ò 	2ˆFØ�H‰H”X˜y¨&Õ1ñ	2r&   c           
     ó¶  — |j                   D �cg c]V  }t        j                  t        j                  «       j
                  | j
                  t        ||fdd|j                  › �¬«      ‘ŒX }}|D ]  }|j                  «        Œ t        j                  «       t        z   }|D ]2  }|j                  t        d|t        j                  «       z
  «      «       Œ4 yc c}w )a2  Start every OAuth flow at once and wait for the URLs once. Each flow blocks until its
        provider publishes an authorization URL, so a sequential prepare would keep the card empty
        for one wait per target.

        The wait bounds how long prepare blocks, not how long a provider may take: a row still
        pending afterwards is left to its own thread, which is the only writer of that row and
        ends with the URL or the flow's own failure. Failing it here as well would make two
        writers of one row, and a URL that arrives a moment later would have no row to land on.

        Each thread runs in its own copy of the calling thread's context: a named-profile turn
        binds its home through a contextvar, and the flow resolves ``mcp_servers`` and stores the
        token by that home.Tzmcp-prepare-rÁ   g        N)rÎ   r¦   rÅ   rÆ   rÇ   rµ   rÐ   r   r\   ÚtimeÚPREPARE_WAIT_SECONDSr5   Úmax)rT   r³   r´   ÚthreadsÚthreadÚdeadlines         r!   rÏ   z_Runner._prepare_together  sÈ   € ð V_×UfÑUföhàKQô ×#Ñ#¬;×+CÑ+CÓ+E×+IÑ+IØ*.¯(©(´H¸iÈÐ)PÐY]Ø+7¸¿¹°}Ð)EöGð hˆð hð ò 	ˆFØ�L‰L�Nð	ä—9‘9“;Ô!5Ñ5ˆØò 	:ˆFØ�K‰Kœ˜C ¬D¯I©I«KÑ!7Ó8Õ9ñ	:ùòhs   �ACc                óÌ   — |j                   D ]U  }|j                  s,|j                  t        j                  t        j
                  fvrŒ<t        | j                     | ||«       ŒW y r   )rÎ   r¹   Ústater   ÚpendingÚ	initiatedÚ_OBSERVEr/   rÑ   s      r!   Úobservez_Runner.observe'  sT   € Ø×'Ñ'ò 	;ˆFà× Ò  F§L¡L¼×9LÑ9LÌk×NcÑNcÐ8dÑ$dØÜ�T—[‘[Ñ! $¨	°6Õ:ñ		;r&   c                óø  — | j                   � t        j                  | j                   d«       t        | dd«      }t	        | j
                  j                  «       «      D ]�  \  }}|j                  �|€Œ|j                  t        j                  k(  r#ddlm}  ||j                  j                  «       ŒU|j                  t        j                  |j                   i «      |<   Œƒ | j
                  j#                  «        y)a  The operation is over. An attempt still waiting on the browser is stopped when the user
        ended the turn, and otherwise left to finish: the card closed, not the authorization. What
        it commits is picked up before the session's next turn (``adopt_late_connections``).Nr³   r   ©Úcancel_attempt)r­   rÌ   ÚpopÚgetattrr¨   r®   ru   r¡   Ú
settled_byr   Ú	interruptÚtools.connectors.mcp_oauthrâ   ÚflowÚ_LATE_ATTEMPTSÚ
setdefaultÚsession_keyÚclear)rT   r³   r   r®   râ   s        r!   Úclosez_Runner.close.  s¿   € ð �:‰:Ð!Ü�L‰L˜Ÿ™ TÔ*Ü˜D +¨tÓ4ˆ	Ü˜tŸy™yŸ™Ó0Ó1ò 	Z‰JˆD�$Ø�|‰|Ð# yÐ'8ØØ×#Ñ#¤|×'=Ñ'=Ò=ÝEá˜tŸ|™|×0Ñ0Õ1àMQÏ\É\”×)Ñ)¨)×*?Ñ*?ÀÓDÀTÒJð	Zð 	�	‰	�‰Õr&   )r/   rw   r¬   r   r   )
r²   zDict[str, Callable]r³   r   r´   r   rS   zOptional[Dict[str, str]]r�   r’   )r³   r   r´   r   r½   zCallable[[], Any]r�   r’   )r³   r   r�   r’   rÄ   )r“   r”   r•   r–   r°   rµ   rÈ   rÒ   rÏ   rß   rí   r—   r&   r!   rª   rª   Ø   s>   „ Ù@ó	:ð -1ð?Ø)ð?Ø59ó?óJó:2ó:ó,;ôr&   rª   zDict[str, Dict[str, Any]]ré   c                ó¤  ‡
— t        t        | dd«      «      }t        j                  |«      }|sg S g }t	        |j                  «       «      D ]˜  \  }}|j                  «       }|d   dk(  rŒ|j                  |d«       |d   dk7  s|j                  d«      rŒK	 ddlm	} dd	l
m}  |«       j                  |«      }	t        |	t        «      r |||	i«       |j                  |«       Œš |st        j                  |d«       t        | dd«      Š
|r‰
�d‰
vrg ‰
¢ˆ
fd„|D «       ¢| _        |S # t        $ r t         j#                  d
|d¬«       Y �Œw xY w)zöRegister the servers whose authorization committed after their card had closed, and add
    them to the agent's toolset selection. Runs between turns, so the result that said "not
    connected" is followed by a turn in which the tools are there.Ú
session_idNÚstatusrÜ   ÚapprovedÚdiscovery_errorr   ©Ú_load_mcp_config©Úregister_mcp_serversz&late MCP connection %s was not adoptedT)Úexc_infoÚenabled_toolsetsÚno_mcpc              3  ó,   •K  — | ]  }|‰vsŒ|–— Œ y ­wr   r—   )r   r;   r†   s     €r!   r"   z)adopt_late_connections.<locals>.<genexpr>c  s   øè ø€ Ò-U°AÀAÈWÒDT¬aÑ-Uùs   ƒ	�)r   rä   ré   rˆ   r¨   ru   Úpollrã   Útools.mcp_tool_configrô   Útools.mcp_tool_discoveryrö   r‰   rv   Úappendr3   rº   r»   rø   )Úagentrë   ÚattemptsÚadoptedr   r¡   Úsnapshotrô   rö   rŠ   r†   s             @r!   Úadopt_late_connectionsr  E  sT  ø€ ô (¬°°|ÀTÓ(JÓK€KÜ×!Ñ! +Ó.€HÙØˆ	Ø€GÜ˜hŸn™nÓ.Ó/ò X‰ˆˆgØ—<‘<“>ˆØ�HÑ Ò*ØØ�‰�T˜4Ô Ø�HÑ Ò+¨x¯|©|Ð<MÔ/NØð		XÝ>ÝEá%Ó'×+Ñ+¨DÓ1ˆFÜ˜&¤$Ô'Ù$ d¨F ^Ô4Ø—‘˜tÔ$øðXñ" Ü×Ñ˜;¨Ô-Ü�eÐ/°Ó6€GÙ�7Ð&¨8¸7Ñ+BØ!V 7Ð!VÓ-U¸Ô-UÐ!VˆÔØ€Nøô ò 	XÜ�L‰LÐAÀ4ÐRVˆL×Wð	Xús   ÂAD*Ä*!EÅEzDict[str, _Runner]rÌ   c                ó2   — t        | |xs
 t        «       «      S )u¶   The runner for one MCP operation. ``prepare`` binds it to the operation, so the card's
    answer and its Try again â€” both of which arrive on another thread â€” find the same work.)rª   rž   )r/   r¬   s     r!   Úopen_runnerr  k  s   € ô �6˜7Ò8Ô&6Ó&8Ó9Ð9r&   zKtool discovery was interrupted; run the same action again to list the toolsz!the server did not answer in time)ÚCancelledErrorÚTimeoutErrorc                ó¬  — ddl m} t        | «      xsP t        | t        «      r>t
        j                  | j                  j                  | j                  j                  «      nd}t
        j                  ||«      }|j                  j                  |j                  i «      j                  «       D ]  }|sŒ|j                  |d«      }Œ  ||d¬«      xs dS )zïThe user-facing text of a failure. Every value the card submitted for this target is
    replaced by exact match before the pattern redactor runs: an opaque credential has no
    recognizable shape, so only the runner knows what to remove.r   )Úredact_sensitive_textr¤   z
[REDACTED]T)Úforce)Úagent.redactr	  rw   r‰   ÚBaseExceptionÚ_BARE_ERRORSrˆ   Ú	__class__r“   r¯   r   ÚvaluesÚreplace)r9   Úrunnerr´   r	  Útextr{   s         r!   r¸   r¸   x  s´   € õ 3äˆs‹8ò HÜ% c¬=Ô9ô %×(Ñ(¨¯©×)?Ñ)?ÀÇÁ×AWÑAWÔXØ?Fð 	ä×Ñ˜D $Ó'€DØ×$Ñ$×(Ñ(¨¯©°bÓ9×@Ñ@ÓBò 5ˆÚØ—<‘<  |Ó4‰Dð5ñ ! ¨TÔ2Ò=°gÐ=r&   c                óX   — ddl m}  || «      }|�t        |j                  xs d«      S dS )z]The manifest's ``post_install`` text for a catalog name; a custom configured server has none.r   rB   r2   )r#   rC   rw   Úpost_installrF   s      r!   Ú_catalog_instructionsr  ‡  s.   € å0á�d‹O€EØ,1Ð,=Œ3ˆu×!Ñ!Ò' RÓ(ÐEÀ2ÐEr&   c                óÒ   — 	  | j                   |j                  ||fi |¤Ž y# t        $ r; | j                  s‚ t        j                  d|j                  |j                  «       Y yw xY w)aR  Move one target from the prepare, worker-outcome or observe path.

    Continue on the RPC thread can settle the operation between any read of the target's state and
    this call. A settled operation has a frozen result, so the lost move is dropped rather than
    raised into the tool result; anything else is a real contract violation.Tz6mcp target %s: %s dropped, the operation settled firstF)Ú
transitionr   r   r¹   rº   r»   r{   )r³   r´   ÚtoÚactorÚfieldss        r!   Ú_mover  �  sa   € ðØˆ	×Ñ˜VŸ[™[¨"¨eÑ>°vÒ>ØøÜò Ø× Ò ØÜ�‰ÐMÈvÏ{É{Ð\^×\dÑ\dÔeÙð	ús   ‚" ¢AA&Á%A&c                óZ  — | j                   r!t        j                  d|j                  «       y|j                  t
        j                  k(  r.| j                  |j                  d|t        j                  ¬«       yd|_
        t        | |t
        j                  t        j                  |¬«       y)zrReport a failure, whatever the row was doing: a repeated failure has no state change to
    emit, only newer text.z;mcp target %s: failure dropped, the operation settled firstN)Úconnect_urlÚdetailr  ©r  )r¹   rº   r»   r   rÛ   r   ÚfailedÚrefreshr   Úbackend_watcherr  r  )r³   r´   r  s      r!   Ú_failr#  Ÿ  s€   € ð ×ÒÜ�‰ÐRÐTZ×T_ÑT_Ô`ØØ‡|�|”{×)Ñ)Ò)Ø×Ñ˜&Ÿ+™+°4ÀÌe×NcÑNcÐÔdØØ€FÔÜ	ˆ)�Vœ[×/Ñ/´×1FÑ1FÈvÖVr&   c                óþ   — 	 ddl m} ddlm}  |«       j	                  |«      }t        |t        «      st        d|› d�«      ‚ |||i«       t        |«      dfS # t        $ r}g t        || |«      fcY d}~S d}~ww xY w)zYRegister one committed server in the current profile scope and report its callable names.r   ró   rõ   z$no committed MCP configuration for 'rD   r2   N)rü   rô   rý   rö   rˆ   r‰   rv   rx   Ú_registered_tool_namesr3   r¸   )r  r´   r   rô   rö   rŠ   r9   s          r!   Ú_register_connectedr&  ¬  s   € ð
0Ý:ÝAá!Ó#×'Ñ'¨Ó-ˆÜ˜&¤$Ô'ÜÐ!EÀdÀVÈ1ÐMÓNÐNÙ˜d F˜^Ô,Ü% dÓ+¨RÐ/Ð/øÜò 0Ø”7˜3 ¨Ó/Ð/Õ/ûð0ús   ‚AA Á	A<Á#A7Á1A<Á7A<c                óÀ  — ddl m} ddlm} ddlm} ddlm}  || «      }t        j                  «       |z   }d}	 |j                  d| › �«      }	|	st        j                  «       |k\  r|	S ||j                  vrR|j                  j                  |«      }
|
d	uxr t        |
d
d	«      d	uxr t        |
d«      }|r|	S |s
|
� || «      s|	S d}t        j                  d«       Œ¥)a;  The server's callable names, read from the registry once its registration has finished.

    Registration is a no-op for a server the process already holds, and that includes one another
    task is still connecting: saving the configuration wakes the config watcher, which starts its
    own connect, so a large server (hundreds of tools) was reported with no tools three seconds
    before they were registered. A server that failed discovery earlier is parked with no tools
    and is woken once. A server that finished registering with no tools is a valid empty list.r   )Úmcp_tool)Úreconnect_mcp_server)Ú_resolve_server_key)ÚregistryFTr¿   NÚsessionr%  g      Ð?)r~   r(  Útools.mcp_tool_loopr)  Útools.mcp_tool_scoper*  Útools.registryr+  rÔ   Úget_tool_names_for_toolsetÚ_server_connectingÚ_serversrˆ   rä   ÚhasattrÚsleep)r   Úwait_secondsÚ_corer)  r*  r+  rz   rÙ   Úwokenr6   ÚserverÚfinisheds               r!   r%  r%  »  sä   € õ (Ý8Ý8Ý'á
˜dÓ
#€CÜ�y‰y‹{˜\Ñ)€HØ€EØ
Ø×3Ñ3°d¸4¸&°MÓBˆÙ”D—I‘I“K 8Ò+ØˆLØ�e×.Ñ.Ñ.Ø—^‘^×'Ñ'¨Ó,ˆFØ TÐ)ò >¬g°f¸iÈÓ.NÐVZÐ.Zò >Ü˜FÐ$<Ó=ð áØ�Ù˜˜Ñ.BÀ4Ô.HØ�ØˆEÜ�
‰
�4Ôð r&   c                óp   — d|i}|r||d<   t        | |t        j                  t        j                  fi |¤Ž y )Nr~   rò   )r  r   Ú	connectedr   r"  )r³   r´   r~   rò   Úextras        r!   Ú_connectr=  Û  s9   € Ø$ eÐ,€EÙØ#2ˆÐÑ Ü	ˆ)�Vœ[×2Ñ2´E×4IÑ4IÑSÈUÓSr&   c                ó|   — | j                   t        j                  k(  rt        j                  S t        j
                  S )z?Try again is the user's move; a first attempt is the backend's.)rÛ   r   r   r   Úuserr"  )r´   s    r!   Ú_actorr@  â  s(   € àŸ™¬×);Ñ);Ò;Œ5�:‰:ÐVÄ×AVÑAVÐVr&   c                ó¤  — t        |«      }t        |j                  «      |_        	 | j                  j                  |j                  «      }t        |¬«      | j                  |j                  <   t        ||t        j                  ||j                  t        |dd«      ¬«       y # t        $ r"}t        ||t        || |«      «       Y d }~y d }~ww xY w)N©r¡   r  r2   ©r  r  )r@  r  r   Úinstructionsr¬   r]   r3   r#  r¸   r    r®   r  r   rÝ   Úauth_urlrä   )r  r³   r´   rS   r  r¡   r9   s          r!   Ú_start_oauthrF  ç  s¦   € Ü�6‹N€EÜ/°·±Ó<€FÔðØ—.‘.×,Ñ,¨V¯[©[Ó9ˆô  %¨WÔ5€F‡K�K�—‘ÑÜ	ˆ)�Vœ[×2Ñ2°EÀw×GWÑGWÜ˜ (¨BÓ/ö1øô	 ò Üˆi˜¤¨¨f°fÓ!=Ô>Üûðús   §%B$ Â$	CÂ-C
Ã
Cc           
     óî   — t        |j                  «      |_        	 | j                  j	                  |j                  «      }||_        y# t
        $ r"}t        ||t        || |«      «       Y d}~yd}~ww xY w)zTThe install row waits pending; the card draws a field per credential it still needs.N)r  r   rD  r¬   rV   r3   r#  r¸   )r  r³   r´   rS   rN   r9   s         r!   Ú_declare_envrH  ô  sd   € ä/°·±Ó<€FÔðØ—>‘>×.Ñ.¨v¯{©{Ó;ˆð #€FÕøô ò Üˆi˜¤¨¨f°fÓ!=Ô>Üûðús   œ%A	 Á		A4ÁA/Á/A4c           
     óô   — | j                   j                  |j                  «      }|D �cg c]C  }|j                  dd«      r/|j                  t	        |j                  d«      xs d«      «      s|‘ŒE c}S c c}w )z³The declared credentials that still have no value. The install runs on a worker thread,
    where ``install_entry``'s prompt for a missing credential would block on stdin forever.rN   Tr   r2   )r¬   rV   r   rˆ   rw   )r  r´   rS   rš   rU   s        r!   Ú_missing_requiredrJ  ÿ  sl   € ð �~‰~×*Ñ*¨6¯;©;Ó7€HØ%ö X�TØ�x‰x˜
 DÔ)°#·'±'¼#¸d¿h¹hÀvÓ>NÒ>TÐRTÓ:UÔ2Vò ò Xð Xùò Xs   ªAA5c           
     ó„  ‡ ‡‡— i ‰ j                   j                  ‰j                  i «      ¥|¥Š	 t        ‰ ‰‰«      }|rX|‰_        |j                  ‰j                  ‰j                  t        j                  ddj                  d„ |D «       «      › �¬«       y ‰‰ j                   ‰j                  <   t        ‰«      }g ‰_        t        |‰t        j                   |d¬«      sy t#        ‰ ‰«      rt%        ‰ |‰‰«       y ‰ j'                  |‰ˆˆ ˆfd„«       y # t        $ r"}t        |‰t        |‰ ‰«      «       Y d }~y d }~ww xY w)Nzwaiting for r0   c              3  ó8   K  — | ]  }t        |d    «      –— Œ y­w)r   N)rw   )r   rU   s     r!   r"   z!_start_install.<locals>.<genexpr>  s   è ø€ Ò9`ÐPT¼#¸dÀ6¹l×:KÑ9`ùs   ‚©r  r  r  r2   r  c                 óP   •— ‰j                   j                  ‰j                  ‰ «      S r   )r¬   r,   r   )rñ   r  r´   s   €€€r!   rg   z _start_install.<locals>.<lambda>  s   ø€ ¨F¯N©N×,BÑ,BÀ6Ç;Á;ÐPXÓ,Y€ r&   )r¯   rˆ   r   rJ  r3   r#  r¸   rV   r!  r  r   r"  r5   r@  r  r   rÝ   Ú_installs_with_oauthÚ_start_install_oauthrÈ   )r  r³   r´   rS   Úmissingr9   r  rñ   s   ` `    @r!   Ú_start_installrR    s'  ú€ ØB�&×%Ñ%×)Ñ)¨&¯+©+°rÓ:ÐB¸cÐB€HðÜ# F¨F°HÓ=ˆñ ð &ˆÔØ×Ñ˜&Ÿ+™+°6×3EÑ3EÌU×MbÑMbØ#/°·	±	Ñ9`ÐX_Ô9`Ó0`Ð/aÐ!bð 	ô 	dàØ'/€F×Ñ˜Ÿ™Ñ$Ü�6‹N€EØ€FÔÜ�˜F¤K×$9Ñ$9¸5ÈÕLØÜ˜F FÔ+Ü˜V Y°¸ÔAØØ
‡L�L�˜FÕ$YÕZøô% ò Üˆi˜¤¨¨f°fÓ!=Ô>Üûðús   ¯D Ä	D?ÄD:Ä:D?c                ó~   — 	 t        | j                  j                  |j                  «      «      S # t        $ r Y yw xY w)NF)r�   r¬   rb   r   r3   )r  r´   s     r!   rO  rO     s7   € ðÜ�F—N‘N×6Ñ6°v·{±{ÓCÓDÐDøÜò Ùðús   ‚-0 °	<»<c           
     ó~  — 	 | j                   j                  |j                  |«      }t        |¬«      | j                  |j                  <   |j                  ry|j                  |j                  |j                  t        j                  t        |dd«      ¬«       y# t        $ r}t	        | |||«       Y d}~yd}~ww xY w)z¥The row is already ``initiated``; publish the authorization link onto it. The same
    ``initiated`` + ``connect_url`` pair is what every card reads as its URL step.NrB  r  r2   rM  )r¬   rk   r   r3   Ú_fail_installr    r®   r¹   r!  rE  r   r"  rä   )r  r³   r´   rS   r¡   r9   s         r!   rP  rP  '  sž   € ðØ—.‘.×4Ñ4°V·[±[À#ÓFˆô  %¨WÔ5€F‡K�K�—‘ÑØ×ÒØØ×Ñ�f—k‘k¨w×/?Ñ/?Äu×G\ÑG\Ü$ W¨h¸Ó;ð õ =øô ò Ü�f˜i¨°Ô5Üûðús   ‚&B Â	B<Â$B7Â7B<c           	     óä   — t        j                  t        «      5  | j                  j	                  |j
                  «      |_        ddd«       t        ||t        || |«      «       y# 1 sw Y   Œ"xY w)z¤A failed install asks for its fields again, so the card can reopen the form over the draft
    it kept. Nothing was saved, so every declared field is still missing.N)Ú
contextlibÚsuppressr3   r¬   rV   r   r#  r¸   )r  r³   r´   r¤   s       r!   rU  rU  7  s[   € ô 
×	Ñ	œYÓ	'ñ GØ$Ÿn™n×9Ñ9¸&¿+¹+ÓFˆÔ÷Gä	ˆ)�VœW U¨F°FÓ;Õ<÷Gð Gús   š+A&Á&A/c           
     óP  — t        |«      }t        ||t        j                  |d¬«      sy 	 | j                  j                  |j                  «       t        | ||j                  «      \  }}t        ||||«       y # t        $ r"}t        ||t        || |«      «       Y d }~y d }~ww xY w)Nr2   r  )r@  r  r   rÝ   r¬   rŒ   r   r3   r#  r¸   r&  r=  )r  r³   r´   rS   r  r9   r~   rò   s           r!   Ú
_do_enablerZ  ?  s�   € Ü�6‹N€EÜ�˜F¤K×$9Ñ$9¸5ÈÕLØðØ�‰×Ñ˜fŸk™kÔ*ô 1°¸ÀÇÁÓMÑ€Eˆ?ÜˆY˜  Õ7øô	 ò Üˆi˜¤¨¨f°fÓ!=Ô>Üûðús   ¬%A: Á:	B%ÂB Â B%c                ó  — 	 | j                   j                  |j                  «      D �cg c]  }|j                  dd«      sŒ|d   ‘Œ }}|r/ddlm} t        ||ddj                  |«      › d	 |«       › d
�«       yt        |«      }t        | |«      r	 | j                   j                  |j                  i «      }	t        |	¬«      | j                  |j                  <   t        ||t         j"                  ||	j$                  t'        |	dd«      ¬«       yt        ||t         j"                  |«       	 | j                   j)                  |j                  i «       t+        | ||j                  «      \  }
}t-        |||
|«       yc c}w # t        $ r"}t        ||t        || |«      «       Y d}~yd}~ww xY w# t        $ r"}t        ||t        || |«      «       Y d}~yd}~ww xY w# t        $ r"}t        ||t        || |«      «       Y d}~yd}~ww xY w)zPOff the desktop nobody can fill a credential in, so a missing one is the answer.rN   Tr   Nr   )Údisplay_hermes_homezset r0   z in the environment or z/.env, then install againrB  r  r2   rC  )r¬   rV   r   rˆ   r3   r#  r¸   Úhermes_constantsr\  r5   r@  rO  rk   r    r®   r  r   rÝ   rE  rä   r,   r&  r=  )r  r³   r´   rS   rU   rQ  r9   r\  r  r¡   r~   rò   s               r!   Ú_install_nowr^  L  sÐ  € ðØ,2¯N©N×,GÑ,GÈÏÉÓ,TÖs DÐX\×X`ÑX`ÐakÐmqÕXr�4˜“<ÐsˆÐsñ Ý8äˆi˜ 4¨¯	©	°'Ó(:Ð';Ð;RÙ$7Ó$9Ð#:Ð:Sð"Uô 	VàÜ�6‹N€EÜ˜F FÔ+ð	Ø—n‘n×8Ñ8¸¿¹ÀbÓIˆGô $)°Ô#9ˆ�‰�F—K‘KÑ Üˆi˜¤×!6Ñ!6¸È7×K[ÑK[Ü˜W h°Ó3õ	5àÜ	ˆ)�Vœ[×2Ñ2°EÔ:ðØ�‰×Ñ˜vŸ{™{¨BÔ/ô 1°¸ÀÇÁÓMÑ€Eˆ?ÜˆY˜  Õ7ùò; tøÜò Üˆi˜¤¨¨f°fÓ!=Ô>Üûðûô ò 	Ü�)˜V¤W¨S°&¸&Ó%AÔBÜûð	ûô ò Üˆi˜¤¨¨f°fÓ!=Ô>Üûðús^   ‚'F ©E=ÁE=ÁF Â&F0 Ä.&G Å=F Æ	F-ÆF(Æ(F-Æ0	GÆ9GÇGÇ	H	Ç'HÈH	c           
     ól  — | j                   j                  |j                  «      }|�|j                  €y |j                  j	                  «       }|j                  d«      }|dvry | j                   j                  |j                  d «       |dk(  rZ|j                  d«      xs d}|rt        ||g t        || |«      «       y t        | ||j                  «      \  }}t        ||||«       y |j                  d«      xs d}	| j                  dk(  rt        | |||	«       y t        ||t        |	| |«      «       y )	Nrð   )rñ   r¤   rñ   rò   r2   r¤   zthe authorization flow failedr,   )r®   rˆ   r   r¡   rû   rã   r=  r¸   r&  r/   rU  r#  )
r  r³   r´   r®   r  rð   rò   r~   Úregistration_errorr¤   s
             r!   Ú_observe_oauthra  o  s  € Ø�;‰;�?‰?˜6Ÿ;™;Ó'€DØ€|�t—|‘|Ð+ØØ�|‰|× Ñ Ó"€HØ�\‰\˜(Ó#€FØÐ*Ñ*ØØ
‡K�K‡O�O�F—K‘K Ô&Ø�ÒØ"Ÿ,™,Ð'8Ó9Ò?¸RˆÙÜ�Y ¨¬G°OÀVÈVÓ,TÔUð 	ô )<¸FÀFÈFÏKÉKÓ(XÑ%ˆEÐ%Ü�Y ¨Ð/AÔBØØ�L‰L˜Ó!ÒDÐ%D€EØ‡}�}˜	Ò!Ü�f˜i¨°Ô7ØÜ	ˆ)�VœW U¨F°FÓ;Õ<r&   c                ó–   — | j                   j                  |j                  «      }|�|j                  �t        nt
        } || ||«       y)zSAn install is an OAuth attempt for an OAuth entry and a worker for every other one.N)r®   rˆ   r   r¡   ra  Ú_observe_worker)r  r³   r´   r®   rß   s        r!   Ú_observe_installrd  ‡  s:   € à�;‰;�?‰?˜6Ÿ;™;Ó'€DØ $Ð 0°T·\±\Ð5M�nÔSb€GÙˆF�I˜vÕ&r&   c           	     óÒ  — | j                   j                  |j                  «      }|�|j                  j	                  «       sy | j                   j                  |j                  d «       |j                  rK| j                  dk(  rt        | |||j                  «       y t        ||t        |j                  | |«      «       y t        | ||j                  «      \  }}t        ||||«       y )Nr,   )r®   rˆ   r   r£   Úis_setrã   r¤   r/   rU  r#  r¸   r&  r=  )r  r³   r´   r®   r~   rò   s         r!   rc  rc  Ž  s®   € Ø�;‰;�?‰?˜6Ÿ;™;Ó'€DØ€|˜4Ÿ9™9×+Ñ+Ô-ØØ
‡K�K‡O�O�F—K‘K Ô&Ø‡z‚zØ�=‰=˜IÒ%Ü˜& )¨V°T·Z±ZÔ@ØÜˆi˜¤¨¯©°V¸VÓ!DÔEØÜ0°¸ÀÇÁÓMÑ€Eˆ?ÜˆY˜  Õ7r&   c                 ó   — y)zSAuthorize needs no approval: the row's verb opens the link the flow already minted.Nr—   )r  r³   r´   rS   s       r!   Ú_nothingrh  �  s   � r&   )rÊ   r,   rŒ   c                óÀ   — | j                  d«      }t        |t        «      r6|j                  «       D ��ci c]  \  }}t	        |«      t	        |«      “Œ c}}S i S c c}}w )NrS   )rˆ   r‰   rv   ru   rw   )rG   Úrawr   r€   s       r!   Ú_answer_envrk  ­  sI   € Ø
�)‰)�EÓ
€CÜ7AÀ#ÄtÔ7L s§y¡y£{×3™t˜q !ŒC�‹F”C˜“F‰NÓ3ÐTÐRTÐTùÓ3s   µAc           	     óè  — 	 t        j                  |«      }t	        |t
        «      si }t        j                  | j                  «      }|j                  d«      xs dD �]x  }t	        |t
        «      sŒ| j                  t        |j                  d«      xs d«      j                  «       j                  «       «      }|€Œat        |j                  d«      xs d«      j                  «       }|dk(  rOt        ||«      }	  | j                  |j                  t         j"                  t$        j&                  fi |rd|ini ¤Ž Œá|d	k(  sŒç|€Œê|j.                  t         j0                  k(  r#|j3                  t4        | |t7        |«      «       �Œ*|j.                  t         j8                  t         j:                  fv s�ŒX|j3                  t<        | |t7        |«      «       �Œ{ |j                  d
«      t>        j@                  jB                  k(  r-| jD                  s | jG                  t>        j@                  «       yyy# t        t        f$ r i }Y �Œ0w xY w# t(        $ r |j*                  s| j,                  s‚ Y �Œw xY w)zÑFold the card's ``connection.respond`` payload into the operation: a skip, an approval that
    starts the backend's work, and Continue. The card never reports an outcome, so any other claim
    moves nothing.rÎ   r—   r   r2   Nrð   Úskippedr  rñ   rå   )$ÚjsonÚloadsÚ	TypeErrorrE   r‰   rv   rÌ   rˆ   r­   r´   rw   ÚstripÚlowerÚ_cancel_attemptr  r   r   rm  r   r?  r   Úresolvedr¹   rÛ   rÜ   rµ   Ú_APPROVErk  r   ÚexpiredÚ_RETRYr   Ú	continue_r{   Úall_resolvedÚsettle)r³   rj  Úanswerr  rG   r´   rð   Úkepts           r!   Úapply_answerr}  ²  s  € ðÜ—‘˜C“ˆô �fœdÔ#ØˆÜ�\‰\˜)Ÿ/™/Ó*€FØ—‘˜IÓ&Ò,¨"ó JˆÜ˜%¤Ô&ØØ×!Ñ!¤# e§i¡i°Ó&7Ò&=¸2Ó">×"DÑ"DÓ"F×"LÑ"LÓ"NÓOˆØˆ>ØÜ�U—Y‘Y˜xÓ(Ò.¨BÓ/×5Ñ5Ó7ˆØ�YÒô # 6¨6Ó2ˆDðØ$�	×$Ñ$ V§[¡[´+×2EÑ2EÄuÇzÁzñ KÙ<@¨°4Ñ(8ÀbóKð
 �zÓ! fÑ&8Ø�|‰|œ{×2Ñ2Ò2Ø—
‘
œ8 Y°¼ÀEÓ8JÖKØ—‘¤+×"4Ñ"4´k×6IÑ6IÐ!JÓJà—
‘
œ6 9¨f´kÀ%Ó6HÖIð/Jð0 ‡z�z�,Ó¤<×#9Ñ#9×#?Ñ#?Ò?È	×H^ÒH^Ø×Ñœ×/Ñ/Õ0ð I_Ð?øô; ”zÐ"ò Ø‹ðûô( %ò Ø—’¨y×/@Ò/@Øúðús$   ‚H3 Ã<AIÈ3IÉIÉ"I1É0I1z{the authorization had already completed when this was canceled, so it was kept; run the same action again to list the toolsc                ó¸   — | �&| j                   j                  |j                  d«      nd}t        t        |dd«      dd«      }|€yddlm}  ||«      rt        S dS )z¸Stop the target's OAuth attempt so a late reply cannot be adopted. Returns the note for a
    cancel that lost the race: the attempt had committed, and a completed authorization stays.Nr¡   rè   r2   r   rá   )r®   rã   r   rä   rç   râ   ÚAUTHORIZATION_KEPT)r  r´   r®   rè   râ   s        r!   rs  rs  Ý  sX   € ð 28Ð1Cˆ6�;‰;�?‰?˜6Ÿ;™;¨Ô-È€DÜ”7˜4 ¨DÓ1°6¸4Ó@€DØ€|ØÝ9á!/°Ô!5ÔÐ=¸2Ð=r&   c                óÆ   — t         j                  | j                  «      }|€y| j                  ry|D ]-  }| j	                  |«      }|€Œ|j                  t        | |«       Œ/ y)zÖRe-run the named MCP targets on the open operation (the card's Try again): a fresh OAuth
    flow, a fresh install, a fresh enable. Returns an error message when the operation is not one
    this module is running.Nz(this operation has no MCP work to re-runz0this operation has settled; its result is frozen)rÌ   rˆ   r­   r¹   r´   rµ   rw  )r³   r6   r  r   r´   s        r!   Úretryr�  é  sd   € ô �\‰\˜)Ÿ/™/Ó*€FØ€~Ø9Ø×ÒØAØò 2ˆØ×!Ñ! $Ó'ˆØÑØ�J‰J”v˜y¨&Õ1ð2ð r&   c           
     óR  — t        |D �cg c]  }t        |d|«      ‘Œ c}|¬«      }|j                  D ]  }| j                  t        ||«       Œ |j                  d¬«      }t        d„ |j                  D «       «      rdnd|d<   t        |d	<   t        j                  |d
¬«      S c c}w )NÚmcp)rë   T)Ú	with_urlsc              3  óV   K  — | ]!  }|j                   t        j                  k(  –— Œ# y ­wr   )rÛ   r   rÝ   )r   Úts     r!   r"   z"_no_card_result.<locals>.<genexpr>  s    è ø€ Ò*gÐPQ¨1¯7©7´k×6KÑ6KÕ+KÑ*gùs   ‚')rÝ   r¹   rð   ÚnoteF)Úensure_ascii)
r   r   rÎ   rµ   Ú_NO_CARDÚresultÚanyÚNO_CARD_NOTErn  Údumps)r  r6   r/   rë   r;   r³   r´   Úpayloads           r!   Ú_no_card_resultr�  þ  sœ   € Ü!ÀUÖ"KÀ¤6¨!¨U°FÕ#;Ò"KÐYdÔe€IØ×#Ñ#ò 0ˆØ�
‰
”8˜Y¨Õ/ð0à×Ñ¨ÐÓ.€GÜ'*Ñ*gÐU^×UfÑUfÔ*gÔ'g™Ðmv€GˆHÑÜ"€GˆF�OÜ�:‰:�g¨EÔ2Ð2ùò #Ls   ŠB$)Útool_call_idr¬   c          
     ót  — t        || «      }|rt        |«      S t        ||«      }t        |«      }|€t	        || ||«      S 	 t        | D �	cg c]  }	t        |	d|«      ‘Œ c}	t        |j                  |j                  t        ¬«      |||d¬«      |j                  «        S c c}	w # |j                  «        w xY w)Nrƒ  )rÒ   rß   r‡  F)rë   r�  Úconnection_callbackÚwith_urls_in_result)r@   r   r  r   r�  r   r   r   rÒ   rß   ÚNOTErí   )
r6   r/   r’  rï   r�  r¬   r¤   r  rë   r;   s
             r!   Úrun_mcp_operationr•    s¬   € ô ˜v uÓ-€EÙÜ˜%Ó Ð Ü˜ Ó)€FÜ'¨
Ó3€Kð Ð"Ü˜v u¨f°kÓBÐBðÜØ/4Ö5¨!ŒV�A�u˜fÕ%Ò5Ü˜Ÿ™°·±ÄdÔKØ#°,Ø 3Èô	
ð 	�‰�ùò 6øð 	�‰�ús   Á	B% ÁB Á0B% Â B% Â%B7)r�   r‘   )r/   rw   r6   r‘   r�   úOptional[str])r   rw   )r   rw   rG   r   rS   r�   r�   r’   )rS   r�   r�   r’   )r�   r   )rÿ   r   r�   r‘   r   )r/   rw   r¬   r   r�   rª   )r9   r   r  rª   r´   r   r�   rw   )r   rw   r�   rw   )r³   r   r´   r   r  r   r  r   r  r   r�   r�   )r³   r   r´   r   r  rw   r�   r’   )r  rª   r´   r   r   rw   r�   ztuple[List[str], str])r   )r   rw   r5  Úfloatr�   r‘   )r2   )
r³   r   r´   r   r~   r‘   rò   rw   r�   r’   )r´   r   r�   r   )
r  rª   r³   r   r´   r   rS   r�   r�   r’   )r  rª   r´   r   rS   r�   r�   rŽ   )r  rª   r´   r   r�   r�   )
r  rª   r³   r   r´   r   r¤   r   r�   r’   )r  rª   r³   r   r´   r   r�   r’   )rG   zDict[str, Any]r�   r�   )r³   r   rj  rw   r�   r’   )r  zOptional[_Runner]r´   r   r�   rw   )r³   r   r6   r‘   r�   r–  )
r  rª   r6   r‘   r/   rw   rë   rw   r�   rw   )r6   r‘   r/   rw   r’  z3Optional[Callable[[Dict[str, Any]], Optional[str]]]rï   r–  r�  r–  r¬   r   r�   rw   )[Ú
__future__r   rW  rÆ   rn  Úloggingr¦   rÔ   Údataclassesr   r   Útypingr   r   r   r	   r
   Útools.connectors.contractr   r   r   Útools.connectors.gateway.configr   Útools.connectors.operationr   r   r   r   Útools.connectors.runr   r   Útools.connectors.targetsr   r   r/  r   Ú	getLoggerr“   rº   rÕ   r”  rŒ  r%   r*   r@   rH   rJ   rj   rf   rž   r    rª   ré   r¥   r  rÌ   r  r  r¸   r  r  r#  r&  r%  r=  r@  rF  rH  rJ  rR  rO  rP  rU  rZ  r^  ra  rd  rc  rh  rÐ   ru  rw  rÞ   r‰  rk  r}  r  rs  r�  r�  r•  r—   r&   r!   ú<module>r¢     s+  ðÞ "ã Û Û Û Û Û ß (ß 6Õ 6ç FÑ FÝ Aß hÓ hß 4ß IÝ %à	ˆ×	Ñ	˜8Ó	$€ð Ð ð(ð ð=ð ó2ó'óóD÷J ñ J óZ	-ó'óð ÷ð ó ð÷fñ fðT -/€Ð)Ó .óðF  "€Ð
Ó !ô:ð dØ7ñ€ó>óFóó 
Wó0ôô@TóWó

1ó#óXó[ó2ð=Ø,ð=Ø15ó=ó =ó
8ó 8óF=ó0'ó8ó^ð &°,È(ÑS€Ø!¨nÈ
ÑS€Ø#°È*Ñ	U€Ø'Ð4DÐP_Ñ`€Ø%°,È*ÑU€óUó
$1ðNJÐ ó	>óó*3ð  #'ØñØðàðð Mð	ð
 ðð  ðð ðð 	ôr&   