
    JjP                    	   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#dZ$da%dZ&dZ' ej(                    Z)da*e+e,d<    ej(                    Z-i Z.ee ee ef         f         e,d<   de+de+fdZ/de+fdZ0dee ef         ddfdZ1de ddfdZ2de de+fdZ3deee ef                  fdZ4dd d!d"ee ef         d#e5d$e5deee ef                  fd%Z6d&ede fd'Z7d&ede+fd(Z8d)ee          de fd*Z9de5fd+Z:da;de5fd,Z<dee=         fd-Z>de5fd.Z?de+fd/Z@de+fd0ZAd1e de+fd2ZBd3eCdeCfd4ZDd5ee          d3eCe          dee          fd6ZEd7ZFd8ZGd9ZHd:ZIdZJee=         e,d;<   d<ZKd=ZLd>ZMg d?ZN G d@ dAe ejO                  ZPePjQ        ePjQ        ePjR        ePjS        ePjT        dBZUee ePf         e,dC<   de+fdDZV	 dddEdFddGdHe dIee          dJee          dKe dLe5dMe5de fdNZWdee          fdOZXdPee          dee          fdQZYdRe ddfdSZZ	 ddddddddTdUe5dHe dVe5dee          dWee          dXee5         dYee          dPeee                   dZeee ef                  dee[         fd[Z\d\ede fd]Z]d^ee          dee          fd_Z^	 	 	 	 	 	 	 ddUe5dHe dIee          dPeee                   dYee          d`e5dVe5daee          dbee          dcee          ddee          deee          dfeee                   dKe fdgZ_dhedUe5die=dje=dkeej`                 dHe dee          fdlZadUe5dme dee          fdnZbdme doe5dUe5dece ee          f         fdpZddqe5dee5         fdrZedseee ef                  ddfdtZf	 	 ddUe5dHe dee ef         fduZgdvedeceeee ef                           ee          f         fdwZh	 	 	 	 	 	 	 ddHee          dIee          dveeee ef                           d`ee5         dKee          dxee+         de fdyZi	 ddzee          d{ee          fd|Zjd}ekdekfd~ZldekfdZmde fdZnde fdZode fdZpdekfdZqdddddddddddddddddddEdgddddHgdddddEdgddddddg ddZrddlsmtZtmuZu ddekde+fdZvddhZwdvedefdZx etjy        dderd eVdeq           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cronjob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      9/home/rurouni/.hermes/hermes-agent/tools/delegate_tool.py_subagent_auto_denyr    J   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$   X   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,   e   s=     ..C
'')5
1
1Cs &%%r!      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boolr/   )r1   s    r   set_spawn_pausedr5      s|     
  V                 s   +//c                  R    t           5  t          cd d d            S # 1 swxY w Y   d S N)r3   r/    r!   r   is_spawn_pausedr9      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_lockr0   )r:   sids     r   _register_subagentr?      s    
**]
#
#C 	 ( (!'#( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (s   9= =r<   c                 |    t           5  t                              | d            d d d            d S # 1 swxY w Y   d S r7   )r=   r0   pop)r<   s    r   _unregister_subagentrB      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)r=   r0   r(   	interrupt	Exceptionr   debug)r<   r:   rD   excs       r   interrupt_subagentrJ      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 )rD   r8   .0kvs      r   
<dictcomp>z4list_active_subagents.<locals>.<listcomp>.<dictcomp>   s#    888da1<<Q<<<r!   )itemsrO   rs     r   
<listcomp>z)list_active_subagents.<locals>.<listcomp>   s>     
 
 
 98aggii888
 
 
r!   N)r=   r0   valuesr8   r!   r   list_active_subagentsrX      s     
  
 

 
&--//
 
 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
