Commit
·
16407bf
1
Parent(s):
965275f
Add detailed debugging for Gemini API response parsing
Browse files- Add debug logs to show response structure and candidates
- Log each part type and content to diagnose why images aren't being extracted
- Log text responses (error messages) from Gemini
- Log full response on failure for better error diagnosis
- This will help identify why Gemini is returning no image
- src/core.py +45 -11
src/core.py
CHANGED
|
@@ -167,27 +167,61 @@ def _call_gemini_edit(
|
|
| 167 |
|
| 168 |
output_img: Image.Image | None = None
|
| 169 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 170 |
# Extract first image from response parts
|
| 171 |
try:
|
| 172 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 173 |
parts = getattr(candidate, "content", None)
|
| 174 |
-
if not parts
|
|
|
|
| 175 |
continue
|
| 176 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 177 |
inline = getattr(part, "inline_data", None)
|
| 178 |
-
if inline
|
| 179 |
-
|
| 180 |
-
if
|
| 181 |
-
data =
|
| 182 |
-
|
| 183 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 184 |
if output_img:
|
| 185 |
break
|
| 186 |
except Exception as err:
|
| 187 |
-
log.
|
| 188 |
|
| 189 |
if output_img is None:
|
| 190 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 191 |
|
| 192 |
# Ensure output matches original dimensions if Gemini rescaled
|
| 193 |
if output_img.size != target_size:
|
|
|
|
| 167 |
|
| 168 |
output_img: Image.Image | None = None
|
| 169 |
|
| 170 |
+
# Debug: log response structure
|
| 171 |
+
log.debug("Gemini response type: %s", type(response))
|
| 172 |
+
log.debug("Gemini response has candidates: %s", hasattr(response, "candidates"))
|
| 173 |
+
|
| 174 |
# Extract first image from response parts
|
| 175 |
try:
|
| 176 |
+
candidates = getattr(response, "candidates", [])
|
| 177 |
+
log.debug("Number of candidates: %d", len(candidates))
|
| 178 |
+
|
| 179 |
+
for idx, candidate in enumerate(candidates):
|
| 180 |
+
log.debug("Candidate %d type: %s", idx, type(candidate))
|
| 181 |
parts = getattr(candidate, "content", None)
|
| 182 |
+
if not parts:
|
| 183 |
+
log.debug("Candidate %d has no content", idx)
|
| 184 |
continue
|
| 185 |
+
response_parts = getattr(parts, "parts", None)
|
| 186 |
+
if not response_parts:
|
| 187 |
+
log.debug("Candidate %d content has no parts", idx)
|
| 188 |
+
continue
|
| 189 |
+
log.debug("Candidate %d has %d parts", idx, len(response_parts))
|
| 190 |
+
|
| 191 |
+
for part_idx, part in enumerate(response_parts):
|
| 192 |
+
log.debug("Part %d type: %s", part_idx, type(part))
|
| 193 |
inline = getattr(part, "inline_data", None)
|
| 194 |
+
if inline:
|
| 195 |
+
log.debug("Part %d has inline_data, mime_type: %s", part_idx, getattr(inline, "mime_type", None))
|
| 196 |
+
if inline.data:
|
| 197 |
+
data = inline.data
|
| 198 |
+
if isinstance(data, str):
|
| 199 |
+
data = base64.b64decode(data)
|
| 200 |
+
output_img = Image.open(BytesIO(data)).convert("RGB")
|
| 201 |
+
log.info("Successfully extracted image from Gemini response")
|
| 202 |
+
break
|
| 203 |
+
else:
|
| 204 |
+
# Check if part has text (might be an error message)
|
| 205 |
+
text = getattr(part, "text", None)
|
| 206 |
+
if text:
|
| 207 |
+
log.warning("Gemini returned text instead of image in part %d: %s", part_idx, text[:200])
|
| 208 |
if output_img:
|
| 209 |
break
|
| 210 |
except Exception as err:
|
| 211 |
+
log.error("Failed to parse Gemini response image: %s", err, exc_info=True)
|
| 212 |
|
| 213 |
if output_img is None:
|
| 214 |
+
# Log full response for debugging
|
| 215 |
+
try:
|
| 216 |
+
response_text = str(response)
|
| 217 |
+
log.error("Gemini generate_content returned no image. Full response (first 500 chars): %s", response_text[:500])
|
| 218 |
+
# Try to extract any error messages
|
| 219 |
+
if hasattr(response, "prompt_feedback"):
|
| 220 |
+
feedback = response.prompt_feedback
|
| 221 |
+
log.error("Prompt feedback: %s", feedback)
|
| 222 |
+
except Exception:
|
| 223 |
+
pass
|
| 224 |
+
raise RuntimeError("Gemini generate_content returned no image. Check logs for details.")
|
| 225 |
|
| 226 |
# Ensure output matches original dimensions if Gemini rescaled
|
| 227 |
if output_img.size != target_size:
|