mirror of
https://github.com/hwchase17/langchain.git
synced 2026-02-21 06:33:41 +00:00
fix(core): fix merge_lists incorrectly merging parallel tool calls (#35281)
This commit is contained in:
@@ -117,7 +117,15 @@ def merge_lists(left: list | None, *others: list | None) -> list | None:
|
||||
to_merge = [
|
||||
i
|
||||
for i, e_left in enumerate(merged)
|
||||
if "index" in e_left and e_left["index"] == e["index"]
|
||||
if (
|
||||
"index" in e_left
|
||||
and e_left["index"] == e["index"] # index matches
|
||||
and ( # IDs not inconsistent
|
||||
e_left.get("id") is None
|
||||
or e.get("id") is None
|
||||
or e_left["id"] == e["id"]
|
||||
)
|
||||
)
|
||||
]
|
||||
if to_merge:
|
||||
# TODO: Remove this once merge_dict is updated with special
|
||||
|
||||
@@ -916,6 +916,47 @@ def test_merge_tool_calls() -> None:
|
||||
assert len(merged) == 2
|
||||
|
||||
|
||||
def test_merge_tool_calls_parallel_same_index() -> None:
|
||||
"""Test parallel tool calls with same index but different IDs."""
|
||||
# Two parallel tool calls with the same index but different IDs
|
||||
left = create_tool_call_chunk(
|
||||
name="read_file", args='{"path": "foo.txt"}', id="tooluse_ABC", index=0
|
||||
)
|
||||
right = create_tool_call_chunk(
|
||||
name="search_text", args='{"query": "bar"}', id="tooluse_DEF", index=0
|
||||
)
|
||||
merged = merge_lists([left], [right])
|
||||
assert merged is not None
|
||||
assert len(merged) == 2
|
||||
assert merged[0]["name"] == "read_file"
|
||||
assert merged[0]["id"] == "tooluse_ABC"
|
||||
assert merged[1]["name"] == "search_text"
|
||||
assert merged[1]["id"] == "tooluse_DEF"
|
||||
|
||||
# Streaming continuation: same index, id=None on continuation chunk
|
||||
# should still merge correctly with the original chunk
|
||||
first = create_tool_call_chunk(name="tool1", args="", id="id1", index=0)
|
||||
continuation = create_tool_call_chunk(
|
||||
name=None, args='{"key": "value"}', id=None, index=0
|
||||
)
|
||||
merged = merge_lists([first], [continuation])
|
||||
assert merged is not None
|
||||
assert len(merged) == 1
|
||||
assert merged[0]["name"] == "tool1"
|
||||
assert merged[0]["args"] == '{"key": "value"}'
|
||||
assert merged[0]["id"] == "id1"
|
||||
|
||||
# Three parallel tool calls all with the same index
|
||||
tc1 = create_tool_call_chunk(name="tool_a", args="{}", id="id_a", index=0)
|
||||
tc2 = create_tool_call_chunk(name="tool_b", args="{}", id="id_b", index=0)
|
||||
tc3 = create_tool_call_chunk(name="tool_c", args="{}", id="id_c", index=0)
|
||||
merged = merge_lists([tc1], [tc2], [tc3])
|
||||
assert merged is not None
|
||||
assert len(merged) == 3
|
||||
assert [m["name"] for m in merged] == ["tool_a", "tool_b", "tool_c"]
|
||||
assert [m["id"] for m in merged] == ["id_a", "id_b", "id_c"]
|
||||
|
||||
|
||||
def test_tool_message_serdes() -> None:
|
||||
message = ToolMessage(
|
||||
"foo", artifact={"bar": {"baz": 123}}, tool_call_id="1", status="error"
|
||||
|
||||
Reference in New Issue
Block a user