Files
crewAI/lib/crewai-files/src/crewai_files/formatting/gemini.py
Greyson LaLonde a1cbb2f4e2 refactor: improve multimodal file handling architecture
- Make crewai_files an optional dependency with graceful fallbacks
- Move file formatting from executor to LLM layer (_process_message_files)
- Add files field to LLMMessage type for cleaner message passing
- Add cache_control to Anthropic content blocks for prompt caching
- Clean up formatters: static methods for OpenAI/Gemini, proper error handling
- Remove unused ContentFormatter protocol
- Move test fixtures to lib/crewai-files/tests/fixtures
- Add Azure and Bedrock multimodal integration tests
- Fix mypy errors in crew_agent_executor.py
2026-01-22 21:55:10 -05:00

68 lines
1.8 KiB
Python

"""Gemini content block formatter."""
from __future__ import annotations
import base64
from typing import Any
from crewai_files.core.resolved import (
FileReference,
InlineBase64,
InlineBytes,
ResolvedFileType,
UrlReference,
)
class GeminiFormatter:
"""Formats resolved files into Gemini content blocks."""
@staticmethod
def format_block(resolved: ResolvedFileType) -> dict[str, Any]:
"""Format a resolved file into a Gemini content block.
Args:
resolved: Resolved file.
Returns:
Content block dict.
Raises:
TypeError: If resolved type is not supported.
"""
if isinstance(resolved, FileReference):
if not resolved.file_uri:
raise ValueError("Gemini requires file_uri for FileReference")
return {
"fileData": {
"mimeType": resolved.content_type,
"fileUri": resolved.file_uri,
}
}
if isinstance(resolved, UrlReference):
return {
"fileData": {
"mimeType": resolved.content_type,
"fileUri": resolved.url,
}
}
if isinstance(resolved, InlineBase64):
return {
"inlineData": {
"mimeType": resolved.content_type,
"data": resolved.data,
}
}
if isinstance(resolved, InlineBytes):
return {
"inlineData": {
"mimeType": resolved.content_type,
"data": base64.b64encode(resolved.data).decode("ascii"),
}
}
raise TypeError(f"Unexpected resolved type: {type(resolved).__name__}")