Skip to content

Commit 5f24835

Browse files
authored
FIX: Do not return AI content if not in <output> (#223)
There is a bug now where if the new DiscourseAi translator does not return values back in `<translator>` tags, we return the full response. This commit scopes both the input and output in its respective tags, and returns an empty string if there is no output tag. The problem only exists on topic translations, not post translations, as posts contain html and the prompt for translating indicates there will be html (topics do not have them). So an accompanying migration has been added example incorrect result: ``` "To provide a translation, I first need the original text in a specific language to translate it into \"pt\". Could you please provide the text you wish to translate, including any HTML tags?" ```
1 parent c1aa718 commit 5f24835

File tree

4 files changed

+33
-15
lines changed

4 files changed

+33
-15
lines changed

app/services/discourse_ai/translator.rb

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33
module DiscourseAi
44
class Translator
55
PROMPT_TEMPLATE = <<~TEXT.freeze
6-
You are a highly skilled linguist and web programmer, with expertise in many languages, and very well versed in HTML.
6+
You are a highly skilled linguist of many languages and have expert knowledge in HTML.
77
Your task is to identify the language of the text I provide and accurately translate it into this language locale "%{target_language}" while preserving the meaning, tone, and nuance of the original text.
8-
The text will contain html tags, which must absolutely be preserved in the translation.
8+
The text may or may not contain html tags. If they do, preserve them.
99
Maintain proper grammar, spelling, and punctuation in the translated version.
10-
Wrap the translated text in a <translation> tag.
10+
You will find the text between <input></input> XML tags.
11+
Include your translation between <output></output> XML tags.
12+
Do not write explanations.
1113
TEXT
1214

1315
def initialize(text, target_language)
@@ -19,7 +21,7 @@ def translate
1921
prompt =
2022
DiscourseAi::Completions::Prompt.new(
2123
build_prompt(@target_language),
22-
messages: [{ type: :user, content: @text, id: "user" }],
24+
messages: [{ type: :user, content: "<input>#{@text}</input>", id: "user" }],
2325
)
2426

2527
llm_translation =
@@ -29,7 +31,7 @@ def translate
2931
feature_name: "translator-translate",
3032
)
3133

32-
(Nokogiri::HTML5.fragment(llm_translation).at("translation")&.inner_html || llm_translation)
34+
(Nokogiri::HTML5.fragment(llm_translation).at("output")&.inner_html || "").strip
3335
end
3436

3537
private
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# frozen_string_literal: true
2+
3+
class CleanupAiTranslations < ActiveRecord::Migration[7.2]
4+
def up
5+
execute <<~SQL
6+
DELETE FROM discourse_translator_topic_translations
7+
WHERE translation LIKE 'To%'
8+
AND translation ILIKE '%translat%'
9+
AND LENGTH(translation) > 100;
10+
SQL
11+
end
12+
13+
def down
14+
raise ActiveRecord::IrreversibleMigration
15+
end
16+
end

spec/services/discourse_ai/translator_spec.rb

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@
1717
it "creates the correct prompt" do
1818
allow(DiscourseAi::Completions::Prompt).to receive(:new).with(
1919
<<~TEXT,
20-
You are a highly skilled linguist and web programmer, with expertise in many languages, and very well versed in HTML.
20+
You are a highly skilled linguist of many languages and have expert knowledge in HTML.
2121
Your task is to identify the language of the text I provide and accurately translate it into this language locale "de" while preserving the meaning, tone, and nuance of the original text.
22-
The text will contain html tags, which must absolutely be preserved in the translation.
22+
The text may or may not contain html tags. If they do, preserve them.
2323
Maintain proper grammar, spelling, and punctuation in the translated version.
24-
Wrap the translated text in a <translation> tag.
24+
You will find the text between <input></input> XML tags.
25+
Include your translation between <output></output> XML tags.
26+
Do not write explanations.
2527
TEXT
26-
messages: [{ type: :user, content: text_to_translate, id: "user" }],
28+
messages: [{ type: :user, content: "<input>cats are great</input>", id: "user" }],
2729
).and_call_original
2830

2931
described_class.new(text_to_translate, target_language).translate
@@ -48,19 +50,17 @@
4850

4951
it "returns the translation from the llm's response in the translation tag" do
5052
DiscourseAi::Completions::Llm.with_prepared_responses(
51-
["<translation>hur dur hur dur!</translation>"],
53+
["<output>hur dur hur dur!</output>"],
5254
) do
5355
expect(
5456
described_class.new(text_to_translate, target_language).translate,
5557
).to eq "hur dur hur dur!"
5658
end
5759
end
5860

59-
it "returns the raw response if the translation tag is not present" do
61+
it "returns an empty string if the translation tag is not present" do
6062
DiscourseAi::Completions::Llm.with_prepared_responses(["raw response."]) do
61-
expect(
62-
described_class.new(text_to_translate, target_language).translate,
63-
).to eq "raw response."
63+
expect(described_class.new(text_to_translate, target_language).translate).to eq ""
6464
end
6565
end
6666
end

spec/services/discourse_ai_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242

4343
it "translates the post and returns [locale, translated_text]" do
4444
DiscourseAi::Completions::Llm.with_prepared_responses(
45-
["<translation>some translated text</translation>"],
45+
["<output>some translated text</output>"],
4646
) do
4747
locale, translated_text = DiscourseTranslator::DiscourseAi.translate(post)
4848
expect(locale).to eq "de"

0 commit comments

Comments
 (0)