diff --git a/ai-hub/app/core/services/preference.py b/ai-hub/app/core/services/preference.py index 7c4fe55..387663f 100644 --- a/ai-hub/app/core/services/preference.py +++ b/ai-hub/app/core/services/preference.py @@ -63,26 +63,24 @@ return is_success or bool(has_key) # Build effective combined config for processing - def get_effective_providers(section_name, user_section_providers, sys_defaults): - # M6/M3: Deep merge system defaults with user overrides. - # This ensures that if a user configures a model name in the UI, - # they don't lose the API key from config.yaml if it's not provided in the UI. - - # Start with system defaults (config.yaml / env) + def get_effective_providers(section_name, user_section_providers, sys_defaults, user_section_data): + # M6: If the user provides a configuration for a provider that already exists + # in the system defaults, we want to "Add" it as a personal account + # rather than "Overriding" the system default. This allows both to coexist. effective = copy.deepcopy(sys_defaults) + user_active = user_section_data.get("active_provider") - # Layer on overrides (Admin or User) if user_section_providers: for p_id, p_data in user_section_providers.items(): - if p_id not in effective: - # New provider defined in UI - effective[p_id] = copy.deepcopy(p_data) - else: - # Override existing provider fields - for field, val in p_data.items(): - # Only override if the value is meaningful (not empty/null) - if val is not None and val != "" and str(val).lower() != "none": - effective[p_id][field] = val + target_id = p_id + if p_id in effective: + # Collision: Create a distinct personal resource + target_id = f"{p_id}_personal" + # Update the user's active selection to point to their personal version + if user_active == p_id: + user_section_data["active_provider"] = target_id + + effective[target_id] = copy.deepcopy(p_data) # Filter by health and mask keys for the response res = {} @@ -120,7 +118,7 @@ return merged system_llm = get_merged_system_defaults("llm", settings.LLM_PROVIDERS) - llm_providers_effective = get_effective_providers("llm", llm_prefs["providers"], system_llm) + llm_providers_effective = get_effective_providers("llm", llm_prefs["providers"], system_llm, llm_prefs) system_tts = get_merged_system_defaults("tts", { settings.TTS_PROVIDER: { @@ -129,12 +127,12 @@ "voice": settings.TTS_VOICE_NAME } }) - tts_providers_effective = get_effective_providers("tts", tts_prefs["providers"], system_tts) + tts_providers_effective = get_effective_providers("tts", tts_prefs["providers"], system_tts, tts_prefs) system_stt = get_merged_system_defaults("stt", { settings.STT_PROVIDER: {"api_key": settings.STT_API_KEY, "model": settings.STT_MODEL_NAME} }) - stt_providers_effective = get_effective_providers("stt", stt_prefs["providers"], system_stt) + stt_providers_effective = get_effective_providers("stt", stt_prefs["providers"], system_stt, stt_prefs) effective = { "llm": {