Responder for categories

This commit is contained in:
Sam Saffron 2024-04-24 16:36:32 +10:00
parent cd7790f39a
commit c61af76d86
No known key found for this signature in database
GPG Key ID: B9606168D2FFD9F5
3 changed files with 83 additions and 3 deletions

View File

@ -46,6 +46,10 @@ class AiPersona < ActiveRecord::Base
.map(&:class_instance)
end
def self.persona_class_by_id(id)
AiPersona.all_personas.find { |persona| persona.id == id } if id
end
def self.persona_users(user: nil)
persona_users =
persona_cache[:persona_users] ||= AiPersona
@ -72,6 +76,24 @@ class AiPersona < ActiveRecord::Base
end
end
def self.topic_responder_for(category_id:)
return nil if !category_id
all_responders =
persona_cache[:topic_responders] ||= AiPersona
.where(role: "topic_responder")
.where(enabled: true)
.pluck(:id, :role_category_ids)
id, _ = all_responders.find { |id, role_category_ids| role_category_ids.include?(category_id) }
if id
{ id: id }
else
nil
end
end
def self.message_responder_for(group_id: nil)
return nil if !group_id

View File

@ -29,7 +29,10 @@ module DiscourseAi
.map { |group_id| AiPersona.message_responder_for(group_id: group_id) }
.find { |found| !found.nil? }
AiPersona.all_personas.find { |persona| persona.id == info[:id] } if info && info[:id]
AiPersona.persona_class_by_id(info[:id]) if info && info[:id]
elsif post.post_number == 1 && post.topic && post.topic.archetype == Archetype.default
info = AiPersona.topic_responder_for(category_id: post.topic.category_id)
AiPersona.persona_class_by_id(info[:id]) if info && info[:id]
end
end
@ -239,7 +242,7 @@ module DiscourseAi
reply_user = User.find_by(id: bot.persona.class.user_id) || reply_user
end
stream_reply = post.topic.private_message? && !bot.persona.role.include?("responder")
stream_reply = post.topic.private_message? && !bot.persona.class.role.include?("responder")
# we need to ensure persona user is allowed to reply to the pm
if post.topic.private_message?

View File

@ -531,6 +531,62 @@ RSpec.describe DiscourseAi::AiBot::Playground do
end
end
describe "topic_responder role" do
fab!(:category)
fab!(:tag)
it "can reply with a whisper to topics in a category" do
Jobs.run_immediately!
persona =
AiPersona.create!(
name: "Responder Persona",
description: "A responder",
system_prompt: "You are a responder",
enabled: true,
role: "topic_responder",
role_category_ids: [category.id],
role_whispers: true,
default_llm: "anthropic:claude-2",
)
persona.create_user!
post = nil
prompts = nil
DiscourseAi::Completions::Llm.with_prepared_responses(
["An amazing post just for you"],
) do |_, _, _prompts|
post =
create_post(title: "an amazing title", raw: "Howdy I need help!!", category: category)
prompts = _prompts
end
expect(prompts.length).to eq(1)
expect(prompts[0].messages[0][:content]).to eq("You are a responder")
expect(prompts[0].messages[1][:content]).to eq("# An amazing title\n\nHowdy I need help!!")
reply = post.topic.posts.find_by(post_number: 2)
expect(reply.post_type).to eq(Post.types[:whisper])
expect(reply.raw).to eq("An amazing post just for you")
# should be done responding at this point so llm will not be called
create_post(
raw: "should ignore posts that are not first on message",
topic: post.topic,
user: post.user,
)
# should not respond to topics in other categories
create_post(
title: "testing title 2",
raw: "should ignore posts that are not first on message",
user: post.user,
)
end
end
describe "message_responder role" do
fab!(:group) do
Fabricate(:group, name: "test-group", messageable_level: Group::ALIAS_LEVELS[:everyone])
@ -554,7 +610,6 @@ RSpec.describe DiscourseAi::AiBot::Playground do
persona.create_user!
post = nil
prompts = nil
DiscourseAi::Completions::Llm.with_prepared_responses(
["An amazing post just for you"],