Private
Public Access
0
0

fix(ai_client): extract Gemini thought=True parts and wrap in <thinking> tags for parse_thinking_trace

This commit is contained in:
2026-06-15 14:10:43 -04:00
parent 81882c398e
commit e9abadc867
+23
View File
@@ -1536,6 +1536,26 @@ def _ensure_gemini_client() -> None:
creds = _load_credentials()
_gemini_client = genai.Client(api_key=creds["gemini"]["api_key"])
def _extract_gemini_thoughts(resp: Any) -> str:
"""
Extracts concatenated thinking text from a Gemini response object's parts.
Parts with thought=True are thinking segments; parts with thought=False or unset are visible text.
The google-genai SDK filters thoughts out of resp.text, so we must scan parts directly.
Returns "" if no thoughts are present.
"""
chunks: list[str] = []
try:
candidates = getattr(resp, "candidates", None) or []
for cand in candidates:
content = getattr(cand, "content", None)
if content is None: continue
parts = getattr(content, "parts", None) or []
for p in parts:
if getattr(p, "thought", False) and getattr(p, "text", None):
chunks.append(p.text)
except Exception: pass
return "".join(chunks).strip()
def _get_gemini_history_list(chat: Any | None) -> list[Any]:
if not chat: return []
if hasattr(chat, "_history"): return cast(list[Any], chat._history)
@@ -1782,6 +1802,9 @@ def _send_gemini(md_content: str, user_message: str, base_dir: str,
_append_comms("OUT", "tool_result_send", {"results": log})
payload = f_resps
res = "\n\n".join(all_text) if all_text else "(No text returned)"
thought_text = _extract_gemini_thoughts(final_resp if stream_callback else resp)
if thought_text:
res = f"<thinking>\n{thought_text}\n</thinking>\n\n{res}"
if monitor.enabled: monitor.end_component("ai_client._send_gemini")
return Result(data=res)
except Exception as e: