
    PL
j)                    R	   U d Z ddlZddlZddlZ ej        e          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 ddlmZ dZddlmZ ddlmZ dd	lmZmZ  eg d
          Zde de de fdZ!de de de fdZ"d Z# eh d          Z$ e%d  ej&                    D                       Z'd(                    d e'D                       Z)dZ*dZ+dZ,dZ- ej.                    Z/da0e1e2d<    ej.                    Z3i Z4ee ee ef         f         e2d<   de1de1fdZ5de1fdZ6dee ef         ddfdZ7de ddfd Z8de de1fd!Z9deee ef                  fd"Z:d#d$d%d&ee ef         d'e;d(e;deee ef                  fd)Z<d*e de1fd+Z=d,ee          de fd-Z>de;fd.Z?de@fd/ZAde;fd0ZBde1fd1ZCde1fd2ZDd3e de1fd4ZEd5eFdeFfd6ZGd7ee          d5eFe          dee          fd8ZHd9ZId:ZJd;ZKd<ZLd=ZMg d>ZN G d? d@e ejO                  ZPePjQ        ePjQ        ePjR        ePjS        ePjT        dAZUee ePf         e2dB<   de1fdCZV	 dddDdEddFdGe dHee          dIee          dJe dKe;dLe;de fdMZWdee          fdNZXdOee          dee          fdPZY	 dddddddQdRe;dGe dSe;dee          dTee          dUee;         dVee          dOeee                   deeZ         fdWZ[	 	 	 	 	 	 	 ddRe;dGe dHee          dOeee                   dVee          dXe;dSe;dYee          dZee          d[ee          d\ee          d]ee          d^eee                   dJe fd_Z\d`edRe;dae@dbe@dceej]                 dGe dee          fddZ^	 	 ddRe;dGe dee ef         fdeZ_dfede`eeee ef                           ee          f         fdgZa	 	 	 	 	 	 	 	 	 ddGee          dHee          dOeee                   dfeeee ef                           dXee;         dhee          dieee                   dJee          de fdjZbdkee          fdlZcdmeddedfdnZededfdoZfde fdpZgde fdqZhde fdrZidedfdsZjdtdudvdwdxdydwdzdyd{d|dwid}e) d~dd{dvdwddydwddyd{d|dwide) dddwddyd{d|dwidddwdDdgddddGgddddwdDdgdddwddyd{d|dwidddg ddZkddllmmZmmnZn  emjo        dtdekd eVdej           dS )a  
Delegate Tool -- Subagent Architecture

Spawns child AIAgent instances with isolated context, restricted toolsets,
and their own terminal sessions. Supports single-task and batch (parallel)
modes. The parent blocks until all children complete.

Each child gets:
  - A fresh conversation (no parent history)
  - Its own task_id (own terminal session, file ops cache)
  - A restricted toolset (configurable, with blocked tools always stripped)
  - A focused system prompt built from the delegated goal + context

The parent's context only sees the delegation call and the summary result,
never the child's intermediate tool calls or reasoning.
    N)ThreadPoolExecutorTimeoutError)AnyDictListOptional)TOOLSETScustom)
file_state)set_approval_callback)base_url_hostnameis_truthy_value)delegate_taskclarifymemorysend_messageexecute_codecommanddescriptionreturnc                 >    t                               d| |           dS )zAuto-deny dangerous commands in subagent threads (safe default).

    Returns 'deny' so the subagent sees a refusal it can recover from, and
    never calls input() (which would deadlock the parent TUI).
    zeSubagent auto-denied dangerous command: %s (%s). Set delegation.subagent_auto_approve: true to allow.denyloggerwarningr   r   kwargss      7/home/kuhnn/.hermes/hermes-agent/tools/delegate_tool.py_subagent_auto_denyr   I   s+     NN	?  
 6    c                 >    t                               d| |           dS )zAuto-approve dangerous commands in subagent threads (opt-in YOLO).

    Only installed when delegation.subagent_auto_approve=true. Returns 'once'
    so the subagent proceeds without blocking the parent UI.
    z1Subagent auto-approved dangerous command: %s (%s)oncer   r   s      r   _subagent_auto_approver#   W   s)     NN;   6r    c                      t                      } |                     dd          }t          |          rt          S t          S )a  Return the callback to install into subagent worker threads.

    Config key: delegation.subagent_auto_approve (bool, default False).
    Reads via the same _load_config() path as the rest of delegate_task so
    priority is config.yaml > (no env override for this knob) > default.
    subagent_auto_approveF)_load_configgetr   r#   r   cfgvals     r   _get_subagent_approval_callbackr+   d   s=     ..C
'')5
1
1Cs &%%r    >   rlmoasafe	debugging
delegationc              #      K   | ]T\  }}|t           v|                    d           #t          d |                    dg           D                       P|V  UdS )zhermes-c              3   (   K   | ]}|t           v V  d S N)DELEGATE_BLOCKED_TOOLS.0ts     r   	<genexpr>z<genexpr>.<genexpr>   s(      KK++KKKKKKr    toolsN)_EXCLUDED_TOOLSET_NAMES
startswithallr'   )r6   namedefns      r   r8   r8   {   s        d***OOI&& +KKTXXgr5J5JKKKKK + 	**** r    , c              #   "   K   | ]
}d | d V  dS )'N )r6   ns     r   r8   r8      s*      CC1h!hhhCCCCCCr          F_spawn_paused_active_subagentspausedc                 p    t           5  t          |           at          cddd           S # 1 swxY w Y   dS )zGlobally block/unblock new delegate_task spawns.

    Active children keep running; only NEW calls to delegate_task fail fast
    with a "spawning paused" error until unblocked.  Returns the new state.
    N)_spawn_pause_lockboolrF   )rH   s    r   set_spawn_pausedrL      s|     
  V                 s   +//c                  R    t           5  t          cd d d            S # 1 swxY w Y   d S r3   )rJ   rF   rB   r    r   is_spawn_pausedrN      so    	                   s     recordc                     |                      d          }|sd S t          5  | t          |<   d d d            d S # 1 swxY w Y   d S )Nsubagent_id)r'   _active_subagents_lockrG   )rO   sids     r   _register_subagentrT      s    
**]
#
#C 	 ( (!'#( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (s   9= =rQ   c                 |    t           5  t                              | d            d d d            d S # 1 swxY w Y   d S r3   )rR   rG   pop)rQ   s    r   _unregister_subagentrW      s    	 1 1k40001 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1s   155c                 P   t           5  t                              |           }ddd           n# 1 swxY w Y   |sdS |                    d          }|dS 	 |                    d|  d           n4# t          $ r'}t
                              d| |           Y d}~dS d}~ww xY wdS )aC  Request that a single running subagent stop at its next iteration boundary.

    Does not hard-kill the worker thread (Python can't); sets the child's
    interrupt flag which propagates to in-flight tools and recurses into
    grandchildren via AIAgent.interrupt().  Returns True if a matching
    subagent was found.
    NFagentzInterrupted via TUI ()z!interrupt_subagent(%s) failed: %sT)rR   rG   r'   	interrupt	Exceptionr   debug)rQ   rO   rY   excs       r   interrupt_subagentr_      s
    
  4 4"&&{334 4 4 4 4 4 4 4 4 4 4 4 4 4 4 uJJwE}u>>>>????   8+sKKKuuuuu 4s$   /33A2 2
B#<BB#c                      t           5  d t                                          D             cddd           S # 1 swxY w Y   dS )u   Snapshot of the currently running subagent tree.

    Each record: {subagent_id, parent_id, depth, goal, model, started_at,
    tool_count, status}.  Safe to call from any thread — returns a copy.
    c                 J    g | ] }d  |                                 D             !S )c                 &    i | ]\  }}|d k    ||S )rY   rB   r6   kvs      r   
<dictcomp>z4list_active_subagents.<locals>.<listcomp>.<dictcomp>   s#    888da1<<Q<<<r    )items)r6   rs     r   
<listcomp>z)list_active_subagents.<locals>.<listcomp>   s>     
 
 
 98aggii888
 
 
r    N)rR   rG   valuesrB   r    r   list_active_subagentsrk      s     
  
 

 
&--//
 
 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
s   #8<<   i@  max_entries	max_charsresultrn   ro   c                   t          | t                    r|                     d          nd}t          |t                    sg S g }i }|D ]}t          |t                    s|                    d          dk    ro|                    d          pg D ]W}|                    d          }|                    d          pi }	|r't	          |	                    d          pd	          ||<   Xt          |          D ]}t          |          |k    r nt          |t                    r|                    d          d	k    rF|                    d
          pd}
t          |
t                    st	          |
          }
t          |
          }|                    |                    d          pdd	          }|
d|         }|                    |||d           |	                                 |S )u8  Pull the last N tool-call results from a child's conversation.

    Powers the overlay's "Output" section — the cc-swarm-parity feature.
    We reuse the same messages list the trajectory saver walks, taking
    only the tail to keep event payloads small.  Each entry is
    ``{tool, preview, is_error}``.
    messagesNrole	assistant
tool_callsidfunctionr=   toolcontent tool_call_id)rx   previewis_error)

isinstancedictr'   liststrreversedlen_looks_like_error_outputappendreverse)rp   rn   ro   rr   tailpending_call_by_idmsgtctc_idfnry   r}   	tool_namer|   s                 r   _extract_output_tailr      s    *4FD)A)AKvzz*%%%tHh%% 	 "$D)+  N N#t$$ 	776??k))ggl++1r N NtVVJ''-2 N03BFF6NN4Lf0M0M&u- !! S St99##E#t$$ 	6(A(A'')$$*'3'' 	#'llG+G44&**377>+B+B+Hb&QQ	 *9*%Y7QQRRRRLLNNNKr    ry   c                    | sdS |                                  }|                    d          s|                    d          r	 t          j        |           }t	          |t
                    re|                    d          rdS t          |                    d          pd                                          	                                }|dv rdS n# t          $ r Y nw xY w|                                 r>|                                 d	                                         	                                nd}|                    d
          p>|                    d          p)|                    d          p|                    d          S )a  Conservative stderr/error detector for tool-result previews.

    The old heuristic flagged any preview containing the substring "error",
    which painted perfectly normal terminal/json output red.  We now only
    mark output as an error when there is stronger evidence:
      - structured JSON with an ``error`` key
      - structured JSON with ``status`` of error/failed
      - first line starts with a classic error marker
    F{[errorTstatusrz   >   r   failedfailuretimeoutr   zerror:zfailed:z
traceback z
exception:)lstripr;   jsonloadsr~   r   r'   r   striplowerr\   
splitlines)ry   headparsedr   firsts        r   r   r     s     u>>Ds 
ts33 
		Z((F&$''  ::g&&  4VZZ117R88>>@@FFHHFFF4 	 	 	D	 8?7I7I7K7KSG  #))++11333QSE"" 	*I&&	*L))	* L))	s   >C AC 
C C rh   c                     | | sdS t          |                                                                           }|dv r|S t                              d|            dS )a/  Normalise a caller-provided role to 'leaf' or 'orchestrator'.

    None/empty -> 'leaf'.  Unknown strings coerce to 'leaf' with a
    warning log (matches the silent-degrade pattern of
    _get_orchestrator_enabled).  _build_child_agent adds a second
    degrade layer for depth/kill-switch bounds.
    Nleaf>   r   orchestratorz1Unknown delegate_task role=%r, coercing to 'leaf')r   r   r   r   r   )rh   r_norms     r   _normalize_roler   8  s\     	yyvVV\\^^!!##F)))
