Skip to content

Commit c27e5e4

Browse files
authored
Support gemini-3-pro-image-preview with Nano Banana Pro (#3576)
1 parent adef17f commit c27e5e4

File tree

9 files changed

+658
-94
lines changed

9 files changed

+658
-94
lines changed

docs/builtin-tools.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ The [`ImageGenerationTool`][pydantic_ai.builtin_tools.ImageGenerationTool] enabl
202202
| Provider | Supported | Notes |
203203
|----------|-----------|-------|
204204
| OpenAI Responses || Full feature support. Only supported by models newer than `gpt-5`. Metadata about the generated image, like the [`revised_prompt`](https://platform.openai.com/docs/guides/tools-image-generation#revised-prompt) sent to the underlying image model, is available on the [`BuiltinToolReturnPart`][pydantic_ai.messages.BuiltinToolReturnPart] that's available via [`ModelResponse.builtin_tool_calls`][pydantic_ai.messages.ModelResponse.builtin_tool_calls]. |
205-
| Google || No parameter support. Only supported by [image generation models](https://ai.google.dev/gemini-api/docs/image-generation) like `gemini-2.5-flash-image`. These models do not support [structured output](output.md) or [function tools](tools.md). These models will always generate images, even if this built-in tool is not explicitly specified. |
205+
| Google || No parameter support. Only supported by [image generation models](https://ai.google.dev/gemini-api/docs/image-generation) like `gemini-2.5-flash-image` and `gemini-3-pro-image-preview`. These models do not support [function tools](tools.md). These models will always have the option of generating images, even if this built-in tool is not explicitly specified. |
206206
| Anthropic || |
207207
| Groq || |
208208
| Bedrock || |

pydantic_ai_slim/pydantic_ai/models/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@
156156
'google-gla:gemini-2.5-flash-lite-preview-09-2025',
157157
'google-gla:gemini-2.5-pro',
158158
'google-gla:gemini-3-pro-preview',
159+
'google-gla:gemini-3-pro-image-preview',
159160
'google-vertex:gemini-flash-latest',
160161
'google-vertex:gemini-flash-lite-latest',
161162
'google-vertex:gemini-2.0-flash',
@@ -167,6 +168,7 @@
167168
'google-vertex:gemini-2.5-flash-lite-preview-09-2025',
168169
'google-vertex:gemini-2.5-pro',
169170
'google-vertex:gemini-3-pro-preview',
171+
'google-vertex:gemini-3-pro-image-preview',
170172
'grok:grok-2-image-1212',
171173
'grok:grok-2-vision-1212',
172174
'grok:grok-3',

pydantic_ai_slim/pydantic_ai/models/google.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@
106106
'gemini-2.5-flash-lite-preview-09-2025',
107107
'gemini-2.5-pro',
108108
'gemini-3-pro-preview',
109+
'gemini-3-pro-image-preview',
109110
]
110111
"""Latest Gemini models."""
111112

@@ -420,7 +421,7 @@ async def _build_content_and_config(
420421
model_request_parameters: ModelRequestParameters,
421422
) -> tuple[list[ContentUnionDict], GenerateContentConfigDict]:
422423
tools = self._get_tools(model_request_parameters)
423-
if tools and not self.profile.supports_tools:
424+
if model_request_parameters.function_tools and not self.profile.supports_tools:
424425
raise UserError('Tools are not supported by this model.')
425426

426427
response_mime_type = None
@@ -559,7 +560,7 @@ async def _map_messages(
559560
)
560561
elif isinstance(part, RetryPromptPart):
561562
if part.tool_name is None:
562-
message_parts.append({'text': part.model_response()}) # pragma: no cover
563+
message_parts.append({'text': part.model_response()})
563564
else:
564565
message_parts.append(
565566
{
@@ -741,6 +742,11 @@ async def _get_event_iterator(self) -> AsyncIterator[ModelResponseStreamEvent]:
741742
if maybe_event is not None: # pragma: no branch
742743
yield maybe_event
743744
elif part.inline_data is not None:
745+
if part.thought: # pragma: no cover
746+
# Per https://ai.google.dev/gemini-api/docs/image-generation#thinking-process:
747+
# > The model generates up to two interim images to test composition and logic. The last image within Thinking is also the final rendered image.
748+
# We currently don't expose these image thoughts as they can't be represented with `ThinkingPart`
749+
continue
744750
data = part.inline_data.data
745751
mime_type = part.inline_data.mime_type
746752
assert data and mime_type, 'Inline data must have data and mime type'

pydantic_ai_slim/pydantic_ai/profiles/google.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ def google_model_profile(model_name: str) -> ModelProfile | None:
2525
return GoogleModelProfile(
2626
json_schema_transformer=GoogleJsonSchemaTransformer,
2727
supports_image_output=is_image_model,
28-
supports_json_schema_output=not is_image_model,
29-
supports_json_object_output=not is_image_model,
28+
supports_json_schema_output=is_3_or_newer or not is_image_model,
29+
supports_json_object_output=is_3_or_newer or not is_image_model,
3030
supports_tools=not is_image_model,
3131
google_supports_native_output_with_builtin_tools=is_3_or_newer,
3232
)

tests/models/cassettes/test_google/test_google_image_generation.yaml

Lines changed: 39 additions & 31 deletions
Large diffs are not rendered by default.

tests/models/cassettes/test_google/test_google_image_generation_with_native_output.yaml

Lines changed: 172 additions & 0 deletions
Large diffs are not rendered by default.

tests/models/cassettes/test_google/test_google_image_generation_with_text.yaml

Lines changed: 22 additions & 14 deletions
Large diffs are not rendered by default.

tests/models/cassettes/test_google/test_google_image_generation_with_web_search.yaml

Lines changed: 217 additions & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)