Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7912b5e8be |
@@ -50,7 +50,7 @@ module DiscourseAi
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
SiteSetting.set_and_log("ai_spam_detection_enabled", is_enabled, current_user)
|
SiteSetting.ai_spam_detection_enabled = is_enabled
|
||||||
end
|
end
|
||||||
|
|
||||||
render json: AiSpamSerializer.new(spam_config, root: false)
|
render json: AiSpamSerializer.new(spam_config, root: false)
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
module Jobs
|
|
||||||
class DetectTranslatePost < ::Jobs::Base
|
|
||||||
sidekiq_options retry: false
|
|
||||||
|
|
||||||
def execute(args)
|
|
||||||
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])
|
|
||||||
return if post.blank? || post.raw.blank? || post.deleted_at.present? || post.user_id <= 0
|
|
||||||
|
|
||||||
if SiteSetting.ai_translation_backfill_limit_to_public_content
|
|
||||||
topic = post.topic
|
|
||||||
if topic.blank? || topic.category&.read_restricted? ||
|
|
||||||
topic.archetype == Archetype.private_message
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
begin
|
|
||||||
detected_locale = DiscourseAi::Translation::PostLocaleDetector.detect_locale(post)
|
|
||||||
rescue FinalDestination::SSRFDetector::LookupFailedError
|
|
||||||
# this job is non-critical
|
|
||||||
# the backfill job will handle failures
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
locales = SiteSetting.experimental_content_localization_supported_locales.split("|")
|
|
||||||
return if locales.blank?
|
|
||||||
|
|
||||||
locales.each do |locale|
|
|
||||||
next if locale == detected_locale
|
|
||||||
|
|
||||||
begin
|
|
||||||
DiscourseAi::Translation::PostLocalizer.localize(post, locale)
|
|
||||||
rescue FinalDestination::SSRFDetector::LookupFailedError
|
|
||||||
# do nothing, there are too many sporadic lookup failures
|
|
||||||
rescue => e
|
|
||||||
DiscourseAi::Translation::VerboseLogger.log(
|
|
||||||
"Failed to translate post #{post.id} to #{locale}: #{e.message}",
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
MessageBus.publish("/topic/#{post.topic_id}", type: :localized, id: post.id)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
module Jobs
|
|
||||||
class DetectTranslateTopic < ::Jobs::Base
|
|
||||||
sidekiq_options retry: false
|
|
||||||
|
|
||||||
def execute(args)
|
|
||||||
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])
|
|
||||||
if topic.blank? || topic.title.blank? || topic.deleted_at.present? || topic.user_id <= 0
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if SiteSetting.ai_translation_backfill_limit_to_public_content
|
|
||||||
return if topic.category&.read_restricted?
|
|
||||||
end
|
|
||||||
|
|
||||||
begin
|
|
||||||
detected_locale = DiscourseAi::Translation::TopicLocaleDetector.detect_locale(topic)
|
|
||||||
rescue FinalDestination::SSRFDetector::LookupFailedError
|
|
||||||
# this job is non-critical
|
|
||||||
# the backfill job will handle failures
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
locales = SiteSetting.experimental_content_localization_supported_locales.split("|")
|
|
||||||
return if locales.blank?
|
|
||||||
|
|
||||||
locales.each do |locale|
|
|
||||||
next if locale == detected_locale
|
|
||||||
|
|
||||||
begin
|
|
||||||
DiscourseAi::Translation::TopicLocalizer.localize(topic, locale)
|
|
||||||
rescue FinalDestination::SSRFDetector::LookupFailedError
|
|
||||||
# do nothing, there are too many sporadic lookup failures
|
|
||||||
rescue => e
|
|
||||||
DiscourseAi::Translation::VerboseLogger.log(
|
|
||||||
"Failed to translate topic #{topic.id} to #{locale}: #{e.message}",
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
MessageBus.publish("/topic/#{topic.id}", type: :localized, id: 1)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
module Jobs
|
|
||||||
class LocalizeCategories < ::Jobs::Base
|
|
||||||
cluster_concurrency 1
|
|
||||||
sidekiq_options retry: false
|
|
||||||
|
|
||||||
BATCH_SIZE = 50
|
|
||||||
|
|
||||||
def execute(args)
|
|
||||||
return if !SiteSetting.discourse_ai_enabled
|
|
||||||
return if !SiteSetting.ai_translation_enabled
|
|
||||||
|
|
||||||
locales = SiteSetting.experimental_content_localization_supported_locales.split("|")
|
|
||||||
return if locales.blank?
|
|
||||||
|
|
||||||
cat_id = args[:from_category_id] || Category.order(:id).first&.id
|
|
||||||
last_id = nil
|
|
||||||
|
|
||||||
categories = Category.where("id >= ?", cat_id).order(:id).limit(BATCH_SIZE)
|
|
||||||
return if categories.empty?
|
|
||||||
|
|
||||||
categories.each do |category|
|
|
||||||
if SiteSetting.ai_translation_backfill_limit_to_public_content && category.read_restricted?
|
|
||||||
last_id = category.id
|
|
||||||
next
|
|
||||||
end
|
|
||||||
|
|
||||||
CategoryLocalization.transaction do
|
|
||||||
locales.each do |locale|
|
|
||||||
next if CategoryLocalization.exists?(category_id: category.id, locale: locale)
|
|
||||||
begin
|
|
||||||
DiscourseAi::Translation::CategoryLocalizer.localize(category, locale)
|
|
||||||
rescue FinalDestination::SSRFDetector::LookupFailedError
|
|
||||||
# do nothing, there are too many sporadic lookup failures
|
|
||||||
rescue => e
|
|
||||||
DiscourseAi::Translation::VerboseLogger.log(
|
|
||||||
"Failed to translate category #{category.id} to #{locale}: #{e.message}",
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
last_id = category.id
|
|
||||||
end
|
|
||||||
|
|
||||||
if categories.size == BATCH_SIZE
|
|
||||||
Jobs.enqueue_in(10.seconds, :localize_categories, from_category_id: last_id + 1)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
module Jobs
|
|
||||||
class LocalizePosts < ::Jobs::Base
|
|
||||||
cluster_concurrency 1
|
|
||||||
sidekiq_options retry: false
|
|
||||||
|
|
||||||
BATCH_SIZE = 50
|
|
||||||
|
|
||||||
def execute(args)
|
|
||||||
return if !SiteSetting.discourse_ai_enabled
|
|
||||||
return if !SiteSetting.ai_translation_enabled
|
|
||||||
|
|
||||||
locales = SiteSetting.experimental_content_localization_supported_locales.split("|")
|
|
||||||
return if locales.blank?
|
|
||||||
|
|
||||||
limit = args[:limit] || BATCH_SIZE
|
|
||||||
|
|
||||||
locales.each do |locale|
|
|
||||||
posts =
|
|
||||||
Post
|
|
||||||
.joins(
|
|
||||||
"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.not(locale: locale)
|
|
||||||
.where("pl.id IS NULL")
|
|
||||||
|
|
||||||
if SiteSetting.ai_translation_backfill_limit_to_public_content
|
|
||||||
posts =
|
|
||||||
posts
|
|
||||||
.joins(:topic)
|
|
||||||
.where(topics: { category_id: Category.where(read_restricted: false).select(:id) })
|
|
||||||
.where.not(topics: { archetype: Archetype.private_message })
|
|
||||||
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?
|
|
||||||
|
|
||||||
posts.each do |post|
|
|
||||||
begin
|
|
||||||
DiscourseAi::Translation::PostLocalizer.localize(post, locale)
|
|
||||||
rescue FinalDestination::SSRFDetector::LookupFailedError
|
|
||||||
# do nothing, there are too many sporadic lookup failures
|
|
||||||
rescue => e
|
|
||||||
DiscourseAi::Translation::VerboseLogger.log(
|
|
||||||
"Failed to translate post #{post.id} to #{locale}: #{e.message}",
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
DiscourseAi::Translation::VerboseLogger.log("Translated #{posts.size} posts to #{locale}")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
module Jobs
|
|
||||||
class LocalizeTopics < ::Jobs::Base
|
|
||||||
cluster_concurrency 1
|
|
||||||
sidekiq_options retry: false
|
|
||||||
|
|
||||||
BATCH_SIZE = 50
|
|
||||||
|
|
||||||
def execute(args)
|
|
||||||
return if !SiteSetting.discourse_ai_enabled
|
|
||||||
return if !SiteSetting.ai_translation_enabled
|
|
||||||
|
|
||||||
locales = SiteSetting.experimental_content_localization_supported_locales.split("|")
|
|
||||||
return if locales.blank?
|
|
||||||
|
|
||||||
limit = args[:limit] || BATCH_SIZE
|
|
||||||
|
|
||||||
locales.each do |locale|
|
|
||||||
topics =
|
|
||||||
Topic
|
|
||||||
.joins(
|
|
||||||
"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.not(locale: locale)
|
|
||||||
.where("tl.id IS NULL")
|
|
||||||
|
|
||||||
if SiteSetting.ai_translation_backfill_limit_to_public_content
|
|
||||||
topics = topics.where(category_id: Category.where(read_restricted: false).select(:id))
|
|
||||||
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?
|
|
||||||
|
|
||||||
topics.each do |topic|
|
|
||||||
begin
|
|
||||||
DiscourseAi::Translation::TopicLocalizer.localize(topic, locale)
|
|
||||||
rescue FinalDestination::SSRFDetector::LookupFailedError
|
|
||||||
# do nothing, there are too many sporadic lookup failures
|
|
||||||
rescue => e
|
|
||||||
DiscourseAi::Translation::VerboseLogger.log(
|
|
||||||
"Failed to translate topic #{topic.id} to #{locale}: #{e.message}",
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
DiscourseAi::Translation::VerboseLogger.log("Translated #{topics.size} topics to #{locale}")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
module Jobs
|
|
||||||
class CategoryLocalizationBackfill < ::Jobs::Scheduled
|
|
||||||
every 12.hours
|
|
||||||
cluster_concurrency 1
|
|
||||||
|
|
||||||
def execute(args)
|
|
||||||
return if !SiteSetting.discourse_ai_enabled
|
|
||||||
return if !SiteSetting.ai_translation_enabled
|
|
||||||
return if SiteSetting.experimental_content_localization_supported_locales.blank?
|
|
||||||
|
|
||||||
Jobs.enqueue(:localize_categories)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
module Jobs
|
|
||||||
class PostLocalizationBackfill < ::Jobs::Scheduled
|
|
||||||
every 5.minutes
|
|
||||||
cluster_concurrency 1
|
|
||||||
|
|
||||||
def execute(args)
|
|
||||||
return if !SiteSetting.discourse_ai_enabled
|
|
||||||
return if !SiteSetting.ai_translation_enabled
|
|
||||||
|
|
||||||
return if SiteSetting.experimental_content_localization_supported_locales.blank?
|
|
||||||
return if SiteSetting.ai_translation_backfill_rate == 0
|
|
||||||
|
|
||||||
Jobs.enqueue(:localize_posts, limit: SiteSetting.ai_translation_backfill_rate)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
module Jobs
|
|
||||||
class PostsLocaleDetectionBackfill < ::Jobs::Scheduled
|
|
||||||
every 5.minutes
|
|
||||||
sidekiq_options retry: false
|
|
||||||
cluster_concurrency 1
|
|
||||||
|
|
||||||
def execute(args)
|
|
||||||
return if !SiteSetting.discourse_ai_enabled
|
|
||||||
return if !SiteSetting.ai_translation_enabled
|
|
||||||
return if SiteSetting.ai_translation_backfill_rate == 0
|
|
||||||
|
|
||||||
posts =
|
|
||||||
Post
|
|
||||||
.where(locale: nil)
|
|
||||||
.where(deleted_at: nil)
|
|
||||||
.where("posts.user_id > 0")
|
|
||||||
.where.not(raw: [nil, ""])
|
|
||||||
|
|
||||||
if SiteSetting.ai_translation_backfill_limit_to_public_content
|
|
||||||
public_categories = Category.where(read_restricted: false).pluck(:id)
|
|
||||||
posts =
|
|
||||||
posts
|
|
||||||
.joins(:topic)
|
|
||||||
.where(topics: { category_id: public_categories })
|
|
||||||
.where(topics: { archetype: "regular" })
|
|
||||||
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(SiteSetting.ai_translation_backfill_rate)
|
|
||||||
return if posts.empty?
|
|
||||||
|
|
||||||
posts.each do |post|
|
|
||||||
begin
|
|
||||||
DiscourseAi::Translation::PostLocaleDetector.detect_locale(post)
|
|
||||||
rescue FinalDestination::SSRFDetector::LookupFailedError
|
|
||||||
# do nothing, there are too many sporadic lookup failures
|
|
||||||
rescue => e
|
|
||||||
DiscourseAi::Translation::VerboseLogger.log(
|
|
||||||
"Failed to detect post #{post.id}'s locale: #{e.message}",
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
DiscourseAi::Translation::VerboseLogger.log("Detected #{posts.size} post locales")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
module Jobs
|
|
||||||
class TopicLocalizationBackfill < ::Jobs::Scheduled
|
|
||||||
every 5.minutes
|
|
||||||
cluster_concurrency 1
|
|
||||||
|
|
||||||
def execute(args)
|
|
||||||
return if !SiteSetting.discourse_ai_enabled
|
|
||||||
return if !SiteSetting.ai_translation_enabled
|
|
||||||
|
|
||||||
return if SiteSetting.experimental_content_localization_supported_locales.blank?
|
|
||||||
return if SiteSetting.ai_translation_backfill_rate == 0
|
|
||||||
|
|
||||||
Jobs.enqueue(:localize_topics, limit: SiteSetting.ai_translation_backfill_rate)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
module Jobs
|
|
||||||
class TopicsLocaleDetectionBackfill < ::Jobs::Scheduled
|
|
||||||
every 5.minutes
|
|
||||||
sidekiq_options retry: false
|
|
||||||
cluster_concurrency 1
|
|
||||||
|
|
||||||
def execute(args)
|
|
||||||
return if !SiteSetting.discourse_ai_enabled
|
|
||||||
return if !SiteSetting.ai_translation_enabled
|
|
||||||
limit = SiteSetting.ai_translation_backfill_rate
|
|
||||||
return if limit == 0
|
|
||||||
|
|
||||||
topics = Topic.where(locale: nil, deleted_at: nil).where("topics.user_id > 0")
|
|
||||||
|
|
||||||
if SiteSetting.ai_translation_backfill_limit_to_public_content
|
|
||||||
topics = topics.where(category_id: Category.where(read_restricted: false).select(:id))
|
|
||||||
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?
|
|
||||||
|
|
||||||
topics.each do |topic|
|
|
||||||
begin
|
|
||||||
DiscourseAi::Translation::TopicLocaleDetector.detect_locale(topic)
|
|
||||||
rescue FinalDestination::SSRFDetector::LookupFailedError
|
|
||||||
# do nothing, there are too many sporadic lookup failures
|
|
||||||
rescue => e
|
|
||||||
DiscourseAi::Translation::VerboseLogger.log(
|
|
||||||
"Failed to detect topic #{topic.id}'s locale: #{e.message}",
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
DiscourseAi::Translation::VerboseLogger.log("Detected #{topics.size} topic locales")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -5,7 +5,6 @@ import DButton from "discourse/components/d-button";
|
|||||||
import { AI_CONVERSATIONS_PANEL } from "../services/ai-conversations-sidebar-manager";
|
import { AI_CONVERSATIONS_PANEL } from "../services/ai-conversations-sidebar-manager";
|
||||||
|
|
||||||
export default class AiBotSidebarNewConversation extends Component {
|
export default class AiBotSidebarNewConversation extends Component {
|
||||||
@service appEvents;
|
|
||||||
@service router;
|
@service router;
|
||||||
@service sidebarState;
|
@service sidebarState;
|
||||||
|
|
||||||
@@ -15,8 +14,6 @@ export default class AiBotSidebarNewConversation extends Component {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
routeTo() {
|
routeTo() {
|
||||||
this.appEvents.trigger("discourse-ai:new-conversation-btn-clicked");
|
|
||||||
|
|
||||||
if (this.router.currentRouteName !== "discourse-ai-bot-conversations") {
|
if (this.router.currentRouteName !== "discourse-ai-bot-conversations") {
|
||||||
this.router.transitionTo("/discourse-ai/ai-bot/conversations");
|
this.router.transitionTo("/discourse-ai/ai-bot/conversations");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ export default class AiPersonaCollapsableExample extends Component {
|
|||||||
(if (eq pairIdx 0) "user" "model")
|
(if (eq pairIdx 0) "user" "model")
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
@validation="required|length:1,5000"
|
@validation="required|length:1,100"
|
||||||
@disabled={{@system}}
|
@disabled={{@system}}
|
||||||
as |field|
|
as |field|
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -18,16 +18,14 @@ import DiffStreamer from "../../lib/diff-streamer";
|
|||||||
import SmoothStreamer from "../../lib/smooth-streamer";
|
import SmoothStreamer from "../../lib/smooth-streamer";
|
||||||
import AiIndicatorWave from "../ai-indicator-wave";
|
import AiIndicatorWave from "../ai-indicator-wave";
|
||||||
|
|
||||||
const CHANNEL = "/discourse-ai/ai-helper/stream_composer_suggestion";
|
|
||||||
|
|
||||||
export default class ModalDiffModal extends Component {
|
export default class ModalDiffModal extends Component {
|
||||||
@service currentUser;
|
@service currentUser;
|
||||||
@service messageBus;
|
@service messageBus;
|
||||||
|
|
||||||
@tracked loading = false;
|
@tracked loading = false;
|
||||||
@tracked finalResult = "";
|
@tracked finalResult = "";
|
||||||
@tracked escapedSelectedText = escapeExpression(this.args.model.selectedText);
|
@tracked selectedText = escapeExpression(this.args.model.selectedText);
|
||||||
@tracked diffStreamer = new DiffStreamer(this.args.model.selectedText);
|
@tracked diffStreamer = new DiffStreamer(this.selectedText);
|
||||||
@tracked suggestion = "";
|
@tracked suggestion = "";
|
||||||
@tracked
|
@tracked
|
||||||
smoothStreamer = new SmoothStreamer(
|
smoothStreamer = new SmoothStreamer(
|
||||||
@@ -47,13 +45,11 @@ export default class ModalDiffModal extends Component {
|
|||||||
|
|
||||||
// Prevents flash by showing the
|
// Prevents flash by showing the
|
||||||
// original text when the diff is empty
|
// original text when the diff is empty
|
||||||
return this.escapedSelectedText;
|
return this.selectedText;
|
||||||
}
|
}
|
||||||
|
|
||||||
get isStreaming() {
|
get isStreaming() {
|
||||||
// diffStreamer stops Streaming when it is finished with a chunk, looking at isDone is safe
|
return this.diffStreamer.isStreaming || this.smoothStreamer.isStreaming;
|
||||||
// it starts off not done
|
|
||||||
return !this.diffStreamer.isDone || this.smoothStreamer.isStreaming;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get primaryBtnLabel() {
|
get primaryBtnLabel() {
|
||||||
@@ -68,23 +64,25 @@ export default class ModalDiffModal extends Component {
|
|||||||
|
|
||||||
@bind
|
@bind
|
||||||
subscribe() {
|
subscribe() {
|
||||||
this.messageBus.subscribe(CHANNEL, this.updateResult);
|
const channel = "/discourse-ai/ai-helper/stream_composer_suggestion";
|
||||||
|
this.messageBus.subscribe(channel, this.updateResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
@bind
|
@bind
|
||||||
cleanup() {
|
unsubscribe() {
|
||||||
// stop all callbacks so it does not end up streaming pointlessly
|
const channel = "/discourse-ai/ai-helper/stream_composer_suggestion";
|
||||||
this.smoothStreamer.resetStreaming();
|
this.messageBus.subscribe(channel, this.updateResult);
|
||||||
this.diffStreamer.reset();
|
|
||||||
this.messageBus.unsubscribe(CHANNEL, this.updateResult);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
updateResult(result) {
|
async updateResult(result) {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
|
|
||||||
if (result.done) {
|
if (result.done) {
|
||||||
this.finalResult = result.result;
|
this.finalResult = result.result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.done) {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,7 +105,7 @@ export default class ModalDiffModal extends Component {
|
|||||||
data: {
|
data: {
|
||||||
location: "composer",
|
location: "composer",
|
||||||
mode: this.args.model.mode,
|
mode: this.args.model.mode,
|
||||||
text: this.args.model.selectedText,
|
text: this.selectedText,
|
||||||
custom_prompt: this.args.model.customPromptValue,
|
custom_prompt: this.args.model.customPromptValue,
|
||||||
force_default_locale: true,
|
force_default_locale: true,
|
||||||
client_id: this.messageBus.clientId,
|
client_id: this.messageBus.clientId,
|
||||||
@@ -124,7 +122,7 @@ export default class ModalDiffModal extends Component {
|
|||||||
|
|
||||||
if (this.suggestion) {
|
if (this.suggestion) {
|
||||||
this.args.model.toolbarEvent.replaceText(
|
this.args.model.toolbarEvent.replaceText(
|
||||||
this.args.model.selectedText,
|
this.selectedText,
|
||||||
this.suggestion
|
this.suggestion
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -133,12 +131,8 @@ export default class ModalDiffModal extends Component {
|
|||||||
this.finalResult?.length > 0
|
this.finalResult?.length > 0
|
||||||
? this.finalResult
|
? this.finalResult
|
||||||
: this.diffStreamer.suggestion;
|
: this.diffStreamer.suggestion;
|
||||||
|
|
||||||
if (this.args.model.showResultAsDiff && finalResult) {
|
if (this.args.model.showResultAsDiff && finalResult) {
|
||||||
this.args.model.toolbarEvent.replaceText(
|
this.args.model.toolbarEvent.replaceText(this.selectedText, finalResult);
|
||||||
this.args.model.selectedText,
|
|
||||||
finalResult
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,7 +145,7 @@ export default class ModalDiffModal extends Component {
|
|||||||
<:body>
|
<:body>
|
||||||
<div
|
<div
|
||||||
{{didInsert this.subscribe}}
|
{{didInsert this.subscribe}}
|
||||||
{{willDestroy this.cleanup}}
|
{{willDestroy this.unsubscribe}}
|
||||||
class="text-preview"
|
class="text-preview"
|
||||||
>
|
>
|
||||||
{{#if this.loading}}
|
{{#if this.loading}}
|
||||||
|
|||||||
+3
-9
@@ -19,6 +19,7 @@ export default class AiPostHelperTrigger extends Component {
|
|||||||
@tracked menuState = this.MENU_STATES.triggers;
|
@tracked menuState = this.MENU_STATES.triggers;
|
||||||
@tracked showMainButtons = true;
|
@tracked showMainButtons = true;
|
||||||
@tracked showAiButtons = true;
|
@tracked showAiButtons = true;
|
||||||
|
@tracked originalPostHTML = null;
|
||||||
@tracked postHighlighted = false;
|
@tracked postHighlighted = false;
|
||||||
@tracked currentMenu = this.menu.getByIdentifier(
|
@tracked currentMenu = this.menu.getByIdentifier(
|
||||||
"post-text-selection-toolbar"
|
"post-text-selection-toolbar"
|
||||||
@@ -44,6 +45,7 @@ export default class AiPostHelperTrigger extends Component {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.originalPostHTML = postElement.innerHTML;
|
||||||
this.selectedText = this.args.outletArgs.data.quoteState.buffer;
|
this.selectedText = this.args.outletArgs.data.quoteState.buffer;
|
||||||
|
|
||||||
const selection = window.getSelection();
|
const selection = window.getSelection();
|
||||||
@@ -119,15 +121,7 @@ export default class AiPostHelperTrigger extends Component {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const highlightedSpans = postElement.querySelectorAll(
|
postElement.innerHTML = this.originalPostHTML;
|
||||||
"span.ai-helper-highlighted-selection"
|
|
||||||
);
|
|
||||||
|
|
||||||
highlightedSpans.forEach((span) => {
|
|
||||||
const textNode = document.createTextNode(span.textContent);
|
|
||||||
span.parentNode.replaceChild(textNode, span);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.postHighlighted = false;
|
this.postHighlighted = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -18,8 +18,8 @@ export default class AiConversationInvite extends Component {
|
|||||||
|
|
||||||
get participants() {
|
get participants() {
|
||||||
const participants = [
|
const participants = [
|
||||||
...(this.header.topicInfo.details?.allowed_users ?? []),
|
...this.header.topicInfo.details.allowed_users,
|
||||||
...(this.header.topicInfo.details?.allowed_groups ?? []),
|
...this.header.topicInfo.details.allowed_groups,
|
||||||
];
|
];
|
||||||
return participants;
|
return participants;
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,24 +0,0 @@
|
|||||||
import { apiInitializer } from "discourse/lib/api";
|
|
||||||
import cookie from "discourse/lib/cookie";
|
|
||||||
|
|
||||||
export default apiInitializer((api) => {
|
|
||||||
const settings = api.container.lookup("service:site-settings");
|
|
||||||
|
|
||||||
if (!settings.discourse_ai_enabled || !settings.ai_translation_enabled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
api.registerCustomPostMessageCallback(
|
|
||||||
"localized",
|
|
||||||
(topicController, data) => {
|
|
||||||
if (!cookie("content-localization-show-original")) {
|
|
||||||
const postStream = topicController.get("model.postStream");
|
|
||||||
postStream.triggerChangedPost(data.id, data.updated_at).then(() => {
|
|
||||||
topicController.appEvents.trigger("post-stream:refresh", {
|
|
||||||
id: data.id,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
@use "lib/viewport";
|
|
||||||
|
|
||||||
.composer-ai-helper-modal {
|
.composer-ai-helper-modal {
|
||||||
.text-preview,
|
.text-preview,
|
||||||
.inline-diff {
|
.inline-diff {
|
||||||
@@ -181,7 +179,7 @@
|
|||||||
|
|
||||||
@keyframes dot-falling {
|
@keyframes dot-falling {
|
||||||
0% {
|
0% {
|
||||||
box-shadow: 9999px -15px 0 0 rgb(152, 128, 255, 0);
|
box-shadow: 9999px -15px 0 0 rgba(152, 128, 255, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
25%,
|
25%,
|
||||||
@@ -191,13 +189,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
100% {
|
100% {
|
||||||
box-shadow: 9999px 15px 0 0 rgb(152, 128, 255, 0);
|
box-shadow: 9999px 15px 0 0 rgba(152, 128, 255, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes dot-falling-before {
|
@keyframes dot-falling-before {
|
||||||
0% {
|
0% {
|
||||||
box-shadow: 9984px -15px 0 0 rgb(152, 128, 255, 0);
|
box-shadow: 9984px -15px 0 0 rgba(152, 128, 255, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
25%,
|
25%,
|
||||||
@@ -207,13 +205,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
100% {
|
100% {
|
||||||
box-shadow: 9984px 15px 0 0 rgb(152, 128, 255, 0);
|
box-shadow: 9984px 15px 0 0 rgba(152, 128, 255, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes dot-falling-after {
|
@keyframes dot-falling-after {
|
||||||
0% {
|
0% {
|
||||||
box-shadow: 10014px -15px 0 0 rgb(152, 128, 255, 0);
|
box-shadow: 10014px -15px 0 0 rgba(152, 128, 255, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
25%,
|
25%,
|
||||||
@@ -223,7 +221,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
100% {
|
100% {
|
||||||
box-shadow: 10014px 15px 0 0 rgb(152, 128, 255, 0);
|
box-shadow: 10014px 15px 0 0 rgba(152, 128, 255, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,6 +232,19 @@
|
|||||||
input:focus {
|
input:focus {
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.category-chooser,
|
||||||
|
.mini-tag-chooser {
|
||||||
|
.select-kit-header {
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#edit-title {
|
#edit-title {
|
||||||
@@ -628,7 +639,7 @@
|
|||||||
height: 7em;
|
height: 7em;
|
||||||
min-width: var(--ai-caption-popup-min-width);
|
min-width: var(--ai-caption-popup-min-width);
|
||||||
|
|
||||||
@include viewport.until(md) {
|
@include breakpoint(tablet) {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: unset;
|
max-width: unset;
|
||||||
min-width: unset;
|
min-width: unset;
|
||||||
|
|||||||
@@ -603,8 +603,6 @@ ar:
|
|||||||
share_ai_conversation:
|
share_ai_conversation:
|
||||||
name: "مشاركة محادثة الذكاء الاصطناعي"
|
name: "مشاركة محادثة الذكاء الاصطناعي"
|
||||||
title: "مشاركة هذه المحادثة بشكلٍ علني"
|
title: "مشاركة هذه المحادثة بشكلٍ علني"
|
||||||
invite_ai_conversation:
|
|
||||||
button: "دعوة"
|
|
||||||
ai_label: "الذكاء الاصطناعي"
|
ai_label: "الذكاء الاصطناعي"
|
||||||
ai_title: "المحادثة مع الذكاء الاصطناعي"
|
ai_title: "المحادثة مع الذكاء الاصطناعي"
|
||||||
share_modal:
|
share_modal:
|
||||||
|
|||||||
@@ -134,8 +134,6 @@ bg:
|
|||||||
request: "Заявка"
|
request: "Заявка"
|
||||||
next_log: "Напред"
|
next_log: "Напред"
|
||||||
previous_log: "Предишни"
|
previous_log: "Предишни"
|
||||||
invite_ai_conversation:
|
|
||||||
button: "Покана"
|
|
||||||
share_modal:
|
share_modal:
|
||||||
copy: "Копирай"
|
copy: "Копирай"
|
||||||
conversations:
|
conversations:
|
||||||
|
|||||||
@@ -128,8 +128,6 @@ bs_BA:
|
|||||||
response: "Odgovor"
|
response: "Odgovor"
|
||||||
next_log: "Iduće"
|
next_log: "Iduće"
|
||||||
previous_log: "Previous"
|
previous_log: "Previous"
|
||||||
invite_ai_conversation:
|
|
||||||
button: "Invite"
|
|
||||||
share_modal:
|
share_modal:
|
||||||
copy: "Copy"
|
copy: "Copy"
|
||||||
conversations:
|
conversations:
|
||||||
|
|||||||
@@ -133,8 +133,6 @@ ca:
|
|||||||
response: "Reacció"
|
response: "Reacció"
|
||||||
next_log: "Següent"
|
next_log: "Següent"
|
||||||
previous_log: "Previ"
|
previous_log: "Previ"
|
||||||
invite_ai_conversation:
|
|
||||||
button: "Convida"
|
|
||||||
share_modal:
|
share_modal:
|
||||||
copy: "Còpia"
|
copy: "Còpia"
|
||||||
conversations:
|
conversations:
|
||||||
|
|||||||
@@ -211,69 +211,24 @@ cs:
|
|||||||
ai_artifact:
|
ai_artifact:
|
||||||
collapse_view_label: "Ukončení celé obrazovky (ESC nebo tlačítko Zpět)"
|
collapse_view_label: "Ukončení celé obrazovky (ESC nebo tlačítko Zpět)"
|
||||||
ai_bot:
|
ai_bot:
|
||||||
pm_warning: "Zprávy chatbotů s umělou inteligencí jsou pravidelně monitorovány moderátory."
|
|
||||||
cancel_streaming: "Zastavit odpověď"
|
cancel_streaming: "Zastavit odpověď"
|
||||||
default_pm_prefix: "[Nepojmenovaná SZ od AI bota]"
|
default_pm_prefix: "[Nepojmenovaná SZ od AI bota]"
|
||||||
shortcut_title: "Začněte SZ s AI botem"
|
shortcut_title: "Začněte SZ s AI botem"
|
||||||
share: "Kopírovat konverzaci s AI"
|
share: "Kopírovat konverzaci s AI"
|
||||||
conversation_shared: "Konverzace zkopírována"
|
|
||||||
debug_ai: "Zobrazit nezpracovaný požadavek a odpověď umělé inteligence"
|
|
||||||
sidebar_empty: "Zde se zobrazí historie konverzace s botem."
|
|
||||||
debug_ai_modal:
|
debug_ai_modal:
|
||||||
title: "Zobrazit interakci s umělou inteligencí"
|
|
||||||
copy_request: "Kopírovat požadavek"
|
|
||||||
copy_response: "Kopírovat odpověď"
|
|
||||||
request_tokens: "Tokeny požadavku:"
|
|
||||||
response_tokens: "Tokeny odpovědi:"
|
|
||||||
request: "Požadavek"
|
request: "Požadavek"
|
||||||
response: "Odpověď"
|
response: "Odpověď"
|
||||||
next_log: "Další"
|
next_log: "Další"
|
||||||
previous_log: "Předchozí"
|
previous_log: "Předchozí"
|
||||||
share_full_topic_modal:
|
|
||||||
title: "Veřejně sdílet konverzaci"
|
|
||||||
share: "Sdílet a kopírovat odkaz"
|
|
||||||
update: "Aktualizovat a zkopírovat odkaz"
|
|
||||||
delete: "Odstranit sdílení"
|
|
||||||
share_ai_conversation:
|
|
||||||
name: "Sdílet konverzaci s AI"
|
|
||||||
title: "Sdílejte veřejně tuto konverzaci s umělou inteligencí"
|
|
||||||
invite_ai_conversation:
|
|
||||||
button: "Pozvat"
|
|
||||||
title: "Pozvat do konverzace s AI"
|
|
||||||
ai_title: "Konverzace s AI"
|
|
||||||
share_modal:
|
share_modal:
|
||||||
title: "Kopírovat konverzaci s AI"
|
|
||||||
copy: "Kopírovat"
|
copy: "Kopírovat"
|
||||||
context: "Interakce ke sdílení:"
|
|
||||||
share_tip: "Můžete také sdílet celou konverzaci."
|
|
||||||
bot_names:
|
bot_names:
|
||||||
fake: "Falešný testovací bot"
|
|
||||||
claude-3-opus: "Claude 3 Opus"
|
|
||||||
claude-3-sonnet: "Claude 3 Sonet"
|
|
||||||
claude-3-haiku: "Haiku Claude 3"
|
|
||||||
cohere-command-r-plus: "Cohere Command R Plus"
|
|
||||||
gpt-4: "GPT-4"
|
|
||||||
gpt-4-turbo: "GPT-4 Turbo"
|
|
||||||
gpt-4o: "GPT-4 Omni"
|
|
||||||
gpt-3:
|
|
||||||
5-turbo: "GPT-3.5"
|
|
||||||
claude-2: "Claude 2"
|
claude-2: "Claude 2"
|
||||||
gemini-1:
|
gemini-1:
|
||||||
5-pro: "Gemini"
|
5-pro: "Gemini"
|
||||||
mixtral-8x7B-Instruct-V0:
|
mixtral-8x7B-Instruct-V0:
|
||||||
"1": "Mixtral-8x7B V0.1"
|
"1": "Mixtral-8x7B V0.1"
|
||||||
conversations:
|
conversations:
|
||||||
header: "S čím mohu pomoci?"
|
|
||||||
submit: "Odeslat otázku"
|
|
||||||
disclaimer: "Generativní umělá inteligence může dělat chyby. Ověřte si důležité informace."
|
|
||||||
placeholder: "Zeptejte se..."
|
|
||||||
new: "Nová otázka"
|
|
||||||
min_input_length_message:
|
|
||||||
one: "Zpráva musí mít 1 nebo více znaků"
|
|
||||||
few: "Zpráva musí mít %{count} nebo více znaků"
|
|
||||||
many: "Zpráva musí mít %{count} nebo více znaků"
|
|
||||||
other: "Zpráva musí mít %{count} nebo více znaků"
|
|
||||||
messages_sidebar_title: "Konverzace"
|
|
||||||
today: "Dnes"
|
today: "Dnes"
|
||||||
last_7_days: "Posledních 7 dní"
|
last_7_days: "Posledních 7 dní"
|
||||||
last_30_days: "Posledních 30 dní"
|
last_30_days: "Posledních 30 dní"
|
||||||
|
|||||||
@@ -147,8 +147,6 @@ da:
|
|||||||
response: "Svar"
|
response: "Svar"
|
||||||
next_log: "Næste"
|
next_log: "Næste"
|
||||||
previous_log: "Forrige"
|
previous_log: "Forrige"
|
||||||
invite_ai_conversation:
|
|
||||||
button: "Invitér"
|
|
||||||
share_modal:
|
share_modal:
|
||||||
copy: "Kopier"
|
copy: "Kopier"
|
||||||
conversations:
|
conversations:
|
||||||
|
|||||||
@@ -328,11 +328,9 @@ de:
|
|||||||
key_title: "Schlüssel"
|
key_title: "Schlüssel"
|
||||||
examples:
|
examples:
|
||||||
title: Beispiele
|
title: Beispiele
|
||||||
examples_help: Simuliere frühere Interaktionen mit dem LLM und erde es, um bessere Ergebnisse zu erzielen.
|
|
||||||
new: Neues Beispiel
|
new: Neues Beispiel
|
||||||
remove: Beispiel löschen
|
remove: Beispiel löschen
|
||||||
collapsable_title: "Beispiel #%{number}"
|
collapsable_title: "Beispiel #%{number}"
|
||||||
user: "Nachricht des Benutzers"
|
|
||||||
model: "Antwort des Modells"
|
model: "Antwort des Modells"
|
||||||
list:
|
list:
|
||||||
enabled: "KI-Bot?"
|
enabled: "KI-Bot?"
|
||||||
@@ -524,8 +522,7 @@ de:
|
|||||||
provider_quantizations: "Reihenfolge der Provider-Quantisierungen (kommagetrennte Liste, z. B.: fp16,fp8)"
|
provider_quantizations: "Reihenfolge der Provider-Quantisierungen (kommagetrennte Liste, z. B.: fp16,fp8)"
|
||||||
disable_streaming: "Streaming-Vervollständigung deaktivieren (Streaming-Anfragen in Nicht-Streaming-Anfragen umwandeln)"
|
disable_streaming: "Streaming-Vervollständigung deaktivieren (Streaming-Anfragen in Nicht-Streaming-Anfragen umwandeln)"
|
||||||
reasoning_effort: "Argumentationsaufwand (gilt nur für Argumentationsmodelle)"
|
reasoning_effort: "Argumentationsaufwand (gilt nur für Argumentationsmodelle)"
|
||||||
enable_reasoning: "Argumentation aktivieren (nur für Argumentationsmodelle anwendbar)"
|
enable_reasoning: "Argumentation aktivieren (gilt nur für Sonnet 3.7)"
|
||||||
enable_thinking: "Denken aktivieren (nur bei entsprechenden Modellen, z.B.: Flash 2.5)"
|
|
||||||
thinking_tokens: "Anzahl der zum Denken verwendeten Token"
|
thinking_tokens: "Anzahl der zum Denken verwendeten Token"
|
||||||
reasoning_tokens: "Anzahl der für die Argumentation verwendeten Token"
|
reasoning_tokens: "Anzahl der für die Argumentation verwendeten Token"
|
||||||
disable_temperature: "Temperatur deaktivieren (einige Denkmodelle unterstützen keine Temperatur)"
|
disable_temperature: "Temperatur deaktivieren (einige Denkmodelle unterstützen keine Temperatur)"
|
||||||
@@ -667,7 +664,6 @@ de:
|
|||||||
share: "KI-Unterhaltung kopieren"
|
share: "KI-Unterhaltung kopieren"
|
||||||
conversation_shared: "Unterhaltung kopiert"
|
conversation_shared: "Unterhaltung kopiert"
|
||||||
debug_ai: "Rohdaten der KI-Anfrage und -Antwort anzeigen"
|
debug_ai: "Rohdaten der KI-Anfrage und -Antwort anzeigen"
|
||||||
sidebar_empty: "Der Verlauf der Bot-Konversation wird hier angezeigt."
|
|
||||||
debug_ai_modal:
|
debug_ai_modal:
|
||||||
title: "KI-Interaktion ansehen"
|
title: "KI-Interaktion ansehen"
|
||||||
copy_request: "Anfrage kopieren"
|
copy_request: "Anfrage kopieren"
|
||||||
@@ -686,9 +682,6 @@ de:
|
|||||||
share_ai_conversation:
|
share_ai_conversation:
|
||||||
name: "KI-Unterhaltung teilen"
|
name: "KI-Unterhaltung teilen"
|
||||||
title: "Diese KI-Unterhaltung öffentlich teilen"
|
title: "Diese KI-Unterhaltung öffentlich teilen"
|
||||||
invite_ai_conversation:
|
|
||||||
button: "Einladen"
|
|
||||||
title: "Zur KI-Konversation einladen"
|
|
||||||
ai_label: "KI"
|
ai_label: "KI"
|
||||||
ai_title: "Unterhaltung mit KI"
|
ai_title: "Unterhaltung mit KI"
|
||||||
share_modal:
|
share_modal:
|
||||||
|
|||||||
@@ -142,8 +142,6 @@ el:
|
|||||||
response: "Απάντηση"
|
response: "Απάντηση"
|
||||||
next_log: "Επόμενο"
|
next_log: "Επόμενο"
|
||||||
previous_log: "Προηγούμενο"
|
previous_log: "Προηγούμενο"
|
||||||
invite_ai_conversation:
|
|
||||||
button: "Πρόσκληση"
|
|
||||||
share_modal:
|
share_modal:
|
||||||
copy: "Αντιγραφή"
|
copy: "Αντιγραφή"
|
||||||
conversations:
|
conversations:
|
||||||
|
|||||||
@@ -540,7 +540,7 @@ en:
|
|||||||
provider_quantizations: "Order of provider quantizations (comma delimited list eg: fp16,fp8)"
|
provider_quantizations: "Order of provider quantizations (comma delimited list eg: fp16,fp8)"
|
||||||
disable_streaming: "Disable streaming completions (convert streaming to non streaming requests)"
|
disable_streaming: "Disable streaming completions (convert streaming to non streaming requests)"
|
||||||
reasoning_effort: "Reasoning effort (only applicable to reasoning models)"
|
reasoning_effort: "Reasoning effort (only applicable to reasoning models)"
|
||||||
enable_reasoning: "Enable reasoning (only applicable to reasoning models)"
|
enable_reasoning: "Enable reasoning (only applicable to Sonnet 3.7)"
|
||||||
enable_thinking: "Enable thinking (only on applicable models eg: flash 2.5)"
|
enable_thinking: "Enable thinking (only on applicable models eg: flash 2.5)"
|
||||||
thinking_tokens: "Number of tokens used for thinking"
|
thinking_tokens: "Number of tokens used for thinking"
|
||||||
reasoning_tokens: "Number of tokens used for reasoning"
|
reasoning_tokens: "Number of tokens used for reasoning"
|
||||||
|
|||||||
@@ -591,8 +591,6 @@ es:
|
|||||||
share_ai_conversation:
|
share_ai_conversation:
|
||||||
name: "Compartir conversación de IA"
|
name: "Compartir conversación de IA"
|
||||||
title: "Compartir esta conversación de IA públicamente"
|
title: "Compartir esta conversación de IA públicamente"
|
||||||
invite_ai_conversation:
|
|
||||||
button: "Invitar"
|
|
||||||
ai_label: "IA"
|
ai_label: "IA"
|
||||||
ai_title: "Conversación con IA"
|
ai_title: "Conversación con IA"
|
||||||
share_modal:
|
share_modal:
|
||||||
|
|||||||
@@ -130,8 +130,6 @@ et:
|
|||||||
response: "Vastus"
|
response: "Vastus"
|
||||||
next_log: "Järgmine"
|
next_log: "Järgmine"
|
||||||
previous_log: "Eelmine"
|
previous_log: "Eelmine"
|
||||||
invite_ai_conversation:
|
|
||||||
button: "Kutsu"
|
|
||||||
share_modal:
|
share_modal:
|
||||||
copy: "Kopeeri"
|
copy: "Kopeeri"
|
||||||
conversations:
|
conversations:
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user