Skip to content

Commit b17c688

Browse files
authored
DEV: Improve title suggester suggestions when editing topic (#1182)
This update ensures topic title suggestions when suggesting from edit topic take into account the whole topic for more accurate title suggestions.
1 parent e59184b commit b17c688

File tree

5 files changed

+84
-23
lines changed

5 files changed

+84
-23
lines changed

app/controllers/discourse_ai/ai_helper/assistant_controller.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,12 @@ def suggest
5353
end
5454

5555
def suggest_title
56-
input = get_text_param!
56+
if params[:topic_id]
57+
topic = Topic.find_by(id: params[:topic_id])
58+
input = DiscourseAi::Summarization::Strategies::TopicSummary.new(topic).targets_data
59+
else
60+
input = get_text_param!
61+
end
5762

5863
prompt = CompletionPrompt.enabled_by_name("generate_titles")
5964
raise Discourse::InvalidParameters.new(:mode) if !prompt

assets/javascripts/discourse/components/suggestion-menus/ai-title-suggester.gjs

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,30 +17,15 @@ export default class AiTitleSuggester extends Component {
1717
@tracked untriggers = [];
1818
@tracked triggerIcon = "discourse-sparkles";
1919
@tracked content = null;
20-
@tracked topicContent = null;
21-
22-
constructor() {
23-
super(...arguments);
24-
25-
if (!this.topicContent && this.args.composer?.reply === undefined) {
26-
this.fetchTopicContent();
27-
}
28-
}
29-
30-
async fetchTopicContent() {
31-
await ajax(`/t/${this.args.buffered.content.id}.json`).then(
32-
({ post_stream }) => {
33-
this.topicContent = post_stream.posts[0].cooked;
34-
}
35-
);
36-
}
3720

3821
get showSuggestionButton() {
3922
const composerFields = document.querySelector(".composer-fields");
4023
const editTopicTitleField = document.querySelector(".edit-topic-title");
4124

42-
this.content = this.args.composer?.reply || this.topicContent;
43-
const showTrigger = this.content?.length > MIN_CHARACTER_COUNT;
25+
this.content = this.args.composer?.reply;
26+
const showTrigger =
27+
this.content?.length > MIN_CHARACTER_COUNT ||
28+
this.args.topicState === "edit";
4429

4530
if (composerFields) {
4631
if (showTrigger) {
@@ -69,13 +54,20 @@ export default class AiTitleSuggester extends Component {
6954

7055
this.loading = true;
7156
this.triggerIcon = "spinner";
57+
const data = {};
58+
59+
if (this.content) {
60+
data.text = this.content;
61+
} else {
62+
data.topic_id = this.args.buffered.content.id;
63+
}
7264

7365
try {
7466
const { suggestions } = await ajax(
7567
"/discourse-ai/ai-helper/suggest_title",
7668
{
7769
method: "POST",
78-
data: { text: this.content },
70+
data,
7971
}
8072
);
8173
this.suggestions = suggestions;

assets/javascripts/discourse/connectors/after-composer-title-input/ai-title-suggestion.gjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ export default class AiTitleSuggestion extends Component {
1313
}
1414

1515
<template>
16-
<AiTitleSuggester @composer={{@outletArgs.composer}} />
16+
<AiTitleSuggester @composer={{@outletArgs.composer}} @topicState="new" />
1717
</template>
1818
}

assets/javascripts/discourse/connectors/edit-topic-title__after/ai-title-suggestion.gjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ export default class AiTitleSuggestion extends Component {
1313
}
1414

1515
<template>
16-
<AiTitleSuggester @buffered={{@outletArgs.buffered}} />
16+
<AiTitleSuggester @buffered={{@outletArgs.buffered}} @topicState="edit" />
1717
</template>
1818
}

spec/requests/ai_helper/assistant_controller_spec.rb

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,70 @@
134134
end
135135
end
136136

137+
describe "#suggest_title" do
138+
fab!(:topic)
139+
fab!(:post_1) { Fabricate(:post, topic: topic, raw: "I love apples") }
140+
fab!(:post_3) { Fabricate(:post, topic: topic, raw: "I love mangos") }
141+
fab!(:post_2) { Fabricate(:post, topic: topic, raw: "I love bananas") }
142+
143+
context "when logged in as an allowed user" do
144+
fab!(:user)
145+
146+
before do
147+
sign_in(user)
148+
user.group_ids = [Group::AUTO_GROUPS[:trust_level_1]]
149+
SiteSetting.composer_ai_helper_allowed_groups = Group::AUTO_GROUPS[:trust_level_1]
150+
end
151+
152+
context "when suggesting titles with a topic_id" do
153+
let(:title_suggestions) do
154+
"<item>What are your favourite fruits?</item><item>Love for fruits</item><item>Fruits are amazing</item><item>Favourite fruit list</item><item>Fruit share topic</item>"
155+
end
156+
let(:title_suggestions_array) do
157+
[
158+
"What are your favourite fruits?",
159+
"Love for fruits",
160+
"Fruits are amazing",
161+
"Favourite fruit list",
162+
"Fruit share topic",
163+
]
164+
end
165+
166+
it "returns title suggestions based on all topic post context" do
167+
DiscourseAi::Completions::Llm.with_prepared_responses([title_suggestions]) do
168+
post "/discourse-ai/ai-helper/suggest_title", params: { topic_id: topic.id }
169+
170+
expect(response.status).to eq(200)
171+
expect(response.parsed_body["suggestions"]).to eq(title_suggestions_array)
172+
end
173+
end
174+
end
175+
176+
context "when suggesting titles with input text" do
177+
let(:title_suggestions) do
178+
"<item>Apples - the best fruit</item><item>Why apples are great</item><item>Apples are the best fruit</item><item>My love for apples</item><item>I love apples</item>"
179+
end
180+
let(:title_suggestions_array) do
181+
[
182+
"Apples - the best fruit",
183+
"Why apples are great",
184+
"Apples are the best fruit",
185+
"My love for apples",
186+
"I love apples",
187+
]
188+
end
189+
it "returns title suggestions based on the input text" do
190+
DiscourseAi::Completions::Llm.with_prepared_responses([title_suggestions]) do
191+
post "/discourse-ai/ai-helper/suggest_title", params: { text: post_1.raw }
192+
193+
expect(response.status).to eq(200)
194+
expect(response.parsed_body["suggestions"]).to eq(title_suggestions_array)
195+
end
196+
end
197+
end
198+
end
199+
end
200+
137201
describe "#caption_image" do
138202
let(:image) { plugin_file_from_fixtures("100x100.jpg") }
139203
let(:upload) { UploadCreator.new(image, "image.jpg").create_for(Discourse.system_user.id) }

0 commit comments

Comments
 (0)