Add vision model support to LLM Manager admin and rename index for clarity

This commit is contained in:
2026-03-29 17:03:59 +00:00
parent 90db904959
commit fb38a881d9
3 changed files with 43 additions and 0 deletions

View File

@@ -166,6 +166,8 @@ Titania provides TLS termination and reverse proxy for all services.
| `peitho.ouranos.helu.ca` | puck.incus:22981 | Peitho (Django) |
| `pgadmin.ouranos.helu.ca` | prospero.incus:443 (SSL) | PgAdmin 4 |
| `prometheus.ouranos.helu.ca` | prospero.incus:443 (SSL) | Prometheus |
| `freecad-mcp.ouranos.helu.ca` | caliban.incus:22032 | FreeCAD Robust MCP Server |
| `rommie.ouranos.helu.ca` | caliban.incus:22031 | Rommie MCP Server (Agent S GUI automation) |
| `searxng.ouranos.helu.ca` | oberon.incus:22073 | SearXNG (OAuth2-Proxy) |
| `smtp4dev.ouranos.helu.ca` | oberon.incus:22085 | smtp4dev |
| `spelunker.ouranos.helu.ca` | puck.incus:22881 | Spelunker (Django) |

View File

@@ -100,6 +100,7 @@ class LLMModelAdmin(admin.ModelAdmin):
"system_embedding_badge",
"system_chat_badge",
"system_reranker_badge",
"system_vision_badge",
"is_active",
"created_at",
)
@@ -113,6 +114,7 @@ class LLMModelAdmin(admin.ModelAdmin):
"is_system_embedding_model",
"is_system_chat_model",
"is_system_reranker_model",
"is_system_vision_model",
)
search_fields = ("name", "display_name", "api__name")
readonly_fields = (
@@ -121,11 +123,13 @@ class LLMModelAdmin(admin.ModelAdmin):
"is_system_embedding_model",
"is_system_chat_model",
"is_system_reranker_model",
"is_system_vision_model",
)
actions = [
"set_as_system_embedding_model",
"set_as_system_chat_model",
"set_as_system_reranker_model",
"set_as_system_vision_model",
]
fieldsets = (
("Model Info", {"fields": ("api", "name", "display_name", "model_type", "is_active")}),
@@ -136,6 +140,7 @@ class LLMModelAdmin(admin.ModelAdmin):
"is_system_embedding_model",
"is_system_chat_model",
"is_system_reranker_model",
"is_system_vision_model",
),
"classes": ("collapse",),
"description": (
@@ -208,6 +213,16 @@ class LLMModelAdmin(admin.ModelAdmin):
system_reranker_badge.short_description = "Reranker Default"
def system_vision_badge(self, obj):
if obj.is_system_vision_model and obj.model_type in ("vision", "chat"):
return format_html(
'<span style="background:#6f42c1;color:white;padding:3px 8px;'
'border-radius:3px;font-weight:bold;">SYSTEM DEFAULT</span>'
)
return ""
system_vision_badge.short_description = "Vision Default"
# --- System model actions -----------------------------------------------
def _set_system_model(self, request, queryset, model_type, field_name, label):
@@ -225,6 +240,8 @@ class LLMModelAdmin(admin.ModelAdmin):
valid_types = [model_type]
if model_type == "embedding":
valid_types = ["embedding", "multimodal_embed"]
elif model_type == "vision":
valid_types = ["vision", "chat"]
if new_model.model_type not in valid_types:
self.message_user(
@@ -269,6 +286,11 @@ class LLMModelAdmin(admin.ModelAdmin):
set_as_system_reranker_model.short_description = "Set as System Reranker Model"
def set_as_system_vision_model(self, request, queryset):
self._set_system_model(request, queryset, "vision", "is_system_vision_model", "vision model")
set_as_system_vision_model.short_description = "Set as System Vision Model"
def save_model(self, request, obj, form, change):
"""Ensure only ONE model per type is marked as system default."""
type_field_map = {
@@ -276,6 +298,7 @@ class LLMModelAdmin(admin.ModelAdmin):
"multimodal_embed": "is_system_embedding_model",
"chat": "is_system_chat_model",
"reranker": "is_system_reranker_model",
"vision": "is_system_vision_model",
}
for mtype, field in type_field_map.items():
if getattr(obj, field, False) and obj.model_type == mtype:

View File

@@ -0,0 +1,18 @@
# Generated by Django 5.2.11 on 2026-03-22 15:15
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("llm_manager", "0003_add_vision_model_and_usage"),
]
operations = [
migrations.RenameIndex(
model_name="llmmodel",
new_name="llm_manager_is_syst_d190bb_idx",
old_name="llm_manager__is_syst_b2f4e7_idx",
),
]