Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions instructor/processing/multimodal.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,19 @@ def from_gs_url(cls, data_uri: str, timeout: int = 30) -> Image:
def from_raw_base64(cls, data: str) -> Image:
try:
decoded = base64.b64decode(data)
import imghdr

img_type = imghdr.what(None, decoded)
# Detect image type from file signature (magic bytes)
# This replaces imghdr which was removed in Python 3.13
img_type = None
if decoded.startswith(b'\xff\xd8\xff'):
img_type = 'jpeg'
elif decoded.startswith(b'\x89PNG\r\n\x1a\n'):
img_type = 'png'
elif decoded.startswith(b'GIF87a') or decoded.startswith(b'GIF89a'):
img_type = 'gif'
elif decoded.startswith(b'RIFF') and decoded[8:12] == b'WEBP':
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding a bounds check (e.g. len(decoded) >= 12) before accessing decoded[8:12] to avoid potential IndexError on very short inputs.

Suggested change
elif decoded.startswith(b'RIFF') and decoded[8:12] == b'WEBP':
elif decoded.startswith(b'RIFF') and len(decoded) >= 12 and decoded[8:12] == b'WEBP':

img_type = 'webp'

if img_type:
media_type = f"image/{img_type}"
if media_type in VALID_MIME_TYPES:
Expand Down
2 changes: 1 addition & 1 deletion instructor/providers/gemini/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -961,7 +961,7 @@ def handle_vertexai_tools(
def handle_vertexai_json(
response_model: type[Any] | None, new_kwargs: dict[str, Any]
) -> tuple[type[Any] | None, dict[str, Any]]:
from instructor.client_vertexai import vertexai_process_json_response
from instructor.providers.vertexai.client import vertexai_process_json_response

"""
Handle Vertex AI JSON mode.
Expand Down
6 changes: 5 additions & 1 deletion tests/test_response_model_conversion.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@

def get_system_prompt(user_tool_definition, mode):
if mode == instructor.Mode.ANTHROPIC_JSON:
return user_tool_definition["system"]
system = user_tool_definition["system"]
# Handle both string and list[dict] formats
if isinstance(system, list):
return "".join(block.get("text", "") for block in system)
return system
elif mode == instructor.Mode.GEMINI_JSON:
return "\n".join(user_tool_definition["contents"][0]["parts"])
elif mode == instructor.Mode.VERTEXAI_JSON:
Expand Down
Loading