Ë
    ãß²jeŠ  ã                  ó  — U d Z ddlmZ ddlZddlZddlmZmZmZm	Z	 ddl
mZmZ ddlmZ  ej                  d«      ZdZd	Zd
ZdZdZd
ZdZded<   d2d„Zd3d„Zd3d„Zd„ Zd4d„Zd5d„Zd6d„Zd6d„Z d7d„Z!d7d„Z"d6d„Z#d8d„Z$d9d„Z%d6d„Z&d7d„Z'd7d„Z(d:d„Z)d;d„Z*d<d „Z+d=d!„Z,d>d"„Z-	 	 d?	 	 	 	 	 d@d#„Z.d$„ Z/ e0h d%£«      Z1 e0h d&£«      Z2dAd'„Z3d2d(„Z4dBd)„Z5dBd*„Z6dCd+„Z7d2d,„Z8d-Z9 e0h d.£«      Z:dDd/„Z;dd0œ	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dEd1„Z<y)FzUDelegation config knobs (delegation.* keys) and child credential/provider resolution.é    )ÚannotationsN)ÚAnyÚDictÚListÚOptional)Úbase_url_hostnameÚis_truthy_value)Úget_fallback_chainztools.delegate_toolÚcustomé
   Fé   úOptional[float]ÚDEFAULT_CHILD_TIMEOUTc                 ó   — ddl m}   | «       S )zJThe ``delegation`` section, read through the origin so tests can patch it.r   ©Ú_load_config)Útools.delegate_toolr   r   s    ú?/home/ubuntu/.hermes/hermes-agent/tools/delegate_tool_config.pyÚ_cfgr      s   € å0Ù‹>Ðó    c                ó2   — t         j                  d| |«       y)zQAuto-deny (safe default): returns 'deny' so the child sees a recoverable refusal.zeSubagent auto-denied dangerous command: %s (%s). Set delegation.subagent_auto_approve: true to allow.Údeny©ÚloggerÚwarning©ÚcommandÚdescriptionÚkwargss      r   Ú_subagent_auto_denyr    *   s   € ä
‡N�NØoØ�ôð r   c                ó2   — t         j                  d| |«       y)zPAuto-approve (opt-in YOLO via delegation.subagent_auto_approve): returns 'once'.z1Subagent auto-approved dangerous command: %s (%s)Úoncer   r   s      r   Ú_subagent_auto_approver#   2   s   € ä
‡N�NÐFÈÐQ\Ô]Ør   c                 ó`   — t        t        «       j                  dd«      «      rt        S t        S )zZCallback for subagent worker threads per delegation.subagent_auto_approve (default False).Úsubagent_auto_approveF)r	   r   Úgetr#   r    © r   r   Ú_get_subagent_approval_callbackr(   7   s$   € ä”t“v—z‘zÐ"9¸5ÓAÔBÜ%Ð%ÜÐr   c                ó  — t        «       j                  | «      }|�		  ||«      S |rt        j                  |«      nd}|r		  ||«      S |S # t        t        f$ r t        j                  ||«       |cY S w xY w# t        t        f$ r Y |S w xY w)z¾delegation.<key> > <env_var> > default. A config value that fails ``parse`` logs ``invalid_msg`` (``%r`` = the
    value) and yields the default; an env value that fails is silently ignored.N)r   r&   Ú	TypeErrorÚ
ValueErrorr   r   ÚosÚgetenv)ÚkeyÚenv_varÚparseÚdefaultÚinvalid_msgÚvalÚenv_vals          r   Ú_knobr5   =   sš   € ô ‹&�*‰*�S‹/€CØ
€ð	Ù˜“:Ðñ %,Œb�i‰i˜Ô °€GÙð	Ù˜“>Ð!ð €Nøô œ:Ð&ò 	Ü�N‰N˜;¨Ô,ØŠNð	ûô œ:Ð&ò 	ØØ€Nð	ús#   �A ÁA8 Á'A5Á4A5Á8BÂ
Bc                óf   — t        «       |    s$dt        «       | <   t        j                  |g|¢­Ž  yy)zKModule-global one-shot warning (``flag_name`` is the ``_*_WARNED`` global).TN)Úglobalsr   r   )Ú	flag_nameÚmessageÚargss      r   Ú
_warn_oncer;   O   s.   € ä‹9�YÒØ#Œ‹	�)ÑÜ�‰�wÐ& Ô&ð  r   c                 ó"   — t        ddd„ dd«      S )z\delegation.oneshot_max_children (total children per finite one-shot session; 0 = unlimited).Úoneshot_max_childrenNc                ó,   — t        dt        | «      «      S )Nr   ©ÚmaxÚint©Úvs    r   ú<lambda>z+_get_oneshot_max_children.<locals>.<lambda>X   s   € ´°A´s¸1³v³€ r   é   zJdelegation.oneshot_max_children=%r is not a valid integer; using default 2)r5   r'   r   r   Ú_get_oneshot_max_childrenrF   U   s   € äØ Ñ&>ÀØTóð r   c                 ó’   — t        ddd„ t        dt        › �«      } | dkD  r&t        «       j                  d«      �t	        dd| «       | S )z—delegation.max_concurrent_children > DELEGATION_MAX_CONCURRENT_CHILDREN env > 10.

    Floor of 1 is the only bound enforced; there is no ceiling.
    Úmax_concurrent_childrenÚ"DELEGATION_MAX_CONCURRENT_CHILDRENc                ó,   — t        dt        | «      «      S )Nr   r?   rB   s    r   rD   z._get_max_concurrent_children.<locals>.<lambda>c   s   € ÔSVÐWXÔZ]Ð^_ÓZ`ÓSa€ r   zLdelegation.max_concurrent_children=%r is not a valid integer; using default r   Ú_HIGH_CONCURRENCY_WARNEDzxdelegation.max_concurrent_children=%d: each child consumes API tokens independently. High values multiply cost linearly.)r5   Ú _DEFAULT_MAX_CONCURRENT_CHILDRENr   r&   r;   )Úresults    r   Ú_get_max_concurrent_childrenrN   ]   s[   € ô
 Ø!Ð#GÑIaÜ(Ø
VÔWwÐVxÐyó€Fð
 �‚{”t“v—z‘zÐ";Ó<ÐHÜØ&ð )AØBHô	
ð €Mr   c                 óH   — t        t        «       j                  dd«      «      S )zÛdelegation.independent_completions (bool, default False): split a background call into per-task / per-group
    completion messages that land as each finishes. Off = one consolidated message when the whole call is done.Úindependent_completionsF©r	   r   r&   r'   r   r   Ú_get_independent_completionsrR   n   s   € ô œ4›6Ÿ:™:Ð&?ÀÓGÓHÐHr   c                 óH   — t        t        «       j                  dd«      «      S )zídelegation.worktree_isolation (bool, default False): each child gets its own
    git worktree off the parent's HEAD so parallel children never contend for one
    working copy. Git-only and local-backend-only; otherwise silently ignored.Úworktree_isolationF)Úboolr   r&   r'   r   r   Ú_get_worktree_isolationrV   s   s   € ô ”“—
