Compare commits

..
Author SHA1 Message Date
David Taylor aee2081356 Fix lib directory 2024-05-02 19:19:09 +01:00
David Taylor e6bfec5bdb DEV: Update engine config to match skeleton
- adds `lib/` autoloading (and removes the plugin.rb workaround)
- adds eager loading of scheduled jobs in development (otherwise they don't work at all)
2024-05-02 18:53:22 +01:00
Martin Brennan b52d3c7d29 DEV: Moving around admin persona config routes again (#586)
The initial setup done in fb0d56324f
clashed with other plugins, I found this when trying to do the same
for Gamification. This uses a better routing setup and removes the
need to define the config nav link for Settings -- that is always inserted.

Relies on https://github.com/discourse/discourse/pull/26707
2024-05-02 12:42:30 +10:00
Sam 6623928b95 FIX: call after tool calls failing on OpenAI / Gemini (#599)
A recent change meant that llm instance got cached internally, repeat calls
to inference would cache data in Endpoint object leading model to
failures.

Both Gemini and Open AI expect a clean endpoint object cause they
set data.

This amends internals to make sure llm.generate will always operate
on clean objects
2024-05-01 17:50:58 +10:00
Discourse Translator Bot aab59b9327 Update translations (#598) 2024-04-30 21:57:37 +02:00
Kris 6860ee50be UX: prevent social share content from overflowing container (#597) 2024-04-30 09:47:21 -04:00
161 changed files with 157 additions and 415 deletions
@@ -1,7 +0,0 @@
import DiscourseRoute from "discourse/routes/discourse";
export default DiscourseRoute.extend({
model() {
return this.modelFor("adminPlugins.show.discourse-ai.ai-personas");
},
});
@@ -1,12 +0,0 @@
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"
);
}
}
@@ -17,7 +17,7 @@ export default DiscourseRoute.extend({
this._super(controller, model);
controller.set(
"allPersonas",
this.modelFor("adminPlugins.show.discourse-ai.ai-personas")
this.modelFor("adminPlugins.show.discourse-ai-personas")
);
},
});
@@ -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.ai-personas"
"adminPlugins.show.discourse-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.ai-personas")
this.modelFor("adminPlugins.show.discourse-ai-personas")
);
},
});
@@ -125,7 +125,6 @@ module DiscourseAi
:rag_chunk_overlap_tokens,
:rag_conversation_chunks,
:question_consolidator_llm,
:role,
allowed_group_ids: [],
rag_uploads: [:id],
)
+1 -7
View File
@@ -10,13 +10,7 @@ module ::Jobs
persona_id = args[:persona_id]
begin
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
persona = DiscourseAi::AiBot::Personas::Persona.find_by(user: post.user, id: persona_id)
raise DiscourseAi::AiBot::Bot::BOT_NOT_FOUND if persona.nil?
bot = DiscourseAi::AiBot::Bot.as(bot_user, persona: persona.new)
+2 -66
View File
@@ -46,10 +46,6 @@ 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
@@ -76,42 +72,6 @@ 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
@@ -154,8 +114,6 @@ 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
@@ -203,14 +161,6 @@ 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
@@ -302,14 +252,6 @@ 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
@@ -401,8 +343,8 @@ class AiPersona < ActiveRecord::Base
private
def system_persona_unchangeable
if role_changed? || top_p_changed? || temperature_changed? || system_prompt_changed? ||
commands_changed? || name_changed? || description_changed?
if 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
@@ -445,12 +387,6 @@ 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,12 +23,7 @@ class LocalizedAiPersonaSerializer < ApplicationSerializer
:rag_chunk_tokens,
:rag_chunk_overlap_tokens,
:rag_conversation_chunks,
:question_consolidator_llm,
:role,
:role_tags,
:role_category_ids,
:role_whispers,
:role_max_responses_per_hour
:question_consolidator_llm
has_one :user, serializer: BasicUserSerializer, embed: :object
has_many :rag_uploads, serializer: UploadSerializer, embed: :object
@@ -4,11 +4,9 @@ export default {
path: "/plugins",
map() {
this.route("discourse-ai", { path: "/" }, function () {
this.route("ai-personas", function () {
this.route("new");
this.route("show", { path: "/:id" });
});
this.route("discourse-ai-personas", { path: "ai-personas" }, function () {
this.route("new");
this.route("show", { path: "/:id" });
});
},
};
@@ -26,9 +26,6 @@ const CREATE_ATTRIBUTES = [
"rag_chunk_overlap_tokens",
"rag_conversation_chunks",
"question_consolidator_llm",
"role",
"role_category_ids",
"role_whispers",
];
const SYSTEM_ATTRIBUTES = [
@@ -23,7 +23,6 @@ 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 {
@@ -103,7 +102,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.ai-personas.show",
"adminPlugins.show.discourse-ai-personas.show",
this.args.model
);
} else {
@@ -176,7 +175,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.ai-personas.index"
"adminPlugins.show.discourse-ai-personas.index"
);
});
},
@@ -266,7 +265,7 @@ export default class PersonaEditor extends Component {
<template>
<BackButton
@route="adminPlugins.show.discourse-ai.ai-personas"
@route="adminPlugins.show.discourse-ai-personas"
@label="discourse_ai.ai_persona.back"
/>
<form
@@ -337,14 +336,6 @@ 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.ai-personas.new"
@route="adminPlugins.show.discourse-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.ai-personas.show"
@route="adminPlugins.show.discourse-ai-personas.show"
@model={{persona}}
class="btn btn-text btn-small"
>{{i18n "discourse_ai.ai_persona.edit"}} </LinkTo>
@@ -1,26 +0,0 @@
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,
},
});
@@ -1 +0,0 @@
<AiPersonaListEditor @personas={{this.model}} />
@@ -1 +0,0 @@
<AiPersonaListEditor @personas={{this.model}} />
@@ -12,13 +12,9 @@ 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.ai-personas",
route: "adminPlugins.show.discourse-ai-personas",
},
]);
});
+5 -4
View File
@@ -144,9 +144,11 @@ 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: "Indizierungsoptionen anzeigen"
hide_indexing_options: "Indizierungsoptionen ausblenden"
show_indexing_options: "Upload-Optionen anzeigen"
hide_indexing_options: "Upload-Optionen ausblenden"
save: Speichern
saved: KI-Persona gespeichert
enabled: "Aktiviert?"
@@ -183,8 +185,7 @@ 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 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."
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."
button: "Dateien hinzufügen"
filter: "Uploads filtern"
indexed: "Indiziert"
-4
View File
@@ -137,10 +137,6 @@ 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
+5 -2
View File
@@ -144,9 +144,11 @@ 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: "מאופשר?"
@@ -180,6 +182,7 @@ he:
יתרה מכך, אפשר להגדיר אותה כך שרק לקבוצות מסוימות תהיינה גישה לדמויות מסוימות. משמעות הדבר היא שאפשר לנהל התנהגויות שונות לבינה המלאכותית לאזורים שונים בפורום שלך, ובכך להרחיב את הגיוון ואת העושר של ההתנהלות בקהילה שלך.
uploads:
title: "העלאות"
description: "דמות הבינה המלאכותית שלך תוכל לחפש ולהפנות לתוכן של קבצים כלולים. קבצים שהועלו אמורים להיות בתסדירי טקסט פשוט (‎.txt) או markdown‏ (‎.md)."
button: "הוספת קבצים"
filter: "סינון העלאות"
indexed: "סודר במפתח"
+5
View File
@@ -107,10 +107,15 @@ 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."
-2
View File
@@ -170,8 +170,6 @@ 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..."
@@ -1,14 +0,0 @@
# 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