Skip to content

Commit bfb40c5

Browse files
authored
fix(types): require id field on tool calls in ChatMessage.from_dict (#1775)
1 parent 6cc77c5 commit bfb40c5

2 files changed

Lines changed: 21 additions & 1 deletion

File tree

nemoguardrails/types.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,9 +164,13 @@ def from_dict(cls, d: Dict[str, Any]) -> "ChatMessage":
164164
)
165165
args_dict = raw_args
166166

167+
tc_id = tc.get("id")
168+
if not tc_id:
169+
raise ValueError("Tool call missing required 'id' field.")
170+
167171
tool_calls.append(
168172
ToolCall(
169-
id=tc.get("id", ""),
173+
id=tc_id,
170174
type=tc.get("type", "function"),
171175
function=ToolCallFunction(
172176
name=func_data.get("name", ""),

tests/test_types.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,22 @@ def test_from_dict_with_legacy_flat_tool_calls(self):
258258
assert msg.tool_calls[0].function.arguments == {"q": "x"}
259259
assert msg.tool_calls[0].id == "tc_1"
260260

261+
def test_from_dict_raises_on_tool_call_missing_id(self):
262+
d = {
263+
"role": "assistant",
264+
"tool_calls": [{"function": {"name": "search", "arguments": {"q": "x"}}}],
265+
}
266+
with pytest.raises(ValueError, match="missing required 'id'"):
267+
ChatMessage.from_dict(d)
268+
269+
def test_from_dict_raises_on_tool_call_empty_id(self):
270+
d = {
271+
"role": "assistant",
272+
"tool_calls": [{"id": "", "function": {"name": "search", "arguments": {"q": "x"}}}],
273+
}
274+
with pytest.raises(ValueError, match="missing required 'id'"):
275+
ChatMessage.from_dict(d)
276+
261277
def test_from_dict_captures_provider_metadata(self):
262278
d = {"role": "user", "content": "hi", "provider_metadata": {"custom_field": "value", "model": "gpt-4"}}
263279
msg = ChatMessage.from_dict(d)

0 commit comments

Comments
 (0)