‘
Ð/°Ó7Ó8Ð8r   c                 óf   — ddl m}  t        «       j                  d«      �t	        dd«        | «       S )aH  Concurrency cap for background delegations == delegation.max_concurrent_children. At capacity a new async
    dispatch is REJECTED (not queued) so a runaway model can't pile up unbounded background work; the caller then
    runs synchronously. A leftover ``delegation.max_async_children`` key is ignored with a one-time warning.r   ©rN   Úmax_async_childrenÚ_LEGACY_MAX_ASYNC_WARNEDz§delegation.max_async_children is deprecated and ignored; delegation.max_concurrent_children now caps background delegations too. Remove the stale key from config.yaml.)r   rN   r   r&   r;   rX   s    r   Ú_get_max_async_childrenr[   y   s6   € õ AÜƒv‡z�zÐ&Ó'Ð3ÜØ&ð )Fô	
ñ
 (Ó)Ð)r   c                ó>   — t        | «      }|dk  rdS t        d|«      S )uJ   Seconds â†’ None (<= 0 disables) or max(30, value). Raises on non-numeric.r   Ng      >@)Úfloatr@   )ÚrawÚparseds     r   Ú_parse_timeoutr`   †   s#   € ä�3‹Z€FØ˜Q’;ˆ4Ð5¤C¨¨fÓ$5Ð5r   c                 ó0   — t        ddt        t        d«      S )u™  Inactivity cap for one child (seconds of NO progress), or None (default: no cap). Failures should come from
    what the child does (API/tool errors, iteration budget), not a stopwatch: the cap restarts on every sign of
    progress â€” a completed call, a tool change, an activity-clock tick â€” so a slow provider serving multi-minute
    completions never loses a live child, and a child frozen for the whole window is still caught. A configured
    value pre-empts nothing the heartbeat staleness monitor would not also catch. delegation.child_timeout_seconds
    > 0 opts in (floor 30 s); 0 or negative disables. Env fallback: DELEGATION_CHILD_TIMEOUT_SECONDS.Úchild_timeout_secondsÚ DELEGATION_CHILD_TIMEOUT_SECONDSzUdelegation.child_timeout_seconds=%r is not a valid number; using default (no timeout))r5   r`   r   r'   r   r   Ú_get_child_timeoutrd   ‹   s   € ô ØÐ!CÄ^ÔUjØ_óð r   c                 ó<   — d„ } t        dd| t        dt        › �«      S )zÇdelegation.max_spawn_depth floored at 1 (no ceiling). Depth 0 is the parent; agents at depths 0..N-1 may spawn,
    depth N is the leaf floor. Default 1 is flat. Each extra level multiplies API cost.c                óŠ   — t        | «      }|t        k  r t        j                  d|t        t        «       t	        t        |«      S )Nz6delegation.max_spawn_depth=%d below floor %d; using %d)rA   Ú_MIN_SPAWN_DEPTHr   r   r@   )rC   Úivals     r   Ú_flooredz&_get_max_spawn_depth.<locals>._flooredš   s8   € Ü�1‹vˆØÔ"Ò"Ü�N‰NÐSÐUYÔ[kÔm}Ô~ÜÔ# TÓ*Ð*r   Úmax_spawn_depthNzDdelegation.max_spawn_depth=%r is not a valid integer; using default )r5   Ú	MAX_DEPTH)ri   s    r   Ú_get_max_spawn_depthrl   —   s)   € ò+ô Ø˜4 ¬9Ø
