-
Notifications
You must be signed in to change notification settings - Fork 5.9k
fix(langgraph): Make Overwrite survive JSON roundtrips
#8127
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,3 +1,3 @@ | ||||||||||
| import collections.abc | ||||||||||
| from collections.abc import Callable, Sequence | ||||||||||
| from typing import Any, Generic | ||||||||||
|
|
@@ -29,11 +29,25 @@ | |||||||||
|
|
||||||||||
|
|
||||||||||
| def _get_overwrite(value: Any) -> tuple[bool, Any]: | ||||||||||
| """Inspects the given value and returns (is_overwrite, overwrite_value).""" | ||||||||||
| """Inspects the given value and returns (is_overwrite, overwrite_value). | ||||||||||
|
|
||||||||||
| Recognises three forms: | ||||||||||
|
|
||||||||||
| * The typed `Overwrite` dataclass instance. | ||||||||||
| * The sentinel-keyed `{"__overwrite__": value}` dict form. | ||||||||||
| * The dataclass-erased `{"value": ..., "type": "__overwrite__"}` form that | ||||||||||
| results from JSON-serialising an `Overwrite` (e.g. an `orjson`-encoded | ||||||||||
| state update routed through the LangGraph API server). This keeps the | ||||||||||
| `Overwrite` semantics intact across JSON boundaries that strip dataclass | ||||||||||
| types. | ||||||||||
| """ | ||||||||||
| if isinstance(value, Overwrite): | ||||||||||
| return True, value.value | ||||||||||
| if isinstance(value, dict) and len(value) == 1 and OVERWRITE in value: | ||||||||||
| return True, value[OVERWRITE] | ||||||||||
| if isinstance(value, dict): | ||||||||||
| if len(value) == 1 and OVERWRITE in value: | ||||||||||
| return True, value[OVERWRITE] | ||||||||||
| if value.get("type") == OVERWRITE and "value" in value: | ||||||||||
| return True, value["value"] | ||||||||||
|
Comment on lines
+49
to
+50
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Extra-key dicts bypass reducers This now treats any channel update dict with (Refers to lines 49-50) Your feedback helps Open SWE learn. React with 👍 or 👎 to tell us if this review comment was useful.
Suggested change
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. that's fine |
||||||||||
| return False, None | ||||||||||
|
|
||||||||||
|
|
||||||||||
|
|
||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -976,3 +976,9 @@ def node_b(state: State): | |
|
|
||
| value: Any | ||
| """The value to write directly to the channel, bypassing any reducer.""" | ||
|
|
||
| type: Literal["__overwrite__"] = "__overwrite__" | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cursor said we can use not sure that is true |
||
| """Discriminator field. Lets the channel reducer recognise an `Overwrite` | ||
| even after its dataclass form is JSON-serialised and the typed instance | ||
| is lost (e.g. an `orjson`-encoded state update routed through the | ||
| LangGraph API server).""" | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe add more details where this is from -- seems like from user hand writing the return from a node?