mirror of
https://github.com/discourse/discourse-ai.git
synced 2025-02-12 06:24:42 +00:00
This improves the site setting search so it performs a somewhat fuzzy match. Previously it did not handle seperators such as "space" and a term such as "min_post_length" would not find "min_first_post_length" A more liberal search algorithm makes it easier to the AI to navigate settings. * Minor fix, {{and parameter.enum parameter.enum.length}} is non obviously broken. If parameter.enum is a tracked array it will return the object cause embers and helper implementation. This corrects an issue where enum keeps on selecting itself by mistake.
104 lines
2.7 KiB
Ruby
104 lines
2.7 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module DiscourseAi
|
|
module AiBot
|
|
module Tools
|
|
class SearchSettings < Tool
|
|
INCLUDE_DESCRIPTIONS_MAX_LENGTH = 10
|
|
MAX_RESULTS = 200
|
|
|
|
def self.signature
|
|
{
|
|
name: name,
|
|
description: "Will search through site settings and return top 20 results",
|
|
parameters: [
|
|
{
|
|
name: "query",
|
|
description:
|
|
"comma delimited list of settings to search for (e.g. 'setting_1,setting_2')",
|
|
type: "string",
|
|
required: true,
|
|
},
|
|
],
|
|
}
|
|
end
|
|
|
|
def self.name
|
|
"search_settings"
|
|
end
|
|
|
|
def query
|
|
parameters[:query].to_s
|
|
end
|
|
|
|
def all_settings
|
|
@all_settings ||= SiteSetting.all_settings
|
|
end
|
|
|
|
def all_settings=(settings)
|
|
# this is only used for testing
|
|
@all_settings = settings
|
|
end
|
|
|
|
def invoke
|
|
@last_num_results = 0
|
|
|
|
terms = query.split(",").map(&:strip).map(&:downcase).reject(&:blank?)
|
|
|
|
terms_regexes =
|
|
terms.map do |term|
|
|
regex_string = term.split(/[ _\.\|]/).map { |t| Regexp.escape(t) }.join(".*")
|
|
Regexp.new(regex_string, Regexp::IGNORECASE)
|
|
end
|
|
|
|
found =
|
|
all_settings.filter do |setting|
|
|
name = setting[:setting].to_s.downcase
|
|
description = setting[:description].to_s.downcase
|
|
plugin = setting[:plugin].to_s.downcase
|
|
|
|
search_string = "#{name} #{description} #{plugin}"
|
|
|
|
terms_regexes.any? { |regex| search_string.match?(regex) }
|
|
end
|
|
|
|
if found.blank?
|
|
{
|
|
args: {
|
|
query: query,
|
|
},
|
|
rows: [],
|
|
instruction: "no settings matched #{query}, expand your search",
|
|
}
|
|
else
|
|
include_descriptions = false
|
|
|
|
if found.length > MAX_RESULTS
|
|
found = found[0..MAX_RESULTS]
|
|
elsif found.length < INCLUDE_DESCRIPTIONS_MAX_LENGTH
|
|
include_descriptions = true
|
|
end
|
|
|
|
@last_num_results = found.length
|
|
|
|
format_results(found, args: { query: query }) do |setting|
|
|
result = { name: setting[:setting] }
|
|
if include_descriptions
|
|
result[:description] = setting[:description]
|
|
result[:plugin] = setting[:plugin]
|
|
end
|
|
result
|
|
end
|
|
end
|
|
end
|
|
|
|
protected
|
|
|
|
def description_args
|
|
{ count: @last_num_results || 0, query: parameters[:query].to_s }
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|