DEV: Use site locale for composer helper translations (#698)
This commit is contained in:
parent
38153608f8
commit
eab2f74b58
|
@ -12,6 +12,7 @@ module DiscourseAi
|
||||||
|
|
||||||
def suggest
|
def suggest
|
||||||
input = get_text_param!
|
input = get_text_param!
|
||||||
|
force_default_locale = params[:force_default_locale] || false
|
||||||
|
|
||||||
prompt = CompletionPrompt.find_by(id: params[:mode])
|
prompt = CompletionPrompt.find_by(id: params[:mode])
|
||||||
|
|
||||||
|
@ -31,6 +32,7 @@ module DiscourseAi
|
||||||
prompt,
|
prompt,
|
||||||
input,
|
input,
|
||||||
current_user,
|
current_user,
|
||||||
|
force_default_locale,
|
||||||
),
|
),
|
||||||
status: 200
|
status: 200
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||||
import { caretPosition, getCaretPosition } from "discourse/lib/utilities";
|
import { caretPosition, getCaretPosition } from "discourse/lib/utilities";
|
||||||
import { INPUT_DELAY } from "discourse-common/config/environment";
|
import { INPUT_DELAY } from "discourse-common/config/environment";
|
||||||
import { afterRender, bind, debounce } from "discourse-common/utils/decorators";
|
import { afterRender, bind, debounce } from "discourse-common/utils/decorators";
|
||||||
|
import I18n from "discourse-i18n";
|
||||||
import { showComposerAIHelper } from "../../lib/show-ai-helper";
|
import { showComposerAIHelper } from "../../lib/show-ai-helper";
|
||||||
|
|
||||||
export default class AiHelperContextMenu extends Component {
|
export default class AiHelperContextMenu extends Component {
|
||||||
|
@ -76,7 +77,28 @@ export default class AiHelperContextMenu extends Component {
|
||||||
|
|
||||||
prompts = prompts
|
prompts = prompts
|
||||||
.filter((p) => p.location.includes("composer"))
|
.filter((p) => p.location.includes("composer"))
|
||||||
.filter((p) => p.name !== "generate_titles");
|
.filter((p) => p.name !== "generate_titles")
|
||||||
|
.map((p) => {
|
||||||
|
// AI helper by default returns interface locale on translations
|
||||||
|
// Since we want site default translations (and we are using: force_default_locale)
|
||||||
|
// we need to replace the translated_name with the site default locale name
|
||||||
|
const siteLocale = this.siteSettings.default_locale;
|
||||||
|
const availableLocales = JSON.parse(
|
||||||
|
this.siteSettings.available_locales
|
||||||
|
);
|
||||||
|
const locale = availableLocales.find((l) => l.value === siteLocale);
|
||||||
|
const translatedName = I18n.t(
|
||||||
|
"discourse_ai.ai_helper.context_menu.translate_prompt",
|
||||||
|
{
|
||||||
|
language: locale.name,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (p.name === "translate") {
|
||||||
|
return { ...p, translated_name: translatedName };
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
});
|
||||||
|
|
||||||
// Find the custom_prompt object and move it to the beginning of the array
|
// Find the custom_prompt object and move it to the beginning of the array
|
||||||
const customPromptIndex = prompts.findIndex(
|
const customPromptIndex = prompts.findIndex(
|
||||||
|
@ -367,6 +389,7 @@ export default class AiHelperContextMenu extends Component {
|
||||||
mode: option.id,
|
mode: option.id,
|
||||||
text: this.selectedText,
|
text: this.selectedText,
|
||||||
custom_prompt: this.customPromptValue,
|
custom_prompt: this.customPromptValue,
|
||||||
|
force_default_locale: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -292,6 +292,7 @@ en:
|
||||||
title: "Custom Prompt"
|
title: "Custom Prompt"
|
||||||
placeholder: "Enter a custom prompt..."
|
placeholder: "Enter a custom prompt..."
|
||||||
submit: "Send Prompt"
|
submit: "Send Prompt"
|
||||||
|
translate_prompt: "Translate to %{language}"
|
||||||
post_options_menu:
|
post_options_menu:
|
||||||
trigger: "Ask AI"
|
trigger: "Ask AI"
|
||||||
title: "Ask AI"
|
title: "Ask AI"
|
||||||
|
|
|
@ -158,7 +158,7 @@ en:
|
||||||
errors:
|
errors:
|
||||||
completion_request_failed: "Something went wrong while trying to provide suggestions. Please, try again."
|
completion_request_failed: "Something went wrong while trying to provide suggestions. Please, try again."
|
||||||
prompts:
|
prompts:
|
||||||
translate: Translate to English
|
translate: Translate to %{language}
|
||||||
generate_titles: Suggest topic titles
|
generate_titles: Suggest topic titles
|
||||||
proofread: Proofread text
|
proofread: Proofread text
|
||||||
markdown_table: Generate Markdown table
|
markdown_table: Generate Markdown table
|
||||||
|
|
|
@ -11,7 +11,7 @@ module DiscourseAi
|
||||||
prompt_cache.flush!
|
prompt_cache.flush!
|
||||||
end
|
end
|
||||||
|
|
||||||
def available_prompts
|
def available_prompts(user)
|
||||||
key = "prompt_cache_#{I18n.locale}"
|
key = "prompt_cache_#{I18n.locale}"
|
||||||
self
|
self
|
||||||
.class
|
.class
|
||||||
|
@ -27,9 +27,19 @@ module DiscourseAi
|
||||||
|
|
||||||
prompts =
|
prompts =
|
||||||
prompts.map do |prompt|
|
prompts.map do |prompt|
|
||||||
|
if prompt.name == "translate"
|
||||||
|
locale = user.effective_locale
|
||||||
|
locale_hash = LocaleSiteSetting.language_names[locale]
|
||||||
|
translation =
|
||||||
|
I18n.t(
|
||||||
|
"discourse_ai.ai_helper.prompts.translate",
|
||||||
|
language: locale_hash["nativeName"],
|
||||||
|
) || prompt.translated_name || prompt.name
|
||||||
|
else
|
||||||
translation =
|
translation =
|
||||||
I18n.t("discourse_ai.ai_helper.prompts.#{prompt.name}", default: nil) ||
|
I18n.t("discourse_ai.ai_helper.prompts.#{prompt.name}", default: nil) ||
|
||||||
prompt.translated_name || prompt.name
|
prompt.translated_name || prompt.name
|
||||||
|
end
|
||||||
|
|
||||||
{
|
{
|
||||||
id: prompt.id,
|
id: prompt.id,
|
||||||
|
@ -44,9 +54,9 @@ module DiscourseAi
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def custom_locale_instructions(user = nil)
|
def custom_locale_instructions(user = nil, force_default_locale)
|
||||||
locale = SiteSetting.default_locale
|
locale = SiteSetting.default_locale
|
||||||
locale = user.locale || SiteSetting.default_locale if SiteSetting.allow_user_locale && user
|
locale = user.effective_locale if !force_default_locale
|
||||||
locale_hash = LocaleSiteSetting.language_names[locale]
|
locale_hash = LocaleSiteSetting.language_names[locale]
|
||||||
|
|
||||||
if locale != "en" && locale_hash
|
if locale != "en" && locale_hash
|
||||||
|
@ -57,15 +67,17 @@ module DiscourseAi
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def localize_prompt!(prompt, user = nil)
|
def localize_prompt!(prompt, user = nil, force_default_locale)
|
||||||
locale_instructions = custom_locale_instructions(user)
|
locale_instructions = custom_locale_instructions(user, force_default_locale)
|
||||||
if locale_instructions
|
if locale_instructions
|
||||||
prompt.messages[0][:content] = prompt.messages[0][:content] + locale_instructions
|
prompt.messages[0][:content] = prompt.messages[0][:content] + locale_instructions
|
||||||
end
|
end
|
||||||
|
|
||||||
if prompt.messages[0][:content].include?("%LANGUAGE%")
|
if prompt.messages[0][:content].include?("%LANGUAGE%")
|
||||||
locale = SiteSetting.default_locale
|
locale = SiteSetting.default_locale
|
||||||
locale = user.locale if SiteSetting.allow_user_locale && user&.locale.present?
|
|
||||||
|
locale = user.effective_locale if user && !force_default_locale
|
||||||
|
|
||||||
locale_hash = LocaleSiteSetting.language_names[locale]
|
locale_hash = LocaleSiteSetting.language_names[locale]
|
||||||
|
|
||||||
prompt.messages[0][:content] = prompt.messages[0][:content].gsub(
|
prompt.messages[0][:content] = prompt.messages[0][:content].gsub(
|
||||||
|
@ -75,10 +87,10 @@ module DiscourseAi
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_prompt(completion_prompt, input, user, &block)
|
def generate_prompt(completion_prompt, input, user, force_default_locale = false, &block)
|
||||||
llm = DiscourseAi::Completions::Llm.proxy(SiteSetting.ai_helper_model)
|
llm = DiscourseAi::Completions::Llm.proxy(SiteSetting.ai_helper_model)
|
||||||
prompt = completion_prompt.messages_with_input(input)
|
prompt = completion_prompt.messages_with_input(input)
|
||||||
localize_prompt!(prompt, user)
|
localize_prompt!(prompt, user, force_default_locale)
|
||||||
|
|
||||||
llm.generate(
|
llm.generate(
|
||||||
prompt,
|
prompt,
|
||||||
|
@ -90,8 +102,8 @@ module DiscourseAi
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_and_send_prompt(completion_prompt, input, user)
|
def generate_and_send_prompt(completion_prompt, input, user, force_default_locale = false)
|
||||||
completion_result = generate_prompt(completion_prompt, input, user)
|
completion_result = generate_prompt(completion_prompt, input, user, force_default_locale)
|
||||||
result = { type: completion_prompt.prompt_type }
|
result = { type: completion_prompt.prompt_type }
|
||||||
|
|
||||||
result[:suggestions] = (
|
result[:suggestions] = (
|
||||||
|
|
|
@ -38,7 +38,7 @@ module DiscourseAi
|
||||||
end,
|
end,
|
||||||
) do
|
) do
|
||||||
ActiveModel::ArraySerializer.new(
|
ActiveModel::ArraySerializer.new(
|
||||||
DiscourseAi::AiHelper::Assistant.new.available_prompts,
|
DiscourseAi::AiHelper::Assistant.new.available_prompts(scope.user),
|
||||||
root: false,
|
root: false,
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,17 +16,27 @@ RSpec.describe DiscourseAi::AiHelper::Assistant do
|
||||||
describe("#custom_locale_instructions") do
|
describe("#custom_locale_instructions") do
|
||||||
it "Properly generates the per locale system instruction" do
|
it "Properly generates the per locale system instruction" do
|
||||||
SiteSetting.default_locale = "ko"
|
SiteSetting.default_locale = "ko"
|
||||||
expect(subject.custom_locale_instructions).to eq(
|
expect(subject.custom_locale_instructions(user, false)).to eq(
|
||||||
"It is imperative that you write your answer in Korean (한국어), you are interacting with a Korean (한국어) speaking user. Leave tag names in English.",
|
"It is imperative that you write your answer in Korean (한국어), you are interacting with a Korean (한국어) speaking user. Leave tag names in English.",
|
||||||
)
|
)
|
||||||
|
|
||||||
SiteSetting.allow_user_locale = true
|
SiteSetting.allow_user_locale = true
|
||||||
user.update!(locale: "he")
|
user.update!(locale: "he")
|
||||||
|
|
||||||
expect(subject.custom_locale_instructions(user)).to eq(
|
expect(subject.custom_locale_instructions(user, false)).to eq(
|
||||||
"It is imperative that you write your answer in Hebrew (עברית), you are interacting with a Hebrew (עברית) speaking user. Leave tag names in English.",
|
"It is imperative that you write your answer in Hebrew (עברית), you are interacting with a Hebrew (עברית) speaking user. Leave tag names in English.",
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "returns sytstem instructions using Site locale if force_default_locale is true" do
|
||||||
|
SiteSetting.default_locale = "ko"
|
||||||
|
SiteSetting.allow_user_locale = true
|
||||||
|
user.update!(locale: "he")
|
||||||
|
|
||||||
|
expect(subject.custom_locale_instructions(user, true)).to eq(
|
||||||
|
"It is imperative that you write your answer in Korean (한국어), you are interacting with a Korean (한국어) speaking user. Leave tag names in English.",
|
||||||
|
)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe("#available_prompts") do
|
describe("#available_prompts") do
|
||||||
|
@ -36,7 +46,7 @@ RSpec.describe DiscourseAi::AiHelper::Assistant do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns all available prompts" do
|
it "returns all available prompts" do
|
||||||
prompts = subject.available_prompts
|
prompts = subject.available_prompts(user)
|
||||||
|
|
||||||
expect(prompts.length).to eq(6)
|
expect(prompts.length).to eq(6)
|
||||||
expect(prompts.map { |p| p[:name] }).to contain_exactly(
|
expect(prompts.map { |p| p[:name] }).to contain_exactly(
|
||||||
|
@ -56,7 +66,7 @@ RSpec.describe DiscourseAi::AiHelper::Assistant do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns the illustrate_post prompt in the list of all prompts" do
|
it "returns the illustrate_post prompt in the list of all prompts" do
|
||||||
prompts = subject.available_prompts
|
prompts = subject.available_prompts(user)
|
||||||
|
|
||||||
expect(prompts.length).to eq(7)
|
expect(prompts.length).to eq(7)
|
||||||
expect(prompts.map { |p| p[:name] }).to contain_exactly(
|
expect(prompts.map { |p| p[:name] }).to contain_exactly(
|
||||||
|
|
|
@ -21,7 +21,7 @@ describe DiscourseAi::AiHelper::EntryPoint do
|
||||||
parsed["current_user"]["ai_helper_prompts"].find { |prompt| prompt["name"] == "translate" }
|
parsed["current_user"]["ai_helper_prompts"].find { |prompt| prompt["name"] == "translate" }
|
||||||
|
|
||||||
expect(translate_prompt["translated_name"]).to eq(
|
expect(translate_prompt["translated_name"]).to eq(
|
||||||
I18n.t("discourse_ai.ai_helper.prompts.translate"),
|
I18n.t("discourse_ai.ai_helper.prompts.translate", language: "English (US)"),
|
||||||
)
|
)
|
||||||
|
|
||||||
I18n.with_locale("fr") do
|
I18n.with_locale("fr") do
|
||||||
|
@ -32,7 +32,7 @@ describe DiscourseAi::AiHelper::EntryPoint do
|
||||||
parsed["current_user"]["ai_helper_prompts"].find { |prompt| prompt["name"] == "translate" }
|
parsed["current_user"]["ai_helper_prompts"].find { |prompt| prompt["name"] == "translate" }
|
||||||
|
|
||||||
expect(translate_prompt["translated_name"]).to eq(
|
expect(translate_prompt["translated_name"]).to eq(
|
||||||
I18n.t("discourse_ai.ai_helper.prompts.translate", locale: "fr"),
|
I18n.t("discourse_ai.ai_helper.prompts.translate", locale: "fr", language: "Français"),
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue