diff --git a/py/plugins/google-genai/src/genkit/plugins/google_genai/models/imagen.py b/py/plugins/google-genai/src/genkit/plugins/google_genai/models/imagen.py index b348891318..8d209be804 100644 --- a/py/plugins/google-genai/src/genkit/plugins/google_genai/models/imagen.py +++ b/py/plugins/google-genai/src/genkit/plugins/google_genai/models/imagen.py @@ -206,10 +206,11 @@ def _contents_from_response(self, response: genai_types.GenerateImagesResponse) content = [] if response.generated_images: for image in response.generated_images: + b64_data = base64.b64encode(image.image.image_bytes).decode('utf-8') content.append( Part( media=Media( - url=base64.b64encode(image.image.image_bytes), + url=f'data:{image.image.mime_type};base64,{b64_data}', contentType=image.image.mime_type, ) ) diff --git a/py/plugins/google-genai/src/genkit/plugins/google_genai/models/utils.py b/py/plugins/google-genai/src/genkit/plugins/google_genai/models/utils.py index 2940a8983a..7cb69c03bb 100644 --- a/py/plugins/google-genai/src/genkit/plugins/google_genai/models/utils.py +++ b/py/plugins/google-genai/src/genkit/plugins/google_genai/models/utils.py @@ -89,10 +89,13 @@ def to_gemini(cls, part: Part) -> genai.types.Part: ) ) if isinstance(part.root, MediaPart): + url = part.root.media.url + if not url.startswith(cls.DATA): + raise ValueError(f'Unsupported media URL for inline_data: {url}') + data = base64.b64decode(url.split(',', 1)[1]) return genai.types.Part( inline_data=genai.types.Blob( - data=part.root.media.url, - mime_type=part.root.media.content_type, + data=data, ) ) if isinstance(part.root, CustomPart): @@ -160,9 +163,10 @@ def from_gemini(cls, part: genai.types.Part) -> Part: ) ) if part.inline_data: + b64_data = base64.b64encode(part.inline_data.data).decode('utf-8') return Part( media=Media( - url=base64.b64encode(part.inline_data.data), + url=f'data:{part.inline_data.mime_type};base64,{b64_data}', contentType=part.inline_data.mime_type, ) ) diff --git a/py/plugins/google-genai/test/models/test_googlegenai_gemini.py b/py/plugins/google-genai/test/models/test_googlegenai_gemini.py index 6690d6a353..50c05b2b9a 100644 --- a/py/plugins/google-genai/test/models/test_googlegenai_gemini.py +++ b/py/plugins/google-genai/test/models/test_googlegenai_gemini.py @@ -14,9 +14,8 @@ # # SPDX-License-Identifier: Apache-2.0 -import base64 import sys -import unittest +import urllib.request from unittest.mock import ANY, AsyncMock, MagicMock, patch if sys.version_info < (3, 11): # noqa @@ -186,8 +185,8 @@ async def test_generate_media_response(mocker, version): assert content.root.media.content_type == response_mimetype - decoded_url = base64.b64decode(content.root.media.url) - assert decoded_url == response_byte_string + with urllib.request.urlopen(content.root.media.url) as response: + assert response.read() == response_byte_string def test_convert_schema_property(mocker): diff --git a/py/plugins/google-genai/test/models/test_googlegenai_imagen.py b/py/plugins/google-genai/test/models/test_googlegenai_imagen.py index a91ee21599..c884389193 100644 --- a/py/plugins/google-genai/test/models/test_googlegenai_imagen.py +++ b/py/plugins/google-genai/test/models/test_googlegenai_imagen.py @@ -15,6 +15,7 @@ # SPDX-License-Identifier: Apache-2.0 import base64 +import urllib.request import pytest from google import genai @@ -76,5 +77,5 @@ async def test_generate_media_response(mocker, version): assert content.root.media.content_type == response_mimetype - decoded_url = base64.b64decode(content.root.media.url) - assert decoded_url == response_byte_string + with urllib.request.urlopen(content.root.media.url) as response: + assert response.read() == response_byte_string diff --git a/py/samples/google-genai-hello/src/google_genai_hello.py b/py/samples/google-genai-hello/src/google_genai_hello.py index b504fdbb4a..2c8da83e98 100644 --- a/py/samples/google-genai-hello/src/google_genai_hello.py +++ b/py/samples/google-genai-hello/src/google_genai_hello.py @@ -116,7 +116,6 @@ async def simple_generate_with_tools_flow(value: int, ctx: ActionRunContext) -> The generated response with a function. """ response = await ai.generate( - model='googleai/gemini-2.5-flash', prompt=f'what is a gablorken of {value}', tools=['gablorkenTool'], on_chunk=ctx.send_chunk, @@ -149,7 +148,6 @@ async def simple_generate_with_interrupts(value: int) -> str: The generated response with a function. """ response1 = await ai.generate( - model='googleai/gemini-2.5-flash', messages=[ Message( role=Role.USER, @@ -164,7 +162,6 @@ async def simple_generate_with_interrupts(value: int) -> str: tr = tool_response(response1.interrupts[0], 178) response = await ai.generate( - model='googleai/gemini-2.5-flash', messages=response1.messages, tool_responses=[tr], tools=['gablorkenTool'],