NNFJJJ6r    c                     t                      } |                     d          }|	 t          dt          |                    }|dk    rt                              d|           |S # t          t          f$ r+ t                              d|t                     t          cY S w xY wt          j
        d          }|r<	 t          dt          |                    S # t          t          f$ r
 t          cY S w xY wt          S )ay  Read delegation.max_concurrent_children from config, falling back to
    DELEGATION_MAX_CONCURRENT_CHILDREN env var, then the default (3).

    Users can raise this as high as they want; only the floor (1) is enforced.

    Uses the same ``_load_config()`` path that the rest of ``delegate_task``
    uses, keeping config priority consistent (config.yaml > env > default).
    max_concurrent_childrenNrE   
   zxdelegation.max_concurrent_children=%d: each child consumes API tokens independently. High values multiply cost linearly.zNdelegation.max_concurrent_children=%r is not a valid integer; using default %d"DELEGATION_MAX_CONCURRENT_CHILDREN)r&   r'   maxintr   r   	TypeError
ValueError _DEFAULT_MAX_CONCURRENT_CHILDRENosgetenv)r)   r*   rp   env_vals       r   _get_max_concurrent_childrenr   I  s#    ..C
''+
,
,C
	4CHH%%F{{I  
 M:& 	4 	4 	4NN#0	   4333	4 i<==G 4	4q#g,,''':& 	4 	4 	43333	4++s#   ?A' '9B#"B#=C C54C5c                     t                      } |                     d          }|V	 t          dt          |                    S # t          t
          f$ r$ t                              d|t                     Y nw xY wt          j
        d          }|r5	 t          dt          |                    S # t          t
          f$ r Y nw xY wt          t                    S )zRead delegation.child_timeout_seconds from config.

    Returns the number of seconds a single child agent is allowed to run
    before being considered stuck.  Default: 600 s (10 minutes).
    child_timeout_secondsNg      >@zKdelegation.child_timeout_seconds=%r is not a valid number; using default %d DELEGATION_CHILD_TIMEOUT_SECONDS)r&   r'   r   floatr   r   r   r   DEFAULT_CHILD_TIMEOUTr   r   )r)   r*   r   s      r   _get_child_timeoutr   o  s     ..C
'')
*
*C
	tU3ZZ(((:& 	 	 	NN#%	    	 i:;;G 	tU7^^,,,:& 	 	 	D	&'''s#   A 2A98A9B0 0CCc                     t                      } |                     d          }|t          S 	 t          |          }n?# t          t
          f$ r+ t                              d|t                     t          cY S w xY wt          t          t          t          |                    }||k    r(t                              d|t          t          |           |S )aL  Read delegation.max_spawn_depth from config, clamped to [1, 3].

    depth 0 = parent agent.  max_spawn_depth = N means agents at depths
    0..N-1 can spawn; depth N is the leaf floor.  Default 1 is flat:
    parent spawns children (depth 1), depth-1 children cannot spawn
    (blocked by this guard AND, for leaf children, by the delegation
    toolset strip in _strip_blocked_tools).

    Raise to 2 or 3 to unlock nested orchestration. role="orchestrator"
    removes the toolset strip for depth-1 children when
    max_spawn_depth >= 2, enabling them to spawn their own workers.
    max_spawn_depthNzFdelegation.max_spawn_depth=%r is not a valid integer; using default %dzCdelegation.max_spawn_depth=%d out of range [%d, %d]; clamping to %d)r&   r'   	MAX_DEPTHr   r   r   r   r   r   _MIN_SPAWN_DEPTHmin_MAX_SPAWN_DEPTH_CAP)r)   r*   ivalclampeds       r   _get_max_spawn_depthr     s     ..C
''#
$
$C
{3xxz"   W	
 	
 	

  "C(<d$C$CDDG$T 	
 	
 	
 Ns   > 9A:9A:c                      t                      } |                     dd          }t          |t                    r|S t          |t                    r(|                                                                dv S dS )a   Global kill switch for the orchestrator role.

    When False, role="orchestrator" is silently forced to "leaf" in
    _build_child_agent and the delegation toolset is stripped as before.
    Lets an operator disable the feature without a code revert.
    orchestrator_enabledT>   1onyestrue)r&   r'   r~   rK   r   r   r   r(   s     r   _get_orchestrator_enabledr     sp     ..C
''($
/
/C#t 
#s Ayy{{  ""&@@@4r    c                  f    t                      } t          |                     d          d          S )zFWhether narrowed child toolsets should keep the parent's MCP toolsets.inherit_mcp_toolsetsTdefault)r&   r   r'   )r)   s    r   _get_inherit_mcp_toolsetsr     s+    
..C377#9::DIIIIr    r=   c                 "   | sdS t          |                               d          rdS 	 ddlm}  |j        t          |                     }n# t
          $ r d}Y nw xY wt          |o!t          |                              d                    S )zDReturn True for canonical MCP toolsets and their registered aliases.Fzmcp-Tr   )registryN)r   r;   tools.registryr   get_toolset_alias_targetr\   rK   )r=   r   targets      r   _is_mcp_toolset_namer     s     u
4yyF## t++++++223t99==   93v;;11&99:::s   #A AAparent_toolsetsc                    t                      }| D ]A}t          j        |          }|r)|                    |                    dg                      B|st          |           S t          |           }t          j                    D ]Y\  }}||v r
|                    dg           }|r7t          |                              |          r|                    |           Z|S )a@  Expand composite toolsets so individual toolset names are recognized.

    When a parent uses a composite toolset like ``hermes-cli`` (which bundles
    all core tools), the child may request individual toolsets such as ``web``
    or ``terminal``.  A simple name-based intersection would reject them
    because ``"web" != "hermes-cli"``.

    This helper collects the tool names from each parent toolset, then adds
    the names of any individual toolsets whose tools are a *subset* of the
    parent's available tools.  The original parent toolset names are preserved.
    r9   )setr	   r'   updaterg   issubsetadd)r   parent_tool_namests_namets_defexpandedts_toolss         r   _expand_parent_toolsetsr     s     !UU" > >g&& 	>$$VZZ%<%<=== $?###?##H#>++ " "h::gr** 	"H../@AA 	"LL!!!Or    child_toolsetsc                     t          |           }t          |          D ]*}t          |          r||vr|                    |           +|S )zFAppend any parent MCP toolsets that are missing from a narrowed child.)r   sortedr   r   )r   r   	preservedtoolset_names       r   _preserve_parent_mcp_toolsetsr     s]     ^$$I// + +-- 	+,i2O2O\***r    2   X        (   )terminalfilewebc                   .    e Zd ZdZdZdZdZdZdZdZ	dZ
d	S )
DelegateEventu  Formal event types emitted during delegation progress.

    _build_child_progress_callback normalises incoming legacy strings
    (``tool.started``, ``_thinking``, …) to these enum values via
    ``_LEGACY_EVENT_MAP``.  External consumers (gateway SSE, ACP adapter,
    CLI) still receive the legacy strings during the deprecation window.

    TASK_SPAWNED / TASK_COMPLETED / TASK_FAILED are reserved for
    future orchestrator lifecycle events and are not currently emitted.
    zdelegate.task_spawnedzdelegate.task_progresszdelegate.task_completedzdelegate.task_failedzdelegate.task_thinkingzdelegate.tool_startedzdelegate.tool_completedN)__name__
__module____qualname____doc__TASK_SPAWNEDTASK_PROGRESSTASK_COMPLETEDTASK_FAILEDTASK_THINKINGTASK_TOOL_STARTEDTASK_TOOL_COMPLETEDrB   r    r   r   r     sA        	 	 +L,M.N(K,M/3r    r   )	_thinkingzreasoning.availableztool.startedztool.completedsubagent_progress_LEGACY_EVENT_MAPc                      dS )z<Delegation has no external requirements -- always available.TrB   rB   r    r   check_delegate_requirementsr   4  s    4r    r      workspace_pathrs   r   child_depthgoalcontextr  rs   r   r  c                   ddd|  g}|r,|                                 r|                    d|            |r:t          |                                           r|                    d| d           |                    d           |dk    r+|d	z   |k    rd
nd}|                    d| d| d|            d                    |          S )a  Build a focused system prompt for a child agent.

    When role='orchestrator', appends a delegation-capability block
    modeled on OpenClaw's buildSubagentSystemPrompt (canSpawn branch at
    inspiration/openclaw/src/agents/subagent-system-prompt.ts:63-95).
    The depth note is literal truth (grounded in the passed config) so
    the LLM doesn't confabulate nesting capabilities that don't exist.
    z@You are a focused subagent working on a specific delegated task.rz   zYOUR TASK:
z

CONTEXT:
z
WORKSPACE PATH:
zg
Use this exact path for local repository/workdir operations unless the task explicitly says otherwise.a5  
Complete this task using the tools available to you. When finished, provide a clear, concise summary of:
- What you did
- What you found or accomplished
- Any files you created or modified
- Any issues encountered

Important workspace rule: Never assume a repository lives at /workspace/... or any other container-style path unless the task/context explicitly gives that path. If no exact local path is provided, discover it first before issuing git/workdir-specific commands.

Be thorough but concise -- your response is returned to the parent agent as a summary.r   rE   u   Your own children MUST be leaves (cannot delegate further) because they would be at the depth floor — you cannot pass role='orchestrator' to your own delegate_task calls.zYour own children can themselves be orchestrators or leaves, depending on the `role` you pass to delegate_task. Default is 'leaf'; pass role='orchestrator' explicitly when a child needs to further decompose its work.u  
## Subagent Spawning (Orchestrator Role)
You have access to the `delegate_task` tool and CAN spawn your own subagents to parallelize independent work.

WHEN to delegate:
- The goal decomposes into 2+ independent subtasks that can run in parallel (e.g. research A and B simultaneously).
- A subtask is reasoning-heavy and would flood your context with intermediate data.

WHEN NOT to delegate:
- Single-step mechanical work — do it directly.
- Trivial tasks you can execute in one or two tool calls.
- Re-delegating your entire assigned goal to one worker (that's just pass-through with no value added).

Coordinate your workers' results and synthesize them before reporting back to your parent. You are responsible for the final summary, not your workers.

NOTE: You are at depth z3. The delegation tree is capped at max_spawn_depth=z. 
)r   r   r   join)r  r  r  rs   r   r  parts
child_notes           r   _build_child_system_promptr
  9  s]   $ 	K
tE
  /7==?? /-G--... 
#n--3355 
uu u u	
 	
 	

 
LL		%   ~
 Q/11C C3 	 	L  '2!L L" -<#L L" @J#L L	
 	
 	
( 99Ur    c                    t          j        d          t          t          | dd          dd          t          | dd          t          | dd          g}|D ]}|s	 t           j                            t           j                            t          |                              }n# t          $ r Y \w xY wt           j                            |          r#t           j        	                    |          r|c S dS )a  Best-effort local workspace hint for child prompts.

    We only inject a path when we have a concrete absolute directory. This avoids
    teaching subagents a fake container path while still helping them avoid
    guessing `/workspace/...` for local repo tasks.
    TERMINAL_CWD_subdirectory_hintsNworking_dirterminal_cwdcwd)
