fix(memory): guard against malformed image_url in parse_vision_messages (#5631)
This commit is contained in:
@@ -31,9 +31,11 @@ const parse_vision_messages = async (messages: Message[]) => {
|
|||||||
typeof message.content === "object" &&
|
typeof message.content === "object" &&
|
||||||
message.content.type === "image_url"
|
message.content.type === "image_url"
|
||||||
) {
|
) {
|
||||||
const description = await get_image_description(
|
const imageUrl = message.content.image_url?.url;
|
||||||
message.content.image_url.url,
|
if (!imageUrl) {
|
||||||
);
|
throw new Error("image_url content part is missing image_url.url");
|
||||||
|
}
|
||||||
|
const description = await get_image_description(imageUrl);
|
||||||
new_message.content =
|
new_message.content =
|
||||||
typeof description === "string"
|
typeof description === "string"
|
||||||
? description
|
? description
|
||||||
|
|||||||
@@ -206,7 +206,10 @@ def parse_vision_messages(messages, llm=None, vision_details="auto"):
|
|||||||
elif isinstance(content, dict) and content.get("type") == "image_url":
|
elif isinstance(content, dict) and content.get("type") == "image_url":
|
||||||
if llm is None:
|
if llm is None:
|
||||||
continue
|
continue
|
||||||
image_url = content["image_url"]["url"]
|
image_url_obj = content.get("image_url")
|
||||||
|
image_url = image_url_obj.get("url") if isinstance(image_url_obj, dict) else None
|
||||||
|
if not image_url:
|
||||||
|
raise ValueError("image_url content part is missing image_url.url")
|
||||||
try:
|
try:
|
||||||
description = get_image_description(image_url, llm, vision_details)
|
description = get_image_description(image_url, llm, vision_details)
|
||||||
returned_messages.append({"role": role, "content": description})
|
returned_messages.append({"role": role, "content": description})
|
||||||
|
|||||||
@@ -96,6 +96,24 @@ class TestParseVisionMessages:
|
|||||||
result = parse_vision_messages(messages, llm=None)
|
result = parse_vision_messages(messages, llm=None)
|
||||||
assert result == messages
|
assert result == messages
|
||||||
|
|
||||||
|
def test_malformed_image_dict_raises_value_error(self):
|
||||||
|
# A malformed image part (missing the nested url) used to raise an
|
||||||
|
# uncaught KeyError that aborted add(); it should raise a clear ValueError.
|
||||||
|
mock_llm = Mock()
|
||||||
|
messages = [{"role": "user", "content": {"type": "image_url", "image_url": {}}}]
|
||||||
|
with pytest.raises(ValueError, match=r"missing image_url\.url"):
|
||||||
|
parse_vision_messages(messages, llm=mock_llm)
|
||||||
|
mock_llm.generate_response.assert_not_called()
|
||||||
|
|
||||||
|
def test_none_image_url_raises_value_error(self):
|
||||||
|
# image_url present but None (or any non-dict) must also raise the clear
|
||||||
|
# ValueError, not an AttributeError from calling .get() on None.
|
||||||
|
mock_llm = Mock()
|
||||||
|
messages = [{"role": "user", "content": {"type": "image_url", "image_url": None}}]
|
||||||
|
with pytest.raises(ValueError, match=r"missing image_url\.url"):
|
||||||
|
parse_vision_messages(messages, llm=mock_llm)
|
||||||
|
mock_llm.generate_response.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
class TestRemoveSpacesFromEntities:
|
class TestRemoveSpacesFromEntities:
|
||||||
"""
|
"""
|
||||||
|
|||||||
Reference in New Issue
Block a user