
    PL
j                    >    d Z ddlmZ ddlZ G d d          ZdgZdS )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                  Z    e Zd ZdZddZddZdd	Zedd
            Zedd            Z	dS )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.
    	max_totalintc                R    || _         d| _        t          j                    | _        d S Nr   )r   _used	threadingLock_lock)selfr   s     :/home/kuhnn/.hermes/hermes-agent/agent/iteration_budget.py__init__zIterationBudget.__init__    s#    "
^%%


    returnboolc                    | j         5  | j        | j        k    r	 ddd           dS | xj        dz  c_        	 ddd           dS # 1 swxY w Y   dS )z7Try to consume one iteration.  Returns True if allowed.NF   T)r   r
   r   r   s    r   consumezIterationBudget.consume%   s    Z 	 	zT^++	 	 	 	 	 	 	 	 JJ!OJJ		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s   AAA	A	Nonec                |    | j         5  | j        dk    r| xj        dz  c_        ddd           dS # 1 swxY w Y   dS )z6Give back one iteration (e.g. for execute_code turns).r   r   Nr   r
   r   s    r   refundzIterationBudget.refund-   s    Z 	  	 zA~~

a

	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 s   155c                R    | j         5  | j        cd d d            S # 1 swxY w Y   d S )Nr   r   s    r   usedzIterationBudget.used3   ss    Z 	 	:	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s     c                ~    | j         5  t          d| j        | j        z
            cd d d            S # 1 swxY w Y   d S r	   )r   maxr   r
   r   s    r   	remainingzIterationBudget.remaining8   s    Z 	7 	7q$.4:566	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7s   266N)r   r   )r   r   )r   r   )r   r   )
__name__
__module____qualname____doc__r   r   r   propertyr   r     r   r   r   r      s         & & & &
              X 7 7 7 X7 7 7r   r   )r$   
__future__r   r   r   __all__r&   r   r   <module>r)      sf   	 	 # " " " " "    *7 *7 *7 *7 *7 *7 *7 *7Z 
r   