r   r   getattrpathabspath
expanduserr   r\   isabsisdir)parent_agent
candidates	candidatetexts       r   _resolve_workspace_hintr    s     		.!!L"7>>t	
 	
 	nd33eT**J    	 		7??27#5#5c)nn#E#EFFDD 	 	 	H	7== 	27==#6#6 	KKK4s   A	B''
B43B4toolsetsc                 (    h dfd| D             S )z0Remove toolsets that contain only blocked tools.>   r   r   r0   code_executionc                     g | ]}|v|	S rB   rB   )r6   r7   blocked_toolset_namess     r   ri   z(_strip_blocked_tools.<locals>.<listcomp>  s$    BBB!1,A#A#AA#A#A#Ar    rB   )r  r   s    @r   _strip_blocked_toolsr!    s2       CBBBxBBBBr    rQ   	parent_iddepthmodelr  
task_index
task_countr#  r$  r%  c                    t          |dd          t          |dd          ssdS dk    r	d dz    dnd|pd                                dg d	gd
t          t          t          f         f f	d	 ddt          dt          dt          ffd	 ddt          dt          ff	d}	fd}
|
|	_        |	S )u  Build a callback that relays child agent tool calls to the parent display.

    Two display paths:
      CLI:     prints tree-view lines above the parent's delegation spinner
      Gateway: batches tool names and relays to parent's progress callback

    The identity kwargs (``subagent_id``, ``parent_id``, ``depth``, ``model``,
    ``toolsets``) are threaded into every relayed event so the TUI can
    reconstruct the live spawn tree and route per-branch controls (kill,
    pause) back by ``subagent_id``.  All are optional for backward compat —
    older callers that ignore them still produce a flat list on the TUI.

    Returns None if no display mechanism is available, in which case the
    child agent runs with no progress callback (identical to current behavior).
    _delegate_spinnerNtool_progress_callbackrE   r   ] rz      r   r   c                     	 d} | d<   | d<   | d<   | d<   	t          	          | d<   d         | d<   | S )	N)r&  r'  r  rQ   r#  r$  r%  r  r   
tool_count)r   )
kw_tool_countr$  
goal_labelr%  r#  rQ   r'  r&  r  s
    r   _identity_kwargsz8_build_child_progress_callback.<locals>._identity_kwargs  s    $$
 

 " +B} 'B{OBwKBwK!(^^BzN&q><	r    
event_typer   r|   c                     sd S              }|                     |           	  | |||fi | d S # t          $ r&}t                              d|           Y d }~d S d }~ww xY w)NzParent callback failed: %s)r   r\   r   r]   )	r3  r   r|   argsr   payloader2  	parent_cbs	          r   _relayz._build_child_progress_callback.<locals>._relay  s      	F""$$v	:Ij)WdFFgFFFFF 	: 	: 	:LL5q999999999	:s   4 
A$AA$c                   	 | dk    rrsrqt                    dk    rd d         dz   n}	                     d d|            n2# t          $ r%}t                              d|           Y d }~nd }~ww xY w dd|ppdi| d S | d	k    r dd|i| d S t          | t                    r| }nEt                              |           }|)	 t          |           }n# t          t          f$ r Y d S w xY w|t          j        k    r|p|pd}rrt          |          dk    r|d d         dz   n|}	                     d d
| d           n2# t          $ r%}t                              d|           Y d }~nd }~ww xY w d|           d S |t          j        k    rd S |t          j        k    r|p|pd}	rQ|	rO	                     d d|	            n2# t          $ r%}t                              d|           Y d }~nd }~ww xY wrD	  d |	            n2# t          $ r%}t                              d|           Y d }~nd }~ww xY wd S dxx         dz  cc<   Mt          5  t                                        }
|
d         |
d<   |pd|
d<   d d d            n# 1 swxY w Y   r|r t          |          dk    r|d d         dz   n|pd}ddlm}  ||pd          }d d| d| }|r	|d| dz  }	                     |           n2# t          $ r%}t                              d|           Y d }~nd }~ww xY wru d|||                               |pd           t                    k    r?d                              } dd |                                             d S d S d S )Nsubagent.start7   z... u   ├─ 🔀 zSpinner print_above failed: %sr|   rz   subagent.completeu   ├─ 💭 ""zsubagent.thinkingr|   r   z Parent callback relay failed: %sr   rE   r.  	last_tool#   )get_tool_emojiu   ├─ z  "zsubagent.toolr?   subagent.progress   🔀 )r;  r>  )r   print_abover\   r   r]   r~   r   r   r'   r   r   r   r   r   rR   rG   agent.displayrC  r   r  clear)r3  r   r|   r5  r   shortr7  eventr  summary_textrecrC  emojilinesummary_BATCH_SIZE_batchr9  r0  r1  r8  prefixspinnerrQ   s                  r   	_callbackz1_build_child_progress_callback.<locals>._callback  s   
 ))) F: F14Z21E1EZ_u,,: F''(GF(G(G(G(GHHHH  F F FLL!A1EEEEEEEEFFSSW-H
-HbSFSSSF,,,FBBB6BBBF j-00 	EE%))*55E})*55EE"I.   FF M///-i-2D F/24yy2~~crcU**4F''(IF(I(I(I(I(IJJJJ  F F FLL!A1EEEEEEEEFF&5555FM555FM/// %552L F< FF''(NF(N(N(N(NOOOO  F F FLL!A1EEEEEEEEF HHI1f3Ll3L3LMMMM  H H HLL!CQGGGGGGGGHF 	A!"' 7 7'++K88?(3AC%'0BC$	7 7 7 7 7 7 7 7 7 7 7 7 7 7 7
  	B %"7||b00 "%%m 
 544444"N9?33E9v99e99i99D 'e&B##D)))) B B B=qAAAAAAAAB  	F?Iw===MM)/r***6{{k))))F++*4MF4MG4M4MNNNN	 	 *)s   A 
A:A55A:C$ $C98C97E 
FE>>FG 
H(HHH$ $
I.II1/J,,J03J0	L 
M)M		Mc                      r?r?d                               }  dd |                                              dS dS dS )z<Flush remaining batched tool names to gateway on completion.r?   rD  rE  r@  N)r  rI  )rP  rR  r9  r8  rS  s    r   _flushz._build_child_progress_callback.<locals>._flush[  sl     	 	ii''GF&0I0I0I0IJJJJLLNNNNN	 	 	 	r    )NNN)r  r   r   r   r   rW  )r&  r  r  r'  rQ   r#  r$  r%  r  rU  rW  rQ  rR  r2  r9  r0  r1  r8  rS  rT  s   `  ``````  @@@@@@@@@r   _build_child_progress_callbackrX    s   6 l$7>>G&>EEI 9 t (2A~~#a####2F*"##%%J KF#Kd38n              ( KO
: 
:
:$'
:9<
: 
: 
: 
: 
: 
: 
: FJe e"e47e e e e e e e e e e e e e eN        Ir    max_iterationsoverride_provideroverride_base_urloverride_api_keyoverride_api_modeoverride_acp_commandoverride_acp_argsc                   9:;< ddl m} ddl}t          |dd          dz   }t	                      }t                      o||k     }|dk    r|r|nd}d|  d	|                                j        dd
          }t          |dd          }t          d|dz
            }t                      }t          |dd          }|t          |          }n?|r)t          |d          rddl;;<fd|j        D             }nt          t                    }|rKt          |          ::fd|D             }t!                      rt#          ||          }t%          |          }nG|r|t%          |          }n3|rt%          t'          |                    }nt%          t                    }|dk    rd|vr|                    d           t+          |          }t-          ||||||          }t          |dd          }|s*t          |d          r|j                            d          }|pt          |dd          }t3          | ||||||||	  	        9d} 9rdt4          ddf9fd}!|!} |p|j        }"|pt          |dd          }#|	p|j        }$|
p|}%t          |dd          pd}&||}'n|#|&k    rd}'nt          |dd          }'|pt          |dd          }(t;          ||nt          |dg           pg           })|r|sd}(g })|rd}#d}'t          |d d          }*|*}+	 t5          |                    d!          pd                                          },|,r1dd"lm }-  |-|,          }.|.|.}+ntB          "                    d#|,           n2# tF          $ r%}/tB          $                    d$|/           Y d}/~/nd}/~/ww xY wt          |d%d          pd}0t          |d&d          }1t          |d'd          }2t          |d(d          }3t          |d)d          }4t          |d*d          }5|rd}1d}2d}3d}4 |dGi d+|$d|%d|"d|#d|'d|(d|)d,|d-t          |d-d          d |+d.t          |d.d          d/|0d|d0d1d2|d3d4|  d5d6|j%        d7d1d8d1d9dd:| d;t          |d<d          d=t          |d>d          d&|1d'|2d(|3d)|4d*|5d?9d@d}6t          |dAd          |6_&        ||6_'        ||6_(        ||6_)        ||6_*        ||6_+        tY          |#|          }7|7|7|6_-        t          |dB          rbt          |dCd          }8|8r5|85  |j.                            |6           ddd           n# 1 swxY w Y   n|j.                            |6           9rA	  9dD|E           n2# tF          $ r%}/tB          $                    dF|/           Y d}/~/nd}/~/ww xY w|6S )Ha  
    Build a child AIAgent on the main thread (thread-safe construction).
    Returns the constructed child agent without running it.

    When override_* params are set (from delegation config), the child uses
    those credentials instead of inheriting from the parent.  This enables
    routing subagents to a different provider:model pair (e.g. cheap/fast
    model on OpenRouter while the parent runs on Nous Portal).
    r   )AIAgentN_delegate_depthrE   r   r   zsa--   _subagent_idenabled_toolsetsvalid_tool_namesc                 B    h | ]}                     |          xS r3   )get_toolset_for_tool)r6   r=   model_toolstss     r   	<setcomp>z%_build_child_agent.<locals>.<setcomp>  s<     
 
 
