Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6351c401f8 | ||
|
|
acd3ac2371 | ||
|
|
c61af76d86 | ||
|
|
cd7790f39a | ||
|
|
4fcf12287f |
+7
@@ -0,0 +1,7 @@
|
||||
import DiscourseRoute from "discourse/routes/discourse";
|
||||
|
||||
export default DiscourseRoute.extend({
|
||||
model() {
|
||||
return this.modelFor("adminPlugins.show.discourse-ai.ai-personas");
|
||||
},
|
||||
});
|
||||
+1
-1
@@ -17,7 +17,7 @@ export default DiscourseRoute.extend({
|
||||
this._super(controller, model);
|
||||
controller.set(
|
||||
"allPersonas",
|
||||
this.modelFor("adminPlugins.show.discourse-ai-personas")
|
||||
this.modelFor("adminPlugins.show.discourse-ai.ai-personas")
|
||||
);
|
||||
},
|
||||
});
|
||||
+2
-2
@@ -3,7 +3,7 @@ import DiscourseRoute from "discourse/routes/discourse";
|
||||
export default DiscourseRoute.extend({
|
||||
async model(params) {
|
||||
const allPersonas = this.modelFor(
|
||||
"adminPlugins.show.discourse-ai-personas"
|
||||
"adminPlugins.show.discourse-ai.ai-personas"
|
||||
);
|
||||
const id = parseInt(params.id, 10);
|
||||
return allPersonas.findBy("id", id);
|
||||
@@ -13,7 +13,7 @@ export default DiscourseRoute.extend({
|
||||
this._super(controller, model);
|
||||
controller.set(
|
||||
"allPersonas",
|
||||
this.modelFor("adminPlugins.show.discourse-ai-personas")
|
||||
this.modelFor("adminPlugins.show.discourse-ai.ai-personas")
|
||||
);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,12 @@
|
||||
import { inject as service } from "@ember/service";
|
||||
import DiscourseRoute from "discourse/routes/discourse";
|
||||
|
||||
export default class DiscourseAiIndexRoute extends DiscourseRoute {
|
||||
@service router;
|
||||
|
||||
beforeModel() {
|
||||
return this.router.transitionTo(
|
||||
"adminPlugins.show.discourse-ai.ai-personas.index"
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -125,6 +125,7 @@ module DiscourseAi
|
||||
:rag_chunk_overlap_tokens,
|
||||
:rag_conversation_chunks,
|
||||
:question_consolidator_llm,
|
||||
:role,
|
||||
allowed_group_ids: [],
|
||||
rag_uploads: [:id],
|
||||
)
|
||||
|
||||
@@ -10,7 +10,13 @@ module ::Jobs
|
||||
persona_id = args[:persona_id]
|
||||
|
||||
begin
|
||||
persona = DiscourseAi::AiBot::Personas::Persona.find_by(user: post.user, id: persona_id)
|
||||
persona =
|
||||
if args[:skip_persona_security_check]
|
||||
persona = AiPersona.all_personas.find { |persona| persona.id == persona_id }
|
||||
else
|
||||
persona = DiscourseAi::AiBot::Personas::Persona.find_by(user: post.user, id: persona_id)
|
||||
end
|
||||
|
||||
raise DiscourseAi::AiBot::Bot::BOT_NOT_FOUND if persona.nil?
|
||||
|
||||
bot = DiscourseAi::AiBot::Bot.as(bot_user, persona: persona.new)
|
||||
|
||||
@@ -46,6 +46,10 @@ class AiPersona < ActiveRecord::Base
|
||||
.map(&:class_instance)
|
||||
end
|
||||
|
||||
def self.persona_class_by_id(id)
|
||||
AiPersona.all_personas.find { |persona| persona.id == id } if id
|
||||
end
|
||||
|
||||
def self.persona_users(user: nil)
|
||||
persona_users =
|
||||
persona_cache[:persona_users] ||= AiPersona
|
||||
@@ -72,6 +76,42 @@ class AiPersona < ActiveRecord::Base
|
||||
end
|
||||
end
|
||||
|
||||
def self.topic_responder_for(category_id:)
|
||||
return nil if !category_id
|
||||
|
||||
all_responders =
|
||||
persona_cache[:topic_responders] ||= AiPersona
|
||||
.where(role: "topic_responder")
|
||||
.where(enabled: true)
|
||||
.pluck(:id, :role_category_ids)
|
||||
|
||||
id, _ = all_responders.find { |id, role_category_ids| role_category_ids.include?(category_id) }
|
||||
|
||||
if id
|
||||
{ id: id }
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def self.message_responder_for(group_id: nil)
|
||||
return nil if !group_id
|
||||
|
||||
all_responders =
|
||||
persona_cache[:message_responders] ||= AiPersona
|
||||
.where(role: "message_responder")
|
||||
.where(enabled: true)
|
||||
.pluck(:id, :role_group_ids)
|
||||
|
||||
id, _ = all_responders.find { |id, role_group_ids| role_group_ids.include?(group_id) }
|
||||
|
||||
if id
|
||||
{ id: id }
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def self.mentionables(user: nil)
|
||||
all_mentionables =
|
||||
persona_cache[:mentionable_usernames] ||= AiPersona
|
||||
@@ -114,6 +154,8 @@ class AiPersona < ActiveRecord::Base
|
||||
vision_max_pixels = self.vision_max_pixels
|
||||
rag_conversation_chunks = self.rag_conversation_chunks
|
||||
question_consolidator_llm = self.question_consolidator_llm
|
||||
role = self.role
|
||||
role_whispers = self.role_whispers
|
||||
|
||||
persona_class = DiscourseAi::AiBot::Personas::Persona.system_personas_by_id[self.id]
|
||||
if persona_class
|
||||
@@ -161,6 +203,14 @@ class AiPersona < ActiveRecord::Base
|
||||
rag_conversation_chunks
|
||||
end
|
||||
|
||||
persona_class.define_singleton_method :role_whispers do
|
||||
role_whispers
|
||||
end
|
||||
|
||||
persona_class.define_singleton_method :role do
|
||||
role
|
||||
end
|
||||
|
||||
return persona_class
|
||||
end
|
||||
|
||||
@@ -252,6 +302,14 @@ class AiPersona < ActiveRecord::Base
|
||||
question_consolidator_llm
|
||||
end
|
||||
|
||||
define_singleton_method :role do
|
||||
role
|
||||
end
|
||||
|
||||
define_singleton_method :role_whispers do
|
||||
role_whispers
|
||||
end
|
||||
|
||||
define_singleton_method :to_s do
|
||||
"#<DiscourseAi::AiBot::Personas::Persona::Custom @name=#{self.name} @allowed_group_ids=#{self.allowed_group_ids.join(",")}>"
|
||||
end
|
||||
@@ -343,8 +401,8 @@ class AiPersona < ActiveRecord::Base
|
||||
private
|
||||
|
||||
def system_persona_unchangeable
|
||||
if top_p_changed? || temperature_changed? || system_prompt_changed? || commands_changed? ||
|
||||
name_changed? || description_changed?
|
||||
if role_changed? || top_p_changed? || temperature_changed? || system_prompt_changed? ||
|
||||
commands_changed? || name_changed? || description_changed?
|
||||
errors.add(:base, I18n.t("discourse_ai.ai_bot.personas.cannot_edit_system_persona"))
|
||||
end
|
||||
end
|
||||
@@ -387,6 +445,12 @@ end
|
||||
# rag_chunk_overlap_tokens :integer default(10), not null
|
||||
# rag_conversation_chunks :integer default(10), not null
|
||||
# question_consolidator_llm :text
|
||||
# role :enum default("bot"), not null
|
||||
# role_category_ids :integer default([]), not null, is an Array
|
||||
# role_tags :string default([]), not null, is an Array
|
||||
# role_group_ids :integer default([]), not null, is an Array
|
||||
# role_whispers :boolean default(FALSE), not null
|
||||
# role_max_responses_per_hour :integer default(50), not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
|
||||
@@ -23,7 +23,12 @@ class LocalizedAiPersonaSerializer < ApplicationSerializer
|
||||
:rag_chunk_tokens,
|
||||
:rag_chunk_overlap_tokens,
|
||||
:rag_conversation_chunks,
|
||||
:question_consolidator_llm
|
||||
:question_consolidator_llm,
|
||||
:role,
|
||||
:role_tags,
|
||||
:role_category_ids,
|
||||
:role_whispers,
|
||||
:role_max_responses_per_hour
|
||||
|
||||
has_one :user, serializer: BasicUserSerializer, embed: :object
|
||||
has_many :rag_uploads, serializer: UploadSerializer, embed: :object
|
||||
|
||||
@@ -4,9 +4,11 @@ export default {
|
||||
path: "/plugins",
|
||||
|
||||
map() {
|
||||
this.route("discourse-ai-personas", { path: "ai-personas" }, function () {
|
||||
this.route("new");
|
||||
this.route("show", { path: "/:id" });
|
||||
this.route("discourse-ai", { path: "/" }, function () {
|
||||
this.route("ai-personas", function () {
|
||||
this.route("new");
|
||||
this.route("show", { path: "/:id" });
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
@@ -26,6 +26,9 @@ const CREATE_ATTRIBUTES = [
|
||||
"rag_chunk_overlap_tokens",
|
||||
"rag_conversation_chunks",
|
||||
"question_consolidator_llm",
|
||||
"role",
|
||||
"role_category_ids",
|
||||
"role_whispers",
|
||||
];
|
||||
|
||||
const SYSTEM_ATTRIBUTES = [
|
||||
|
||||
@@ -23,6 +23,7 @@ import DTooltip from "float-kit/components/d-tooltip";
|
||||
import AiCommandSelector from "./ai-command-selector";
|
||||
import AiLlmSelector from "./ai-llm-selector";
|
||||
import AiPersonaCommandOptions from "./ai-persona-command-options";
|
||||
import RoleSelector from "./ai-persona-role-selector";
|
||||
import PersonaRagUploader from "./persona-rag-uploader";
|
||||
|
||||
export default class PersonaEditor extends Component {
|
||||
@@ -102,7 +103,7 @@ export default class PersonaEditor extends Component {
|
||||
if (isNew && this.args.model.rag_uploads.length === 0) {
|
||||
this.args.personas.addObject(this.args.model);
|
||||
this.router.transitionTo(
|
||||
"adminPlugins.show.discourse-ai-personas.show",
|
||||
"adminPlugins.show.discourse-ai.ai-personas.show",
|
||||
this.args.model
|
||||
);
|
||||
} else {
|
||||
@@ -175,7 +176,7 @@ export default class PersonaEditor extends Component {
|
||||
return this.args.model.destroyRecord().then(() => {
|
||||
this.args.personas.removeObject(this.args.model);
|
||||
this.router.transitionTo(
|
||||
"adminPlugins.show.discourse-ai-personas.index"
|
||||
"adminPlugins.show.discourse-ai.ai-personas.index"
|
||||
);
|
||||
});
|
||||
},
|
||||
@@ -265,7 +266,7 @@ export default class PersonaEditor extends Component {
|
||||
|
||||
<template>
|
||||
<BackButton
|
||||
@route="adminPlugins.show.discourse-ai-personas"
|
||||
@route="adminPlugins.show.discourse-ai.ai-personas"
|
||||
@label="discourse_ai.ai_persona.back"
|
||||
/>
|
||||
<form
|
||||
@@ -336,6 +337,14 @@ export default class PersonaEditor extends Component {
|
||||
disabled={{this.editingModel.system}}
|
||||
/>
|
||||
</div>
|
||||
<div class="control-group ai-persona-editor__role">
|
||||
<label>{{I18n.t "discourse_ai.ai_persona.role"}}</label>
|
||||
<RoleSelector
|
||||
class="ai-persona-editor__role_selctor"
|
||||
@value={{this.editingModel.role}}
|
||||
@disabled={{this.editingModel.system}}
|
||||
/>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label>{{I18n.t "discourse_ai.ai_persona.default_llm"}}</label>
|
||||
<AiLlmSelector
|
||||
|
||||
@@ -50,7 +50,7 @@ export default class AiPersonaListEditor extends Component {
|
||||
<h3>{{i18n "discourse_ai.ai_persona.short_title"}}</h3>
|
||||
{{#unless @currentPersona.isNew}}
|
||||
<LinkTo
|
||||
@route="adminPlugins.show.discourse-ai-personas.new"
|
||||
@route="adminPlugins.show.discourse-ai.ai-personas.new"
|
||||
class="btn btn-small btn-primary"
|
||||
>
|
||||
{{icon "plus"}}
|
||||
@@ -105,7 +105,7 @@ export default class AiPersonaListEditor extends Component {
|
||||
</td>
|
||||
<td>
|
||||
<LinkTo
|
||||
@route="adminPlugins.show.discourse-ai-personas.show"
|
||||
@route="adminPlugins.show.discourse-ai.ai-personas.show"
|
||||
@model={{persona}}
|
||||
class="btn btn-text btn-small"
|
||||
>{{i18n "discourse_ai.ai_persona.edit"}} </LinkTo>
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import { computed, observer } from "@ember/object";
|
||||
import I18n from "discourse-i18n";
|
||||
import ComboBox from "select-kit/components/combo-box";
|
||||
|
||||
export default ComboBox.extend({
|
||||
_modelDisabledChanged: observer("attrs.disabled", function () {
|
||||
this.selectKit.options.set("disabled", this.get("attrs.disabled.value"));
|
||||
}),
|
||||
|
||||
content: computed(function () {
|
||||
return [
|
||||
{
|
||||
id: "bot",
|
||||
name: I18n.t("discourse_ai.ai_persona.role_options.bot"),
|
||||
},
|
||||
{
|
||||
id: "message_responder",
|
||||
name: I18n.t("discourse_ai.ai_persona.role_options.message_responder"),
|
||||
},
|
||||
];
|
||||
}),
|
||||
|
||||
selectKitOptions: {
|
||||
filterable: false,
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
<AiPersonaListEditor @personas={{this.model}} />
|
||||
+1
@@ -0,0 +1 @@
|
||||
<AiPersonaListEditor @personas={{this.model}} />
|
||||
@@ -12,9 +12,13 @@ export default {
|
||||
|
||||
withPluginApi("1.1.0", (api) => {
|
||||
api.addAdminPluginConfigurationNav("discourse-ai", PLUGIN_NAV_MODE_TOP, [
|
||||
{
|
||||
label: "admin.plugins.change_settings_short",
|
||||
route: "adminPlugins.show.settings",
|
||||
},
|
||||
{
|
||||
label: "discourse_ai.ai_persona.short_title",
|
||||
route: "adminPlugins.show.discourse-ai-personas",
|
||||
route: "adminPlugins.show.discourse-ai.ai-personas",
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -144,11 +144,9 @@ de:
|
||||
create_user_help: Du kannst dieser Persona optional einen Benutzer zuordnen. Wenn du das tust, wird die KI diesen Benutzer verwenden, um auf Anfragen zu antworten.
|
||||
default_llm: Standard-Sprachmodell
|
||||
default_llm_help: Das Standard-Sprachmodell, das für diese Persona verwendet werden soll. Erforderlich, wenn du die Persona in öffentlichen Beiträgen erwähnen möchtest.
|
||||
question_consolidator_llm: Sprachmodell für Fragenkonsolidierer
|
||||
question_consolidator_llm_help: Das Sprachmodell, das für den Fragenkonsolidierer verwendet werden soll. Du kannst ein weniger leistungsfähiges Modell wählen, um Kosten zu sparen.
|
||||
system_prompt: System-Eingabeaufforderung
|
||||
show_indexing_options: "Upload-Optionen anzeigen"
|
||||
hide_indexing_options: "Upload-Optionen ausblenden"
|
||||
show_indexing_options: "Indizierungsoptionen anzeigen"
|
||||
hide_indexing_options: "Indizierungsoptionen ausblenden"
|
||||
save: Speichern
|
||||
saved: KI-Persona gespeichert
|
||||
enabled: "Aktiviert?"
|
||||
@@ -185,7 +183,8 @@ de:
|
||||
Außerdem kannst du ihn so einrichten, dass bestimmte Benutzergruppen Zugriff auf bestimmte Personas haben. Das bedeutet, dass Sie für verschiedene Bereiche Ihres Forums unterschiedliche KI-Verhaltensweisen verwenden können, was die Vielfalt und den Reichtum der Interaktionen Ihrer Community weiter verbessert.
|
||||
uploads:
|
||||
title: "Uploads"
|
||||
description: "Deine KI-Persona wird in der Lage sein, den Inhalt der enthaltenen Dateien zu durchsuchen und zu referenzieren. Hochgeladene Dateien sollten als Plaintext (.txt) oder Markdown (.md) formatiert sein."
|
||||
description: "Deine KI-Persona wird in der Lage sein, den Inhalt der enthaltenen Dateien zu durchsuchen und zu referenzieren. Hochgeladene Dateien müssen als Klartext (.txt) formatiert sein."
|
||||
hint: "Um zu kontrollieren, wo der Inhalt der Datei in der System-Eingabeaufforderung platziert wird, füge den Platzhalter {uploads} in die obige System-Eingabeaufforderung ein."
|
||||
button: "Dateien hinzufügen"
|
||||
filter: "Uploads filtern"
|
||||
indexed: "Indiziert"
|
||||
|
||||
@@ -137,6 +137,10 @@ en:
|
||||
mentionable: Mentionable
|
||||
mentionable_help: If enabled, users in allowed groups can mention this user in posts and messages, the AI will respond as this persona.
|
||||
user: User
|
||||
role: Role
|
||||
role_options:
|
||||
bot: Bot
|
||||
message_responder: Message Responder
|
||||
create_user: Create User
|
||||
create_user_help: You can optionally attach a user to this persona. If you do, the AI will use this user to respond to requests.
|
||||
default_llm: Default Language Model
|
||||
|
||||
@@ -144,11 +144,9 @@ he:
|
||||
create_user_help: אפשר לצרף משתמש לדמות הזאת כרשות. אם האפשרות הזאת תסומן, הבינה המלאכותית תשתמש במשתמש הזה כדי להגיב לבקשות.
|
||||
default_llm: דגם שפה כברירת מחדל
|
||||
default_llm_help: דגם ברירת המחדל לשימוש לדמות הזאת. נחוץ כדי לאזכר דמות בפוסטים ציבוריים.
|
||||
question_consolidator_llm: מודל שפה למגבש השאלות
|
||||
question_consolidator_llm_help: מודל השפה לשימוש עבור מגבש השאלות, אפשר לבחור במודל פחות חזק כדי לחסוך בעלויות.
|
||||
system_prompt: בקשת מערכת
|
||||
show_indexing_options: "הצגת אפשרויות העלאה"
|
||||
hide_indexing_options: "הסתרת אפשרויות העלאה"
|
||||
show_indexing_options: "הצגת אפשרויות סידור במפתח"
|
||||
hide_indexing_options: "הסתרת אפשרויות סידור במפתח"
|
||||
save: שמירה
|
||||
saved: דמות בינה מלאכותית נשמרה
|
||||
enabled: "מאופשר?"
|
||||
@@ -182,7 +180,6 @@ he:
|
||||
יתרה מכך, אפשר להגדיר אותה כך שרק לקבוצות מסוימות תהיינה גישה לדמויות מסוימות. משמעות הדבר היא שאפשר לנהל התנהגויות שונות לבינה המלאכותית לאזורים שונים בפורום שלך, ובכך להרחיב את הגיוון ואת העושר של ההתנהלות בקהילה שלך.
|
||||
uploads:
|
||||
title: "העלאות"
|
||||
description: "דמות הבינה המלאכותית שלך תוכל לחפש ולהפנות לתוכן של קבצים כלולים. קבצים שהועלו אמורים להיות בתסדירי טקסט פשוט (.txt) או markdown (.md)."
|
||||
button: "הוספת קבצים"
|
||||
filter: "סינון העלאות"
|
||||
indexed: "סודר במפתח"
|
||||
|
||||
@@ -107,15 +107,10 @@ id:
|
||||
edit: Ubah
|
||||
description: Deskripsi
|
||||
user: Pengguna
|
||||
question_consolidator_llm: Model Bahasa untuk Konsolidator Pertanyaan
|
||||
question_consolidator_llm_help: Model bahasa yang digunakan untuk konsolidator pertanyaan, Anda dapat memilih model yang kurang kuat untuk menghemat biaya.
|
||||
show_indexing_options: "Tampilkan Opsi Unggah"
|
||||
hide_indexing_options: "Sembunyikan Opsi Unggah"
|
||||
save: Simpan
|
||||
enabled: "Diaktifkan?"
|
||||
delete: Hapus
|
||||
uploads:
|
||||
description: "Persona AI Anda akan dapat mencari dan mereferensikan konten file yang disertakan. File yang diunggah harus diformat sebagai teks biasa (.txt) atau markdown (.md)."
|
||||
uploading: "Mengunggah..."
|
||||
ai_helper:
|
||||
missing_content: "Silakan masukkan beberapa konten untuk menghasilkan saran."
|
||||
|
||||
@@ -170,6 +170,8 @@ tr_TR:
|
||||
Dahası, belirli kullanıcı gruplarının belirli kişiliklere erişime sahip olacak şekilde de belirleyebilirsiniz. Bu, forumunuzun farklı bölümleri için farklı YZ davranışlarına sahip olabileceğiniz anlamına gelir ve böylece topluluğunuzun etkileşimlerinin çeşitliliğini ve zenginliğini geliştirebilirsiniz.
|
||||
uploads:
|
||||
title: "Yüklemeler"
|
||||
description: "Yapay zeka personanız, dahil edilen dosyaların içeriğini arayabilecek ve referans verebilecektir. Yüklenen dosyalar düz metin (.txt) olarak biçimlendirilmelidir"
|
||||
hint: "Dosyanın içeriğinin sistem isteminde nereye yerleştirileceğini kontrol etmek için, yukarıdaki sistem istemine {uploads} yer tutucusunu ekleyin."
|
||||
button: "Dosya Ekle"
|
||||
filter: "Yüklemeleri filtrele"
|
||||
uploading: "Yükleniyor..."
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class AddRoleToAiPersona < ActiveRecord::Migration[7.0]
|
||||
def change
|
||||
create_enum :ai_persona_role, %w[bot topic_responder message_responder summarizer]
|
||||
add_column :ai_personas, :role, :enum, default: "bot", null: false, enum_type: :ai_persona_role
|
||||
|
||||
add_column :ai_personas, :role_category_ids, :integer, array: true, default: [], null: false
|
||||
add_column :ai_personas, :role_tags, :string, array: true, default: [], null: false
|
||||
add_column :ai_personas, :role_group_ids, :integer, array: true, default: [], null: false
|
||||
add_column :ai_personas, :role_whispers, :boolean, default: false, null: false
|
||||
add_column :ai_personas, :role_max_responses_per_hour, :integer, default: 50, null: false
|
||||
end
|
||||
end
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user