From eb8eec21cefa95f5d8ec3e986c974eeb349bbd74 Mon Sep 17 00:00:00 2001 From: Daoyuan Li <94409450+DaoyuanLi2816@users.noreply.github.com> Date: Thu, 9 Jul 2026 20:08:30 -0700 Subject: [PATCH] Return the full-resolution image URL from image_search (#3990) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `image_search` set both `image_url` and `thumbnail_url` to the DDGS result's `thumbnail` field, so the tool never returned the full-resolution image even though its docstring/usage_hint promise reference-quality images (and a result with no `thumbnail` returned an empty `image_url`). DDGS `.images()` exposes the full-res source under the separate `image` key — read that for `image_url`, matching the serper/brave providers which keep image vs thumbnail distinct. Adds a regression test. --- .../deerflow/community/image_search/tools.py | 2 +- backend/tests/test_image_search.py | 28 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 backend/tests/test_image_search.py diff --git a/backend/packages/harness/deerflow/community/image_search/tools.py b/backend/packages/harness/deerflow/community/image_search/tools.py index dc78a5ad3..4b300b230 100644 --- a/backend/packages/harness/deerflow/community/image_search/tools.py +++ b/backend/packages/harness/deerflow/community/image_search/tools.py @@ -119,7 +119,7 @@ def image_search_tool( normalized_results = [ { "title": r.get("title", ""), - "image_url": r.get("thumbnail", ""), + "image_url": r.get("image", ""), "thumbnail_url": r.get("thumbnail", ""), } for r in results diff --git a/backend/tests/test_image_search.py b/backend/tests/test_image_search.py new file mode 100644 index 000000000..12f5f0501 --- /dev/null +++ b/backend/tests/test_image_search.py @@ -0,0 +1,28 @@ +import json +from unittest.mock import MagicMock, patch + +from deerflow.community.image_search.tools import image_search_tool + + +def test_image_search_uses_full_image_url_not_thumbnail(): + # Regression: `image_url` must expose the full-resolution `image` from the DDGS result, + # not the low-res `thumbnail` (both fields were previously set to `thumbnail`). + fake_results = [ + { + "title": "a cat", + "image": "https://example.com/full.jpg", + "thumbnail": "https://example.com/thumb.jpg", + } + ] + cfg = MagicMock() + cfg.get_tool_config.return_value = None + + with ( + patch("deerflow.community.image_search.tools._search_images", return_value=fake_results), + patch("deerflow.community.image_search.tools.get_app_config", return_value=cfg), + ): + output = json.loads(image_search_tool.invoke({"query": "a cat"})) + + result = output["results"][0] + assert result["image_url"] == "https://example.com/full.jpg" + assert result["thumbnail_url"] == "https://example.com/thumb.jpg"