diff --git a/.github/workflows/_integration_test.yml b/.github/workflows/_integration_test.yml index 2057dceae..b55e23664 100644 --- a/.github/workflows/_integration_test.yml +++ b/.github/workflows/_integration_test.yml @@ -19,7 +19,7 @@ jobs: run: working-directory: libs/cli steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Get changed files id: changed-files uses: Ana06/get-changed-files@v2.3.0 diff --git a/.github/workflows/_lint.yml b/.github/workflows/_lint.yml index 68c9a78f3..eb64ea4ce 100644 --- a/.github/workflows/_lint.yml +++ b/.github/workflows/_lint.yml @@ -31,7 +31,7 @@ jobs: - "3.12" name: "lint #${{ matrix.python-version }}" steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Get changed files id: changed-files uses: Ana06/get-changed-files@v2.3.0 diff --git a/.github/workflows/_test.yml b/.github/workflows/_test.yml index 2dd21aa97..769fa642a 100644 --- a/.github/workflows/_test.yml +++ b/.github/workflows/_test.yml @@ -24,7 +24,7 @@ jobs: name: "test #${{ matrix.python-version }}" steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python ${{ matrix.python-version }} uses: astral-sh/setup-uv@v6 with: diff --git a/.github/workflows/_test_langgraph.yml b/.github/workflows/_test_langgraph.yml index f4f66e532..e58874b00 100644 --- a/.github/workflows/_test_langgraph.yml +++ b/.github/workflows/_test_langgraph.yml @@ -22,7 +22,7 @@ jobs: working-directory: libs/langgraph name: "test #${{ matrix.python-version }}" steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python ${{ matrix.python-version }} uses: astral-sh/setup-uv@v6 with: diff --git a/.github/workflows/_test_release.yml b/.github/workflows/_test_release.yml index a99312349..4e88d1c04 100644 --- a/.github/workflows/_test_release.yml +++ b/.github/workflows/_test_release.yml @@ -23,7 +23,7 @@ jobs: version: ${{ steps.check-version.outputs.version }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python $${ env.PYTHON_VERSION }} uses: astral-sh/setup-uv@v6 @@ -74,7 +74,7 @@ jobs: id-token: write steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: actions/download-artifact@v4 with: diff --git a/.github/workflows/baseline.yml b/.github/workflows/baseline.yml index 9b2c7cd71..27f7d179a 100644 --- a/.github/workflows/baseline.yml +++ b/.github/workflows/baseline.yml @@ -17,7 +17,7 @@ jobs: run: working-directory: libs/langgraph steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - run: SHA=$(git rev-parse HEAD) && echo "SHA=$SHA" >> $GITHUB_ENV - name: Set up Python 3.11 uses: astral-sh/setup-uv@v6 diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index f5484badb..7061e2852 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -15,7 +15,7 @@ jobs: run: working-directory: libs/langgraph steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - id: files name: Get changed files uses: Ana06/get-changed-files@v2.3.0 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8c37bac96..d84b982d9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,7 +27,7 @@ jobs: python: ${{ steps.filter.outputs.python }} deps: ${{ steps.filter.outputs.deps }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: dorny/paths-filter@v3 id: filter with: @@ -100,9 +100,9 @@ jobs: name: "Check SDK methods matching" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: "3.11" - name: Run check_sdk_methods script @@ -118,7 +118,7 @@ jobs: python-version: - "3.11" steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python ${{ matrix.python-version }} uses: astral-sh/setup-uv@v6 with: diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml index a4d9f9c41..b1be72f7e 100644 --- a/.github/workflows/codespell.yml +++ b/.github/workflows/codespell.yml @@ -21,7 +21,7 @@ steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install Dependencies run: | diff --git a/.github/workflows/deploy_docs.yml b/.github/workflows/deploy_docs.yml index 4c31784c2..6368aeeca 100644 --- a/.github/workflows/deploy_docs.yml +++ b/.github/workflows/deploy_docs.yml @@ -28,7 +28,7 @@ jobs: outputs: changed-files: ${{ steps.changed-files.outputs.added_modified }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Get changed files id: changed-files uses: Ana06/get-changed-files@v2.3.0 @@ -41,7 +41,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.MKDOCS_GITHUB_TOKEN }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: fetch-depth: 0 @@ -140,7 +140,7 @@ jobs: - name: Upload Pages Artifact # if: github.ref == 'refs/heads/main' - uses: actions/upload-pages-artifact@v3 + uses: actions/upload-pages-artifact@v4 with: path: ./docs/site/ diff --git a/.github/workflows/link_check.yml b/.github/workflows/link_check.yml index 65e041e7b..95e792b18 100644 --- a/.github/workflows/link_check.yml +++ b/.github/workflows/link_check.yml @@ -19,7 +19,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: fetch-depth: 0 @@ -36,7 +36,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: fetch-depth: 1 diff --git a/.github/workflows/pr_lint.yml b/.github/workflows/pr_lint.yml index f4bc62f51..944f51e59 100644 --- a/.github/workflows/pr_lint.yml +++ b/.github/workflows/pr_lint.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Validate PR Title - uses: amannn/action-semantic-pull-request@v5 + uses: amannn/action-semantic-pull-request@v6 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: @@ -40,6 +40,7 @@ jobs: sdk-py docs ci + deps requireScope: false ignoreLabels: | ignore-lint-pr-title diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f6d09ed63..cfa8fd2bc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,7 +25,7 @@ jobs: tag: ${{ steps.check-version.outputs.tag }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python uses: astral-sh/setup-uv@v6 @@ -86,7 +86,7 @@ jobs: outputs: release-body: ${{ steps.generate-release-body.outputs.release-body }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: repository: langchain-ai/langgraph path: langgraph @@ -157,7 +157,7 @@ jobs: - test-pypi-publish runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 # We explicitly *don't* set up caching here. This ensures our tests are # maximally sensitive to catching breakage. @@ -260,7 +260,7 @@ jobs: working-directory: ${{ inputs.working-directory }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python uses: astral-sh/setup-uv@v6 @@ -301,7 +301,7 @@ jobs: working-directory: ${{ inputs.working-directory }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python uses: astral-sh/setup-uv@v6 diff --git a/.github/workflows/run_notebooks.yml b/.github/workflows/run_notebooks.yml index 975df0191..1602eb970 100644 --- a/.github/workflows/run_notebooks.yml +++ b/.github/workflows/run_notebooks.yml @@ -28,7 +28,7 @@ jobs: - "latest" steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python + Poetry uses: astral-sh/setup-uv@v6 with: diff --git a/.github/workflows/uv_lock_ugprade.yml b/.github/workflows/uv_lock_ugprade.yml index 5d57a1f4d..72d31e94a 100644 --- a/.github/workflows/uv_lock_ugprade.yml +++ b/.github/workflows/uv_lock_ugprade.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up uv uses: astral-sh/setup-uv@v6 diff --git a/README.md b/README.md index 47cc4d052..8fe8c5f2c 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ While LangGraph can be used standalone, it also integrates seamlessly with any L ## Additional resources -- [Guides](https://langchain-ai.github.io/langgraph/how-tos/): Quick, actionable code snippets for topics such as streaming, adding memory & persistence, and design patterns (e.g. branching, subgraphs, etc.). +- [Guides](https://langchain-ai.github.io/langgraph/guides/): Quick, actionable code snippets for topics such as streaming, adding memory & persistence, and design patterns (e.g. branching, subgraphs, etc.). - [Reference](https://langchain-ai.github.io/langgraph/reference/graphs/): Detailed reference on core classes, methods, how to use the graph and checkpointing APIs, and higher-level prebuilt components. - [Examples](https://langchain-ai.github.io/langgraph/examples/): Guided examples on getting started with LangGraph. - [LangChain Forum](https://forum.langchain.com/): Connect with the community and share all of your technical questions, ideas, and feedback. diff --git a/docs/_scripts/js_translation/codeblocks/.yarn/install-state.gz b/docs/_scripts/js_translation/codeblocks/.yarn/install-state.gz new file mode 100644 index 000000000..625ab3e67 Binary files /dev/null and b/docs/_scripts/js_translation/codeblocks/.yarn/install-state.gz differ diff --git a/docs/_scripts/js_translation/codeblocks/yarn.lock b/docs/_scripts/js_translation/codeblocks/yarn.lock index 0c6068c46..2891897a8 100644 --- a/docs/_scripts/js_translation/codeblocks/yarn.lock +++ b/docs/_scripts/js_translation/codeblocks/yarn.lock @@ -2108,9 +2108,9 @@ __metadata: linkType: hard "hono@npm:^4.5.4": - version: 4.8.9 - resolution: "hono@npm:4.8.9" - checksum: 10c0/385539d1787fdc747bc869ef0e5ccc9f39cbe40289b94f23eecfc82c6ca440f059704647cd6381a5066d2cf7baa43ab25184c78d44af4c5c98a5c5b07670059e + version: 4.9.6 + resolution: "hono@npm:4.9.6" + checksum: 10c0/182a144eb3b9e05bd9e43d15af15c93f60d3d747fef6c6904b9993e9db8129ea7fadf6190331d6f76b1bf6dd2b2c3b13efea105236f541ef411397e30475422d languageName: node linkType: hard diff --git a/docs/docs/agents/context.md b/docs/docs/agents/context.md index 5aa71a608..942e7d628 100644 --- a/docs/docs/agents/context.md +++ b/docs/docs/agents/context.md @@ -90,7 +90,7 @@ graph.invoke( # (1)! from langgraph.runtime import Runtime # highlight-next-line - def node(state: State, config: Runtime[ContextSchema]): + def node(state: State, runtime: Runtime[ContextSchema]): user_name = runtime.context.user_name ... ``` diff --git a/docs/docs/concepts/memory.md b/docs/docs/concepts/memory.md index 83d3f29a0..390693965 100644 --- a/docs/docs/concepts/memory.md +++ b/docs/docs/concepts/memory.md @@ -134,7 +134,7 @@ def update_instructions(state: State, store: BaseStore): namespace = ("instructions",) current_instructions = store.search(namespace)[0] # Memory logic - prompt = prompt_template.format(instructions=instructions.value["instructions"], conversation=state["messages"]) + prompt = prompt_template.format(instructions=current_instructions.value["instructions"], conversation=state["messages"]) output = llm.invoke(prompt) new_instructions = output['new_instructions'] store.put(("agent_instructions",), "agent_a", {"instructions": new_instructions}) @@ -278,4 +278,4 @@ const items = await store.search( ``` ::: -For more information about the memory store, see the [Persistence](persistence.md#memory-store) guide. \ No newline at end of file +For more information about the memory store, see the [Persistence](persistence.md#memory-store) guide. diff --git a/docs/docs/how-tos/graph-api.md b/docs/docs/how-tos/graph-api.md index bf0af9610..9a64d5cd8 100644 --- a/docs/docs/how-tos/graph-api.md +++ b/docs/docs/how-tos/graph-api.md @@ -1205,7 +1205,7 @@ There are many use cases where you may wish for your node to have a custom retry To configure a retry policy, pass the `retry_policy` parameter to the [add_node](../reference/graphs.md#langgraph.graph.state.StateGraph.add_node). The `retry_policy` parameter takes in a `RetryPolicy` named tuple object. Below we instantiate a `RetryPolicy` object with the default parameters and associate it with a node: ```python -from langgraph.pregel import RetryPolicy +from langgraph.types import RetryPolicy builder.add_node( "node_name", @@ -1260,7 +1260,7 @@ By default, the retry policy retries on any exception except for the following: from typing_extensions import TypedDict from langchain.chat_models import init_chat_model from langgraph.graph import END, MessagesState, StateGraph, START - from langgraph.pregel import RetryPolicy + from langgraph.types import RetryPolicy from langchain_community.utilities import SQLDatabase from langchain_core.messages import AIMessage @@ -1422,15 +1422,15 @@ const builder = new StateGraph(State) ::: ??? info "Why split application steps into a sequence with LangGraph?" -LangGraph makes it easy to add an underlying persistence layer to your application. -This allows state to be checkpointed in between the execution of nodes, so your LangGraph nodes govern: + LangGraph makes it easy to add an underlying persistence layer to your application. + This allows state to be checkpointed in between the execution of nodes, so your LangGraph nodes govern: - - How state updates are [checkpointed](../concepts/persistence.md) - - How interruptions are resumed in [human-in-the-loop](../concepts/human_in_the_loop.md) workflows - - How we can "rewind" and branch-off executions using LangGraph's [time travel](../concepts/time-travel.md) features +- How state updates are [checkpointed](../concepts/persistence.md) +- How interruptions are resumed in [human-in-the-loop](../concepts/human_in_the_loop.md) workflows +- How we can "rewind" and branch-off executions using LangGraph's [time travel](../concepts/time-travel.md) features - They also determine how execution steps are [streamed](../concepts/streaming.md), and how your application is visualized - and debugged using [LangGraph Studio](../concepts/langgraph_studio.md). +They also determine how execution steps are [streamed](../concepts/streaming.md), and how your application is visualized +and debugged using [LangGraph Studio](../concepts/langgraph_studio.md). Let's demonstrate an end-to-end example. We will create a sequence of three steps: @@ -2333,7 +2333,7 @@ from IPython.display import Image, display display(Image(graph.get_graph().draw_mermaid_png())) ``` -![Simple loop graph](assets/graph_api_image_3.png) +![Simple loop graph](assets/graph_api_image_7.png) ::: :::js @@ -3272,7 +3272,7 @@ from langchain_core.runnables.graph import CurveStyle, MermaidDrawMethod, NodeSt display(Image(app.get_graph().draw_mermaid_png())) ``` -![Fractal graph visualization](assets/graph_api_image_5.png) +![Fractal graph visualization](assets/graph_api_image_10.png) **Using Mermaid + Pyppeteer** @@ -3320,4 +3320,4 @@ const imageBuffer = new Uint8Array(await image.arrayBuffer()); await fs.writeFile("graph.png", imageBuffer); ``` -::: \ No newline at end of file +::: diff --git a/docs/docs/how-tos/human_in_the_loop/add-human-in-the-loop.md b/docs/docs/how-tos/human_in_the_loop/add-human-in-the-loop.md index 6e7330f2f..49dffd465 100644 --- a/docs/docs/how-tos/human_in_the_loop/add-human-in-the-loop.md +++ b/docs/docs/how-tos/human_in_the_loop/add-human-in-the-loop.md @@ -366,8 +366,8 @@ result = graph.invoke( # Resume with mapping of interrupt IDs to values resume_map = { - i.interrupt_id: f"human input for prompt {i.value}" - for i in parent.get_state(thread_config).interrupts + i.id: f"edited text for {i.value['text_to_revise']}" + for i in graph.get_state(config).interrupts } print(graph.invoke(Command(resume=resume_map), config=config)) # > {'text_1': 'edited text for original text 1', 'text_2': 'edited text for original text 2'} diff --git a/docs/docs/tutorials/workflows.md b/docs/docs/tutorials/workflows.md index 7d46f853e..9b2f4de88 100644 --- a/docs/docs/tutorials/workflows.md +++ b/docs/docs/tutorials/workflows.md @@ -1948,7 +1948,7 @@ const llmWithTools = llm.bindTools(tools); # Conditional edge function to route to the tool node or end based upon whether the LLM made a tool call - def should_continue(state: MessagesState) -> Literal["environment", END]: + def should_continue(state: MessagesState) -> Literal["Action", END]: """Decide if we should continue the loop or stop based upon whether the LLM made a tool call""" messages = state["messages"] diff --git a/examples/rag/langgraph_crag_local.ipynb b/examples/rag/langgraph_crag_local.ipynb index 19dc84410..c454127f2 100644 --- a/examples/rag/langgraph_crag_local.ipynb +++ b/examples/rag/langgraph_crag_local.ipynb @@ -707,7 +707,9 @@ " \"\"\"\n", " Find all tool calls in the messages returned\n", " \"\"\"\n", - " tool_calls = [tc['name'] for m in messages['messages'] for tc in getattr(m, 'tool_calls', [])]\n", + " tool_calls = [\n", + " tc[\"name\"] for m in messages[\"messages\"] for tc in getattr(m, \"tool_calls\", [])\n", + " ]\n", " return tool_calls\n", "\n", "\n", diff --git a/libs/cli/examples/graphs/agent.py b/libs/cli/examples/graphs/agent.py index f39df4cae..931982061 100644 --- a/libs/cli/examples/graphs/agent.py +++ b/libs/cli/examples/graphs/agent.py @@ -7,6 +7,7 @@ from langchain_core.messages import BaseMessage from langchain_openai import ChatOpenAI from langgraph.graph import END, StateGraph, add_messages from langgraph.prebuilt import ToolNode +from langgraph.runtime import Runtime tools = [TavilySearchResults(max_results=1)] @@ -17,6 +18,10 @@ model_anth = model_anth.bind_tools(tools) model_oai = model_oai.bind_tools(tools) +class AgentContext(TypedDict): + model: Literal["anthropic", "openai"] + + class AgentState(TypedDict): messages: Annotated[Sequence[BaseMessage], add_messages] @@ -34,8 +39,8 @@ def should_continue(state): # Define the function that calls the model -def call_model(state, config): - if config["configurable"].get("model", "anthropic") == "anthropic": +def call_model(state, runtime: Runtime[AgentContext]): + if runtime.context.get("model", "anthropic") == "anthropic": model = model_anth else: model = model_oai @@ -49,12 +54,8 @@ def call_model(state, config): tool_node = ToolNode(tools) -class ContextSchema(TypedDict): - model: Literal["anthropic", "openai"] - - # Define a new graph -workflow = StateGraph(AgentState, context_schema=ContextSchema) +workflow = StateGraph(AgentState, context_schema=AgentContext) # Define the two nodes we will cycle between workflow.add_node("agent", call_model) diff --git a/libs/cli/examples/graphs_reqs_a/graphs_submod/agent.py b/libs/cli/examples/graphs_reqs_a/graphs_submod/agent.py index 1073110cb..7971b3ce0 100644 --- a/libs/cli/examples/graphs_reqs_a/graphs_submod/agent.py +++ b/libs/cli/examples/graphs_reqs_a/graphs_submod/agent.py @@ -1,6 +1,6 @@ from collections.abc import Sequence from pathlib import Path -from typing import Annotated, TypedDict +from typing import Annotated, Literal, TypedDict from langchain_anthropic import ChatAnthropic from langchain_community.tools.tavily_search import TavilySearchResults @@ -8,6 +8,7 @@ from langchain_core.messages import BaseMessage from langchain_openai import ChatOpenAI from langgraph.graph import END, StateGraph, add_messages from langgraph.prebuilt import ToolNode +from langgraph.runtime import Runtime tools = [TavilySearchResults(max_results=1)] @@ -21,6 +22,10 @@ prompt = open(Path(__file__).parent.parent / "prompt.txt").read() subprompt = open(Path(__file__).parent / "subprompt.txt").read() +class AgentContext(TypedDict): + model: Literal["anthropic", "openai"] + + class AgentState(TypedDict): messages: Annotated[Sequence[BaseMessage], add_messages] @@ -38,8 +43,8 @@ def should_continue(state): # Define the function that calls the model -def call_model(state, config): - if config["configurable"].get("model", "anthropic") == "anthropic": +def call_model(state, runtime: Runtime[AgentContext]): + if runtime.context.get("model", "anthropic") == "anthropic": model = model_anth else: model = model_oai @@ -52,9 +57,8 @@ def call_model(state, config): # Define the function to execute tools tool_node = ToolNode(tools) - # Define a new graph -workflow = StateGraph(AgentState) +workflow = StateGraph(AgentState, context_schema=AgentContext) # Define the two nodes we will cycle between workflow.add_node("agent", call_model) diff --git a/libs/cli/examples/graphs_reqs_b/graphs_submod/agent.py b/libs/cli/examples/graphs_reqs_b/graphs_submod/agent.py index 1073110cb..eb81a0a7f 100644 --- a/libs/cli/examples/graphs_reqs_b/graphs_submod/agent.py +++ b/libs/cli/examples/graphs_reqs_b/graphs_submod/agent.py @@ -1,6 +1,6 @@ from collections.abc import Sequence from pathlib import Path -from typing import Annotated, TypedDict +from typing import Annotated, Literal, TypedDict from langchain_anthropic import ChatAnthropic from langchain_community.tools.tavily_search import TavilySearchResults @@ -8,6 +8,7 @@ from langchain_core.messages import BaseMessage from langchain_openai import ChatOpenAI from langgraph.graph import END, StateGraph, add_messages from langgraph.prebuilt import ToolNode +from langgraph.runtime import Runtime tools = [TavilySearchResults(max_results=1)] @@ -21,6 +22,10 @@ prompt = open(Path(__file__).parent.parent / "prompt.txt").read() subprompt = open(Path(__file__).parent / "subprompt.txt").read() +class AgentContext(TypedDict): + model: Literal["anthropic", "openai"] + + class AgentState(TypedDict): messages: Annotated[Sequence[BaseMessage], add_messages] @@ -38,8 +43,8 @@ def should_continue(state): # Define the function that calls the model -def call_model(state, config): - if config["configurable"].get("model", "anthropic") == "anthropic": +def call_model(state, runtime: Runtime[AgentContext]): + if runtime.context.get("model", "anthropic") == "anthropic": model = model_anth else: model = model_oai @@ -54,7 +59,7 @@ tool_node = ToolNode(tools) # Define a new graph -workflow = StateGraph(AgentState) +workflow = StateGraph(AgentState, context_schema=AgentContext) # Define the two nodes we will cycle between workflow.add_node("agent", call_model) diff --git a/libs/langgraph/README.md b/libs/langgraph/README.md index 47cc4d052..8fe8c5f2c 100644 --- a/libs/langgraph/README.md +++ b/libs/langgraph/README.md @@ -71,7 +71,7 @@ While LangGraph can be used standalone, it also integrates seamlessly with any L ## Additional resources -- [Guides](https://langchain-ai.github.io/langgraph/how-tos/): Quick, actionable code snippets for topics such as streaming, adding memory & persistence, and design patterns (e.g. branching, subgraphs, etc.). +- [Guides](https://langchain-ai.github.io/langgraph/guides/): Quick, actionable code snippets for topics such as streaming, adding memory & persistence, and design patterns (e.g. branching, subgraphs, etc.). - [Reference](https://langchain-ai.github.io/langgraph/reference/graphs/): Detailed reference on core classes, methods, how to use the graph and checkpointing APIs, and higher-level prebuilt components. - [Examples](https://langchain-ai.github.io/langgraph/examples/): Guided examples on getting started with LangGraph. - [LangChain Forum](https://forum.langchain.com/): Connect with the community and share all of your technical questions, ideas, and feedback. diff --git a/libs/langgraph/langgraph/graph/state.py b/libs/langgraph/langgraph/graph/state.py index 3512b3fa5..2f7d3f75b 100644 --- a/libs/langgraph/langgraph/graph/state.py +++ b/libs/langgraph/langgraph/graph/state.py @@ -155,7 +155,7 @@ class StateGraph(Generic[StateT, ContextT, InputT, OutputT]): graph = StateGraph(state_schema=State, context_schema=Context) def node(state: State, runtime: Runtime[Context]) -> dict: - r = runtie.context.get("r", 1.0) + r = runtime.context.get("r", 1.0) x = state["x"][-1] next_value = x * r * (1 - x) return {"x": next_value}