s   #8<<   i@  max_entries	max_charsresultr[   r\   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Ft          |                    d
          pd          }
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functionnametoolcontent tool_call_id)rf   previewis_error)
isinstancedictr(   liststrreversedlen_stringify_tool_content_looks_like_error_outputappendreverse)r]   r[   r\   r_   tailpending_call_by_idmsgtctc_idfnrg   rk   	tool_namerj   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
 *#'')*<*<*BCC+G44&**377>+B+B+Hb&QQ	 *9*%Y7QQRRRRLLNNNKr!   rg   c                 h   | dS t          | t                    r| S t          | t                    rg }| D ]}t          |t                    rp|                    d          }t          |t                    r|                    |           W|                    t          j        |dt                               |                    t          |                     d                    |          S t          | t                    rt          j        | dt                    S t          |           S )a+  Return a stable text representation for tool-result content.

    Most providers store tool results as strings, but some OpenAI-compatible
    paths can return content-block lists. Delegate observability must never
    crash while summarising a child run just because the transport used blocks.
    Nrh   textF)ensure_asciidefault
)	rl   ro   rn   rm   r(   rt   jsondumpsjoin)rg   partsitemr   s       r   rr   rr     s    r'3 '4     	( 	(D$%% (xx''dC(( TLL&&&&LLDuc!R!R!RSSSSSYY''''yy'4   Dz'sCCCCw<<r!   c                 4   t          |           } | 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statusrh   >   r   failedfailuretimeoutr   zerror:zfailed:z
traceback z
exception:)rr   lstrip
startswithr   loadsrl   rm   r(   ro   striplowerrG   
splitlines)rg   headparsedr   firsts        r   rs   rs   -  s    &g..G 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/rU   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')ro   r   r   r   r   )rU   r_norms     r   _normalize_roler   Q  s\     	yyvVV\\^^!!##F)))
NNFJJJ6r!   c                     t                      } |                     d          }|	 t          dt          |                    }|dk    r$t          sda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_childrenNr.   
   Tzxdelegation.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int_HIGH_CONCURRENCY_WARNEDr   r   	TypeError
ValueError _DEFAULT_MAX_CONCURRENT_CHILDRENosgetenv)r*   r+   r]   env_vals       r   _get_max_concurrent_childrenr   b  s1    ..C
''+
,
,C
	4CHH%%F{{/ /3,NNM  
 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A0 09B,+B,C# #C>=C>c                      t                      } |                     d          #t          sdat                              d           t                      S )u  Concurrency cap for background (``background=true``) delegations.

    DEPRECATED KNOB: ``delegation.max_async_children`` has been unified into
    ``delegation.max_concurrent_children`` — one cap governs both a single
    synchronous batch's parallelism and how many background delegation units
    may run at once. When at capacity, a new async dispatch is REJECTED (not
    queued) so a runaway model can't pile up unbounded background work; the
    caller falls back to running the work synchronously.

    A leftover ``max_async_children`` in config.yaml is ignored (the config
    migration removes it, folding a raised value into
    ``max_concurrent_children``); we log a one-time deprecation warning if
    one is still present.
    max_async_childrenNTzdelegation.max_async_children is deprecated and ignored; delegation.max_concurrent_children now caps background delegations too. Remove the stale key from config.yaml.)r'   r(   _LEGACY_MAX_ASYNC_WARNEDr   r   r   r*   s    r   _get_max_async_childrenr     sV      ..C
ww#$$09Q0#' F	
 	
 	

 ()))r!   c                     t                      } |                     d          }|Z	 t          |          }|dk    rdnt          d|          S # t          t
          f$ r t                              d|           Y nw xY wt          j	        d          }|r?	 t          |          }|dk    rdnt          d|          S # t          t
          f$ r Y nw xY wt          S )u  Read delegation.child_timeout_seconds from config.

    Returns the number of seconds a single child agent is allowed to run
    before being cut off, or ``None`` when no wall-clock cap applies.

    Default: ``None`` (no timeout). Subagents doing legitimate heavy work
    (deep code review, large research fan-outs, slow reasoning models) were
    routinely killed mid-task by the old blanket cap even though they were
    making steady progress. Failures should come from what the child is
    actually doing — API errors, tool errors, iteration budget — not from a
    generic delegation-level stopwatch. Stuck-child protection is handled
    separately by the heartbeat staleness monitor, which stops refreshing
    parent activity so the gateway inactivity timeout can fire.

    Set ``delegation.child_timeout_seconds`` to a positive number to opt back
    in to a hard cap (floor 30 s); ``0`` or a negative value means disabled.
    child_timeout_secondsNr   g      >@zUdelegation.child_timeout_seconds=%r is not a valid number; using default (no timeout) DELEGATION_CHILD_TIMEOUT_SECONDS)r'   r(   floatr   r   r   r   r   r   r   DEFAULT_CHILD_TIMEOUT)r*   r+   r   r   s       r   _get_child_timeoutr     s   $ ..C
'')
*
*C
		>3ZZF "Q;;44Cf,=,== :& 	 	 	NN-    	 i:;;G >	>7^^F "Q;;44Cf,=,== :& 	 	 	D	 ! s#   A ,A=<A=B> >CCc                  x   t                      } |                     d          }|t          S 	 t          |          }n?# t          t
          f$ r+ t                              d|t                     t          cY S w xY wt          t          |          }||k    r"t                              d|t          |           |S )u  Read delegation.max_spawn_depth from config, floored at 1 (no ceiling).

    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+ to unlock nested orchestration. role="orchestrator"
    removes the toolset strip for spawning children when
    max_spawn_depth >= 2, enabling them to spawn their own workers.
    Like max_concurrent_children, there is no upper ceiling — but each
    extra level multiplies API cost, so raise it deliberately.
    max_spawn_depthNzFdelegation.max_spawn_depth=%r is not a valid integer; using default %dz6delegation.max_spawn_depth=%d below floor %d; using %d)
r'   r(   	MAX_DEPTHr   r   r   r   r   r   _MIN_SPAWN_DEPTH)r*   r+   ivalflooreds       r   _get_max_spawn_depthr     s     ..C
''#
$
$C
{3xxz"   W	
 	
 	

  "D))G$D		
 	
 	
 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(   rl   r4   ro   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r   )r'   r   r(   r   s    r   _get_inherit_mcp_toolsetsr     s+    
..C377#9::DIIIIr!   re   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)ro   r   tools.registryr   get_toolset_alias_targetrG   r4   )re   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.
    tools)setr	   r(   updaterS   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.)rn   sortedr   rt   )r   r   	preservedtoolset_names       r   _preserve_parent_mcp_toolsetsr   ?  s]     ^$$I// + +-- 	+,i2O2O\***r!   2   i]        ?i  r         (   )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_COMPLETEDr8   r!   r   r   r   p  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.Tr8   r8   r!   r   check_delegate_requirementsr     s    4r!   r      workspace_pathr`   r   child_depthgoalcontextr   r`   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.rh   zYOUR TASK:
z

CONTEXT:
z
WORKSPACE PATH:
zg
Use this exact path for local repository/workdir operations unless the task explicitly says otherwise.a  
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.

Keep your final summary tight: lead with outcomes, prefer bullet points over paragraphs, and don't replay your whole process. Your response is returned to the parent agent as a summary, and overlong summaries crowd out the parent's context window.r   r.   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   rt   ro   r   )r   r  r   r`   r   r   r   
child_notes           r   _build_child_system_promptr    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
expanduserro   rG   isabsisdir)parent_agent
candidates	candidater   s       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                     t          ddh          fdt          j                    D             fd| D             S )a^  Remove toolsets that contain only blocked tools.

    The strip set is derived from DELEGATE_BLOCKED_TOOLS plus the explicit
    composite/scenario toolsets (delegation, code_execution) that have no
    one-to-one tool. This keeps the blocklist and the strip set in lockstep
    so new blocked tools can't silently leak through as toolset names.
    
delegationcode_executionc           	      |    h | ]8\  }}|v s-t          d  |                    dg           D                       6|9S )c              3   (   K   | ]}|t           v V  d S r7   )DELEGATE_BLOCKED_TOOLSrO   ts     r   	<genexpr>z1_strip_blocked_tools.<locals>.<setcomp>.<genexpr>  s(      JJqq**JJJJJJr!   r   )allr(   )rO   re   defn_COMPOSITE_BLOCKED_TOOLSETSs      r   	<setcomp>z'_strip_blocked_tools.<locals>.<setcomp>	  s`       D$...JJDHHWb4I4IJJJJJ / 	...r!   c                     g | ]}|v|	S r8   r8   )rO   r  blocked_toolset_namess     r   rV   z(_strip_blocked_tools.<locals>.<listcomp>  s$    BBB!1,A#A#AA#A#A#Ar!   )	frozensetr	   rS   )r  r!  r$  s    @@r   _strip_blocked_toolsr&    sh     #,\;K,L"M"M   ".**   CBBBxBBBBr!   linec                     t          | dd          }t          |          r	  ||           dS # t          $ r Y nw xY wt          |           dS )aW  Emit a human-readable progress line to the parent's console.

    Routes through ``parent_agent._safe_print`` when available so headless
    stdio hosts (ACP, gateway API) can redirect non-protocol output to
    stderr via their configured ``_print_fn``. A bare ``print()`` would
    otherwise land on stdout and corrupt JSON-RPC framing.
    _safe_printN)r  callablerG   print)r  r'  printers      r   _emit_parent_consoler-    sk     lM488G 	GDMMMF 	 	 	D		$KKKKKs   / 
<<r<   	parent_iddepthmodelr  session_ref
task_index
task_countr/  r0  r1  r2  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_callbackr.   r   ] rh      r   r   c                     
 	d} | d<   | d<   | d<   | d<   
t          
          | d<   r-                    d          rt          d                   | d<   d	         | d
<   | S )N)r3  r4  r   r<   r/  r0  r1  r  
session_idchild_session_idr   
tool_count)rn   r(   ro   )kw_tool_countr0  
goal_labelr1  r/  r2  r<   r4  r3  r  s    r   _identity_kwargsz8_build_child_progress_callback.<locals>._identity_kwargsO  s    $$
 

 " +B} 'B{OBwKBwK!(^^BzN  	D;??<88 	D%(\)B%C%CB!"&q><	r!   
event_typer|   rj   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   rG   r   rH   )	rB  r|   rj   argsr   payloaderA  	parent_cbs	          r   _relayz._build_child_progress_callback.<locals>._relayg  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 | d
k    r d
|           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: %srj   rh   subagent.completesubagent.textrj   u   ├─ 💭 ""zsubagent.thinkingr   z Parent callback relay failed: %sr   r.   r=  	last_tool#   )get_tool_emojiu   ├─ z  "zsubagent.tool, subagent.progress   🔀 )rJ  rM  )rq   print_aboverG   r   rH   rl   r   r   r(   r   r   r   r   r   r=   r0   agent.displayrS  rt   r   clear)rB  r|   rj   rD  r   shortrF  eventr   summary_textrecrS  emojir'  summary_BATCH_SIZE_batchrH  r?  r@  rG  prefixspinnerr<   s                  r   	_callbackz1_build_child_progress_callback.<locals>._callbacks  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(( F?G4444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:)C9 9DDE) )
F3FFG3 3
H"=HH"(H9 9
I(I##I(/KKKL4 4
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.rT  rU  rV  rO  N)r   rZ  )r`  rb  rH  rG  rc  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   ro   r   rg  )r3  r   r  r4  r<   r/  r0  r1  r  r2  re  rg  ra  rb  rA  rH  r?  r@  rG  rc  rd  s   `  ```````  @@@@@@@@@r   _build_child_progress_callbackrh  $  s   8 l$7>>G&>EEI 9 t (2A~~#a####2F*"##%%J KF#Kd38n               2 KO
: 
:
:$'
:9<
: 
: 
: 
: 
: 
: 
: FJn n"n47n n n n n n n n n n n n n n`        Ir!   valuec                 n    t          | pd                                                              d          S )Nrh   /)ro   r   rstrip)ri  s    r   _normalized_runtime_urlrm    s.    u{!!##**3///r!   fallback_base_urlc                    t          |          }t          | dd          }t          |t                    rAt          |                    d                    }|r||k    r|                    d          r|S t          | dd          }|=t          t          |dd                    }|r||k    r|                    d          r|S |pdS )al  Return the base URL the parent is actually calling, not a stale attribute.

    ``parent_agent.base_url`` can still carry a leftover OpenRouter URL from an
    old config while the live OpenAI client in ``_client_kwargs`` already points
    at local Ollama. Subagents must inherit the active endpoint or they 401
    against OpenRouter with a dummy/local key.
    _client_kwargsNbase_url)zhttp://zhttps://clientrh   )rm  r  rl   rm   r(   r   )r  rn  surface_urlclient_kwargs
kwargs_urlrr  live_urls          r   _inherit_parent_base_urlrw    s     **;<<KL*:DAAM-&& ,]->->z-J-JKK
	k))%%&=>> * \8T22F +76:r+J+JKK	K''##$;<< ( O$$r!   max_iterationsoverride_provideroverride_base_urloverride_api_keyoverride_api_modeoverride_acp_commandoverride_acp_argsc                   =>?@ 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          }i } t3          | ||||||||| 
  
        =d}!=rdt4          ddf=fd}"|"}!|p|j        }#|pt          |dd          }$|	p|j        }%|	st;          ||%          }%|
p|}&t          |dd          pd}'||}(n|$|'k    rd}(nt          |dd          }(|r8ddl})|)                    |          st@          !                    d|           d}d}|pt          |dd          }*tE          ||nt          |dg           pg           }+|r|sd}*g }+|rd}$d }(t          |d!d          },|,}-	 |                    d"          }.|.s|.d#u r1dd$l#m$}/  |/|.          }0|0|0}-nt@          !                    d%|.           n2# tJ          $ r%}1t@          &                    d&|1           Y d}1~1nd}1~1ww xY wt          |d'd          pd}2t          |d(d          }3t          |d)d          }4t          |d*d          }5t          |d+d          }6t          |d,d          }7|rd}3d}4d}5d}6 |dRi d-|%d|&d|#d|$d|(d|*d|+d.|d/t          |d/d          d!|-d0t          |d0d          d1|2d|d2d3d4|d5d6|  d7d8d9d:d3d;d3d<dd=|!d>t          |d?d          d@t          |dAd          d(|3d)|4d*|5d+|6d,|7dB=dCd}8t          |dDd          |8_'        t          |8dAd          pd| dA<   ||8_(        ||8_)        ||8_*        ||8_+        ||8_,        t          |dEd          pd|8_-        t          |dAd          }9|9rt          |8dFd          
|9|8j.        dG<   t_          |$||%          }:|:|:|8_0        t          |dH          rbt          |dId          };|;r5|;5  |j1                            |8           ddd           n# 1 swxY w Y   n|j1                            |8           =rA	  =dJ|K           n2# tJ          $ r%}1t@          &                    dL|1           Y d}1~1nd}1~1ww xY w	 ddMl2m3}<  |<dNt          |dAd          t          |dEd          pd|t          |8dAd          |||O           n,# tJ          $ r t@          &                    dPd3Q           Y nw xY w|8S )Sa  
    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_depthr.   r   r   zsa--   _subagent_idenabled_toolsetsvalid_tool_namesc                 B    h | ]}                     |          xS r7   )get_toolset_for_tool)rO   re   model_toolstss     r   r"  z%_build_child_agent.<locals>.<setcomp>W  s<     
 
 
!66t<<<I IIIr!   c                     g | ]}|v |	S r8   r8   )rO   r  expanded_parents     r   rV   z&_build_child_agent.<locals>.<listcomp>d  s#    FFFo1E1E!1E1E1Er!   r  r   api_keyrp  r1  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rG   r   rH   )r   rF  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providerrh   api_modezUIgnoring acp_command=%r: binary not found on PATH; falling back to default transport.acp_commandacp_argszcopilot-acpchat_completionsreasoning_configreasoning_effortF)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_scorerq  rx  
max_tokensprefill_messagesfallback_model
quiet_modeTephemeral_system_prompt
log_prefix
[subagent-]platformsubagentskip_context_filesskip_memoryclarify_callbackthinking_callback
session_db_session_dbparent_session_idr;  r7  iteration_budget	_print_fn_current_turn_id_session_init_model_config_delegate_from_active_children_active_children_lockzsubagent.spawn_requestedrO  z spawn_requested relay failed: %sinvoke_hooksubagent_start)r  parent_turn_idparent_subagent_idr<  child_subagent_id
child_role
child_goalz%subagent_start hook invocation failedexc_infor8   )4	run_agentr  uuidr  r   r   uuid4hexr   r'   r   hasattrr  r  DEFAULT_TOOLSETSr   r   r   r&  r   rt   r  r  rp  r(   rh  ro   r1  rq  rw  shutilwhichr   r   rn   hermes_constantsr  rG   rH   r  r  _delegate_roler  _parent_subagent_id_subagent_goal_parent_turn_idr  _resolve_child_credential_pool_credential_poolr  hermes_cli.pluginsr  )Ar3  r   r  r  r1  rx  r4  r  ry  rz  r{  r|  r}  r~  r`   r  _uuidr   	max_spawnorchestrator_okeffective_roler<   r  	tui_depthdelegation_cfgparent_enabledr   r   workspace_hintchild_promptparent_api_keyeffective_model_for_cbchild_session_refchild_thinking_cbr  effective_modeleffective_providereffective_base_urleffective_api_key_parent_providereffective_api_mode_shutileffective_acp_commandeffective_acp_argsparent_reasoningchild_reasoningdelegation_effortr  r   rI   parent_fallbackchild_providers_allowedchild_providers_ignoredchild_providers_orderchild_provider_sort!child_openrouter_min_coding_scorechild
parent_sid
child_poollock_invoke_hookr  r  r  r  sA                                                                @@@@r   _build_child_agentr    s
   > "!!!!! ,(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
 )+6$$%  $  
,	L# 	L$ 	L 	L 	L 	L 	L 	L , 1|1O*UglJPT.U.U*Cl.C X5lDVWW(:N |Z>>D"$.	/	/	/!$\:tDD  
%    }}122 	%NN5$  
 $(  $0 GmT5 5 ( 	lJ339r    !5   $ 0 +/ |-?FF&OL +../ABB 
	 1U : :??????++,=>>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\2&F&F&L"l#'E *E %E 2EE#L2DbIIORE
 |T::J Hge%A4HHT=G()9: 0L*< J !+ |/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MBBBBBB%lL$GG"<1CRHHNB1$UL$??)%		
 		
 		
 		
 		
  M M M<tLLLLLM LsV   #AN0 0
O:OOW//W36W3X& &
Y0YYAZ" "&[
[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_okr  idxz%Y%m%d_%H%M%Szsubagent-timeout-r  z.logrh   r'  r   c                 2                         |            d S r7   )rt   )r'  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](empty)z## Child config)r1  r  r  rq  rx  r  r  r  r  r  r  rq    z: z: <unreadable>z## Toolsetsr  z  enabled_toolsets:  r  z  loaded tool count: z  loaded tools:      z## Prompt / schema sizesr  system_promptz  system_prompt_bytes: utf-8zn/az  system_prompt_chars: z  system_prompt: <error: >r   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)rh   ) r  r  datetimesys	tracebackmkdirrG   r  nowstrftimero   	isoformatr   rq   rl   r   encoder   r   get_activity_summaryrS   is_alive_current_framesr(   identformat_stackrl  split
write_textr   r   r   )"r  r3  r  r  r  r   r  _dt_sys
_tracebackhermes_homelogs_dirr<   r  	dump_pathr  _goal_previewattrr+   enabled
tool_names
sys_promptrI   tools_schema_schema_jsonr`  rP   rQ   framesworker_framestack
frame_linesubr  s"                                    @r   !_dump_subagent_timeout_diagnosticr.  x  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r`  c                    	 ddl m} ddl} |dd          }|                    dd           |j                                                            d          }|d	|  d
| dz  }|                    |d           t          |          S # t          $ r&}t          
                    d|           Y d}~dS d}~ww xY w)a  Write a subagent's full summary to the delegation cache and return path.

    Mirrors web_extract's ``_store_full_text``: the file lands in
    ``cache/delegation`` which is mounted read-only into remote backends
    (Docker/Modal/SSH) via ``credential_files._CACHE_DIRS``, so the parent's
    terminal/``read_file`` tools can page through the complete text on any
    backend. Returns the absolute path, or None on failure (best-effort:
    the trimmed head+tail is still returned to the parent regardless).
    r   )get_hermes_dirNzcache/delegationdelegation_cacheTr  z%Y%m%d_%H%M%S_%fzsubagent-summary-r  z.txtr	  r  z,Failed to spill subagent summary to file: %s)r  r0  r  r  r  r  r  ro   rG   r   rH   )r3  r`  r0  r  	cache_dirr  r  rI   s           r   _spill_summary_to_filer3    s    333333"N#57IJJ	t444\(();<<DzDDBDDDD'2224yy   CSIIIttttts   B
B 
B=B88B=capc           	         t          |           }t          |dz            }||z
  }| d|         }| | d         }|                    d          }||dz  k    r
|d|         }|                    d          }d|cxk    r	|dz  k     rn n||dz   d         }t	          ||           }	ddd	t          |          d
dt          |          d
d|d
dg}
|	rM|                    d          dz   }|
                    d|	            |
                    d|	 d| d           n|
                    d           |
                    d           |dz   |z   d                    |
          z   }||	fS )a  Return (model_text, spill_path) for one over-budget summary.

    Mirrors web_extract's ``_truncate_with_footer``: keep a head+tail window
    (~75% head / ~25% tail, snapped to line boundaries) so the subagent's
    opening AND its closing (outcomes / files-changed / issues, which live at
    the end) both survive, spill the full text to disk, and append a footer
    telling the parent exactly how much it's seeing and the precise
    ``read_file offset=`` to page into the omitted middle. Deterministic.
    g      ?Nr   r   r   r.   rh   uE   ──────── [SUMMARY TRUNCATED] ────────zShowing ,z chars (head) + z chars (tail) of u:    total — trimmed to protect the parent's context window.r   zFull subagent output saved to: z,To read the omitted middle: read_file path="z	" offset=zV limit=200  (the file is the complete summary; raise/lower offset to page through it).zWFull output could not be stored to disk; the head+tail above is all that was preserved.uo   ─────────────────────────────────────u+   

[... middle omitted — see footer ...]

)rq   r   rfindfindr3  countrt   r   )r`  r4  r3  original_lenhead_budgettail_budgetr   rv   nl
spill_pathfooter_linesmiddle_start_line
model_texts                r   _trim_summary_with_footerrB  !  s    w<<LcDj//K#K<K< DK<==!D	D		B	K#CRCy	4BB""""s""""""BFGG}'
G<<J 	7	Y3t99K 	Y 	YD		K 	Y 	YX	Y 	Y 	YL  
 JJt,,q0JjJJKKK@: @ @'@ @ @	
 	
 	
 	
 	&	
 	
 	
 
###IIDPSWS\S\]iSjSjjJz!!r!   n_summariesc                 R   	 t          | dd          }t          |dd          }t          |t                    r|dk    rdS t          | dd          }t          |t          t          f          r|dk     rd}t          |dd          pd}|t          |          z
  t          |          z
  }|dk    rt          S t          |t
          z            }|t          d|          z  }|dz  }	t          t          |	          S # t          $ r  t          	                    d	d
           Y dS w xY w)u  Per-summary character budget sized against the parent's *remaining*
    context headroom, split across the batch.

    The overflow this guards against is N summaries entering the parent
    context at once (batch fan-out), not any single summary being large.  We
    take a fraction of the headroom the parent has left (resolved context
    length minus what's already in its prompt) and divide it across the batch,
    converting tokens→chars at the standard ~4 chars/token estimate.

    Returns the per-summary char budget, or None when the parent's context
    state is unknown (no compressor / no token count) — in which case the
    caller falls back to the static char ceiling only.
    context_compressorNcontext_lengthr   session_prompt_tokensr  r.      z!Summary budget computation failedTr  )
r  rl   r   r   _MIN_SUMMARY_CHARS_SUMMARY_HEADROOM_FRACTIONr   rG   r   rH   )
r  rC  
compressorrF  used_tokensreservedheadroom_tokensbatch_token_budgetper_summary_tokensper_summary_charss
             r   _parent_summary_char_budgetrR  X  sF   \+?FF
 -=tDD.#.. 	.A2E2E4l,CQGG+U|44 	aK :|Q77<1(3{+;+;;c(mmKa%% 3M!MNN/3q+3F3FF.2%'8999   84HHHtts   =C< A6C< 8AC< <&D&%D&resultsc           	         d | D             }|sdS t                      }	 t          |                    dt                              }n# t          t
          f$ r
 t          }Y nw xY wt          |t          |                    }d ||fD             }|sdS t          |          }|D ]}|d         }	t          |	          |k    rt          |	          }
t          |	||                    dd                    \  }}||d<   d|d	<   |r||d
<   t                              d|                    dd          |
||pd           dS )u  Trim subagent summaries in-place so the batch can't overflow the
    parent's context window, spilling full text to disk so nothing is lost.

    The effective per-summary cap is the MIN of:
      - the dynamic headroom budget (remaining parent context ÷ batch size), and
      - the static ``delegation.max_summary_chars`` ceiling (0 = disabled).

    When a summary exceeds the cap, its full text is written to a file and the
    in-context summary becomes a head slice plus a pointer to that file. This
    addresses issue/PR #9126: batch fan-out returned N full summaries verbatim,
    blowing the parent context and (on rate-limited providers) triggering a
    compression/429 death spiral.
    c                     g | ]I}t          |t                    t          |                    d           t                    ?|d          G|JS )r`  )rl   rm   r(   ro   rT   s     r   rV   z)_apply_summary_budget.<locals>.<listcomp>  sd       jD116@yAQAQSV6W6W\]^g\h	  r!   Nmax_summary_charsc                 "    g | ]}||d k    
|S )r   r8   )rO   cs     r   rV   z)_apply_summary_budget.<locals>.<listcomp>  s"    MMMMq1uu!uuur!   r`  r3  Tsummary_truncatedsummary_full_pathu9   [subagent-%s] summary trimmed %d → ~%d chars (spill=%s)?none)r'   r   r(   DEFAULT_MAX_SUMMARY_CHARSr   r   rR  rq   minrB  r   rH   )rS  r  	summariesr*   static_ceilingdynamic_budgetr  r4  entryr`  r:  rA  r>  s                r   _apply_summary_budgetrd    s      I  
..C3SWW%8:STTUUz" 3 3 323 1s9~~NNN NMnn=MMMJ 
j//C 
 
	"w<<37||!:S%))L"55"
 "

J &i%)!" 	4)3E%&GIIlC(( &	
 	
 	
 	

 
s   (A	 	A$#A$c                 )   HIJKLMNO t          j                    }t          dd          Nd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                    HdgIdgJdgLHIJL 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	           	 |                                 NrA	  Nd           n2# t          $ r%}t                              d|           Y d}~nd}~ww xY wddl}|p&d  d|                                j        dd          Ot          dd          }t          j                     }|r!t	          t3          j        |                    ng }t7                      }ddlm}  |dt<          t?                      f          }ddiMdt"          ddfNfdKKMOfd}|                     |          }	 |!                    |           }n# t          $ r}	 t          d!          r"                                 nt          d"          rd	_#        n# t          $ r Y nw xY wt!          |tH          tJ          f          }tM          t          j                    |z
  d#          } t          '                    d$ |rd%nd&tQ          |          j)         |            d}!d}"	 *                                }#t%          |#+                    d'd          pd          }"n# t          $ r Y nw xY w|rh|"dk    rbtY           t[          |pd(          t[          |           M+                    d          )          }!|!rt          '                    d* |!           Nr;	  Nd+|rd,|  d-nt#          |          |rd.nd/| d01           n# t          $ r Y nw xY w|r!|"dk    rd2| d3}$|!r|$d4|! z  }$nd2| d5|" d6}$nt#          |          }$ |rd.nd/d|$|rd.nd/|"| t          d7d          |!d8	cY d}~|.                    d9:           H/                                 |j0        |1                    d;            |rte          |           |K|	I	 |3                    |	           n2# t          $ r%}t                              d<|           Y d}~nd}~ww xY wddl}t          dd          }%t!          |%t                    rt	          |%          |_        t          d=          r	 t          d>d          }&|&r5|&5  j4        5                               ddd           n# 1 swxY w Y   nj4        5                               n9# tl          tn          f$ r%}t                              d?|           Y d}~nd}~ww xY w	 t          d@          r8                                 S S # t          $ r t                              dA           Y S w xY wd}~ww xY w	 |.                    d9:           n# |.                    d9:           w xY wNrXt          NdB          rH	 N9                                 n2# t          $ r%}t                              dC|           Y d}~nd}~ww xY wtM          t          j                    |z
  d#          } |+                    dD          pd0}'|+                    dEd9          }(|+                    dFd9          })|+                    dGd          }*|':                                dHk    }+|)rdF},n	|'r|+sdE},ndI},g }-i }.|+                    dJ          pg }/t!          |/t                    r|/D ]}0t!          |0tv                    s|0+                    dK          dLk    r|0+                    dM          pg D ]}1|1+                    dNi           }2|2+                    dOdP          ty          |2+                    dQd0                    dR}3|-=                    |3           |1+                    dS          }4|4r|3|.|4<   |0+                    dK          dTk    rt}          |0+                    dUd0                    }5t          |5          }6ty          |5          |6rd/ndVdW}7|0+                    dX          }4|4r|.+                    |4          nd}8|8|8@                    |7           v|-r|-dY         @                    |7           |)rdF}9n|(rdE}9ndZ}9t          d[d          }:t          d\d          };t          dd          }< |,|'|*| t!          |<t"                    r|<nd|9t!          |:t$          tZ          f          r|:ndt!          |;t$          tZ          f          r|;ndd]|-t          d7d          t!          t          d^d(          t$          tZ          f          r t[          t          d^d(          pd(          nd(d_}=|,dIk    r|+                    d/d`          |=d/<   	 |r|rt3          jA        |||          }>|>rt          da |>C                                D                       }?|?rxdbdc1                    |?dd                   z   ty          |?          dk    rddty          |?          dz
   dend0z   dfz   }@|=+                    dg          r|=dg         |@z   |=dg<   n|?|=dh<   n,# t          $ r t                              did	j           Y nw xY wt          d^d          }At          dkd          }B	 t	          t3          j        O                    ddl         }Cn# t          $ r g }CY nw xY w	 t3          jA        d0|g           }Dn# t          $ r i }DY nw xY wt          Ofdm|DD                                D                       ddl         }Et          |ddno          }F|'r
|'ddp         n|=+                    d/d0          |,| |'r
|'ddq         n|=+                    d/d0          t!          |:t$          tZ          f          rt%          |:          ndt!          |;t$          tZ          f          rt%          |;          ndt!          |Bt$          tZ          f          rt%          |B          ndt!          |*t$          tZ          f          rt%          |*          nd|C|E|Fdr}G|A+	 t[          |A          |Gds<   n# t          tl          f$ r Y nw xY wNr<	  Ndyi |G n2# t          $ r%}t                              dt|           Y d}~nd}~ww xY w|=H/                                 |j0        |1                    d;            |rte          |           |K|	I	 |3                    |	           n2# t          $ r%}t                              d<|           Y d}~nd}~ww xY wddl}t          dd          }%t!          |%t                    rt	          |%          |_        t          d=          r	 t          d>d          }&|&r5|&5  j4        5                               ddd           n# 1 swxY w Y   nj4        5                               n9# tl          tn          f$ r%}t                              d?|           Y d}~nd}~ww xY w	 t          d@          r8                                 S S # t          $ r t                              dA           Y S w xY w# t          $ r}tM          t          j                    |z
  d#          } t          jH        du  dv           Nr^	  Nd+t#          |          dI| t#          |          1           n2# t          $ r%}t                              dw|           Y d}~nd}~ww xY w d/dt#          |          d| t          d7d          dxcY d}~H/                                 |j0        |1                    d;            |rte          |           |K|	I	 |3                    |	           n2# t          $ r%}t                              d<|           Y d}~nd}~ww xY wddl}t          dd          }%t!          |%t                    rt	          |%          |_        t          d=          r	 t          d>d          }&|&r5|&5  j4        5                               ddd           n# 1 swxY w Y   nj4        5                               n9# tl          tn          f$ r%}t                              d?|           Y d}~nd}~ww xY w	 t          d@          r8                                 S S # t          $ r t                              dA           Y S w xY wd}~ww xY w# H/                                 |j0        |1                    d;            |rte          |           |K|	I	 |3                    |	           n2# t          $ r%}t                              d<|           Y d}~nd}~ww xY wddl}t          dd          }%t!          |%t                    rt	          |%          |_        t          d=          r	 t          d>d          }&|&r5|&5  j4        5                               ddd           n# 1 swxY w Y   nj4        5                               n9# tl          tn          f$ r%}t                              d?|           Y d}~nd}~ww xY w	 t          d@          r8                                 w w # t          $ r t                              dA           Y w w xY wxY w)zzi
    Run a pre-built child agent. Called from within a thread.
    Returns a structured result dict.
    r7  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   rx  r.   u_   Subagent %d appears stale (no progress for %d heartbeat cycles, tool=%s) — stopping heartbeatz<none>z delegate_task: subagent running z (iteration rk  rE   last_activity_descrh   )
wait_HEARTBEAT_INTERVALr  r  r(   _HEARTBEAT_STALE_CYCLES_IN_TOOL_HEARTBEAT_STALE_CYCLES_IDLEr   r   rG   )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  r3  s             r   _heartbeat_loopz*_run_single_child.<locals>._heartbeat_loop  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   daemonr  r  r.   r  r1  running)	r<   r/  r0  r   r1  
started_atr   r=  rD   rJ  rO  z"Progress callback start failed: %sz	subagent-r  r  _current_task_idDaemonThreadPoolExecutor)max_workersinitializerinitargsr  deltar   c                     | rsd S 	  d|            d S # t           $ r&}t                              d|           Y d }~d S d }~ww xY w)NrN  rO  zChild text relay failed: %sr  )r  rF  r  s     r   _relay_child_textz,_run_single_child.<locals>._relay_child_textt  s       1 ?!!/5AAAAAA ? ? ?:A>>>>>>>>>?s    
AAAc                  `    t          j                    d<                                  S )Nr  )user_messagetask_idstream_callback)	threadingcurrent_threadrun_conversation)r  _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!#&))!% 1 *   r!   )r   rF   _interrupt_requestedr   zSubagent %d %s after %.1fsz	timed outzraised rk          )r  r3  r  r  r  r   u;   Subagent %d 0-API-call timeout — diagnostic written to %srM  zTimed out after r  r   r   rh   )rj   r   r  r`  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  )	r3  r   r`  r   exit_reason	api_callsr  _child_rolediagnostic_pathF)rm  r9  z&Failed to release credential lease: %sr  r  z/Could not remove child from active_children: %sclosez,Failed to close child agent after delegationrg  z"Progress callback flush failed: %sfinal_response	completedinterruptedr  r  r   r_   r`   ra   rb   rd   re   unknown	arguments)rf   
args_bytesrc   rf   rg   ok)result_bytesr   ri   rY  rx  rG  session_completion_tokens)inputoutputsession_estimated_cost_usd)r3  r   r`  r  r  r1  r  tokens
tool_tracer  _child_cost_usdz$Subagent did not produce a response.c                     h | ]	}|D ]}|
S r8   r8   )rO   pathsps      r   r"  z$_run_single_child.<locals>.<setcomp>o  s%    OOOuOOAOOOOr!   uX   

[NOTE: subagent modified files the parent previously read — re-read before editing: rT  z (+z more)r  r`  stale_pathsz%file_state sibling-write check failedr  session_reasoning_tokensr   c                 0    h | ]\  }}|k    |D ]}|S r8   r8   )rO   tidr  r  r  s       r   r"  z$_run_single_child.<locals>.<setcomp>  sC       C-'' (' ''''r!   iX  rZ      i  )rj   r   r  r`  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r3  r   r`  r   r  r  r  rW  )Itime	monotonicr  r  rn   _last_resolved_tool_namesacquire_leasecurrentr  rg  rG   r   rH   r  EventThreadrl   ro   r   r   r?   startr  r  r  r   known_readsr   tools.daemon_poolr  _set_subagent_approval_cbr,   submitr]   rF   r  FuturesTimeoutErrorr   roundr   typer   r  r(   r.  r   shutdownr   r  r   rB   release_leaser  remover   UnboundLocalErrorr  rg  r   rm   rq   rt   rr   rs   r   writes_sincer   rW   rS   r}   r   logging	exception)Pr3  r   r  r  _kwargschild_startr  _saved_tool_namesr  leased_cred_idleased_entryrI   r  _heartbeat_thread_raw_sidr  
_raw_depth
_tui_depth_parent_sidrF  r  parent_task_id
wall_startparent_reads_snapshotchild_timeoutr  _timeout_executorr  _child_futurer]   _timeout_exc
is_timeoutdurationr  child_api_calls_summary_errsaved_tool_namesr  r`  r  r  r  _empty_sentinelr   r  trace_by_idr_   rx   ry   r{   entry_trz   rg   rk   result_metar   r  _input_tokens_output_tokens_modelrc  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  r  r  sP   ````                                                                    @@@@@@@@r   _run_single_childr    sF    .""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# 	
 	
 	
$B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 	 +,, 	?>>>>>44
 25779
 
 
 ILT{		?S 		?T 		? 		? 		? 		? 		? 		?	 	 	 	 	 	 	 	 	 *001IJJb	3"))-)@@FF \	 \	 \	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) %*-*>3$?$?%*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2l 	".""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C\	 B &&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..	 "--//Y6 	"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__..5cggi6L6LMMG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  ;C   
C/
C**C/AA4 5I AA4 
I2I-(AA4 -I22CAA4 M) '^ )]-5<N21](2
N?<](>N??A=](=9Q76](7
R](RA/](4)T](
T+(](*T++A](]-^ AA4 $W::
X)X$$X);[Z7+[7Z;	;[>Z;	?[\/\\$\>>$]%$]%(]--^ 1AA4 ^  AA4 6_ 
AA4 
_:_50AA4 5_::N
AA4 Cq AA4 &q0-AA4 /q00%AA4 )s  ?AA4  sAA4 sAA4 s* )AA4 *s96AA4 8s99EAA4  y AA4 y'$AA4 &y''AA4 -y6 5AA4 6
z% z AA4  z%%AA4 0|
|5|00|5*7*	*
	**A@ ;A@@A@ @$$AA
A
$AA1A0AA1A4ALA?>ALB>*AC)C(ALC)
ADC3ADDALDADD(ALE ALEAL FAF"F"
AGF,AGGAGH#AJH8AIIAJIAI#	I#AJI&AI#	I'AJJAJ<JAJ7J7AJ<K $AK&K&$ALLALLALLAL LAAS$M AM6M5AS$M6
AN%N AN NAS$N AN%N%AAS$O7AQPAP3P'AQP3AP7P7AQP:AP7P;AQQAS$QARQ+ARRAS$RARRAS$R$AR:R8AS$R:$AS!SAS$S AS!S!AS$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 (z).z3tasks must be a JSON array of task objects; parsed z	 instead.)
rl   ro   r   r   r   JSONDecodeErrorrx   rn   r  r   )r  rawr   rI   s       r   _recover_tasks_from_json_stringr  	  s     eS!! z
++--C ONN
C 
 
 
=14= = =
 	
 	
 	
 	
 	
 	


 fd## 
0F||$0 0 0
 	
 4<s   A A,A'!A,'A,
backgroundc                 R  ()*+,-./0 t          d          S t                      rt          d          S t          |          }|t          |d          nd}t	          dd          }t                      }	||	k    rt          j        dd	| d
|	 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 |0nB| r1t%          | t                    r|                                 r| ||dg0nt          d          S 0st          d          S t-          0          D ]\  }}t%          |t.                    s*t          d| dt1          |          j         d          c S |	                    dd                                          st          d| d          c S t5          j                    -g .t)          0          ,d 0D             /ddl}t'          |j                  }g *	 t-          0          D ]\  }}t          |	                    d          p|          }t=          ||d         |	                    d          d|d         |,|d         |d         |d          |d!         |	                    d"          |	                    d#          |$          }||_        *                     |||f           	 ||_        n# ||_        w xY wd%t.          f*+,-./0fd&)|r%dd'l!m"} dd(l#m$} 	 dd)l%m&}  |            }n# tN          $ r d*}Y nw xY w|sTt          (                    d+            )            }t%          |t.                    rd,|d-<   t          j        |d.          S  |d          }d/ *D             (tS          d0          rxt	          d1d          }(D ]d}	 |r5|5  j*        +                    |           ddd           n# 1 swxY w Y   nj*        +                    |           U# t          $ r Y aw xY w)fd2} (fd3}!d4 0D             }" ||"|d||d         || |!tY                      5	  	        }#|#	                    d6          d7k    rAt)          |"          }$|$d8k    rd9n|$ d:}%d7d;|$|#d<         |"|%d=}&t          j        |&d.          S t          (                    d>|#	                    dd?                      )            }'t%          |'t.                    rd@|'d-<   t          j        |'d.          S t          j         )            d.          S )Aa-  
    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.Fr   r  r   r   z&Delegation depth limit reached (depth=z, max_spawn_depth=z). Raise delegation.max_spawn_depth in config.yaml if deeper nesting is required (no hard ceiling, but each level multiplies API cost).rx  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`   r  zNo tasks provided.Task z must be an object, got .r   rh   z is missing a 'goal'.c                 .    g | ]}|d          dd         S )r   Nr   r8   r  s     r   rV   z!delegate_task.<locals>.<listcomp>	  s$    555a1V9SbS>555r!   r`   r  r1  r  rq  r  r  r   rD  )r3  r   r  r  r1  rx  r4  r  ry  rz  r{  r|  r}  r~  r`   r   c                     (dk    r;&d         \  } }}t          | |d         |*          }+                    |           nnd}t          *dd          }ddlm}  |'          5 }i }&D ]0\  }	}
}|                    t           |	|
d         |*          }|	||<   1d	 &D             }t          |                                          }|rt          *d
d          du r|D ]}||         }|                                rf	 |	                                }n|# t          $ rC}|ddt          |          ddt          |                    |          dd          d}Y d}~n4d}~ww xY w|dddddt          |                    |          dd          d}+                    |           |dz  }ːnddlm}m}  ||d|          \  }}|D ]}	 |	                                }nX# t          $ rK}||         }|ddt          |          ddt          |                    |          dd          d}Y d}~nd}~ww xY w+                    |           |dz  }|d         }|t!          ,          k     r,|         nd| }|                    dd          }|                    dd          }|dk    rdnd}(|z
  }| d|dz    d( d| d | d!
}|r:	 |                    |           n6# t          $ r t%          *d"|            Y nw xY wt%          *d"|            |r`|dk    rZ	 |                    d#| d$|dk    rd%nd& d'           # t          $ r&}t(                              d(|           Y d}~d}~ww xY w|ddd           n# 1 swxY w Y   +                    d) *           t/          +*           *rt1          *d+          r*j        r+D ]}	 |d         t!          -          k     r-|d                  d         nd&}*j                            ||                    d,d&          pd&|d         t!          &          k     r#t          &|d                  d-         d.d&          nd&/           # t          $ r Y w xY wt          *d.d          }	 dd0lm} n# t          $ r d}Y nw xY wd1}+D ]c}|                    d2d          } |                    d3d1          }!	 |!r|t=          |!          z  }n# t>          t@          f$ r Y nw xY w|_	 |                    dd4          }"tC          |"tD                    r+d|"cxk    rt!          &          k     rn n&|"         d-         nd}# |d5|t          *d6d&          pd&t          |#d.d          | |                    d,          |                    d          tE          |                    d          pdd7z            8           8# t          $ r  t(                              d9d:           Y aw xY w|d1k    r	 t=          t          *d;d1          pd1          }$|$|z   *_#        t          *d<d=          d>v rd?*_$        t          *d@dA          dBv rdC*_%        n,# t          $ r t(                              dDd:           Y nw xY wtM          tO          j(                    )z
  d-          }%+|%dES )FuO  Run all built children (1 or N), join on them, aggregate results,
        fire subagent_stop hooks + cost rollup, and return the combined result
        dict. Used by BOTH the synchronous path and the background runner. In
        the background case this whole function runs on the daemon executor, so
        the parent turn isn't blocked — but the batch still JOINS on itself
        here (all children must finish) before producing ONE consolidated
        results block. That is the contract: fan-out runs in the background,
        waits on each other, and returns together.
        r.   r   r   r6  Nr  )r  )r3  r   r  r  c                     i | ]	\  }}}||