NÌyÈkÐZóð r   c                 ó¼   — t        «       j                  dd«      } t        | t        «      r| S t        | t        «      r | j                  «       j                  «       dv S y)z]delegation.orchestrator_enabled kill switch (default True): False forces every child to leaf.Úorchestrator_enabledT>   Ú1ÚonÚyesÚtrue)r   r&   Ú
isinstancerU   ÚstrÚstripÚlower)r3   s    r   Ú_get_orchestrator_enabledrw   ¥   sL   € ä
‹&�*‰*Ð+¨TÓ
2€CÜ�#”tÔØˆ
ä�#”sÔØ�y‰y‹{× Ñ Ó"Ð&@Ð@Ð@Ør   c                 óJ   — t        t        «       j                  d«      d¬«      S )zFWhether narrowed child toolsets should keep the parent's MCP toolsets.Úinherit_mcp_toolsetsT)r1   rQ   r'   r   r   Ú_get_inherit_mcp_toolsetsrz   ¯   s   € äœ4›6Ÿ:™:Ð&<Ó=ÀtÔLÐLr   c                óZ   — t        | xs d«      j                  «       j                  d«      S )NÚ ú/)rt   ru   Úrstrip)Úvalues    r   Ú_normalized_runtime_urlr€   ³   s%   € ÜˆuŠ{˜Ó×!Ñ!Ó#×*Ñ*¨3Ó/Ð/r   c                óà   — |s|ryt        | dd«      }t        |t        «      sy|j                  «       D ��ci c]*  \  }}t        |t        «      sŒt        |t
        «      sŒ(||“Œ, c}}S c c}}w )aE  Parent's endpoint-trust capability map for a child, or None. ``agent.capabilities`` is a trust decision scoped
    to one provider+endpoint: inherited ONLY when the child runs the parent's exact route; any provider or base_url
    override stays DEFAULT-DENY (matches the /model switch posture).

    See #94036, #97292.
    NÚcapabilities)Úgetattrrs   ÚdictÚitemsrt   rU   )Úparent_agentÚoverride_providerÚoverride_base_urlÚparent_capsr.   r   s         r   Ú_inherit_parent_capabilitiesrŠ   ¶   sc   € ñ Ñ-ØÜ˜,¨¸Ó=€KÜ�k¤4Ô(ØØ)4×):Ñ):Ó)<×q™:˜3 Ä
È3ÔPSÕ@TÔYcÐdiÔkoÕYpˆC�‰JÓqÐqùÓqs   ·A*ÁA*Á!A*c                óP  — t        | dd«      }t        | dd«      }t        |t        «      r"|j                  d«      |j                  d«      fnd|�t        |dd«      t        |dd«      fndf}|D ].  \  }}t	        |«      }|sŒ|j                  d«      sŒ&||xs |fc S  |xs d|fS )	uc  ``(base_url, api_key)`` the parent is actually calling, taken from ONE source. ``parent_agent.base_url`` /
    ``api_key`` can lag the live client (old OpenRouter URL vs local Ollama; a fallback runtime the surface attributes
    have not caught up with), and pairing the live endpoint with the surface key hands the child a (base_url, key)
    pair that was never valid anywhere â€” an instant, non-retryable 401 (#90009). The live client's key travels with
    its URL; the surface attributes are used only when there is no live OpenAI-wire client (native Anthropic/Bedrock
    runtimes keep ``client=None``).Ú_client_kwargsNÚclientÚbase_urlÚapi_key©NNr|   )zhttp://zhttps://)rƒ   rs   r„   r&   r€   Ú
