From e80b4e20158b72ed870fc12886b32493b4a72de0 Mon Sep 17 00:00:00 2001 From: Martin Breuss Date: Tue, 16 Jun 2026 20:21:37 +0000 Subject: [PATCH 1/2] Update sample code for: LangGraph Tutorial: Build Stateful AI Agents in Python Refresh the LangGraph companion code for the tutorial update: - Bump to langgraph 1.2.5, langchain-openai 1.3.2, langchain-core 1.4.7, pydantic 2.13.4 (regenerated requirements.txt; pyproject floors raised) - Switch the model to gpt-5.4-nano - Fix check_escalation_status_node to fall back to 0 when no fine is extracted (avoids a TypeError on notices without a max potential fine) - Store the boolean answer.is_true in follow_ups (was storing the model object) - Drop the unused critical_fields_missing key from the agent's initial state - Point the README API-key link at platform.openai.com/api-keys and match the new tutorial title Co-Authored-By: Claude Opus 4.8 (1M context) --- python-langgraph/README.md | 6 +- python-langgraph/chains/binary_questions.py | 2 +- python-langgraph/chains/escalation_check.py | 2 +- python-langgraph/chains/notice_extraction.py | 2 +- python-langgraph/graphs/email_agent.py | 3 +- python-langgraph/graphs/notice_extraction.py | 6 +- python-langgraph/pyproject.toml | 6 +- python-langgraph/requirements.txt | 62 +++++++++++++++----- 8 files changed, 59 insertions(+), 30 deletions(-) diff --git a/python-langgraph/README.md b/python-langgraph/README.md index 3c3867eab0..082f7e5561 100644 --- a/python-langgraph/README.md +++ b/python-langgraph/README.md @@ -1,6 +1,6 @@ -# LangGraph: Build Stateful AI Agents in Python +# LangGraph Tutorial: Build Stateful AI Agents in Python -This folder contains the source code for [LangGraph: Build Stateful AI Agents in Python](https://realpython.com/langgraph-python/) +This folder contains the source code for [LangGraph Tutorial: Build Stateful AI Agents in Python](https://realpython.com/langgraph-python/) ## Setup @@ -12,7 +12,7 @@ Create a new virtual environment, and run the following command to install LangG You'll use `langchain-openai` to interact with OpenAI LLMs, but keep in mind you can use any LLM provider you like with LangGraph and LangChain. You'll use [`pydantic`](https://realpython.com/python-pydantic/) to validate the information your agent parses from emails. -Before moving forward, if you choose to use OpenAI, make sure you're signed up for an OpenAI account and you have a valid [API key](https://openai.com/api/). You'll need to set the following [environment variable](https://en.wikipedia.org/wiki/Environment_variable) before running any examples in this tutorial: +Before moving forward, if you choose to use OpenAI, make sure you're signed up for an OpenAI account and you have a valid [API key](https://platform.openai.com/api-keys). You'll need to set the following [environment variable](https://en.wikipedia.org/wiki/Environment_variable) before running any examples in this tutorial: ```dotenv OPENAI_API_KEY= diff --git a/python-langgraph/chains/binary_questions.py b/python-langgraph/chains/binary_questions.py index bf1fe2c830..2634d79be4 100644 --- a/python-langgraph/chains/binary_questions.py +++ b/python-langgraph/chains/binary_questions.py @@ -23,7 +23,7 @@ class BinaryAnswer(BaseModel): ] ) -binary_question_model = ChatOpenAI(model="gpt-4o-mini", temperature=0) +binary_question_model = ChatOpenAI(model="gpt-5.4-nano", temperature=0) BINARY_QUESTION_CHAIN = ( binary_question_prompt diff --git a/python-langgraph/chains/escalation_check.py b/python-langgraph/chains/escalation_check.py index 739b0cb5a1..73d91ace9b 100644 --- a/python-langgraph/chains/escalation_check.py +++ b/python-langgraph/chains/escalation_check.py @@ -25,7 +25,7 @@ class EscalationCheck(BaseModel): ] ) -escalation_check_model = ChatOpenAI(model="gpt-4o-mini", temperature=0) +escalation_check_model = ChatOpenAI(model="gpt-5.4-nano", temperature=0) ESCALATION_CHECK_CHAIN = ( escalation_prompt diff --git a/python-langgraph/chains/notice_extraction.py b/python-langgraph/chains/notice_extraction.py index 8479b6f94d..6c2d59f940 100644 --- a/python-langgraph/chains/notice_extraction.py +++ b/python-langgraph/chains/notice_extraction.py @@ -98,7 +98,7 @@ def compliance_deadline(self) -> date | None: ] ) -notice_parser_model = ChatOpenAI(model="gpt-4o-mini", temperature=0) +notice_parser_model = ChatOpenAI(model="gpt-5.4-nano", temperature=0) NOTICE_PARSER_CHAIN = ( info_parse_prompt diff --git a/python-langgraph/graphs/email_agent.py b/python-langgraph/graphs/email_agent.py index ae5c257d62..00bb17de97 100644 --- a/python-langgraph/graphs/email_agent.py +++ b/python-langgraph/graphs/email_agent.py @@ -62,7 +62,6 @@ def extract_notice_data( initial_state = { "notice_message": email, "notice_email_extract": None, - "critical_fields_missing": False, "escalation_text_criteria": escalation_criteria, "escalation_dollar_criteria": 100_000, "requires_escalation": False, @@ -110,7 +109,7 @@ def determine_email_action(email: str) -> str: ] tool_node = ToolNode(tools) -EMAIL_AGENT_MODEL = ChatOpenAI(model="gpt-4o-mini", temperature=0).bind_tools( +EMAIL_AGENT_MODEL = ChatOpenAI(model="gpt-5.4-nano", temperature=0).bind_tools( tools ) diff --git a/python-langgraph/graphs/notice_extraction.py b/python-langgraph/graphs/notice_extraction.py index bc6958765c..9406c282cd 100644 --- a/python-langgraph/graphs/notice_extraction.py +++ b/python-langgraph/graphs/notice_extraction.py @@ -51,7 +51,7 @@ def check_escalation_status_node(state: GraphState) -> GraphState: if ( text_check - or state["notice_email_extract"].max_potential_fine + or (state["notice_email_extract"].max_potential_fine or 0) >= state["escalation_dollar_criteria"] ): state["requires_escalation"] = True @@ -95,10 +95,10 @@ def answer_follow_up_question_node(state: GraphState) -> GraphState: answer = BINARY_QUESTION_CHAIN.invoke({"question": question}) if state.get("follow_ups"): - state["follow_ups"][state["current_follow_up"]] = answer + state["follow_ups"][state["current_follow_up"]] = answer.is_true else: - state["follow_ups"] = {state["current_follow_up"]: answer} + state["follow_ups"] = {state["current_follow_up"]: answer.is_true} return state diff --git a/python-langgraph/pyproject.toml b/python-langgraph/pyproject.toml index e7f8d5cfe5..34b1c856ea 100644 --- a/python-langgraph/pyproject.toml +++ b/python-langgraph/pyproject.toml @@ -5,7 +5,7 @@ description = "Companion code to Real Python tutorial" readme = "README.md" requires-python = ">=3.12" dependencies = [ - "langchain-openai>=0.3.2", - "langgraph>=0.2.67", - "pydantic[email]>=2.10.6", + "langchain-openai>=1.3.2", + "langgraph>=1.2.5", + "pydantic[email]>=2.13.4", ] diff --git a/python-langgraph/requirements.txt b/python-langgraph/requirements.txt index 22d4d9687f..68c171773a 100644 --- a/python-langgraph/requirements.txt +++ b/python-langgraph/requirements.txt @@ -1,5 +1,5 @@ # This file was autogenerated by uv via the following command: -# uv pip compile --output-file requirements.txt pyproject.toml +# uv pip compile pyproject.toml -o requirements.txt --python-version 3.12 annotated-types==0.7.0 # via pydantic anyio==4.8.0 @@ -34,44 +34,57 @@ idna==3.10 # email-validator # httpx # requests -jiter==0.8.2 +jiter==0.15.0 # via openai jsonpatch==1.33 # via langchain-core jsonpointer==3.0.0 # via jsonpatch -langchain-core==0.3.33 +langchain-core==1.4.7 # via # langchain-openai # langgraph # langgraph-checkpoint -langchain-openai==0.3.3 + # langgraph-prebuilt + # langgraph-sdk +langchain-openai==1.3.2 # via python-langgraph (pyproject.toml) -langgraph==0.2.69 +langchain-protocol==0.0.17 + # via + # langchain-core + # langgraph-sdk +langgraph==1.2.5 # via python-langgraph (pyproject.toml) -langgraph-checkpoint==2.0.10 +langgraph-checkpoint==4.1.1 + # via + # langgraph + # langgraph-prebuilt +langgraph-prebuilt==1.1.0 # via langgraph -langgraph-sdk==0.1.51 +langgraph-sdk==0.4.2 # via langgraph -langsmith==0.3.4 +langsmith==0.8.16 # via langchain-core -msgpack==1.1.0 - # via langgraph-checkpoint -openai==1.61.0 +openai==2.41.1 # via langchain-openai -orjson==3.10.15 +orjson==3.11.9 # via # langgraph-sdk # langsmith +ormsgpack==1.12.2 + # via langgraph-checkpoint packaging==24.2 - # via langchain-core -pydantic==2.10.6 + # via + # langchain-core + # langsmith +pydantic==2.13.4 # via # python-langgraph (pyproject.toml) # langchain-core + # langgraph # langsmith # openai -pydantic-core==2.27.2 +pydantic-core==2.46.4 # via pydantic pyyaml==6.0.2 # via langchain-core @@ -94,13 +107,30 @@ tiktoken==0.8.0 # via langchain-openai tqdm==4.67.1 # via openai -typing-extensions==4.12.2 +typing-extensions==4.15.0 # via + # anyio # langchain-core + # langchain-protocol # openai # pydantic # pydantic-core + # typing-inspection +typing-inspection==0.4.2 + # via pydantic urllib3==2.3.0 # via requests +uuid-utils==0.16.1 + # via + # langchain-core + # langsmith +websockets==15.0.1 + # via + # langgraph-sdk + # langsmith +xxhash==3.7.0 + # via + # langgraph + # langsmith zstandard==0.23.0 # via langsmith From e85bdfc1fee5a77845e1aea5b3514b02f2405003 Mon Sep 17 00:00:00 2001 From: Martin Breuss Date: Tue, 16 Jun 2026 21:04:30 +0000 Subject: [PATCH 2/2] Sync example_emails.py dates to 2026 to match the tutorial The companion emails still used 2024/2025 dates while the tutorial's examples and REPL transcripts use 2026. Update Email 0 (May 15 / June 10, 2026) and Email 3 (June 10 / August 5, 2026) so extracted dates match the tutorial output. Co-Authored-By: Claude Opus 4.8 (1M context) --- python-langgraph/example_emails.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/python-langgraph/example_emails.py b/python-langgraph/example_emails.py index d9df1dd89c..b54d5b5e12 100644 --- a/python-langgraph/example_emails.py +++ b/python-langgraph/example_emails.py @@ -1,7 +1,7 @@ EMAILS = [ # Email 1 """ - Date: October 15, 2024 + Date: May 15, 2026 From: Occupational Safety and Health Administration (OSHA) To: Blue Ridge Construction, project 111232345 - Downtown Office Complex Location: Dallas, TX @@ -21,7 +21,7 @@ Conduct an inspection of all scaffolding structures and reinforce unstable sections. Ensure all workers on-site are provided with necessary PPE and conduct safety training on proper usage. - Deadline for Compliance: All violations must be rectified by November 10, 2024. + Deadline for Compliance: All violations must be rectified by June 10, 2026. Failure to comply may result in fines of up to $25,000 per violation. Contact: For questions or to confirm compliance, please reach out to the OSHA @@ -44,7 +44,7 @@ """, # Email 4 """ - Date: January 10, 2025 + Date: June 10, 2026 From: City of Los Angeles Building and Safety Department To: West Coast Development, project 345678123 - Sunset Luxury Condominiums @@ -62,8 +62,8 @@ standards. Install additional fire extinguishers in compliance with fire code requirements. Reinforce or replace temporary support beams to ensure structural stability. Deadline for Compliance: Violations - must be addressed no later than February 5, - 2025. Failure to comply may result in + must be addressed no later than August 5, + 2026. Failure to comply may result in a stop-work order and additional fines. Contact: For questions or to schedule a re-inspection, please contact the Building and Safety Department at