langchain-ai/langchain

AddableUpdatesDict does not support right-side addition

Opened this issue · 4 comments

Checked other resources

  • This is a bug, not a usage question.
  • I added a clear and descriptive title that summarizes this issue.
  • I used the GitHub search to find a similar question and didn't find it.
  • I am sure that this is a bug in LangChain rather than my code.
  • The bug is not resolved by updating to the latest stable version of LangChain (or the specific integration package).
  • This is not related to the langchain-community package.
  • I read what a minimal reproducible example is (https://stackoverflow.com/help/minimal-reproducible-example).
  • I posted a self-contained, minimal, reproducible example. A maintainer can copy it and run it AS IS.

Example Code

from dotenv import load_dotenv
from mcp import ClientSession, StdioServerParameters, types
from mcp.client.stdio import stdio_client
from langchain_core.messages import HumanMessage, AIMessage, SystemMessage
from langchain.agents import AgentExecutor
from langchain.memory import ConversationSummaryMemory
from langchain_mcp_adapters.tools import load_mcp_tools
from langchain_mcp_adapters.client import MultiServerMCPClient
from langgraph.prebuilt import create_react_agent
from contextlib import AsyncExitStack
import json
import asyncio
from module.llm.gpt_oss_20B import GPT_OSS_20B
import os
from typing import List

load_dotenv()

from pydantic import BaseModel, Field


class Onpremise_RAG_Agent:
    def __init__(self):
        self.exit_stack = AsyncExitStack()
        self.llm = GPT_OSS_20B(
            model_path = os.getenv("llm_model_path"),
            host="localhost",
            port=os.getenv("llm_port"),
            gpu_devices=[int(x) for x in os.getenv("llm_gpu_devices","").split(",") if x != ''],
        )
        # Tools list
        self.available_tools = []
        # Prompts list
        self.available_prompts = []
        # Sessions dict maps tool/prompt names or resource URIs to MCP client sessions
        self.messages = [] # 세션별 메시지
        self.agent = None
        self.prompt = (
            "당신은 유용한 어시스턴트입니다. 다음의 규칙을 엄격하게 준수하여 답변하세요:\n"
            "- 검색된 문서에 있는 정보만 사용하여 답변하세요. 문서에 없는 내용은 추측하지 마세요.\n"
            "- 답변의 끝에는 반드시 사용한 문서의 출처(파일 이름, 페이지 번호 또는 행 번호)를 명확히 명시하세요.\n"
            "- 답변은 명확하고 간결하게 작성하세요."
            "- 생성된 답변이 사용자의 질문에 적절한 답이 되는지 논리적으로 생각하세요."
        )
        self.memory = ConversationSummaryMemory(
            llm = self.llm,
            memory_key="chat_history",
            )

    async def connect_to_mcp_servers(self):
        try:
            with open("server_config.json", "r") as file:
                data = json.load(file)
            
            client = MultiServerMCPClient(data)
            self.available_tools.extend(await client.get_tools())
            
            self.agent = create_react_agent(
                self.llm, 
                tools = self.available_tools, 
                prompt=self.prompt,
                )
                #,response_format=AgentAnswerFormat)
            self.agent_ex = AgentExecutor(
                agent= self.agent, 
                tools= self.available_tools, 
                memory = self.memory
                )
        except Exception as e:
            print(f"Error loading server config: {e}")
            raise

    async def process_query(self, query):
        self.messages.append(HumanMessage(content=query))

        while True:
            # response = await self.agent.ainvoke(input={"messages" : self.messages})
            response = await self.agent_ex.ainvoke(input={"messages" : self.messages})

            # 메시지의 마지막 AIMessage를 찾아 출력
            for message in reversed(response["messages"]):
                if isinstance(message, AIMessage):
                    # Handle AIMessage content
                    if isinstance(message.content, str) and message.content.strip():
                        print(f"Assistant: {message.content}")
                        self.messages.append(message)
                        self.messages = await self._summarize_messages()
                        return

    # API 환경에 맞게 수정된 메서드
    async def invoke_agent(self, query: str, chat_history: List = None) -> dict:
        """단일 질문에 대해 에이전트를 실행하고 구조화된 답변을 반환합니다."""
        if chat_history is None:
            chat_history = []
        
        messages = chat_history + [HumanMessage(content=query)]
        
        response = await self.agent.ainvoke(input={"messages": messages})

        if response:
            return response
        else:
            # 에러 또는 예상치 못한 응답 형식 처리
            return {"answer": "에이전트가 답변을 생성하지 못했습니다."}


    async def _summarize_messages(self):
        """대화 기록을 요약합니다."""
        # 이전 메시지들을 HumanMessage와 AIMessage로 결합

        conversation_history = ""
        for msg in self.messages:
            if isinstance(msg, HumanMessage):
                conversation_history += f"user: {msg.content}\n"
            elif isinstance(msg, AIMessage):
                conversation_history += f"assistant: {msg.content}\n"
            elif isinstance(msg, SystemMessage):
                conversation_history += f"history : {msg.content}\n"
            
        summary_prompt = (
            f"다음 대화 내용을 1000자 이내로 요약하여 중요한 정보와 맥락을 유지해 주세요.\n\n"
            f"대화:\n{conversation_history}\n\n"
            f"요약:"
        )
        try:
            summary = await self.llm.ainvoke(input=[HumanMessage(content=summary_prompt)])
            messages = [SystemMessage(content=summary.content)]
        except Exception as e:
            # 요약 실패 시 메시지 리스트를 초기화하여 토큰 초과 오류 방지
            messages = []

        return messages


    async def chat_loop(self):
        print("\nMCP Chatbot Started!")
        print("Type your queries or 'quit' to exit.")
        
        while True:
            try:
                query = input("\nQuery: ").strip()
                if not query:
                    continue
        
                if query.lower() == 'quit':
                    break
                
                await self.process_query(query)
                    
            except Exception as e:
                print(f"\nError: {str(e)}")

    async def cleanup(self):
        await self.exit_stack.aclose()
    

async def main():
    chatbot = Onpremise_RAG_Agent()
    try:
        await chatbot.connect_to_mcp_servers()
        await chatbot.chat_loop()
    finally:
        await chatbot.cleanup()


if __name__ == "__main__":
    asyncio.run(main())

Error Message and Stack Trace (if applicable)

Traceback (most recent call last):
  File "/mnt/data1/anaconda3/envs/lit_gpt/lib/python3.12/site-packages/langchain/chains/base.py", line 209, in ainvoke
    await self._acall(inputs, run_manager=run_manager)
  File "/mnt/data1/anaconda3/envs/lit_gpt/lib/python3.12/site-packages/langchain/agents/agent.py", line 1669, in _acall
    next_step_output = await self._atake_next_step(
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/mnt/data1/anaconda3/envs/lit_gpt/lib/python3.12/site-packages/langchain/agents/agent.py", line 1463, in _atake_next_step
    [
  File "/mnt/data1/anaconda3/envs/lit_gpt/lib/python3.12/site-packages/langchain/agents/agent.py", line 1491, in _aiter_next_step
    output = await self._action_agent.aplan(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/mnt/data1/anaconda3/envs/lit_gpt/lib/python3.12/site-packages/langchain/agents/agent.py", line 506, in aplan
    final_output += chunk
  File "/mnt/data1/anaconda3/envs/lit_gpt/lib/python3.12/site-packages/langgraph/pregel/io.py", line 133, in __radd__
    raise TypeError("AddableUpdatesDict does not support right-side addition")
TypeError: AddableUpdatesDict does not support right-side addition

Description

I'm trying to use AgentExecutor.

but something is wrong.. It's ok when i use create_react_agent instance

System Info

System Information

OS: Linux
OS Version: #15~24.04.1-Ubuntu SMP Fri Jul 25 23:26:08 UTC 2025
Python Version: 3.12.9 | packaged by Anaconda, Inc. | (main, Feb 6 2025, 18:56:27) [GCC 11.2.0]

Package Information

langchain_core: 0.3.70
langchain: 0.3.26
langchain_community: 0.3.27
langsmith: 0.3.45
langchain_chroma: 0.2.4
langchain_cohere: 0.3.5
langchain_docling: 1.0.0
langchain_experimental: 0.3.4
langchain_google_genai: 2.1.7
langchain_groq: 0.3.4
langchain_huggingface: 0.3.1
langchain_mcp_adapters: 0.1.9
langchain_ollama: 0.3.6
langchain_openai: 0.2.14
langchain_pymupdf4llm: 0.4.1
langchain_text_splitters: 0.3.8
langchain_unstructured: 0.1.2
langgraph_sdk: 0.1.70

Optional packages not installed

langserve

Other Dependencies

aiohttp<4.0.0,>=3.8.3: Installed. No version info available.
async-timeout<5.0.0,>=4.0.0;: Installed. No version info available.
chromadb>=1.0.9: Installed. No version info available.
cohere: 5.16.1
dataclasses-json<0.7,>=0.5.7: Installed. No version info available.
docling~=2.18: Installed. No version info available.
filetype: 1.2.0
google-ai-generativelanguage: 0.6.18
groq<1,>=0.28.0: Installed. No version info available.
httpx: 0.28.1
httpx-sse<1.0.0,>=0.4.0: Installed. No version info available.
httpx>=0.25.2: Installed. No version info available.
huggingface-hub>=0.33.4: Installed. No version info available.
jsonpatch<2.0,>=1.33: Installed. No version info available.
langchain-anthropic;: Installed. No version info available.
langchain-aws;: Installed. No version info available.
langchain-azure-ai;: Installed. No version info available.
langchain-cohere;: Installed. No version info available.
langchain-community;: Installed. No version info available.
langchain-core<0.4,>=0.3.36: Installed. No version info available.
langchain-core<1.0.0,>=0.3.51: Installed. No version info available.
langchain-core<1.0.0,>=0.3.66: Installed. No version info available.
langchain-core<1.0.0,>=0.3.70: Installed. No version info available.
langchain-core>=0.3.60: Installed. No version info available.
langchain-core~=0.3.19: Installed. No version info available.
langchain-deepseek;: Installed. No version info available.
langchain-fireworks;: Installed. No version info available.
langchain-google-genai;: Installed. No version info available.
langchain-google-vertexai;: Installed. No version info available.
langchain-groq;: Installed. No version info available.
langchain-huggingface;: Installed. No version info available.
langchain-mistralai;: Installed. No version info available.
langchain-ollama;: Installed. No version info available.
langchain-openai;: Installed. No version info available.
langchain-perplexity;: Installed. No version info available.
langchain-text-splitters<1.0.0,>=0.3.8: Installed. No version info available.
langchain-together;: Installed. No version info available.
langchain-xai;: Installed. No version info available.
langchain<1.0.0,>=0.3.26: Installed. No version info available.
langsmith-pyo3: Installed. No version info available.
langsmith>=0.1.125: Installed. No version info available.
langsmith>=0.1.17: Installed. No version info available.
langsmith>=0.3.45: Installed. No version info available.
mcp>=1.9.2: Installed. No version info available.
numpy>=1.26.0;: Installed. No version info available.
numpy>=1.26.2;: Installed. No version info available.
numpy>=2.1.0;: Installed. No version info available.
ollama<1.0.0,>=0.5.1: Installed. No version info available.
openai: 1.90.0
openai-agents: Installed. No version info available.
opentelemetry-api: 1.36.0
opentelemetry-exporter-otlp-proto-http: 1.36.0
opentelemetry-sdk: 1.36.0
orjson: 3.10.18
orjson>=3.10.1: Installed. No version info available.
packaging: 24.2
packaging>=23.2: Installed. No version info available.
pandas: 2.2.3
pydantic: 2.11.7
pydantic-settings<3.0.0,>=2.4.0: Installed. No version info available.
pydantic<3.0.0,>=2.7.4: Installed. No version info available.
pydantic>=2.7.4: Installed. No version info available.
pymupdf4llm: 0.0.24
pytest: 8.3.5
PyYAML>=5.3: Installed. No version info available.
requests: 2.32.3
requests-toolbelt: 1.0.0
requests<3,>=2: Installed. No version info available.
rich: 13.9.4
sentence-transformers>=2.6.0;: Installed. No version info available.
SQLAlchemy<3,>=1.4: Installed. No version info available.
tabulate: 0.9.0
tenacity!=8.4.0,<10,>=8.1.0: Installed. No version info available.
tenacity!=8.4.0,<10.0.0,>=8.1.0: Installed. No version info available.
tiktoken: 0.9.0
tokenizers>=0.19.1: Installed. No version info available.
transformers>=4.39.0;: Installed. No version info available.
typing-extensions>=4.14.0: Installed. No version info available.
typing-extensions>=4.7: Installed. No version info available.
unstructured-client: 0.24.1
unstructured[all-docs]: Installed. No version info available.
zstandard: 0.23.0

i found the type of final_output is 'langgraph.pregel.io.AddableUpdatesDict'

Hi @HERIUN , I tried to solve the bug , can you please mention the langgraph version you are using, I couldnt track AddableUpdatesDict from the present langgraph repo

The issue is probably an inconsistency with add and radd attributes of AddableDict method and any method AddableUpdatesDict

The AddableDict supports both add and radd. So if we can locate the file with AddableUpdatesDict we can resolve the bug

I would solve this issue if you confirm the bug with latest langgraph version

@aroun-coumar sorry for late.. I used 0.6.7 but failed..

langgraph                                0.6.7
langgraph-checkpoint                     2.1.0
langgraph-checkpoint-redis               0.1.1
langgraph-prebuilt                       0.6.4
langgraph-sdk                            0.2.9

@HERIUN The code seems to be refactored because AddableUpdatesDict isnt present in the traceback given. Please reinstall all dependencies and check it once