The langgraph manual said " Do not conditionally skip interrupt calls within a node", but I do have some situations in which I need to conditionally interrupt. For example, I have a very complex tool
def generate_elementary_steps(self,
ntimes:int = -1,
max_natoms_tot:int = -1,
min_natoms_tot:int = 0,
max_natoms:Dict[str, int] = None,
min_natoms:Dict[str, int] = None,
forbidden_pattern: List[Tuple[str, str]] = None):
'''
Generate reactions.
Args:
ntimes: The number of times the elementary steps is sampled. Here, "sample" means use BFS and DFS to search elementary steps. If `ntimes > 0`, use BFS firstly to get the shortest path and the remaining attempts will be made using DFS (DFS does not always guarantee to find a path, so multiple attempts are necessary). If `ntimes = -1` (default), a BFS-like method will be used to find all possible elementary steps.
max_natoms_tot: Maximum number of atoms in the intermediates. `-1` means no limitation.
min_natoms_tot: Minimum number of atoms in the intermediates.
max_natoms: A `dict` used to limit the maximum number of atoms of each element in the intermediates. If omitted, a default value is calculated from the final products.
min_natoms: A `dict` used to limit the minimum number of atoms of each element in the intermediates.
forbidden_pattern: Substructures of intermediates that are prohibited. For example, use `('H,O,C,O,H','0-1,1-2,2-3,3-4')` to represent geminal diol. If omitted, a list of default patterns are generated.
'''
If the user provided enough information in the initial prompt, then LLM can determine these arguments. However, if they did’t I should interrupt and ask them for the arguments, so I would write something like this
# I will wap this function in a global class, this class stores the objects used by the tool `generate_elementary_steps`
@tool
def generate_elementary_steps(...):
if max_natoms is None and forbidden_pattern is None:
response = interrupt({"message": "Ask for arguments",
"source": "tool.generate_elementary_steps", ...})
# The user may just click yes, in this case I will return a prompt to the LLM
if response == "yes":
return "User ask us to determine the arguments by ourself, let's investigate this chemical system and determine the args."
else: # The response contains the arguments we need
pass
Can I write interrupt in the way? There is another way, I build a interrupt_tool tool and ask the agent to call it when interruption is required:
@tool
def interrupt_tool(message: Dict[str, Any]):
'''
Call this tool if interruption is need. For example, ask for the arguments from the user.
'''
response = interrupt(message)
But I don’t think this is reliable, although it seems more clean and idempotent by default (only interrupt, no other operations).