From 5a29074799d2b5bb7e5df5e251f2d72a3d8a3670 Mon Sep 17 00:00:00 2001 From: Keegan George Date: Thu, 10 Jul 2025 11:54:35 -0700 Subject: [PATCH] DEV: Use default LLM model --- config/locales/client.en.yml | 2 +- config/settings.yml | 8 +++---- ...0250710173803_seed_ai_default_llm_model.rb | 16 +++++++++++++ ..._summarization_model_to_persona_default.rb | 23 +++++++++++++++++++ ...copy_ai_helper_model_to_persona_default.rb | 23 +++++++++++++++++++ lib/ai_helper/assistant.rb | 14 +++-------- lib/embeddings/semantic_search.rb | 5 ++-- lib/summarization.rb | 5 ++-- 8 files changed, 74 insertions(+), 22 deletions(-) create mode 100644 db/migrate/20250710173803_seed_ai_default_llm_model.rb create mode 100644 db/migrate/20250710180401_copy_ai_summarization_model_to_persona_default.rb create mode 100644 db/migrate/20250710181656_copy_ai_helper_model_to_persona_default.rb diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index ec4b9632..8e797711 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -183,7 +183,7 @@ en: default_llm: title: "Default LLM model" - description: "The default LLM model to use for all AI features. This will be used if no LLM is specified in the feature configuration or persona." + description: "The default LLM model to use for all AI features. This will be used if no LLM is specified in the feature configuration or persona. If no default LLM is specified, the last created LLM will be used." features: short_title: "Features" diff --git a/config/settings.yml b/config/settings.yml index 59bfea04..d5bfa8a3 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -109,7 +109,7 @@ discourse_ai: default: false client: true area: "ai-features/ai_helper" - ai_helper_model: + ai_helper_model: # Deprecated. TODO(keegan): Remove 2025-09-01 default: "" allow_any: false type: enum @@ -155,7 +155,7 @@ discourse_ai: - "context_menu" - "image_caption" area: "ai-features/ai_helper" - ai_helper_image_caption_model: + ai_helper_image_caption_model: # Deprecated. TODO(keegan): Remove 2025-09-01 default: "" type: enum enum: "DiscourseAi::Configuration::LlmVisionEnumerator" @@ -266,7 +266,7 @@ discourse_ai: client: true validator: "DiscourseAi::Configuration::LlmDependencyValidator" area: "ai-features/embeddings" - ai_embeddings_semantic_search_hyde_model: + ai_embeddings_semantic_search_hyde_model: # Deprecated. TODO(keegan): Remove 2025-09-01 default: "" type: enum allow_any: false @@ -322,7 +322,7 @@ discourse_ai: client: true validator: "DiscourseAi::Configuration::LlmDependencyValidator" area: "ai-features/summarization" - ai_summarization_model: + ai_summarization_model: # Deprecated. TODO(keegan): Remove 2025-09-01 default: "" allow_any: false type: enum diff --git a/db/migrate/20250710173803_seed_ai_default_llm_model.rb b/db/migrate/20250710173803_seed_ai_default_llm_model.rb new file mode 100644 index 00000000..c9710613 --- /dev/null +++ b/db/migrate/20250710173803_seed_ai_default_llm_model.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true +class SeedAiDefaultLlmModel < ActiveRecord::Migration[7.2] + def up + return if DB.query_single("SELECT 1 FROM llm_models LIMIT 1").empty? + + last_model_id = DB.query_single("SELECT id FROM llm_models ORDER BY id DESC LIMIT 1").first + + if last_model_id.present? + execute "UPDATE site_settings SET value = 'custom:#{last_model_id}' WHERE name = 'ai_default_llm_model' AND (value IS NULL OR value = '');" + end + end + + def down + raise ActiveRecord::IrreversibleMigration + end +end diff --git a/db/migrate/20250710180401_copy_ai_summarization_model_to_persona_default.rb b/db/migrate/20250710180401_copy_ai_summarization_model_to_persona_default.rb new file mode 100644 index 00000000..ef286cb3 --- /dev/null +++ b/db/migrate/20250710180401_copy_ai_summarization_model_to_persona_default.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true +class CopyAiSummarizationModelToPersonaDefault < ActiveRecord::Migration[7.2] + def up + ai_summarization_model = + DB.query_single("SELECT value FROM site_settings WHERE name = 'ai_summarization_model'").first + + if ai_summarization_model.present? && ai_summarization_model.start_with?("custom:") + # Extract the model ID from the setting value (e.g., "custom:-5" -> "-5") + model_id = ai_summarization_model.split(":").last + + # Update the summarization personas (IDs -11 and -12) with the extracted model ID + execute(<<~SQL) + UPDATE ai_personas + SET default_llm_id = #{model_id} + WHERE id IN (-11, -12) AND default_llm_id IS NULL + SQL + end + end + + def down + raise ActiveRecord::IrreversibleMigration + end +end diff --git a/db/migrate/20250710181656_copy_ai_helper_model_to_persona_default.rb b/db/migrate/20250710181656_copy_ai_helper_model_to_persona_default.rb new file mode 100644 index 00000000..0b4187b1 --- /dev/null +++ b/db/migrate/20250710181656_copy_ai_helper_model_to_persona_default.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true +class CopyAiHelperModelToPersonaDefault < ActiveRecord::Migration[7.2] + def up + ai_helper_model = + DB.query_single("SELECT value FROM site_settings WHERE name = 'ai_helper_model'").first + + if ai_helper_model.present? && ai_helper_model.start_with?("custom:") + # Extract the model ID from the setting value (e.g., "custom:1" -> "1") + model_id = ai_helper_model.split(":").last + + # Update the helper personas with the extracted model ID + execute(<<~SQL) + UPDATE ai_personas + SET default_llm_id = #{model_id} + WHERE id IN (-18, -19, -20, -21, -22, -23, -24, -25, -26) AND default_llm_id IS NULL + SQL + end + end + + def down + raise ActiveRecord::IrreversibleMigration + end +end diff --git a/lib/ai_helper/assistant.rb b/lib/ai_helper/assistant.rb index be61e415..8081e9cd 100644 --- a/lib/ai_helper/assistant.rb +++ b/lib/ai_helper/assistant.rb @@ -312,18 +312,10 @@ module DiscourseAi # Priorities are: # 1. Persona's default LLM - # 2. Hidden `ai_helper_model` setting, or `ai_helper_image_caption_model` for image_caption. - # 3. Newest LLM config + # 2. SiteSetting.ai_default_llm_id (or newest LLM if not set) def self.find_ai_helper_model(helper_mode, persona_klass) - model_id = persona_klass.default_llm_id - - if !model_id - if helper_mode == IMAGE_CAPTION - model_id = SiteSetting.ai_helper_image_caption_model&.split(":")&.last - else - model_id = SiteSetting.ai_helper_model&.split(":")&.last - end - end + model_id = + persona_klass.default_llm_id || SiteSetting.ai_default_llm_model&.split(":")&.last # Remove legacy custom provider. if model_id.present? LlmModel.find_by(id: model_id) diff --git a/lib/embeddings/semantic_search.rb b/lib/embeddings/semantic_search.rb index 726f203d..3ed27920 100644 --- a/lib/embeddings/semantic_search.rb +++ b/lib/embeddings/semantic_search.rb @@ -210,11 +210,10 @@ module DiscourseAi # Priorities are: # 1. Persona's default LLM - # 2. `ai_embeddings_semantic_search_hyde_model` setting. + # 2. SiteSetting.ai_default_llm_id (or newest LLM if not set) def find_ai_hyde_model(persona_klass) model_id = - persona_klass.default_llm_id || - SiteSetting.ai_embeddings_semantic_search_hyde_model&.split(":")&.last + persona_klass.default_llm_id || SiteSetting.ai_default_llm_model&.split(":")&.last # Remove legacy custom provider. return if model_id.blank? diff --git a/lib/summarization.rb b/lib/summarization.rb index a7b69763..f530b89b 100644 --- a/lib/summarization.rb +++ b/lib/summarization.rb @@ -54,11 +54,10 @@ module DiscourseAi # Priorities are: # 1. Persona's default LLM - # 2. Hidden `ai_summarization_model` setting - # 3. Newest LLM config + # 2. SiteSetting.ai_default_llm_id (or newest LLM if not set) def find_summarization_model(persona_klass) model_id = - persona_klass.default_llm_id || SiteSetting.ai_summarization_model&.split(":")&.last # Remove legacy custom provider. + persona_klass.default_llm_id || SiteSetting.ai_default_llm_model&.split(":")&.last # Remove legacy custom provider. if model_id.present? LlmModel.find_by(id: model_id)