
    ij1                     t   S r SSKJrJrJr  SSKJrJrJr  SSK	J
r
  SSKJr  SSKJrJr  SSKJrJr   " S S	\5      r " S
 S\5      r\S   r " S S\5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r\\-  \-  r " S S\5      r " S S\5      r " S S\5      r " S S\5      rg) Human in the loop middleware.    )AnyLiteralProtocol)	AIMessageToolCallToolMessage)Runtime)	interrupt)NotRequired	TypedDict)AgentMiddleware
AgentStatec                   :    \ rS rSr% Sr\\S'    \\\4   \S'   Sr	g)Action   z*Represents an action with a name and args.nameargs N)
__name__
__module____qualname____firstlineno____doc__str__annotations__dictr   __static_attributes__r       g/home/james-whalen/.local/lib/python3.13/site-packages/langchain/agents/middleware/human_in_the_loop.pyr   r      s    4
IK
sCx.Qr   r   c                   L    \ rS rSr% Sr\\S'    \\\4   \S'    \	\   \S'   Sr
g)ActionRequest   z@Represents an action request with a name, args, and description.r   r   descriptionr   N)r   r   r   r   r   r   r   r   r   r   r   r   r   r    r"   r"      s,    J
I1
sCx.QS!!7r   r"   approveeditrejectc                   R    \ rS rSr% Sr\\S'    \\   \S'    \	\
\\4      \S'   Srg)ReviewConfig'   z$Policy for reviewing a HITL request.action_nameallowed_decisionsargs_schemar   N)r   r   r   r   r   r   r   listDecisionTyper   r   r   r   r   r   r    r*   r*   '   s2    .GL)):T#s(^,,Tr   r*   c                   <    \ rS rSr% Sr\\   \S'    \\   \S'   Sr	g)HITLRequest4   zIRequest for human feedback on a sequence of actions requested by a model.action_requestsreview_configsr   N)
r   r   r   r   r   r/   r"   r   r*   r   r   r   r    r2   r2   4   s!    S-((3&&8r   r2   c                   *    \ rS rSr% Sr\S   \S'   Srg)ApproveDecision>   z*Response when a human approves the action.r&   typer   N)r   r   r   r   r   r   r   r   r   r   r    r7   r7   >   s    4
)
@r   r7   c                   6    \ rS rSr% Sr\S   \S'    \\S'   Srg)EditDecisionE   z'Response when a human edits the action.r'   r9   edited_actionr   N)	r   r   r   r   r   r   r   r   r   r   r   r    r;   r;   E   s    1
&/=r   r;   c                   <    \ rS rSr% Sr\S   \S'    \\   \S'   Sr	g)RejectDecisionR   z)Response when a human rejects the action.r(   r9   messager   N)
r   r   r   r   r   r   r   r   r   r   r   r   r    r?   r?   R   s!    3
(
?Or   r?   c                   *    \ rS rSr% Sr\\   \S'   Srg)HITLResponse_   z#Response payload for a HITLRequest.	decisionsr   N)	r   r   r   r   r   r/   Decisionr   r   r   r   r    rC   rC   _   s    -H~*r   rC   c                   2    \ rS rSrSrS\S\S\S\4S jr	Sr
g	)
_DescriptionFactoryf   z6Callable that generates a description for a tool call.	tool_callstateruntimereturnc                     g)z'Generate a description for a tool call.Nr   )selfrJ   rK   rL   s       r    __call___DescriptionFactory.__call__i   s    r   r   N)r   r   r   r   r   r   r   r
   r   rP   r   r   r   r    rH   rH   f   s'    @( :  TW r   rH   c                   ^    \ rS rSr% Sr\\   \S'    \\	\
-     \S'    \\\	\4      \S'   Srg)InterruptOnConfign   zConfiguration for an action requiring human in the loop.

