From b0310f90d35cdac4177737dc1c2e04a60da919d2 Mon Sep 17 00:00:00 2001 From: Sam Date: Tue, 12 Sep 2023 11:06:55 +1000 Subject: [PATCH] FEATURE: add tags and categories to read context (#215) Note, we perform permission checks on tag list against anon to ensure we do not disclose information about private tags to the llm which could get extracted. --- lib/modules/ai_bot/commands/read_command.rb | 14 ++++++- .../ai_bot/commands/read_command_spec.rb | 41 ++++++++++++++++--- 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/lib/modules/ai_bot/commands/read_command.rb b/lib/modules/ai_bot/commands/read_command.rb index 22adbe26..b8025b51 100644 --- a/lib/modules/ai_bot/commands/read_command.rb +++ b/lib/modules/ai_bot/commands/read_command.rb @@ -50,7 +50,19 @@ module DiscourseAi::AiBot::Commands posts = posts.where("post_number = ?", post_number) if post_number - content = +"title: #{topic.title}\n\n" + content = +<<~TEXT.strip + title: #{topic.title} + TEXT + + category_names = [topic.category&.parent_category&.name, topic.category&.name].compact.join( + " ", + ) + content << "\ncategories: #{category_names}" if category_names.present? + + if topic.tags.length > 0 + tags = DiscourseTagging.filter_visible(topic.tags, Guardian.new) + content << "\ntags: #{tags.map(&:name).join(", ")}\n\n" if tags.length > 0 + end posts.each { |post| content << "\n\n#{post.username} said:\n\n#{post.raw}" } diff --git a/spec/lib/modules/ai_bot/commands/read_command_spec.rb b/spec/lib/modules/ai_bot/commands/read_command_spec.rb index 992c29f8..47cc4661 100644 --- a/spec/lib/modules/ai_bot/commands/read_command_spec.rb +++ b/spec/lib/modules/ai_bot/commands/read_command_spec.rb @@ -3,19 +3,48 @@ RSpec.describe DiscourseAi::AiBot::Commands::ReadCommand do fab!(:bot_user) { User.find(DiscourseAi::AiBot::EntryPoint::GPT3_5_TURBO_ID) } + fab!(:parent_category) { Fabricate(:category, name: "animals") } + fab!(:category) { Fabricate(:category, parent_category: parent_category, name: "amazing-cat") } + + fab!(:tag_funny) { Fabricate(:tag, name: "funny") } + fab!(:tag_sad) { Fabricate(:tag, name: "sad") } + fab!(:tag_hidden) { Fabricate(:tag, name: "hidden") } + fab!(:staff_tag_group) { Fabricate(:tag_group, name: "Staff only", tag_names: ["hidden"]) } + fab!(:topic_with_tags) do + Fabricate(:topic, category: category, tags: [tag_funny, tag_sad, tag_hidden]) + end + + let(:staff) { Group::AUTO_GROUPS[:staff] } + let(:full) { TagGroupPermission.permission_types[:full] } + + before do + staff_tag_group.permissions = [[staff, full]] + staff_tag_group.save! + end + describe "#process" do it "can read a topic" do - post1 = Fabricate(:post, raw: "hello there") - Fabricate(:post, raw: "mister sam", topic: post1.topic) + topic_id = topic_with_tags.id - read = described_class.new(bot_user: bot_user, args: nil, post: post1) + Fabricate(:post, topic: topic_with_tags, raw: "hello there") + Fabricate(:post, topic: topic_with_tags, raw: "mister sam") - results = read.process(topic_id: post1.topic_id) + read = described_class.new(bot_user: bot_user, args: nil) - expect(results[:topic_id]).to eq(post1.topic_id) + results = read.process(topic_id: topic_id) + + expect(results[:topic_id]).to eq(topic_id) expect(results[:content]).to include("hello") expect(results[:content]).to include("sam") - expect(read.description_args).to eq(title: post1.topic.title, url: post1.topic.relative_url) + expect(results[:content]).to include("amazing-cat") + expect(results[:content]).to include("funny") + expect(results[:content]).to include("sad") + expect(results[:content]).to include("animals") + expect(results[:content]).not_to include("hidden") + expect(read.description_args).to eq( + title: topic_with_tags.title, + url: topic_with_tags.relative_url, + ) end end end