Skip to content

Commit 91f5c7f

Browse files
Maanik23Maanik Garg
authored andcommitted
fix: restore .text attribute when loading text artifacts from GCS
GcsArtifactService._load_artifact() always used Part.from_bytes() which populates inline_data even for text/plain content. This caused Part.from_text() artifacts to lose their .text attribute after a save/load cycle. Now detects text/plain content type and returns Part(text=...) instead, matching the behavior of FileArtifactService which already handles this correctly. Fixes #3157
1 parent e3060ca commit 91f5c7f

2 files changed

Lines changed: 50 additions & 0 deletions

File tree

src/google/adk/artifacts/gcs_artifact_service.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,10 @@ def _load_artifact(
268268
artifact_bytes = blob.download_as_bytes()
269269
if not artifact_bytes:
270270
return None
271+
# Restore text artifacts with the .text attribute rather than
272+
# inline_data so that round-tripping Part.from_text() works correctly.
273+
if blob.content_type and blob.content_type.startswith("text/plain"):
274+
return types.Part(text=artifact_bytes.decode("utf-8"))
271275
artifact = types.Part.from_bytes(
272276
data=artifact_bytes, mime_type=blob.content_type
273277
)

tests/unittests/artifacts/test_artifact_service.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -959,3 +959,49 @@ async def test_save_artifact_with_snake_case_dict(
959959
assert loaded is not None
960960
assert loaded.inline_data is not None
961961
assert loaded.inline_data.mime_type == "text/plain"
962+
963+
964+
@pytest.mark.asyncio
965+
@pytest.mark.parametrize(
966+
"service_type",
967+
[
968+
ArtifactServiceType.IN_MEMORY,
969+
ArtifactServiceType.GCS,
970+
ArtifactServiceType.FILE,
971+
],
972+
)
973+
async def test_text_artifact_roundtrip(service_type, artifact_service_factory):
974+
"""Text artifacts saved via Part.from_text() should preserve .text on load.
975+
976+
Regression test for https://github.com/google/adk-python/issues/3157
977+
"""
978+
artifact_service = artifact_service_factory(service_type)
979+
app_name = "app0"
980+
user_id = "user0"
981+
session_id = "sess0"
982+
filename = "report.txt"
983+
text_content = '{"status": "success", "report": "Sunny, 25C"}'
984+
985+
artifact = types.Part.from_text(text=text_content)
986+
assert artifact.text == text_content # sanity check
987+
988+
version = await artifact_service.save_artifact(
989+
app_name=app_name,
990+
user_id=user_id,
991+
session_id=session_id,
992+
filename=filename,
993+
artifact=artifact,
994+
)
995+
assert version == 0
996+
997+
loaded = await artifact_service.load_artifact(
998+
app_name=app_name,
999+
user_id=user_id,
1000+
session_id=session_id,
1001+
filename=filename,
1002+
)
1003+
assert loaded is not None
1004+
assert loaded.text == text_content, (
1005+
f"Expected .text='{text_content}', got .text={loaded.text!r} "
1006+
f"(inline_data={loaded.inline_data!r})"
1007+
)

0 commit comments

Comments
 (0)