S r8   r8   )rO   i_r  s       r   rR   zAdelegate_task.<locals>._execute_and_aggregate.<locals>.<dictcomp>	  s     "J"J"JAu1e"J"J"Jr!   r  FTr   r  r  r  u9   Parent agent interrupted — child did not finish in time)rm  FIRST_COMPLETEDr   )r   return_whenr3  r  r  r   r\  r  u   ✓u   ✗z [rk  r8  z  (zs)r  rV  z taskr  rh   z
 remainingzSpinner update_text failed: %sc                     | d         S )Nr3  r8   )rU   s    r   <lambda>z?delegate_task.<locals>._execute_and_aggregate.<locals>.<lambda>Z
  s
    q r!   )key_memory_managerr`  r   r;  )taskr]   r<  r  r  r  r  rY  subagent_stopr  r  )r  r  r<  r  rs  child_statusduration_msz$subagent_stop hook invocation failedr  r  session_cost_sourcer]  >   Nrh   r]  r  session_cost_statusr  >   Nrh   r  	estimatedzSubagent cost rollup failed)rS  total_duration_seconds))r  rt   r  r  r  r  r   keysdoner]   rG   ro   r(   concurrent.futuresrm  r  rq   rX  r-  update_textr   rH   sortrd  r  r  on_delegationr  r  rA   r   r   r   rl   r   r  r  r  r  r  r  )._i_tr  r]   completed_countspinner_refr  executorfuturesr
  r  future_child_by_indexpendingfr   rc  rI   _cf_waitr  r  labeldurr   icon	remainingcompletion_linerF  
_task_goal_parent_session_idr  _children_cost_totalr  
child_cost_child_index_child_agentr  total_durationchildrenmax_childrenn_tasksoverall_startr  rS  task_labels	task_lists.                                         r   _execute_and_aggregatez-delegate_task.<locals>._execute_and_aggregate	  s	    a<<$QKMBE&r2f:ulKKFNN6""""  O!,0CTJJK
 CBBBBB))lCCC mRx#+ ( (KAq%%__)#$vY#%1 -  F '(GFOO #K"J"J"J"Jgllnn-- WR|-CUKKtSS ") 1 1A")!*C vvxx "!&,-HHJJEE'0 !& !& !&69293714S56<=7>,;,?,?,D,DFVX\8* 8*
-& 
-&EEEEEE!& 36.;/3-h12893:(7(;(;C(@(@BRTX4& 4&
)" 
)" $NN5111+q0OOTTTTTTTT$,H/% % %MD' #' ,R ,R$*MMOOEE(   ")&/C.1*1+/),S-.45/6$3$7$7$<$<>NPT0" 0"
% 
%EEEEEE  u---'1, $L103c+6F6F0F0FK,,MTWMM  $ii(:A>>!&8S!9!9(.+(=(=uu5$+o$=	-1*Y*YSU*Y*YW*Y*Y*Y*YRU*Y*Y*Y& W[ + 7 7 H H H H#, [ [ [ 4\CYCYCY Z Z Z Z Z[ 1?UO?U?UVVV ' R9q==R + 7 7$eI$e$e9PQ>>CCWY$e$e$e!" !" !" !" $- R R R &-Mq Q Q Q Q Q Q Q QRm  WR-mR mR mR mR mR mR mR mR mR mR mR mR mR mR mR` LL66L777 	g|444 	&788	 ,	
 !   !.Y?? "%"56v>> 
 !0>>'$yyB77=2  %\2S]]BB $HU<-@$A!$DlTVWWW!# ?     !   D %\<FF	 FFFFFFF 	  	  	 LLL	   # 	T 	TE=$77J#4c::J >(E*,=,==(z*   #T$yyr:: ",449:l9Z9Z9Z9ZSQY]]9Z9Z9Z9Z9Z \*1-- 
 #&8#*<9KR#P#P#VTV%,\<%N%N)"'))I"6"6!&8!4!4 #UYY/A%B%B%Ga4$O P P	 	 	 	 	  T T TCdSSSSST  #%%K6RTW X X _\_``:ADX:X7
 <)>GGK]]]7AL4<)>	JJNccc7BL4 K K K:TJJJJJK t~//-?CC &4
 
 	
