diff --git a/app/controllers/discourse_ai/admin/ai_personas_controller.rb b/app/controllers/discourse_ai/admin/ai_personas_controller.rb
index 2b57dda9..5d00f8cd 100644
--- a/app/controllers/discourse_ai/admin/ai_personas_controller.rb
+++ b/app/controllers/discourse_ai/admin/ai_personas_controller.rb
@@ -8,16 +8,25 @@ module DiscourseAi
before_action :find_ai_persona, only: %i[edit update destroy create_user]
def index
+ features_by_persona_id = DiscourseAi::Features.features.group_by { |f| f[:persona]&.id }
+
ai_personas =
- AiPersona.ordered.map do |persona|
- # we use a special serializer here cause names and descriptions are
- # localized for system personas
- LocalizedAiPersonaSerializer.new(persona, root: false)
- end
+ AiPersona
+ .ordered
+ .includes(:user, :uploads)
+ .map do |persona|
+ LocalizedAiPersonaSerializer.new(
+ persona,
+ root: false,
+ features_by_persona_id: features_by_persona_id,
+ )
+ end
+
tools =
DiscourseAi::Personas::Persona.all_available_tools.map do |tool|
AiToolSerializer.new(tool, root: false)
end
+
AiTool
.where(enabled: true)
.each do |tool|
@@ -31,10 +40,12 @@ module DiscourseAi
),
}
end
+
llms =
DiscourseAi::Configuration::LlmEnumerator.values_for_serialization(
allowed_seeded_llm_ids: SiteSetting.ai_bot_allowed_seeded_models_map,
)
+
render json: {
ai_personas: ai_personas,
meta: {
diff --git a/app/serializers/localized_ai_persona_serializer.rb b/app/serializers/localized_ai_persona_serializer.rb
index 52ff044b..5f7f328f 100644
--- a/app/serializers/localized_ai_persona_serializer.rb
+++ b/app/serializers/localized_ai_persona_serializer.rb
@@ -3,6 +3,11 @@
class LocalizedAiPersonaSerializer < ApplicationSerializer
root "ai_persona"
+ def initialize(object, options = {})
+ @features_by_persona_id = options.delete(:features_by_persona_id)
+ super(object, options)
+ end
+
attributes :id,
:name,
:description,
@@ -32,7 +37,8 @@ class LocalizedAiPersonaSerializer < ApplicationSerializer
:allow_personal_messages,
:force_default_llm,
:response_format,
- :examples
+ :examples,
+ :features
has_one :user, serializer: BasicUserSerializer, embed: :object
has_many :rag_uploads, serializer: UploadSerializer, embed: :object
diff --git a/assets/javascripts/discourse/components/ai-persona-list-editor.gjs b/assets/javascripts/discourse/components/ai-persona-list-editor.gjs
index 69cadec1..39dcd40e 100644
--- a/assets/javascripts/discourse/components/ai-persona-list-editor.gjs
+++ b/assets/javascripts/discourse/components/ai-persona-list-editor.gjs
@@ -1,13 +1,12 @@
import Component from "@glimmer/component";
-import { fn } from "@ember/helper";
-import { on } from "@ember/modifier";
import { action } from "@ember/object";
import { LinkTo } from "@ember/routing";
import { service } from "@ember/service";
import DBreadcrumbsItem from "discourse/components/d-breadcrumbs-item";
+import DButton from "discourse/components/d-button";
import DPageSubheader from "discourse/components/d-page-subheader";
-import DToggleSwitch from "discourse/components/d-toggle-switch";
import concatClass from "discourse/helpers/concat-class";
+import icon from "discourse/helpers/d-icon";
import { popupAjaxError } from "discourse/lib/ajax-error";
import { i18n } from "discourse-i18n";
import AdminConfigAreaEmptyList from "admin/components/admin-config-area-empty-list";
@@ -61,17 +60,18 @@ export default class AiPersonaListEditor extends Component {
{{i18n "discourse_ai.ai_persona.name"}}
- {{i18n "discourse_ai.ai_persona.list.enabled"}}
-
+ {{i18n "discourse_ai.features.short_title"}}