Recognize local vision models so their images aren't dropped (#185)

An image attachment only got through if the model name was on a short
built-in list. Anything else was treated as text-only and the image was
quietly dropped, so the model never saw it. That left out a lot of the
smaller vision models you can run locally (moondream was the one I hit).

Pulled the check into is_vision_model() in chat_helpers, broadened it to
cover those, and added a test. Models that already worked are unaffected.

Fixes #124.
This commit is contained in:
Håkon Julius Størholt
2026-06-01 06:09:21 +02:00
committed by GitHub
parent 32e7cec362
commit 91d3511580
3 changed files with 62 additions and 12 deletions

View File

@@ -15,7 +15,7 @@ from src.constants import (
UPLOAD_DIR,
)
from core.models import ChatMessage
from src.chat_helpers import extract_urls
from src.chat_helpers import extract_urls, is_vision_model
from src.document_processor import build_user_content, analyze_image_with_vl_result
from src.youtube_handler import (
is_youtube_url,
@@ -147,17 +147,7 @@ class ChatHandler:
# Analyze images — skip if vision disabled, or if main model is vision-capable
from src.settings import get_setting
vision_enabled = get_setting("vision_enabled", True)
VISION_KEYWORDS = [
"gpt-4o", "gpt-4.1", "gpt-4.5", "gpt-4-turbo", "gpt-4-vision",
"claude-sonnet", "claude-opus", "claude-haiku",
"gemini", "llava", "pixtral", "qwen2-vl", "qwen-vl", "qwen3-vl", "qwen3vl", "minicpm",
]
main_model = (sess.model or "").lower()
main_is_vision = any(kw in main_model for kw in VISION_KEYWORDS)
# Also match models with "vl" in the name (e.g. Qwen3VL, InternVL, any *-VL-*)
if not main_is_vision:
import re
main_is_vision = bool(re.search(r'\dvl|vl\d|[-_]vl[-_.\d]|vl-', main_model))
main_is_vision = is_vision_model(sess.model or "")
# Read uploads DB once and index by id (was read twice + linear-scanned per attachment)
files_by_id: Dict[str, Dict] = {}