s  (BNDN
E$!9ENE$$A*NG$#N$
H9.AH4/N4H99BNK&%N&LNLN%$M	N
M;M60N6M;;NNNBQ>>
R
R R' 'R65R6-TTTCW55&XX)AZ &Z10Z1)dispatch_async_delegation_batch)get_current_session_key)async_delivery_supportedTzxdelegate_task: async delivery unsupported on this session (stateless HTTP API); running the batch synchronously instead.u   background=true is not available on this endpoint (stateless HTTP API — no channel to deliver a detached subagent result after the turn ends), so the subagent(s) ran SYNCHRONOUSLY and the result is included above.note)r   c                     g | ]\  }}}|	S r8   r8   )rO   r  rX  s      r   rV   z!delegate_task.<locals>.<listcomp>
  s    555y1a555r!   r  r  c                                    S r7   r8   )r=  s   r   _batch_runnerz$delegate_task.<locals>._batch_runner   s    ))+++r!   c                      D ]P} 	 t          | d          r|                     d           nt          | d          rd| _        A# t          $ r Y Mw xY wd S )NrF   zAsync delegation cancelledr  T)r  rF   r  rG   )_c_child_agentss    r   _batch_interruptz'delegate_task.<locals>._batch_interrupt  s    #  r;// 7%ABBBB %;<< 726/    D s   =A
