| 
									
										
										
										
											2023-03-15 17:21:45 -03:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module DiscourseAi | 
					
						
							|  |  |  |   module Embeddings | 
					
						
							| 
									
										
										
										
											2023-03-31 11:04:34 +11:00
										 |  |  |     class SemanticRelated | 
					
						
							| 
									
										
										
										
											2023-07-13 12:41:36 -03:00
										 |  |  |       MissingEmbeddingError = Class.new(StandardError) | 
					
						
							| 
									
										
										
										
											2023-05-23 10:43:24 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-05 11:08:23 -03:00
										 |  |  |       def self.clear_cache_for(topic) | 
					
						
							|  |  |  |         Discourse.cache.delete("semantic-suggested-topic-#{topic.id}") | 
					
						
							|  |  |  |         Discourse.redis.del("build-semantic-suggested-topic-#{topic.id}") | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2023-05-23 10:43:24 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-05 11:08:23 -03:00
										 |  |  |       def related_topic_ids_for(topic) | 
					
						
							|  |  |  |         return [] if SiteSetting.ai_embeddings_semantic_related_topics < 1
 | 
					
						
							| 
									
										
										
										
											2023-03-31 11:04:34 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-05 11:08:23 -03:00
										 |  |  |         strategy = DiscourseAi::Embeddings::Strategies::Truncation.new | 
					
						
							|  |  |  |         vector_rep = | 
					
						
							|  |  |  |           DiscourseAi::Embeddings::VectorRepresentations::Base.current_representation(strategy) | 
					
						
							|  |  |  |         cache_for = results_ttl(topic) | 
					
						
							| 
									
										
										
										
											2023-07-13 12:41:36 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-05 11:08:23 -03:00
										 |  |  |         asd = | 
					
						
							|  |  |  |           Discourse | 
					
						
							|  |  |  |             .cache | 
					
						
							|  |  |  |             .fetch(semantic_suggested_key(topic.id), expires_in: cache_for) do | 
					
						
							|  |  |  |               vector_rep | 
					
						
							|  |  |  |                 .symmetric_topics_similarity_search(topic) | 
					
						
							|  |  |  |                 .tap do |candidate_ids| | 
					
						
							|  |  |  |                   # Happens when the topic doesn't have any embeddings | 
					
						
							|  |  |  |                   # I'd rather not use Exceptions to control the flow, so this should be refactored soon | 
					
						
							|  |  |  |                   if candidate_ids.empty? || !candidate_ids.include?(topic.id) | 
					
						
							|  |  |  |                     raise MissingEmbeddingError, "No embeddings found for topic #{topic.id}" | 
					
						
							|  |  |  |                   end | 
					
						
							|  |  |  |                 end | 
					
						
							| 
									
										
										
										
											2023-07-13 12:41:36 -03:00
										 |  |  |             end | 
					
						
							| 
									
										
										
										
											2023-09-05 11:08:23 -03:00
										 |  |  |       rescue MissingEmbeddingError | 
					
						
							|  |  |  |         # avoid a flood of jobs when visiting topic | 
					
						
							|  |  |  |         if Discourse.redis.set( | 
					
						
							|  |  |  |              build_semantic_suggested_key(topic.id), | 
					
						
							|  |  |  |              "queued", | 
					
						
							|  |  |  |              ex: 15.minutes.to_i, | 
					
						
							|  |  |  |              nx: true, | 
					
						
							|  |  |  |            ) | 
					
						
							|  |  |  |           Jobs.enqueue(:generate_embeddings, topic_id: topic.id) | 
					
						
							| 
									
										
										
										
											2023-03-15 17:21:45 -03:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2023-09-05 11:08:23 -03:00
										 |  |  |         [] | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2023-03-15 17:21:45 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-05 11:08:23 -03:00
										 |  |  |       def results_ttl(topic) | 
					
						
							|  |  |  |         case topic.created_at | 
					
						
							|  |  |  |         when 6.hour.ago..Time.now | 
					
						
							|  |  |  |           15.minutes | 
					
						
							|  |  |  |         when 3.day.ago..6.hour.ago | 
					
						
							|  |  |  |           1.hour | 
					
						
							|  |  |  |         when 15.days.ago..3.day.ago | 
					
						
							|  |  |  |           12.hours | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           1.week | 
					
						
							| 
									
										
										
										
											2023-05-09 15:30:50 -03:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2023-09-05 11:08:23 -03:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2023-05-09 15:30:50 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-05 11:08:23 -03:00
										 |  |  |       private | 
					
						
							| 
									
										
										
										
											2023-08-02 16:58:09 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-05 11:08:23 -03:00
										 |  |  |       def semantic_suggested_key(topic_id) | 
					
						
							|  |  |  |         "semantic-suggested-topic-#{topic_id}" | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       def build_semantic_suggested_key(topic_id) | 
					
						
							|  |  |  |         "build-semantic-suggested-topic-#{topic_id}" | 
					
						
							| 
									
										
										
										
											2023-03-15 17:21:45 -03:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end |