From a32072f454a766f7e0f988f4a0fbeff938565d9b Mon Sep 17 00:00:00 2001 From: Sara Burke <115188+saralilyb@users.noreply.github.com> Date: Wed, 3 Jun 2026 15:55:34 -0400 Subject: [PATCH] fix(gateway): deliver ics files as attachments --- gateway/platforms/base.py | 3 ++- tests/gateway/test_media_extraction.py | 30 ++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/gateway/platforms/base.py b/gateway/platforms/base.py index d7654ff6c147..54a09e9f8b5e 100644 --- a/gateway/platforms/base.py +++ b/gateway/platforms/base.py @@ -1539,6 +1539,7 @@ def _log_safe_path(path: str) -> str: SUPPORTED_DOCUMENT_TYPES = { ".pdf": "application/pdf", + ".ics": "text/calendar", ".md": "text/markdown", ".txt": "text/plain", ".csv": "text/csv", @@ -1644,7 +1645,7 @@ def _log_safe_path(path: str) -> str: # Audio (delivered as voice/audio where supported) ".mp3", ".m2a", ".wav", ".ogg", ".opus", ".m4a", ".flac", # Documents (uploaded as file attachments) - ".pdf", ".docx", ".doc", ".odt", ".rtf", ".txt", ".md", ".epub", + ".pdf", ".ics", ".docx", ".doc", ".odt", ".rtf", ".txt", ".md", ".epub", # Spreadsheets / data ".xlsx", ".xls", ".ods", ".csv", ".tsv", ".json", ".xml", ".yaml", ".yml", # Geospatial / GIS (#24032) diff --git a/tests/gateway/test_media_extraction.py b/tests/gateway/test_media_extraction.py index 65f64e6650bc..4a790550f339 100644 --- a/tests/gateway/test_media_extraction.py +++ b/tests/gateway/test_media_extraction.py @@ -102,6 +102,36 @@ def extract_media_tags_broken(result_messages): return media_tags, has_voice_directive +class TestMediaDeliveryExtensions: + """Tests for the shared outbound media-delivery allowlist.""" + + def test_ics_media_tag_is_extracted_for_document_delivery(self): + """Calendar invites should upload instead of rendering MEDIA: text.""" + from gateway.platforms.base import BasePlatformAdapter + + media, cleaned = BasePlatformAdapter.extract_media( + "Here is the calendar invite.\nMEDIA:/tmp/event.ics" + ) + + assert media == [("/tmp/event.ics", False)] + assert "MEDIA:" not in cleaned + assert "event.ics" not in cleaned + + def test_ics_bare_path_is_allowed_for_document_delivery(self, tmp_path): + """Bare local .ics paths should use the same delivery allowlist.""" + from gateway.platforms.base import BasePlatformAdapter + + invite_path = tmp_path / "event.ics" + invite_path.write_text("BEGIN:VCALENDAR\nEND:VCALENDAR\n") + + files, cleaned = BasePlatformAdapter.extract_local_files( + f"The invite is at {invite_path}" + ) + + assert files == [str(invite_path)] + assert "event.ics" not in cleaned + + class TestMediaExtraction: """Tests for MEDIA tag extraction from tool results."""