diff --git a/src/celeste/client.py b/src/celeste/client.py index 213fc5db..7cd5aeaa 100644 --- a/src/celeste/client.py +++ b/src/celeste/client.py @@ -237,7 +237,7 @@ def _stream( @classmethod @abstractmethod - def parameter_mappers(cls) -> list[ParameterMapper]: + def parameter_mappers(cls) -> list[ParameterMapper[Content]]: """Provider-specific parameter mappers.""" ... diff --git a/src/celeste/modalities/audio/providers/elevenlabs/client.py b/src/celeste/modalities/audio/providers/elevenlabs/client.py index 50c76814..cc230ed4 100644 --- a/src/celeste/modalities/audio/providers/elevenlabs/client.py +++ b/src/celeste/modalities/audio/providers/elevenlabs/client.py @@ -11,6 +11,7 @@ from celeste.providers.elevenlabs.text_to_speech.streaming import ( ElevenLabsTextToSpeechStream as _ElevenLabsTextToSpeechStream, ) +from celeste.types import AudioContent from ...client import AudioClient from ...io import ( @@ -40,7 +41,7 @@ class ElevenLabsAudioClient(ElevenLabsTextToSpeechMixin, AudioClient): """ElevenLabs audio client (TTS).""" @classmethod - def parameter_mappers(cls) -> list[ParameterMapper]: + def parameter_mappers(cls) -> list[ParameterMapper[AudioContent]]: return ELEVENLABS_PARAMETER_MAPPERS async def speak( diff --git a/src/celeste/modalities/audio/providers/elevenlabs/parameters.py b/src/celeste/modalities/audio/providers/elevenlabs/parameters.py index 479a0d2d..a2fd69f0 100644 --- a/src/celeste/modalities/audio/providers/elevenlabs/parameters.py +++ b/src/celeste/modalities/audio/providers/elevenlabs/parameters.py @@ -13,6 +13,7 @@ from celeste.providers.elevenlabs.text_to_speech.parameters import ( VoiceMapper as _VoiceMapper, ) +from celeste.types import AudioContent from ...parameters import AudioParameter @@ -41,7 +42,7 @@ class LanguageCodeMapper(_LanguageCodeMapper): name = AudioParameter.LANGUAGE -ELEVENLABS_PARAMETER_MAPPERS: list[ParameterMapper] = [ +ELEVENLABS_PARAMETER_MAPPERS: list[ParameterMapper[AudioContent]] = [ VoiceMapper(), SpeedMapper(), OutputFormatMapper(), diff --git a/src/celeste/modalities/audio/providers/google/client.py b/src/celeste/modalities/audio/providers/google/client.py index 800346e5..96ea1d2b 100644 --- a/src/celeste/modalities/audio/providers/google/client.py +++ b/src/celeste/modalities/audio/providers/google/client.py @@ -9,6 +9,7 @@ from celeste.providers.google.cloud_tts.client import ( GoogleCloudTTSClient as GoogleCloudTTSMixin, ) +from celeste.types import AudioContent from ...client import AudioClient from ...io import ( @@ -23,7 +24,7 @@ class GoogleAudioClient(GoogleCloudTTSMixin, AudioClient): """Google audio client (Cloud TTS).""" @classmethod - def parameter_mappers(cls) -> list[ParameterMapper]: + def parameter_mappers(cls) -> list[ParameterMapper[AudioContent]]: return GOOGLE_PARAMETER_MAPPERS async def speak( diff --git a/src/celeste/modalities/audio/providers/google/parameters.py b/src/celeste/modalities/audio/providers/google/parameters.py index 2083ba19..437f4769 100644 --- a/src/celeste/modalities/audio/providers/google/parameters.py +++ b/src/celeste/modalities/audio/providers/google/parameters.py @@ -13,6 +13,7 @@ from celeste.providers.google.cloud_tts.parameters import ( VoiceMapper as _VoiceMapper, ) +from celeste.types import AudioContent from ...parameters import AudioParameter @@ -63,7 +64,7 @@ class OutputFormatMapper(_AudioEncodingMapper): } -GOOGLE_PARAMETER_MAPPERS: list[ParameterMapper] = [ +GOOGLE_PARAMETER_MAPPERS: list[ParameterMapper[AudioContent]] = [ VoiceMapper(), LanguageMapper(), OutputFormatMapper(), diff --git a/src/celeste/modalities/audio/providers/gradium/client.py b/src/celeste/modalities/audio/providers/gradium/client.py index 029a03e4..7ed7c061 100644 --- a/src/celeste/modalities/audio/providers/gradium/client.py +++ b/src/celeste/modalities/audio/providers/gradium/client.py @@ -11,6 +11,7 @@ from celeste.providers.gradium.text_to_speech.streaming import ( GradiumTextToSpeechStream as _GradiumTextToSpeechStream, ) +from celeste.types import AudioContent from ...client import AudioClient from ...io import ( @@ -40,7 +41,7 @@ class GradiumAudioClient(GradiumTextToSpeechMixin, AudioClient): """Gradium audio client (TTS).""" @classmethod - def parameter_mappers(cls) -> list[ParameterMapper]: + def parameter_mappers(cls) -> list[ParameterMapper[AudioContent]]: return GRADIUM_PARAMETER_MAPPERS async def speak( diff --git a/src/celeste/modalities/audio/providers/gradium/parameters.py b/src/celeste/modalities/audio/providers/gradium/parameters.py index 4d8ff942..e3e4f686 100644 --- a/src/celeste/modalities/audio/providers/gradium/parameters.py +++ b/src/celeste/modalities/audio/providers/gradium/parameters.py @@ -7,6 +7,7 @@ from celeste.providers.gradium.text_to_speech.parameters import ( VoiceMapper as _VoiceMapper, ) +from celeste.types import AudioContent from ...parameters import AudioParameter @@ -23,7 +24,7 @@ class OutputFormatMapper(_OutputFormatMapper): name = AudioParameter.OUTPUT_FORMAT -GRADIUM_PARAMETER_MAPPERS: list[ParameterMapper] = [ +GRADIUM_PARAMETER_MAPPERS: list[ParameterMapper[AudioContent]] = [ VoiceMapper(), OutputFormatMapper(), ] diff --git a/src/celeste/modalities/audio/providers/openai/client.py b/src/celeste/modalities/audio/providers/openai/client.py index e712f1e8..bd7daeed 100644 --- a/src/celeste/modalities/audio/providers/openai/client.py +++ b/src/celeste/modalities/audio/providers/openai/client.py @@ -6,6 +6,7 @@ from celeste.parameters import ParameterMapper from celeste.providers.openai.audio import config from celeste.providers.openai.audio.client import OpenAIAudioClient as OpenAIAudioMixin +from celeste.types import AudioContent from ...client import AudioClient from ...io import AudioFinishReason, AudioInput, AudioOutput @@ -17,7 +18,7 @@ class OpenAIAudioClient(OpenAIAudioMixin, AudioClient): """OpenAI audio client (TTS).""" @classmethod - def parameter_mappers(cls) -> list[ParameterMapper]: + def parameter_mappers(cls) -> list[ParameterMapper[AudioContent]]: return OPENAI_PARAMETER_MAPPERS async def speak( diff --git a/src/celeste/modalities/audio/providers/openai/parameters.py b/src/celeste/modalities/audio/providers/openai/parameters.py index 5754f960..80a0cc53 100644 --- a/src/celeste/modalities/audio/providers/openai/parameters.py +++ b/src/celeste/modalities/audio/providers/openai/parameters.py @@ -10,6 +10,7 @@ from celeste.providers.openai.audio.parameters import ( VoiceMapper as _VoiceMapper, ) +from celeste.types import AudioContent from ...parameters import AudioParameter @@ -32,7 +33,7 @@ class OutputFormatMapper(_ResponseFormatMapper): name = AudioParameter.OUTPUT_FORMAT -OPENAI_PARAMETER_MAPPERS: list[ParameterMapper] = [ +OPENAI_PARAMETER_MAPPERS: list[ParameterMapper[AudioContent]] = [ VoiceMapper(), SpeedMapper(), OutputFormatMapper(), diff --git a/src/celeste/modalities/embeddings/providers/google/client.py b/src/celeste/modalities/embeddings/providers/google/client.py index 39bfff97..aa857cad 100644 --- a/src/celeste/modalities/embeddings/providers/google/client.py +++ b/src/celeste/modalities/embeddings/providers/google/client.py @@ -18,7 +18,7 @@ class GoogleEmbeddingsClient(GoogleEmbeddingsMixin, EmbeddingsClient): """Google embeddings client.""" @classmethod - def parameter_mappers(cls) -> list[ParameterMapper]: + def parameter_mappers(cls) -> list[ParameterMapper[EmbeddingsContent]]: """Return parameter mappers for Google embeddings.""" return GOOGLE_PARAMETER_MAPPERS diff --git a/src/celeste/modalities/embeddings/providers/google/parameters.py b/src/celeste/modalities/embeddings/providers/google/parameters.py index 639ae14c..664b307d 100644 --- a/src/celeste/modalities/embeddings/providers/google/parameters.py +++ b/src/celeste/modalities/embeddings/providers/google/parameters.py @@ -4,6 +4,7 @@ from celeste.providers.google.embeddings.parameters import ( OutputDimensionalityMapper as _OutputDimensionalityMapper, ) +from celeste.types import EmbeddingsContent from ...parameters import EmbeddingsParameter @@ -14,7 +15,7 @@ class DimensionsMapper(_OutputDimensionalityMapper): name = EmbeddingsParameter.DIMENSIONS -GOOGLE_PARAMETER_MAPPERS: list[ParameterMapper] = [ +GOOGLE_PARAMETER_MAPPERS: list[ParameterMapper[EmbeddingsContent]] = [ DimensionsMapper(), ] diff --git a/src/celeste/modalities/images/providers/bfl/client.py b/src/celeste/modalities/images/providers/bfl/client.py index 6842afd2..73a9d949 100644 --- a/src/celeste/modalities/images/providers/bfl/client.py +++ b/src/celeste/modalities/images/providers/bfl/client.py @@ -7,6 +7,7 @@ from celeste.providers.bfl.images import config as bfl_config from celeste.providers.bfl.images.client import BFLImagesClient as _BFLImagesClient from celeste.providers.bfl.images.utils import encode_image +from celeste.types import ImageContent from ...client import ImagesClient from ...io import ImageFinishReason, ImageInput, ImageOutput @@ -18,7 +19,7 @@ class BFLImagesClient(_BFLImagesClient, ImagesClient): """BFL images client (generate + edit).""" @classmethod - def parameter_mappers(cls) -> list[ParameterMapper]: + def parameter_mappers(cls) -> list[ParameterMapper[ImageContent]]: return BFL_PARAMETER_MAPPERS async def generate( diff --git a/src/celeste/modalities/images/providers/bfl/parameters.py b/src/celeste/modalities/images/providers/bfl/parameters.py index f5c64c5e..187d53ed 100644 --- a/src/celeste/modalities/images/providers/bfl/parameters.py +++ b/src/celeste/modalities/images/providers/bfl/parameters.py @@ -29,11 +29,12 @@ WidthMapper as _WidthMapper, ) from celeste.providers.bfl.images.utils import add_reference_images +from celeste.types import ImageContent from ...parameters import ImageParameter -class AspectRatioMapper(ParameterMapper): +class AspectRatioMapper(ParameterMapper[ImageContent]): """Map aspect_ratio to BFL width/height parameters. Converts 'WxH' string to width/height, rounded to nearest multiple of 16. @@ -91,7 +92,7 @@ class GuidanceMapper(_GuidanceMapper): name = ImageParameter.GUIDANCE -class ReferenceImagesMapper(ParameterMapper): +class ReferenceImagesMapper(ParameterMapper[ImageContent]): name = ImageParameter.REFERENCE_IMAGES def map( @@ -108,7 +109,7 @@ def map( return add_reference_images(request, validated_value) -BFL_PARAMETER_MAPPERS: list[ParameterMapper] = [ +BFL_PARAMETER_MAPPERS: list[ParameterMapper[ImageContent]] = [ AspectRatioMapper(), PromptUpsamplingMapper(), SeedMapper(), diff --git a/src/celeste/modalities/images/providers/byteplus/client.py b/src/celeste/modalities/images/providers/byteplus/client.py index 7827381f..97ec1dd1 100644 --- a/src/celeste/modalities/images/providers/byteplus/client.py +++ b/src/celeste/modalities/images/providers/byteplus/client.py @@ -13,6 +13,7 @@ from celeste.providers.byteplus.images.streaming import ( BytePlusImagesStream as _BytePlusImagesStream, ) +from celeste.types import ImageContent from ...client import ImagesClient from ...io import ( @@ -94,7 +95,7 @@ class BytePlusImagesClient(BytePlusImagesMixin, ImagesClient): """BytePlus images client (generate + streaming).""" @classmethod - def parameter_mappers(cls) -> list[ParameterMapper]: + def parameter_mappers(cls) -> list[ParameterMapper[ImageContent]]: return BYTEPLUS_PARAMETER_MAPPERS async def generate( diff --git a/src/celeste/modalities/images/providers/byteplus/parameters.py b/src/celeste/modalities/images/providers/byteplus/parameters.py index 9942fc78..a74cb55e 100644 --- a/src/celeste/modalities/images/providers/byteplus/parameters.py +++ b/src/celeste/modalities/images/providers/byteplus/parameters.py @@ -7,6 +7,7 @@ from celeste.providers.byteplus.images.parameters import ( WatermarkMapper as _WatermarkMapper, ) +from celeste.types import ImageContent from ...parameters import ImageParameter @@ -25,7 +26,7 @@ class WatermarkMapper(_WatermarkMapper): name = ImageParameter.WATERMARK -BYTEPLUS_PARAMETER_MAPPERS: list[ParameterMapper] = [ +BYTEPLUS_PARAMETER_MAPPERS: list[ParameterMapper[ImageContent]] = [ AspectRatioMapper(), QualityMapper(), WatermarkMapper(), diff --git a/src/celeste/modalities/images/providers/google/client.py b/src/celeste/modalities/images/providers/google/client.py index 5f2d3a89..bf16bebd 100644 --- a/src/celeste/modalities/images/providers/google/client.py +++ b/src/celeste/modalities/images/providers/google/client.py @@ -44,7 +44,7 @@ def model_post_init(self, __context: object) -> None: object.__setattr__(self, "_strategy", strategy) @classmethod - def parameter_mappers(cls) -> list[ParameterMapper]: + def parameter_mappers(cls) -> list[ParameterMapper[ImageContent]]: return [*GEMINI_PARAMETER_MAPPERS, *IMAGEN_PARAMETER_MAPPERS] async def generate( diff --git a/src/celeste/modalities/images/providers/google/gemini.py b/src/celeste/modalities/images/providers/google/gemini.py index 51f333df..530342b3 100644 --- a/src/celeste/modalities/images/providers/google/gemini.py +++ b/src/celeste/modalities/images/providers/google/gemini.py @@ -44,7 +44,7 @@ class GeminiImagesClient(GoogleGenerateContentClient, ImagesClient): """Google Gemini client for images modality (generate + edit).""" @classmethod - def parameter_mappers(cls) -> list[ParameterMapper]: + def parameter_mappers(cls) -> list[ParameterMapper[ImageContent]]: return GEMINI_PARAMETER_MAPPERS async def generate( diff --git a/src/celeste/modalities/images/providers/google/imagen.py b/src/celeste/modalities/images/providers/google/imagen.py index c415fc33..d2faa1a7 100644 --- a/src/celeste/modalities/images/providers/google/imagen.py +++ b/src/celeste/modalities/images/providers/google/imagen.py @@ -19,7 +19,7 @@ class ImagenImagesClient(GoogleImagenClient, ImagesClient): """Google Imagen client for images modality (generate).""" @classmethod - def parameter_mappers(cls) -> list[ParameterMapper]: + def parameter_mappers(cls) -> list[ParameterMapper[ImageContent]]: return IMAGEN_PARAMETER_MAPPERS async def generate( diff --git a/src/celeste/modalities/images/providers/google/parameters.py b/src/celeste/modalities/images/providers/google/parameters.py index 5c15e730..5feb4c0b 100644 --- a/src/celeste/modalities/images/providers/google/parameters.py +++ b/src/celeste/modalities/images/providers/google/parameters.py @@ -19,6 +19,7 @@ from celeste.providers.google.imagen.parameters import ( SampleCountMapper as _ImagenSampleCountMapper, ) +from celeste.types import ImageContent from ...parameters import ImageParameter @@ -41,32 +42,32 @@ class ImagenNumImagesMapper(_ImagenSampleCountMapper): name = ImageParameter.NUM_IMAGES -IMAGEN_PARAMETER_MAPPERS: list[ParameterMapper] = [ +IMAGEN_PARAMETER_MAPPERS: list[ParameterMapper[ImageContent]] = [ ImagenAspectRatioMapper(), ImagenQualityMapper(), ImagenNumImagesMapper(), ] -class GeminiAspectRatioMapper(_GeminiAspectRatioMapper): +class GeminiAspectRatioMapper(_GeminiAspectRatioMapper[ImageContent]): """Map aspect_ratio to Gemini generationConfig.imageConfig.aspectRatio.""" name = ImageParameter.ASPECT_RATIO -class GeminiQualityMapper(_GeminiImageSizeMapper): +class GeminiQualityMapper(_GeminiImageSizeMapper[ImageContent]): """Map quality to Gemini generationConfig.imageConfig.imageSize.""" name = ImageParameter.QUALITY -class GeminiReferenceImagesMapper(_GeminiMediaContentMapper): +class GeminiReferenceImagesMapper(_GeminiMediaContentMapper[ImageContent]): """Map reference_images to Gemini contents.parts.""" name = ImageParameter.REFERENCE_IMAGES -GEMINI_PARAMETER_MAPPERS: list[ParameterMapper] = [ +GEMINI_PARAMETER_MAPPERS: list[ParameterMapper[ImageContent]] = [ GeminiAspectRatioMapper(), GeminiQualityMapper(), GeminiReferenceImagesMapper(), diff --git a/src/celeste/modalities/images/providers/ollama/client.py b/src/celeste/modalities/images/providers/ollama/client.py index d1bbf264..c600c7c3 100644 --- a/src/celeste/modalities/images/providers/ollama/client.py +++ b/src/celeste/modalities/images/providers/ollama/client.py @@ -9,6 +9,7 @@ from celeste.providers.ollama.generate.streaming import ( OllamaGenerateStream as _OllamaGenerateStream, ) +from celeste.types import ImageContent from ...client import ImagesClient from ...io import ( @@ -54,7 +55,7 @@ class OllamaImagesClient(OllamaGenerateClient, ImagesClient): """Ollama images client (generate only, no edit support yet).""" @classmethod - def parameter_mappers(cls) -> list[ParameterMapper]: + def parameter_mappers(cls) -> list[ParameterMapper[ImageContent]]: return OLLAMA_PARAMETER_MAPPERS async def generate( diff --git a/src/celeste/modalities/images/providers/ollama/parameters.py b/src/celeste/modalities/images/providers/ollama/parameters.py index c91b9e24..02e5748b 100644 --- a/src/celeste/modalities/images/providers/ollama/parameters.py +++ b/src/celeste/modalities/images/providers/ollama/parameters.py @@ -19,11 +19,12 @@ from celeste.providers.ollama.generate.parameters import ( WidthMapper as _WidthMapper, ) +from celeste.types import ImageContent from ...parameters import ImageParameter -class AspectRatioMapper(ParameterMapper): +class AspectRatioMapper(ParameterMapper[ImageContent]): """Map aspect_ratio to Ollama's width and height parameters. Parses 'WxH' string and delegates to native mappers. @@ -69,7 +70,7 @@ class NegativePromptMapper(_NegativePromptMapper): name = ImageParameter.NEGATIVE_PROMPT -OLLAMA_PARAMETER_MAPPERS: list[ParameterMapper] = [ +OLLAMA_PARAMETER_MAPPERS: list[ParameterMapper[ImageContent]] = [ AspectRatioMapper(), StepsMapper(), SeedMapper(), diff --git a/src/celeste/modalities/images/providers/openai/client.py b/src/celeste/modalities/images/providers/openai/client.py index e440bf79..325e04c9 100644 --- a/src/celeste/modalities/images/providers/openai/client.py +++ b/src/celeste/modalities/images/providers/openai/client.py @@ -11,6 +11,7 @@ from celeste.providers.openai.images.streaming import ( OpenAIImagesStream as _OpenAIImagesStream, ) +from celeste.types import ImageContent from ...client import ImagesClient from ...io import ( @@ -35,7 +36,7 @@ class OpenAIImagesClient(OpenAIImagesMixin, ImagesClient): """OpenAI images client.""" @classmethod - def parameter_mappers(cls) -> list[ParameterMapper]: + def parameter_mappers(cls) -> list[ParameterMapper[ImageContent]]: return OPENAI_PARAMETER_MAPPERS def _init_request(self, inputs: ImageInput) -> dict[str, Any]: diff --git a/src/celeste/modalities/images/providers/openai/parameters.py b/src/celeste/modalities/images/providers/openai/parameters.py index 84485d6c..4896f16c 100644 --- a/src/celeste/modalities/images/providers/openai/parameters.py +++ b/src/celeste/modalities/images/providers/openai/parameters.py @@ -10,6 +10,7 @@ from celeste.providers.openai.images.parameters import ( SizeMapper as _SizeMapper, ) +from celeste.types import ImageContent from ...parameters import ImageParameter @@ -32,7 +33,7 @@ class QualityMapper(_QualityMapper): name = ImageParameter.QUALITY -OPENAI_PARAMETER_MAPPERS: list[ParameterMapper] = [ +OPENAI_PARAMETER_MAPPERS: list[ParameterMapper[ImageContent]] = [ AspectRatioMapper(), PartialImagesMapper(), QualityMapper(), diff --git a/src/celeste/modalities/images/providers/xai/client.py b/src/celeste/modalities/images/providers/xai/client.py index 6c27e0ee..1b10e2ab 100644 --- a/src/celeste/modalities/images/providers/xai/client.py +++ b/src/celeste/modalities/images/providers/xai/client.py @@ -6,6 +6,7 @@ from celeste.parameters import ParameterMapper from celeste.providers.xai.images import config from celeste.providers.xai.images.client import XAIImagesClient as XAIImagesMixin +from celeste.types import ImageContent from ...client import ImagesClient from ...io import ( @@ -20,7 +21,7 @@ class XAIImagesClient(XAIImagesMixin, ImagesClient): """xAI images client.""" @classmethod - def parameter_mappers(cls) -> list[ParameterMapper]: + def parameter_mappers(cls) -> list[ParameterMapper[ImageContent]]: return XAI_PARAMETER_MAPPERS def _init_request(self, inputs: ImageInput) -> dict[str, Any]: diff --git a/src/celeste/modalities/images/providers/xai/parameters.py b/src/celeste/modalities/images/providers/xai/parameters.py index 3078a095..edb77d08 100644 --- a/src/celeste/modalities/images/providers/xai/parameters.py +++ b/src/celeste/modalities/images/providers/xai/parameters.py @@ -10,6 +10,7 @@ from celeste.providers.xai.images.parameters import ( ResponseFormatMapper as _ResponseFormatMapper, ) +from celeste.types import ImageContent from ...parameters import ImageParameter @@ -32,7 +33,7 @@ class OutputFormatMapper(_ResponseFormatMapper): name = ImageParameter.OUTPUT_FORMAT -XAI_PARAMETER_MAPPERS: list[ParameterMapper] = [ +XAI_PARAMETER_MAPPERS: list[ParameterMapper[ImageContent]] = [ AspectRatioMapper(), NumImagesMapper(), OutputFormatMapper(), diff --git a/src/celeste/modalities/text/providers/anthropic/client.py b/src/celeste/modalities/text/providers/anthropic/client.py index e28b289d..05be71bb 100644 --- a/src/celeste/modalities/text/providers/anthropic/client.py +++ b/src/celeste/modalities/text/providers/anthropic/client.py @@ -54,7 +54,7 @@ class AnthropicTextClient(AnthropicMessagesClient, TextClient): """Anthropic text client.""" @classmethod - def parameter_mappers(cls) -> list[ParameterMapper]: + def parameter_mappers(cls) -> list[ParameterMapper[TextContent]]: return ANTHROPIC_PARAMETER_MAPPERS async def generate( diff --git a/src/celeste/modalities/text/providers/anthropic/parameters.py b/src/celeste/modalities/text/providers/anthropic/parameters.py index 3c29d718..0470a3f8 100644 --- a/src/celeste/modalities/text/providers/anthropic/parameters.py +++ b/src/celeste/modalities/text/providers/anthropic/parameters.py @@ -19,6 +19,7 @@ from celeste.providers.anthropic.messages.parameters import ( WebSearchMapper as _WebSearchMapper, ) +from celeste.types import TextContent from ...parameters import TextParameter @@ -72,7 +73,7 @@ class WebSearchMapper(_WebSearchMapper): name = TextParameter.WEB_SEARCH -ANTHROPIC_PARAMETER_MAPPERS: list[ParameterMapper] = [ +ANTHROPIC_PARAMETER_MAPPERS: list[ParameterMapper[TextContent]] = [ TemperatureMapper(), MaxTokensMapper(), ThinkingBudgetMapper(), diff --git a/src/celeste/modalities/text/providers/cohere/client.py b/src/celeste/modalities/text/providers/cohere/client.py index cdfb793f..8f3fd25a 100644 --- a/src/celeste/modalities/text/providers/cohere/client.py +++ b/src/celeste/modalities/text/providers/cohere/client.py @@ -28,7 +28,7 @@ class CohereTextClient(CohereChatClient, TextClient): """Cohere text client.""" @classmethod - def parameter_mappers(cls) -> list[ParameterMapper]: + def parameter_mappers(cls) -> list[ParameterMapper[TextContent]]: return COHERE_PARAMETER_MAPPERS async def generate( diff --git a/src/celeste/modalities/text/providers/cohere/parameters.py b/src/celeste/modalities/text/providers/cohere/parameters.py index 726e6605..94b328e9 100644 --- a/src/celeste/modalities/text/providers/cohere/parameters.py +++ b/src/celeste/modalities/text/providers/cohere/parameters.py @@ -16,6 +16,7 @@ from celeste.providers.cohere.chat.parameters import ( ThinkingMapper as _ThinkingMapper, ) +from celeste.types import TextContent from ...parameters import TextParameter @@ -65,7 +66,7 @@ class OutputSchemaMapper(_ResponseFormatMapper): name = TextParameter.OUTPUT_SCHEMA -COHERE_PARAMETER_MAPPERS: list[ParameterMapper] = [ +COHERE_PARAMETER_MAPPERS: list[ParameterMapper[TextContent]] = [ TemperatureMapper(), MaxTokensMapper(), ThinkingBudgetMapper(), diff --git a/src/celeste/modalities/text/providers/deepseek/client.py b/src/celeste/modalities/text/providers/deepseek/client.py index 40e6010e..356c1003 100644 --- a/src/celeste/modalities/text/providers/deepseek/client.py +++ b/src/celeste/modalities/text/providers/deepseek/client.py @@ -27,7 +27,7 @@ class DeepSeekTextClient(DeepSeekChatClient, TextClient): """DeepSeek text client.""" @classmethod - def parameter_mappers(cls) -> list[ParameterMapper]: + def parameter_mappers(cls) -> list[ParameterMapper[TextContent]]: return DEEPSEEK_PARAMETER_MAPPERS async def generate( diff --git a/src/celeste/modalities/text/providers/deepseek/parameters.py b/src/celeste/modalities/text/providers/deepseek/parameters.py index 4dd6bd27..f5e65101 100644 --- a/src/celeste/modalities/text/providers/deepseek/parameters.py +++ b/src/celeste/modalities/text/providers/deepseek/parameters.py @@ -10,6 +10,7 @@ from celeste.protocols.chatcompletions.parameters import ( TemperatureMapper as _TemperatureMapper, ) +from celeste.types import TextContent from ...parameters import TextParameter @@ -32,7 +33,7 @@ class OutputSchemaMapper(_ResponseFormatMapper): name = TextParameter.OUTPUT_SCHEMA -DEEPSEEK_PARAMETER_MAPPERS: list[ParameterMapper] = [ +DEEPSEEK_PARAMETER_MAPPERS: list[ParameterMapper[TextContent]] = [ TemperatureMapper(), MaxTokensMapper(), OutputSchemaMapper(), diff --git a/src/celeste/modalities/text/providers/google/client.py b/src/celeste/modalities/text/providers/google/client.py index 0d3f0236..d418be5a 100644 --- a/src/celeste/modalities/text/providers/google/client.py +++ b/src/celeste/modalities/text/providers/google/client.py @@ -31,7 +31,7 @@ class GoogleTextClient(GoogleGenerateContentClient, TextClient): """Google text client.""" @classmethod - def parameter_mappers(cls) -> list[ParameterMapper]: + def parameter_mappers(cls) -> list[ParameterMapper[TextContent]]: return GOOGLE_PARAMETER_MAPPERS async def generate( diff --git a/src/celeste/modalities/text/providers/google/parameters.py b/src/celeste/modalities/text/providers/google/parameters.py index 2a61e808..d9a0702e 100644 --- a/src/celeste/modalities/text/providers/google/parameters.py +++ b/src/celeste/modalities/text/providers/google/parameters.py @@ -19,29 +19,30 @@ from celeste.providers.google.generate_content.parameters import ( WebSearchMapper as _WebSearchMapper, ) +from celeste.types import TextContent from ...parameters import TextParameter -class TemperatureMapper(_TemperatureMapper): +class TemperatureMapper(_TemperatureMapper[TextContent]): """Map temperature to Google's generationConfig.temperature parameter.""" name = TextParameter.TEMPERATURE -class MaxTokensMapper(_MaxOutputTokensMapper): +class MaxTokensMapper(_MaxOutputTokensMapper[TextContent]): """Map max_tokens to Google's generationConfig.maxOutputTokens parameter.""" name = TextParameter.MAX_TOKENS -class ThinkingBudgetMapper(_ThinkingBudgetMapper): +class ThinkingBudgetMapper(_ThinkingBudgetMapper[TextContent]): """Map thinking_budget to Google's generationConfig.thinkingConfig.thinkingBudget parameter.""" name = TextParameter.THINKING_BUDGET -class ThinkingLevelMapper(_ThinkingLevelMapper): +class ThinkingLevelMapper(_ThinkingLevelMapper[TextContent]): """Map thinking_level to Google's generationConfig.thinkingConfig.thinkingLevel parameter.""" name = TextParameter.THINKING_LEVEL @@ -53,13 +54,13 @@ class OutputSchemaMapper(_ResponseJsonSchemaMapper): name = TextParameter.OUTPUT_SCHEMA -class WebSearchMapper(_WebSearchMapper): +class WebSearchMapper(_WebSearchMapper[TextContent]): """Map web_search to Google's tools parameter.""" name = TextParameter.WEB_SEARCH -GOOGLE_PARAMETER_MAPPERS: list[ParameterMapper] = [ +GOOGLE_PARAMETER_MAPPERS: list[ParameterMapper[TextContent]] = [ TemperatureMapper(), MaxTokensMapper(), ThinkingBudgetMapper(), diff --git a/src/celeste/modalities/text/providers/groq/client.py b/src/celeste/modalities/text/providers/groq/client.py index b48ea373..97b6d4dc 100644 --- a/src/celeste/modalities/text/providers/groq/client.py +++ b/src/celeste/modalities/text/providers/groq/client.py @@ -26,7 +26,7 @@ class GroqTextClient(GroqChatClient, TextClient): """Groq text client.""" @classmethod - def parameter_mappers(cls) -> list[ParameterMapper]: + def parameter_mappers(cls) -> list[ParameterMapper[TextContent]]: return GROQ_PARAMETER_MAPPERS async def generate( diff --git a/src/celeste/modalities/text/providers/groq/parameters.py b/src/celeste/modalities/text/providers/groq/parameters.py index 0a55f443..d1ce11ce 100644 --- a/src/celeste/modalities/text/providers/groq/parameters.py +++ b/src/celeste/modalities/text/providers/groq/parameters.py @@ -10,6 +10,7 @@ from celeste.providers.groq.chat.parameters import ( ResponseFormatMapper as _ResponseFormatMapper, ) +from celeste.types import TextContent from ...parameters import TextParameter @@ -32,7 +33,7 @@ class OutputSchemaMapper(_ResponseFormatMapper): name = TextParameter.OUTPUT_SCHEMA -GROQ_PARAMETER_MAPPERS: list[ParameterMapper] = [ +GROQ_PARAMETER_MAPPERS: list[ParameterMapper[TextContent]] = [ TemperatureMapper(), MaxTokensMapper(), OutputSchemaMapper(), diff --git a/src/celeste/modalities/text/providers/huggingface/client.py b/src/celeste/modalities/text/providers/huggingface/client.py index c403c07d..d586198d 100644 --- a/src/celeste/modalities/text/providers/huggingface/client.py +++ b/src/celeste/modalities/text/providers/huggingface/client.py @@ -28,7 +28,7 @@ class HuggingFaceTextClient(HuggingFaceChatClient, TextClient): """HuggingFace text client.""" @classmethod - def parameter_mappers(cls) -> list[ParameterMapper]: + def parameter_mappers(cls) -> list[ParameterMapper[TextContent]]: return HUGGINGFACE_PARAMETER_MAPPERS async def generate( diff --git a/src/celeste/modalities/text/providers/huggingface/parameters.py b/src/celeste/modalities/text/providers/huggingface/parameters.py index bd0aa238..c03adb46 100644 --- a/src/celeste/modalities/text/providers/huggingface/parameters.py +++ b/src/celeste/modalities/text/providers/huggingface/parameters.py @@ -10,6 +10,7 @@ from celeste.providers.huggingface.chat.parameters import ( ResponseFormatMapper as _ResponseFormatMapper, ) +from celeste.types import TextContent from ...parameters import TextParameter @@ -32,7 +33,7 @@ class OutputSchemaMapper(_ResponseFormatMapper): name = TextParameter.OUTPUT_SCHEMA -HUGGINGFACE_PARAMETER_MAPPERS: list[ParameterMapper] = [ +HUGGINGFACE_PARAMETER_MAPPERS: list[ParameterMapper[TextContent]] = [ TemperatureMapper(), MaxTokensMapper(), OutputSchemaMapper(), diff --git a/src/celeste/modalities/text/providers/mistral/client.py b/src/celeste/modalities/text/providers/mistral/client.py index 2a30fc88..cf621e83 100644 --- a/src/celeste/modalities/text/providers/mistral/client.py +++ b/src/celeste/modalities/text/providers/mistral/client.py @@ -28,7 +28,7 @@ class MistralTextClient(MistralChatClient, TextClient): """Mistral text client.""" @classmethod - def parameter_mappers(cls) -> list[ParameterMapper]: + def parameter_mappers(cls) -> list[ParameterMapper[TextContent]]: return MISTRAL_PARAMETER_MAPPERS async def generate( diff --git a/src/celeste/modalities/text/providers/mistral/parameters.py b/src/celeste/modalities/text/providers/mistral/parameters.py index 1f545d5a..fc96729c 100644 --- a/src/celeste/modalities/text/providers/mistral/parameters.py +++ b/src/celeste/modalities/text/providers/mistral/parameters.py @@ -13,6 +13,7 @@ from celeste.providers.mistral.chat.parameters import ( ResponseFormatMapper as _ResponseFormatMapper, ) +from celeste.types import TextContent from ...parameters import TextParameter @@ -29,7 +30,7 @@ class MaxTokensMapper(_MaxTokensMapper): name = TextParameter.MAX_TOKENS -class ThinkingBudgetMapper(ParameterMapper): +class ThinkingBudgetMapper(ParameterMapper[TextContent]): """Map thinking_budget to Mistral's prompt_mode parameter.""" name = TextParameter.THINKING_BUDGET @@ -62,7 +63,7 @@ class OutputSchemaMapper(_ResponseFormatMapper): name = TextParameter.OUTPUT_SCHEMA -MISTRAL_PARAMETER_MAPPERS: list[ParameterMapper] = [ +MISTRAL_PARAMETER_MAPPERS: list[ParameterMapper[TextContent]] = [ TemperatureMapper(), MaxTokensMapper(), ThinkingBudgetMapper(), diff --git a/src/celeste/modalities/text/providers/moonshot/client.py b/src/celeste/modalities/text/providers/moonshot/client.py index 165d72e3..9640d6e8 100644 --- a/src/celeste/modalities/text/providers/moonshot/client.py +++ b/src/celeste/modalities/text/providers/moonshot/client.py @@ -28,7 +28,7 @@ class MoonshotTextClient(MoonshotChatClient, TextClient): """Moonshot text client.""" @classmethod - def parameter_mappers(cls) -> list[ParameterMapper]: + def parameter_mappers(cls) -> list[ParameterMapper[TextContent]]: return MOONSHOT_PARAMETER_MAPPERS async def generate( diff --git a/src/celeste/modalities/text/providers/moonshot/parameters.py b/src/celeste/modalities/text/providers/moonshot/parameters.py index 3a232519..480cf175 100644 --- a/src/celeste/modalities/text/providers/moonshot/parameters.py +++ b/src/celeste/modalities/text/providers/moonshot/parameters.py @@ -10,6 +10,7 @@ from celeste.protocols.chatcompletions.parameters import ( TemperatureMapper as _TemperatureMapper, ) +from celeste.types import TextContent from ...parameters import TextParameter @@ -32,7 +33,7 @@ class OutputSchemaMapper(_ResponseFormatMapper): name = TextParameter.OUTPUT_SCHEMA -MOONSHOT_PARAMETER_MAPPERS: list[ParameterMapper] = [ +MOONSHOT_PARAMETER_MAPPERS: list[ParameterMapper[TextContent]] = [ TemperatureMapper(), MaxTokensMapper(), OutputSchemaMapper(), diff --git a/src/celeste/modalities/text/providers/openai/client.py b/src/celeste/modalities/text/providers/openai/client.py index 51156916..175c2cfa 100644 --- a/src/celeste/modalities/text/providers/openai/client.py +++ b/src/celeste/modalities/text/providers/openai/client.py @@ -31,7 +31,7 @@ class OpenAITextClient(OpenAIResponsesMixin, TextClient): """OpenAI text client using Responses API.""" @classmethod - def parameter_mappers(cls) -> list[ParameterMapper]: + def parameter_mappers(cls) -> list[ParameterMapper[TextContent]]: return OPENAI_PARAMETER_MAPPERS async def generate( diff --git a/src/celeste/modalities/text/providers/openai/parameters.py b/src/celeste/modalities/text/providers/openai/parameters.py index c13b2c53..96b6381b 100644 --- a/src/celeste/modalities/text/providers/openai/parameters.py +++ b/src/celeste/modalities/text/providers/openai/parameters.py @@ -19,6 +19,7 @@ from celeste.protocols.openresponses.parameters import ( WebSearchMapper as _WebSearchMapper, ) +from celeste.types import TextContent from ...parameters import TextParameter @@ -59,7 +60,7 @@ class ThinkingBudgetMapper(_ReasoningEffortMapper): name = TextParameter.THINKING_BUDGET -OPENAI_PARAMETER_MAPPERS: list[ParameterMapper] = [ +OPENAI_PARAMETER_MAPPERS: list[ParameterMapper[TextContent]] = [ TemperatureMapper(), MaxTokensMapper(), OutputSchemaMapper(), diff --git a/src/celeste/modalities/text/providers/openresponses/client.py b/src/celeste/modalities/text/providers/openresponses/client.py index 0185c1fc..6fc23c3a 100644 --- a/src/celeste/modalities/text/providers/openresponses/client.py +++ b/src/celeste/modalities/text/providers/openresponses/client.py @@ -52,7 +52,7 @@ class OpenResponsesTextClient(OpenResponsesMixin, TextClient): """OpenResponses text client using Responses API.""" @classmethod - def parameter_mappers(cls) -> list[ParameterMapper]: + def parameter_mappers(cls) -> list[ParameterMapper[TextContent]]: return OPENRESPONSES_PARAMETER_MAPPERS async def generate( diff --git a/src/celeste/modalities/text/providers/openresponses/parameters.py b/src/celeste/modalities/text/providers/openresponses/parameters.py index 52305abe..378237bd 100644 --- a/src/celeste/modalities/text/providers/openresponses/parameters.py +++ b/src/celeste/modalities/text/providers/openresponses/parameters.py @@ -10,6 +10,7 @@ from celeste.protocols.openresponses.parameters import ( TextFormatMapper as _TextFormatMapper, ) +from celeste.types import TextContent from ...parameters import TextParameter @@ -32,7 +33,7 @@ class OutputSchemaMapper(_TextFormatMapper): name = TextParameter.OUTPUT_SCHEMA -OPENRESPONSES_PARAMETER_MAPPERS: list[ParameterMapper] = [ +OPENRESPONSES_PARAMETER_MAPPERS: list[ParameterMapper[TextContent]] = [ TemperatureMapper(), MaxTokensMapper(), OutputSchemaMapper(), diff --git a/src/celeste/modalities/text/providers/xai/client.py b/src/celeste/modalities/text/providers/xai/client.py index 91f0ad07..71dfc4c0 100644 --- a/src/celeste/modalities/text/providers/xai/client.py +++ b/src/celeste/modalities/text/providers/xai/client.py @@ -29,7 +29,7 @@ class XAITextClient(XAIResponsesClient, TextClient): """xAI text client.""" @classmethod - def parameter_mappers(cls) -> list[ParameterMapper]: + def parameter_mappers(cls) -> list[ParameterMapper[TextContent]]: return XAI_PARAMETER_MAPPERS async def generate( diff --git a/src/celeste/modalities/text/providers/xai/parameters.py b/src/celeste/modalities/text/providers/xai/parameters.py index 7b1b88ce..064d79fc 100644 --- a/src/celeste/modalities/text/providers/xai/parameters.py +++ b/src/celeste/modalities/text/providers/xai/parameters.py @@ -22,6 +22,7 @@ from celeste.protocols.openresponses.parameters import ( XSearchMapper as _XSearchMapper, ) +from celeste.types import TextContent from ...parameters import TextParameter @@ -68,7 +69,7 @@ class CodeExecutionMapper(_CodeExecutionMapper): name = TextParameter.CODE_EXECUTION -XAI_PARAMETER_MAPPERS: list[ParameterMapper] = [ +XAI_PARAMETER_MAPPERS: list[ParameterMapper[TextContent]] = [ TemperatureMapper(), MaxTokensMapper(), ThinkingBudgetMapper(), diff --git a/src/celeste/modalities/videos/providers/byteplus/client.py b/src/celeste/modalities/videos/providers/byteplus/client.py index 05d06d2f..f4672079 100644 --- a/src/celeste/modalities/videos/providers/byteplus/client.py +++ b/src/celeste/modalities/videos/providers/byteplus/client.py @@ -8,6 +8,7 @@ from celeste.providers.byteplus.videos.client import ( BytePlusVideosClient as BytePlusVideosMixin, ) +from celeste.types import VideoContent from ...client import VideosClient from ...io import VideoInput, VideoOutput @@ -19,7 +20,7 @@ class BytePlusVideosClient(BytePlusVideosMixin, VideosClient): """BytePlus client for video generation.""" @classmethod - def parameter_mappers(cls) -> list[ParameterMapper]: + def parameter_mappers(cls) -> list[ParameterMapper[VideoContent]]: return BYTEPLUS_PARAMETER_MAPPERS def _init_request(self, inputs: VideoInput) -> dict[str, Any]: diff --git a/src/celeste/modalities/videos/providers/byteplus/parameters.py b/src/celeste/modalities/videos/providers/byteplus/parameters.py index ee409973..6fff0c41 100644 --- a/src/celeste/modalities/videos/providers/byteplus/parameters.py +++ b/src/celeste/modalities/videos/providers/byteplus/parameters.py @@ -19,6 +19,7 @@ from celeste.providers.byteplus.videos.parameters import ( ResolutionMapper as _ResolutionMapper, ) +from celeste.types import VideoContent from ...parameters import VideoParameter @@ -59,7 +60,7 @@ class LastFrameMapper(_LastFrameMapper): name = VideoParameter.LAST_FRAME -BYTEPLUS_PARAMETER_MAPPERS: list[ParameterMapper] = [ +BYTEPLUS_PARAMETER_MAPPERS: list[ParameterMapper[VideoContent]] = [ AspectRatioMapper(), ResolutionMapper(), DurationMapper(), diff --git a/src/celeste/modalities/videos/providers/google/client.py b/src/celeste/modalities/videos/providers/google/client.py index 171aff38..fdbbaaa8 100644 --- a/src/celeste/modalities/videos/providers/google/client.py +++ b/src/celeste/modalities/videos/providers/google/client.py @@ -7,6 +7,7 @@ from celeste.parameters import ParameterMapper from celeste.providers.google.veo import config from celeste.providers.google.veo.client import GoogleVeoClient as GoogleVeoMixin +from celeste.types import VideoContent from ...client import VideosClient from ...io import VideoInput, VideoOutput @@ -18,7 +19,7 @@ class GoogleVideosClient(GoogleVeoMixin, VideosClient): """Google client for video generation.""" @classmethod - def parameter_mappers(cls) -> list[ParameterMapper]: + def parameter_mappers(cls) -> list[ParameterMapper[VideoContent]]: return GOOGLE_PARAMETER_MAPPERS def _init_request(self, inputs: VideoInput) -> dict[str, Any]: diff --git a/src/celeste/modalities/videos/providers/google/parameters.py b/src/celeste/modalities/videos/providers/google/parameters.py index 30ad7610..13e56274 100644 --- a/src/celeste/modalities/videos/providers/google/parameters.py +++ b/src/celeste/modalities/videos/providers/google/parameters.py @@ -19,6 +19,7 @@ from celeste.providers.google.veo.parameters import ( ResolutionMapper as _ResolutionMapper, ) +from celeste.types import VideoContent from ...parameters import VideoParameter @@ -59,7 +60,7 @@ class LastFrameMapper(_LastFrameMapper): name = VideoParameter.LAST_FRAME -GOOGLE_PARAMETER_MAPPERS: list[ParameterMapper] = [ +GOOGLE_PARAMETER_MAPPERS: list[ParameterMapper[VideoContent]] = [ AspectRatioMapper(), ResolutionMapper(), DurationMapper(), diff --git a/src/celeste/modalities/videos/providers/openai/client.py b/src/celeste/modalities/videos/providers/openai/client.py index e2284499..4509616e 100644 --- a/src/celeste/modalities/videos/providers/openai/client.py +++ b/src/celeste/modalities/videos/providers/openai/client.py @@ -9,6 +9,7 @@ from celeste.providers.openai.videos.client import ( OpenAIVideosClient as OpenAIVideosMixin, ) +from celeste.types import VideoContent from ...client import VideosClient from ...io import VideoInput, VideoOutput @@ -20,7 +21,7 @@ class OpenAIVideosClient(OpenAIVideosMixin, VideosClient): """OpenAI client for video generation.""" @classmethod - def parameter_mappers(cls) -> list[ParameterMapper]: + def parameter_mappers(cls) -> list[ParameterMapper[VideoContent]]: return OPENAI_PARAMETER_MAPPERS def _init_request(self, inputs: VideoInput) -> dict[str, Any]: diff --git a/src/celeste/modalities/videos/providers/openai/parameters.py b/src/celeste/modalities/videos/providers/openai/parameters.py index 81ddb945..0f133c73 100644 --- a/src/celeste/modalities/videos/providers/openai/parameters.py +++ b/src/celeste/modalities/videos/providers/openai/parameters.py @@ -19,6 +19,7 @@ from celeste.providers.openai.videos.parameters import ( SizeMapper as _SizeMapper, ) +from celeste.types import VideoContent from ...parameters import VideoParameter @@ -58,7 +59,7 @@ def _compute_size(aspect_ratio: str, resolution: str) -> str: return f"{width}x{height}" -class AspectRatioMapper(ParameterMapper): +class AspectRatioMapper(ParameterMapper[VideoContent]): """Store aspect_ratio for later combination with resolution.""" name = VideoParameter.ASPECT_RATIO @@ -107,7 +108,7 @@ class DurationMapper(_SecondsMapper): name = VideoParameter.DURATION -OPENAI_PARAMETER_MAPPERS: list[ParameterMapper] = [ +OPENAI_PARAMETER_MAPPERS: list[ParameterMapper[VideoContent]] = [ AspectRatioMapper(), ResolutionMapper(), DurationMapper(), diff --git a/src/celeste/modalities/videos/providers/xai/client.py b/src/celeste/modalities/videos/providers/xai/client.py index 8acdf485..fc3c8b50 100644 --- a/src/celeste/modalities/videos/providers/xai/client.py +++ b/src/celeste/modalities/videos/providers/xai/client.py @@ -6,6 +6,7 @@ from celeste.parameters import ParameterMapper from celeste.providers.xai.videos import config from celeste.providers.xai.videos.client import XAIVideosClient as XAIVideosMixin +from celeste.types import VideoContent from ...client import VideosClient from ...io import VideoInput, VideoOutput @@ -17,7 +18,7 @@ class XAIVideosClient(XAIVideosMixin, VideosClient): """xAI client for video generation.""" @classmethod - def parameter_mappers(cls) -> list[ParameterMapper]: + def parameter_mappers(cls) -> list[ParameterMapper[VideoContent]]: return XAI_PARAMETER_MAPPERS def _init_request(self, inputs: VideoInput) -> dict[str, Any]: diff --git a/src/celeste/modalities/videos/providers/xai/parameters.py b/src/celeste/modalities/videos/providers/xai/parameters.py index aa355485..db411e1d 100644 --- a/src/celeste/modalities/videos/providers/xai/parameters.py +++ b/src/celeste/modalities/videos/providers/xai/parameters.py @@ -10,6 +10,7 @@ from celeste.providers.xai.videos.parameters import ( ResolutionMapper as _ResolutionMapper, ) +from celeste.types import VideoContent from ...parameters import VideoParameter @@ -32,7 +33,7 @@ class ResolutionMapper(_ResolutionMapper): name = VideoParameter.RESOLUTION -XAI_PARAMETER_MAPPERS: list[ParameterMapper] = [ +XAI_PARAMETER_MAPPERS: list[ParameterMapper[VideoContent]] = [ DurationMapper(), AspectRatioMapper(), ResolutionMapper(), diff --git a/src/celeste/parameters.py b/src/celeste/parameters.py index fa5fcac9..2657fc28 100644 --- a/src/celeste/parameters.py +++ b/src/celeste/parameters.py @@ -11,7 +11,7 @@ class Parameters(TypedDict, total=False): """Base parameters for all capabilities.""" -class ParameterMapper(ABC): +class ParameterMapper[Content](ABC): """Base class for provider-specific parameter transformation.""" name: ClassVar[StrEnum] @@ -31,7 +31,7 @@ def map(self, request: dict[str, Any], value: Any, model: Model) -> dict[str, An """ ... - def parse_output(self, content: Any, value: object | None) -> Any: # noqa: ANN401 + def parse_output(self, content: Content, value: object | None) -> Content: """Optionally transform parsed content based on parameter value (default: return unchanged).""" return content @@ -47,7 +47,7 @@ def _validate_value(self, value: Any, model: Model) -> Any: # noqa: ANN401 return constraint(value) -class FieldMapper(ParameterMapper): +class FieldMapper[Content](ParameterMapper[Content]): """Maps a parameter directly to a flat request field after validation.""" field: ClassVar[str] diff --git a/src/celeste/protocols/chatcompletions/parameters.py b/src/celeste/protocols/chatcompletions/parameters.py index dfe4607e..39173118 100644 --- a/src/celeste/protocols/chatcompletions/parameters.py +++ b/src/celeste/protocols/chatcompletions/parameters.py @@ -10,19 +10,19 @@ from celeste.types import TextContent -class TemperatureMapper(FieldMapper): +class TemperatureMapper(FieldMapper[TextContent]): """Map temperature to Chat Completions temperature field.""" field = "temperature" -class MaxTokensMapper(FieldMapper): +class MaxTokensMapper(FieldMapper[TextContent]): """Map max_tokens to Chat Completions max_tokens field.""" field = "max_tokens" -class ResponseFormatMapper(ParameterMapper): +class ResponseFormatMapper(ParameterMapper[TextContent]): """Map output_schema to Chat Completions response_format field. Default uses json_object mode (no schema validation server-side). diff --git a/src/celeste/protocols/openresponses/parameters.py b/src/celeste/protocols/openresponses/parameters.py index 635b27b6..4f7a6d39 100644 --- a/src/celeste/protocols/openresponses/parameters.py +++ b/src/celeste/protocols/openresponses/parameters.py @@ -11,19 +11,19 @@ from celeste.types import TextContent -class TemperatureMapper(FieldMapper): +class TemperatureMapper(FieldMapper[TextContent]): """Map temperature to Responses temperature field.""" field = "temperature" -class MaxOutputTokensMapper(FieldMapper): +class MaxOutputTokensMapper(FieldMapper[TextContent]): """Map max_tokens to Responses max_output_tokens field.""" field = "max_output_tokens" -class TextFormatMapper(ParameterMapper): +class TextFormatMapper(ParameterMapper[TextContent]): """Map output_schema to Responses text.format field. Handles both single BaseModel and list[BaseModel] types. @@ -92,7 +92,7 @@ def parse_output(self, content: TextContent, value: object | None) -> TextConten return TypeAdapter(value).validate_python(parsed) -class ReasoningEffortMapper(ParameterMapper): +class ReasoningEffortMapper(ParameterMapper[TextContent]): """Map reasoning_effort to Responses reasoning.effort field.""" def map( @@ -110,7 +110,7 @@ def map( return request -class VerbosityMapper(ParameterMapper): +class VerbosityMapper(ParameterMapper[TextContent]): """Map verbosity to Responses text.verbosity field.""" def map( @@ -128,7 +128,7 @@ def map( return request -class WebSearchMapper(ParameterMapper): +class WebSearchMapper(ParameterMapper[TextContent]): """Map web_search to Responses tools array.""" def map( @@ -146,7 +146,7 @@ def map( return request -class XSearchMapper(ParameterMapper): +class XSearchMapper(ParameterMapper[TextContent]): """Map x_search to Responses tools array (search X/Twitter).""" def map( @@ -164,7 +164,7 @@ def map( return request -class CodeExecutionMapper(ParameterMapper): +class CodeExecutionMapper(ParameterMapper[TextContent]): """Map code_execution to Responses tools array.""" def map( diff --git a/src/celeste/providers/anthropic/messages/parameters.py b/src/celeste/providers/anthropic/messages/parameters.py index 2b63bdaf..7146653e 100644 --- a/src/celeste/providers/anthropic/messages/parameters.py +++ b/src/celeste/providers/anthropic/messages/parameters.py @@ -11,37 +11,37 @@ from celeste.types import TextContent -class TemperatureMapper(FieldMapper): +class TemperatureMapper(FieldMapper[TextContent]): """Map temperature to Anthropic temperature field.""" field = "temperature" -class TopPMapper(FieldMapper): +class TopPMapper(FieldMapper[TextContent]): """Map top_p to Anthropic top_p field.""" field = "top_p" -class TopKMapper(FieldMapper): +class TopKMapper(FieldMapper[TextContent]): """Map top_k to Anthropic top_k field.""" field = "top_k" -class MaxTokensMapper(FieldMapper): +class MaxTokensMapper(FieldMapper[TextContent]): """Map max_tokens to Anthropic max_tokens field.""" field = "max_tokens" -class StopSequencesMapper(FieldMapper): +class StopSequencesMapper(FieldMapper[TextContent]): """Map stop_sequences to Anthropic stop_sequences field.""" field = "stop_sequences" -class ThinkingMapper(ParameterMapper): +class ThinkingMapper(ParameterMapper[TextContent]): """Map thinking to Anthropic thinking field. Accepts provider-native values: @@ -67,7 +67,7 @@ def map( return request -class WebSearchMapper(ParameterMapper): +class WebSearchMapper(ParameterMapper[TextContent]): """Map web_search to Anthropic tools field.""" def map( @@ -90,7 +90,7 @@ def map( return request -class OutputFormatMapper(ParameterMapper): +class OutputFormatMapper(ParameterMapper[TextContent]): """Map output_schema to Anthropic output_format field. Handles both single BaseModel and list[BaseModel] types. diff --git a/src/celeste/providers/bfl/images/parameters.py b/src/celeste/providers/bfl/images/parameters.py index 39f92de1..7ee1a3ed 100644 --- a/src/celeste/providers/bfl/images/parameters.py +++ b/src/celeste/providers/bfl/images/parameters.py @@ -5,9 +5,10 @@ from celeste.constraints import Int from celeste.models import Model from celeste.parameters import FieldMapper, ParameterMapper +from celeste.types import ImageContent -class WidthMapper(ParameterMapper): +class WidthMapper(ParameterMapper[ImageContent]): """Map width to BFL width field.""" def map( @@ -24,7 +25,7 @@ def map( return request -class HeightMapper(ParameterMapper): +class HeightMapper(ParameterMapper[ImageContent]): """Map height to BFL height field.""" def map( @@ -41,37 +42,37 @@ def map( return request -class PromptUpsamplingMapper(FieldMapper): +class PromptUpsamplingMapper(FieldMapper[ImageContent]): """Map prompt_upsampling to BFL prompt_upsampling field.""" field = "prompt_upsampling" -class SeedMapper(FieldMapper): +class SeedMapper(FieldMapper[ImageContent]): """Map seed to BFL seed field.""" field = "seed" -class SafetyToleranceMapper(FieldMapper): +class SafetyToleranceMapper(FieldMapper[ImageContent]): """Map safety_tolerance to BFL safety_tolerance field.""" field = "safety_tolerance" -class OutputFormatMapper(FieldMapper): +class OutputFormatMapper(FieldMapper[ImageContent]): """Map output_format to BFL output_format field.""" field = "output_format" -class StepsMapper(FieldMapper): +class StepsMapper(FieldMapper[ImageContent]): """Map steps to BFL steps field.""" field = "steps" -class GuidanceMapper(FieldMapper): +class GuidanceMapper(FieldMapper[ImageContent]): """Map guidance to BFL guidance field.""" field = "guidance" diff --git a/src/celeste/providers/byteplus/images/parameters.py b/src/celeste/providers/byteplus/images/parameters.py index b2bbbe02..661db818 100644 --- a/src/celeste/providers/byteplus/images/parameters.py +++ b/src/celeste/providers/byteplus/images/parameters.py @@ -1,15 +1,16 @@ """BytePlus Images API parameter mappers.""" from celeste.parameters import FieldMapper +from celeste.types import ImageContent -class SizeMapper(FieldMapper): +class SizeMapper(FieldMapper[ImageContent]): """Map size to BytePlus size field.""" field = "size" -class WatermarkMapper(FieldMapper): +class WatermarkMapper(FieldMapper[ImageContent]): """Map watermark to BytePlus watermark field.""" field = "watermark" diff --git a/src/celeste/providers/byteplus/videos/parameters.py b/src/celeste/providers/byteplus/videos/parameters.py index b0ea3f1e..55eaa1d3 100644 --- a/src/celeste/providers/byteplus/videos/parameters.py +++ b/src/celeste/providers/byteplus/videos/parameters.py @@ -5,9 +5,10 @@ from celeste.exceptions import ValidationError from celeste.models import Model from celeste.parameters import ParameterMapper +from celeste.types import VideoContent -class DurationMapper(ParameterMapper): +class DurationMapper(ParameterMapper[VideoContent]): """Map duration parameter to BytePlus text prompt format. Appends --duration to the text prompt. @@ -32,7 +33,7 @@ def map( return request -class ResolutionMapper(ParameterMapper): +class ResolutionMapper(ParameterMapper[VideoContent]): """Map resolution parameter to BytePlus text prompt format. Appends --resolution to the text prompt. @@ -57,7 +58,7 @@ def map( return request -class AspectRatioMapper(ParameterMapper): +class AspectRatioMapper(ParameterMapper[VideoContent]): """Map aspect_ratio parameter to BytePlus text prompt format. Appends --ratio to the text prompt. @@ -82,7 +83,7 @@ def map( return request -class ReferenceImagesMapper(ParameterMapper): +class ReferenceImagesMapper(ParameterMapper[VideoContent]): """Map reference_images to BytePlus content array format. Adds images with role="reference_image" to the content array. @@ -109,7 +110,7 @@ def map( return request -class FirstFrameMapper(ParameterMapper): +class FirstFrameMapper(ParameterMapper[VideoContent]): """Map first_frame to BytePlus content array format. Adds image with role="first_frame" to the content array. @@ -139,7 +140,7 @@ def map( return request -class LastFrameMapper(ParameterMapper): +class LastFrameMapper(ParameterMapper[VideoContent]): """Map last_frame to BytePlus content array format. Adds image with role="last_frame" to the content array. diff --git a/src/celeste/providers/cohere/chat/parameters.py b/src/celeste/providers/cohere/chat/parameters.py index e10433ad..c9ea4de3 100644 --- a/src/celeste/providers/cohere/chat/parameters.py +++ b/src/celeste/providers/cohere/chat/parameters.py @@ -11,19 +11,19 @@ from celeste.types import TextContent -class TemperatureMapper(FieldMapper): +class TemperatureMapper(FieldMapper[TextContent]): """Map temperature to Cohere temperature field.""" field = "temperature" -class MaxTokensMapper(FieldMapper): +class MaxTokensMapper(FieldMapper[TextContent]): """Map max_tokens to Cohere max_tokens field.""" field = "max_tokens" -class ThinkingMapper(ParameterMapper): +class ThinkingMapper(ParameterMapper[TextContent]): """Map thinking to Cohere thinking field.""" def map( @@ -46,7 +46,7 @@ def map( return request -class ResponseFormatMapper(ParameterMapper): +class ResponseFormatMapper(ParameterMapper[TextContent]): """Map output_schema to Cohere response_format field. Handles both single BaseModel and list[BaseModel] types. diff --git a/src/celeste/providers/elevenlabs/text_to_speech/parameters.py b/src/celeste/providers/elevenlabs/text_to_speech/parameters.py index 788d5050..a90f9ec5 100644 --- a/src/celeste/providers/elevenlabs/text_to_speech/parameters.py +++ b/src/celeste/providers/elevenlabs/text_to_speech/parameters.py @@ -4,9 +4,10 @@ from celeste.models import Model from celeste.parameters import FieldMapper, ParameterMapper +from celeste.types import AudioContent -class VoiceMapper(FieldMapper): +class VoiceMapper(FieldMapper[AudioContent]): """Map voice parameter to ElevenLabs URL path. Note: Voice ID goes in URL path, not request body. @@ -17,7 +18,7 @@ class VoiceMapper(FieldMapper): field = "_voice_id" -class OutputFormatMapper(ParameterMapper): +class OutputFormatMapper(ParameterMapper[AudioContent]): """Map response_format parameter to ElevenLabs output_format field.""" def map( @@ -36,7 +37,7 @@ def map( return request -class SpeedMapper(ParameterMapper): +class SpeedMapper(ParameterMapper[AudioContent]): """Map speed parameter to ElevenLabs voice_settings.speed field.""" def map( @@ -57,7 +58,7 @@ def map( return request -class LanguageCodeMapper(ParameterMapper): +class LanguageCodeMapper(ParameterMapper[AudioContent]): """Map language parameter to ElevenLabs language_code field. Only supported by eleven_turbo_v2_5 and eleven_flash_v2_5 models. diff --git a/src/celeste/providers/google/cloud_tts/parameters.py b/src/celeste/providers/google/cloud_tts/parameters.py index 047b81e9..2e12c185 100644 --- a/src/celeste/providers/google/cloud_tts/parameters.py +++ b/src/celeste/providers/google/cloud_tts/parameters.py @@ -5,9 +5,10 @@ from celeste.mime_types import AudioMimeType from celeste.models import Model from celeste.parameters import ParameterMapper +from celeste.types import AudioContent -class VoiceMapper(ParameterMapper): +class VoiceMapper(ParameterMapper[AudioContent]): """Map voice to Google Cloud TTS voice.name field.""" def map( @@ -25,7 +26,7 @@ def map( return request -class LanguageMapper(ParameterMapper): +class LanguageMapper(ParameterMapper[AudioContent]): """Map language to Google Cloud TTS voice.languageCode field.""" locale_map: ClassVar[dict[str, str]] = {} @@ -52,7 +53,7 @@ def map( return request -class PromptMapper(ParameterMapper): +class PromptMapper(ParameterMapper[AudioContent]): """Map prompt to Google Cloud TTS input.prompt field.""" def map( @@ -69,7 +70,7 @@ def map( return request -class AudioEncodingMapper(ParameterMapper): +class AudioEncodingMapper(ParameterMapper[AudioContent]): """Map audio_encoding to Google Cloud TTS audioConfig.audioEncoding field.""" encoding_map: ClassVar[dict[AudioMimeType, str]] = {} diff --git a/src/celeste/providers/google/embeddings/parameters.py b/src/celeste/providers/google/embeddings/parameters.py index fad69e00..3cd75eae 100644 --- a/src/celeste/providers/google/embeddings/parameters.py +++ b/src/celeste/providers/google/embeddings/parameters.py @@ -4,9 +4,10 @@ from celeste.models import Model from celeste.parameters import ParameterMapper +from celeste.types import EmbeddingsContent -class OutputDimensionalityMapper(ParameterMapper): +class OutputDimensionalityMapper(ParameterMapper[EmbeddingsContent]): """Map dimensions to Google Embeddings outputDimensionality field.""" def map( diff --git a/src/celeste/providers/google/generate_content/parameters.py b/src/celeste/providers/google/generate_content/parameters.py index ed6f54d9..e7e979ae 100644 --- a/src/celeste/providers/google/generate_content/parameters.py +++ b/src/celeste/providers/google/generate_content/parameters.py @@ -13,7 +13,7 @@ from celeste.types import TextContent -class TemperatureMapper(ParameterMapper): +class TemperatureMapper[Content](ParameterMapper[Content]): """Map temperature to Google generationConfig.temperature field.""" def map( @@ -31,7 +31,7 @@ def map( return request -class MaxOutputTokensMapper(ParameterMapper): +class MaxOutputTokensMapper[Content](ParameterMapper[Content]): """Map max_tokens to Google generationConfig.maxOutputTokens field.""" def map( @@ -49,7 +49,7 @@ def map( return request -class ThinkingBudgetMapper(ParameterMapper): +class ThinkingBudgetMapper[Content](ParameterMapper[Content]): """Map thinkingBudget to Google generationConfig.thinkingConfig.thinkingBudget field.""" def map( @@ -69,7 +69,7 @@ def map( return request -class ThinkingLevelMapper(ParameterMapper): +class ThinkingLevelMapper[Content](ParameterMapper[Content]): """Map thinkingLevel to Google generationConfig.thinkingConfig.thinkingLevel field.""" def map( @@ -89,7 +89,7 @@ def map( return request -class AspectRatioMapper(ParameterMapper): +class AspectRatioMapper[Content](ParameterMapper[Content]): """Map aspect_ratio to Google generationConfig.imageConfig.aspectRatio field.""" def map( @@ -109,7 +109,7 @@ def map( return request -class ImageSizeMapper(ParameterMapper): +class ImageSizeMapper[Content](ParameterMapper[Content]): """Map image_size to Google generationConfig.imageConfig.imageSize field.""" def map( @@ -129,7 +129,7 @@ def map( return request -class MediaContentMapper(ParameterMapper): +class MediaContentMapper[Content](ParameterMapper[Content]): """Map reference_images to Google contents.parts field.""" def _build_image_part(self, image: ImageArtifact) -> dict[str, Any]: @@ -181,7 +181,7 @@ def map( return request -class WebSearchMapper(ParameterMapper): +class WebSearchMapper[Content](ParameterMapper[Content]): """Map web_search to Google tools field.""" def map( @@ -199,7 +199,7 @@ def map( return request -class ResponseJsonSchemaMapper(ParameterMapper): +class ResponseJsonSchemaMapper(ParameterMapper[TextContent]): """Map output_schema to Google generationConfig.responseJsonSchema field.""" def map( diff --git a/src/celeste/providers/google/imagen/parameters.py b/src/celeste/providers/google/imagen/parameters.py index fd24bbd5..8784026b 100644 --- a/src/celeste/providers/google/imagen/parameters.py +++ b/src/celeste/providers/google/imagen/parameters.py @@ -4,9 +4,10 @@ from celeste.models import Model from celeste.parameters import ParameterMapper +from celeste.types import ImageContent -class SampleCountMapper(ParameterMapper): +class SampleCountMapper(ParameterMapper[ImageContent]): """Map num_images to Google Imagen parameters.sampleCount field.""" def map( @@ -24,7 +25,7 @@ def map( return request -class AspectRatioMapper(ParameterMapper): +class AspectRatioMapper(ParameterMapper[ImageContent]): """Map aspect_ratio to Google Imagen parameters.aspectRatio field.""" def map( @@ -42,7 +43,7 @@ def map( return request -class ImageSizeMapper(ParameterMapper): +class ImageSizeMapper(ParameterMapper[ImageContent]): """Map image_size to Google Imagen parameters.imageSize field.""" def map( diff --git a/src/celeste/providers/google/interactions/parameters.py b/src/celeste/providers/google/interactions/parameters.py index c990a949..f6b271be 100644 --- a/src/celeste/providers/google/interactions/parameters.py +++ b/src/celeste/providers/google/interactions/parameters.py @@ -12,7 +12,7 @@ from celeste.types import TextContent -class TemperatureMapper(ParameterMapper): +class TemperatureMapper(ParameterMapper[TextContent]): """Map temperature to Google Interactions generation_config.temperature field.""" def map( @@ -30,7 +30,7 @@ def map( return request -class MaxOutputTokensMapper(ParameterMapper): +class MaxOutputTokensMapper(ParameterMapper[TextContent]): """Map max_tokens to Google Interactions generation_config.max_output_tokens field.""" def map( @@ -50,7 +50,7 @@ def map( return request -class ThinkingBudgetMapper(ParameterMapper): +class ThinkingBudgetMapper(ParameterMapper[TextContent]): """Map thinking_budget to Interactions generation_config.thinking_config.thinking_budget.""" def map( @@ -70,7 +70,7 @@ def map( return request -class ThinkingLevelMapper(ParameterMapper): +class ThinkingLevelMapper(ParameterMapper[TextContent]): """Map thinking_level to Interactions generation_config.thinking_level field.""" def map( @@ -88,13 +88,13 @@ def map( return request -class PreviousInteractionIdMapper(FieldMapper): +class PreviousInteractionIdMapper(FieldMapper[TextContent]): """Map previous_interaction_id for stateful conversations.""" field = "previous_interaction_id" -class BackgroundMapper(ParameterMapper): +class BackgroundMapper(ParameterMapper[TextContent]): """Map background mode for long-running operations.""" def map( @@ -112,7 +112,7 @@ def map( return request -class GoogleSearchMapper(ParameterMapper): +class GoogleSearchMapper(ParameterMapper[TextContent]): """Map google_search to Google Interactions tools field.""" def map( @@ -131,7 +131,7 @@ def map( return request -class CodeExecutionMapper(ParameterMapper): +class CodeExecutionMapper(ParameterMapper[TextContent]): """Map code_execution to Google Interactions tools field.""" def map( @@ -150,7 +150,7 @@ def map( return request -class UrlContextMapper(ParameterMapper): +class UrlContextMapper(ParameterMapper[TextContent]): """Map url_context to Google Interactions tools field.""" def map( @@ -169,7 +169,7 @@ def map( return request -class ResponseFormatMapper(ParameterMapper): +class ResponseFormatMapper(ParameterMapper[TextContent]): """Map response_format to Google Interactions response_format field.""" def map( @@ -254,7 +254,7 @@ def _remove_unsupported_fields(self, schema: dict[str, Any]) -> dict[str, Any]: return result -class MediaContentMapper(ParameterMapper): +class MediaContentMapper(ParameterMapper[TextContent]): """Map reference_images to Google Interactions input content.""" def _build_image_part(self, image: ImageArtifact) -> dict[str, Any]: @@ -317,13 +317,13 @@ def map( return request -class ResponseModalitiesMapper(FieldMapper): +class ResponseModalitiesMapper(FieldMapper[TextContent]): """Map response_modalities for multimodal output generation.""" field = "response_modalities" -class SystemInstructionMapper(FieldMapper): +class SystemInstructionMapper(FieldMapper[TextContent]): """Map system_instruction for system prompts.""" field = "system_instruction" diff --git a/src/celeste/providers/google/veo/parameters.py b/src/celeste/providers/google/veo/parameters.py index 8b98110b..7905138a 100644 --- a/src/celeste/providers/google/veo/parameters.py +++ b/src/celeste/providers/google/veo/parameters.py @@ -5,10 +5,11 @@ from celeste.exceptions import ValidationError from celeste.models import Model from celeste.parameters import ParameterMapper +from celeste.types import VideoContent from celeste.utils import detect_mime_type -class AspectRatioMapper(ParameterMapper): +class AspectRatioMapper(ParameterMapper[VideoContent]): """Map aspect_ratio to Google Veo parameters.aspectRatio field.""" def map( @@ -27,7 +28,7 @@ def map( return request -class ResolutionMapper(ParameterMapper): +class ResolutionMapper(ParameterMapper[VideoContent]): """Map resolution to Google Veo parameters.resolution field.""" def map( @@ -46,7 +47,7 @@ def map( return request -class DurationSecondsMapper(ParameterMapper): +class DurationSecondsMapper(ParameterMapper[VideoContent]): """Map duration to Google Veo parameters.durationSeconds field.""" def map( @@ -69,7 +70,7 @@ def map( return request -class ReferenceImagesMapper(ParameterMapper): +class ReferenceImagesMapper(ParameterMapper[VideoContent]): """Map reference_images to Google Veo instances.referenceImages field.""" def map( @@ -104,7 +105,7 @@ def map( return request -class FirstFrameMapper(ParameterMapper): +class FirstFrameMapper(ParameterMapper[VideoContent]): """Map first_frame to Google Veo instances.image field.""" def map( @@ -131,7 +132,7 @@ def map( return request -class LastFrameMapper(ParameterMapper): +class LastFrameMapper(ParameterMapper[VideoContent]): """Map last_frame to Google Veo instances.lastFrame field.""" def map( diff --git a/src/celeste/providers/gradium/text_to_speech/parameters.py b/src/celeste/providers/gradium/text_to_speech/parameters.py index 594f0b90..1ff78ff3 100644 --- a/src/celeste/providers/gradium/text_to_speech/parameters.py +++ b/src/celeste/providers/gradium/text_to_speech/parameters.py @@ -4,15 +4,16 @@ from celeste.models import Model from celeste.parameters import FieldMapper, ParameterMapper +from celeste.types import AudioContent -class VoiceMapper(FieldMapper): +class VoiceMapper(FieldMapper[AudioContent]): """Map voice to Gradium voice_id field.""" field = "voice_id" -class PaddingBonusMapper(ParameterMapper): +class PaddingBonusMapper(ParameterMapper[AudioContent]): """Map padding_bonus to Gradium json_config.padding_bonus field.""" def map( @@ -30,7 +31,7 @@ def map( return request -class OutputFormatMapper(FieldMapper): +class OutputFormatMapper(FieldMapper[AudioContent]): """Map output_format to Gradium output_format field.""" field = "output_format" diff --git a/src/celeste/providers/mistral/chat/parameters.py b/src/celeste/providers/mistral/chat/parameters.py index 22e24c16..664246f3 100644 --- a/src/celeste/providers/mistral/chat/parameters.py +++ b/src/celeste/providers/mistral/chat/parameters.py @@ -10,9 +10,10 @@ ResponseFormatMapper as _ResponseFormatMapper, ) from celeste.structured_outputs import StrictRefResolvingJsonSchemaGenerator +from celeste.types import TextContent -class WebSearchMapper(ParameterMapper): +class WebSearchMapper(ParameterMapper[TextContent]): """Map web_search to Mistral tools field.""" def map( diff --git a/src/celeste/providers/ollama/generate/parameters.py b/src/celeste/providers/ollama/generate/parameters.py index b94a20fe..cb08e66f 100644 --- a/src/celeste/providers/ollama/generate/parameters.py +++ b/src/celeste/providers/ollama/generate/parameters.py @@ -11,9 +11,10 @@ from celeste.constraints import Int from celeste.models import Model from celeste.parameters import FieldMapper, ParameterMapper +from celeste.types import ImageContent -class WidthMapper(ParameterMapper): +class WidthMapper(ParameterMapper[ImageContent]): """Map width to Ollama width field.""" def map( @@ -30,7 +31,7 @@ def map( return request -class HeightMapper(ParameterMapper): +class HeightMapper(ParameterMapper[ImageContent]): """Map height to Ollama height field.""" def map( @@ -47,13 +48,13 @@ def map( return request -class StepsMapper(FieldMapper): +class StepsMapper(FieldMapper[ImageContent]): """Map steps to Ollama steps field.""" field = "steps" -class SeedMapper(ParameterMapper): +class SeedMapper(ParameterMapper[ImageContent]): """Map seed to Ollama options.seed field (nested).""" def map( @@ -71,7 +72,7 @@ def map( return request -class NegativePromptMapper(FieldMapper): +class NegativePromptMapper(FieldMapper[ImageContent]): """Map negative_prompt to Ollama negative_prompt field.""" field = "negative_prompt" diff --git a/src/celeste/providers/openai/audio/parameters.py b/src/celeste/providers/openai/audio/parameters.py index 4a9591b9..aaf02421 100644 --- a/src/celeste/providers/openai/audio/parameters.py +++ b/src/celeste/providers/openai/audio/parameters.py @@ -5,21 +5,22 @@ from celeste.mime_types import AudioMimeType from celeste.models import Model from celeste.parameters import FieldMapper, ParameterMapper +from celeste.types import AudioContent -class VoiceMapper(FieldMapper): +class VoiceMapper(FieldMapper[AudioContent]): """Map voice to OpenAI voice field.""" field = "voice" -class SpeedMapper(FieldMapper): +class SpeedMapper(FieldMapper[AudioContent]): """Map speed to OpenAI speed field.""" field = "speed" -class ResponseFormatMapper(ParameterMapper): +class ResponseFormatMapper(ParameterMapper[AudioContent]): """Map response_format to OpenAI response_format field.""" def map( @@ -56,7 +57,7 @@ def map( return request -class InstructionsMapper(FieldMapper): +class InstructionsMapper(FieldMapper[AudioContent]): """Map instructions to OpenAI instructions field.""" field = "instructions" diff --git a/src/celeste/providers/openai/images/parameters.py b/src/celeste/providers/openai/images/parameters.py index ab6b4de0..465522f7 100644 --- a/src/celeste/providers/openai/images/parameters.py +++ b/src/celeste/providers/openai/images/parameters.py @@ -1,51 +1,52 @@ """OpenAI Images API parameter mappers.""" from celeste.parameters import FieldMapper +from celeste.types import ImageContent -class SizeMapper(FieldMapper): +class SizeMapper(FieldMapper[ImageContent]): """Map size to OpenAI size field.""" field = "size" -class PartialImagesMapper(FieldMapper): +class PartialImagesMapper(FieldMapper[ImageContent]): """Map partial_images to OpenAI partial_images field.""" field = "partial_images" -class QualityMapper(FieldMapper): +class QualityMapper(FieldMapper[ImageContent]): """Map quality to OpenAI quality field.""" field = "quality" -class BackgroundMapper(FieldMapper): +class BackgroundMapper(FieldMapper[ImageContent]): """Map background to OpenAI background field.""" field = "background" -class OutputFormatMapper(FieldMapper): +class OutputFormatMapper(FieldMapper[ImageContent]): """Map output_format to OpenAI output_format field.""" field = "output_format" -class StyleMapper(FieldMapper): +class StyleMapper(FieldMapper[ImageContent]): """Map style to OpenAI style field.""" field = "style" -class ModerationMapper(FieldMapper): +class ModerationMapper(FieldMapper[ImageContent]): """Map moderation to OpenAI moderation field.""" field = "moderation" -class OutputCompressionMapper(FieldMapper): +class OutputCompressionMapper(FieldMapper[ImageContent]): """Map output_compression to OpenAI output_compression field.""" field = "output_compression" diff --git a/src/celeste/providers/openai/videos/parameters.py b/src/celeste/providers/openai/videos/parameters.py index 951f55c1..d6d1072e 100644 --- a/src/celeste/providers/openai/videos/parameters.py +++ b/src/celeste/providers/openai/videos/parameters.py @@ -4,9 +4,10 @@ from celeste.models import Model from celeste.parameters import FieldMapper, ParameterMapper +from celeste.types import VideoContent -class SecondsMapper(ParameterMapper): +class SecondsMapper(ParameterMapper[VideoContent]): """Map seconds to OpenAI seconds field.""" def map( @@ -27,7 +28,7 @@ def map( return request -class SizeMapper(ParameterMapper): +class SizeMapper(ParameterMapper[VideoContent]): """Map size to OpenAI size field.""" def map( @@ -44,7 +45,7 @@ def map( return request -class InputReferenceMapper(FieldMapper): +class InputReferenceMapper(FieldMapper[VideoContent]): """Map input_reference to OpenAI input_reference field.""" field = "input_reference" diff --git a/src/celeste/providers/xai/images/parameters.py b/src/celeste/providers/xai/images/parameters.py index 2429db9f..7bfa9630 100644 --- a/src/celeste/providers/xai/images/parameters.py +++ b/src/celeste/providers/xai/images/parameters.py @@ -7,21 +7,22 @@ """ from celeste.parameters import FieldMapper +from celeste.types import ImageContent -class AspectRatioMapper(FieldMapper): +class AspectRatioMapper(FieldMapper[ImageContent]): """Map aspect_ratio to xAI aspect_ratio field.""" field = "aspect_ratio" -class NumImagesMapper(FieldMapper): +class NumImagesMapper(FieldMapper[ImageContent]): """Map num_images to xAI n field.""" field = "n" -class ResponseFormatMapper(FieldMapper): +class ResponseFormatMapper(FieldMapper[ImageContent]): """Map response_format to xAI response_format field.""" field = "response_format" diff --git a/src/celeste/providers/xai/videos/parameters.py b/src/celeste/providers/xai/videos/parameters.py index 3a80504a..1aaa13f5 100644 --- a/src/celeste/providers/xai/videos/parameters.py +++ b/src/celeste/providers/xai/videos/parameters.py @@ -1,21 +1,22 @@ """xAI Videos API parameter mappers.""" from celeste.parameters import FieldMapper +from celeste.types import VideoContent -class DurationMapper(FieldMapper): +class DurationMapper(FieldMapper[VideoContent]): """Map duration to xAI duration field.""" field = "duration" -class AspectRatioMapper(FieldMapper): +class AspectRatioMapper(FieldMapper[VideoContent]): """Map aspect_ratio to xAI aspect_ratio field.""" field = "aspect_ratio" -class ResolutionMapper(FieldMapper): +class ResolutionMapper(FieldMapper[VideoContent]): """Map resolution to xAI resolution field.""" field = "resolution" diff --git a/templates/modalities/{modality_slug}/providers/{provider_slug}/client.py.template b/templates/modalities/{modality_slug}/providers/{provider_slug}/client.py.template index 32bd9960..b1845070 100644 --- a/templates/modalities/{modality_slug}/providers/{provider_slug}/client.py.template +++ b/templates/modalities/{modality_slug}/providers/{provider_slug}/client.py.template @@ -40,7 +40,7 @@ class {Provider}{Modality}Client({Provider}{Api}Mixin, {Modality}Client): """{Provider} {modality} client.""" @classmethod - def parameter_mappers(cls) -> list[ParameterMapper]: + def parameter_mappers(cls) -> list[ParameterMapper[{Content}]]: return {PROVIDER}_PARAMETER_MAPPERS def _stream_class(self) -> type[{Modality}Stream]: diff --git a/templates/modalities/{modality_slug}/providers/{provider_slug}/parameters.py.template b/templates/modalities/{modality_slug}/providers/{provider_slug}/parameters.py.template index 800756e3..e4b03630 100644 --- a/templates/modalities/{modality_slug}/providers/{provider_slug}/parameters.py.template +++ b/templates/modalities/{modality_slug}/providers/{provider_slug}/parameters.py.template @@ -1,6 +1,7 @@ """{Provider} parameter mappers for {modality}.""" from celeste.parameters import ParameterMapper +from celeste.types import {Content} from celeste.providers.{provider}.{api}.parameters import ( ExampleMapper as _ExampleMapper, ) @@ -14,7 +15,7 @@ class AspectRatioMapper(_ExampleMapper): name = {Modality}Parameter.ASPECT_RATIO -{PROVIDER}_PARAMETER_MAPPERS: list[ParameterMapper] = [ +{PROVIDER}_PARAMETER_MAPPERS: list[ParameterMapper[{Content}]] = [ AspectRatioMapper(), ] diff --git a/templates/protocols/{protocol_slug}/parameters.py.template b/templates/protocols/{protocol_slug}/parameters.py.template index a651765c..4726c206 100644 --- a/templates/protocols/{protocol_slug}/parameters.py.template +++ b/templates/protocols/{protocol_slug}/parameters.py.template @@ -7,7 +7,7 @@ from celeste.parameters import ParameterMapper # PATTERN 1: Simple flat mapping -# class TemperatureMapper(ParameterMapper): +# class TemperatureMapper(ParameterMapper[TextContent]): # """Map temperature to {Protocol} temperature field.""" # # def map( @@ -26,7 +26,7 @@ from celeste.parameters import ParameterMapper # PATTERN 2: Nested mapping -# class ReasoningEffortMapper(ParameterMapper): +# class ReasoningEffortMapper(ParameterMapper[TextContent]): # """Map reasoning_effort to {Protocol} reasoning.effort field.""" # # def map( @@ -45,7 +45,7 @@ from celeste.parameters import ParameterMapper # PATTERN 3: Response format with parse_output -# class ResponseFormatMapper(ParameterMapper): +# class ResponseFormatMapper(ParameterMapper[TextContent]): # """Map output_schema to {Protocol} response_format field.""" # # def map( diff --git a/templates/providers/{provider_slug}/{api_slug}/parameters.py.template b/templates/providers/{provider_slug}/{api_slug}/parameters.py.template index ac1d480d..95e1a23e 100644 --- a/templates/providers/{provider_slug}/{api_slug}/parameters.py.template +++ b/templates/providers/{provider_slug}/{api_slug}/parameters.py.template @@ -15,7 +15,7 @@ from celeste.parameters import ParameterMapper # PATTERN 1: Simple flat mapping # Use when provider expects flat request body: {"param": value} -class ExampleParamMapper(ParameterMapper): +class ExampleParamMapper[Content](ParameterMapper[Content]): """Map example_param to {Provider} example_param field.""" def map( @@ -36,7 +36,7 @@ class ExampleParamMapper(ParameterMapper): # PATTERN 2: Nested mapping # Use when provider expects nested structure: {"parameters": {"param": value}} -class NestedParamMapper(ParameterMapper): +class NestedParamMapper[Content](ParameterMapper[Content]): """Map nested_param to {Provider} parameters.nestedParam field.""" def map( diff --git a/tests/unit_tests/test_client.py b/tests/unit_tests/test_client.py index 87e4712a..0c39046d 100644 --- a/tests/unit_tests/test_client.py +++ b/tests/unit_tests/test_client.py @@ -36,11 +36,11 @@ class _TestInput(Input): def _create_test_mapper( param_name: StrEnum, map_key: str | None = None, -) -> ParameterMapper: +) -> ParameterMapper[str]: """Create a test parameter mapper instance.""" actual_map_key = map_key if map_key is not None else param_name.value - class TestMapperClass(ParameterMapper): + class TestMapperClass(ParameterMapper[str]): """Test mapper implementation.""" name = param_name @@ -66,11 +66,11 @@ def parse_output( def _create_transform_mapper( param_name: StrEnum, map_key: str | None = None, -) -> ParameterMapper: +) -> ParameterMapper[str]: """Create a test parameter mapper that transforms output.""" actual_map_key = map_key if map_key is not None else param_name.value - class TransformMapperClass(ParameterMapper): + class TransformMapperClass(ParameterMapper[str]): """Test mapper with output transformation.""" name = param_name @@ -116,7 +116,7 @@ class ConcreteModalityClient(ModalityClient[_TestInput, Output, Parameters, str] """Concrete ModalityClient implementation for testing.""" @classmethod - def parameter_mappers(cls) -> list[ParameterMapper]: + def parameter_mappers(cls) -> list[ParameterMapper[str]]: return [] def _init_request(self, inputs: _TestInput) -> dict[str, Any]: @@ -169,7 +169,7 @@ class ClientWithMapper(ConcreteModalityClient): """Client with custom parameter mapper.""" @classmethod - def parameter_mappers(cls) -> list[ParameterMapper]: + def parameter_mappers(cls) -> list[ParameterMapper[str]]: return [_create_test_mapper(ParamEnum.TEST_PARAM)] client = ClientWithMapper( @@ -198,7 +198,7 @@ class ClientWithMultipleMappers(ConcreteModalityClient): """Client with multiple parameter mappers.""" @classmethod - def parameter_mappers(cls) -> list[ParameterMapper]: + def parameter_mappers(cls) -> list[ParameterMapper[str]]: return [ _create_test_mapper(ParamEnum.FIRST_PARAM), _create_test_mapper(ParamEnum.SECOND_PARAM), @@ -244,7 +244,7 @@ class ClientWithTransformMapper(ConcreteModalityClient): """Client with output transformation mapper.""" @classmethod - def parameter_mappers(cls) -> list[ParameterMapper]: + def parameter_mappers(cls) -> list[ParameterMapper[str]]: return [_create_transform_mapper(ParamEnum.TEST_PARAM)] client = ClientWithTransformMapper( @@ -275,7 +275,7 @@ async def test_predict_applies_transform_output( class ClientWithTransformMapper(ConcreteModalityClient): @classmethod - def parameter_mappers(cls) -> list[ParameterMapper]: + def parameter_mappers(cls) -> list[ParameterMapper[str]]: return [_create_transform_mapper(ParamEnum.TEST_PARAM)] client = ClientWithTransformMapper( @@ -299,7 +299,7 @@ async def test_predict_no_transform_without_param( class ClientWithTransformMapper(ConcreteModalityClient): @classmethod - def parameter_mappers(cls) -> list[ParameterMapper]: + def parameter_mappers(cls) -> list[ParameterMapper[str]]: return [_create_transform_mapper(ParamEnum.TEST_PARAM)] client = ClientWithTransformMapper( diff --git a/tests/unit_tests/test_parameters.py b/tests/unit_tests/test_parameters.py index 8741e218..23b7b7c0 100644 --- a/tests/unit_tests/test_parameters.py +++ b/tests/unit_tests/test_parameters.py @@ -68,7 +68,7 @@ def test_parse_output_default_returns_content_unchanged(self) -> None: """Test that ParameterMapper.parse_output default returns content unchanged.""" from celeste.parameters import ParameterMapper - class TestMapper(ParameterMapper): + class TestMapper(ParameterMapper[TextContent]): name = Parameter.TEMPERATURE def map( @@ -88,7 +88,7 @@ def test_validate_value_with_none_returns_none(self) -> None: """Test that _validate_value returns None when value is None.""" from celeste.parameters import ParameterMapper - class TestMapper(ParameterMapper): + class TestMapper(ParameterMapper[TextContent]): name = Parameter.TEMPERATURE def map( @@ -112,7 +112,7 @@ def test_validate_value_with_missing_constraint_passes_through(self) -> None: """Missing constraints pass through without error.""" from celeste.parameters import ParameterMapper - class TestMapper(ParameterMapper): + class TestMapper(ParameterMapper[TextContent]): name = Parameter.TEMPERATURE def map( @@ -137,7 +137,7 @@ def test_validate_value_with_valid_constraint_calls_constraint(self) -> None: """Test that _validate_value calls constraint when parameter is supported.""" from celeste.parameters import ParameterMapper - class TestMapper(ParameterMapper): + class TestMapper(ParameterMapper[TextContent]): name = Parameter.TEMPERATURE def map( @@ -165,7 +165,7 @@ def test_validate_value_with_valid_constraint_returns_validated_value(self) -> N """Test that _validate_value returns constraint-validated value.""" from celeste.parameters import ParameterMapper - class TestMapper(ParameterMapper): + class TestMapper(ParameterMapper[TextContent]): name = Parameter.TEMPERATURE def map(