Retry truncated Ollama character analysis
This commit is contained in:
@@ -438,9 +438,10 @@ _PROVIDER_DEFAULTS = {
|
||||
}
|
||||
|
||||
_ANALYZE_PROMPT = (
|
||||
"Describe the character's physical appearance in two concise sentences. "
|
||||
"Specify their hair color/style, face details, and their clothing type/color. "
|
||||
"Keep the entire response very brief."
|
||||
"Describe only the visible character in exactly two complete sentences. "
|
||||
"Sentence 1 must cover hair, face, age impression, and any standout physical traits. "
|
||||
"Sentence 2 must cover clothing, accessories, and overall silhouette. "
|
||||
"Do not start with fragments like 'The'. Do not mention image quality, background, framing, or emotions."
|
||||
)
|
||||
|
||||
|
||||
@@ -470,6 +471,17 @@ def _extract_ollama_generated_text(resp_json: dict) -> str:
|
||||
return ""
|
||||
|
||||
|
||||
def _analysis_text_is_usable(text: str) -> bool:
|
||||
text = (text or "").strip()
|
||||
if not text:
|
||||
return False
|
||||
if len(text) < 24:
|
||||
return False
|
||||
if len(text.split()) < 6:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def _resolve_provider(data):
|
||||
provider = (data.get("provider") or "ollama").lower()
|
||||
defs = _PROVIDER_DEFAULTS.get(provider, _PROVIDER_DEFAULTS["ollama"])
|
||||
@@ -515,8 +527,15 @@ async def analyze_character_endpoint(request):
|
||||
async with aiohttp.ClientSession() as session:
|
||||
if provider == "ollama":
|
||||
payload = {
|
||||
"model": model_name, "prompt": _ANALYZE_PROMPT,
|
||||
"images": cleaned_b64_list, "stream": False, "keep_alive": 0,
|
||||
"model": model_name,
|
||||
"prompt": _ANALYZE_PROMPT,
|
||||
"images": cleaned_b64_list,
|
||||
"stream": False,
|
||||
"keep_alive": 0,
|
||||
"options": {
|
||||
"temperature": 0.2,
|
||||
"num_predict": 120,
|
||||
},
|
||||
}
|
||||
async with session.post(f"{base_url}/api/generate", json=payload, timeout=300) as response:
|
||||
if response.status != 200:
|
||||
@@ -525,9 +544,9 @@ async def analyze_character_endpoint(request):
|
||||
resp_json = await response.json()
|
||||
generated_text = _extract_ollama_generated_text(resp_json)
|
||||
|
||||
# Some Ollama model variants return an empty `response` from `/api/generate`
|
||||
# even though the same request succeeds via the chat endpoint.
|
||||
if not generated_text:
|
||||
# Some Ollama model variants return an empty or truncated response from
|
||||
# `/api/generate` even though the same request succeeds via the chat endpoint.
|
||||
if not _analysis_text_is_usable(generated_text):
|
||||
chat_payload = {
|
||||
"model": model_name,
|
||||
"messages": [{
|
||||
@@ -537,6 +556,10 @@ async def analyze_character_endpoint(request):
|
||||
}],
|
||||
"stream": False,
|
||||
"keep_alive": 0,
|
||||
"options": {
|
||||
"temperature": 0.2,
|
||||
"num_predict": 120,
|
||||
},
|
||||
}
|
||||
async with session.post(f"{base_url}/api/chat", json=chat_payload, timeout=300) as response:
|
||||
if response.status == 200:
|
||||
@@ -574,10 +597,10 @@ async def analyze_character_endpoint(request):
|
||||
|
||||
if "<think>" in generated_text:
|
||||
generated_text = generated_text.split("</think>")[-1].strip()
|
||||
if not generated_text:
|
||||
if not _analysis_text_is_usable(generated_text):
|
||||
return web.json_response({
|
||||
"status": "error",
|
||||
"message": f"{provider} returned an empty analysis response.",
|
||||
"message": f"{provider} returned an empty or truncated analysis response.",
|
||||
})
|
||||
|
||||
log.info("[LTXDirector] Analysis complete: %s", generated_text)
|
||||
|
||||
Reference in New Issue
Block a user