mirror of
				https://github.com/discourse/discourse-ai.git
				synced 2025-10-31 14:38:37 +00:00 
			
		
		
		
	This command can be used to extract information about a discourse site setting directly from source. To operate it needs the rg binary in the container.
		
			
				
	
	
		
			155 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			155 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
| #frozen_string_literal: true
 | |
| 
 | |
| module DiscourseAi::AiBot::Commands
 | |
|   MAX_CONTEXT_TOKENS = 2000
 | |
| 
 | |
|   class SettingContextCommand < Command
 | |
|     def self.rg_installed?
 | |
|       if defined?(@rg_installed)
 | |
|         @rg_installed
 | |
|       else
 | |
|         @rg_installed =
 | |
|           begin
 | |
|             Discourse::Utils.execute_command("which", "rg")
 | |
|             true
 | |
|           rescue Discourse::Utils::CommandError
 | |
|             false
 | |
|           end
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     class << self
 | |
|       def name
 | |
|         "setting_context"
 | |
|       end
 | |
| 
 | |
|       def desc
 | |
|         "Will provide you with full context regarding a particular site setting in Discourse"
 | |
|       end
 | |
| 
 | |
|       def parameters
 | |
|         [
 | |
|           Parameter.new(
 | |
|             name: "setting_name",
 | |
|             description: "The name of the site setting we need context for",
 | |
|             type: "string",
 | |
|             required: true,
 | |
|           ),
 | |
|         ]
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     def result_name
 | |
|       "context"
 | |
|     end
 | |
| 
 | |
|     def description_args
 | |
|       { setting_name: @setting_name }
 | |
|     end
 | |
| 
 | |
|     CODE_FILE_EXTENSIONS = "rb,js,gjs,hbs"
 | |
| 
 | |
|     def process(setting_name:)
 | |
|       if !self.class.rg_installed?
 | |
|         return(
 | |
|           {
 | |
|             setting_name: setting_name,
 | |
|             context: "This command requires the rg command line tool to be installed on the server",
 | |
|           }
 | |
|         )
 | |
|       end
 | |
| 
 | |
|       @setting_name = setting_name
 | |
|       if !SiteSetting.has_setting?(setting_name)
 | |
|         { setting_name: setting_name, context: "This setting does not exist" }
 | |
|       else
 | |
|         description = SiteSetting.description(setting_name)
 | |
|         result = +"# #{setting_name}\n#{description}\n\n"
 | |
| 
 | |
|         setting_info =
 | |
|           find_setting_info(setting_name, [Rails.root.join("config", "site_settings.yml").to_s])
 | |
|         if !setting_info
 | |
|           setting_info =
 | |
|             find_setting_info(setting_name, Dir[Rails.root.join("plugins/**/settings.yml")])
 | |
|         end
 | |
| 
 | |
|         result << setting_info
 | |
|         result << "\n\n"
 | |
| 
 | |
|         %w[lib app plugins].each do |dir|
 | |
|           path = Rails.root.join(dir).to_s
 | |
|           result << Discourse::Utils.execute_command(
 | |
|             "rg",
 | |
|             setting_name,
 | |
|             path,
 | |
|             "-g",
 | |
|             "!**/spec/**",
 | |
|             "-g",
 | |
|             "!**/dist/**",
 | |
|             "-g",
 | |
|             "*.{#{CODE_FILE_EXTENSIONS}}",
 | |
|             "-C",
 | |
|             "10",
 | |
|             "--color",
 | |
|             "never",
 | |
|             "--heading",
 | |
|             "--no-ignore",
 | |
|             chdir: path,
 | |
|             success_status_codes: [0, 1],
 | |
|           )
 | |
|         end
 | |
| 
 | |
|         result.gsub!(/^#{Regexp.escape(Rails.root.to_s)}/, "")
 | |
| 
 | |
|         result = tokenizer.truncate(result, MAX_CONTEXT_TOKENS)
 | |
| 
 | |
|         { setting_name: setting_name, context: result }
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     def find_setting_info(name, paths)
 | |
|       path, result = nil
 | |
| 
 | |
|       paths.each do |search_path|
 | |
|         result =
 | |
|           Discourse::Utils.execute_command(
 | |
|             "rg",
 | |
|             name,
 | |
|             search_path,
 | |
|             "-g",
 | |
|             "*.{#{CODE_FILE_EXTENSIONS}}",
 | |
|             "-A",
 | |
|             "10",
 | |
|             "--color",
 | |
|             "never",
 | |
|             "--heading",
 | |
|             success_status_codes: [0, 1],
 | |
|           )
 | |
|         if !result.blank?
 | |
|           path = search_path
 | |
|           break
 | |
|         end
 | |
|       end
 | |
| 
 | |
|       if result.blank?
 | |
|         nil
 | |
|       else
 | |
|         rows = result.split("\n")
 | |
|         leading_spaces = rows[0].match(/^\s*/)[0].length
 | |
| 
 | |
|         filtered = []
 | |
| 
 | |
|         rows.each do |row|
 | |
|           if !filtered.blank?
 | |
|             break if row.match(/^\s*/)[0].length <= leading_spaces
 | |
|           end
 | |
|           filtered << row
 | |
|         end
 | |
| 
 | |
|         filtered.unshift("#{path}")
 | |
|         filtered.join("\n")
 | |
|       end
 | |
|     end
 | |
|   end
 | |
| end
 |