fix: seed outfit factory config
This commit is contained in:
@@ -130,6 +130,88 @@ def _seed_factory_config_if_missing(filename):
|
||||
return False
|
||||
|
||||
|
||||
def _factory_config_path(filename):
|
||||
"""Return the packaged factory config path under the program root."""
|
||||
from services.file_service import get_app_dir
|
||||
return get_app_dir() / "config" / filename
|
||||
|
||||
|
||||
def _load_json_file(path):
|
||||
with open(str(path), encoding="utf-8-sig") as f:
|
||||
return json.load(f)
|
||||
|
||||
|
||||
def _model_list_from_data(data):
|
||||
models = data.get("models") if isinstance(data, dict) else data
|
||||
return models if isinstance(models, list) else None
|
||||
|
||||
|
||||
def _model_name(model):
|
||||
if not isinstance(model, dict):
|
||||
return ""
|
||||
return str(model.get("name", "")).strip()
|
||||
|
||||
|
||||
def _append_missing_title_model(models_file):
|
||||
"""Append the configured title model from factory ai_models.json if missing.
|
||||
|
||||
Existing user models and API keys are never overwritten. This only handles
|
||||
the upgrade case where a user already has ai_models.json but lacks the new
|
||||
app_config.title_model entry (docs/11 §6.1).
|
||||
"""
|
||||
title_model_name = str(load_config().get("title_model", "")).strip()
|
||||
if not title_model_name or not models_file.exists():
|
||||
return False
|
||||
|
||||
try:
|
||||
user_data = _load_json_file(models_file)
|
||||
except (json.JSONDecodeError, ValueError, OSError) as exc:
|
||||
logger.warning("AI models file unreadable (%s): %s", exc, models_file)
|
||||
return False
|
||||
|
||||
user_models = _model_list_from_data(user_data)
|
||||
if user_models is None:
|
||||
logger.warning("AI models file has no model list: %s", models_file)
|
||||
return False
|
||||
if any(_model_name(model) == title_model_name for model in user_models):
|
||||
return False
|
||||
|
||||
factory_file = _factory_config_path(_AI_MODELS_FILENAME)
|
||||
if not factory_file.exists():
|
||||
logger.info("Factory AI models template not found: %s", factory_file)
|
||||
return False
|
||||
|
||||
try:
|
||||
factory_data = _load_json_file(factory_file)
|
||||
except (json.JSONDecodeError, ValueError, OSError) as exc:
|
||||
logger.warning("Factory AI models template unreadable (%s): %s", exc, factory_file)
|
||||
return False
|
||||
|
||||
factory_models = _model_list_from_data(factory_data) or []
|
||||
title_model = None
|
||||
for model in factory_models:
|
||||
if _model_name(model) == title_model_name:
|
||||
title_model = dict(model)
|
||||
break
|
||||
if title_model is None:
|
||||
logger.info(
|
||||
"Factory AI models template has no title model named %s: %s",
|
||||
title_model_name,
|
||||
factory_file,
|
||||
)
|
||||
return False
|
||||
|
||||
try:
|
||||
user_models.append(title_model)
|
||||
with open(str(models_file), "w", encoding="utf-8") as f:
|
||||
json.dump(user_data, f, ensure_ascii=False, indent=2)
|
||||
logger.info("Appended missing title model %s to %s", title_model_name, models_file)
|
||||
return True
|
||||
except OSError as exc:
|
||||
logger.warning("Failed to append title model to %s: %s", models_file, exc)
|
||||
return False
|
||||
|
||||
|
||||
def load_ai_models():
|
||||
"""Load AI model configs from ai_models.json.
|
||||
|
||||
@@ -140,17 +222,17 @@ def load_ai_models():
|
||||
from services.file_service import get_config_path
|
||||
_seed_factory_config_if_missing(_AI_MODELS_FILENAME)
|
||||
models_file = get_config_path(_AI_MODELS_FILENAME)
|
||||
_append_missing_title_model(models_file)
|
||||
if not models_file.exists():
|
||||
logger.info("AI models file not found: %s", models_file)
|
||||
return []
|
||||
try:
|
||||
with open(str(models_file), encoding="utf-8-sig") as f:
|
||||
data = json.load(f)
|
||||
data = _load_json_file(models_file)
|
||||
except (json.JSONDecodeError, ValueError, OSError) as exc:
|
||||
logger.warning("AI models file unreadable (%s): %s", exc, models_file)
|
||||
return []
|
||||
|
||||
models = data.get("models") if isinstance(data, dict) else data
|
||||
models = _model_list_from_data(data)
|
||||
if not isinstance(models, list):
|
||||
logger.warning("AI models file has no model list: %s", models_file)
|
||||
return []
|
||||
@@ -160,6 +242,7 @@ def load_ai_models():
|
||||
def load_outfit_prompt():
|
||||
"""Return the saved outfit prompt template, or the built-in default."""
|
||||
from services.file_service import get_config_path
|
||||
_seed_factory_config_if_missing(_OUTFIT_PROMPT_FILENAME)
|
||||
prompt_file = get_config_path(_OUTFIT_PROMPT_FILENAME)
|
||||
if not prompt_file.exists():
|
||||
return DEFAULT_OUTFIT_PROMPT
|
||||
@@ -187,6 +270,7 @@ def save_outfit_prompt(text):
|
||||
def load_title_prompt():
|
||||
"""Return the saved 标题生成提示词, or the built-in default (docs/11 §17.3)."""
|
||||
from services.file_service import get_config_path
|
||||
_seed_factory_config_if_missing(_TITLE_PROMPT_FILENAME)
|
||||
prompt_file = get_config_path(_TITLE_PROMPT_FILENAME)
|
||||
if not prompt_file.exists():
|
||||
return DEFAULT_TITLE_PROMPT
|
||||
|
||||
Reference in New Issue
Block a user