Skip to content

Commit d10dc18

Browse files
DavdGaoclaude
andcommitted
refactor(tool): expose Read.model_input_types as a plain attribute and evaluate it at use sites
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 5ddd6fb commit d10dc18

2 files changed

Lines changed: 30 additions & 13 deletions

File tree

src/agentscope/tool/_builtin/_read.py

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -100,13 +100,19 @@ def description(self) -> str: # type: ignore[override]
100100
"""The description presented to the agent, with the image and PDF
101101
bullets rendered from the model's accepted input types."""
102102
lines = [self._DESCRIPTION_HEAD]
103-
if self._image_types:
103+
image_types = [
104+
t for t in self.model_input_types if t.startswith("image/")
105+
]
106+
if image_types:
104107
lines.append(
105-
f"- This tool allows you to read images ({', '.join(self._image_types)}). When reading an image file the contents are presented visually as you're a multimodal LLM.", # noqa: E501
108+
f"- This tool allows you to read images ({', '.join(image_types)}). When reading an image file the contents are presented visually as you're a multimodal LLM.", # noqa: E501
106109
)
107110
pdf_presentation = (
108111
"When reading a PDF file the pages are presented to you as a document." # noqa: E501
109-
if self._pdf_passthrough
112+
if any(
113+
fnmatch.fnmatch("application/pdf", t)
114+
for t in self.model_input_types
115+
)
110116
else "Text is extracted per page."
111117
)
112118
lines.append(
@@ -159,13 +165,10 @@ def __init__(
159165

160166
super().__init__(middlewares=middlewares)
161167
self._max_line_characters = max_line_characters
162-
model_input_types = model_input_types or _DEFAULT_MODEL_INPUT_TYPES
163-
self._image_types = [
164-
t for t in model_input_types if t.startswith("image/")
165-
]
166-
self._pdf_passthrough = any(
167-
fnmatch.fnmatch("application/pdf", t) for t in model_input_types
168+
self.model_input_types = (
169+
model_input_types or _DEFAULT_MODEL_INPUT_TYPES
168170
)
171+
"""The media types the model accepts as input, see ``__init__``."""
169172
self._backend = backend or LocalBackend()
170173

171174
async def check_permissions(
@@ -326,12 +329,18 @@ async def _read_image_file(
326329
) -> ToolChunk:
327330
"""Read an image file and return as DataBlock."""
328331
media_type = _IMAGE_EXTENSIONS[ext]
329-
if not any(fnmatch.fnmatch(media_type, t) for t in self._image_types):
332+
if not any(
333+
fnmatch.fnmatch(media_type, t) for t in self.model_input_types
334+
):
335+
image_types = [
336+
t for t in self.model_input_types if t.startswith("image/")
337+
]
330338
return ToolChunk(
331339
content=[
332340
TextBlock(
333341
text=f"Error: Unsupported image type {media_type}, "
334-
f"only {', '.join(self._image_types)} are supported.",
342+
f"only {', '.join(image_types) or 'none'} are "
343+
"supported.",
335344
),
336345
],
337346
state=ToolResultState.ERROR,
@@ -442,7 +451,10 @@ async def _read_pdf(
442451
is_last=True,
443452
)
444453

445-
if not self._pdf_passthrough:
454+
if not any(
455+
fnmatch.fnmatch("application/pdf", t)
456+
for t in self.model_input_types
457+
):
446458
text_parts = [
447459
f"--- Page {page_num}/{total_pages} ---\n"
448460
f"{reader.pages[page_num - 1].extract_text() or ''}"

tests/builtin_read_test.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,10 +385,15 @@ async def test_read_image_unsupported_type(self) -> None:
385385
self.assertIn("image/bmp", tool.description)
386386
self.assertNotIn("text/plain", tool.description)
387387

388-
# Glob patterns are accepted.
388+
# Glob patterns are accepted, and the attribute can be changed
389+
# after construction.
389390
tool = Read(model_input_types=["image/*"])
390391
chunk = await tool(file_path=f.name)
391392
self.assertEqual(chunk.state, "running")
393+
tool.model_input_types = ["text/plain"]
394+
chunk = await tool(file_path=f.name)
395+
self.assertEqual(chunk.state, "error")
396+
self.assertNotIn("read images", tool.description)
392397

393398
# A supported image is rejected once it's excluded.
394399
tool = Read(model_input_types=["image/png"])

0 commit comments

Comments
 (0)