startswith)	r†   Úsurface_base_urlÚsurface_api_keyÚclient_kwargsr�   Úlive_candidatesÚraw_urlÚlive_keyÚurls	            r   Ú_inherit_parent_endpointr™   Ä   sÇ   € ô ˜LÐ*:¸DÓA€MÜ�\ 8¨TÓ2€FäISÐTaÔcgÔIhˆ×	Ñ	˜:Ó	&¨×(9Ñ(9¸)Ó(DÑEÐnzàOUÐOaŒ�˜ RÓ	(¬'°&¸)ÀTÓ*JÑKÐgsð€Oð
 -ò 6Ñˆ�Ü% gÓ.ˆÚ�3—>‘>Ð"9Õ:Ø˜Ò4 _Ð5Ò5ð6ð Ò$  Ð6Ð6r   c                óJ   — ddl m}  || «      }|�|j                  «       r|S dS )z8``load_pool(key)`` when it holds credentials, else None.r   )Ú	load_poolN)Úagent.credential_poolr›   Úhas_credentials)r.   r›   Úpools      r   Ú_loaded_poolrŸ   Ø   s)   € å/Ù�S‹>€DØÐ#¨×(<Ñ(<Ô(>ˆ4ÐHÀDÐHr   c                ó¾   ‡‡— ddl mŠm}  || |‰¬«      syt        | dd«      }t	        |«      sy |«       }t        |t        «       xs t        ˆˆfd„|D «       «      S )	zeProvider identity AND at least one entry for the child's endpoint; pools without entry metadata pass.r   )Ú%credential_pool_entry_serves_endpointÚ credential_pool_matches_provider)rŽ   FÚentriesNTc              3  ó0   •K  — | ]  } ‰|‰«      –— Œ y ­w)Nr'   )Ú.0ÚentryÚ_entry_serves_endpointrŽ   s     €€r   ú	<genexpr>z(_pool_serves_endpoint.<locals>.<genexpr>é   s   øè ø€ Ò/mÐ\aÑ0FÀuÈh×0WÑ/mùs   ƒ)rœ   r¡   r¢   rƒ   Úcallablers   ÚlistÚany)rž   ÚproviderrŽ   r¢   Ú
entries_fnr£   r§   s     `   @r   Ú_pool_serves_endpointr®   Þ   sZ   ù€ ÷ñ ,¨D°(ÀXÕNØÜ˜˜y¨$Ó/€JÜ�JÔØÙ‹l€GÜ˜'¤4Ó(Ð(Òm¬CÔ/mÐelÔ/mÓ,mÐmr   c                ó  — t        |dd«      }| s|S t        |dd«      xs d}	 | dk(  rNddlm}  |||¬«      }|€y |t        |d	d«      t        |d
d«      ¬«      }|�|dk(  r	|�||k(  r|S t        |«      S |�-| |k(  r(|rt	        || |«      r|S t
        j                  d| |«       t        | «      }	|	�|rt	        |	| |«      sy|	S # t        $ r>}
| dk(  rt
        j                  d||
«       nt
        j                  d| |
«       Y d}
~
yd}
~
ww xY w)u  Credential pool for the child: parent's pool (same provider), that provider's own pool, or None (child keeps
    its fixed credential). Custom endpoints all collapse to ``provider="custom"``, so they are matched by endpoint
    identity (the ``custom:<name>`` pool key) â€” sharing the parent's pool across different custom endpoints would
    overwrite the child's delegated base_url on lease; an unregistered custom endpoint (no custom_providers entry)
    keeps the child's fixed credential rather than inherit the parent's.

    Custom endpoints are a special case: every direct ``delegation.base_url`` runtime collapses to
    ``provider="custom"``, so bare provider equality would treat two *different* custom endpoints as
    interchangeable and let the child inherit the parent's pool. We therefore resolve custom runtimes by
    endpoint identity (the ``custom:<name>`` pool key derived from the base_url) and only share the parent's
    pool when both resolve to the *same* custom endpoint. See #7833.

    Named custom providers may share one gateway URL with different credentials, so the inherited
    ``requested_provider`` identity takes precedence over URL-only matching (#45763): the child must not
    lease the first pool registered for the shared endpoint.
    Ú_credential_poolNr¬   r|   r   r   )Úget_custom_provider_pool_key)Úprovider_namerŽ   Úrequested_providerzAParent %s pool has no entry for child endpoint %s; not sharing itzDCould not resolve custom credential pool for child endpoint '%s': %sz:Could not load credential pool for child provider '%s': %s)rƒ   rœ   r±   rŸ   r®   r   ÚdebugÚ	Exception)Úeffective_providerr†   Úeffective_base_urlÚeffective_requested_providerÚparent_poolÚparent_providerr±   Ú	child_keyÚ
parent_keyrž   Úexcs              r   Ú_resolve_child_credential_poolr¾   ë   sR  € ô( ˜,Ð(:¸DÓA€KÙØÐÜ˜l¨J¸Ó=ÒCÀ€OðpØ Ò)ÝJÙ4Ð5GÐWsÔtˆIØÐ ØÙ5Ü˜ j°$Ó7ÄwÈ|Ð]qÐswÓGxôˆJð Ð&¨?¸hÒ+FÈ:ÐKaÐfpÐt}Òf}Ø"Ð"Ü 	Ó*Ð*ØÐ"Ð'9¸_Ò'LÙ%Ô)>¸{ÐL^Ð`rÔ)sØ"Ð"Ü�L‰LÐ\Ø+Ð-?ôAäÐ.Ó/ˆØÐÑ 2Ô;PÐQUÐWiÐk}Ô;~ØØˆøÜò pØ Ò)Ü�L‰LÐ_ÐasÐuxÕyä�L‰LÐUÐWiÐknÔoûØûðpús4   ¤C ¼/C Á,
C Á7C Â3C ÃC Ã	DÃ4DÄDc                ó¨  — ddl }t        | t        «      r| nd} t        |t        «      r|nd}| s|sy| r|j                  | «      ni }|r|j                  |«      ni }|j	                  d«      }|j                  dd«      }|j                  |«       t        |t        «      r't        |t        «      r|j                  |«       ||d<   n|�||d<   |xs dS )a�  Merge explicit ``delegation.request_overrides`` OVER runtime-derived ones. Explicit top-level keys win;
    ``extra_body`` is deep-merged ONE level so provider personality (e.g. ``thinking: {type: disabled}``) survives
    unless the explicit dict redefines that exact key. Both sides are deep-copied so transport-side mutation can't
    leak into the config/runtime cache. None when both are empty.r   NÚ