!66t<<<I IIIr    c                     g | ]}|v |	S rB   rB   )r6   r7   expanded_parents     r   ri   z&_build_child_agent.<locals>.<listcomp>  s#    FFFo1E1E!1E1E1Er    r0   r   api_key_client_kwargsr%  r"  r  r   c                     | sd S 	  d|            d S # t           $ r&}t                              d|           Y d }~d S d }~ww xY w)Nr   z(Child thinking callback relay failed: %s)r\   r   r]   )r  r7  child_progress_cbs     r   _child_thinkingz+_build_child_agent.<locals>._child_thinking  sy     L!!+t44444 L L LGKKKKKKKKKLs    
AA  Aproviderrz   api_modeacp_commandacp_argszcopilot-acpchat_completionsreasoning_configreasoning_effort)parse_reasoning_effortzAUnknown delegation.reasoning_effort '%s', inheriting parent levelz.Could not load delegation reasoning_effort: %s_fallback_chainproviders_allowedproviders_ignoredproviders_orderprovider_sortopenrouter_min_coding_scorebase_urlrY  
max_tokensprefill_messagesfallback_model
quiet_modeTephemeral_system_prompt
log_prefix
[subagent-]platformskip_context_filesskip_memoryclarify_callbackthinking_callback
session_db_session_dbparent_session_id
session_idr*  iteration_budget	_print_fn_active_children_active_children_lockzsubagent.spawn_requestedr@  z spawn_requested relay failed: %srB   )/	run_agentra  uuidr  r   r   uuid4hexr   r&   r   hasattrrj  rg  DEFAULT_TOOLSETSr   r   r   r!  r   r   r  r
  rp  r'   rX  r   r%  r  r   r   hermes_constantsr{  r   r   r\   r]   r  r  rb  _delegate_rolere  _parent_subagent_id_subagent_goal_resolve_child_credential_pool_credential_poolr  )=r&  r  r  r  r%  rY  r'  r  rZ  r[  r\  r]  r^  r_  rs   ra  _uuidr  	max_spawnorchestrator_okeffective_rolerQ   parent_subagent_id	tui_depthdelegation_cfgparent_enabledr   r   workspace_hintchild_promptparent_api_keyeffective_model_for_cbchild_thinking_cbrs  effective_modeleffective_providereffective_base_urleffective_api_key_parent_providereffective_api_modeeffective_acp_commandeffective_acp_argsparent_reasoningchild_reasoningdelegation_effortr{  r   r^   parent_fallbackchild_providers_allowedchild_providers_ignoredchild_providers_orderchild_provider_sort!child_openrouter_min_coding_scorechild
child_poollockrr  rn  rj  rk  s=                                                            @@@@r   _build_child_agentr  f  sJ	   > "!!!!! ,(91==AK$&&I/11MkI6MO"n444TTvN =
<<U[[]]%6rr%:<<K ~tDDA{Q''I!^^N \+=tDDN!n--	 
0',0BCC 
0
 
 
 
 
$5
 
 
 .// @ 2/BBFFFFXFFF$&& 	: N .n==	 @.4-n==	 @-f_.E.EFF-.>?? ''L,N,Nl+++,\::N-%!  L \9d;;N D6F G G D%488CC #JglGT&J&J
 7$$
 
 
"  
,	L# 	L$ 	L 	L 	L 	L 	L 	L , 1|1O*UglJPT.U.U*Cl.C(:N |Z>>D"$.	/	/	/!$\:tDD0 GmT5 5 ( 	lJ339r    !5   $ 0 +/ |-?FF&OL 2 23E F F L"MMSSUU 
	??????++,=>>F!"(W%    L L LEsKKKKKKKKL l,=tDDLO &l4GNN%l4GNN#L2CTJJ!,FF(/>[]a(b(b% #"&"& $"
 G   ##!! o $#	
 $# *) $# &~ <t<<< ) !/A4HHH ' ( 4 !-  .
----!" &&#$  4%& D'( )* ,++, <===-. ",dCCC/0 2112 2134 .-56 *)78 %F$E9:  10;< =E@ lK>>EO'E *E %E 2EE 00BLQQJ!+ |/00 8|%<dCC 	8 < <-44U;;;< < < < < < < < < < < < < < < )00777
  B	B8$GGGGG 	B 	B 	BLL;SAAAAAAAA	B LsC   A)M> >
N-N((N->U%%U),U)V 
W&WWr  timeout_secondsduration_secondsworker_threadc                 4  ! 	 ddl m} ddl}ddl}ddl}	 |            }
|
dz  }	 |                    dd           n# t          $ r Y dS w xY wt          | dd          pd| }|j                                        	                    d	          }|d
| d| dz  }g !dFdt          ddf!fd} |d            |d|j                                                                                     |d            |d            |d|             |d|             |d| d            |d|dd            |d            |d           |pd                                }t          |          dk    r|dd         dz   } ||pd            |d            |d           dD ]`}	 t          | |d          }t          |t                    r|d k    r	  |d!| d"|           B# t          $ r  |d!| d#           Y ]w xY w |d            |d$           t          | d%d          } |d&|           t          | d'd          }|rH |d(t          |                      	  |d)t          |                      n# t          $ r Y nw xY w |d            |d*           	 t          | d+d          pt          | d,d          pd} |d-t          |t                    r"t          |                    d.                    nd/             |d0t          |t                    rt          |          nd/            n&# t          $ r} |d1| d2           Y d}~nd}~ww xY w	 t          | d3d          }|dt#          j        |t          4          } |d5t          |                       |d6t          |                    d.                                n&# t          $ r} |d7| d2           Y d}~nd}~ww xY w |d            |d8           	 |                                 }|                                D ]\  }} |d!| d"|           n&# t          $ r} |d9| d2           Y d}~nd}~ww xY w |d            |d:           ||                                r|                                }|                    |j                  }|S|	                    |          }|D ]:}|                                                    d;          D ]}  |d!|             ;n% |d<           n| |d=           n |d>            |d            |d?            |d@            |dA            |dB            |dC           |                    d;                    !          d.D           t          |          S # t          $ r&}t<                              dE|           Y d}~dS d}~ww xY w)Ga,  Write a structured diagnostic dump for a subagent that timed out
    before making any API call.

    See issue #14726: users hit "subagent timed out after 300s with no response"
    with zero API calls and no way to inspect what happened. This helper
    writes a dedicated log under ``~/.hermes/logs/subagent-<sid>-<ts>.log``
    capturing the child's config, system-prompt / tool-schema sizes, activity
    tracker snapshot, and the worker thread's Python stack at timeout.

    Returns the absolute path to the diagnostic file, or None on failure.
    r   )get_hermes_homeNlogsT)parentsexist_okre  idxz%Y%m%d_%H%M%Szsubagent-timeout-rc  z.logrz   rO  r   c                 2                         |            d S r3   )r   )rO  liness    r   _wz-_dump_subagent_timeout_diagnostic.<locals>._w  s    LLr    u.   # Subagent timeout diagnostic — issue #14726z# Generated: z
## Timeoutz  task_index:        z  subagent_id:       z  configured_timeout: sz  actual_duration:   z.2fz## Goal  z ...[truncated]z(empty)z## Child config)r%  rt  ru  r  rY  r  r  r  r  r  rb  r    z: z: <unreadable>z## Toolsetsrf  z  enabled_toolsets:  rg  z  loaded tool count: z  loaded tools:      z## Prompt / schema sizesr  system_promptz  system_prompt_bytes: zutf-8zn/az  system_prompt_chars: z  system_prompt: <error: >r9   r   z  tool_schema_count: z  tool_schema_bytes: z  tool_schema: <error: z## Activity summaryz   <get_activity_summary failed: z!## Worker thread stack at timeoutr  z  <worker frame not available>z  <no worker thread handle>z   <worker thread already exited>z## NoteszG  This file is written ONLY when a subagent times out with 0 API calls.zI  0-API-call timeouts mean the child never reached its first LLM request.zG  Common causes: oversized prompt rejected by provider, transport hang,z<  credential resolution stuck. See issue #14726 for context.)encodingz+Subagent timeout diagnostic dump failed: %s)rz   ) r  r  datetimesys	tracebackmkdirr\   r  nowstrftimer   	isoformatr   r   r~   r   encoder   dumpsget_activity_summaryrg   is_alive_current_framesr'   identformat_stackrstripsplit
write_textr  r   r   )"r  r&  r  r  r  r  r  _dt_sys
_tracebackhermes_homelogs_dirrQ   rk  	dump_pathr  _goal_previewattrr*   enabled
tool_names
sys_promptr^   tools_schema_schema_jsonrP  rd   re   framesworker_framestack
frame_linesubr  s"                                    @r   !_dump_subagent_timeout_diagnosticr    sw   (y444444&&&&%o'''	NN4$N7777 	 	 	44	 e^T::P>PJ>P>P\((99I;IIIIII		 	S 	$ 	 	 	 	 	 	 	<===
;3<++--7799;;<<<
2
<
/://000
0;00111
6O666777
:#3::::;;;
2
9**,,}$$)%4%03DDM
=%I&&&
2

 	. 	.D
.eT400c3'' DJ,>,>'''''(((( . . .,,,,-----.
2
=%!3T::
.7..///U$6==
 	B8s:88999?6*+=+=??@@@@   
2
%&&&	3 (A4HH 5/488  BtJWacfLgLg)rZ->->w-G-G)H)H)HmrttuuuBdJzSV<W<W)bZ]bddeeee 	3 	3 	3B1311122222222	3	1"5'488L'#z,DDD>3|+<+<>>???N3|/B/B7/K/K+L+LNNOOO 	1 	1 	1B////00000000	1
2
 !!!	:0022G $ $1???Q??####$ 	: 	: 	:B8#88899999999	:
2
.///$)?)?)A)A$))++F!::m&9::L'"//=="' ' 'J)002288>> ' ':::'' 34444"B,----B1222
2
:
TUUU
VWWW
TUUU
IJJJTYYu--@@@9~~   DcJJJttttts  !W' = W' 
AW' 
AE)W' 5>G43W' 4HW' HA&W' 7J W' 
J W' J  W' :BM W' 
M9 M4/W' 4M99W' =A7O5 4W' 5
P?PW' PW' 2?Q2 1W' 2
R<RW' REW' '
X1XXc                 T)   GHIJKL t          j                    }t          dd          }ddl}t          dt	          |j                            }t          dd          }	d}
|	|	                                }
|
o	 |	                                }|%t          d          r	                    |           n2# t          $ r%}t                              d|           Y d}~nd}~ww xY wt          j                    GdgHdgIdgJGHIJ fd}t          j        |d	
          }t          dd          }t!          |t"                    r|nd}|rt          dd          }t!          |t$                    rt'          d|dz
            nd}t          dd          }t)          |t!          |t"                    r|nd|t!          t          dd          t"                    rt          dd          ndt          j                     ddd	           	 |                                 |rA	  |d           n2# t          $ r%}t                              d|           Y d}~nd}~ww xY wddl}|p&d  d|                                j        dd          Lt          dd          }t          j                     }|r!t	          t3          j        |                    ng }t7                      }t9          dt:          t=                      f          }ddiKKLfd}|                    |          }	 |                     |          }n# t          $ r}	 t          d          r!                                 nt          d          rd	_"        n# t          $ r Y nw xY wt!          |tF          tH          f          }tK          t          j                    |z
  d          } t          &                    d  |rd!nd"tO          |          j(         |            d}!d}"	 )                                }#t%          |#*                    d#d          pd          }"n# t          $ r Y nw xY w|rf|"dk    r`tW           tY          |          tY          |           K*                    d          $          }!|!rt          &                    d% |!           |r;	  |d&|rd'|  d(nt#          |          |rd)nd*| d+,           n# t          $ r Y nw xY w|r!|"dk    rd-| d.}$|!r|$d/|! z  }$nd-| d0|" d1}$nt#          |          }$ |rd)nd*d|$|rd)nd*|"| t          d2d          |!d3	cY d}~|-                    d45           G.                                 |j/        |0                    d6           |rtc          |           |	K|
