mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-01-28 09:38:17 +00:00
feat(files): add api parameter to format_multimodal_content
Allows selecting OpenAIResponsesFormatter via api="responses" parameter instead of always using Chat Completions format.
This commit is contained in:
@@ -10,7 +10,7 @@ from crewai_files.core.types import FileInput
|
|||||||
from crewai_files.formatting.anthropic import AnthropicFormatter
|
from crewai_files.formatting.anthropic import AnthropicFormatter
|
||||||
from crewai_files.formatting.bedrock import BedrockFormatter
|
from crewai_files.formatting.bedrock import BedrockFormatter
|
||||||
from crewai_files.formatting.gemini import GeminiFormatter
|
from crewai_files.formatting.gemini import GeminiFormatter
|
||||||
from crewai_files.formatting.openai import OpenAIFormatter
|
from crewai_files.formatting.openai import OpenAIFormatter, OpenAIResponsesFormatter
|
||||||
from crewai_files.processing.constraints import get_constraints_for_provider
|
from crewai_files.processing.constraints import get_constraints_for_provider
|
||||||
from crewai_files.processing.processor import FileProcessor
|
from crewai_files.processing.processor import FileProcessor
|
||||||
from crewai_files.resolution.resolver import FileResolver, FileResolverConfig
|
from crewai_files.resolution.resolver import FileResolver, FileResolverConfig
|
||||||
@@ -57,6 +57,7 @@ def _normalize_provider(provider: str | None) -> ProviderType:
|
|||||||
def format_multimodal_content(
|
def format_multimodal_content(
|
||||||
files: dict[str, FileInput],
|
files: dict[str, FileInput],
|
||||||
provider: str | None = None,
|
provider: str | None = None,
|
||||||
|
api: str | None = None,
|
||||||
) -> list[dict[str, Any]]:
|
) -> list[dict[str, Any]]:
|
||||||
"""Format files as provider-specific multimodal content blocks.
|
"""Format files as provider-specific multimodal content blocks.
|
||||||
|
|
||||||
@@ -69,6 +70,7 @@ def format_multimodal_content(
|
|||||||
Args:
|
Args:
|
||||||
files: Dictionary mapping file names to FileInput objects.
|
files: Dictionary mapping file names to FileInput objects.
|
||||||
provider: Provider name (e.g., "openai", "anthropic", "bedrock", "gemini").
|
provider: Provider name (e.g., "openai", "anthropic", "bedrock", "gemini").
|
||||||
|
api: API variant (e.g., "responses" for OpenAI Responses API).
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
List of content blocks in the provider's expected format.
|
List of content blocks in the provider's expected format.
|
||||||
@@ -77,6 +79,8 @@ def format_multimodal_content(
|
|||||||
>>> from crewai_files import format_multimodal_content, ImageFile
|
>>> from crewai_files import format_multimodal_content, ImageFile
|
||||||
>>> files = {"photo": ImageFile(source="image.jpg")}
|
>>> files = {"photo": ImageFile(source="image.jpg")}
|
||||||
>>> blocks = format_multimodal_content(files, "openai")
|
>>> blocks = format_multimodal_content(files, "openai")
|
||||||
|
>>> # For OpenAI Responses API:
|
||||||
|
>>> blocks = format_multimodal_content(files, "openai", api="responses")
|
||||||
"""
|
"""
|
||||||
if not files:
|
if not files:
|
||||||
return []
|
return []
|
||||||
@@ -100,7 +104,7 @@ def format_multimodal_content(
|
|||||||
upload_cache = get_upload_cache()
|
upload_cache = get_upload_cache()
|
||||||
resolver = FileResolver(config=config, upload_cache=upload_cache)
|
resolver = FileResolver(config=config, upload_cache=upload_cache)
|
||||||
|
|
||||||
formatter = _get_formatter(provider_type)
|
formatter = _get_formatter(provider_type, api)
|
||||||
content_blocks: list[dict[str, Any]] = []
|
content_blocks: list[dict[str, Any]] = []
|
||||||
|
|
||||||
for name, file_input in supported_files.items():
|
for name, file_input in supported_files.items():
|
||||||
@@ -115,6 +119,7 @@ def format_multimodal_content(
|
|||||||
async def aformat_multimodal_content(
|
async def aformat_multimodal_content(
|
||||||
files: dict[str, FileInput],
|
files: dict[str, FileInput],
|
||||||
provider: str | None = None,
|
provider: str | None = None,
|
||||||
|
api: str | None = None,
|
||||||
) -> list[dict[str, Any]]:
|
) -> list[dict[str, Any]]:
|
||||||
"""Async format files as provider-specific multimodal content blocks.
|
"""Async format files as provider-specific multimodal content blocks.
|
||||||
|
|
||||||
@@ -123,6 +128,7 @@ async def aformat_multimodal_content(
|
|||||||
Args:
|
Args:
|
||||||
files: Dictionary mapping file names to FileInput objects.
|
files: Dictionary mapping file names to FileInput objects.
|
||||||
provider: Provider name (e.g., "openai", "anthropic", "bedrock", "gemini").
|
provider: Provider name (e.g., "openai", "anthropic", "bedrock", "gemini").
|
||||||
|
api: API variant (e.g., "responses" for OpenAI Responses API).
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
List of content blocks in the provider's expected format.
|
List of content blocks in the provider's expected format.
|
||||||
@@ -151,7 +157,7 @@ async def aformat_multimodal_content(
|
|||||||
|
|
||||||
resolved_files = await resolver.aresolve_files(supported_files, provider_type)
|
resolved_files = await resolver.aresolve_files(supported_files, provider_type)
|
||||||
|
|
||||||
formatter = _get_formatter(provider_type)
|
formatter = _get_formatter(provider_type, api)
|
||||||
content_blocks: list[dict[str, Any]] = []
|
content_blocks: list[dict[str, Any]] = []
|
||||||
|
|
||||||
for name, resolved in resolved_files.items():
|
for name, resolved in resolved_files.items():
|
||||||
@@ -235,11 +241,19 @@ def _get_resolver_config(provider_lower: str) -> FileResolverConfig:
|
|||||||
|
|
||||||
def _get_formatter(
|
def _get_formatter(
|
||||||
provider_lower: str,
|
provider_lower: str,
|
||||||
) -> OpenAIFormatter | AnthropicFormatter | BedrockFormatter | GeminiFormatter:
|
api: str | None = None,
|
||||||
|
) -> (
|
||||||
|
OpenAIFormatter
|
||||||
|
| OpenAIResponsesFormatter
|
||||||
|
| AnthropicFormatter
|
||||||
|
| BedrockFormatter
|
||||||
|
| GeminiFormatter
|
||||||
|
):
|
||||||
"""Get formatter for provider.
|
"""Get formatter for provider.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
provider_lower: Lowercase provider name.
|
provider_lower: Lowercase provider name.
|
||||||
|
api: API variant (e.g., "responses" for OpenAI Responses API).
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Provider-specific formatter instance.
|
Provider-specific formatter instance.
|
||||||
@@ -254,11 +268,15 @@ def _get_formatter(
|
|||||||
if "gemini" in provider_lower or "google" in provider_lower:
|
if "gemini" in provider_lower or "google" in provider_lower:
|
||||||
return GeminiFormatter()
|
return GeminiFormatter()
|
||||||
|
|
||||||
|
if api == "responses":
|
||||||
|
return OpenAIResponsesFormatter()
|
||||||
|
|
||||||
return OpenAIFormatter()
|
return OpenAIFormatter()
|
||||||
|
|
||||||
|
|
||||||
def _format_block(
|
def _format_block(
|
||||||
formatter: OpenAIFormatter
|
formatter: OpenAIFormatter
|
||||||
|
| OpenAIResponsesFormatter
|
||||||
| AnthropicFormatter
|
| AnthropicFormatter
|
||||||
| BedrockFormatter
|
| BedrockFormatter
|
||||||
| GeminiFormatter,
|
| GeminiFormatter,
|
||||||
@@ -281,6 +299,8 @@ def _format_block(
|
|||||||
return formatter.format_block(file_input, resolved, name=name)
|
return formatter.format_block(file_input, resolved, name=name)
|
||||||
if isinstance(formatter, AnthropicFormatter):
|
if isinstance(formatter, AnthropicFormatter):
|
||||||
return formatter.format_block(file_input, resolved)
|
return formatter.format_block(file_input, resolved)
|
||||||
|
if isinstance(formatter, OpenAIResponsesFormatter):
|
||||||
|
return formatter.format_block(resolved, file_input.content_type)
|
||||||
if isinstance(formatter, (OpenAIFormatter, GeminiFormatter)):
|
if isinstance(formatter, (OpenAIFormatter, GeminiFormatter)):
|
||||||
return formatter.format_block(resolved)
|
return formatter.format_block(resolved)
|
||||||
raise TypeError(f"Unknown formatter type: {type(formatter).__name__}")
|
raise TypeError(f"Unknown formatter type: {type(formatter).__name__}")
|
||||||
|
|||||||
Reference in New Issue
Block a user