extra_body)Úcopyrs   r„   Údeepcopyr&   ÚpopÚupdate)Úruntime_overridesÚexplicit_overridesÚ_copyÚmergedÚexplicitÚruntime_extraÚexplicit_extras          r   Ú_merge_request_overridesrÌ     sÍ   € ó
 Ü-7Ð8IÌ4Ô-PÑ)ÐVZÐÜ/9Ð:LÌdÔ/SÑ+ÐY]ÐÙÑ%7ØÙ2CˆU�^‰^Ð-Ô.È€FÙ5Gˆu�~‰~Ð0Ô1ÈR€HØ—J‘J˜|Ó,€MØ—\‘\ ,°Ó5€NØ
‡M�M�(ÔÜ�-¤Ô&¬:°nÄdÔ+KØ×Ñ˜^Ô,Ø,ˆˆ|ÒØ	Ð	#Ø-ˆˆ|ÑØŠ>�TÐr   >   úgoogle-genaiÚgoogleÚvertexÚbedrock>   Úcodex_responsesÚchat_completionsÚanthropic_messagesc                óJ   — ddl }| r|j                  | «      st        |«      ‚yy)uŠ   A pinned ACP transport command must exist on PATH â€” refuse loudly rather
    than let the child silently fall back to another transport.r   N)ÚshutilÚwhichr+   )r   r9   Ú_shutils      r   Ú_require_pinned_commandrØ   :  s'   € ó Ù�w—}‘} WÔ-Ü˜Ó!Ð!ð .€wr   c                ó   — | |||||dœ|¥S )zVThe child credential dict every branch of ``_resolve_delegation_credentials`` returns.)Úmodelr¬   rŽ   r�   Úapi_modeÚrequest_overridesr'   )rÚ   r¬   rŽ   r�   rÛ   rÜ   Úextras          r   Ú_credential_bundlerÞ   A  s%   € ð  H¸(ÈwÐdlØ.ñà27ðð r   c                ó&  — ddl m} | d   j                  «       }t        | d   «      }d} || d   «      xs d}|dk(  r
d|v rd\  }}n|d	k(  rd
\  }}nd|v rd}ddlm} | d   t        v s| d   r| d    |«       v r| d   }d}| d   r9	 ddl m}	  |	| d   | d   ¬«      }
t        |
j                  d«      xs i «      xs d}t        | d   || d   | d   |t        ||«      «      S # t        $ r$}t        j                  d| d   |«       Y d}~ŒKd}~ww xY w)zF``delegation.base_url`` branch: provider/api_mode from URL heuristics.r   )Ú_detect_api_mode_for_urlrŽ   r   rÒ   zchatgpt.comz/backend-api/codex)zopenai-codexrÑ   zapi.anthropic.com)Ú	anthropicrÓ   zapi.kimi.com/codingrÓ   )Úregistered_api_modesrÛ   Nr¬   ©Úresolve_runtime_providerrÚ   ©Ú	requestedÚtarget_modelrÜ   zjdelegation.base_url: runtime resolution for provider '%s' failed; proceeding without request_overrides: %sr�   )Úhermes_cli.runtime_providerrà   rv   r   Úagent.transportsrâ   Ú_EXPLICIT_API_MODESrä   r„   r&   rµ   r   r´   rÞ   rÌ   )rC   Úexplicit_request_overridesrà   Ú
base_lowerÚhostr¬   rÛ   râ   rÜ   rä   Úruntimer½   s               r   Ú_direct_endpoint_credentialsrï   H  sZ  € õ EØ�:‘×$Ñ$Ó&€JÜ˜Q˜z™]Ó+€DØ€HÙ'¨¨*©Ó6ÒLÐ:L€HØˆ}ÒÐ!5¸Ñ!CØ>Ñˆ‘(Ø	Ð$Ò	$Ø>Ñˆ‘(Ø	 *Ñ	,Ø'ˆõ 6Øˆ�}Ô+Ñ+°°*²À!ÀJÁ-ÑSgÓSiÑBiØ�Z‘=ˆð ÐØˆ‚}ð		ÝLÙ.¸¸:¹ÐUVÐW^ÑU_Ô`ˆGÜ $ W§[¡[Ð1DÓ%EÒ%KÈÓ LÒ TÐPTÐô Ø	ˆ'‰
�H˜a 
™m¨Q¨y©\¸8Ü Ð!2Ð4NÓOóð øô ò 	Ü�L‰LØ|Ø�*‘˜s÷ñ ûð	ús   Â8C# Ã#	DÃ,DÄDc                óð  — | d   }	 ddl m}  ||| d   ¬«      }|j	                  d
d«      }|st        d|› d�«      ‚|j	                  d«      }t        |d|› d|› d�«       |j	                  d«      s5|s3|j                  «       j                  «       t        vrt        d|› d�«      ‚t        | d   xs |j	                  d«      xs d	|j	                  d«      t        k(  r|n|j	                  d«      |j	                  d«      ||j	                  d«      t        |j	                  d«      |«      xs i |t        |j	                  d«      xs g «      ¬«      S # t        $ r}t        d|› d|› d�«      |‚d	}~ww xY w)zL``delegation.provider`` branch: full bundle via the runtime provider system.r¬   r   rã   rÚ   rå   z$Cannot resolve delegation provider 'z': zÒ. Check that the provider is configured (API key set, valid provider name), or set delegation.base_url/delegation.api_key for a direct endpoint. Available providers: openrouter, nous, zai, kimi-coding, minimax.Nr�   r|   zDelegation provider 'z]' resolved but has no API key. Set the appropriate environment variable or run 'hermes auth'.r   z' is pinned to the 'z]' command, which was not found on PATH. Install it or choose a different delegation provider.rŽ   uÁ   ' resolved without a base_url. Refusing to build a subagent with an incomplete credential bundle â€” check the provider's configuration / auth, or set delegation.base_url for a direct endpoint.rÛ   rÜ   r:   )r   r:   )rè   rä   rµ   r+   r&   rØ   ru   rv   Ú_NATIVE_SDK_PROVIDERSrÞ   Ú_RUNTIME_PROVIDER_CUSTOMrÌ   rª   )rC   rë   Úconfigured_providerrä   rî   r½   r�   Úpinned_commands           r   Ú_runtime_provider_credentialsrõ   r  sÂ  € à˜J™-Ðð	ÝHÙ*Ð5HÐWXÐY`ÑWaÔbˆð �k‰k˜) RÓ(€GÙÜØ#Ð$7Ð#8ð 9Mð Nó
ð 	
ð —[‘[ Ó+€NÜØÐ/Ð0CÐ/Dð EØÐð @ðAôð �K‰K˜
Ô#©NØ#×)Ñ)Ó+×1Ñ1Ó3Ô;PÑPÜØ#Ð$7Ð#8ð 9Vð Wó
ð 	
ô
 Ø	ˆ'‰
Ò2�g—k‘k 'Ó*Ò2¨dØ&Ÿ{™{¨:Ó6Ô:RÒRÑÐX_×XcÑXcÐdnÓXoØ�‰�JÓ ¨'¯+©+°jÓ*AÜ  §¡Ð-@Ó!AÐC]Ó^ÒdÐbdØ¤T¨'¯+©+°fÓ*=Ò*CÀÓ%Dôð øôA ò ÜØ2Ð3FÐ2GÀsÈ3È%ð PPð Qó
ð
 ð	ûðús   ‡E Å	E5ÅE0Å0E5c                ó\  — dD �ci c]3  }|t        | j                  |«      xs d«      j                  «       xs d“Œ5 }}t        | j                  d«      xs d«      j                  «       j                  «       xs d|d<   t	        | j                  d«      t
        «      r| j                  d«      nd}|d   xs dj                  «       j                  «       t        v }|d   r|st        ||«      S |d   s(t        |d   ddddt        t        |dd«      |«      «      S t        ||«      S c c}w )	uà  Child credential bundle from the ``delegation`` config section. Three branches: ``base_url`` set â†’ direct
    endpoint (``api_key`` None means inherit the parent's key, so providers keyed outside OPENAI_API_KEY work);
    ``provider`` set â†’ full bundle via the runtime provider system (same path as CLI/gateway startup); neither â†’
    None values, child inherits everything. ``request_overrides`` is honored on every branch. Raises ValueError
    with a user-facing message.)rÚ   r¬   rŽ   r�   r|   NrÛ   rÜ   r¬   rŽ   rÚ   )rt   r&   ru   rv   rs   r„   rñ   rï   rÞ   rÌ   rƒ   rõ   )Úcfgr†   ÚkÚvaluesrë   Úis_native_sdk_providers         r   Ú_resolve_delegation_credentialsrû      s*  € ð AmÖm¸1ˆa”�S—W‘W˜Q“ZÒ% 2Ó&×,Ñ,Ó.Ò6°$Ñ6Ðm€FÐmÜ˜SŸW™W ZÓ0Ò6°BÓ7×=Ñ=Ó?×EÑEÓGÒOÈ4€Fˆ:ÑÜAKÈCÏGÉGÐTgÓLhÔjnÔAo §¡Ð)<Ô!=ÐuyÐØ$ ZÑ0Ò6°B×=Ñ=Ó?×EÑEÓGÔK`Ð`ÐàˆjÒÑ"8Ü+¨FÐ4NÓOÐOØ�*Òä!Ø�7‰O˜T 4¨¨tÜ$¤W¨\Ð;NÐPTÓ%UÐWqÓró