I	 |	2                    |
           n2# t          $ r%}t                              d7|           Y d}~nd}~ww xY wddl}t          dd          }%t!          |%t                    rt	          |%          |_        t          d8          r	 t          d9d          }&|&r5|&5  j3        4                               ddd           n# 1 swxY w Y   nj3        4                               n9# tj          tl          f$ r%}t                              d:|           Y d}~nd}~ww xY w	 t          d;          r7                                 S S # t          $ r t                              d<           Y S w xY wd}~ww xY w	 |-                    d45           n# |-                    d45           w xY w|rXt          |d=          rH	 |8                                 n2# t          $ r%}t                              d>|           Y d}~nd}~ww xY wtK          t          j                    |z
  d          } |*                    d?          pd+}'|*                    d@d4          }(|*                    dAd4          })|*                    dBd          }*|)rdA}+n|'rd@}+ndC}+g },i }-|*                    dD          pg }.t!          |.t                    r|.D ]}/t!          |/tr                    s|/*                    dE          dFk    r|/*                    dG          pg D ]}0|0*                    dHi           }1|1*                    dIdJ          tu          |1*                    dKd+                    dL}2|,;                    |2           |0*                    dM          }3|3r|2|-|3<   |/*                    dE          dNk    r|/*                    dOd+          }4ty          |4          }5tu          |4          |5rd*ndPdQ}6|/*                    dR          }3|3r|-*                    |3          nd}7|7|7=                    |6           i|,r|,dS         =                    |6           |)rdA}8n|(rd@}8ndT}8t          dUd          }9t          dVd          }:t          dd          }; |+|'|*| t!          |;t"                    r|;nd|8t!          |9t$          tX          f          r|9ndt!          |:t$          tX          f          r|:nddW|,t          d2d          t!          t          dXdY          t$          tX          f          r tY          t          dXdY          pdY          ndYdZ}<|+dCk    r|*                    d*d[          |<d*<   	 |r|rt3          j>        |||          }=|=rt          d\ |=@                                D                       }>|>rxd]d^0                    |>dd                   z   tu          |>          dk    rd_tu          |>          dz
   d`nd+z   daz   }?|<*                    db          r|<db         |?z   |<db<   n|>|<dc<   n,# t          $ r t                              ddd	e           Y nw xY wt          dXd          }@t          dfd          }A	 t	          t3          j        L                    ddg         }Bn# t          $ r g }BY nw xY w	 t3          j>        d+|g           }Cn# t          $ r i }CY nw xY wt          Lfdh|CA                                D                       ddg         }Dt          |ddij          }E|'r
|'ddk         n|<*                    d*d+          |+| |'r
|'ddl         n|<*                    d*d+          t!          |9t$          tX          f          rt%          |9          ndt!          |:t$          tX          f          rt%          |:          ndt!          |At$          tX          f          rt%          |A          ndt!          |*t$          tX          f          rt%          |*          nd|B|D|Edm}F|@+	 tY          |@          |Fdn<   n# t          tj          f$ r Y nw xY w|r<	  |dti |F n2# t          $ r%}t                              do|           Y d}~nd}~ww xY w|<G.                                 |j/        |0                    d6           |rtc          |           |	K|
I	 |	2                    |
           n2# t          $ r%}t                              d7|           Y d}~nd}~ww xY wddl}t          dd          }%t!          |%t                    rt	          |%          |_        t          d8          r	 t          d9d          }&|&r5|&5  j3        4                               ddd           n# 1 swxY w Y   nj3        4                               n9# tj          tl          f$ r%}t                              d:|           Y d}~nd}~ww xY w	 t          d;          r7                                 S S # t          $ r t                              d<           Y S w xY w# t          $ r}tK          t          j                    |z
  d          } t          jE        dp  dq           |r^	  |d&t#          |          dC| t#          |          ,           n2# t          $ r%}t                              dr|           Y d}~nd}~ww xY w d*dt#          |          d| t          d2d          dscY d}~G.                                 |j/        |0                    d6           |rtc          |           |	K|
I	 |	2                    |
           n2# t          $ r%}t                              d7|           Y d}~nd}~ww xY wddl}t          dd          }%t!          |%t                    rt	          |%          |_        t          d8          r	 t          d9d          }&|&r5|&5  j3        4                               ddd           n# 1 swxY w Y   nj3        4                               n9# tj          tl          f$ r%}t                              d:|           Y d}~nd}~ww xY w	 t          d;          r7                                 S S # t          $ r t                              d<           Y S w xY wd}~ww xY w# G.                                 |j/        |0                    d6           |rtc          |           |	K|
I	 |	2                    |
           n2# t          $ r%}t                              d7|           Y d}~nd}~ww xY wddl}t          dd          }%t!          |%t                    rt	          |%          |_        t          d8          r	 t          d9d          }&|&r5|&5  j3        4                               ddd           n# 1 swxY w Y   nj3        4                               n9# tj          tl          f$ r%}t                              d:|           Y d}~nd}~ww xY w	 t          d;          r7                                 w w # t          $ r t                              d<           Y w w xY wxY w)uzi
    Run a pre-built child agent. Called from within a thread.
    Returns a structured result dict.
    r*  Nr   _delegate_saved_tool_namesr  _swap_credentialz-Failed to bind child to leased credential: %sc                     
                     t                    spt          dd           } | s2d d}	                                 }|                    d          }|                    dd          }|                    dd          }|d         k    }|d         k    }|s|r|d<   |d<   dd<   ndxx         dz  cc<   |rt
          nt          }d         |k    r't                              d	d         |pd
           d S |rd| d| d| d}n$|                    dd          }	|	rd|	 d| d| d}n# t          $ r Y nw xY w	  | |           n# t          $ r Y nw xY w
                     t                    nd S d S )N_touch_activityzdelegate_task: subagent z workingcurrent_toolapi_call_countr   rY  rE   u_   Subagent %d appears stale (no progress for %d heartbeat cycles, tool=%s) — stopping heartbeatz<none>z delegate_task: subagent running z (iteration /rZ   last_activity_descrz   )
wait_HEARTBEAT_INTERVALr  r  r'   _HEARTBEAT_STALE_CYCLES_IN_TOOL_HEARTBEAT_STALE_CYCLES_IDLEr   r   r\   )touchdescchild_summary
child_tool
child_iter	child_maxiter_advancedtool_changedstale_limit
child_desc_heartbeat_stop_last_seen_iter_last_seen_tool_stale_countr  r  r&  s             r   _heartbeat_loopz*_run_single_child.<locals>._heartbeat_loopY  s   !&&':;; B	#L*;TBBE BjBBBD6 % : : < <*..~>>
*../?CC
)--.>BB	 !+_Q-? ?)_Q-??  )L ))3OA&)3OA&&'LOO OOOq(OOO "6335 
  ?k11NNL"$Q".h   E @: @ @&0@ @3<@ @ @ D
 "/!2!23G!L!LJ! Dz D D*4D D7@D D D     d   C "&&':;; B	 B	 B	 B	 B	s*   CE 3E 
EEE   
E-,E-T)r   daemonre  rb  rE   r  r%  running)	rQ   r#  r$  r  r%  
started_atr   r.  rY   r;  r@  z"Progress callback start failed: %sz	subagent-rc  rd  _current_task_id)max_workersinitializerinitargsr7   c                  ^    t          j                     d<                                 S )Nr7   )user_messagetask_id)	threadingcurrent_threadrun_conversation)_worker_thread_holderr  child_task_idr  s   r   _run_with_thread_capturez3_run_single_child.<locals>._run_with_thread_capture  s:    )2)A)C)C!#&))!% *   r    )r   r[   _interrupt_requestedr   zSubagent %d %s after %.1fsz	timed outzraised r  )r  r&  r  r  r  r  u;   Subagent %d 0-API-call timeout — diagnostic written to %sr>  zTimed out after r  r   r   rz   )r|   r   r  rP  zSubagent timed out after u   s without making any API call — the child never reached its first LLM request (prompt construction, credential resolution, or transport may be stuck).z Diagnostic: zs with u[    API call(s) completed — likely stuck on a slow API call or unresponsive network request.r  )	r&  r   rP  r   exit_reason	api_callsr  _child_rolediagnostic_pathF)r  r,  z&Failed to release credential lease: %sr  r  z/Could not remove child from active_children: %sclosez,Failed to close child agent after delegationrW  z"Progress callback flush failed: %sfinal_response	completedinterruptedr*  r   rr   rs   rt   ru   rw   r=   unknown	arguments)rx   
args_bytesrv   rx   ry   ok)result_bytesr   r{   rY  session_prompt_tokenssession_completion_tokens)inputoutputsession_estimated_cost_usd        )r&  r   rP  r*  r  r%  r)  tokens
tool_tracer+  _child_cost_usdz$Subagent did not produce a response.c                     h | ]	}|D ]}|
S rB   rB   )r6   pathsps      r   rl  z$_run_single_child.<locals>.<setcomp>  s%    OOOuOOAOOOOr    uX   

[NOTE: subagent modified files the parent previously read — re-read before editing: r?   z (+z more)r  rP  stale_pathsz%file_state sibling-write check failedexc_infosession_reasoning_tokensr   c                 0    h | ]\  }}|k    |D ]}|S rB   rB   )r6   tidrA  rB  r&  s       r   rl  z$_run_single_child.<locals>.<setcomp>  sC       C-'' (' ''''r    r   rm      i  )r|   r   r  rP  input_tokensoutput_tokensreasoning_tokensr*  
files_readfiles_writtenoutput_tailcost_usdz'Progress callback completion failed: %sr  z] failedz*Progress callback failure relay failed: %sr&  r   rP  r   r*  r  r+  rF  )Ftime	monotonicr  rj  r   _last_resolved_tool_namesacquire_leasecurrentr  r  r\   r   r]   r"  EventThreadr~   r   r   r   rT   startr  r  r  r   known_readsr   r   _set_subagent_approval_cbr+   submitrp   r[   r(  FuturesTimeoutErrorr   roundr   typer   r  r'   r  r   shutdownr   r  r  rW   release_leaser  remover   UnboundLocalErrorr-  rW  r   r   r   r   r   writes_sincer   rj   rg   r   r   logging	exception)Mr&  r  r  r  _kwargschild_startrr  rj  _saved_tool_namesr  leased_cred_idleased_entryr^   r  _heartbeat_thread_raw_sidre  
_raw_depth
_tui_depth_parent_sidr7  r  parent_task_id
wall_startparent_reads_snapshotchild_timeout_timeout_executorr'  _child_futurerp   _timeout_exc
is_timeoutdurationr,  child_api_calls_summary_errsaved_tool_namesr  rP  r/  r0  r*  r   r>  trace_by_idrr   r   r   r   entry_tr   ry   r}   result_metar   r)  _input_tokens_output_tokens_modelentrysibling_writes	mod_pathsreminder	_cost_usd_reasoning_tokens_files_read_files_written_map_files_written_output_tailcomplete_kwargsr  r  r  r  r%  r&  sM   ````                                                                   @@@@@@r   _run_single_childr  )  s    .""K  '?FF +T+2W-X-X   2D99JN#1133%S)1133+?Q0R0R+**<888 S S SLcRRRRRRRRS  o''O cOfO3LC C C C C C C C C C CJ "(MMM und33H)(C88B88dL 
U$5q99
/9*c/J/JQSJN+++PQ
e%:DAA+,6{C,H,HR[[d# "'%$"?"?EEGE7D111"ikk# 	
 	
 	
$hI!!! 	FF!!"2DAAAAA F F FA1EEEEEEEEF 	$X(XJ(X(XARSUTUSUAV(X(X /A4HHY[[
<JRD'77888PR 	 +,,.
 25779
 
 
 ILT{	 	 	 	 	 	 	 	 *001IJJ`	3"))-)@@FF Z	 Z	 Z	5+.. 6OO%%%%U$:;; 615E.    $L3F2UVVJT^--;Q??HNN,)V/Vl9K9K9T/V/V	   .2OO 5577"%hll3CQ&G&G&L1"M"M    o22"C)$)-$8$8%*8__"7";";C"@"@# # # # NNU"'   ! %%+  *3:x::::!$\!2!2,6CyyG)1 "
 
 
 
 
 !   D  )"a''CM C C C  ' B A A AAUM U U*U U U D <(( )'1>))w,6CyyG,$,&u.>EE#2
 
 
 
 
 
 
 &&E&222^ 	".""1"---  	/ ...!n&@L((8888 L L LEsKKKKKKKKL
 	"5*FMM&-- 	K489I4J4JK1
 <!344 		SS|-DdKK @ D D$5<<UCCCD D D D D D D D D D D D D D D !188??? 12 S S SNPQRRRRRRRRS	Iug&&  	I 	I 	ILLGHHHHH	IqZ	 ~ &&E&2222&&E&2222  	F):H!E!E 	FF!((**** F F FA1EEEEEEEEF ))K7;;**-..4"JJ{E22	jj66JJ{A..	 	"FF 	 !FFF ,.
13::j))/Rh%% 	; ; ;!#t,, 776??k11!ggl339r 	9 	9VVJ33$&FF69$=$=*-bff[".E.E*F*F# # #))'222 "t  918K.	9 WWV__..!ggi44G7@@H(+G-5"?''4# #K
  GGN33E7<F[__U333$F)k2222# ;"2--k:::  	+'KK 	+%KK*K  '>BB (CQGG.. %" ()&#66@VVD& &0U|%L%LSMMRS '1#u&N&NUNNTU  % #5*:DAA E#?EE%L ge%A3GGN3OOO
 A"!
 "!
F X#ZZ1WXXE'N	Q ="7 =!+!8"J0E" " " = &OO(=(=(?(?OOO! !I ! =K"ii	"1"667
 $'y>>A#5#5 !Ac)nnq&8 @ @ @ @%' "" ! !99Y// =/4Y/?(/JE),,3<E-0 	Q 	Q 	QLL@4LPPPPP	Q E#?FF	#E+EqII	z5mDDEEcrcJKK 	 	 	KKK		$!+!8J" "  	$ 	$ 	$!#	$   "4":":"<"<  
 
 2# ,FSQQQ )0Kwtt}}UYYw5K5K ((/Kwtt}}UYYw5K5K&0e&M&MTM"""ST (2.3,'O'OVN###UV /#u>>%&&&+5i#u+N+NUYTU%+''+
 +
*  .3I.>.>
++z*     	KK!!IIIIII K K KFJJJJJJJJK @ 	".""1"---  	/ ...!n&@L((8888 L L LEsKKKKKKKKL
 	"5*FMM&-- 	K489I4J4JK1
 <!344 		SS|-DdKK @ D D$5<<UCCCD D D D D D D D D D D D D D D !188??? 12 S S SNPQRRRRRRRRS	Iug&&  	I 	I 	ILLGHHHHH	IS  
 
 
))K7;;;z;;;<<< 
	N	N!!'HH#%-HH      N N NI1MMMMMMMMN %XX ("5*:DAA
 
 	
 	
 	
 	
 	
  	".""1"---  	/ ...!n&@L((8888 L L LEsKKKKKKKKL
 	"5*FMM&-- 	K489I4J4JK1
 <!344 		SS|-DdKK @ D D$5<<UCCCD D D D D D D D D D D D D D D !188??? 12 S S SNPQRRRRRRRRS	Iug&&  	I 	I 	ILLGHHHHH	IS
< 	".""1"---  	/ ...!n&@L((8888 L L LEsKKKKKKKKL
 	"5*FMM&-- 	K489I4J4JK1
 <!344 		SS|-DdKK @ D D$5<<UCCCD D D D D D D D D D D D D D D !188??? 12 S S SNPQRRRRRRRRS	Iug&&  	I 	I 	ILLGHHHHH	Is  ;B> >
C-C((C-A@7 3I  A@7 
I0I+&A@7 +I00CA@7 =M ]2 ]!<N]
N+(]*N++A=])9Q#"]#
Q0-]/Q00A-])T]
T]TA],]-]2 1A@7 W$$
X.XX%[:Z![!Z%	%[(Z%	)[[>[99[>$\(($]]]]2 A@7 2^

A@7  ^5 4A@7 5
_$?_A@7 _$$M#A@7 Cp
 	A@7 
&p30A@7 2p33%A@7 )r A@7 rA@7 rA@7 r- ,A@7 -r<9A@7 ;r<<EA@7 x A@7 x*'A@7 )x**A@7 0x9 8A@7 9
y(y#A@7 #y((A@7 3{		
{8{33{8
~-~:~-~
	
~-~
	~--#>#'$A@@$A@4@3A@4@7AKA>AKB*AB,B+AKB,
ACB6ACCAKCACC(AKDAKDAK EAE%E%
AFE/AFFAFG&AI	G;AH"HAI	H"AH&	H&AI	H)AH&	H*AI	I	AI?IAI:I:AI?J$AJ)J)$AKKAKKAKKAK KAAR'L#AL9L8AR'L9
AM(MAM#MAR'M#AM(M(AAR'N:APOAO6O*APO6AO:O:APO=AO:O>APPAR'PAQP.AQQ	AR'QAQQAR'Q$AQ=Q;AR'Q=$AR$R!AR'R#AR$R$AR'tasksc                 D   t          | t                    sdS |                                 }|sdS 	 t          j        |          }n)# t          j        $ r}d d|j         dfcY d }~S d }~ww xY wt          |t                    sd dt          |          j	         dfS |d fS )NNN)N7Provide either 'goal' (single task) or 'tasks' (batch).z`tasks must be a JSON array of task objects; received a string that could not be parsed as JSON ().z3tasks must be a JSON array of task objects; parsed z	 instead.)
r~   r   r   r   r   JSONDecodeErrorr   r   r_  r   )r  rawr   r^   s       r   _recover_tasks_from_json_stringr  g  s     eS!! z
++--C ONN
C 
 
 
=14= = =
 	
 	
 	
 	
 	
 	


 fd## 
0F||$0 0 0
 	
 4<s   A A,A'!A,'A,rv  rw  c	                    |t          d          S t                      rt          d          S t          |          }	t          |dd          }
t	                      }|
|k    r%t          j        dd|
 d| d	t           d
i          S t                      }|	                    dt                    }|"||k    rt                              d||           |}	 t          ||          }n3# t          $ r&}t          t          |                    cY d}~S d}~ww xY wt!                      }t#          |          \  }}|rt          |          S ||}|rNt%          |t&                    r9t)          |          |k    r#t          dt)          |           d| d          S |}nC| r2t%          | t                    r|                                 r	| |||	dg}nt          d          S |st          d          S t-          |          D ]\  }}t%          |t.                    s*t          d| dt1          |          j         d          c S |	                    dd                                          st          d| d          c S t5          j                    }g }t)          |          }d |D             }ddl}t'          |j                  }g }	 t-          |          D ]\  }}d|v r|	                    d          nd}t          |	                    d          p|	          } t=          ||d         |	                    d          |	                    d          p||d         ||||d         |d          |d!         |d"         |	                    d#          p|p|	                    d$          ||n||n|	                    d%          | &          }!||!_        |                     |||!f           	 ||_        n# ||_        w xY w|d'k    r;|d         \  }"}#}!tC          d|#d         |!|          }$|                     |$           njd}%t          |d(d          }&tE          |)          5 }'i }(|D ]0\  }}}!|'#                    tB          ||d         |!|*          })||(|)<   1d+ |D             }*tI          |(%                                          }+|+rt          |d,d-          d.u r|+D ]},|(|,         }-|,&                                rf	 |,'                                }.n|# tP          $ rC}|-ddt          |          ddt          |*	                    |-          d/d          d0}.Y d}~n4d}~ww xY w|-d1dd2ddt          |*	                    |-          d/d          d0}.|                     |.           |%d'z  }%ːndd3l)m*}/m+}0  |/|+d4|05          \  }1}+|1D ]})	 |)'                                }.nX# tP          $ rK}|(|)         }-|-ddt          |          ddt          |*	                    |-          d/d          d0}.Y d}~nd}~ww xY w|                     |.           |%d'z  }%|.d6         }-|-t)          |          k     r||-         nd|- }2|.	                    d7d          }3|.	                    d8d9          }4|4d:k    rd;nd<}5||%z
  }6|5 d=|-d'z    d>| d?|2 d@|3 dA
}7|&r9	 |&,                    |7           n4# tP          $ r t[          dB|7            Y nw xY wt[          dB|7            |&r`|6dk    rZ	 |&.                    dC|6 dD|6d'k    rdEnd dF           ~# tP          $ r&}8t                              dG|8           Y d}8~8d}8~8ww xY w|+ddd           n# 1 swxY w Y   |/                    dH I           |rta          |dJ          r|j1        r|D ]}.	 |.d6         t)          |          k     r||.d6                  d         nd}9|j1        2                    |9|.	                    dKd          pd|.d6         t)          |          k     r#t          ||.d6                  dL         dMd          ndN           # tP          $ r Y w xY wt          |dMd          }:	 ddOl3m4}; n# tP          $ r d};Y nw xY wdP}<|D ]}.|.5                    dQd          }=|.5                    dRdP          }>	 |>r|<tm          |>          z  }<n# tn          t          f$ r Y nw xY w|;^	  |;dS|:|=|.	                    dK          |.	                    d8          tq          |.	                    d7          pddTz            U           # tP          $ r t                              dVd.W           Y w xY w|<dPk    r	 tm          t          |dXdP          pdP          }?|?|<z   |_9        t          |dYdZ          d[v rd\|_:        t          |d]d^          d_v rd`|_;        n,# tP          $ r t                              dad.W           Y nw xY wty          t5          j                    |z
  dL          }@t          j        ||@dbd-c          S )da-  
    Spawn one or more child agents to handle delegated tasks.

    Supports two modes:
      - Single: provide goal (+ optional context, toolsets, role)
      - Batch:  provide tasks array [{goal, context, toolsets, role}, ...]

    The 'role' parameter controls whether a child can further delegate:
    'leaf' (default) cannot; 'orchestrator' retains the delegation
    toolset and can spawn its own workers, bounded by
    delegation.max_spawn_depth.  Per-task role beats the top-level one.

    Returns JSON with results array, one entry per task.
    Nz.delegate_task requires a parent agent context.zzDelegation spawning is paused. Clear the pause via the TUI (`p` in /agents) or the `delegation.pause` RPC before retrying.rb  r   r   z&Delegation depth limit reached (depth=z, max_spawn_depth=zW). Raise delegation.max_spawn_depth in config.yaml if deeper nesting is required (cap: r  rY  zidelegate_task: ignoring caller-supplied max_iterations=%s; using delegation.max_iterations=%s from configzToo many tasks: z* provided, but max_concurrent_children is z. Either reduce the task count, split into multiple delegate_task calls, or increase delegation.max_concurrent_children in config.yaml.)r  r  r  rs   r  zNo tasks provided.zTask z must be an object, got .r  rz   z is missing a 'goal'.c                 .    g | ]}|d          dd         S )r  Nr   rB   r5   s     r   ri   z!delegate_task.<locals>.<listcomp>  s$    555a1V9SbS>555r    rw  rs   r  r  r%  rt  r  ro  ru  rv  r   r5  )r&  r  r  r  r%  rY  r'  r  rZ  r[  r\  r]  r^  r_  rs   rE   r)  )r  )r&  r  r  r  c                     i | ]	\  }}}||
S rB   rB   )r6   i_r  s       r   rf   z!delegate_task.<locals>.<dictcomp>H  s     FFFMQ5q%FFFr    r(  FTr  rQ  r0  u9   Parent agent interrupted — child did not finish in time)r  FIRST_COMPLETEDg      ?)r   return_whenr&  r  r   ?r/  u   ✓u   ✗z [r  r+  z  (zs)r  rE  z taskr  z
 remainingzSpinner update_text failed: %sc                     | d         S )Nr&  rB   )rh   s    r   <lambda>zdelegate_task.<locals>.<lambda>  s
    1\? r    )key_memory_managerrP  r   r  )taskrp   child_session_id)invoke_hookr<  r+  r?  subagent_stopr  )r  
child_roler  child_statusduration_msz$subagent_stop hook invocation failedrD  r;  session_cost_sourcenone>   Nrz   r  subagentsession_cost_statusr1  >   Nrz   r1  	estimatedzSubagent cost rollup failed)resultstotal_duration_seconds)ensure_ascii)=
tool_errorrN   r   r  r   r   r  r   r&   r'   DEFAULT_MAX_ITERATIONSr   r]   _resolve_delegation_credentialsr   r   r   r  r~   r   r   r   	enumerater   r_  r   rR  rS  rj  rT  r  r  r   r  r   r\  r   keysdonerp   r\   concurrent.futuresr  r  rG  printupdate_textsortr  r  on_delegationhermes_cli.pluginsr  rV   r   r   r   r;  r  r  r^  )Ar  r  r  r  rY  rv  rw  rs   r  top_roler$  r  r)   default_max_itereffective_max_itercredsr^   max_childrenrecovered_taskstasks_error	task_listr  r  overall_startr  n_taskstask_labels_model_tools_parent_tool_nameschildrenr7   task_acp_argsr  r  _i_trp   completed_countspinner_refexecutorfuturesfuture_child_by_indexpendingfr  r  _cf_waitr  r  labeldurr   icon	remainingcompletion_liner7  
_task_goal_parent_session_id_invoke_hook_children_cost_totalr  
child_costrV  total_durationsA                                                                    r   r   r   ~  sV   2 JKKK
  
N
 
 	
 t$$H L"3Q77E$&&I	zJU J J'0J J 2FJ J J	
 	
 		
 ..Cww/1GHH !n8H&H&H=,	
 	
 	

 *$/\BB $ $ $#c((########$ 011L#B5#I#I O[ '+&&&" UE4(( Uu::$$F3u:: F F.:F F F   			 U*T3'' UDJJLL Ug8XVV
		 STTT 0./// Y'' @ @4$%% 	III4::3FIII     xx##))++ 	@>a>>>?????	@ N$$MG)nnG559555K
 '&&&lDEE
 H"Di(( 	+ 	+DAq1;qAEE*---dM -QUU6]]-FhGGN&vYi((z**6hGn1")"'
"3"'
"3!&y!1"'
"3%&UU=%9%9 &(&(99Y'' %0 "M&.&:((		&@Q@Q#+  E0 0BE,OOQ5M****=	+B 2D..1C.CCCC!|| B"1bj%FFv l,?FFL999 m	NXG' $ $1e!% 6!- )   #$ GFXFFFO',,..))G WN<)?GG4OO % - -%aj6688 "()

#, " " "25.5/3-0XX12893:(7(;(;C(@(@BRTX4& 4&
)" 
)"" /2*7+/)d-.45/6$3$7$7$<$<>NPT0" 0"
% 
%E  u---'1,PPPPPPPP (So! ! !g # ,N ,NF &$   %fo*-&-'+%(XX)*01+2 / 3 3C 8 8:JD, ,
! 
! NN5)))#q(O  -C,/#k2B2B,B,BC((PS   ))$6::C"YYx55F$*k$9$955uD '/ 9I)-&U&UQ&U&U&U&UE&U&Uc&U&U&UO" 6:'33ODDDD( : : :!"8"8"899999: 4?44555 # Ny1}}N'33 a	 a ayA~~SU a a a     ) N N N"LL)I1MMMMMMMMNm  WN-m	N m	N m	N m	N m	N m	N m	N m	N m	N m	N m	N m	N m	N m	N m	N` 	22333 	L"344 (
  	 	E \*S^^;; eL126:: 
 ,::# 99Y339r !.X>>  |)< =a @,PRSSS ;         !|TBBBBBBBBB     P PYY}d33
YY0#66
	 :$j(9(99$:& 	 	 	D	
	PL"4%#ii	22"YYx00+=!>!>!C!t KLL      	P 	P 	PLL?$LOOOOO	P c!!	GGL2NPSTT[X[\\G6=@T6TL3
 |%:FCCGYYY3=0|%:IFFJ___3>0 	G 	G 	GLL6LFFFFF	G 4>++m;Q??N:&4	
 	
    s@  C) )
D3DDDD$O> >	P.B^T^
U*'9U% ^%U**A*^W*)^*
X?4AX:5^:X??B^[,+^,\^
\^)$]^
]?]:4^:]??^^^Ba22
a?>a?b b*)b* c55d	d	Ae--&ff Ag? ?&h('h(r  c                 D   | st          |dd          S t          |dd          pd}t          |dd          }|| |k    r|S 	 ddlm}  ||           }||                                r|S n3# t          $ r&}t
                              d| |           Y d}~nd}~ww xY wdS )ah  Resolve a credential pool for the child agent.

    Rules:
    1. Same provider as the parent -> share the parent's pool so cooldown state
       and rotation stay synchronized.
    2. Different provider -> try to load that provider's own pool.
    3. No pool available -> return None and let the child keep the inherited
       fixed credential behavior.
    r  Nrt  rz   r   )	load_poolz:Could not load credential pool for child provider '%s': %s)r  agent.credential_poolr  has_credentialsr\   r   r]   )r  r  parent_providerparent_poolr  poolr^   s          r   r  r  	  s      ?|%7>>>lJ==CO,(:DAAK#5#H#H
333333y+,, 4 4 6 6K 
 
 
H	
 	
 	
 	
 	
 	
 	
 	

 4s   (A- -
B7BBr)   c                    t          |                     d          pd                                          pd}t          |                     d          pd                                          pd}t          |                     d          pd                                          pd}t          |                     d          pd                                          pd}t          |                     d          pd                                                                          pd}|ru|}dd	lm} |                                }	d
}
 ||          pd}t          |          dk    r	d|	v rd}
d}n t          |          dk    rd}
d}nd|	v rd
}
d}|dv r|}||
|||dS |s|dddddS 	 ddlm}  |||          }n)# t          $ r}t          d| d| d          |d}~ww xY w|                    dd          }|st          d| d          |p|                    d          pd|                    d          t          k    r|n|                    d          |                    d          ||                    d          |                    d          t          |                    d          pg           dS ) u  Resolve credentials for subagent delegation.

    If ``delegation.base_url`` is configured, subagents use that direct
    OpenAI-compatible endpoint. ``delegation.api_key`` overrides the key; when
    omitted, ``api_key`` is returned as ``None`` so ``_build_child_agent``
    inherits the parent agent's key (``effective_api_key = override_api_key or
    parent_api_key``). This lets providers that store their key outside
    ``OPENAI_API_KEY`` (e.g. ``MINIMAX_API_KEY``, ``DASHSCOPE_API_KEY``) work
    without a duplicate config entry.

    Otherwise, if ``delegation.provider`` is configured, the full credential
    bundle (base_url, api_key, api_mode, provider) is resolved via the runtime
    provider system — the same path used by CLI/gateway startup. This lets
    subagents run on a completely different provider:model pair.

    If neither base_url nor provider is configured, returns None values so the
    child inherits everything from the parent agent.

    Raises ValueError with a user-friendly message on credential failure.
    r%  rz   Nrt  r  ro  ru  r   )_detect_api_mode_for_urlr
   rx  zchatgpt.comz/backend-api/codexzopenai-codexcodex_responseszapi.anthropic.com	anthropicanthropic_messageszapi.kimi.com/coding>   r  rx  r  )r%  rt  r  ro  ru  )resolve_runtime_provider)	requestedtarget_modelz$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.zDelegation provider 'z]' resolved but has no API key. Set the appropriate environment variable or run 'hermes auth'.r   r5  )r%  rt  r  ro  ru  r   r5  )r   r'   r   r   hermes_cli.runtime_providerr  r   r  r\   r   _RUNTIME_PROVIDER_CUSTOMr   )r)   r  configured_modelconfigured_providerconfigured_base_urlconfigured_api_keyconfigured_api_modero  r  
base_lowerrt  ru  r  runtimer^   s                  r   r  r  )	  s   * 3777++1r2288::Bdcggj117R88>>@@HDcggj117R88>>@@HDSWWY//5266<<>>F$cggj117R88>>@@FFHHPD ,
 % 	IHHHHH(..00
++,?@@VDV122mCC$
22%H(HH2337JJJ"H+HH"j00H+H "___*H & + 
 
 	
  
 &
 
 	

HHHHHH**5HWghhh   Q3F Q Q3 Q Q Q
 

 	 kk)R((G 
N$7 N N N
 
 	
 "AW[[%9%9AT+2;;z+B+BF^+^+^''dkdodopzd{d{KK
++KK
++;;y))W[[((.B//  s   -G 
G'G""G'c                      	 ddl m}  |                     d          pi }|r|S n# t          $ r Y nw xY w	 ddlm}  |            }|                    d          pi S # t          $ r i cY S w xY w)aN  Load delegation config from CLI_CONFIG or persistent config.

    Checks the runtime config (cli.py CLI_CONFIG) first, then falls back
    to the persistent config (hermes_cli/config.py load_config()) so that
    ``delegation.model`` / ``delegation.provider`` are picked up regardless
    of the entry point (CLI, gateway, cron).
    r   )
CLI_CONFIGr0   )load_config)clir  r'   r\   hermes_cli.configr  )r  r)   r  fulls       r   r&   r&   	  s    """"""nn\**0b 	J	   111111{}}xx%%++   			s    $ 
11&A A+*A+c                  N   	 t                      } n# t          $ r
 t          } Y nw xY w	 t                      }n# t          $ r
 t          }Y nw xY w	 t                      }n# t          $ r d}Y nw xY w|dk    r|rd| d|dz
   d}n|dk    r	|sd| d}nd	| d
}d|  d| d| dS )a  Compose the delegate_task tool description with current runtime limits.

    The model needs to know its actual ceilings (not the framework defaults),
    otherwise it self-caps at "default 3" / "default 2" even when the user has
    raised delegation.max_concurrent_children / max_spawn_depth. Called both
    at module import (to seed DELEGATE_TASK_SCHEMA) and on every
    get_definitions() call via dynamic_schema_overrides.
    Tr   z<Nested delegation IS enabled for this user (max_spawn_depth=zN): pass role='orchestrator' on a child to let it spawn its own workers, up to rE   z additional level(s) deep.zsNested delegation is DISABLED on this install (delegation.orchestrator_enabled=false), even though max_spawn_depth=z3. role='orchestrator' is silently forced to 'leaf'.z8Nested delegation is OFF for this user (max_spawn_depth=zx): every child is a leaf and cannot delegate further. Raise delegation.max_spawn_depth in config.yaml to enable nesting.a  Spawn one or more subagents to work on tasks in isolated contexts. Each subagent gets its own conversation, terminal session, and toolset. Only the final summary is returned -- intermediate tool results never enter your context window.

TWO MODES (one of 'goal' or 'tasks' is required):
1. Single task: provide 'goal' (+ optional context, toolsets)
2. Batch (parallel): provide 'tasks' array with up to z items concurrently for this user (configured via delegation.max_concurrent_children in config.yaml). All run in parallel and results are returned together. uU  

WHEN TO USE delegate_task:
- Reasoning-heavy subtasks (debugging, code review, research synthesis)
- Tasks that would flood your context with intermediate data
- Parallel independent workstreams (research A and B simultaneously)

WHEN NOT TO USE (use these instead):
- Mechanical multi-step work with no reasoning needed -> use execute_code
- Single tool call -> just call the tool directly
- Tasks needing user interaction -> subagents cannot use clarify
- Durable long-running work that must outlive the current turn -> use cronjob (action='create') or terminal(background=True, notify_on_complete=True) instead. delegate_task runs SYNCHRONOUSLY inside the parent turn: if the parent is interrupted (user sends a new message, /stop, /new) the child is cancelled with status='interrupted' and its work is discarded. Children cannot continue in the background.

IMPORTANT:
- Subagents have NO memory of your conversation. Pass all relevant info (file paths, error messages, constraints) via the 'context' field.
- If the user is writing in a non-English language, or asked for output in a specific language / tone / style, say so in 'context' (e.g. "respond in Chinese", "return output in Japanese"). Otherwise subagents default to English and their summaries will contaminate your final reply with the wrong language.
- Subagent summaries are SELF-REPORTS, not verified facts. A subagent that claims "uploaded successfully" or "file written" may be wrong. For operations with external side-effects (HTTP POST/PUT, remote writes, file creation at shared paths, publishing), require the subagent to return a verifiable handle (URL, ID, absolute path, HTTP status) and verify it yourself — fetch the URL, stat the file, read back the content — before telling the user the operation succeeded.
- Leaf subagents (role='leaf', the default) CANNOT call: delegate_task, clarify, memory, send_message, execute_code.
- Orchestrator subagents (role='orchestrator') retain delegate_task so they can spawn their own workers, but still cannot use clarify, memory, send_message, or execute_code. Orchestrators are bounded by max_spawn_depth=z for this user and can be disabled globally via delegation.orchestrator_enabled=false.
- Each subagent gets its own terminal session (separate working directory and state).
- Results are always returned as an array, one entry per task.)r   r\   r   r   r   r   )r  	max_depthorchestrator_onnesting_clauses       r   _build_top_level_descriptionr  	  sv   8355 8 8 878(**		   			355    A~~/~) )) )<EM) ) ) 	 
a!(! ! ! 	. ). . . 	1	I BN1	I 1	I CQ1	I 1	IZ 9B[1	I 1	I 1	I3s-    %%8 AAA A.-A.c                  \    	 t                      } n# t          $ r
 t          } Y nw xY wd|  dS )zICompose the 'tasks' parameter description with current concurrency limit.z,Batch mode: tasks to run in parallel (up to z for this user, set via delegation.max_concurrent_children). Each gets its own subagent with isolated context and terminal session. When provided, top-level goal/context/toolsets are ignored.)r   r\   r   )r  s    r   _build_tasks_param_descriptionr	  
  sW    8355 8 8 878	F| 	F 	F 	Fs    %%c                      	 t                      } n# t          $ r
 t          } Y nw xY w	 t                      }n# t          $ r d}Y nw xY w| dk    r|rd|  d| dz
   d}n| dk    r|sd}nd|  d	}d
| S )zHCompose the 'role' parameter description with current spawn-depth limit.Tr   z2Nesting IS enabled for this user (max_spawn_depth=z7): orchestrator children can themselves delegate up to rE   z more level(s) deep.zsNesting is currently disabled (delegation.orchestrator_enabled=false); 'orchestrator' is silently forced to 'leaf'.z.Nesting is OFF for this user (max_spawn_depth=zj); 'orchestrator' is silently forced to 'leaf'. Raise delegation.max_spawn_depth in config.yaml to enable.zRole of the child agent. 'leaf' (default) = focused worker, cannot delegate further. 'orchestrator' = can use delegate_task to spawn its own workers. )r   r\   r   r   )r  r  nesting_notes      r   _build_role_param_descriptionr  )
  s    (**		   			355    A~~/~" " "CLq=" " " 	
 
a) 	CY C C C 		F7C	F 	Fs    %%8 AAc                     i t           d         } d t           d         d                                         D             | d<   t                      | d         d         d<   t                      | d         d         d<   t	                      | dS )zReturn per-call schema overrides reflecting current config.

    Plugged into ToolEntry.dynamic_schema_overrides so every
    get_definitions() pass rewrites the description fields to the user's
    actual limits.
    
parametersc                 4    i | ]\  }}|t          |          S rB   )r   rc   s      r   rf   z3_build_dynamic_schema_overrides.<locals>.<dictcomp>Y
  s1     & & &q!477& & &r    
propertiesr  r   rs   )r   r  )DELEGATE_TASK_SCHEMArg   r	  r  r  )overrides_paramss    r   _build_dynamic_schema_overridesr  N
  s    
|
,& &3LA,OUUWW& & &\" >\=]=]\"7+M:<Y<[<[\"6*=9355&  r    r   zSpawn one or more subagents in isolated contexts. Description is rebuilt at every get_definitions() call to reflect the user's current delegation limits.objectstringzWhat the subagent should accomplish. Be specific and self-contained -- the subagent knows nothing about your conversation history.)r_  r   zBackground information the subagent needs: file paths, error messages, project structure, constraints. The more specific you are, the better the subagent performs.arrayr_  zcToolsets to enable for this subagent. Default: inherits your enabled toolsets. Available toolsets: z. Common patterns: ['terminal', 'file'] for code work, ['web'] for research, ['browser'] for web interaction, ['terminal', 'file', 'web'] for full-stack tasks.)r_  rg   r   z	Task goalzTask-specific contextz,Toolsets for this specific task. Available: zT. Use 'web' for network access, 'terminal' for shell, 'browser' for web interaction.zPer-task ACP command override (e.g. 'copilot'). Overrides the top-level acp_command for this task only. Do NOT set unless the user explicitly told you an ACP CLI is installed.zBPer-task ACP args override. Leave empty unless acp_command is set.r   z;Per-task role override. See top-level 'role' for semantics.)r_  enumr   )r  r  r  rv  rw  rs   )r_  r  requiredz#(rebuilt at get_definitions() time)a  Override ACP command for child agents (e.g. 'copilot'). When set, children use ACP subprocess transport instead of inheriting the parent's transport. Requires an ACP-compatible CLI (currently GitHub Copilot CLI via 'copilot --acp --stdio'). See agent/copilot_acp_client.py for the implementation. IMPORTANT: Do NOT set this unless the user has explicitly told you a specific ACP-compatible CLI is installed and configured. Leave empty to use the parent's default transport (Hermes subagents).zArguments for the ACP command (default: ['--acp', '--stdio']). Only used when acp_command is set. Leave empty unless acp_command is explicitly provided.)r  r  r  r  rs   rv  rw  )r=   r   r  )r   r  r0   c                    t          |                     d          |                     d          |                     d          |                     d          |                     d          |                     d          |                     d          |                     d          |                    d	          
	  	        S )Nr  r  r  r  rY  rv  rw  rs   r  )	r  r  r  r  rY  rv  rw  rs   r  )r   r'   )r5  r/  s     r   r  r  
  s    }XXf##*%%hhwxx 011HH]++*%%XXfVVN++
  
  
  r    u   🔀)r=   toolsetschemahandlercheck_fnrN  dynamic_schema_overridesr3   )rE   )NNNNNNr   r  )	NNNNNNNNN)pr   r  r   re  	getLoggerr   r   r   r"  rR  r  r   r   r]  typingr   r   r   r   r  r	   r  r9   r   tools.terminal_toolr   r[  utilsr   r   	frozensetr4   r   r   r#   r+   r:   r   rg   _SUBAGENT_TOOLSETSr  _TOOLSET_LIST_STRr   r   r   r   LockrJ   rF   rK   __annotations__rR   rG   rL   rN   rT   rW   r_   rk   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r   r  r  r  r  Enumr   r   r   r   r   r   r   r
  r  r!  callablerX  r  rX  r  r  tupler  r   r  r   r  r&   r  r	  r  r  r  r   r   r  registerrB   r    r   <module>r,     s    "   		8	$	$ 				             - , , , , , , , , , , ,      
 $        R R R R R R 4 4 4 4 4 4 4 4 #    8 3 S    
C 
c 
 
 
 
 
  , $)$T$T$TUU V  $hn&&      IICC0BCCCCC #$  	    #IN$$ t   '))  02 4T#s(^+, 1 1 1	T 	d 	 	 	 	    
(tCH~ ($ ( ( ( (1c 1d 1 1 1 1
C D    .

tDcN3 

 

 

 

  	2 2 2cN2 2 	2
 
$sCx.2 2 2 2j c  d        Fx}     "#,c #, #, #, #,L(E ( ( ( (6#c # # # #L4    "J4 J J J J;s ;t ; ; ; ;S S    >I03C	#Y         " "$ ... 4 4 4 4 4C 4 4 40 ,(6!3#7&4/ / 4]*+   T     "I %)I I I
Ic]I SM	I
 I I I 	I I I IXXc]    6C49 Cc C C C C 	x "&#$(x x xx
x 	x #x }x C=x C=x tCy!x hx x x xJ (,'+&*'+*.-1 )p pp
p c]p tCy!	p
 C=p p p  }p  }p smp  }p #3-p   S	*!p( )p p p pf	MM M 	M
 M I,-M M c]M M M Mf 	{I {I{I
{I 
#s(^{I {I {I {I|
8Dc3h()8C=89   0 !$(,0$(!%$(G G
3-Gc]G tCy!G Dc3h()	G
 SMG #G tCy!G 3-G 	G G G GTx}    Bo o o o o odd    <_c _ _ _ _D    "s " " " "J    . 	0
  !,  !J    (+H+<H H H	   $)1+ N N$,+B$ $
 %,&,h%7 ,BZk  ,B  ,B  ,B% % %-!j( ( %,&,h%7+o% % %-%+^$<+h! !1# #< "(A! !J  EO( (T !0D  !\    (+M	 qa
 a
D Ie eu u r 0 / / / / / / /  	
 
 )
<#     r    