FIX: automatic bot titles missing sometime (#151)

This fixes 2 big issues:

1. No matter how hard you try, grounding anthropic title prompt
is just too hard. This works around by only looking at the last
sentence it returns and treating as title

2. Non English locales would be stuck with "generic" title, this
ensures every bot message gets a title, using a custom field to
track

Also, slightly tunes some anthropic prompts.
This commit is contained in:
Sam 2023-08-24 07:20:24 +10:00 committed by GitHub
parent 45b7b57726
commit 7d943be7b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 66 additions and 5 deletions

View File

@ -39,7 +39,7 @@ module DiscourseAi
DiscourseAi::Inference::AnthropicCompletions.perform!(
prompt,
model_for,
temperature: 0.7,
temperature: 0.4,
max_tokens: 40,
).dig(:completion)
end

View File

@ -63,12 +63,14 @@ module DiscourseAi
def update_pm_title(post)
prompt = title_prompt(post)
new_title = get_updated_title(prompt)
new_title = get_updated_title(prompt).strip.split("\n").last
PostRevisor.new(post.topic.first_post, post.topic).revise!(
bot_user,
title: new_title.sub(/\A"/, "").sub(/"\Z/, ""),
)
post.topic.custom_fields.delete(DiscourseAi::AiBot::EntryPoint::REQUIRE_TITLE_UPDATE)
post.topic.save_custom_fields
end
def max_commands_per_reply=(val)
@ -254,6 +256,8 @@ module DiscourseAi
def title_prompt(post)
[build_message(bot_user.username, <<~TEXT)]
You are titlebot. Given a topic you will figure out a title.
You will never respond with anything but a topic title.
Suggest a 7 word title for the following topic without quoting any of it:
#{post.topic.posts[1..-1].map(&:raw).join("\n\n")[0..prompt_limit]}

View File

@ -3,6 +3,8 @@
module DiscourseAi
module AiBot
class EntryPoint
REQUIRE_TITLE_UPDATE = "discourse-ai-title-update"
GPT4_ID = -110
GPT3_5_TURBO_ID = -111
CLAUDE_V2_ID = -112
@ -81,6 +83,10 @@ module DiscourseAi
bot_id = post.topic.topic_allowed_users.where(user_id: bot_ids).first&.user_id
if bot_id
if post.post_number == 1
post.topic.custom_fields[REQUIRE_TITLE_UPDATE] = true
post.topic.save_custom_fields
end
Jobs.enqueue(:create_ai_reply, post_id: post.id, bot_user_id: bot_id)
Jobs.enqueue_in(
5.minutes,

View File

@ -9,7 +9,7 @@ module ::Jobs
return unless bot = DiscourseAi::AiBot::Bot.as(bot_user)
return unless post = Post.includes(:topic).find_by(id: args[:post_id])
return unless post.topic.title.start_with?(I18n.t("discourse_ai.ai_bot.default_pm_prefix"))
return unless post.topic.custom_fields[DiscourseAi::AiBot::EntryPoint::REQUIRE_TITLE_UPDATE]
bot.update_pm_title(post)
end

View File

@ -69,6 +69,8 @@ module ::DiscourseAi
- When you run a command/function you will gain access to real information in a subsequant call!
- NEVER EVER pretend to know stuff, you ALWAYS lean on functions to discover the truth!
- You have direct access to data on this forum using !functions
- You are not a lier, liers are bad bots, you are a good bot!
- You always prefer to say "I don't know" as opposed to inventing a lie!
{
PROMPT
@ -111,8 +113,14 @@ module ::DiscourseAi
echo(message: string [required])
}
You can execute with:
!echo(message: "hello world")
Human: please echo out "hello"
Assistant: !echo(message: "hello")
Human: please say "hello"
Assistant: !echo(message: "hello")
PROMPT
prompt

View File

@ -0,0 +1,43 @@
# frozen_string_literal: true
RSpec.describe Jobs::UpdateAiBotPmTitle do
let(:user) { Fabricate(:admin) }
let(:bot_user) { User.find(DiscourseAi::AiBot::EntryPoint::CLAUDE_V2_ID) }
it "will properly update title on bot PMs" do
SiteSetting.ai_bot_allowed_groups = Group::AUTO_GROUPS[:staff]
Jobs.run_immediately!
WebMock
.stub_request(:post, "https://api.anthropic.com/v1/complete")
.with(body: /You are a helpful Discourse assistant/)
.to_return(status: 200, body: "data: {\"completion\": \"Hello back at you\"}", headers: {})
WebMock
.stub_request(:post, "https://api.anthropic.com/v1/complete")
.with(body: /Suggest a 7 word title/)
.to_return(
status: 200,
body: "{\"completion\": \"A great title would be:\n\nMy amazing title\n\n\"}",
headers: {
},
)
post =
create_post(
user: user,
raw: "Hello there",
title: "does not matter should be updated",
archetype: Archetype.private_message,
target_usernames: bot_user.username,
)
expect(post.reload.topic.title).to eq("My amazing title")
WebMock.reset!
Jobs::UpdateAiBotPmTitle.new.execute(bot_user_id: bot_user.id, post_id: post.id)
# should be a no op cause title is updated
end
end