Expose truncated Ollama analysis candidates

This commit is contained in:
OpenClaw Agent
2026-07-10 11:33:26 +00:00
parent 27f1d6a1e4
commit b059974544

View File

@@ -477,6 +477,30 @@ def _extract_ollama_generated_text(resp_json: dict) -> str:
return max(cleaned_candidates, key=len) return max(cleaned_candidates, key=len)
def _collect_ollama_text_candidates(resp_json: dict) -> list[str]:
if not isinstance(resp_json, dict):
return []
candidates = [resp_json.get("response"), resp_json.get("content"), resp_json.get("thinking")]
message = resp_json.get("message")
if isinstance(message, dict):
candidates.extend([
message.get("content"),
message.get("reasoning_content"),
message.get("thinking"),
])
cleaned = []
for candidate in candidates:
if isinstance(candidate, str):
text = candidate.strip()
if "<think>" in text:
text = text.split("</think>")[-1].strip()
if text:
cleaned.append(text)
return cleaned
def _analysis_text_is_usable(text: str) -> bool: def _analysis_text_is_usable(text: str) -> bool:
text = (text or "").strip() text = (text or "").strip()
if not text: if not text:
@@ -555,6 +579,7 @@ async def analyze_character_endpoint(request):
try: try:
async with aiohttp.ClientSession() as session: async with aiohttp.ClientSession() as session:
if provider == "ollama": if provider == "ollama":
debug_candidates = []
analysis_images = cleaned_b64_list analysis_images = cleaned_b64_list
payload = { payload = {
"model": model_name, "model": model_name,
@@ -578,11 +603,13 @@ async def analyze_character_endpoint(request):
retry_err = await retry_response.text() retry_err = await retry_response.text()
return web.json_response({"status": "error", "message": f"Ollama HTTP {retry_response.status}: {retry_err}"}) return web.json_response({"status": "error", "message": f"Ollama HTTP {retry_response.status}: {retry_err}"})
resp_json = await retry_response.json() resp_json = await retry_response.json()
debug_candidates.extend(_collect_ollama_text_candidates(resp_json))
generated_text = _extract_ollama_generated_text(resp_json) generated_text = _extract_ollama_generated_text(resp_json)
else: else:
return web.json_response({"status": "error", "message": f"Ollama HTTP {response.status}: {err_txt}"}) return web.json_response({"status": "error", "message": f"Ollama HTTP {response.status}: {err_txt}"})
else: else:
resp_json = await response.json() resp_json = await response.json()
debug_candidates.extend(_collect_ollama_text_candidates(resp_json))
generated_text = _extract_ollama_generated_text(resp_json) generated_text = _extract_ollama_generated_text(resp_json)
if not _analysis_text_is_usable(generated_text): if not _analysis_text_is_usable(generated_text):
@@ -603,9 +630,17 @@ async def analyze_character_endpoint(request):
async with session.post(f"{base_url}/api/chat", json=chat_payload, timeout=300) as response: async with session.post(f"{base_url}/api/chat", json=chat_payload, timeout=300) as response:
if response.status == 200: if response.status == 200:
resp_json = await response.json() resp_json = await response.json()
debug_candidates.extend(_collect_ollama_text_candidates(resp_json))
chat_text = _extract_ollama_generated_text(resp_json) chat_text = _extract_ollama_generated_text(resp_json)
if _analysis_text_is_usable(chat_text): if _analysis_text_is_usable(chat_text):
generated_text = chat_text generated_text = chat_text
if not _analysis_text_is_usable(generated_text):
return web.json_response({
"status": "error",
"message": "Ollama returned only a truncated analysis response.",
"debug_candidates": debug_candidates,
"description": generated_text,
})
else: else:
# OpenAI-compatible vision chat (LM Studio / Custom). # OpenAI-compatible vision chat (LM Studio / Custom).
content = [{"type": "text", "text": _ANALYZE_PROMPT}] content = [{"type": "text", "text": _ANALYZE_PROMPT}]