Files
Hy-Memory/tests/test_normalize_message_tool_calls.py
T
2026-10-16 16:26:27 +08:00

86 lines
2.8 KiB
Python

# -*- coding: utf-8 -*-
"""
覆盖 `HyMemoryClient._normalize_message` 对 `tool_calls` 字段的兼容处理。
背景:部分客户端(如 codebuddy)会把 `tool_calls` 编码成 JSON 字符串而非
list[dict],直接对字符串做 for 循环会按字符迭代,随后 `tc.get(...)` 抛出
`AttributeError: 'str' object has no attribute 'get'`。
运行方式:
pytest tests/test_normalize_message_tool_calls.py -v
"""
from hy_memory.client import HyMemoryClient
def test_tool_calls_normal_list():
msg = {
"role": "assistant",
"content": "",
"tool_calls": [
{"id": "1", "function": {"name": "f", "arguments": "{}"}},
],
}
result = HyMemoryClient._normalize_message(msg)
assert len(result) == 1
assert len(result[0].tool_calls) == 1
assert result[0].tool_calls[0].name == "f"
assert result[0].tool_calls[0].id == "1"
def test_tool_calls_json_string():
msg = {
"role": "assistant",
"content": "",
"tool_calls": '[{"id":"1","function":{"name":"f","arguments":"{}"}}]',
}
result = HyMemoryClient._normalize_message(msg)
assert len(result) == 1
assert len(result[0].tool_calls) == 1
assert result[0].tool_calls[0].name == "f"
assert result[0].tool_calls[0].id == "1"
def test_tool_calls_empty_string():
msg = {"role": "assistant", "content": "", "tool_calls": ""}
result = HyMemoryClient._normalize_message(msg)
assert result[0].tool_calls == []
def test_tool_calls_invalid_json_string():
msg = {"role": "assistant", "content": "", "tool_calls": "not-json"}
result = HyMemoryClient._normalize_message(msg)
assert result[0].tool_calls == []
def test_tool_calls_list_with_non_dict_items():
msg = {
"role": "assistant",
"content": "",
"tool_calls": ["x", {"id": "1", "function": {"name": "f", "arguments": "{}"}}],
}
result = HyMemoryClient._normalize_message(msg)
assert len(result[0].tool_calls) == 1
assert result[0].tool_calls[0].name == "f"
def test_real_world_codebuddy_case():
"""回归验收现场:assistant 消息 tool_calls 为字符串,read_file 调用需被正确抽出。"""
msg = {
"role": "assistant",
"content": "",
"tool_calls": (
'[{"id":"toolu_bdrk_013NXmCFJ53CN1uTUuUtz8mH","type":"function",'
'"function":{"name":"read_file",'
'"arguments":"{\\"filePath\\":\\"/a/b.java\\"}"}}]'
),
"tool_call_id": "",
}
result = HyMemoryClient._normalize_message(msg)
assert len(result) == 1
tool_calls = result[0].tool_calls
assert len(tool_calls) == 1
assert tool_calls[0].id == "toolu_bdrk_013NXmCFJ53CN1uTUuUtz8mH"
assert tool_calls[0].name == "read_file"
assert tool_calls[0].arguments == {"filePath": "/a/b.java"}