astream bug #946

Closed
opened 2026-02-20 17:42:29 -05:00 by yindo · 2 comments
Owner

Originally created by @xiaohuialg on GitHub (Aug 28, 2025).

Originally assigned to: @casparb on GitHub.

Checked other resources

  • This is a bug, not a usage question. For questions, please use the LangChain Forum (https://forum.langchain.com/).
  • I added a clear and detailed title that summarizes the issue.
  • I read what a minimal reproducible example is (https://stackoverflow.com/help/minimal-reproducible-example).
  • I included a self-contained, minimal example that demonstrates the issue INCLUDING all the relevant imports. The code run AS IS to reproduce the issue.

Example Code

agent_app = build_single_react_agent_app(
            tool_names=agent_configs.tool_names,
            mcp_servers=agent_configs.mcp_servers,
            knowledge_bases=agent_configs.knowledge_bases,
            agent_prompt=agent_configs.agent_prompt,
            think_switch=user_input.think_switch,
        )
        agent_app.get_graph().print_ascii()

        stream = agent_app.astream(
            input={"messages": messages},
            stream_mode=stream_mode,
            config=graph_config
        )

        try:
            async for output in stream:
                print(output)
                events = parser.filter_stream_output(output)
                if events:
                    for event in events:
                        yield f"data: {json.dumps(event, ensure_ascii=False)}\n\n"
                if (events and len(events) > 0 and
                        events[0].get('type') == 'finish_stop'):
                    return
        finally:
            try:
                await stream.aclose()
            except:
                pass

    return StreamingResponse(
        generate_json(),
        media_type="text/event-stream",
        headers={"Cache-Control": "no-cache"}
    )


def build_single_react_agent_app(
        tool_names: List[str],
        mcp_servers: Optional[Dict[str, Dict[str, Any]]] = None,
        knowledge_bases: List[str] = None,
        agent_prompt: str = "",
        think_switch: bool = False
):
    local_tools = get_tool()
    print("local_tools ", local_tools)
    mcp_tools = load_mcp_tools(mcp_servers)
    print("mcp_tools ", mcp_tools)
    tools_map = {**local_tools, **mcp_tools}
    print("tools_map ", tools_map)
    if not tool_names:
        tools = [tool for tool in tools_map.values() if not tool.name.startswith("workflow_")]
    else:
        workflow_tools_in_names = [name for name in tool_names if name.startswith("workflow_")]
        non_workflow_tools_in_names = [name for name in tool_names if not name.startswith("workflow_")]
        if non_workflow_tools_in_names:
            tools = [tools_map[name] for name in tool_names if name in tools_map]
        else:
            non_workflow_tools = [tool for tool in tools_map.values() if not tool.name.startswith("workflow_")]
            specified_workflow_tools = [tools_map[name] for name in workflow_tools_in_names if name in tools_map]
            tools = non_workflow_tools + specified_workflow_tools

    tools = [tool for tool in tools if not tool.name.startswith("alone_")]

    if knowledge_bases:
        db_session = next(get_db())
        crud = PostgresCRUD(db_url=None, model=RagKnowledgeBase, session=db_session)
        db_results = crud.get_by_names(knowledge_bases)
        if db_results:
            kb_info = {
                kb.name: kb.description
                for kb in db_results
            }
            kb_info_str = "\n".join(f"{name}:{desc}" for name, desc in kb_info.items())
            kb_keys = ", ".join(kb_info.keys())
            prompt_template = (
                "Use local knowledgebase from one or more of these:\n"
                "{kb_info_str}\n"
                "to get information. Only local data on this knowledge uses this tool. "
                "The 'database' should be one of the above [{kb_keys}]."
            )
            description = prompt_template.format(kb_info_str=kb_info_str, kb_keys=kb_keys)
            old_context = request_context.get()
            old_context["search_remote_knowledgebase_description"] = description
            request_context.set(old_context)
            tools.append(StructuredTool.from_function(
                func=sync_wrapper_for_dynamic_search,
                name="agent_search_knowledgebase",
                description=description,
                args_schema=DynamicInputSchema,
            ))

    agent = create_react_agent(
        model=gat_openai_model(think_switch),
        tools=tools,
        prompt=agent_prompt
    )

    return agent

Error Message and Stack Trace (if applicable)


Description

After using create_react_agent method, if you continue to use the astream method, if the MCP service tool parameter is empty, the call will get stuck and stop.

System Info

chatchat-server/chatchat/cli.py start --api

Originally created by @xiaohuialg on GitHub (Aug 28, 2025). Originally assigned to: @casparb on GitHub. ### Checked other resources - [x] This is a bug, not a usage question. For questions, please use the LangChain Forum (https://forum.langchain.com/). - [x] I added a clear and detailed title that summarizes the issue. - [x] I read what a minimal reproducible example is (https://stackoverflow.com/help/minimal-reproducible-example). - [x] I included a self-contained, minimal example that demonstrates the issue INCLUDING all the relevant imports. The code run AS IS to reproduce the issue. ### Example Code ```python agent_app = build_single_react_agent_app( tool_names=agent_configs.tool_names, mcp_servers=agent_configs.mcp_servers, knowledge_bases=agent_configs.knowledge_bases, agent_prompt=agent_configs.agent_prompt, think_switch=user_input.think_switch, ) agent_app.get_graph().print_ascii() stream = agent_app.astream( input={"messages": messages}, stream_mode=stream_mode, config=graph_config ) try: async for output in stream: print(output) events = parser.filter_stream_output(output) if events: for event in events: yield f"data: {json.dumps(event, ensure_ascii=False)}\n\n" if (events and len(events) > 0 and events[0].get('type') == 'finish_stop'): return finally: try: await stream.aclose() except: pass return StreamingResponse( generate_json(), media_type="text/event-stream", headers={"Cache-Control": "no-cache"} ) def build_single_react_agent_app( tool_names: List[str], mcp_servers: Optional[Dict[str, Dict[str, Any]]] = None, knowledge_bases: List[str] = None, agent_prompt: str = "", think_switch: bool = False ): local_tools = get_tool() print("local_tools ", local_tools) mcp_tools = load_mcp_tools(mcp_servers) print("mcp_tools ", mcp_tools) tools_map = {**local_tools, **mcp_tools} print("tools_map ", tools_map) if not tool_names: tools = [tool for tool in tools_map.values() if not tool.name.startswith("workflow_")] else: workflow_tools_in_names = [name for name in tool_names if name.startswith("workflow_")] non_workflow_tools_in_names = [name for name in tool_names if not name.startswith("workflow_")] if non_workflow_tools_in_names: tools = [tools_map[name] for name in tool_names if name in tools_map] else: non_workflow_tools = [tool for tool in tools_map.values() if not tool.name.startswith("workflow_")] specified_workflow_tools = [tools_map[name] for name in workflow_tools_in_names if name in tools_map] tools = non_workflow_tools + specified_workflow_tools tools = [tool for tool in tools if not tool.name.startswith("alone_")] if knowledge_bases: db_session = next(get_db()) crud = PostgresCRUD(db_url=None, model=RagKnowledgeBase, session=db_session) db_results = crud.get_by_names(knowledge_bases) if db_results: kb_info = { kb.name: kb.description for kb in db_results } kb_info_str = "\n".join(f"{name}:{desc}" for name, desc in kb_info.items()) kb_keys = ", ".join(kb_info.keys()) prompt_template = ( "Use local knowledgebase from one or more of these:\n" "{kb_info_str}\n" "to get information. Only local data on this knowledge uses this tool. " "The 'database' should be one of the above [{kb_keys}]." ) description = prompt_template.format(kb_info_str=kb_info_str, kb_keys=kb_keys) old_context = request_context.get() old_context["search_remote_knowledgebase_description"] = description request_context.set(old_context) tools.append(StructuredTool.from_function( func=sync_wrapper_for_dynamic_search, name="agent_search_knowledgebase", description=description, args_schema=DynamicInputSchema, )) agent = create_react_agent( model=gat_openai_model(think_switch), tools=tools, prompt=agent_prompt ) return agent ``` ### Error Message and Stack Trace (if applicable) ```shell ``` ### Description After using create_react_agent method, if you continue to use the astream method, if the MCP service tool parameter is empty, the call will get stuck and stop. ### System Info chatchat-server/chatchat/cli.py start --api
yindo added the bugpending labels 2026-02-20 17:42:29 -05:00
yindo closed this issue 2026-02-20 17:42:29 -05:00
Author
Owner

@casparb commented on GitHub (Sep 12, 2025):

Hi @xiaohuialg, I am closing this issue because your code is not an MRE. An MRE is a "self-contained, minimal example that demonstrates the issue INCLUDING all the relevant imports. The code run AS IS to reproduce the issue.".

If you're still experiencing issues, please tag me in a reply that includes an MRE that I can run as-is to reproduce the error, and I would be happy to help you out. Thanks!

@casparb commented on GitHub (Sep 12, 2025): Hi @xiaohuialg, I am closing this issue because your code is not an MRE. An MRE is a _"**self-contained, minimal example** that demonstrates the issue **INCLUDING** all the relevant imports. The code run **AS IS** to reproduce the issue."_. If you're still experiencing issues, please tag me in a reply that includes an MRE that I can run as-is to reproduce the error, and I would be happy to help you out. Thanks!
Author
Owner

@xiaohuialg commented on GitHub (Sep 12, 2025):

我已经收到,谢谢您!

@xiaohuialg commented on GitHub (Sep 12, 2025): 我已经收到,谢谢您!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langchain-ai/langgraph#946