AAc                     g | ]
}|d          S )r   r8   r  s     r   rV   z!delegate_task.<locals>.<listcomp>  s    ///!F)///r!   )	goalsr  r  r`   r1  session_keyrunnerinterrupt_fnr   r   
dispatchedr.   u   Subagent is running in the background. You and the user can keep working; its full result re-enters the conversation as a new message when it finishes. Do not wait or poll — just continue.u    subagents are running in parallel in the background. You and the user can keep working; they wait on each other and their consolidated results re-enter the conversation as a single message once ALL of them finish. Do not wait or poll — just continue.r  delegation_id)r   moder9  rO  rJ  rA  zZdelegate_task: async pool at capacity (%s); running the whole batch synchronously instead.rejecteda  The background delegation pool was at capacity (delegation.max_concurrent_children), so the subagent(s) ran SYNCHRONOUSLY and the result is included above. Raise delegation.max_concurrent_children in config.yaml to allow more concurrent background delegations.)-
tool_errorr9   r   r   r  r   r   r   r'   r(   DEFAULT_MAX_ITERATIONSr   rH   _resolve_delegation_credentialsr   ro   r   r  rl   rn   rq   r   	enumeraterm   r  r   r  r  r  r  r  rf  rt   tools.async_delegationr>  tools.approvalr?  gateway.session_contextr@  rG   infor  r  r  r   )1r   r  r  rx  r`   r  r  top_roler0  r  r*   default_max_itereffective_max_itercredsrI   recovered_taskstasks_errorr
  r  _model_tools_parent_tool_namesr  r  r  r>  r?  r@  	_async_ok_sync_result_session_key_ac_lockrF  rD  rH  _goalsdispatchnrA  rE  _cap_resultrG  r=  r7  r8  r9  r:  rS  r;  r<  s1         `                                 @@@@@@@@@r   r   r   &	  s   . JKKK
  
N
 
 	
 t$$H @J?UU;;;;[`J L"3Q77E$&&I	z-U - -'0- - -

 

 
	
 ..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"wIIJ		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(( 	+ 	+DAq -QUU6]]-FhGGN&vYi(( Gn1")"'
