FIX: Use a dedicated prompt for thread titles (#464)
This commit is contained in:
parent
0ff5c0c2c4
commit
bccb7efdd6
|
@ -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 = "<input>\n#{thread_content}\n</input>"
|
||||
|
||||
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 <input></input> 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
|
||||
|
|
|
@ -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 =
|
||||
"<item>The solitary horse</item><item>The horse etched in gold</item><item>A horse's infinite journey</item><item>A horse lost in time</item><item>A horse's last ride</item>"
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue