From 977ed59caa4de7ad9695de3b5a2570993582d700 Mon Sep 17 00:00:00 2001 From: kamilbenkirane Date: Wed, 20 May 2026 11:31:13 +0200 Subject: [PATCH 1/2] feat(models): add high-priority provider models with confirmed constraints Register Cohere Command A+, BytePlus Seedance 2.0, xAI Grok 4.3/4.20 canonical and image-quality, OpenAI GPT-5.5/5.4-mini/nano, and Mistral Large 3 / Small 4 with token limits, tools, and modality parameters aligned to provider docs. Co-authored-by: Cursor --- .../modalities/images/providers/xai/models.py | 28 ++++++++++ .../text/providers/cohere/models.py | 14 +++++ .../text/providers/mistral/models.py | 32 +++++++++++ .../text/providers/openai/models.py | 54 +++++++++++++++++++ .../modalities/text/providers/xai/models.py | 46 ++++++++++++++++ .../videos/providers/byteplus/models.py | 42 ++++++++++++++- 6 files changed, 215 insertions(+), 1 deletion(-) diff --git a/src/celeste/modalities/images/providers/xai/models.py b/src/celeste/modalities/images/providers/xai/models.py index 85aabb23..f5c2153e 100644 --- a/src/celeste/modalities/images/providers/xai/models.py +++ b/src/celeste/modalities/images/providers/xai/models.py @@ -35,4 +35,32 @@ ImageParameter.OUTPUT_FORMAT: Choice(options=["url", "b64_json"]), }, ), + Model( + id="grok-imagine-image-quality", + provider=Provider.XAI, + display_name="Grok Imagine Image Quality", + operations={Modality.IMAGES: {Operation.GENERATE, Operation.EDIT}}, + parameter_constraints={ + ImageParameter.NUM_IMAGES: Range(min=1, max=10), + ImageParameter.ASPECT_RATIO: Choice( + options=[ + "1:1", + "3:4", + "4:3", + "9:16", + "16:9", + "2:3", + "3:2", + "9:19.5", + "19.5:9", + "9:20", + "20:9", + "1:2", + "2:1", + "auto", + ] + ), + ImageParameter.OUTPUT_FORMAT: Choice(options=["url", "b64_json"]), + }, + ), ] diff --git a/src/celeste/modalities/text/providers/cohere/models.py b/src/celeste/modalities/text/providers/cohere/models.py index 111f0b32..1642c7a6 100644 --- a/src/celeste/modalities/text/providers/cohere/models.py +++ b/src/celeste/modalities/text/providers/cohere/models.py @@ -7,6 +7,20 @@ from ...parameters import TextParameter MODELS: list[Model] = [ + Model( + id="command-a-plus-05-2026", + provider=Provider.COHERE, + display_name="Command A+ 05-2026", + operations={Modality.TEXT: {Operation.GENERATE, Operation.ANALYZE}}, + streaming=True, + parameter_constraints={ + Parameter.TEMPERATURE: Range(min=0.0, max=1.0, step=0.01), + Parameter.MAX_TOKENS: Range(min=1, max=65536, step=1), + TextParameter.THINKING_BUDGET: Range(min=-1, max=65536), + TextParameter.OUTPUT_SCHEMA: Schema(), + TextParameter.IMAGE: ImagesConstraint(), + }, + ), Model( id="command-a-vision-07-2025", provider=Provider.COHERE, diff --git a/src/celeste/modalities/text/providers/mistral/models.py b/src/celeste/modalities/text/providers/mistral/models.py index 67f56bcf..3a7a89fb 100644 --- a/src/celeste/modalities/text/providers/mistral/models.py +++ b/src/celeste/modalities/text/providers/mistral/models.py @@ -14,6 +14,22 @@ from ...parameters import TextParameter MODELS: list[Model] = [ + Model( + id="mistral-large-2512", + provider=Provider.MISTRAL, + display_name="Mistral Large 3 (25.12)", + operations={Modality.TEXT: {Operation.GENERATE, Operation.ANALYZE}}, + streaming=True, + parameter_constraints={ + Parameter.TEMPERATURE: Range(min=0.0, max=2.0, step=0.01), + Parameter.MAX_TOKENS: Range(min=1, max=32768, step=1), + TextParameter.OUTPUT_SCHEMA: Schema(), + TextParameter.IMAGE: ImagesConstraint(), + TextParameter.DOCUMENT: DocumentsConstraint(), + TextParameter.TOOLS: ToolSupport(tools=[]), + TextParameter.TOOL_CHOICE: ToolChoiceSupport(), + }, + ), Model( id="mistral-large-latest", provider=Provider.MISTRAL, @@ -60,6 +76,22 @@ TextParameter.TOOL_CHOICE: ToolChoiceSupport(), }, ), + Model( + id="mistral-small-2603", + provider=Provider.MISTRAL, + display_name="Mistral Small 4 (26.03)", + operations={Modality.TEXT: {Operation.GENERATE, Operation.ANALYZE}}, + streaming=True, + parameter_constraints={ + Parameter.TEMPERATURE: Range(min=0.0, max=2.0, step=0.01), + Parameter.MAX_TOKENS: Range(min=1, max=32768, step=1), + TextParameter.OUTPUT_SCHEMA: Schema(), + TextParameter.IMAGE: ImagesConstraint(), + TextParameter.DOCUMENT: DocumentsConstraint(), + TextParameter.TOOLS: ToolSupport(tools=[]), + TextParameter.TOOL_CHOICE: ToolChoiceSupport(), + }, + ), Model( id="mistral-small-latest", provider=Provider.MISTRAL, diff --git a/src/celeste/modalities/text/providers/openai/models.py b/src/celeste/modalities/text/providers/openai/models.py index d1383350..b7dbaf85 100644 --- a/src/celeste/modalities/text/providers/openai/models.py +++ b/src/celeste/modalities/text/providers/openai/models.py @@ -207,6 +207,60 @@ TextParameter.DOCUMENT: DocumentsConstraint(), }, ), + Model( + id="gpt-5.5", + provider=Provider.OPENAI, + display_name="GPT-5.5", + operations={Modality.TEXT: {Operation.GENERATE, Operation.ANALYZE}}, + streaming=True, + parameter_constraints={ + Parameter.MAX_TOKENS: Range(min=1, max=128000), + TextParameter.THINKING_BUDGET: Choice( + options=["minimal", "low", "medium", "high", "xhigh"] + ), + TextParameter.VERBOSITY: Choice(options=["low", "medium", "high"]), + TextParameter.TOOLS: ToolSupport(tools=[WebSearch]), + TextParameter.TOOL_CHOICE: ToolChoiceSupport(), + TextParameter.OUTPUT_SCHEMA: Schema(), + TextParameter.IMAGE: ImagesConstraint(), + TextParameter.DOCUMENT: DocumentsConstraint(), + }, + ), + Model( + id="gpt-5.4-mini", + provider=Provider.OPENAI, + display_name="GPT-5.4 Mini", + operations={Modality.TEXT: {Operation.GENERATE, Operation.ANALYZE}}, + streaming=True, + parameter_constraints={ + Parameter.MAX_TOKENS: Range(min=1, max=128000), + TextParameter.THINKING_BUDGET: Choice( + options=["minimal", "low", "medium", "high"] + ), + TextParameter.TOOLS: ToolSupport(tools=[WebSearch]), + TextParameter.TOOL_CHOICE: ToolChoiceSupport(), + TextParameter.OUTPUT_SCHEMA: Schema(), + TextParameter.IMAGE: ImagesConstraint(), + TextParameter.DOCUMENT: DocumentsConstraint(), + }, + ), + Model( + id="gpt-5.4-nano", + provider=Provider.OPENAI, + display_name="GPT-5.4 Nano", + operations={Modality.TEXT: {Operation.GENERATE, Operation.ANALYZE}}, + streaming=True, + parameter_constraints={ + Parameter.MAX_TOKENS: Range(min=1, max=128000), + TextParameter.THINKING_BUDGET: Choice( + options=["minimal", "low", "medium", "high"] + ), + TextParameter.TOOLS: ToolSupport(tools=[WebSearch]), + TextParameter.OUTPUT_SCHEMA: Schema(), + TextParameter.IMAGE: ImagesConstraint(), + TextParameter.DOCUMENT: DocumentsConstraint(), + }, + ), Model( id="gpt-5.4", provider=Provider.OPENAI, diff --git a/src/celeste/modalities/text/providers/xai/models.py b/src/celeste/modalities/text/providers/xai/models.py index ee45d1ee..cdce5bef 100644 --- a/src/celeste/modalities/text/providers/xai/models.py +++ b/src/celeste/modalities/text/providers/xai/models.py @@ -2,6 +2,7 @@ from celeste.constraints import ( Choice, + ImagesConstraint, Range, Schema, ToolChoiceSupport, @@ -14,6 +15,51 @@ from ...parameters import TextParameter MODELS: list[Model] = [ + Model( + id="grok-4.3", + provider=Provider.XAI, + display_name="Grok 4.3", + operations={Modality.TEXT: {Operation.GENERATE, Operation.ANALYZE}}, + streaming=True, + parameter_constraints={ + Parameter.TEMPERATURE: Range(min=0.0, max=2.0), + Parameter.MAX_TOKENS: Range(min=1, max=131072), + TextParameter.TOOLS: ToolSupport(tools=[WebSearch, XSearch, CodeExecution]), + TextParameter.TOOL_CHOICE: ToolChoiceSupport(), + TextParameter.OUTPUT_SCHEMA: Schema(), + TextParameter.IMAGE: ImagesConstraint(), + }, + ), + Model( + id="grok-4.20-0309-reasoning", + provider=Provider.XAI, + display_name="Grok 4.20 0309 Reasoning", + operations={Modality.TEXT: {Operation.GENERATE, Operation.ANALYZE}}, + streaming=True, + parameter_constraints={ + Parameter.TEMPERATURE: Range(min=0.0, max=2.0), + Parameter.MAX_TOKENS: Range(min=1, max=131072), + TextParameter.TOOLS: ToolSupport(tools=[WebSearch, XSearch, CodeExecution]), + TextParameter.TOOL_CHOICE: ToolChoiceSupport(), + TextParameter.OUTPUT_SCHEMA: Schema(), + TextParameter.IMAGE: ImagesConstraint(), + }, + ), + Model( + id="grok-4.20-0309-non-reasoning", + provider=Provider.XAI, + display_name="Grok 4.20 0309 Non Reasoning", + operations={Modality.TEXT: {Operation.GENERATE, Operation.ANALYZE}}, + streaming=True, + parameter_constraints={ + Parameter.TEMPERATURE: Range(min=0.0, max=2.0), + Parameter.MAX_TOKENS: Range(min=1, max=131072), + TextParameter.TOOLS: ToolSupport(tools=[WebSearch, XSearch, CodeExecution]), + TextParameter.TOOL_CHOICE: ToolChoiceSupport(), + TextParameter.OUTPUT_SCHEMA: Schema(), + TextParameter.IMAGE: ImagesConstraint(), + }, + ), Model( id="grok-4.20-beta-0309-reasoning", provider=Provider.XAI, diff --git a/src/celeste/modalities/videos/providers/byteplus/models.py b/src/celeste/modalities/videos/providers/byteplus/models.py index 9ed03815..78dda58b 100644 --- a/src/celeste/modalities/videos/providers/byteplus/models.py +++ b/src/celeste/modalities/videos/providers/byteplus/models.py @@ -4,7 +4,7 @@ Console display names differ from API model IDs. """ -from celeste.constraints import Choice, ImageConstraint, Range +from celeste.constraints import Choice, ImageConstraint, ImagesConstraint, Range from celeste.core import Modality, Operation, Provider from celeste.mime_types import ImageMimeType from celeste.models import Model @@ -70,4 +70,44 @@ ), }, ), + Model( + id="seedance-2-0-260128", + provider=Provider.BYTEPLUS, + operations={Modality.VIDEOS: {Operation.GENERATE}}, + display_name="Seedance 2.0", + parameter_constraints={ + VideoParameter.DURATION: Range(min=4, max=15), + VideoParameter.RESOLUTION: Choice(options=["480p", "720p"]), + VideoParameter.REFERENCE_IMAGES: ImagesConstraint( + supported_mime_types=BYTEPLUS_SUPPORTED_MIME_TYPES, + max_count=9, + ), + VideoParameter.FIRST_FRAME: ImageConstraint( + supported_mime_types=BYTEPLUS_SUPPORTED_MIME_TYPES, + ), + VideoParameter.LAST_FRAME: ImageConstraint( + supported_mime_types=BYTEPLUS_SUPPORTED_MIME_TYPES, + ), + }, + ), + Model( + id="seedance-2-0-fast-260128", + provider=Provider.BYTEPLUS, + operations={Modality.VIDEOS: {Operation.GENERATE}}, + display_name="Seedance 2.0 Fast", + parameter_constraints={ + VideoParameter.DURATION: Range(min=4, max=15), + VideoParameter.RESOLUTION: Choice(options=["480p", "720p"]), + VideoParameter.REFERENCE_IMAGES: ImagesConstraint( + supported_mime_types=BYTEPLUS_SUPPORTED_MIME_TYPES, + max_count=9, + ), + VideoParameter.FIRST_FRAME: ImageConstraint( + supported_mime_types=BYTEPLUS_SUPPORTED_MIME_TYPES, + ), + VideoParameter.LAST_FRAME: ImageConstraint( + supported_mime_types=BYTEPLUS_SUPPORTED_MIME_TYPES, + ), + }, + ), ] From f66c23e3c5a0c87bb9e7964bff648990e97e6072 Mon Sep 17 00:00:00 2001 From: kamilbenkirane Date: Wed, 20 May 2026 11:48:57 +0200 Subject: [PATCH 2/2] fix(xai): drop grok-4.20-beta catalog duplicates Remove beta-prefixed Grok 4.20 entries; xAI treats those slugs as API aliases only. Keep canonical grok-4.20-0309-* ids and point tests at them. Co-authored-by: Cursor --- .../modalities/text/providers/xai/models.py | 28 ------------------- tests/integration_tests/text/test_tools.py | 4 +-- .../test_text_modality_analyze_image.py | 2 +- 3 files changed, 3 insertions(+), 31 deletions(-) diff --git a/src/celeste/modalities/text/providers/xai/models.py b/src/celeste/modalities/text/providers/xai/models.py index cdce5bef..e2ff51fc 100644 --- a/src/celeste/modalities/text/providers/xai/models.py +++ b/src/celeste/modalities/text/providers/xai/models.py @@ -60,34 +60,6 @@ TextParameter.IMAGE: ImagesConstraint(), }, ), - Model( - id="grok-4.20-beta-0309-reasoning", - provider=Provider.XAI, - display_name="Grok 4.20 Beta 0309 Reasoning", - operations={Modality.TEXT: {Operation.GENERATE}}, - streaming=True, - parameter_constraints={ - Parameter.TEMPERATURE: Range(min=0.0, max=2.0), - Parameter.MAX_TOKENS: Range(min=1, max=30000), - TextParameter.TOOLS: ToolSupport(tools=[WebSearch, XSearch, CodeExecution]), - TextParameter.TOOL_CHOICE: ToolChoiceSupport(), - TextParameter.OUTPUT_SCHEMA: Schema(), - }, - ), - Model( - id="grok-4.20-beta-0309-non-reasoning", - provider=Provider.XAI, - display_name="Grok 4.20 Beta 0309 Non Reasoning", - operations={Modality.TEXT: {Operation.GENERATE}}, - streaming=True, - parameter_constraints={ - Parameter.TEMPERATURE: Range(min=0.0, max=2.0), - Parameter.MAX_TOKENS: Range(min=1, max=30000), - TextParameter.TOOLS: ToolSupport(tools=[WebSearch, XSearch, CodeExecution]), - TextParameter.TOOL_CHOICE: ToolChoiceSupport(), - TextParameter.OUTPUT_SCHEMA: Schema(), - }, - ), Model( id="grok-3-mini", provider=Provider.XAI, diff --git a/tests/integration_tests/text/test_tools.py b/tests/integration_tests/text/test_tools.py index 263f5afa..b3bfe517 100644 --- a/tests/integration_tests/text/test_tools.py +++ b/tests/integration_tests/text/test_tools.py @@ -22,7 +22,7 @@ ("anthropic", "claude-haiku-4-5"), ("openai", "gpt-4o-mini"), ("google", "gemini-2.5-flash"), - ("xai", "grok-4.20-beta-0309-non-reasoning"), + ("xai", "grok-4.20-0309-non-reasoning"), ] # One cheap model per provider for function tools (user-defined) @@ -135,7 +135,7 @@ async def test_xai_x_search() -> None: client = create_client( modality=Modality.TEXT, provider="xai", - model="grok-4.20-beta-0309-non-reasoning", + model="grok-4.20-0309-non-reasoning", ) output = await client.generate( diff --git a/tests/unit_tests/test_text_modality_analyze_image.py b/tests/unit_tests/test_text_modality_analyze_image.py index fa67112d..4d8e6cc7 100644 --- a/tests/unit_tests/test_text_modality_analyze_image.py +++ b/tests/unit_tests/test_text_modality_analyze_image.py @@ -239,7 +239,7 @@ def test_moonshot_init_request_includes_image_url_block() -> None: def test_xai_init_request_includes_input_image_block() -> None: model = Model( - id="grok-4.20-beta-0309-reasoning", + id="grok-4.20-0309-reasoning", provider=Provider.XAI, display_name="Grok 4", operations={Modality.TEXT: {Operation.GENERATE, Operation.ANALYZE}},