
    `gj                    6    d Z ddlmZ ddlZ G d d      ZdgZy)u  Per-agent iteration budget — thread-safe consume/refund counter.

Extracted from ``run_agent.py``.  Each ``AIAgent`` instance (parent or
subagent) holds an :class:`IterationBudget`; the parent's cap comes from
``max_iterations`` (default 90), each subagent's cap comes from
``delegation.max_iterations`` (default 50).

``run_agent`` re-exports ``IterationBudget`` so existing
``from run_agent import IterationBudget`` imports keep working unchanged.
    )annotationsNc                  L    e Zd ZdZddZd	dZd
dZedd       Zedd       Z	y)IterationBudgetua  Thread-safe iteration counter for an agent.

    Each agent (parent or subagent) gets its own ``IterationBudget``.
    The parent's budget is capped at ``max_iterations`` (default 90).
    Each subagent gets an independent budget capped at
    ``delegation.max_iterations`` (default 50) — this means total
    iterations across parent + subagents can exceed the parent's cap.
    Users control the per-subagent limit via ``delegation.max_iterations``
    in config.yaml.

    ``execute_code`` (programmatic tool calling) iterations are refunded via
    :meth:`refund` so they don't eat into the budget.
    c                R    || _         d| _        t        j                         | _        y Nr   )	max_total_used	threadingLock_lock)selfr   s     I/root/.hermes/venv/lib/python3.12/site-packages/agent/iteration_budget.py__init__zIterationBudget.__init__    s    "
^^%
    c                    | j                   5  | j                  | j                  k\  r
	 ddd       y| xj                  dz  c_        	 ddd       y# 1 sw Y   yxY w)z7Try to consume one iteration.  Returns True if allowed.NF   T)r   r	   r   r   s    r   consumezIterationBudget.consume%   sM    ZZ 	zzT^^+	 	 JJ!OJ		 	 	s   AAAc                    | j                   5  | j                  dkD  r| xj                  dz  c_        ddd       y# 1 sw Y   yxY w)z6Give back one iteration (e.g. for execute_code turns).r   r   Nr   r	   r   s    r   refundzIterationBudget.refund-   s6    ZZ 	 zzA~

a
	  	  	 s	   %;Ac                ^    | j                   5  | j                  cd d d        S # 1 sw Y   y xY w)Nr   r   s    r   usedzIterationBudget.used3   s%    ZZ 	::	 	 	s   #,c                    | j                   5  t        d| j                  | j                  z
        cd d d        S # 1 sw Y   y xY wr   )r   maxr   r	   r   s    r   	remainingzIterationBudget.remaining8   s5    ZZ 	7q$..4::56	7 	7 	7s	   #:AN)r   int)returnbool)r   None)r   r   )
__name__
__module____qualname____doc__r   r   r   propertyr   r    r   r   r   r      s>    &
    7 7r   r   )r$   
__future__r   r
   r   __all__r&   r   r   <module>r)      s'   	 # *7 *7Z 
r   