diff --git a/lib/modules/ai_bot/anthropic_bot.rb b/lib/modules/ai_bot/anthropic_bot.rb index 799b0932..b9f7a072 100644 --- a/lib/modules/ai_bot/anthropic_bot.rb +++ b/lib/modules/ai_bot/anthropic_bot.rb @@ -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 diff --git a/lib/modules/ai_bot/bot.rb b/lib/modules/ai_bot/bot.rb index 36b40350..d0159e78 100644 --- a/lib/modules/ai_bot/bot.rb +++ b/lib/modules/ai_bot/bot.rb @@ -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]} diff --git a/lib/modules/ai_bot/entry_point.rb b/lib/modules/ai_bot/entry_point.rb index f2dae10a..cdbc8e89 100644 --- a/lib/modules/ai_bot/entry_point.rb +++ b/lib/modules/ai_bot/entry_point.rb @@ -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, diff --git a/lib/modules/ai_bot/jobs/regular/update_ai_bot_pm_title.rb b/lib/modules/ai_bot/jobs/regular/update_ai_bot_pm_title.rb index 5e70338d..2ba7a9c3 100644 --- a/lib/modules/ai_bot/jobs/regular/update_ai_bot_pm_title.rb +++ b/lib/modules/ai_bot/jobs/regular/update_ai_bot_pm_title.rb @@ -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 diff --git a/lib/shared/inference/function_list.rb b/lib/shared/inference/function_list.rb index f1aa3fe0..fab9b0e6 100644 --- a/lib/shared/inference/function_list.rb +++ b/lib/shared/inference/function_list.rb @@ -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 diff --git a/spec/lib/modules/ai_bot/jobs/regular/update_ai_bot_pm_title_spec.rb b/spec/lib/modules/ai_bot/jobs/regular/update_ai_bot_pm_title_spec.rb new file mode 100644 index 00000000..1916c268 --- /dev/null +++ b/spec/lib/modules/ai_bot/jobs/regular/update_ai_bot_pm_title_spec.rb @@ -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