"3"'
"3!&y!1"'
"3%*YYy%9%9"'))F"3"3##  E( 0BE,OOQ5M****3	+8 2D..1C.CCCCs
D s
 s
 s
 s
 s
 s
 s
 s
 s
 s
 s
 s
 s
x  w;JJJJJJ::::::	HHHHHH0022II 	 	 	III	 	@KKQ   2133L,-- 4 V$ :l????..r:::55H555
 <!344 
	|-DdKKH#   A% E E(9@@DDDE E E E E E E E E E E E E E E %5<<R@@@!   D	, 	, 	, 	, 	,	 	 	 	 	 0/Y///22 .$ )688
 
 
 <<!!\11FA 66	 
  & & &  '$!)/!: G :gE::::
 	+LL*--	
 	
 	

 -,..k4(( 	:  z+E:::: :,,..UCCCCss   /D   
D0
D+%D0+D0'CO 	O3P PP*S<.S	S<S	S<S	S<<
T	T	r  r  c                    | st          |dd          S t          |dd          pd}t          |dd          }| dk    r	 ddlm}m}  ||          }|dS  |t          |dd                    }||dk    r
|||k    r|S  ||          }	|	|	                                r|	S n3# t
          $ r&}
t                              d	||
           Y d}
~
nd}
~
ww xY wdS || |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 )a  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.

    Custom endpoints are a special case: every direct ``delegation.base_url``
    runtime collapses to ``provider="custom"``, so bare provider equality would
    treat two *different* custom endpoints as interchangeable and let the child
    inherit the parent's pool. Leasing from that pool then overwrites the
    child's delegated ``base_url`` with the parent's endpoint (issue #7833).
    We therefore resolve custom runtimes by endpoint identity (the
    ``custom:<name>`` pool key derived from the base_url) and only share the
    parent's pool when both resolve to the *same* custom endpoint.
    r  Nr  rh   r
   r   )get_custom_provider_pool_key	load_poolrq  zDCould not resolve custom credential pool for child endpoint '%s': %s)rl  z:Could not load credential pool for child provider '%s': %s)r  agent.credential_poolrk  rl  has_credentialsrG   r   rH   )r  r  r  parent_providerparent_poolrk  rl  	child_key
