Describe the bug
使用 graph.astream_events(version="v2") 时,通过 Send() 启动的并行节点产生的 on_chain_stream 事件中,data.chunk 同时存在两种格式:元组格式 ("updates", {"node_name": data}) 和裸 dict 格式 {"field": data}。execute_run 中有两条独立的处理路径分别处理这两种格式,各自调用 apublish_updates_event(),导致同一个节点的输出在 SSE 流中出现两次 event: updates。
涉及代码位置
services/run_executor.py — execute_run() 函数中的 on_chain_stream 处理:
- 元组路径:处理
("updates", {"node_name": data})
- 裸 dict 兜底路径:处理
{"field": data} ← 重复源
Environment
agentseek-api version: 0.1.0
python: 3.12
langgraph: 1.2.1
Fast reproduce steps
- 部署一个包含 Send() 并行节点的 LangGraph 应用,某节点返回结构化输出
- 调用
/threads/{id}/runs/stream,stream_mode=["updates", "messages"]
- 观察 SSE 响应中的
event: updates 行
Expected behavior
每个 Send() 节点的输出在 SSE 流中只出现一次 event: updates,格式与 langgraph-api 一致:{"node_name": {"field": data}}。
Actual behavior
同一个节点的输出出现两次 event: updates:
event: updates
data: {"templates": {"templates": []}} ← 字段级(裸 dict 路径)
event: updates
data: {"extract_templates": {"templates": {...}}} ← 节点级(元组路径,重复)
Additional context
根因: astream_events(version="v2") 对同一个 Send() 节点输出同时触发了内部 astream() 回调(产生 ("updates", data) 元组)和节点输出回调(产生裸 dict)。代码没有过滤重复。
修复建议(二选一):
方案 A——切换为 graph.astream(),与 langgraph-api 对 /threads/{id}/runs/stream 端点的处理一致:
# Before
async for stream_event in graph.astream_events(invocation, config, version="v2"):
...
# After
async with aclosing(graph.astream(invocation, config)) as stream:
while True:
mode, chunk = await anext(stream, sentinel)
...
方案 B——保留 astream_events,删除裸 dict 兜底路径,仅保留元组路径(我未成功)。
Describe the bug
使用
graph.astream_events(version="v2")时,通过Send()启动的并行节点产生的on_chain_stream事件中,data.chunk同时存在两种格式:元组格式("updates", {"node_name": data})和裸 dict 格式{"field": data}。execute_run中有两条独立的处理路径分别处理这两种格式,各自调用apublish_updates_event(),导致同一个节点的输出在 SSE 流中出现两次event: updates。涉及代码位置
services/run_executor.py—execute_run()函数中的on_chain_stream处理:("updates", {"node_name": data}){"field": data}← 重复源Environment
agentseek-api version: 0.1.0
python: 3.12
langgraph: 1.2.1
Fast reproduce steps
/threads/{id}/runs/stream,stream_mode=["updates", "messages"]event: updates行Expected behavior
每个 Send() 节点的输出在 SSE 流中只出现一次
event: updates,格式与 langgraph-api 一致:{"node_name": {"field": data}}。Actual behavior
同一个节点的输出出现两次
event: updates:Additional context
根因:
astream_events(version="v2")对同一个 Send() 节点输出同时触发了内部astream()回调(产生("updates", data)元组)和节点输出回调(产生裸 dict)。代码没有过滤重复。修复建议(二选一):
方案 A——切换为
graph.astream(),与 langgraph-api 对/threads/{id}/runs/stream端点的处理一致:方案 B——保留
astream_events,删除裸 dict 兜底路径,仅保留元组路径(我未成功)。