| 
									
										
										
										
											2023-05-20 17:45:54 +10:00
										 |  |  | #frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module DiscourseAi::AiBot::Commands | 
					
						
							|  |  |  |   class SearchCommand < Command | 
					
						
							|  |  |  |     class << self | 
					
						
							|  |  |  |       def name | 
					
						
							|  |  |  |         "search" | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       def desc | 
					
						
							| 
									
										
										
										
											2023-06-20 08:45:31 +10:00
										 |  |  |         "Will search topics in the current discourse instance, when rendering always prefer to link to the topics you find" | 
					
						
							| 
									
										
										
										
											2023-05-20 17:45:54 +10:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-20 08:45:31 +10:00
										 |  |  |       def parameters | 
					
						
							|  |  |  |         [ | 
					
						
							|  |  |  |           Parameter.new( | 
					
						
							|  |  |  |             name: "search_query", | 
					
						
							| 
									
										
										
										
											2023-06-21 17:10:30 +10:00
										 |  |  |             description: "Search query (correct bad spelling, remove connector words!)", | 
					
						
							| 
									
										
										
										
											2023-06-20 08:45:31 +10:00
										 |  |  |             type: "string", | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |           Parameter.new( | 
					
						
							|  |  |  |             name: "user", | 
					
						
							| 
									
										
										
										
											2023-06-20 15:44:03 +10:00
										 |  |  |             description: | 
					
						
							|  |  |  |               "Filter search results to this username (only include if user explicitly asks to filter by user)", | 
					
						
							| 
									
										
										
										
											2023-06-20 08:45:31 +10:00
										 |  |  |             type: "string", | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |           Parameter.new( | 
					
						
							|  |  |  |             name: "order", | 
					
						
							| 
									
										
										
										
											2023-08-23 07:49:36 +10:00
										 |  |  |             description: "search result order", | 
					
						
							| 
									
										
										
										
											2023-06-20 08:45:31 +10:00
										 |  |  |             type: "string", | 
					
						
							|  |  |  |             enum: %w[latest latest_topic oldest views likes], | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |           Parameter.new( | 
					
						
							|  |  |  |             name: "limit", | 
					
						
							| 
									
										
										
										
											2023-06-20 15:44:03 +10:00
										 |  |  |             description: | 
					
						
							|  |  |  |               "limit number of results returned (generally prefer to just keep to default)", | 
					
						
							| 
									
										
										
										
											2023-06-20 08:45:31 +10:00
										 |  |  |             type: "integer", | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |           Parameter.new( | 
					
						
							|  |  |  |             name: "max_posts", | 
					
						
							|  |  |  |             description: | 
					
						
							|  |  |  |               "maximum number of posts on the topics (topics where lots of people posted)", | 
					
						
							|  |  |  |             type: "integer", | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |           Parameter.new( | 
					
						
							|  |  |  |             name: "tags", | 
					
						
							|  |  |  |             description: | 
					
						
							|  |  |  |               "list of tags to search for. Use + to join with OR, use , to join with AND", | 
					
						
							|  |  |  |             type: "string", | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |           Parameter.new( | 
					
						
							|  |  |  |             name: "category", | 
					
						
							|  |  |  |             description: "category name to filter to", | 
					
						
							|  |  |  |             type: "string", | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |           Parameter.new( | 
					
						
							|  |  |  |             name: "before", | 
					
						
							|  |  |  |             description: "only topics created before a specific date YYYY-MM-DD", | 
					
						
							|  |  |  |             type: "string", | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |           Parameter.new( | 
					
						
							|  |  |  |             name: "after", | 
					
						
							|  |  |  |             description: "only topics created after a specific date YYYY-MM-DD", | 
					
						
							|  |  |  |             type: "string", | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |           Parameter.new( | 
					
						
							|  |  |  |             name: "status", | 
					
						
							|  |  |  |             description: "search for topics in a particular state", | 
					
						
							|  |  |  |             type: "string", | 
					
						
							|  |  |  |             enum: %w[open closed archived noreplies single_user], | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2023-05-20 17:45:54 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-20 08:45:31 +10:00
										 |  |  |       def custom_system_message | 
					
						
							| 
									
										
										
										
											2023-06-21 20:07:55 +10:00
										 |  |  |         <<~TEXT | 
					
						
							|  |  |  |           You were trained on OLD data, lean on search to get up to date information about this forum | 
					
						
							|  |  |  |           When searching try to SIMPLIFY search terms | 
					
						
							|  |  |  |           Discourse search joins all terms with AND. Reduce and simplify terms to find more results. | 
					
						
							|  |  |  |         TEXT | 
					
						
							| 
									
										
										
										
											2023-05-20 17:45:54 +10:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def result_name | 
					
						
							|  |  |  |       "results" | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def description_args | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         count: @last_num_results || 0, | 
					
						
							|  |  |  |         query: @last_query || "", | 
					
						
							|  |  |  |         url: "#{Discourse.base_path}/search?q=#{CGI.escape(@last_query || "")}", | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-04 09:37:58 +10:00
										 |  |  |     def process(**search_args) | 
					
						
							| 
									
										
										
										
											2023-05-22 12:09:14 +10:00
										 |  |  |       limit = nil | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       search_string = | 
					
						
							| 
									
										
										
										
											2023-08-04 09:37:58 +10:00
										 |  |  |         search_args | 
					
						
							| 
									
										
										
										
											2023-06-20 08:45:31 +10:00
										 |  |  |           .map do |key, value| | 
					
						
							| 
									
										
										
										
											2023-08-04 09:37:58 +10:00
										 |  |  |             if key == :search_query | 
					
						
							| 
									
										
										
										
											2023-06-20 08:45:31 +10:00
										 |  |  |               value | 
					
						
							| 
									
										
										
										
											2023-08-04 09:37:58 +10:00
										 |  |  |             elsif key == :limit | 
					
						
							| 
									
										
										
										
											2023-06-20 08:45:31 +10:00
										 |  |  |               limit = value.to_i | 
					
						
							| 
									
										
										
										
											2023-05-22 12:09:14 +10:00
										 |  |  |               nil | 
					
						
							|  |  |  |             else | 
					
						
							| 
									
										
										
										
											2023-06-20 08:45:31 +10:00
										 |  |  |               "#{key}:#{value}" | 
					
						
							| 
									
										
										
										
											2023-05-22 12:09:14 +10:00
										 |  |  |             end | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |           .compact | 
					
						
							|  |  |  |           .join(" ") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-20 17:45:54 +10:00
										 |  |  |       @last_query = search_string | 
					
						
							|  |  |  |       results = | 
					
						
							| 
									
										
										
										
											2023-05-23 23:08:17 +10:00
										 |  |  |         Search.execute( | 
					
						
							|  |  |  |           search_string.to_s + " status:public", | 
					
						
							|  |  |  |           search_type: :full_page, | 
					
						
							|  |  |  |           guardian: Guardian.new(), | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       # let's be frugal with tokens, 50 results is too much and stuff gets cut off | 
					
						
							| 
									
										
										
										
											2023-06-20 08:45:31 +10:00
										 |  |  |       limit ||= 20
 | 
					
						
							|  |  |  |       limit = 20 if limit > 20
 | 
					
						
							| 
									
										
										
										
											2023-05-20 17:45:54 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-22 15:14:26 +10:00
										 |  |  |       posts = results&.posts || [] | 
					
						
							| 
									
										
										
										
											2023-05-23 23:08:17 +10:00
										 |  |  |       posts = posts[0..limit - 1] | 
					
						
							| 
									
										
										
										
											2023-05-22 12:09:14 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-22 15:14:26 +10:00
										 |  |  |       @last_num_results = posts.length | 
					
						
							| 
									
										
										
										
											2023-05-20 17:45:54 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-22 12:09:14 +10:00
										 |  |  |       if posts.blank? | 
					
						
							| 
									
										
										
										
											2023-06-21 17:10:30 +10:00
										 |  |  |         { args: search_args, rows: [], instruction: "nothing was found, expand your search" } | 
					
						
							| 
									
										
										
										
											2023-05-22 12:09:14 +10:00
										 |  |  |       else | 
					
						
							| 
									
										
										
										
											2023-06-21 17:10:30 +10:00
										 |  |  |         format_results(posts, args: search_args) do |post| | 
					
						
							| 
									
										
										
										
											2023-05-20 17:45:54 +10:00
										 |  |  |           { | 
					
						
							| 
									
										
										
										
											2023-05-22 12:09:14 +10:00
										 |  |  |             title: post.topic.title, | 
					
						
							| 
									
										
										
										
											2023-06-20 08:45:31 +10:00
										 |  |  |             url: Discourse.base_path + post.url, | 
					
						
							| 
									
										
										
										
											2023-05-22 12:09:14 +10:00
										 |  |  |             excerpt: post.excerpt, | 
					
						
							|  |  |  |             created: post.created_at, | 
					
						
							| 
									
										
										
										
											2023-05-20 17:45:54 +10:00
										 |  |  |           } | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2023-05-22 12:09:14 +10:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2023-05-20 17:45:54 +10:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end |