import tempfile import unittest from pathlib import Path try: import tomllib except ModuleNotFoundError: # Python < 3.11 import tomli as tomllib from app.config import config as cfg from app.config.defaults import ( get_openai_compatible_ui_values, normalize_openai_compatible_model_name, ) class ConfigBootstrapDefaultsTests(unittest.TestCase): def test_load_config_bootstraps_webui_llm_defaults(self): original_root_dir = cfg.root_dir original_config_file = cfg.config_file with tempfile.TemporaryDirectory() as tmp_dir: tmp_path = Path(tmp_dir) example_file = tmp_path / "config.example.toml" example_file.write_text( """ [app] vision_llm_provider = "openai" vision_openai_model_name = "gemini/gemini-2.0-flash-lite" vision_openai_api_key = "" vision_openai_base_url = "" text_llm_provider = "openai" text_openai_model_name = "deepseek/deepseek-chat" text_openai_api_key = "" text_openai_base_url = "" hide_config = true """.strip() + "\n", encoding="utf-8", ) config_path = tmp_path / "config.toml" try: cfg.root_dir = str(tmp_path) cfg.config_file = str(config_path) config_data = cfg.load_config() saved_config = tomllib.loads(config_path.read_text(encoding="utf-8")) finally: cfg.root_dir = original_root_dir cfg.config_file = original_config_file self.assertEqual("openai", config_data["app"]["vision_llm_provider"]) self.assertEqual("Qwen/Qwen3.5-122B-A10B", config_data["app"]["vision_openai_model_name"]) self.assertEqual("https://api.siliconflow.cn/v1", config_data["app"]["vision_openai_base_url"]) self.assertEqual(1.0, config_data["app"]["vision_openai_temperature"]) self.assertEqual(0.95, config_data["app"]["vision_openai_top_p"]) self.assertEqual("openai", config_data["app"]["text_llm_provider"]) self.assertEqual("Pro/zai-org/GLM-5", config_data["app"]["text_openai_model_name"]) self.assertEqual("https://api.siliconflow.cn/v1", config_data["app"]["text_openai_base_url"]) self.assertEqual(1.0, config_data["app"]["text_openai_temperature"]) self.assertEqual(0.95, config_data["app"]["text_openai_top_p"]) self.assertEqual("Qwen/Qwen3.5-122B-A10B", saved_config["app"]["vision_openai_model_name"]) self.assertEqual("Pro/zai-org/GLM-5", saved_config["app"]["text_openai_model_name"]) self.assertTrue(saved_config["app"]["hide_config"]) def test_legacy_indextts2_config_is_migrated_to_indextts_15(self): migrated = cfg.migrate_indextts_config( { "indextts2": {"api_url": "http://127.0.0.1:8081/tts"}, "ui": { "tts_engine": "indextts2", "voice_name": "indextts2:/tmp/reference.wav", }, } ) self.assertEqual("http://127.0.0.1:8081/tts", migrated["indextts"]["api_url"]) self.assertNotIn("indextts2", migrated) self.assertEqual("indextts", migrated["ui"]["tts_engine"]) self.assertEqual("indextts:/tmp/reference.wav", migrated["ui"]["voice_name"]) def test_indextts2_config_is_kept_as_separate_engine(self): migrated = cfg.migrate_indextts_config( { "indextts": {"api_url": "http://127.0.0.1:8081/tts"}, "indextts2": { "api_url": "http://192.168.3.6:7863/tts", "emotion_mode": "speaker", }, "ui": { "tts_engine": "indextts2", "voice_name": "indextts2:/tmp/reference.wav", }, } ) self.assertEqual("http://127.0.0.1:8081/tts", migrated["indextts"]["api_url"]) self.assertEqual("http://192.168.3.6:7863/tts", migrated["indextts2"]["api_url"]) self.assertEqual("indextts2", migrated["ui"]["tts_engine"]) self.assertEqual("indextts2:/tmp/reference.wav", migrated["ui"]["voice_name"]) class OpenAICompatibleModelDefaultsTests(unittest.TestCase): def test_ui_keeps_full_model_name_and_openai_provider(self): provider, model_name = get_openai_compatible_ui_values( "Qwen/Qwen3.5-122B-A10B", "fallback-model", ) self.assertEqual("openai", provider) self.assertEqual("Qwen/Qwen3.5-122B-A10B", model_name) def test_normalize_only_strips_openai_prefix(self): self.assertEqual( "Qwen/Qwen3.5-122B-A10B", normalize_openai_compatible_model_name("openai/Qwen/Qwen3.5-122B-A10B"), ) self.assertEqual( "Qwen/Qwen3.5-122B-A10B", normalize_openai_compatible_model_name("Qwen/Qwen3.5-122B-A10B"), ) if __name__ == "__main__": unittest.main()