feat: default model metadata & params

This commit is contained in:
Timothy Jaeryang Baek
2026-02-22 16:54:34 -06:00
parent 32aabe6bae
commit c341f97cfe
8 changed files with 364 additions and 108 deletions

View File

@@ -1263,6 +1263,18 @@ MODEL_ORDER_LIST = PersistentConfig(
[],
)
DEFAULT_MODEL_METADATA = PersistentConfig(
"DEFAULT_MODEL_METADATA",
"models.default_metadata",
{},
)
DEFAULT_MODEL_PARAMS = PersistentConfig(
"DEFAULT_MODEL_PARAMS",
"models.default_params",
{},
)
DEFAULT_USER_ROLE = PersistentConfig(
"DEFAULT_USER_ROLE",
"ui.default_user_role",

View File

@@ -394,6 +394,8 @@ from open_webui.config import (
DEFAULT_PINNED_MODELS,
DEFAULT_ARENA_MODEL,
MODEL_ORDER_LIST,
DEFAULT_MODEL_METADATA,
DEFAULT_MODEL_PARAMS,
EVALUATION_ARENA_MODELS,
# WebUI (OAuth)
ENABLE_OAUTH_ROLE_MANAGEMENT,
@@ -822,6 +824,8 @@ app.state.config.ADMIN_EMAIL = ADMIN_EMAIL
app.state.config.DEFAULT_MODELS = DEFAULT_MODELS
app.state.config.DEFAULT_PINNED_MODELS = DEFAULT_PINNED_MODELS
app.state.config.MODEL_ORDER_LIST = MODEL_ORDER_LIST
app.state.config.DEFAULT_MODEL_METADATA = DEFAULT_MODEL_METADATA
app.state.config.DEFAULT_MODEL_PARAMS = DEFAULT_MODEL_PARAMS
app.state.config.DEFAULT_PROMPT_SUGGESTIONS = DEFAULT_PROMPT_SUGGESTIONS
@@ -1688,9 +1692,14 @@ async def chat_completion(
request.state.direct = True
request.state.model = model
model_info_params = (
model_info.params.model_dump() if model_info and model_info.params else {}
# Model params: global defaults as base, per-model overrides win
default_model_params = (
getattr(request.app.state.config, "DEFAULT_MODEL_PARAMS", None) or {}
)
model_info_params = {
**default_model_params,
**(model_info.params.model_dump() if model_info and model_info.params else {}),
}
# Check base model existence for custom models
if model_info_params.get("base_model_id"):

View File

@@ -467,6 +467,8 @@ class ModelsConfigForm(BaseModel):
DEFAULT_MODELS: Optional[str]
DEFAULT_PINNED_MODELS: Optional[str]
MODEL_ORDER_LIST: Optional[list[str]]
DEFAULT_MODEL_METADATA: Optional[dict] = None
DEFAULT_MODEL_PARAMS: Optional[dict] = None
@router.get("/models", response_model=ModelsConfigForm)
@@ -475,6 +477,8 @@ async def get_models_config(request: Request, user=Depends(get_admin_user)):
"DEFAULT_MODELS": request.app.state.config.DEFAULT_MODELS,
"DEFAULT_PINNED_MODELS": request.app.state.config.DEFAULT_PINNED_MODELS,
"MODEL_ORDER_LIST": request.app.state.config.MODEL_ORDER_LIST,
"DEFAULT_MODEL_METADATA": request.app.state.config.DEFAULT_MODEL_METADATA,
"DEFAULT_MODEL_PARAMS": request.app.state.config.DEFAULT_MODEL_PARAMS,
}
@@ -485,10 +489,14 @@ async def set_models_config(
request.app.state.config.DEFAULT_MODELS = form_data.DEFAULT_MODELS
request.app.state.config.DEFAULT_PINNED_MODELS = form_data.DEFAULT_PINNED_MODELS
request.app.state.config.MODEL_ORDER_LIST = form_data.MODEL_ORDER_LIST
request.app.state.config.DEFAULT_MODEL_METADATA = form_data.DEFAULT_MODEL_METADATA
request.app.state.config.DEFAULT_MODEL_PARAMS = form_data.DEFAULT_MODEL_PARAMS
return {
"DEFAULT_MODELS": request.app.state.config.DEFAULT_MODELS,
"DEFAULT_PINNED_MODELS": request.app.state.config.DEFAULT_PINNED_MODELS,
"MODEL_ORDER_LIST": request.app.state.config.MODEL_ORDER_LIST,
"DEFAULT_MODEL_METADATA": request.app.state.config.DEFAULT_MODEL_METADATA,
"DEFAULT_MODEL_PARAMS": request.app.state.config.DEFAULT_MODEL_PARAMS,
}

View File

@@ -1,3 +1,4 @@
import copy
import time
import logging
import asyncio
@@ -307,6 +308,29 @@ async def get_all_models(request, refresh: bool = False, user: UserModel = None)
except Exception as e:
log.info(f"Failed to load function module for {function_id}: {e}")
# Apply global model defaults to all models
# Per-model overrides take precedence over global defaults
default_metadata = (
getattr(request.app.state.config, "DEFAULT_MODEL_METADATA", None) or {}
)
if default_metadata:
for model in models:
info = model.get("info")
if info is None:
model["info"] = {"meta": copy.deepcopy(default_metadata)}
continue
meta = info.setdefault("meta", {})
for key, value in default_metadata.items():
if key == "capabilities":
# Merge capabilities: defaults as base, per-model overrides win
existing = meta.get("capabilities") or {}
meta["capabilities"] = {**value, **existing}
elif meta.get(key) is None:
meta[key] = copy.deepcopy(value)
for model in models:
action_ids = [
action_id