From 38f52bcf26334e19b8d1287d6b4f931c17cb43b7 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Wed, 30 Jul 2025 15:26:41 -0400 Subject: [PATCH] x --- .../langchain/_internal/__init__.py | 0 .../langchain_v1/langchain/_internal/utils.py | 8 ++ .../langchain/chains/summarization.py | 82 +++++++++++++++++++ libs/langchain_v1/pyproject.toml | 2 +- libs/langchain_v1/uv.lock | 22 ++--- 5 files changed, 102 insertions(+), 12 deletions(-) create mode 100644 libs/langchain_v1/langchain/_internal/__init__.py create mode 100644 libs/langchain_v1/langchain/_internal/utils.py create mode 100644 libs/langchain_v1/langchain/chains/summarization.py diff --git a/libs/langchain_v1/langchain/_internal/__init__.py b/libs/langchain_v1/langchain/_internal/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/libs/langchain_v1/langchain/_internal/utils.py b/libs/langchain_v1/langchain/_internal/utils.py new file mode 100644 index 00000000000..dac7d799546 --- /dev/null +++ b/libs/langchain_v1/langchain/_internal/utils.py @@ -0,0 +1,8 @@ +# Re-exporting internal utilities from LangGraph for internal use in LangChain. +# TODO: We need to revisit the solution. Perhaps we expose a simple wrapper in langgraph +# create_node(sync, async) that will return a new node or something like that +from langgraph._internal._runnable import RunnableCallable as RunnableCallable + +__all__ = [ + "RunnableCallable", +] diff --git a/libs/langchain_v1/langchain/chains/summarization.py b/libs/langchain_v1/langchain/chains/summarization.py new file mode 100644 index 00000000000..4d0c2022d3b --- /dev/null +++ b/libs/langchain_v1/langchain/chains/summarization.py @@ -0,0 +1,82 @@ +"""Inline Summarization Chain""" + +from typing import NotRequired, cast +from typing import TypedDict + +from langgraph.graph import StateGraph, END +from langgraph.pregel import Pregel + +from langchain_core.documents import Document +from langchain_core.language_models.chat_models import BaseChatModel +from langchain_core.messages import MessageLikeRepresentation, AIMessage + + +class InlineSummarizationState(TypedDict): + """State for inline summarization.""" + + documents: list[Document] + summary: NotRequired[str] + + +class InlineSummarizer: + def __init__(self, model: BaseChatModel, prompt: str | None) -> None: + """Initialize the InlineSummarizer with a chat model.""" + self.model = model + self.prompt = prompt + + def _get_prompt( + self, state: InlineSummarizationState + ) -> list[MessageLikeRepresentation]: + """Generates the prompt for inline summarization.""" + if self.prompt is None: + default_system = [ + { + "role": "system", + "content": ( + "You are a helpful assistant that summarizes text. " + "Please provide a concise summary of the documents " + "provided by the user." + ), + } + ] + elif isinstance(self.prompt, str): + default_system = [{"role": "system", "content": self.prompt}] + else: + msg = f"Invalid prompt type: {type(self.prompt)}. Expected str or None." + raise TypeError(msg) + + inlined_docs = "---\n\n".join(doc.page_content for doc in state["documents"]) + return [ + default_system, + { + "role": "user", + "content": inlined_docs, + }, + ] + + def _summarize_node(self, state: InlineSummarizationState) -> TypedDict( + "Update", {"summary": str} + ): + """Builds a LangGraph for inline summarization.""" + prompt = self._get_prompt(state) + response = cast(AIMessage, self.model.invoke(prompt)) + return {"summary": response.text()} + + async def _asummarize_node(self, state: InlineSummarizationState) -> TypedDict( + "Update", {"summary": str} + ): + """Asynchronous version of the summarize node.""" + prompt = self._get_prompt(state) + response = cast(AIMessage, await self.model.ainvoke(prompt)) + return {"summary": response.text()} + + def build(self) -> Pregel: + """Builds the LangGraph for inline summarization.""" + builder = StateGraph(InlineSummarizationState) + builder.add_node("summarize_inline", self._summarize_node) + builder.set_entry_point("summarize_inline") + builder.add_edge("summarize_inline", END) + return builder + + +__all__ = ["InlineSummarizer"] diff --git a/libs/langchain_v1/pyproject.toml b/libs/langchain_v1/pyproject.toml index 3b46da5696d..4626139e978 100644 --- a/libs/langchain_v1/pyproject.toml +++ b/libs/langchain_v1/pyproject.toml @@ -9,7 +9,7 @@ requires-python = ">=3.9, <4.0" dependencies = [ "langchain-core<1.0.0,>=0.3.66", "langchain-text-splitters<1.0.0,>=0.3.8", - "langgraph>=0.5.4", + "langgraph>=0.6.0", "pydantic>=2.7.4", ] diff --git a/libs/langchain_v1/uv.lock b/libs/langchain_v1/uv.lock index 2e2899efa4e..667913a585e 100644 --- a/libs/langchain_v1/uv.lock +++ b/libs/langchain_v1/uv.lock @@ -1667,7 +1667,7 @@ requires-dist = [ { name = "langchain-text-splitters", editable = "../text-splitters" }, { name = "langchain-together", marker = "extra == 'together'" }, { name = "langchain-xai", marker = "extra == 'xai'" }, - { name = "langgraph", specifier = ">=0.5.4" }, + { name = "langgraph", specifier = ">=0.6.0" }, { name = "pydantic", specifier = ">=2.7.4" }, ] provides-extras = ["anthropic", "openai", "azure-ai", "google-vertexai", "google-genai", "fireworks", "ollama", "together", "mistralai", "huggingface", "groq", "aws", "deepseek", "xai", "perplexity"] @@ -1757,7 +1757,7 @@ wheels = [ [[package]] name = "langchain-core" -version = "0.3.70" +version = "0.3.72" source = { editable = "../core" } dependencies = [ { name = "jsonpatch" }, @@ -2133,7 +2133,7 @@ wheels = [ [[package]] name = "langgraph" -version = "0.5.4" +version = "0.6.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "langchain-core" }, @@ -2143,9 +2143,9 @@ dependencies = [ { name = "pydantic" }, { name = "xxhash" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/99/26/f01ae40ea26f8c723b6ec186869c80cc04de801630d99943018428b46105/langgraph-0.5.4.tar.gz", hash = "sha256:ab8f6b7b9c50fd2ae35a2efb072fbbfe79500dfc18071ac4ba6f5de5fa181931", size = 443149, upload-time = "2025-07-21T18:20:55.63Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6e/12/4a30f766de571bfc319e70c2c0f4d050c0576e15c2249dc75ad122706a5d/langgraph-0.6.1.tar.gz", hash = "sha256:e4399ac5ad0b70f58fa28d6fe05a41b84c15959f270d6d1a86edab4e92ae148b", size = 449723, upload-time = "2025-07-29T20:45:28.438Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0d/82/15184e953234877107bad182b79c9111cb6ce6a79a97fdf36ebcaa11c0d0/langgraph-0.5.4-py3-none-any.whl", hash = "sha256:7122840225623e081be24ac30a691a24e5dac4c0361f593208f912838192d7f6", size = 143942, upload-time = "2025-07-21T18:20:54.442Z" }, + { url = "https://files.pythonhosted.org/packages/6e/90/e37e2bc19bee81f859bfd61526d977f54ec5d8e036fa091f2cfe4f19560b/langgraph-0.6.1-py3-none-any.whl", hash = "sha256:2736027faeb6cd5c0f1ab51a5345594cfcb5eb5beeb5ac1799a58fcecf4b4eae", size = 151874, upload-time = "2025-07-29T20:45:26.998Z" }, ] [[package]] @@ -2163,28 +2163,28 @@ wheels = [ [[package]] name = "langgraph-prebuilt" -version = "0.5.2" +version = "0.6.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "langchain-core" }, { name = "langgraph-checkpoint" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/bb/11/98134c47832fbde0caf0e06f1a104577da9215c358d7854093c1d835b272/langgraph_prebuilt-0.5.2.tar.gz", hash = "sha256:2c900a5be0d6a93ea2521e0d931697cad2b646f1fcda7aa5c39d8d7539772465", size = 117808, upload-time = "2025-06-30T19:52:48.307Z" } +sdist = { url = "https://files.pythonhosted.org/packages/55/b6/d4f8e800bdfdd75486595203d5c622bba5f1098e4fd4220452c75568f2be/langgraph_prebuilt-0.6.1.tar.gz", hash = "sha256:574c409113e02d3c58157877c5ea638faa80647b259027647ab88830d7ecef00", size = 125057, upload-time = "2025-07-29T20:44:48.634Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c3/64/6bc45ab9e0e1112698ebff579fe21f5606ea65cd08266995a357e312a4d2/langgraph_prebuilt-0.5.2-py3-none-any.whl", hash = "sha256:1f4cd55deca49dffc3e5127eec12fcd244fc381321002f728afa88642d5ec59d", size = 23776, upload-time = "2025-06-30T19:52:47.494Z" }, + { url = "https://files.pythonhosted.org/packages/a6/df/cb4d73e99719b7ca0d42503d39dec49c67225779c6a1e689954a5604dbe6/langgraph_prebuilt-0.6.1-py3-none-any.whl", hash = "sha256:a3a970451371ec66509c6969505286a5d92132af7062d0b2b6dab08c2e27b50f", size = 28866, upload-time = "2025-07-29T20:44:47.72Z" }, ] [[package]] name = "langgraph-sdk" -version = "0.1.74" +version = "0.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "httpx" }, { name = "orjson" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6d/f7/3807b72988f7eef5e0eb41e7e695eca50f3ed31f7cab5602db3b651c85ff/langgraph_sdk-0.1.74.tar.gz", hash = "sha256:7450e0db5b226cc2e5328ca22c5968725873630ef47c4206a30707cb25dc3ad6", size = 72190, upload-time = "2025-07-21T16:36:50.032Z" } +sdist = { url = "https://files.pythonhosted.org/packages/2a/3e/3dc45dc7682c9940db9edaf8773d2e157397c5bd6881f6806808afd8731e/langgraph_sdk-0.2.0.tar.gz", hash = "sha256:cd8b5f6595e5571be5cbffd04cf936978ab8f5d1005517c99715947ef871e246", size = 72510, upload-time = "2025-07-22T17:31:06.745Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1f/1a/3eacc4df8127781ee4b0b1e5cad7dbaf12510f58c42cbcb9d1e2dba2a164/langgraph_sdk-0.1.74-py3-none-any.whl", hash = "sha256:3a265c3757fe0048adad4391d10486db63ef7aa5a2cbd22da22d4503554cb890", size = 50254, upload-time = "2025-07-21T16:36:49.134Z" }, + { url = "https://files.pythonhosted.org/packages/a5/03/a8ab0e8ea74be6058cb48bb1d85485b5c65d6ea183e3ee1aa8ca1ac73b3e/langgraph_sdk-0.2.0-py3-none-any.whl", hash = "sha256:150722264f225c4d47bbe7394676be102fdbf04c4400a0dd1bd41a70c6430cc7", size = 50569, upload-time = "2025-07-22T17:31:04.582Z" }, ] [[package]]