Files
windmill/integration_tests/ai_agent_tests/test_user_attachments.py
centdix e44504c6e9 feat: add PDF input support to AI agent (#8525)
* feat: add PDF input support to AI agent with user_attachments field

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* test: add integration tests for PDF input and backward compat

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add ContentPart::File variant for PDF support across all providers

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor: address review feedback on PDF support

- Extract parse_data_url_bytes and mime_to_document_format helpers in Bedrock
- Add is_document_mime helper in ai_types for centralized MIME routing
- Extract s3_object_to_content_part helper to deduplicate image_handler/openai
- Rename AnthropicImageSource to AnthropicBase64Source
- Derive Bedrock DocumentFormat from MIME type instead of hardcoding Pdf

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: merge user message and attachments into single message for Bedrock

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 13:55:10 +00:00

97 lines
3.3 KiB
Python

"""Tests for AI agent user_attachments (PDF) functionality with S3 storage.
Prerequisites:
- MinIO running on localhost:9000 with bucket 'wmill'
- Test files uploaded to MinIO (test_images/test_image.webp, test_documents/test_document.pdf)
- S3 resource and storage configured in the integration-tests workspace
"""
import pytest
from .conftest import AIAgentTestClient, create_ai_agent_flow, TEST_IMAGE_S3_KEY
from .providers import VISION_PROVIDERS, get_provider_ids
TEST_PDF_S3_KEY = "test_documents/test_document.pdf"
class TestUserAttachments:
"""Test AI agent with PDF attachments from S3 storage."""
@pytest.mark.parametrize(
"provider_config",
VISION_PROVIDERS,
ids=get_provider_ids(VISION_PROVIDERS),
)
def test_pdf_analysis(
self,
client: AIAgentTestClient,
setup_providers,
provider_config,
):
"""Test that AI can analyze a PDF uploaded to S3."""
flow_value = create_ai_agent_flow(
provider_input_transform=provider_config["input_transform"],
system_prompt="You are a helpful assistant that reads documents. Be concise.",
include_user_images=True,
)
# Run the flow with the PDF (test_document.pdf contains "Hello PDF World")
result = client.run_preview_flow(
flow_value=flow_value,
args={
"user_message": "What text does this PDF document contain? Reply with just the text.",
"user_images": [
{
"s3": TEST_PDF_S3_KEY,
"storage": None,
"filename": "test_document.pdf",
}
],
},
)
assert result is not None
assert isinstance(result, (dict, str))
result_text = str(result).lower()
assert "hello" in result_text or "pdf" in result_text, (
f"Expected AI to read PDF content containing 'Hello PDF World', "
f"got: {result}"
)
print(f"PDF analysis result from {provider_config['name']}: {result}")
@pytest.mark.parametrize(
"provider_config",
VISION_PROVIDERS,
ids=get_provider_ids(VISION_PROVIDERS),
)
def test_backward_compat_user_images(
self,
client: AIAgentTestClient,
setup_providers,
provider_config,
):
"""Test that the old user_images field name still works for images."""
flow_value = create_ai_agent_flow(
provider_input_transform=provider_config["input_transform"],
system_prompt="You are a helpful assistant that describes images. Be concise.",
include_user_images=True,
)
result = client.run_preview_flow(
flow_value=flow_value,
args={
"user_message": "Describe what you see in this image in one sentence.",
"user_images": [
{
"s3": TEST_IMAGE_S3_KEY,
"storage": None,
"filename": "test_image.webp",
}
],
},
)
assert result is not None
assert isinstance(result, (dict, str))
print(f"Backward compat image result from {provider_config['name']}: {result}")