ð 	
ô )¨Ð1KÓLÐLùò ns   …8D)c                 óN  — t         j                  j                  d«      dk7  r4	 ddlm}   | «       j                  d«      xs i }t        |t        «      r|S 	 	 ddlm	} |j                  d«      xs i }t        |t        «      r|S i S # t        $ r Y Œ;w xY w# t        $ r i cY S w xY w)u¡  The ``delegation`` config section (read-only â€” do NOT mutate). Prefers the shared ``load_config_readonly()``
    (follows HERMES_HOME/profile; no deepcopy, since this runs on every get_definitions() rebuild) over the legacy
    ``cli.CLI_CONFIG``, which can hide user-set keys â€” except that ``HERMES_IGNORE_USER_CONFIG=1`` is only honored
    by the legacy loader, so it stays authoritative when that flag is set.ÚHERMES_IGNORE_USER_CONFIGro   r   )Úload_config_readonlyÚ
delegation)Ú
CLI_CONFIG)
r,   Úenvironr&   Úhermes_cli.configrþ   rs   r„   rµ   Úclir   )rþ   r÷   r   s      r   r   r   µ  s¦   € ô
 
‡z�z‡~�~Ð1Ó2°cÒ9ð	Ý>Ù&Ó(×,Ñ,¨\Ó:Ò@¸bˆCÜ˜#œtÔ$Ø�
ð %ðÝ"Ø�n‰n˜\Ó*Ò0¨bˆÜ  ¤dÔ+ˆsÐ3°Ð3øô ò 	Ùð	ûô ò ØŠ	ðús)   ¤1B Á,B ÂB Â	BÂBÂB$Â#B$))Úproviders_allowedN)Úproviders_ignoredN)Úproviders_orderN)Úprovider_sortN)Úprovider_require_parametersF)Úprovider_data_collectionr|   >   únous-portalÚnousÚnousresearchc                óä   — |rdnt        | dd«      xs d}t        |t        «      r|j                  d«      nd}|€|S |g k(  ryt	        d|i«      }|st
        j                  d|rdnd«       |xs |S )ae  Fallback chain for a child, owned by the same config block as its route.

    Pinned children (provider, endpoint or model override) never borrow the parent chain;
    unpinned children inherit it when ``fallback_providers`` is absent/null. An explicit ``[]``
    disables fallback either way. Malformed entries are dropped by the canonical normalizer.
    NÚ_fallback_chainÚfallback_providerszHdelegation fallback_providers has no usable routes; using the %s defaultÚpinnedÚ	inherited)rƒ   rs   r„   r&   r
   r   r   )r†   Úrouting_cfgr  r1   ÚdeclaredÚ
