mirror of
https://github.com/discourse/discourse-ai.git
synced 2025-06-28 18:42:16 +00:00
FEATURE: include tag and category context in search (#217)
Previous to this we just included title/body.. tags and category structure can be very critical for decision making.
This commit is contained in:
parent
b0310f90d3
commit
d75e3ca82b
@ -154,17 +154,33 @@ module DiscourseAi::AiBot::Commands
|
|||||||
end
|
end
|
||||||
|
|
||||||
@last_num_results = posts.length
|
@last_num_results = posts.length
|
||||||
|
# this is the general pattern from core
|
||||||
|
# if there are millions of hidden tags it may fail
|
||||||
|
hidden_tags = nil
|
||||||
|
|
||||||
if posts.blank?
|
if posts.blank?
|
||||||
{ args: search_args, rows: [], instruction: "nothing was found, expand your search" }
|
{ args: search_args, rows: [], instruction: "nothing was found, expand your search" }
|
||||||
else
|
else
|
||||||
format_results(posts, args: search_args) do |post|
|
format_results(posts, args: search_args) do |post|
|
||||||
{
|
category_names = [
|
||||||
|
post.topic.category&.parent_category&.name,
|
||||||
|
post.topic.category&.name,
|
||||||
|
].compact.join(" > ")
|
||||||
|
row = {
|
||||||
title: post.topic.title,
|
title: post.topic.title,
|
||||||
url: Discourse.base_path + post.url,
|
url: Discourse.base_path + post.url,
|
||||||
excerpt: post.excerpt,
|
excerpt: post.excerpt,
|
||||||
created: post.created_at,
|
created: post.created_at,
|
||||||
|
category: category_names,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if SiteSetting.tagging_enabled
|
||||||
|
hidden_tags ||= DiscourseTagging.hidden_tag_names
|
||||||
|
# using map over pluck to avoid n+1 (assuming caller preloading)
|
||||||
|
tags = post.topic.tags.map(&:name) - hidden_tags
|
||||||
|
row[:tags] = tags.join(", ") if tags.present?
|
||||||
|
end
|
||||||
|
row
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -9,19 +9,19 @@ RSpec.describe DiscourseAi::AiBot::Commands::ReadCommand do
|
|||||||
fab!(:tag_funny) { Fabricate(:tag, name: "funny") }
|
fab!(:tag_funny) { Fabricate(:tag, name: "funny") }
|
||||||
fab!(:tag_sad) { Fabricate(:tag, name: "sad") }
|
fab!(:tag_sad) { Fabricate(:tag, name: "sad") }
|
||||||
fab!(:tag_hidden) { Fabricate(:tag, name: "hidden") }
|
fab!(:tag_hidden) { Fabricate(:tag, name: "hidden") }
|
||||||
fab!(:staff_tag_group) { Fabricate(:tag_group, name: "Staff only", tag_names: ["hidden"]) }
|
fab!(:staff_tag_group) do
|
||||||
|
tag_group = Fabricate.build(:tag_group, name: "Staff only", tag_names: ["hidden"])
|
||||||
|
|
||||||
|
tag_group.permissions = [
|
||||||
|
[Group::AUTO_GROUPS[:staff], TagGroupPermission.permission_types[:full]],
|
||||||
|
]
|
||||||
|
tag_group.save!
|
||||||
|
tag_group
|
||||||
|
end
|
||||||
fab!(:topic_with_tags) do
|
fab!(:topic_with_tags) do
|
||||||
Fabricate(:topic, category: category, tags: [tag_funny, tag_sad, tag_hidden])
|
Fabricate(:topic, category: category, tags: [tag_funny, tag_sad, tag_hidden])
|
||||||
end
|
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
|
describe "#process" do
|
||||||
it "can read a topic" do
|
it "can read a topic" do
|
||||||
topic_id = topic_with_tags.id
|
topic_id = topic_with_tags.id
|
||||||
|
@ -9,9 +9,28 @@ RSpec.describe DiscourseAi::AiBot::Commands::SearchCommand do
|
|||||||
before { SearchIndexer.enable }
|
before { SearchIndexer.enable }
|
||||||
after { SearchIndexer.disable }
|
after { SearchIndexer.disable }
|
||||||
|
|
||||||
|
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) do
|
||||||
|
tag_group = Fabricate.build(:tag_group, name: "Staff only", tag_names: ["hidden"])
|
||||||
|
|
||||||
|
tag_group.permissions = [
|
||||||
|
[Group::AUTO_GROUPS[:staff], TagGroupPermission.permission_types[:full]],
|
||||||
|
]
|
||||||
|
tag_group.save!
|
||||||
|
tag_group
|
||||||
|
end
|
||||||
|
fab!(:topic_with_tags) do
|
||||||
|
Fabricate(:topic, category: category, tags: [tag_funny, tag_sad, tag_hidden])
|
||||||
|
end
|
||||||
|
|
||||||
describe "#process" do
|
describe "#process" do
|
||||||
it "can handle no results" do
|
it "can handle no results" do
|
||||||
post1 = Fabricate(:post)
|
post1 = Fabricate(:post, topic: topic_with_tags)
|
||||||
search = described_class.new(bot_user: bot_user, post: post1, args: nil)
|
search = described_class.new(bot_user: bot_user, post: post1, args: nil)
|
||||||
|
|
||||||
results = search.process(query: "order:fake ABDDCDCEDGDG")
|
results = search.process(query: "order:fake ABDDCDCEDGDG")
|
||||||
@ -42,7 +61,7 @@ RSpec.describe DiscourseAi::AiBot::Commands::SearchCommand do
|
|||||||
hyde_embedding,
|
hyde_embedding,
|
||||||
)
|
)
|
||||||
|
|
||||||
post1 = Fabricate(:post)
|
post1 = Fabricate(:post, topic: topic_with_tags)
|
||||||
search = described_class.new(bot_user: bot_user, post: post1, args: nil)
|
search = described_class.new(bot_user: bot_user, post: post1, args: nil)
|
||||||
|
|
||||||
DiscourseAi::Embeddings::VectorRepresentations::AllMpnetBaseV2
|
DiscourseAi::Embeddings::VectorRepresentations::AllMpnetBaseV2
|
||||||
@ -60,7 +79,7 @@ RSpec.describe DiscourseAi::AiBot::Commands::SearchCommand do
|
|||||||
it "supports subfolder properly" do
|
it "supports subfolder properly" do
|
||||||
Discourse.stubs(:base_path).returns("/subfolder")
|
Discourse.stubs(:base_path).returns("/subfolder")
|
||||||
|
|
||||||
post1 = Fabricate(:post)
|
post1 = Fabricate(:post, topic: topic_with_tags)
|
||||||
|
|
||||||
search = described_class.new(bot_user: bot_user, post: post1, args: nil)
|
search = described_class.new(bot_user: bot_user, post: post1, args: nil)
|
||||||
|
|
||||||
@ -68,8 +87,22 @@ RSpec.describe DiscourseAi::AiBot::Commands::SearchCommand do
|
|||||||
expect(results[:rows].to_s).to include("/subfolder" + post1.url)
|
expect(results[:rows].to_s).to include("/subfolder" + post1.url)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "returns category and tags" do
|
||||||
|
post1 = Fabricate(:post, topic: topic_with_tags)
|
||||||
|
search = described_class.new(bot_user: bot_user, post: post1, args: nil)
|
||||||
|
results = search.process(user: post1.user.username)
|
||||||
|
|
||||||
|
row = results[:rows].first
|
||||||
|
category = row[results[:column_names].index("category")]
|
||||||
|
|
||||||
|
expect(category).to eq("animals > amazing-cat")
|
||||||
|
|
||||||
|
tags = row[results[:column_names].index("tags")]
|
||||||
|
expect(tags).to eq("funny, sad")
|
||||||
|
end
|
||||||
|
|
||||||
it "can handle limits" do
|
it "can handle limits" do
|
||||||
post1 = Fabricate(:post)
|
post1 = Fabricate(:post, topic: topic_with_tags)
|
||||||
_post2 = Fabricate(:post, user: post1.user)
|
_post2 = Fabricate(:post, user: post1.user)
|
||||||
_post3 = Fabricate(:post, user: post1.user)
|
_post3 = Fabricate(:post, user: post1.user)
|
||||||
|
|
||||||
@ -78,7 +111,6 @@ RSpec.describe DiscourseAi::AiBot::Commands::SearchCommand do
|
|||||||
|
|
||||||
results = search.process(limit: 2, user: post1.user.username)
|
results = search.process(limit: 2, user: post1.user.username)
|
||||||
|
|
||||||
expect(results[:column_names].length).to eq(4)
|
|
||||||
expect(results[:rows].length).to eq(2)
|
expect(results[:rows].length).to eq(2)
|
||||||
|
|
||||||
# just searching for everything
|
# just searching for everything
|
||||||
|
Loading…
x
Reference in New Issue
Block a user