diff --git a/lib/crewai/src/crewai/tools/file_artifact.py b/lib/crewai/src/crewai/tools/file_artifact.py index 74c17994f..db4838284 100644 --- a/lib/crewai/src/crewai/tools/file_artifact.py +++ b/lib/crewai/src/crewai/tools/file_artifact.py @@ -187,7 +187,10 @@ def resolve_artifact_handles(value: Any) -> Any: return value def _sub(match: re.Match[str]) -> str: - artifact = _store.resolve(match.group(1)) + # Store keys are lowercase uuid4 strings; the regex matches hex + # case-insensitively, so normalize before lookup in case the model + # echoed the handle with uppercase hex. + artifact = _store.resolve(match.group(1).lower()) return artifact.as_base64() if artifact is not None else match.group(0) return _HANDLE_RE.sub(_sub, value) diff --git a/lib/crewai/tests/tools/test_file_artifact.py b/lib/crewai/tests/tools/test_file_artifact.py index f19160128..74f1965be 100644 --- a/lib/crewai/tests/tools/test_file_artifact.py +++ b/lib/crewai/tests/tools/test_file_artifact.py @@ -100,6 +100,16 @@ class TestResolveArtifactHandles: resolved = resolve_artifact_handles(handle) assert base64.b64decode(resolved) == data + def test_resolves_handle_with_uppercased_hex(self) -> None: + # A model may echo the handle with uppercase uuid hex; lookup must still + # hit the lowercase-keyed store. + data = b"upper-case-payload" * 100 + handle = _handle_in(store_artifact(FileArtifact(data=data))) + scheme, _, hex_part = handle.rpartition("/") + upper = f"{scheme}/{hex_part.upper()}" + assert upper != handle + assert base64.b64decode(resolve_artifact_handles(upper)) == data + def test_resolves_handle_inside_dict(self) -> None: data = b"binary-payload" * 1000 handle = _handle_in(store_artifact(FileArtifact(data=data)))