From 6551b4f6c35162b16a672d049fdeac1cafb8f4b8 Mon Sep 17 00:00:00 2001 From: OpenClaw Agent Date: Fri, 10 Jul 2026 10:46:04 +0000 Subject: [PATCH] Add JSON fallback for Ollama character analysis --- ltx_director.py | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/ltx_director.py b/ltx_director.py index 83c192b..4581aee 100644 --- a/ltx_director.py +++ b/ltx_director.py @@ -564,6 +564,24 @@ def _prepare_analysis_images(cleaned_b64_list: list[str], max_dim: int = 768, qu _compress_analysis_image_b64(b64, max_dim=max_dim, quality=quality) for b64 in cleaned_b64_list ] + + +def _extract_json_description(text: str) -> str: + text = (text or "").strip() + if not text: + return "" + try: + start = text.find("{") + end = text.rfind("}") + if start != -1 and end != -1 and end > start: + payload = json.loads(text[start:end + 1]) + if isinstance(payload, dict): + description = payload.get("description") + if isinstance(description, str): + return description.strip() + except Exception: + return "" + return "" def _resolve_provider(data): @@ -683,6 +701,29 @@ async def analyze_character_endpoint(request): return web.json_response({"status": "error", "message": f"Ollama HTTP {retry_response.status}: {err_txt}"}) else: return web.json_response({"status": "error", "message": f"Ollama HTTP {response.status}: {err_txt}"}) + if not _analysis_text_is_usable(generated_text) and analysis_images: + json_prompt = ( + 'Return JSON only with this exact shape: ' + '{"description":"two concise sentences describing only the visible character\'s appearance"}' + ) + single_image = [analysis_images[0]] + json_payload = { + "model": model_name, + "prompt": json_prompt, + "images": single_image, + "stream": False, + "format": "json", + "keep_alive": 0, + "options": { + "temperature": 0.1, + "num_predict": 120, + }, + } + async with session.post(f"{base_url}/api/generate", json=json_payload, timeout=300) as response: + if response.status == 200: + resp_json = await response.json() + raw_text = _extract_ollama_generated_text(resp_json) + generated_text = _extract_json_description(raw_text) or raw_text else: # OpenAI-compatible vision chat (LM Studio / Custom). content = [{"type": "text", "text": _ANALYZE_PROMPT}]