From e39255a792dd456bc2385bd6332815d347303a87 Mon Sep 17 00:00:00 2001 From: bracesproul Date: Tue, 7 Jan 2025 10:00:38 -0800 Subject: [PATCH 1/6] feat: Add interrupt schema to library --- libs/langgraph/langgraph/types.py | 63 +++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/libs/langgraph/langgraph/types.py b/libs/langgraph/langgraph/types.py index fa1adafe6..366394749 100644 --- a/libs/langgraph/langgraph/types.py +++ b/libs/langgraph/langgraph/types.py @@ -491,3 +491,66 @@ def interrupt(value: Any) -> Any: ), ) ) + + +class HumanInterruptConfig(TypedDict): + """Configuration that defines what actions are allowed for a human interrupt. + + This controls the available interaction options when the graph is paused for human input. + + Attributes: + allow_ignore (bool): Whether the human can choose to ignore/skip the current step + allow_respond (bool): Whether the human can provide a text response/feedback + allow_edit (bool): Whether the human can edit the provided content/state + allow_accept (bool): Whether the human can accept/approve the current state + """ + allow_ignore: bool + allow_respond: bool + allow_edit: bool + allow_accept: bool + + +class ActionRequest(TypedDict): + """Represents a request for human action within the graph execution. + + Contains the action type and any associated arguments needed for the action. + + Attributes: + action (str): The type or name of action being requested (e.g., "Approve XYZ action") + args (dict): Key-value pairs of arguments needed for the action + """ + action: str + args: dict + + +class HumanInterrupt(TypedDict): + """Represents an interrupt triggered by the graph that requires human intervention. + + This is passed to the `interrupt` function when execution is paused for human input. + + Attributes: + action_request (ActionRequest): The specific action being requested from the human + config (HumanInterruptConfig): Configuration defining what actions are allowed + description (Optional[str]): Optional detailed description of what input is needed + """ + action_request: ActionRequest + config: HumanInterruptConfig + description: Optional[str] + + +class HumanResponse(TypedDict): + """The response provided by a human to an interrupt, which is returned when graph execution resumes. + + Attributes: + type (Literal['accept', 'ignore', 'response', 'edit']): The type of response: + - "accept": Approves the current state without changes + - "ignore": Skips/ignores the current step + - "response": Provides text feedback or instructions + - "edit": Modifies the current state/content + args (Union[None, str, ActionRequest]): The response payload: + - None: For ignore/accept actions + - str: For text responses + - ActionRequest: For edit actions with updated content + """ + type: Literal['accept', 'ignore', 'response', 'edit'] + args: Union[None, str, ActionRequest] \ No newline at end of file From 8534212a25d6e2c6c8c47a7a8ca6538a29816660 Mon Sep 17 00:00:00 2001 From: bracesproul Date: Tue, 7 Jan 2025 10:15:48 -0800 Subject: [PATCH 2/6] cr --- libs/langgraph/langgraph/types.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/libs/langgraph/langgraph/types.py b/libs/langgraph/langgraph/types.py index 366394749..d6d778e58 100644 --- a/libs/langgraph/langgraph/types.py +++ b/libs/langgraph/langgraph/types.py @@ -495,15 +495,16 @@ def interrupt(value: Any) -> Any: class HumanInterruptConfig(TypedDict): """Configuration that defines what actions are allowed for a human interrupt. - + This controls the available interaction options when the graph is paused for human input. Attributes: allow_ignore (bool): Whether the human can choose to ignore/skip the current step - allow_respond (bool): Whether the human can provide a text response/feedback + allow_respond (bool): Whether the human can provide a text response/feedback allow_edit (bool): Whether the human can edit the provided content/state allow_accept (bool): Whether the human can accept/approve the current state """ + allow_ignore: bool allow_respond: bool allow_edit: bool @@ -512,20 +513,21 @@ class HumanInterruptConfig(TypedDict): class ActionRequest(TypedDict): """Represents a request for human action within the graph execution. - + Contains the action type and any associated arguments needed for the action. Attributes: action (str): The type or name of action being requested (e.g., "Approve XYZ action") args (dict): Key-value pairs of arguments needed for the action """ + action: str args: dict class HumanInterrupt(TypedDict): """Represents an interrupt triggered by the graph that requires human intervention. - + This is passed to the `interrupt` function when execution is paused for human input. Attributes: @@ -533,6 +535,7 @@ class HumanInterrupt(TypedDict): config (HumanInterruptConfig): Configuration defining what actions are allowed description (Optional[str]): Optional detailed description of what input is needed """ + action_request: ActionRequest config: HumanInterruptConfig description: Optional[str] @@ -540,7 +543,7 @@ class HumanInterrupt(TypedDict): class HumanResponse(TypedDict): """The response provided by a human to an interrupt, which is returned when graph execution resumes. - + Attributes: type (Literal['accept', 'ignore', 'response', 'edit']): The type of response: - "accept": Approves the current state without changes @@ -552,5 +555,6 @@ class HumanResponse(TypedDict): - str: For text responses - ActionRequest: For edit actions with updated content """ - type: Literal['accept', 'ignore', 'response', 'edit'] - args: Union[None, str, ActionRequest] \ No newline at end of file + + type: Literal["accept", "ignore", "response", "edit"] + args: Union[None, str, ActionRequest] From d27beeed187060256ff5baa88685bb08926077eb Mon Sep 17 00:00:00 2001 From: bracesproul Date: Fri, 10 Jan 2025 10:45:22 -0800 Subject: [PATCH 3/6] move to prebuilt --- .../langgraph/langgraph/prebuilt/interrupt.py | 65 ++++++++++++++++++ libs/langgraph/langgraph/types.py | 66 ------------------- 2 files changed, 65 insertions(+), 66 deletions(-) create mode 100644 libs/langgraph/langgraph/prebuilt/interrupt.py diff --git a/libs/langgraph/langgraph/prebuilt/interrupt.py b/libs/langgraph/langgraph/prebuilt/interrupt.py new file mode 100644 index 000000000..bf440f210 --- /dev/null +++ b/libs/langgraph/langgraph/prebuilt/interrupt.py @@ -0,0 +1,65 @@ +class HumanInterruptConfig(TypedDict): + """Configuration that defines what actions are allowed for a human interrupt. + + This controls the available interaction options when the graph is paused for human input. + + Attributes: + allow_ignore (bool): Whether the human can choose to ignore/skip the current step + allow_respond (bool): Whether the human can provide a text response/feedback + allow_edit (bool): Whether the human can edit the provided content/state + allow_accept (bool): Whether the human can accept/approve the current state + """ + + allow_ignore: bool + allow_respond: bool + allow_edit: bool + allow_accept: bool + + +class ActionRequest(TypedDict): + """Represents a request for human action within the graph execution. + + Contains the action type and any associated arguments needed for the action. + + Attributes: + action (str): The type or name of action being requested (e.g., "Approve XYZ action") + args (dict): Key-value pairs of arguments needed for the action + """ + + action: str + args: dict + + +class HumanInterrupt(TypedDict): + """Represents an interrupt triggered by the graph that requires human intervention. + + This is passed to the `interrupt` function when execution is paused for human input. + + Attributes: + action_request (ActionRequest): The specific action being requested from the human + config (HumanInterruptConfig): Configuration defining what actions are allowed + description (Optional[str]): Optional detailed description of what input is needed + """ + + action_request: ActionRequest + config: HumanInterruptConfig + description: Optional[str] + + +class HumanResponse(TypedDict): + """The response provided by a human to an interrupt, which is returned when graph execution resumes. + + Attributes: + type (Literal['accept', 'ignore', 'response', 'edit']): The type of response: + - "accept": Approves the current state without changes + - "ignore": Skips/ignores the current step + - "response": Provides text feedback or instructions + - "edit": Modifies the current state/content + args (Union[None, str, ActionRequest]): The response payload: + - None: For ignore/accept actions + - str: For text responses + - ActionRequest: For edit actions with updated content + """ + + type: Literal["accept", "ignore", "response", "edit"] + args: Union[None, str, ActionRequest] diff --git a/libs/langgraph/langgraph/types.py b/libs/langgraph/langgraph/types.py index d6d778e58..9a2c78acd 100644 --- a/libs/langgraph/langgraph/types.py +++ b/libs/langgraph/langgraph/types.py @@ -492,69 +492,3 @@ def interrupt(value: Any) -> Any: ) ) - -class HumanInterruptConfig(TypedDict): - """Configuration that defines what actions are allowed for a human interrupt. - - This controls the available interaction options when the graph is paused for human input. - - Attributes: - allow_ignore (bool): Whether the human can choose to ignore/skip the current step - allow_respond (bool): Whether the human can provide a text response/feedback - allow_edit (bool): Whether the human can edit the provided content/state - allow_accept (bool): Whether the human can accept/approve the current state - """ - - allow_ignore: bool - allow_respond: bool - allow_edit: bool - allow_accept: bool - - -class ActionRequest(TypedDict): - """Represents a request for human action within the graph execution. - - Contains the action type and any associated arguments needed for the action. - - Attributes: - action (str): The type or name of action being requested (e.g., "Approve XYZ action") - args (dict): Key-value pairs of arguments needed for the action - """ - - action: str - args: dict - - -class HumanInterrupt(TypedDict): - """Represents an interrupt triggered by the graph that requires human intervention. - - This is passed to the `interrupt` function when execution is paused for human input. - - Attributes: - action_request (ActionRequest): The specific action being requested from the human - config (HumanInterruptConfig): Configuration defining what actions are allowed - description (Optional[str]): Optional detailed description of what input is needed - """ - - action_request: ActionRequest - config: HumanInterruptConfig - description: Optional[str] - - -class HumanResponse(TypedDict): - """The response provided by a human to an interrupt, which is returned when graph execution resumes. - - Attributes: - type (Literal['accept', 'ignore', 'response', 'edit']): The type of response: - - "accept": Approves the current state without changes - - "ignore": Skips/ignores the current step - - "response": Provides text feedback or instructions - - "edit": Modifies the current state/content - args (Union[None, str, ActionRequest]): The response payload: - - None: For ignore/accept actions - - str: For text responses - - ActionRequest: For edit actions with updated content - """ - - type: Literal["accept", "ignore", "response", "edit"] - args: Union[None, str, ActionRequest] From cfb121ee8f7fc2c83b1a3e63eb4c399e58841112 Mon Sep 17 00:00:00 2001 From: bracesproul Date: Fri, 10 Jan 2025 10:45:45 -0800 Subject: [PATCH 4/6] cr --- libs/langgraph/langgraph/types.py | 1 - 1 file changed, 1 deletion(-) diff --git a/libs/langgraph/langgraph/types.py b/libs/langgraph/langgraph/types.py index 9a2c78acd..fa1adafe6 100644 --- a/libs/langgraph/langgraph/types.py +++ b/libs/langgraph/langgraph/types.py @@ -491,4 +491,3 @@ def interrupt(value: Any) -> Any: ), ) ) - From b52b32b38e4686820e31bffbea69503e7a2db64c Mon Sep 17 00:00:00 2001 From: bracesproul Date: Mon, 13 Jan 2025 13:14:36 -0800 Subject: [PATCH 5/6] format n lint --- libs/langgraph/langgraph/prebuilt/interrupt.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/libs/langgraph/langgraph/prebuilt/interrupt.py b/libs/langgraph/langgraph/prebuilt/interrupt.py index bf440f210..d8bf7e79d 100644 --- a/libs/langgraph/langgraph/prebuilt/interrupt.py +++ b/libs/langgraph/langgraph/prebuilt/interrupt.py @@ -1,3 +1,12 @@ +from typing import ( + Literal, + Optional, + Union, +) + +from typing_extensions import TypedDict + + class HumanInterruptConfig(TypedDict): """Configuration that defines what actions are allowed for a human interrupt. From 0d50c62283847c60fc2d6b8b74b173237a2594ae Mon Sep 17 00:00:00 2001 From: bracesproul Date: Tue, 14 Jan 2025 10:39:57 -0800 Subject: [PATCH 6/6] cr --- .../langgraph/langgraph/prebuilt/interrupt.py | 42 ++++++++++++++----- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/libs/langgraph/langgraph/prebuilt/interrupt.py b/libs/langgraph/langgraph/prebuilt/interrupt.py index d8bf7e79d..2ab3ee0d1 100644 --- a/libs/langgraph/langgraph/prebuilt/interrupt.py +++ b/libs/langgraph/langgraph/prebuilt/interrupt.py @@ -13,10 +13,10 @@ class HumanInterruptConfig(TypedDict): This controls the available interaction options when the graph is paused for human input. Attributes: - allow_ignore (bool): Whether the human can choose to ignore/skip the current step - allow_respond (bool): Whether the human can provide a text response/feedback - allow_edit (bool): Whether the human can edit the provided content/state - allow_accept (bool): Whether the human can accept/approve the current state + allow_ignore: Whether the human can choose to ignore/skip the current step + allow_respond: Whether the human can provide a text response/feedback + allow_edit: Whether the human can edit the provided content/state + allow_accept: Whether the human can accept/approve the current state """ allow_ignore: bool @@ -31,8 +31,8 @@ class ActionRequest(TypedDict): Contains the action type and any associated arguments needed for the action. Attributes: - action (str): The type or name of action being requested (e.g., "Approve XYZ action") - args (dict): Key-value pairs of arguments needed for the action + action: The type or name of action being requested (e.g., "Approve XYZ action") + args: Key-value pairs of arguments needed for the action """ action: str @@ -45,9 +45,29 @@ class HumanInterrupt(TypedDict): This is passed to the `interrupt` function when execution is paused for human input. Attributes: - action_request (ActionRequest): The specific action being requested from the human - config (HumanInterruptConfig): Configuration defining what actions are allowed - description (Optional[str]): Optional detailed description of what input is needed + action_request: The specific action being requested from the human + config: Configuration defining what actions are allowed + description: Optional detailed description of what input is needed + + Example: + ```python + # Extract a tool call from the state and create an interrupt request + request = HumanInterrupt( + action_request=ActionRequest( + action="run_command", # The action being requested + args={"command": "ls", "args": ["-l"]} # Arguments for the action + ), + config=HumanInterruptConfig( + allow_ignore=True, # Allow skipping this step + allow_respond=True, # Allow text feedback + allow_edit=False, # Don't allow editing + allow_accept=True # Allow direct acceptance + ), + description="Please review the command before execution" + ) + # Send the interrupt request and get the response + response = interrupt([request])[0] + ``` """ action_request: ActionRequest @@ -59,12 +79,12 @@ class HumanResponse(TypedDict): """The response provided by a human to an interrupt, which is returned when graph execution resumes. Attributes: - type (Literal['accept', 'ignore', 'response', 'edit']): The type of response: + type: The type of response: - "accept": Approves the current state without changes - "ignore": Skips/ignores the current step - "response": Provides text feedback or instructions - "edit": Modifies the current state/content - args (Union[None, str, ActionRequest]): The response payload: + arg: The response payload: - None: For ignore/accept actions - str: For text responses - ActionRequest: For edit actions with updated content