parent_keypoolrI   s              r   r  r  K  s   .  ?|%7>>>lJ==CO,(:DAAK
 X%%	UUUUUUUU445GHHI 
 t 65j$77 J '#x//*)++""9Y''DD$8$8$:$: 	 	 	LLV"       	 t#5#H#H
333333y+,, 4 4 6 6K 
 
 
H	
 	
 	
 	
 	
 	
 	
 	

 4s;   B& +B& "B& &
C0CC&(D 
E D;;E 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}h d}|pd                                                                }||v }	|rw|	su|}
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.
    r1  rh   Nr  rq  r  r  >   google-genaigooglevertexbedrockr   )_detect_api_mode_for_urlr
   r  zchatgpt.comz/backend-api/codexzopenai-codexcodex_responseszapi.anthropic.com	anthropicanthropic_messageszapi.kimi.com/coding>   rz  r  r|  )r1  r  rq  r  r  )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   rD  )r1  r  rq  r  r  r   rD  )ro   r(   r   r   hermes_cli.runtime_providerry  r   r}  rG   r   _RUNTIME_PROVIDER_CUSTOMrn   )r*   r  configured_modelconfigured_providerconfigured_base_urlconfigured_api_keyconfigured_api_mode_NATIVE_SDK_PROVIDERS_provider_lower_is_native_sdk_providerr  ry  