normalizeds         r   Ú_resolve_child_fallback_chainr  Ô  s‚   € ñ ‰d¤7¨<Ð9JÈDÓ#QÒ#YÐUY€GÜ8BÀ;ÔPTÔ8Uˆ{�‰Ð3Ô4Ð[_€HØÐØˆØ�2‚~ØÜ#Ð%9¸8Ð$DÓE€JÙÜ�‰ÐaÙ#)‘x¨{ô	<àÒ ˜Ð r   )r  c               óÄ  — |xs | j                   }|r|}|}n9|rt        | dd«      }|}n't        | dd«      }t        | | j                  |«      \  }}t        | dd«      xs d}|�|}nL|xs dj	                  «       j                  «       t        v rddlm}  ||«      }n||k7  rd}nt        | dd«      }t        |d|› d�«       |xs t        | d	d«      }t        |	�|	nt        | d
g «      xs g «      }|r|sdg }}|r(ddlm}  ||xs d«      }|�|j                  dk7  rd\  }}|}|s|s|st        | dd«      xs |}t        | dd«      }	 |j                  d«      }|s|du r)ddlm}  ||«      }|€t"        j%                  d|«       n|}||xs ||||t+        | ||«      ||||t-        | |
€|n|
t/        |xs |xs |«      ¬«      t        | dd«      dœt0        D ��ci c]  \  }}||r|nt        | ||«      “Œ c}}¥}|s|d   xs d|d<   t        | dd«      }t3        |t4        «      r||d<   |S # t&        $ r }t"        j)                  d|«       Y d}~ŒÉd}~ww xY wc c}}w )aì  Child credentials, transport and routing (config override > parent inherit) as ``AIAgent`` kwargs. Rules that
    are easy to break: api_mode is re-derived (not inherited) when the child's provider differs from the parent's
    or is Nous Portal (dual-wire); a pinned ``delegation.command`` must exist on PATH or the spawn fails loudly;
    ``override_provider`` clears the parent's ACP transport, fallback chain and OpenRouter routing filters so the
    pinned provider is actually honoured.r¬   Nr|   r   )Únous_api_moderÛ   zPinned delegation command 'zR' was not found on PATH. Install it or remove delegation.command from config.yaml.Úacp_commandÚacp_args)Úget_provider_profileÚexternal_process)zcopilot-acprÒ   r³   Úreasoning_configÚreasoning_effortF)Úparse_reasoning_effortzAUnknown delegation.reasoning_effort '%s', inheriting parent levelz.Could not load delegation reasoning_effort: %s)r  Úopenrouter_min_coding_score)rŽ   r�   rÚ   r¬   r³   r‚   rÛ   r  r  r  Úfallback_modelr  r	  Ú
