
    [j?                        d Z ddlmZ ddlZddlmZmZmZ  eddh          Z	dZ
dd
ZddZddZdde
ddddZg dZdS )u  Turn-end guard for kanban workers.

Kanban workers must end with ``kanban_complete`` or ``kanban_block``. Models
(especially GLM / Qwen families) sometimes narrate the next step
("Let me write the report now") and stop with ``finish_reason=stop`` and no
tool calls. Hermes treats that as a clean exit → ``rc=0`` → dispatcher
``protocol_violation``.

This module is policy-only: when a kanban worker tries to finish without a
terminal board tool, return a bounded synthetic nudge so the conversation
loop continues instead of exiting.
    )annotationsN)AnyIterableOptionalkanban_completekanban_block   returnboolc                    t           j                            d          } | *|                                                                 dv rdS t           j                            d          pd                                }t          |          S )zReturn whether the kanban stop-guard is active for this process.

    On when ``HERMES_KANBAN_TASK`` is set (dispatcher-spawned worker), unless
    ``HERMES_KANBAN_STOP_NUDGE`` explicitly disables it.
    HERMES_KANBAN_STOP_NUDGEN>   0noofffalseFHERMES_KANBAN_TASK )osenvirongetstriplowerr   )envtasks     3/home/ice/.hermes/hermes-agent/agent/kanban_stop.pykanban_stop_nudge_enabledr      sr     *..3
4
4C
399;;,,..2MMMuJNN/006B==??D::    tcr   strc                   t          | t                    rr|                     d          }t          |t                    r$t          |                    d          pd          S t          |                     d          pd          S t	          | dd           }| t          t	          |dd          pd          S t          t	          | dd          pd          S )Nfunctionnamer   )
isinstancedictr   r   getattr)r   fns     r   _tool_call_namer'   &   s    "d )VVJb$ 	-rvvf~~+,,,266&>>'R(((	Z	&	&B	~72vr**0b111wr62&&,"---r   messagesIterable[dict] | Nonec                P   | sdS | D ]}t          |t                    s|                    d          }|dk    r5|                    d          pg D ]}t          |          t          v r  dS h|dk    r0t          |                    d          pd          }|t          v r dS dS )	zATrue if this conversation already invoked a terminal kanban tool.Frole	assistant
tool_callsTtoolr"   r   )r#   r$   r   r'   _TERMINAL_KANBAN_TOOLSr   )r(   msgr+   r   r"   s        r   session_called_kanban_terminalr1   2   s     u  #t$$ 	wwv;ggl++1r    "2&&*@@@444 A  V^^swwv,"--D---tt5r   )r(   attemptsmax_attemptstask_idr2   intr3   r4   Optional[str]c                    t                      sdS ||k    rdS t          |           rdS |p t          j                            d          pd                                pd}d| dS )zReturn a synthetic follow-up when a kanban worker exits without a terminal tool.

    Returns ``None`` when the guard should not fire (not a kanban worker,
    already completed/blocked, or nudge budget exhausted).
    Nr   r   z	this taskzj[System: You are a Hermes kanban worker. A plain-text reply is NOT a terminal state for the board.

Task `u!  ` is still `running`. Ending now without a board tool causes a protocol violation (clean exit with no `kanban_complete` / `kanban_block`).

Do this immediately in your next response — do not narrate intent:
1. Finish any remaining deliverable (write the required file(s) now).
2. Call `kanban_complete(summary=..., artifacts=[...])` if the work is done, OR `kanban_block(reason=...)` if you are blocked.

Never end a turn with only a promise of future action. Repeated protocol violations will block this task and require manual intervention.])r   r1   r   r   r   r   )r(   r2   r3   r4   tids        r   build_kanban_stop_nudger9   E   s     %&& t<t%h// t@bjnn%9::@b
G
G
I
I
X[C
	U
	U 
	U 
	Ur   )r9   r   r1   )r
   r   )r   r   r
   r   )r(   r)   r
   r   )
r(   r)   r2   r5   r3   r5   r4   r6   r
   r6   )__doc__
__future__r   r   typingr   r   r   	frozensetr/   _DEFAULT_MAX_ATTEMPTSr   r'   r1   r9   __all__ r   r   <module>rA      s     # " " " " " 				 * * * * * * * * * * #$5~#FGG  
 
 
 
	. 	. 	. 	.   * '+-!           F  r   