base_lowerr  r  r}  runtimerI   s                     r   rT  rT    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 LKK*0b7799??AAO-1FF ,
#: ,
 % 	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   G3 3
H=HH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_CONFIGr  )load_config)clir  r(   rG   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 r.   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 zf items concurrently for this user (configured via delegation.max_concurrent_children in config.yaml). u	  

BOTH MODES RUN IN THE BACKGROUND. delegate_task returns immediately — you and the user keep working, and each subagent's full result re-enters the conversation as its own new message when it finishes. A batch is just N independent background subagents (N handles, each completes on its own). Do NOT wait or poll; just continue with other work after dispatching.

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. Background delegations are NOT durable: if the parent session is closed (/new) or the process exits before a subagent finishes, that subagent's work is discarded, and /stop cancels every running background subagent.

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=a   for this user and can be disabled globally via delegation.orchestrator_enabled=false.
- Subagent model is NOT selectable per call: children inherit the parent model (plus its fallback chain) unless you pin all subagents to a model via delegation.provider / delegation.model in config.yaml.
- Each subagent gets its own terminal session (separate working directory and state).
- Results are always returned as an array, one entry per task.)r   rG   r   r   r   r   )r8  	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!(! ! ! 	. ). . . 	6	I BN6	I 6	I @N6	I 6	Ib 9Bc6	I 6	I 6	I8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   rG   r   )r8  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 r.   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   rG   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 r8   )rm   rN   s      r   rR   z3_build_dynamic_schema_overrides.<locals>.<dictcomp>  s1     & & &q!477& & &r!   
propertiesr  r   r`   )r   r  )DELEGATE_TASK_SCHEMArS   r  r  r  )overrides_paramss    r   _build_dynamic_schema_overridesr    s    
|
,& &3LA,OUUWW& & &\" >\=]=]\"7+M:<Y<[<[\"6*=9 4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.arrayz	Task goalzTask-specific contextr   z;Per-task role override. See top-level 'role' for semantics.)r  enumr   r  )r  r  requiredz#(rebuilt at get_definitions() time))r  rS   r   booleanuX  DEPRECATED / IGNORED. Single-task delegations always run in the background automatically — you do not need to (and cannot) opt in or out. The result re-enters the conversation as a new message when the subagent finishes; just continue working in the meantime. Setting this has no effect; the parameter remains only for backward compatibility.)r   r  r  r`   r  )re   r   r  )r   rR  rD  c                 2    t          |dd          dk    }| S )u  Background flag for the MODEL-facing dispatch path (registry fallback).

    Delegations from the top-level agent always run in the background — the
    model does not choose. This applies to both a single task and a fan-out
    batch (each task becomes its own independent background subagent). The one
    exception is a delegation from an orchestrator subagent (depth > 0), which
    needs its workers' results within its own turn. The live path is
    ``run_agent._dispatch_delegate_task``; this lambda mirrors it for the rare
    case the intercept is bypassed. Direct Python callers of ``delegate_task``
    keep the historical synchronous default.
    r  r   )r  )rD  r  is_subagents      r   _model_background_valuer  ?  s#     ,(91==AK?r!   r  r  c                 N   t          | t                    s| S g }d}| D ]}t          |t                    s|                    |           -d |                                D             }|pt          |          t          |          k    }|                    |           |r|n| S )NFc                 ,    i | ]\  }}|t           v||S r8   )_MODEL_HIDDEN_TASK_FIELDS)rO   r  ri  s      r   rR   z3_strip_model_hidden_task_fields.<locals>.<dictcomp>[  s4     
 
 
U333 333r!   )rl   rn   rm   rt   rS   rq   )r  stripped_taskschangedr  strippeds        r   _strip_model_hidden_task_fieldsr  R  s    eT"" NG 
( 
($%% 	!!$'''
 
"jjll
 
 

 7S]]c$ii7h''''$/>>%/r!   r  c                 n   t          |                     d          |                     d          t          |                     d                    |                     d          |                     d          t          | |                    d                    |                    d                    S )Nr   r  r  rx  r`   r  )r   r  r  rx  r`   r  r  )r   r(   r  r  )rD  r>  s     r   r  r  i  s    }XXf##-dhhw.?.?@@xx 011XXf*41G1GHHVVN++      r!   u   🔀)re   toolsetschemahandlercheck_fnr_  dynamic_schema_overridesr7   )r.   )NNNNNNr   r  )NNNNNNN)zr   r  r   r  	getLoggerr   r   r   r  r  r  r   r   r  typingr   r   r   r   r  r	   r  r   r   tools.terminal_toolr   r  utilsr   r   r%  r  ro   r    r$   r,   r   r   r   r   Lockr3   r/   r4   __annotations__r=   r0   r5   r9   r?   rB   rJ   rX   r   r}   rr   rs   r   r   r   r   r   r   r   r   r   r   r   r   r   rS  r^  rJ  rI  r   rn  rp  ro  r  Enumr   r   r   r   r   r   r   r  r  r&  r-  r*  rh  rm  rw  r  r  r.  r3  tuplerB  rR  rd  r  r  r   r  rm   rT  r'   r  r  r  r  r  r   r   rR  r  r  r  registerr8   r!   r   <module>r     s    "   		8	$	$ 				             - , , , , , , , , , , ,      
 $        R R R R R R 4 4 4 4 4 4 4 4 #  	 	 : 3 S    
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 

 

 

 

  	4 4 4cN4 4 	4
 
$sCx.4 4 4 4nS S    8!c !d ! ! ! !Hx}     "&,c &, &, &, &,R ! * * * * *6'!HUO '! '! '! '!T$c $ $ $ $N4    "J4 J J J J;s ;t ; ; ; ;S S    >I03C	#Y      " 
 !    *. x - - -   " "$ ... 4 4 4 4 4C 4 4 40 ,(6!3#7&4/ / 4]*+   T     "K %)K K K
Kc]K SM	K
 K K K 	K K K K\Xc]    6C49 Cc C C C C(S T    , 	G "&#$(,0G G GG
G 	G #G }G C=G C=G tCy!G $sCx.)G hG G G GT03 03 0 0 0 0%hsm %PXY\P] % % % %X (,'+&*'+*.-1 )a aa
a c]a tCy!	a
 C=a a a  }a  }a sma  }a #3-a   S	*!a( )a a a aHMM M 	M
 M I,-M M c]M M M M`s S Xc]    24"4"4"(+4"
34" 4" 4" 4"n%3 %8C= % % % %P4
4S#X#7 4
$ 4
 4
 4
 4
t 	U	I U	IU	I
U	I 
#s(^U	I U	I U	I U	Ip
8Dc3h()8C=89   0 !,0$(!%bD bD
3-bDc]bD Dc3h()bD SM	bD
 3-bD bD 	bD bD bD bDP )-R R R !R R R Rjy y y y y yxd    <dc d d d dN    "s " " " "J    0 	0
  !,  !J   $)1+ N N$,+B$ $
 %-%+^$<+h! !# # "( &  E+ 0 !0D  "% [9
 9
t y= =M M b 0 / / / / / / / $ d      +J7 03 03 0 0 0 0&  	  )
<     r!   