max_tokens)rÚ   rƒ   r™   rŽ   ru   rv   Ú_NOUS_PROVIDERSÚhermes_cli.providersr  rØ   rª   Ú	providersr  Ú	auth_typer&   Úhermes_constantsr  r   r   rµ   r´   rŠ   r  rU   Ú_ROUTING_FILTER_DEFAULTSrs   rA   )r†   Údelegation_cfgÚparent_api_keyrÚ   r‡   rˆ   Úoverride_api_keyÚoverride_api_modeÚoverride_acp_commandÚoverride_acp_argsr  Úeffective_modelr¶   r·   Ú_parent_providerÚeffective_api_moder  Úeffective_acp_commandÚeffective_acp_argsr  Úprofiler¸   Úchild_reasoningÚdelegation_effortr  r_   r½   ÚaÚdr   Úchild_max_tokenss                                  r   Ú_resolve_child_runtimer9  è  s  € ð Ò1˜|×1Ñ1€Oñ Ø.ÐØ.ÑÙ	Ü$ \°:¸tÓDÐØ.Ñä$ \°:¸tÓDÐÜ-EÀlÐT`×TiÑTiÐkyÓ-zÑ*Ð˜Nô ˜|¨Z¸Ó>ÒDÀ"ÐØÐ$Ø.ÑØ
Ò
" ×	)Ñ	)Ó	+×	1Ñ	1Ó	3´Ñ	FÝ6Ù*¨?Ó;ÑØ	Ð/Ò	/Ø!Ñä$ \°:¸tÓDÐô ØÐ ;Ð<PÐ;Qð RSð Tôð 1Ò^´G¸LÈ-ÐY]Ó4^ÐÜØ.Ð:ÑÄÈÐWaÐceÓAfÒAlÐjlóÐñ Ñ!5Ø48¸"Ð1Ðñ
 Ý2Ù&Ð'9Ò'?¸RÓ@ˆàˆ?˜g×/Ñ/Ð3EÒEØ5VÑ2ÐÐ 2ð $6Ð ÙÑ%6Ñ?Sä�LÐ"6¸Ó=ÒSÐASð 	%ô ˜lÐ,>ÀÓE€Oð
LØ*×.Ñ.Ð/AÓBÐÙÐ 1°UÑ :Ý?Ù+Ð,=Ó>ˆFØˆ~Ü—‘ÐbÐduÕvà"(�ð
 'Ð3CÒ3UÀ~Ð`oØ&Ð>ZÜ4°\ÐCTÐVgÓhØ&Ð7LÐZlØ+ô 8Ø¨KÐ,?™.À[ÜÐ)ÒGÐ->ÒGÀ%ÓHôJô (/¨|Ð=ZÐ\`Ó'añô Sk×
kÉ$È!ÈQˆ1Ñ$‰a¬'°,ÀÀ1Ó*EÑEÓ
kð€Fñ Ø-3Ð4NÑ-OÒ-UÐSUˆÐ)Ñ*Ü˜|¨\¸4Ó@ÐÜÐ"¤CÔ(Ø/ˆˆ|ÑØ€Møô/ ò LÜ�‰ÐEÀs×KÑKûðLüó  ls   ÅA H0 ÇIÈ0	IÈ9IÉI)Úreturnr„   )r   rt   r   rt   r:  rt   )r.   rt   r/   úOptional[str]r2   rt   )r8   rt   r9   rt   r:   r   r:  ÚNone)r:  rA   )r:  rU   )r^   r   r:  r   )r:  r   )r   r   r:  rt   )r:  zOptional[dict])r’   r;  r“   r   r:  Útuple)r.   r   )rž   r   r¬   r;  rŽ   r;  r:  rU   r�   )r¶   r;  r·   r;  r¸   r;  )r   r;  r9   rt   r:  r<  )rC   r„   r:  r„   )r÷   r„   r:  r„   )r  r   r  rU   r:  zOptional[List[Dict[str, Any]]])r(  r„   r)  r   rÚ   r;  r‡   r;  rˆ   r;  r*  r;  r+  r;  r,  r;  r-  zOptional[List[str]]r  zOptional[Dict[str, Any]]r:  zDict[str, Any])=Ú__doc__Ú
__future__r   Úloggingr,   Útypingr   r   r   r   Úutilsr   r	   Úhermes_cli.fallback_configr
   Ú	getLoggerr   rò   rL   rK   rk   rg   rZ   r   Ú__annotations__r   r    r#   r(   r5   r;   rF   rN   rR   rV   r[   r`   rd   rl   rw   rz   r€   rŠ   r™   rŸ   r®   r¾   rÌ   Ú	frozensetrñ   rê   rØ   rÞ   rï   rõ   rû   r   r'  r"  r  r9  r'   r   r   ú<module>rG     sË  ðÚ [å "ã Û 	ß ,Ó ,ß 4Ý 9à	ˆ×	Ñ	Ð0Ó	1€ð $Ð à#%Ð  ð !Ð Ø€	ØÐ Ø Ð ð *.Ð �Ó -óóóò
óó$'óóó"Ió
9ó*ó6ó

óóóMó0óró7ó(Iónð Z^Ø26ð2Ø%ð2ØIVð2à"/ó2òhñ0 "Ò"QÓRÐ ÙÒ ]Ó^Ð ó"óó(óT,ó\Mó*ð.Ð ñ
 ÒCÓD€ó!ð0 -1ñ	sØ"&ðsØ8;ðsØGTðsØivðsà$ðsà8EðsàZgðsð (ðsð =Pðsð *ð	sð
 ôsr   