
    g3fio2                        d Z ddlmZmZmZ ddlmZmZmZ ddl	m
Z
 ddlmZ ddlmZmZ ddlmZmZmZmZ  G d d	e      Z G d
 de      Zed   Z G d de      Z G d de      Z G d de      Z G d de      Z G d de      Zeez  ez  Z G d de      Z G d de      Z G d de      Z  G d deeef         Z!y) Human in the loop middleware.    )AnyLiteralProtocol)	AIMessageToolCallToolMessage)Runtime)	interrupt)NotRequired	TypedDict)AgentMiddleware
AgentStateContextTStateTc                   2    e Zd ZU dZeed<   	 eeef   ed<   y)Actionz*Represents an action with a name and args.nameargsN)__name__
__module____qualname____doc__str__annotations__dictr        k/var/www/auto_recruiter/arenv/lib/python3.12/site-packages/langchain/agents/middleware/human_in_the_loop.pyr   r      s    4
IM
sCx.Sr   r   c                   D    e Zd ZU dZeed<   	 eeef   ed<   	 ee   ed<   y)ActionRequestz@Represents an action request with a name, args, and description.r   r   descriptionN)	r   r   r   r   r   r   r   r   r   r   r   r   r!   r!      s,    J
I1
sCx.SS!!7r   r!   approveeditrejectc                   J    e Zd ZU dZeed<   	 ee   ed<   	 ee	ee
f      ed<   y)ReviewConfigz$Policy for reviewing a HITL request.action_nameallowed_decisionsargs_schemaN)r   r   r   r   r   r   listDecisionTyper   r   r   r   r   r   r(   r(   '   s2    .GL)):T#s(^,,Tr   r(   c                   4    e Zd ZU dZee   ed<   	 ee   ed<   y)HITLRequestzIRequest for human feedback on a sequence of actions requested by a model.action_requestsreview_configsN)r   r   r   r   r,   r!   r   r(   r   r   r   r/   r/   4   s!    S-((3&&8r   r/   c                   "    e Zd ZU dZed   ed<   y)ApproveDecisionz*Response when a human approves the action.r$   typeN)r   r   r   r   r   r   r   r   r   r3   r3   >   s    4
)
@r   r3   c                   .    e Zd ZU dZed   ed<   	 eed<   y)EditDecisionz'Response when a human edits the action.r%   r4   edited_actionN)r   r   r   r   r   r   r   r   r   r   r6   r6   E   s    1
&/=r   r6   c                   4    e Zd ZU dZed   ed<   	 ee   ed<   y)RejectDecisionz)Response when a human rejects the action.r&   r4   messageN)r   r   r   r   r   r   r   r   r   r   r   r9   r9   R   s!    3
(
?Or   r9   c                   "    e Zd ZU dZee   ed<   y)HITLResponsez#Response payload for a HITLRequest.	decisionsN)r   r   r   r   r,   Decisionr   r   r   r   r<   r<   _   s    -H~*r   r<   c                   .    e Zd ZdZdededee   defdZ	y)_DescriptionFactoryz6Callable that generates a description for a tool call.	tool_callstateruntimereturnc                      y)z'Generate a description for a tool call.Nr   )selfrA   rB   rC   s       r   __call__z_DescriptionFactory.__call__i   s    r   N)
r   r   r   r   r   r   r
   r   r   rG   r   r   r   r@   r@   f   s-    @( : PXHY ^a r   r@   c                   V    e Zd ZU dZee   ed<   	 eee	z     ed<   	 ee
eef      ed<   y)InterruptOnConfigzConfiguration for an action requiring human in the loop.

    This is the configuration format used in the `HumanInTheLoopMiddleware.__init__`
    method.
    r*   r"   r+   N)r   r   r   r   r,   r-   r   r   r   r@   r   r   r   r   r   rI   rI   n   sF     L))9S#6677!D T#s(^,,Tr   rI   c                        e Zd ZdZdddeeeez  f   deddf fdZd	e	d
ede
dee   deeef   f
dZded	e	d
edee	dz  edz  f   fdZde
dee   deeef   dz  fdZde
dee   deeef   dz  fdZ xZS )HumanInTheLoopMiddlewarer   z Tool execution requires approval)description_prefixinterrupt_onrL   rD   Nc                    t         |           i }|j                         D ]C  \  }}t        |t              r|du st        g d      ||<   -|j                  d      s?|||<   E || _        || _        y)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boolrI   getrM   rL   )rF   rM   rL   resolved_configs	tool_nametool_config	__class__s         r   rP   z!HumanInTheLoopMiddleware.__init__   s    6 	9;&2&8&8&: 	:"I{+t,$&2C*G3$Y/ !45.9 +	: -"4r   rA   configrB   rC   c                     |d   }|d   }|j                  d      }t        |      r ||||      }n||}n| j                   d| d| }t        |||      }	t	        ||d         }
|	|
fS )	z9Create an ActionRequest and ReviewConfig for a tool call.r   r   r"   z