This is the configuration format used in the `HumanInTheLoopMiddleware.__init__`
method.
r-   r$   r.   r   N)r   r   r   r   r   r/   r0   r   r   r   rH   r   r   r   r   r   r    rS   rS   n   sF     L))9S#6677!D T#s(^,,Tr   rS   c                      ^  \ rS rSrSrSS.S\\\\-  4   S\SS4U 4S	 jjjr	S
\
S\S\S\S\\\4   4
S jrS\S
\
S\S\\
S-  \S-  4   4S jrS\S\S\\\4   S-  4S jrSrU =r$ )HumanInTheLoopMiddleware   r   z Tool execution requires approval)description_prefixinterrupt_onrX   rM   Nc                   > [         TU ]  5         0 nUR                  5        HL  u  pE[        U[        5      (       a  USL a  [        / SQS9X4'   M.  M0  UR                  S5      (       d  MH  XSU'   MN     X0l        X l        g)a=  Initialize the human in the loop middleware.

Args:
    interrupt_on: Mapping of tool name to allowed actions.
        If a tool doesn't have an entry, it's auto-approved by default.

        * `True` indicates all decisions are allowed: approve, edit, and reject.
        * `False` indicates that the tool is auto-approved.
        * `InterruptOnConfig` indicates the specific decisions allowed for this
            tool.
            The InterruptOnConfig can include a `description` field (`str` or
            `Callable`) for custom formatting of the interrupt description.
    description_prefix: The prefix to use when constructing action requests.
        This is used to provide context about the tool call and the action being
        requested. Not used if a tool has a `description` in its
        `InterruptOnConfig`.
Tr%   )r-   r-   N)	super__init__items
isinstanceboolrS   getrY   rX   )rO   rY   rX   resolved_configs	tool_nametool_config	__class__s         r    r\   !HumanInTheLoopMiddleware.__init__   s    . 	9;&2&8&8&:"I+t,,$&2C*G3$/ ' !455.9+ '; -"4r   rJ   configrK   rL   c                     US   nUS   nUR                  S5      n[        U5      (       a
  U" XU5      nOUb  UnOU R                   SU SU 3n[        UUUS9n	[	        UUS   S9n
X4$ )	z9Create an ActionRequest and ReviewConfig for a tool call.r   r   r$   z

Tool: z
Args: )r   r   r$   r-   )r,   r-   )r`   callablerX   r"   r*   )rO   rJ   rf   rK   rL   rb   	tool_argsdescription_valuer$   action_requestreview_configs              r    _create_action_and_config2HumanInTheLoopMiddleware._create_action_and_config   s     f%	f%	 #JJ}5%&&+IgFK*+K!445Z	{(S\R]^K '#
 %!$%89

 ,,r   decisionc           	      t   US   nUS   S:X  a
  SU;   a  US4$ US   S:X  a"  SU;   a  US   n[        SUS   US	   US
   S9S4$ US   S:X  aA  SU;   a;  UR                  S5      =(       d    SUS    SUS
    3n[        UUS   US
   SS9nX'4$ SU SUR                  S5       SUS    SU S3	n[        U5      e)zUProcess a single decision and return the revised tool call and optional tool message.r-   r9   r&   Nr'   r=   rJ   r   r   id)r9   r   r   rq   r(   rA   z!User rejected the tool call for `z
` with id error)contentr   tool_call_idstatuszUnexpected human decision: z. Decision type 'z' is not allowed for tool 'z'. Expected one of z# based on the tool's configuration.)r   r`   r	   
ValueError)	rO   ro   rJ   rf   r-   r=   rs   tool_messagemsgs	            r    _process_decision*HumanInTheLoopMiddleware._process_decision   sF    ##67Fy(Y:K-Kd?"Fv%&4E*E$_5M$&v.&v. 	   Fx'H8I,Ill9- 3If4E3FjQZ[_Q`Pab  'v&&t_	L **)( 4&ll623 4((1&(9': ;011TV 	 or   c                    US   nU(       d  g[        S [        U5       5       S5      nU(       a  UR                  (       d  g/ n/ nUR                   H:  nUS   U R                  ;   a  UR	                  U5        M)  UR	                  U5        M<     U(       d  gUR                  5       n/ n	/ n
/ nU HK  nU R                  US      nU R                  X|X5      u  pU
R	                  U5        UR	                  U5        MM     [        U
US9n[        U5      nUS   n[        U5      =n[        U5      =n:w  a  SU SU S	3n[        U5      e[        U5       Hd  u  nnUU   nU R                  US      nU R                  UX|5      u  nnU(       a  UR	                  U5        U(       d  MS  U	R	                  U5        Mf     Xl        SU/U	Q0$ )
zETrigger interrupt flows for relevant tool calls after an `AIMessage`.messagesNc              3   T   #    U  H  n[        U[        5      (       d  M  Uv   M      g 7f)N)r^   r   ).0rx   s     r    	<genexpr>7HumanInTheLoopMiddleware.after_model.<locals>.<genexpr>  s     \+=CCQZA[CC+=s   (	(r   )r4   r5   rE   zNumber of human decisions (z/) does not match number of hanging tool calls (z).)nextreversed
tool_callsrY   appendcopyrm   r2   r   lenrv   	enumeratery   )rO   rK   rL   r|   last_ai_msginterrupt_tool_callsauto_approved_tool_callsrJ   revised_tool_callsartificial_tool_messagesr4   r5   rf   rk   rl   hitl_requesthitl_responserE   decisions_leninterrupt_tool_calls_lenrx   iro   revised_tool_callrw   s                            r    after_model$HumanInTheLoopMiddleware.after_model  s   $\8H+=\^bc+"8"8 02#% $//I6?7""7# ''	2(@(G(G	(R 0 $ .F-J-J-L68  02-/-I&&y'89F -1,J,J5-)N "">2!!-0 . #+)
 '0&=!+.	 !^+M(+,@(AA$
 .m_ =11I0J"N  S/! %Y/KAx,Q/I&&y'89F.2.D.DXy.a+| "))*;<|(//= 0 "4[D+CDEEr   )rX   rY   )r   r   r   r   r   r   r   r_   rS   r\   r   r   r
   tupler"   r*   rm   rF   r	   ry   r   r   r   __classcell__)rd   s   @r    rV   rV      s    ' #E	"53'8 889"5  	"5
 
"5 "5H"-"- ""- 	"-
 "- 
}l*	+"-H(( ( "	(
 
x$d 22	3(TKF KFg KF$sCx.SWBW KF KFr   rV   N) r   typingr   r   r   langchain_core.messagesr   r   r	   langgraph.runtimer
   langgraph.typesr   typing_extensionsr   r   !langchain.agents.middleware.typesr   r   r   r"   r0   r*   r2   r7   r;   r?   rF   rC   rH   rS   rV   r   r   r    <module>r      s    # ) ) D D % % 4 IRY R
8I 
8 23
U9 
U9) 9Ai A
9 
PY P \)N:+9 +( .U	 .Ub@F @Fr   