Auto-select Ollama vision model for analysis
This commit is contained in:
@@ -432,11 +432,24 @@ async def ltx_director_check_file(request):
|
|||||||
|
|
||||||
|
|
||||||
# --- Provider defaults shared by the analyze + unload endpoints ---
|
# --- Provider defaults shared by the analyze + unload endpoints ---
|
||||||
_PROVIDER_DEFAULTS = {
|
_PROVIDER_DEFAULTS = {
|
||||||
"ollama": {"url": "http://127.0.0.1:11434", "model": "huihui_ai/qwen3.5-abliterated:2b"},
|
"ollama": {"url": "http://127.0.0.1:11434", "model": "huihui_ai/qwen3.5-abliterated:2b"},
|
||||||
"lmstudio": {"url": "http://127.0.0.1:1234", "model": ""},
|
"lmstudio": {"url": "http://127.0.0.1:1234", "model": ""},
|
||||||
"custom": {"url": "", "model": ""},
|
"custom": {"url": "", "model": ""},
|
||||||
}
|
}
|
||||||
|
_OLLAMA_VISION_MODEL_HINTS = (
|
||||||
|
"qwen2.5vl",
|
||||||
|
"qwen2.5-vl",
|
||||||
|
"qwen2vl",
|
||||||
|
"qwen2-vl",
|
||||||
|
"llava",
|
||||||
|
"bakllava",
|
||||||
|
"minicpm-v",
|
||||||
|
"minicpm",
|
||||||
|
"moondream",
|
||||||
|
"gemma3",
|
||||||
|
"internvl",
|
||||||
|
)
|
||||||
|
|
||||||
_ANALYZE_PROMPT = (
|
_ANALYZE_PROMPT = (
|
||||||
"Describe only the visible character in exactly two complete sentences. "
|
"Describe only the visible character in exactly two complete sentences. "
|
||||||
@@ -582,6 +595,13 @@ def _extract_json_description(text: str) -> str:
|
|||||||
except Exception:
|
except Exception:
|
||||||
return ""
|
return ""
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
def _is_likely_vision_model_name(model_name: str) -> bool:
|
||||||
|
lower = (model_name or "").strip().lower()
|
||||||
|
if not lower:
|
||||||
|
return False
|
||||||
|
return any(hint in lower for hint in _OLLAMA_VISION_MODEL_HINTS)
|
||||||
|
|
||||||
|
|
||||||
def _resolve_provider(data):
|
def _resolve_provider(data):
|
||||||
@@ -623,12 +643,45 @@ async def analyze_character_endpoint(request):
|
|||||||
"message": f"No model name set for {provider}. Open the gear menu and enter your loaded model's name.",
|
"message": f"No model name set for {provider}. Open the gear menu and enter your loaded model's name.",
|
||||||
})
|
})
|
||||||
|
|
||||||
log.info("[LTXDirector] Analyzing Character %d via %s (%s, model '%s')...",
|
log.info("[LTXDirector] Analyzing Character %d via %s (%s, model '%s')...",
|
||||||
char_index + 1, provider, base_url, model_name)
|
char_index + 1, provider, base_url, model_name)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
if provider == "ollama":
|
if provider == "ollama":
|
||||||
|
requested_model_name = model_name
|
||||||
|
if not _is_likely_vision_model_name(model_name):
|
||||||
|
try:
|
||||||
|
async with session.get(f"{base_url}/api/tags", timeout=20) as tags_response:
|
||||||
|
if tags_response.status == 200:
|
||||||
|
tags_json = await tags_response.json()
|
||||||
|
models = tags_json.get("models") or []
|
||||||
|
candidate_names = []
|
||||||
|
for item in models:
|
||||||
|
if isinstance(item, dict):
|
||||||
|
name = item.get("name") or item.get("model")
|
||||||
|
if isinstance(name, str):
|
||||||
|
candidate_names.append(name)
|
||||||
|
vision_candidates = [name for name in candidate_names if _is_likely_vision_model_name(name)]
|
||||||
|
if vision_candidates:
|
||||||
|
model_name = vision_candidates[0]
|
||||||
|
log.info(
|
||||||
|
"[LTXDirector] Auto-selected Ollama vision model '%s' instead of non-vision default '%s'.",
|
||||||
|
model_name, requested_model_name,
|
||||||
|
)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if not _is_likely_vision_model_name(model_name):
|
||||||
|
return web.json_response({
|
||||||
|
"status": "error",
|
||||||
|
"message": (
|
||||||
|
"No Ollama vision model is configured. The current default "
|
||||||
|
f"'{requested_model_name}' is not a vision model. Install/select a vision model "
|
||||||
|
"such as qwen2.5vl, llava, moondream, minicpm-v, or gemma3."
|
||||||
|
),
|
||||||
|
})
|
||||||
|
|
||||||
generated_text = ""
|
generated_text = ""
|
||||||
payload = {
|
payload = {
|
||||||
"model": model_name,
|
"model": model_name,
|
||||||
|
|||||||
Reference in New Issue
Block a user