diff --git a/lib/ai_helper/chat_thread_titler.rb b/lib/ai_helper/chat_thread_titler.rb
index b60a97bc..755a8426 100644
--- a/lib/ai_helper/chat_thread_titler.rb
+++ b/lib/ai_helper/chat_thread_titler.rb
@@ -8,26 +8,38 @@ module DiscourseAi
end
def suggested_title
- return nil if thread_content.blank?
-
- prompt = CompletionPrompt.enabled_by_name("generate_titles")
- raise Discourse::InvalidParameters.new(:mode) if !prompt
-
- response =
- DiscourseAi::AiHelper::Assistant.new.generate_and_send_prompt(
- prompt,
- thread_content,
- thread.original_message_user,
- )
- response.dig(:suggestions)&.first
+ @thread.then { thread_content(_1) }.then { call_llm(_1) }.then { cleanup(_1) }
end
- private
+ def call_llm(thread_content)
+ return nil if thread_content.blank?
- attr_reader :thread
+ chat = "\n#{thread_content}\n"
- def thread_content
- # Replace me by a proper API call
+ prompt =
+ DiscourseAi::Completions::Prompt.new(
+ <<~TEXT.strip,
+ I want you to act as a title generator for chat between users. I will provide you with the chat transcription,
+ and you will generate a single attention-grabbing title. Please keep the title concise and under 15 words
+ and ensure that the meaning is maintained. The title will utilize the same language type of the chat.
+ I want you to only reply the suggested title and nothing else, do not write explanations.
+ You will find the chat between XML tags.
+ TEXT
+ messages: [{ type: :user, content: chat, id: "User" }],
+ )
+
+ DiscourseAi::Completions::Llm.proxy(SiteSetting.ai_helper_model).generate(
+ prompt,
+ user: Discourse.system_user,
+ )
+ end
+
+ def cleanup(title)
+ title.split("\n").first.then { _1.match?(/^("|')(.*)("|')$/) ? title[1..-2] : _1 }
+ end
+
+ def thread_content(thread)
+ # TODO: Replace me by a proper API call
thread
.chat_messages
.joins(:user)
@@ -35,6 +47,8 @@ module DiscourseAi
.map { |username, message| "#{username}: #{message}" }
.join("\n")
end
+
+ attr_reader :thread
end
end
end
diff --git a/spec/lib/modules/ai_helper/chat_thread_titler_spec.rb b/spec/lib/modules/ai_helper/chat_thread_titler_spec.rb
index 3dc07252..89ad6674 100644
--- a/spec/lib/modules/ai_helper/chat_thread_titler_spec.rb
+++ b/spec/lib/modules/ai_helper/chat_thread_titler_spec.rb
@@ -6,17 +6,51 @@ RSpec.describe DiscourseAi::AiHelper::ChatThreadTitler do
before { SiteSetting.ai_helper_model = "fake:fake" }
fab!(:thread) { Fabricate(:chat_thread) }
+ fab!(:chat_message) { Fabricate(:chat_message, thread: thread) }
fab!(:user) { Fabricate(:user) }
- describe "#suggested_title" do
- it "suggest the first option from the generate_titles prompt" do
- titles =
- "The solitary horseThe horse etched in goldA horse's infinite journeyA horse lost in timeA horse's last ride"
+ describe "#cleanup" do
+ it "picks the first when there are multiple" do
+ titles = "The solitary horse\nThe horse etched in gold"
expected_title = "The solitary horse"
- result =
- DiscourseAi::Completions::Llm.with_prepared_responses([titles]) { titler.suggested_title }
+
+ result = titler.cleanup(titles)
+
+ expect(result).to eq(expected_title)
+ end
+
+ it "cleans up double quotes enclosing the whole title" do
+ titles = '"The solitary horse"'
+ expected_title = "The solitary horse"
+
+ result = titler.cleanup(titles)
+
+ expect(result).to eq(expected_title)
+ end
+
+ it "cleans up single quotes enclosing the whole title" do
+ titles = "'The solitary horse'"
+ expected_title = "The solitary horse"
+
+ result = titler.cleanup(titles)
+
+ expect(result).to eq(expected_title)
+ end
+
+ it "leaves quotes in the middle of title" do
+ titles = "The 'solitary' horse"
+ expected_title = "The 'solitary' horse"
+
+ result = titler.cleanup(titles)
expect(result).to eq(expected_title)
end
end
+
+ describe "#thread_content" do
+ it "returns the chat message and user" do
+ expect(titler.thread_content(thread)).to include(chat_message.message)
+ expect(titler.thread_content(thread)).to include(chat_message.user.username)
+ end
+ end
end