diff --git a/src/google/adk/artifacts/file_artifact_service.py b/src/google/adk/artifacts/file_artifact_service.py index 05eb59b9df..21e5b9305d 100644 --- a/src/google/adk/artifacts/file_artifact_service.py +++ b/src/google/adk/artifacts/file_artifact_service.py @@ -34,6 +34,7 @@ from . import artifact_util from ..errors.input_validation_error import InputValidationError +from ..platform import time as platform_time from .base_artifact_service import ArtifactVersion from .base_artifact_service import BaseArtifactService from .base_artifact_service import ensure_part @@ -445,6 +446,9 @@ def _build_artifact_version( canonical_uri=canonical_uri, custom_metadata=dict(custom_metadata_val), mime_type=mime_type, + create_time=metadata.create_time + if metadata + else platform_time.get_time(), ) def _latest_metadata( diff --git a/tests/unittests/artifacts/test_artifact_service.py b/tests/unittests/artifacts/test_artifact_service.py index 30f071f2e9..d72217f317 100644 --- a/tests/unittests/artifacts/test_artifact_service.py +++ b/tests/unittests/artifacts/test_artifact_service.py @@ -1238,6 +1238,50 @@ async def test_file_list_artifact_versions(tmp_path, artifact_service_factory): assert latest.custom_metadata == version_meta.custom_metadata +@pytest.mark.asyncio +@pytest.mark.parametrize( + "session_id,filename", + [ + ("session", "report.txt"), + ("session", "user:report.txt"), + (None, "report.txt"), + ], +) +@pytest.mark.parametrize( + "artifact", + [ + types.Part(text="report"), + types.Part.from_bytes(data=b"report", mime_type="text/plain"), + ], +) +async def test_file_artifact_versions_preserve_create_time( + tmp_path, session_id, filename, artifact +): + """Metadata reads preserve each saved timestamp after reopening the service.""" + service = FileArtifactService(root_dir=tmp_path) + scope = dict( + app_name="app", user_id="user", session_id=session_id, filename=filename + ) + create_times = [0.0, FIXED_DATETIME.timestamp()] + with patch( + "google.adk.artifacts.base_artifact_service.platform_time.get_time" + ) as get_time: + for create_time in create_times: + get_time.return_value = create_time + await service.save_artifact(**scope, artifact=artifact) + + service = FileArtifactService(root_dir=tmp_path) + for read_time in [create_times[-1] + 10, create_times[-1] + 20]: + get_time.return_value = read_time + versions = await service.list_artifact_versions(**scope) + first = await service.get_artifact_version(**scope, version=0) + latest = await service.get_artifact_version(**scope) + + assert [version.create_time for version in versions] == create_times + assert first.create_time == create_times[0] + assert latest.create_time == create_times[-1] + + @pytest.mark.asyncio async def test_file_save_artifact_reserves_concurrent_versions(tmp_path): service = FileArtifactService(root_dir=tmp_path / "artifacts")