Tool: z
Args: )r   r   r"   r*   )r)   r*   )rT   callablerL   r!   r(   )rF   rA   rY   rB   rC   rV   	tool_argsdescription_valuer"   action_requestreview_configs              r   _create_action_and_configz2HumanInTheLoopMiddleware._create_action_and_config   s     f%	f%	 #JJ}5%&+IugFK*+K!445Z	{(S\R]^K '#
 %!$%89

 },,r   decisionc           	      f   |d   }|d   dk(  rd|v r|dfS |d   dk(  r#d|v r|d   }t        d|d   |d	   |d
         dfS |d   dk(  r>d|v r:|j                  d      xs d|d    d|d
    }t        ||d   |d
   d      }||fS d| d|j                  d       d|d    d| d	}t        |      )zUProcess a single decision and return the revised tool call and optional tool message.r*   r4   r$   Nr%   r7   rA   r   r   id)r4   r   r   rc   r&   r:   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   rT   r	   
ValueError)	rF   ra   rA   rY   r*   r7   re   tool_messagemsgs	            r   _process_decisionz*HumanInTheLoopMiddleware._process_decision   sH    ##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 l**)( 4&ll623 4((1&(9': ;011TV 	 or   c                 ^   |d   }|syt        d t        |      D        d      }|r|j                  syg }g }g }t        |j                        D ]p  \  }}	| j                  j                  |	d         x}
'| j                  |	|
||      \  }}|j                  |       |j                  |       |j                  |       r |syt        ||      }t        |      d   }t        |      x}t        |      x}k7  rd| d| d	}t        |      g }g }d
}t        |j                        D ]t  \  }}	||v rZ| j                  |	d      }
||   }|dz  }| j                  ||	|
      \  }}||j                  |       |sR|j                  |       d|j                  |	       v ||_        d|g|iS )zETrigger interrupt flows for relevant tool calls after an `AIMessage`.messagesNc              3   B   K   | ]  }t        |t              s|  y w)N)rR   r   ).0rj   s     r   	<genexpr>z7HumanInTheLoopMiddleware.after_model.<locals>.<genexpr>  s     \CCQZA[C\s   r   )r0   r1   r=   zNumber of human decisions (z/) does not match number of hanging tool calls (z).r      )nextreversed
tool_calls	enumeraterM   rT   r`   appendr/   r   lenrh   rk   )rF   rB   rC   rm   last_ai_msgr0   r1   interrupt_indicesidxrA   rY   r^   r_   hitl_requestr=   decisions_leninterrupt_countrj   revised_tool_callsartificial_tool_messagesdecision_idxra   revised_tool_callri   s                           r   after_modelz$HumanInTheLoopMiddleware.after_model  s   $\8H+=\^bc+"8"8 02-/')'(>(>? 	.NC++//	&0ABBO040N0Nvug1-  &&~6%%m4!((-	.  #+)
 l+K8	 !^+MCHYDZ1Z[-m_ =11@0AE  S/! .068 '(>(>? 	5NC''**9V+<=$\2!262H2Hi3/!< %0&--.?@,33LA #)))4!	5& "4[D+CDEEr   c                 .   K   | j                  ||      S w)zKAsync trigger interrupt flows for relevant tool calls after an `AIMessage`.)r   )rF   rB   rC   s      r   aafter_modelz%HumanInTheLoopMiddleware.aafter_modela  s      w//s   )r   r   r   r   r   r   rS   rI   rP   r   r   r
   r   tupler!   r(   r`   r>   r	   rk   r   r   r   __classcell__)rX   s   @r   rK   rK      s*   ' #E	&53'8 889&5  	&5
 
&5P"-"- ""- 	"-
 ""- 
}l*	+"-H(( ( "	(
 
x$d 22	3(TGF GFgh6G GFDQTVYQYN]aLa GFR00*1(*;0	c3h$	0r   rK   N)"r   typingr   r   r   langchain_core.messagesr   r   r	   langgraph.runtimer
   langgraph.typesr   typing_extensionsr   r   !langchain.agents.middleware.typesr   r   r   r   r   r!   r-   r(   r/   r3   r6   r9   r>   r<   r@   rI   rK   r   r   r   <module>r      s    # ) ) D D % % 4 [ [TY T
8I 
8 23
U9 
U9) 9Ai A
9 
PY P \)N:+9 +( .U	 .UbF0vx/?@ F0r   