Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
67bc4c038a |
@@ -1,8 +1,5 @@
|
||||
# **Discourse AI** Plugin
|
||||
|
||||
> [!IMPORTANT]
|
||||
> This plugin has now been bundled into Discourse core. See: https://meta.discourse.org/t/bundling-more-popular-plugins-with-discourse-core/373574
|
||||
|
||||
**Plugin Summary**
|
||||
|
||||
For more information, please see: https://meta.discourse.org/t/discourse-ai/259214?u=falco
|
||||
|
||||
@@ -6,7 +6,8 @@ module Jobs
|
||||
sidekiq_options retry: false
|
||||
|
||||
def execute(args)
|
||||
return if !DiscourseAi::Translation.enabled?
|
||||
return if !SiteSetting.discourse_ai_enabled
|
||||
return if !SiteSetting.ai_translation_enabled
|
||||
return if args[:post_id].blank?
|
||||
|
||||
post = Post.find_by(id: args[:post_id])
|
||||
@@ -35,14 +36,12 @@ module Jobs
|
||||
end
|
||||
end
|
||||
|
||||
return if detected_locale.blank?
|
||||
locales = SiteSetting.content_localization_supported_locales.split("|")
|
||||
return if locales.blank?
|
||||
|
||||
locales.each do |locale|
|
||||
next if DiscourseAi::Translation::LocaleNormalizer.is_same?(locale, detected_locale)
|
||||
regionless_locale = locale.split("_").first
|
||||
next if post.post_localizations.where("locale LIKE ?", "#{regionless_locale}%").exists?
|
||||
next if locale == detected_locale
|
||||
next if post.post_localizations.exists?(locale:)
|
||||
|
||||
begin
|
||||
DiscourseAi::Translation::PostLocalizer.localize(post, locale)
|
||||
|
||||
@@ -6,7 +6,8 @@ module Jobs
|
||||
sidekiq_options retry: false
|
||||
|
||||
def execute(args)
|
||||
return if !DiscourseAi::Translation.enabled?
|
||||
return if !SiteSetting.discourse_ai_enabled
|
||||
return if !SiteSetting.ai_translation_enabled
|
||||
return if args[:topic_id].blank?
|
||||
|
||||
topic = Topic.find_by(id: args[:topic_id])
|
||||
@@ -33,14 +34,12 @@ module Jobs
|
||||
end
|
||||
end
|
||||
|
||||
return if detected_locale.blank?
|
||||
locales = SiteSetting.content_localization_supported_locales.split("|")
|
||||
return if locales.blank?
|
||||
|
||||
locales.each do |locale|
|
||||
next if DiscourseAi::Translation::LocaleNormalizer.is_same?(locale, detected_locale)
|
||||
regionless_locale = locale.split("_").first
|
||||
next if topic.topic_localizations.where("locale LIKE ?", "#{regionless_locale}%").exists?
|
||||
next if locale == detected_locale
|
||||
next if topic.topic_localizations.exists?(locale:)
|
||||
|
||||
begin
|
||||
DiscourseAi::Translation::TopicLocalizer.localize(topic, locale)
|
||||
|
||||
@@ -6,17 +6,21 @@ module Jobs
|
||||
sidekiq_options retry: false
|
||||
|
||||
def execute(args)
|
||||
return if !DiscourseAi::Translation.enabled?
|
||||
|
||||
limit = args[:limit]
|
||||
raise Discourse::InvalidParameters.new(:limit) if limit.nil?
|
||||
return if limit <= 0
|
||||
|
||||
return if !SiteSetting.discourse_ai_enabled
|
||||
return if !SiteSetting.ai_translation_enabled
|
||||
locales = SiteSetting.content_localization_supported_locales.split("|")
|
||||
return if locales.blank?
|
||||
|
||||
categories = Category.where("locale IS NOT NULL")
|
||||
|
||||
if SiteSetting.ai_translation_backfill_limit_to_public_content
|
||||
categories = categories.where(read_restricted: false)
|
||||
end
|
||||
|
||||
categories = categories.order(:id).limit(limit)
|
||||
return if categories.empty?
|
||||
|
||||
@@ -29,7 +33,6 @@ module Jobs
|
||||
missing_locales = locales - existing_locales - [category.locale]
|
||||
missing_locales.each do |locale|
|
||||
break if remaining_limit <= 0
|
||||
next if DiscourseAi::Translation::LocaleNormalizer.is_same?(locale, category.locale)
|
||||
|
||||
begin
|
||||
DiscourseAi::Translation::CategoryLocalizer.localize(category, locale)
|
||||
|
||||
@@ -9,25 +9,23 @@ module Jobs
|
||||
limit = args[:limit]
|
||||
raise Discourse::InvalidParameters.new(:limit) if limit.blank? || limit <= 0
|
||||
|
||||
return if !DiscourseAi::Translation.backfill_enabled?
|
||||
return if !SiteSetting.discourse_ai_enabled
|
||||
return if !SiteSetting.ai_translation_enabled
|
||||
|
||||
locales = SiteSetting.content_localization_supported_locales.split("|")
|
||||
return if locales.blank?
|
||||
|
||||
locales.each do |locale|
|
||||
base_locale = locale.split("_").first
|
||||
posts =
|
||||
Post
|
||||
.joins(
|
||||
"LEFT JOIN post_localizations pl ON pl.post_id = posts.id AND pl.locale LIKE '#{base_locale}%'",
|
||||
)
|
||||
.where(
|
||||
"posts.created_at > ?",
|
||||
SiteSetting.ai_translation_backfill_max_age_days.days.ago,
|
||||
"LEFT JOIN post_localizations pl ON pl.post_id = posts.id AND pl.locale = #{ActiveRecord::Base.connection.quote(locale)}",
|
||||
)
|
||||
.where(deleted_at: nil)
|
||||
.where("posts.user_id > 0")
|
||||
.where.not(raw: [nil, ""])
|
||||
.where.not(locale: nil)
|
||||
.where("posts.locale NOT LIKE '#{base_locale}%'")
|
||||
.where.not(locale: locale)
|
||||
.where("pl.id IS NULL")
|
||||
|
||||
posts = posts.joins(:topic)
|
||||
@@ -48,6 +46,14 @@ module Jobs
|
||||
)
|
||||
end
|
||||
|
||||
if SiteSetting.ai_translation_backfill_max_age_days > 0
|
||||
posts =
|
||||
posts.where(
|
||||
"posts.created_at > ?",
|
||||
SiteSetting.ai_translation_backfill_max_age_days.days.ago,
|
||||
)
|
||||
end
|
||||
|
||||
posts = posts.order(updated_at: :desc).limit(limit)
|
||||
|
||||
next if posts.empty?
|
||||
|
||||
@@ -9,24 +9,22 @@ module Jobs
|
||||
limit = args[:limit]
|
||||
raise Discourse::InvalidParameters.new(:limit) if limit.blank? || limit <= 0
|
||||
|
||||
return if !DiscourseAi::Translation.backfill_enabled?
|
||||
return if !SiteSetting.discourse_ai_enabled
|
||||
return if !SiteSetting.ai_translation_enabled
|
||||
|
||||
locales = SiteSetting.content_localization_supported_locales.split("|")
|
||||
return if locales.blank?
|
||||
|
||||
locales.each do |locale|
|
||||
base_locale = locale.split("_").first
|
||||
topics =
|
||||
Topic
|
||||
.joins(
|
||||
"LEFT JOIN topic_localizations tl ON tl.topic_id = topics.id AND tl.locale LIKE '#{base_locale}%'",
|
||||
)
|
||||
.where(
|
||||
"topics.created_at > ?",
|
||||
SiteSetting.ai_translation_backfill_max_age_days.days.ago,
|
||||
"LEFT JOIN topic_localizations tl ON tl.topic_id = topics.id AND tl.locale = #{ActiveRecord::Base.connection.quote(locale)}",
|
||||
)
|
||||
.where(deleted_at: nil)
|
||||
.where("topics.user_id > 0")
|
||||
.where.not(locale: nil)
|
||||
.where("topics.locale NOT LIKE '#{base_locale}%'")
|
||||
.where.not(locale: locale)
|
||||
.where("tl.id IS NULL")
|
||||
|
||||
if SiteSetting.ai_translation_backfill_limit_to_public_content
|
||||
@@ -45,6 +43,14 @@ module Jobs
|
||||
)
|
||||
end
|
||||
|
||||
if SiteSetting.ai_translation_backfill_max_age_days > 0
|
||||
topics =
|
||||
topics.where(
|
||||
"topics.created_at > ?",
|
||||
SiteSetting.ai_translation_backfill_max_age_days.days.ago,
|
||||
)
|
||||
end
|
||||
|
||||
topics = topics.order(updated_at: :desc).limit(limit)
|
||||
|
||||
next if topics.empty?
|
||||
|
||||
@@ -7,7 +7,10 @@ module Jobs
|
||||
cluster_concurrency 1
|
||||
|
||||
def execute(args)
|
||||
return if !DiscourseAi::Translation.backfill_enabled?
|
||||
return if !SiteSetting.discourse_ai_enabled
|
||||
return if !SiteSetting.ai_translation_enabled
|
||||
limit = SiteSetting.ai_translation_backfill_hourly_rate
|
||||
return if limit == 0
|
||||
|
||||
categories = Category.where(locale: nil)
|
||||
|
||||
@@ -15,7 +18,6 @@ module Jobs
|
||||
categories = categories.where(read_restricted: false)
|
||||
end
|
||||
|
||||
limit = SiteSetting.ai_translation_backfill_hourly_rate
|
||||
categories = categories.limit(limit)
|
||||
return if categories.empty?
|
||||
|
||||
|
||||
@@ -6,8 +6,11 @@ module Jobs
|
||||
cluster_concurrency 1
|
||||
|
||||
def execute(args)
|
||||
return if !DiscourseAi::Translation.backfill_enabled?
|
||||
return if !SiteSetting.discourse_ai_enabled
|
||||
return if !SiteSetting.ai_translation_enabled
|
||||
return if SiteSetting.content_localization_supported_locales.blank?
|
||||
limit = SiteSetting.ai_translation_backfill_hourly_rate
|
||||
return if limit == 0
|
||||
|
||||
Jobs.enqueue(:localize_categories, limit:)
|
||||
end
|
||||
|
||||
@@ -6,8 +6,10 @@ module Jobs
|
||||
cluster_concurrency 1
|
||||
|
||||
def execute(args)
|
||||
return if !DiscourseAi::Translation.backfill_enabled?
|
||||
return if !SiteSetting.discourse_ai_enabled
|
||||
return if !SiteSetting.ai_translation_enabled
|
||||
|
||||
return if SiteSetting.content_localization_supported_locales.blank?
|
||||
limit = SiteSetting.ai_translation_backfill_hourly_rate / (60 / 5) # this job runs in 5-minute intervals
|
||||
return if limit == 0
|
||||
|
||||
|
||||
@@ -7,16 +7,16 @@ module Jobs
|
||||
cluster_concurrency 1
|
||||
|
||||
def execute(args)
|
||||
return if !DiscourseAi::Translation.backfill_enabled?
|
||||
|
||||
return if !SiteSetting.discourse_ai_enabled
|
||||
return if !SiteSetting.ai_translation_enabled
|
||||
limit = SiteSetting.ai_translation_backfill_hourly_rate / (60 / 5) # this job runs in 5-minute intervals
|
||||
return if limit == 0
|
||||
|
||||
posts =
|
||||
Post
|
||||
.where(locale: nil)
|
||||
.where(deleted_at: nil)
|
||||
.where("posts.user_id > 0")
|
||||
.where("posts.created_at > ?", SiteSetting.ai_translation_backfill_max_age_days.days.ago)
|
||||
.where.not(raw: [nil, ""])
|
||||
|
||||
if SiteSetting.ai_translation_backfill_limit_to_public_content
|
||||
@@ -33,6 +33,14 @@ module Jobs
|
||||
)
|
||||
end
|
||||
|
||||
if SiteSetting.ai_translation_backfill_max_age_days > 0
|
||||
posts =
|
||||
posts.where(
|
||||
"posts.created_at > ?",
|
||||
SiteSetting.ai_translation_backfill_max_age_days.days.ago,
|
||||
)
|
||||
end
|
||||
|
||||
posts = posts.order(updated_at: :desc).limit(limit)
|
||||
return if posts.empty?
|
||||
|
||||
|
||||
@@ -36,12 +36,7 @@ module ::Jobs
|
||||
existing_summary = strategy.existing_summary
|
||||
|
||||
if existing_summary.blank? || existing_summary.outdated
|
||||
begin
|
||||
strategy.summarize(user)
|
||||
rescue => e
|
||||
Rails.logger.error("Error summarizing topic #{topic.id}: #{e.class.name} - #{e.message}")
|
||||
raise e
|
||||
end
|
||||
strategy.summarize(user)
|
||||
else
|
||||
# Hiding or deleting a post, and creating a small action alters the Topic#highest_post_number.
|
||||
# We use this as a quick way to select potential backfill candidates without relying on original_content_sha.
|
||||
|
||||
@@ -6,9 +6,13 @@ module Jobs
|
||||
cluster_concurrency 1
|
||||
|
||||
def execute(args)
|
||||
return if !DiscourseAi::Translation.backfill_enabled?
|
||||
return if !SiteSetting.discourse_ai_enabled
|
||||
return if !SiteSetting.ai_translation_enabled
|
||||
|
||||
return if SiteSetting.content_localization_supported_locales.blank?
|
||||
limit = SiteSetting.ai_translation_backfill_hourly_rate / (60 / 5) # this job runs in 5-minute intervals
|
||||
return if limit == 0
|
||||
|
||||
Jobs.enqueue(:localize_topics, limit:)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -7,15 +7,12 @@ module Jobs
|
||||
cluster_concurrency 1
|
||||
|
||||
def execute(args)
|
||||
return if !DiscourseAi::Translation.backfill_enabled?
|
||||
|
||||
return if !SiteSetting.discourse_ai_enabled
|
||||
return if !SiteSetting.ai_translation_enabled
|
||||
limit = SiteSetting.ai_translation_backfill_hourly_rate / (60 / 5) # this job runs in 5-minute intervals
|
||||
return if limit == 0
|
||||
|
||||
topics =
|
||||
Topic
|
||||
.where(locale: nil, deleted_at: nil)
|
||||
.where("topics.user_id > 0")
|
||||
.where("topics.created_at > ?", SiteSetting.ai_translation_backfill_max_age_days.days.ago)
|
||||
topics = Topic.where(locale: nil, deleted_at: nil).where("topics.user_id > 0")
|
||||
|
||||
if SiteSetting.ai_translation_backfill_limit_to_public_content
|
||||
topics =
|
||||
@@ -31,6 +28,14 @@ module Jobs
|
||||
)
|
||||
end
|
||||
|
||||
if SiteSetting.ai_translation_backfill_max_age_days > 0
|
||||
topics =
|
||||
topics.where(
|
||||
"topics.created_at > ?",
|
||||
SiteSetting.ai_translation_backfill_max_age_days.days.ago,
|
||||
)
|
||||
end
|
||||
|
||||
topics = topics.order(updated_at: :desc).limit(limit)
|
||||
return if topics.empty?
|
||||
|
||||
|
||||
@@ -260,11 +260,10 @@ export default class AiBotConversations extends Component {
|
||||
|
||||
@action
|
||||
async prepareAndSubmitToBot() {
|
||||
// Pass uploads to the service before submitting
|
||||
this.aiBotConversationsHiddenSubmit.uploads = this.uploads;
|
||||
try {
|
||||
await this.aiBotConversationsHiddenSubmit.submitToBot({
|
||||
uploads: this.uploads,
|
||||
inProgressUploadsCount: this.inProgressUploads.length,
|
||||
});
|
||||
await this.aiBotConversationsHiddenSubmit.submitToBot();
|
||||
this.uploads = new TrackedArray();
|
||||
} catch (error) {
|
||||
popupAjaxError(error);
|
||||
|
||||
@@ -18,6 +18,7 @@ export default class AiBotConversationsHiddenSubmit extends Service {
|
||||
|
||||
personaId;
|
||||
targetUsername;
|
||||
uploads = [];
|
||||
|
||||
inputValue = "";
|
||||
|
||||
@@ -31,7 +32,7 @@ export default class AiBotConversationsHiddenSubmit extends Service {
|
||||
}
|
||||
|
||||
@action
|
||||
async submitToBot(uploadData) {
|
||||
async submitToBot() {
|
||||
if (
|
||||
this.inputValue.length <
|
||||
this.siteSettings.min_personal_message_post_length
|
||||
@@ -47,7 +48,7 @@ export default class AiBotConversationsHiddenSubmit extends Service {
|
||||
}
|
||||
|
||||
// Don't submit if there are still uploads in progress
|
||||
if (uploadData.inProgressUploadsCount > 0) {
|
||||
if (document.querySelector(".ai-bot-upload--in-progress")) {
|
||||
return this.dialog.alert({
|
||||
message: i18n("discourse_ai.ai_bot.conversations.uploads_in_progress"),
|
||||
});
|
||||
@@ -60,10 +61,10 @@ export default class AiBotConversationsHiddenSubmit extends Service {
|
||||
let rawContent = this.inputValue;
|
||||
|
||||
// Append upload markdown if we have uploads
|
||||
if (uploadData.uploads && uploadData.uploads.length > 0) {
|
||||
if (this.uploads && this.uploads.length > 0) {
|
||||
rawContent += "\n\n";
|
||||
|
||||
uploadData.uploads.forEach((upload) => {
|
||||
this.uploads.forEach((upload) => {
|
||||
const uploadMarkdown = getUploadMarkdown(upload);
|
||||
rawContent += uploadMarkdown + "\n";
|
||||
});
|
||||
@@ -82,6 +83,7 @@ export default class AiBotConversationsHiddenSubmit extends Service {
|
||||
});
|
||||
|
||||
// Reset uploads after successful submission
|
||||
this.uploads = [];
|
||||
this.inputValue = "";
|
||||
|
||||
this.appEvents.trigger("discourse-ai:bot-pm-created", {
|
||||
|
||||
@@ -158,8 +158,6 @@ ar:
|
||||
reset: "إعادة التعيين"
|
||||
search:
|
||||
name: "البحث"
|
||||
embeddings:
|
||||
name: "التضمينات"
|
||||
ai_helper:
|
||||
name: "المساعد"
|
||||
proofread: تدقيق النص لغويًا
|
||||
|
||||
@@ -29,22 +29,6 @@ de:
|
||||
label: "Sortieren nach"
|
||||
tag:
|
||||
label: "Schlagwort"
|
||||
logs:
|
||||
staff_actions:
|
||||
actions:
|
||||
create_ai_llm_model: "LLM-Modell erstellen"
|
||||
update_ai_llm_model: "LLM-Modell aktualisieren"
|
||||
delete_ai_llm_model: "LLM-Modell löschen"
|
||||
create_ai_persona: "KI-Persona erstellen"
|
||||
update_ai_persona: "KI-Persona aktualisieren"
|
||||
delete_ai_persona: "KI-Persona löschen"
|
||||
create_ai_tool: "KI-Tool erstellen"
|
||||
update_ai_tool: "KI-Tool aktualisieren"
|
||||
delete_ai_tool: "KI-Tool löschen"
|
||||
create_ai_embedding: "KI-Einbettung erstellen"
|
||||
update_ai_embedding: "KI-Einbettung aktualisieren"
|
||||
delete_ai_embedding: "KI-Einbettung löschen"
|
||||
update_ai_spam_settings: "KI-Spam-Einstellungen aktualisieren"
|
||||
js:
|
||||
discourse_automation:
|
||||
scriptables:
|
||||
@@ -114,21 +98,21 @@ de:
|
||||
fields:
|
||||
model:
|
||||
label: "Modell"
|
||||
description: "Das für die Sichtung verwendete Standard-Sprachmodell"
|
||||
description: "Das für die Triage verwendete Standard-Sprachmodell"
|
||||
tool:
|
||||
label: "Tool"
|
||||
description: "Tool für die Sichtung (das Tool darf keine Parameter definiert haben)"
|
||||
label: "Werkzeug"
|
||||
description: "Werkzeug für die Triage (das Werkzeug darf keine Parameter definiert haben)"
|
||||
llm_persona_triage:
|
||||
fields:
|
||||
persona:
|
||||
label: "Persona"
|
||||
description: "KI-Persona, die für die Sichtung verwendet werden soll (Standard-LLM und -Benutzer müssen eingestellt sein)"
|
||||
description: "KI-Persona, die für die Triage verwendet werden soll (Standard-LLM und -Benutzer müssen eingestellt sein)"
|
||||
whisper:
|
||||
label: "Als Flüstern antworten"
|
||||
description: "Ob die Antwort der Persona ein Flüstern sein soll"
|
||||
silent_mode:
|
||||
label: "Stiller Modus"
|
||||
description: "Im stillen Modus empfängt die Persona den Inhalt, schreibt aber nichts in das Forum - nützlich bei der Sichtung mit Tools"
|
||||
description: "Im stillen Modus empfängt die Persona den Inhalt, schreibt aber nichts in das Forum - nützlich bei der Triage mit Tools"
|
||||
llm_triage:
|
||||
fields:
|
||||
system_prompt:
|
||||
@@ -193,7 +177,6 @@ de:
|
||||
llm:
|
||||
one: "LLM:"
|
||||
other: "LLM:"
|
||||
no_llm: "Kein LLM ausgewählt"
|
||||
no_persona: "Nicht festgelegt"
|
||||
no_groups: "Keiner"
|
||||
edit: "Bearbeiten"
|
||||
@@ -201,73 +184,35 @@ de:
|
||||
one: "(%{count} weitere)"
|
||||
other: "(%{count} weitere)"
|
||||
collapse_list: "(weniger anzeigen)"
|
||||
bot:
|
||||
bot: "Chatbot"
|
||||
name: "Bot"
|
||||
description: "Ein Chatbot, der Fragen beantworten und Benutzern in persönlichen Nachrichten, im Forum und im Chat helfen kann"
|
||||
nav:
|
||||
configured: "Konfiguriert"
|
||||
unconfigured: "Nicht konfiguriert"
|
||||
filters:
|
||||
all: "Gesamt"
|
||||
text: "Suche nach Funktionen, Personas, LLMs oder Gruppen..."
|
||||
no_results: "Es wurden keine Funktionen gefunden, die deinen Filtern entsprechen."
|
||||
reset: "Zurücksetzen"
|
||||
summarization:
|
||||
name: "Zusammenfassungen"
|
||||
description: "Stellt eine Schaltfläche für Zusammenfassungen zur Verfügung, mit der Besucher Themen zusammenfassen können"
|
||||
topic_summaries: "Themenzusammenfassungen"
|
||||
gists: "Kurze Zusammenfassungen der in Themenliste"
|
||||
search:
|
||||
name: "Suche"
|
||||
description: "Verbessert das Sucherlebnis durch KI-generierte Antworten auf Suchanfragen"
|
||||
discoveries: "Entdeckungen"
|
||||
embeddings:
|
||||
name: "Einbettungen"
|
||||
description: "Ermöglicht Funktionen wie „Verwandte Themen“ und „KI-Suche“ durch die Erstellung semantischer Textdarstellungen"
|
||||
hyde: "HyDE"
|
||||
discord:
|
||||
name: "Discord-Integration"
|
||||
description: "Fügt die Möglichkeit hinzu, Discord-Kanäle zu durchsuchen"
|
||||
search: "Discord-Suche"
|
||||
inference:
|
||||
name: "Abgeleitete Konzepte"
|
||||
description: "Ordnet Themen und Beiträge in Interessensgebiete / Labels."
|
||||
match_concepts: "Passende Konzepte"
|
||||
ai_helper:
|
||||
name: "Helfer"
|
||||
description: "Unterstützt Benutzer bei der Interaktion in der Community, z. B. beim Erstellen von Themen, Verfassen von Beiträgen und Lesen von Inhalten"
|
||||
proofread: Text korrekturlesen
|
||||
title_suggestions: "Titel vorschlagen"
|
||||
explain: "Erklären"
|
||||
illustrate_post: "Beitrag illustrieren"
|
||||
smart_dates: "Intelligente Termine"
|
||||
translate: "Übersetzen"
|
||||
markdown_tables: "Markdown-Tabelle generieren"
|
||||
custom_prompt: "Benutzerdefinierte Eingabeaufforderung"
|
||||
image_caption: "Bildbeschriftungen"
|
||||
translator: "Übersetzer"
|
||||
translation:
|
||||
name: "Übersetzen"
|
||||
description: "Übersetzt Inhalte in unterstützte Sprachen"
|
||||
locale_detector: "Sprachdetektor"
|
||||
post_raw_translator: "Übersetzer für die Roheingabe des Beitrags"
|
||||
topic_title_translator: "Thementitel-Übersetzer"
|
||||
short_text_translator: "Kurztext-Übersetzer"
|
||||
spam:
|
||||
name: "Spam"
|
||||
description: "Identifiziert potenziellen Spam mithilfe des ausgewählten LLMs und meldet ihn den Moderatoren der Website in der Warteschlange zur Überprüfung."
|
||||
inspect_posts: "Beiträge prüfen"
|
||||
modals:
|
||||
select_option: "Wähle eine Option aus..."
|
||||
layout:
|
||||
table: "Tabelle"
|
||||
card: "Karte"
|
||||
spam:
|
||||
short_title: "Spam"
|
||||
title: "Spam-Behandlung konfigurieren"
|
||||
select_llm: "LLM auswählen"
|
||||
select_persona: "Persona auswählen"
|
||||
custom_instructions: "Benutzerdefinierte Anweisungen"
|
||||
custom_instructions_help: "Benutzerdefinierte Anweisungen speziell für deine Website, die der KI beim Identifizieren von Spam helfen, z. B. „Gehe beim Scannen von Posts, die nicht in englischer Sprache sind, aggressiver vor.“"
|
||||
last_seven_days: "Letzte 7 Tage"
|
||||
@@ -348,9 +293,6 @@ de:
|
||||
name: "Name"
|
||||
edit: "Bearbeiten"
|
||||
export: "Exportieren"
|
||||
import: "Importieren"
|
||||
import_error_conflict: "Beim Importieren von %{name} wurde ein Konflikt erkannt. Möchtest du die vorhandene Persona aktualisieren?"
|
||||
overwrite: "Überschreiben"
|
||||
description: "Beschreibung"
|
||||
no_llm_selected: "Kein Sprachmodell ausgewählt"
|
||||
use_parent_llm: "Verwende das Personas Sprachmodell"
|
||||
@@ -428,10 +370,7 @@ de:
|
||||
title: "KI-Bot-Optionen"
|
||||
save_first: "Weitere KI-Bot-Optionen werden verfügbar, sobald du die Persona gespeichert hast."
|
||||
filters:
|
||||
text: "Finde eine Persona"
|
||||
reset: "Zurücksetzen"
|
||||
no_results: "Es wurden keine Personas gefunden, die deinen Filtern entsprechen."
|
||||
all_features: "Jede Funktion"
|
||||
features_list:
|
||||
one: "Funktion:"
|
||||
other: "Funktionen:"
|
||||
@@ -462,14 +401,11 @@ de:
|
||||
back: "Zurück"
|
||||
short_title: "Tools"
|
||||
export: "Exportieren"
|
||||
import: "Importieren"
|
||||
import_error_conflict: "Tool existiert bereits, möchtest du es aktualisieren?"
|
||||
overwrite: "Überschreiben"
|
||||
no_tools: "Du hast noch keine Tools erstellt"
|
||||
name: "Name"
|
||||
name_help: "Der Name wird in der Discourse-Benutzeroberfläche angezeigt und ist die Kurzkennung, die du verwendest, um das Tool in verschiedenen Einstellungen zu finden. Er sollte eindeutig sein (er ist erforderlich)."
|
||||
name_help: "Der Name wird in der Discourse-Benutzeroberfläche angezeigt und ist die Kurzkennung, die Du verwendest, um das Werkzeug in verschiedenen Einstellungen zu finden. Er sollte eindeutig sein (er ist erforderlich)."
|
||||
new: "Neues Tool"
|
||||
tool_name: "Name des Tools"
|
||||
tool_name: "Werkzeugname"
|
||||
tool_name_help: "Der Werkzeugname wird dem großen Sprachmodell präsentiert. Es ist nicht eindeutig, aber es ist von Person zu Person unterschiedlich. (Persona wird beim Speichern validiert)"
|
||||
description: "Beschreibung"
|
||||
description_help: "Eine klare Beschreibung des Zwecks des Tools für das Sprachmodell"
|
||||
@@ -550,18 +486,14 @@ de:
|
||||
ai_summarization: "Zusammenfassen"
|
||||
ai_embeddings_semantic_search: "KI-Suche"
|
||||
ai_spam: "Spam"
|
||||
automation: "Automatisierung (%{persona})"
|
||||
automation: "Automatisierung (%{name})"
|
||||
in_use_warning:
|
||||
one: "Dieses Modell wird derzeit von %{settings} verwendet. Wenn es falsch konfiguriert ist, wird die Funktion nicht wie erwartet funktionieren."
|
||||
other: "Dieses Modell wird derzeit verwendet von: %{settings}. Wenn es falsch konfiguriert ist, werden die Funktionen nicht wie erwartet funktionieren. "
|
||||
model_description:
|
||||
none: "Allgemeine Einstellungen, die für die meisten Sprachmodelle funktionieren"
|
||||
anthropic-claude-opus-4-0: "Das intelligenteste Modell von Anthropic"
|
||||
anthropic-claude-sonnet-4-0: "Optimales Gleichgewicht zwischen Geschwindigkeit und Kosten"
|
||||
anthropic-claude-3-7-sonnet-latest: "Optimales Gleichgewicht zwischen Geschwindigkeit und Kosten (vorherige Generation)"
|
||||
anthropic-claude-3-5-haiku-latest: "Schnell und kosteneffizient"
|
||||
google-gemini-2-5-pro: "Großes multimodales Modell, das eine Vielzahl von Aufgaben bewältigen kann"
|
||||
google-gemini-2-0-flash: "Leicht, schnell und kosteneffizient mit multimodaler Argumentation (vorherige Generation)"
|
||||
google-gemini-2-5-flash: "Leicht, schnell und kosteneffizient mit multimodaler Argumentation"
|
||||
google-gemini-2-0-flash-lite: "Kosteneffizientes Modell mit niedriger Latenz"
|
||||
open_ai-o3: "Das leistungsfähigste Argumentationsmodell von Open AI"
|
||||
@@ -573,9 +505,6 @@ de:
|
||||
samba_nova-Meta-Llama-3-3-70B-Instruct": "Leistungsstarkes Mehrzweckmodell"
|
||||
mistral-mistral-large-latest: "Das leistungsstärkste Modell von Mistral"
|
||||
mistral-pixtral-large-latest: "Das leistungsstärkste Modell von Mistral mit Sichtfunktion"
|
||||
open_router-x-ai-grok-3-beta: "Das neueste Modell von xAI"
|
||||
open_router-deepseek-deepseek-r1-0528-free: "DeepSeeks neuestes Argumentationsmodell"
|
||||
open_router-meta-llama-3-3-70b-instruct: "Leistungsstarkes mehrsprachiges Modell"
|
||||
preseeded_model_description: "Vorkonfiguriertes Open-Source-Modell unter Verwendung von %{model}"
|
||||
configured:
|
||||
title: "Konfigurierte LLMs"
|
||||
@@ -636,7 +565,6 @@ de:
|
||||
reasoning_tokens: "Anzahl der für die Argumentation verwendeten Token"
|
||||
disable_temperature: "Temperatur deaktivieren (einige Denkmodelle unterstützen keine Temperatur)"
|
||||
disable_top_p: "Top P deaktivieren (einige Denkmodelle unterstützen Top P nicht)"
|
||||
enable_responses_api: "Aktiviere die Antwort-API (bei bestimmten OpenAI-Modellen erforderlich)"
|
||||
related_topics:
|
||||
title: "Verwandte Themen"
|
||||
pill: "Verwandt"
|
||||
@@ -655,7 +583,6 @@ de:
|
||||
trigger: "KI fragen"
|
||||
loading: "KI generiert"
|
||||
cancel: "Abbrechen"
|
||||
regen: "Erneut versuchen"
|
||||
confirm: "Bestätigen"
|
||||
discard: "Verwerfen"
|
||||
changes: "Empfohlene Änderungen"
|
||||
@@ -832,7 +759,6 @@ de:
|
||||
today: "Heute"
|
||||
last_7_days: "Letzte 7 Tage"
|
||||
last_30_days: "Letzte 30 Tage"
|
||||
upload_files: "Dateien hochladen"
|
||||
sentiments:
|
||||
dashboard:
|
||||
title: "Stimmung"
|
||||
|
||||
@@ -106,9 +106,6 @@ en:
|
||||
top_p:
|
||||
label: "Top P"
|
||||
description: "Top P to use for the LLM, increase to increase randomness (leave empty to use model default)"
|
||||
persona_id:
|
||||
label: "Persona"
|
||||
description: "AI Persona to use for report generation"
|
||||
|
||||
llm_tool_triage:
|
||||
fields:
|
||||
@@ -875,7 +872,6 @@ en:
|
||||
last_7_days: "Last 7 days"
|
||||
last_30_days: "Last 30 days"
|
||||
upload_files: "Upload files"
|
||||
uploads_in_progress: "Cannot submit while uploads are in progress"
|
||||
sentiments:
|
||||
dashboard:
|
||||
title: "Sentiment"
|
||||
|
||||
@@ -154,8 +154,6 @@ es:
|
||||
reset: "Restablecer"
|
||||
search:
|
||||
name: "Buscar"
|
||||
embeddings:
|
||||
name: "Incrustaciones"
|
||||
ai_helper:
|
||||
name: "Ayudante"
|
||||
proofread: Corregir el texto
|
||||
|
||||
@@ -154,8 +154,6 @@ fi:
|
||||
reset: "Palauta"
|
||||
search:
|
||||
name: "Hae"
|
||||
embeddings:
|
||||
name: "Upotukset"
|
||||
ai_helper:
|
||||
name: "Apuri"
|
||||
proofread: Oikolue teksti
|
||||
|
||||
@@ -154,8 +154,6 @@ fr:
|
||||
reset: "Réinitialiser"
|
||||
search:
|
||||
name: "Recherche"
|
||||
embeddings:
|
||||
name: "Intégrations"
|
||||
ai_helper:
|
||||
name: "Assistant"
|
||||
proofread: Relisez le texte
|
||||
|
||||
@@ -185,7 +185,6 @@ he:
|
||||
two: "LLMים:"
|
||||
many: "LLMים:"
|
||||
other: "LLMים:"
|
||||
no_llm: "לא נבחר מש״ג/LLM"
|
||||
no_persona: "לא מוגדר"
|
||||
no_groups: "ללא"
|
||||
edit: "עריכה"
|
||||
@@ -197,44 +196,24 @@ he:
|
||||
collapse_list: "(להציג פחות)"
|
||||
bot:
|
||||
name: "בוט"
|
||||
description: "צ׳אט בוט שיכול לענות על שאלות ולסייע למשתמשים בהודעות אישיות, בפורום ובצ׳אט"
|
||||
filters:
|
||||
all: "הכול"
|
||||
text: "חיפוש יכולות, דמויות, LLMים/מש״גים או קבוצות…"
|
||||
reset: "איפוס"
|
||||
summarization:
|
||||
name: "סיכומים"
|
||||
description: "להנגיש את כפתור הסיכום שמאפשר למבקרים לסכם נושאים"
|
||||
topic_summaries: "תקצירי נושאים."
|
||||
search:
|
||||
name: "חיפוש"
|
||||
description: "שיפור חוויית החיפוש על ידי אספקת תשובות שנוצרו על ידי בינה מלאכותית לשאילתות"
|
||||
discoveries: "תגליות"
|
||||
embeddings:
|
||||
name: "הטמעות"
|
||||
discord:
|
||||
name: "שילוב מול Discord"
|
||||
description: "הוספת היכולת לחפש בערוצי Discord"
|
||||
search: "חיפוש ב־Discord"
|
||||
inference:
|
||||
generate_concepts: "הסקת תפיסות"
|
||||
ai_helper:
|
||||
name: "מסייע"
|
||||
proofread: הגהת הטקסט
|
||||
title_suggestions: "הצעת כותרות"
|
||||
explain: "הסבר"
|
||||
illustrate_post: "איור פוסט"
|
||||
smart_dates: "תאריכים חכמים"
|
||||
translate: "תרגום"
|
||||
markdown_tables: "יצירת טבלה ב־Markdown"
|
||||
custom_prompt: "בקשה מותאמת אישית"
|
||||
image_caption: "הוספת כותרות לתמונות"
|
||||
translation:
|
||||
description: "תרגום תוכן לשפות נתמכות"
|
||||
locale_detector: "מזהה שפה ומקום"
|
||||
post_raw_translator: "מתרגם פוסטים גולמי"
|
||||
topic_title_translator: "מתרגם כותרות נושאים"
|
||||
short_text_translator: "מתרגם טקסטים קצרים"
|
||||
spam:
|
||||
name: "ספאם"
|
||||
modals:
|
||||
@@ -512,7 +491,7 @@ he:
|
||||
ai_summarization: "סיכום"
|
||||
ai_embeddings_semantic_search: "חיפוש בינה מלאכותית"
|
||||
ai_spam: "ספאם"
|
||||
automation: "אוטומציה (%{persona})"
|
||||
automation: "אוטומציה (%{name})"
|
||||
in_use_warning:
|
||||
one: "המודל הזה משמש את %{settings}. אם לא מוגדר כראוי, היכולת לא תעבוד כמצופה."
|
||||
two: "המודל הזה משמש את: %{settings}. אם ההגדרות שגויות היכולת לא תעבודנה כמצופה."
|
||||
|
||||
@@ -154,8 +154,6 @@ it:
|
||||
reset: "Annulla"
|
||||
search:
|
||||
name: "Cerca"
|
||||
embeddings:
|
||||
name: "Integrazioni"
|
||||
ai_helper:
|
||||
name: "Assistente"
|
||||
proofread: Testo corretto
|
||||
|
||||
@@ -157,8 +157,6 @@ ja:
|
||||
reset: "リセット"
|
||||
search:
|
||||
name: "検索"
|
||||
embeddings:
|
||||
name: "埋め込み"
|
||||
ai_helper:
|
||||
name: "ヘルパー"
|
||||
proofread: テキストを構成
|
||||
|
||||
@@ -154,8 +154,6 @@ nl:
|
||||
reset: "Resetten"
|
||||
search:
|
||||
name: "Zoeken"
|
||||
embeddings:
|
||||
name: "Insluitingen"
|
||||
ai_helper:
|
||||
name: "Helper"
|
||||
proofread: Tekst proeflezen
|
||||
|
||||
@@ -154,8 +154,6 @@ pt_BR:
|
||||
reset: "Redefinir"
|
||||
search:
|
||||
name: "Pesquisar"
|
||||
embeddings:
|
||||
name: "Incorporações"
|
||||
ai_helper:
|
||||
name: "Ajudante"
|
||||
proofread: Revisar texto
|
||||
|
||||
@@ -156,8 +156,6 @@ ru:
|
||||
reset: "Сбросить"
|
||||
search:
|
||||
name: "Искать"
|
||||
embeddings:
|
||||
name: "Встраивания"
|
||||
ai_helper:
|
||||
name: "Помощник"
|
||||
proofread: Вычитать текст
|
||||
|
||||
@@ -154,8 +154,6 @@ tr_TR:
|
||||
reset: "Sıfırla"
|
||||
search:
|
||||
name: "Ara"
|
||||
embeddings:
|
||||
name: "Gömmeler"
|
||||
ai_helper:
|
||||
name: "Yardımcı"
|
||||
proofread: Yazım hataları düzeltilmiş metin
|
||||
|
||||
@@ -173,8 +173,6 @@ zh_CN:
|
||||
reset: "重置"
|
||||
search:
|
||||
name: "搜索"
|
||||
embeddings:
|
||||
name: "嵌入向量"
|
||||
ai_helper:
|
||||
name: "助手"
|
||||
proofread: 审校文本
|
||||
|
||||
@@ -14,10 +14,10 @@ de:
|
||||
spam_silence: "Als Spam melden, Beitrag ausblenden und Benutzer stummschalten"
|
||||
scriptables:
|
||||
llm_tool_triage:
|
||||
title: Sichtung von Beiträgen mit dem KI-Tool
|
||||
description: "Sichtung von Beiträgen mit benutzerdefinierter Logik in einem KI-Tool"
|
||||
title: Triage von Beiträgen mit dem KI-Tool
|
||||
description: "Triage von Beiträgen mit benutzerdefinierter Logik in einem KI-Tool"
|
||||
llm_persona_triage:
|
||||
title: Sichtung von Beiträgen mit KI-Persona
|
||||
title: Triage von Posts mit KI-Persona
|
||||
description: "Reagiere auf Beiträge mit einer bestimmten KI-Persona"
|
||||
llm_triage:
|
||||
title: Beiträge mithilfe von KI sortieren
|
||||
@@ -31,7 +31,6 @@ de:
|
||||
description: "Regelmäßiger Bericht auf der Grundlage eines großen Sprachmodells"
|
||||
site_settings:
|
||||
discourse_ai_enabled: "Aktiviere das Discourse-KI-Plug-in."
|
||||
ai_artifact_security: "Das KI-Artefaktsystem generiert IFRAMEs mit ausführbarem Code. Der strikte Modus erfordert einen zusätzlichen Klick zum Ausführen des Codes. Der laxe Modus führt Code sofort aus. Im Hybridmodus kann der Benutzer data-ai-artifact-autorun angeben, um den Code sofort anzuzeigen. Der deaktivierte Modus deaktiviert das Artefaktsystem."
|
||||
ai_toxicity_enabled: "Aktiviere das Toxizitätsmodul."
|
||||
ai_toxicity_inference_service_api_endpoint: "URL, unter der die API für das Toxizitätsmodul läuft"
|
||||
ai_toxicity_inference_service_api_key: "API-Schlüssel für die Toxizitäts-API"
|
||||
@@ -112,11 +111,6 @@ de:
|
||||
ai_discord_search_persona: "Die Persona, die für die Discord-Suche verwendet wird."
|
||||
ai_discord_allowed_guilds: "Discord-Gilden (Server), auf denen der Bot suchen darf"
|
||||
ai_bot_enable_dedicated_ux: "Erlaube eine Vollbild-Bot-Oberfläche anstelle einer PM"
|
||||
ai_translation_enabled: "Aktiviert die KI-Übersetzungsfunktion"
|
||||
ai_translation_model: "Das Modell, das für die Übersetzung verwendet werden soll. Dieses Modell muss die Übersetzung unterstützen. Personas können diese Einstellung überschreiben."
|
||||
ai_translation_backfill_limit_to_public_content: "Wenn diese Option aktiviert ist, werden nur Inhalte in öffentlichen Kategorien übersetzt. Wenn sie deaktiviert ist, werden auch Inhalte in Gruppen-PMs und privaten Kategorien zur Übersetzung gesendet."
|
||||
ai_translation_max_post_length: "Die maximale Länge eines zu übersetzenden Beitrags. Längere Beiträge werden nicht übersetzt."
|
||||
ai_translation_backfill_max_age_days: "Das maximale Alter eines zu übersetzenden Beitrags und Themas. Ältere Beiträge und Themen werden nicht übersetzt."
|
||||
reviewables:
|
||||
reasons:
|
||||
flagged_by_toxicity: Das KI-Plug-in meldete dies nach der Klassifizierung als toxisch.
|
||||
@@ -216,15 +210,9 @@ de:
|
||||
description: "Beiträge, die per KI unter Verwendung des Modells „SamLowe/roberta-base-go_emotions“ mit der Emotion „Überraschung“ klassifiziert wurden."
|
||||
discourse_ai:
|
||||
ai_artifact:
|
||||
errors:
|
||||
max_keys_exceeded:
|
||||
one: "Du kannst nur %{count} Schlüssel im Artefakt haben."
|
||||
other: "Du kannst nur %{count} Schlüssel im Artefakt haben."
|
||||
link: "In neuem Tab anzeigen"
|
||||
view_source: "Quelle anzeigen"
|
||||
view_changes: "Änderungen anzeigen"
|
||||
change_description: "Beschreibung ändern"
|
||||
copied: "Wurde in Zwischenablage kopiert"
|
||||
unknown_model: "Unbekanntes KI-Modell"
|
||||
tools:
|
||||
custom_name: "%{name} (benutzerdefiniert)"
|
||||
@@ -277,7 +265,6 @@ de:
|
||||
unexpected: "Ein unerwarteter Fehler ist aufgetreten"
|
||||
bot_user_update_failed: "Aktualisierung des Spam-Scan-Bot-Benutzers fehlgeschlagen"
|
||||
configuration_missing: "Die Konfiguration der KI-Spamerkennung fehlt. Füge die Konfiguration in „Administration > Plug-ins > Discourse KI > Spam“ hinzu, bevor du sie aktivierst."
|
||||
logging_subject: "Spam-Erkennung"
|
||||
ai_bot:
|
||||
reply_error: "Entschuldigung, es sieht so aus, als ob unser System beim Versuch, zu antworten, auf ein unerwartetes Problem gestoßen ist.\n\n[details='Fehlerdetails']\n%{details}\n[/details]"
|
||||
default_pm_prefix: "[KI-Bot-PN ohne Titel]"
|
||||
@@ -365,24 +352,6 @@ de:
|
||||
image_captioner:
|
||||
name: "Bildbeschriftungen"
|
||||
description: "Standard-Persona für die Bildbeschriftungsfunktion des Helfers"
|
||||
locale_detector:
|
||||
name: "Sprachdetektor"
|
||||
description: "Unterstützt die Übersetzungsfunktion durch Erkennen der Sprache eines bestimmten Textes (Beiträge, Titel usw.)."
|
||||
post_raw_translator:
|
||||
name: "Beitragsübersetzer"
|
||||
description: "Unterstützt die Übersetzungsfunktion durch die Übersetzung von Beiträgen, die Discourse Markdown enthalten"
|
||||
topic_title_translator:
|
||||
name: "Thementitel-Übersetzer"
|
||||
description: "Unterstützt die Übersetzungsfunktion durch die Übersetzung von Thementiteln"
|
||||
short_text_translator:
|
||||
name: "Kurztext-Übersetzer"
|
||||
description: "Betreibt die Übersetzungsfunktion als generischer Textübersetzer, der für kurze Texte wie Kategorienamen oder Schlagwörter verwendet wird."
|
||||
spam_detector:
|
||||
name: "Spam-Detektor"
|
||||
description: "Standard-Persona, die unsere Spam-Erkennungsfunktion betreibt"
|
||||
content_creator:
|
||||
name: "Inhaltsersteller"
|
||||
description: "Standard-Persona für die HyDE-Suche"
|
||||
topic_not_found: "Zusammenfassung nicht verfügbar, Thema nicht gefunden!"
|
||||
summarizing: "Thema zusammenfassen"
|
||||
searching: "Suche nach: „%{query}“"
|
||||
@@ -565,7 +534,6 @@ de:
|
||||
set_llm_first: "Stelle zuerst %{setting} ein"
|
||||
model_unreachable: "Wir konnten keine Antwort von diesem Modell abrufen. Überprüfe zuerst deine Einstellungen."
|
||||
invalid_seeded_model: "Du kannst dieses Modell nicht mit dieser Funktion verwenden"
|
||||
invalid_persona_response_format: "Die ausgewählte Persona muss ein Antwortformat mit einem booleschen Feld namens „spam“ haben."
|
||||
must_select_model: "Du musst zuerst ein LLM auswählen"
|
||||
endpoints:
|
||||
not_configured: "%{display_name} (nicht konfiguriert)"
|
||||
@@ -603,10 +571,6 @@ de:
|
||||
no_default_llm: Die Persona muss eine default_llm definiert haben.
|
||||
user_not_allowed: Der Benutzer darf nicht am Thema teilnehmen.
|
||||
prompt_message_length: Die Nachricht %{idx} hat die 1000-Zeichen-Grenze überschritten.
|
||||
persona_already_exists: Eine Persona mit dem Namen %{name} existiert bereits.
|
||||
custom_tool_exists:
|
||||
one: "Ein benutzerdefiniertes Tool mit dem Namen %{names} existiert bereits."
|
||||
other: "Benutzerdefinierte Tools mit den Namen %{names} existieren bereits."
|
||||
dashboard:
|
||||
problem:
|
||||
ai_llm_status: "Bei dem LLM-Modell: %{model_name} treten Probleme auf. Bitte überprüfe <a href='%{url}'>die Konfigurationsseite des Modells</a>."
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user