diff --git a/app/lib/smooch_nlu.rb b/app/lib/smooch_nlu.rb index 9932ed5ec..2f161aef7 100644 --- a/app/lib/smooch_nlu.rb +++ b/app/lib/smooch_nlu.rb @@ -71,7 +71,8 @@ def self.alegre_matches_from_message(message, language, context, alegre_result_k end begin self.increment_global_counter - team_slug = Team.find(Bot::Smooch.config['team_id']).slug + team_id = Bot::Smooch.config['team_id'] + team_slug = Team.find(team_id).slug # FIXME: In the future we could consider matches across all languages when options is nil # FIXME: No need to call Alegre if it's an exact match to one of the keywords # FIXME: No need to call Alegre if message has no word characters @@ -85,7 +86,9 @@ def self.alegre_matches_from_message(message, language, context, alegre_result_k language: language, }.merge(context) } - response = Bot::Alegre.query_sync_with_params(params, "text") + response = Bot::Alegre.query_sync_with_params(params, "text")["result"].collect{|result| + result["context"] = Bot::Alegre.isolate_relevant_context(team_id, result) + } # One approach would be to take the option that has the most matches # Unfortunately this approach is influenced by the number of keywords per option @@ -96,7 +99,7 @@ def self.alegre_matches_from_message(message, language, context, alegre_result_k # ranked_options = option_counts.group_by(&:itself).transform_values(&:count).sort_by{|_k,v| v}.reverse() # Second approach is to sort the results from best to worst - sorted_options = response['result'].to_a.sort_by{ |result| result['score'] }.reverse + sorted_options = response.to_a.sort_by{ |result| result['score'] }.reverse ranked_options = sorted_options.map{ |o| { 'key' => o.dig('context', alegre_result_key), 'score' => o['score'] } } matches = ranked_options diff --git a/app/models/concerns/alegre_v2.rb b/app/models/concerns/alegre_v2.rb index 9bc2a70ab..97e4ab77b 100644 --- a/app/models/concerns/alegre_v2.rb +++ b/app/models/concerns/alegre_v2.rb @@ -336,8 +336,8 @@ def get_per_model_threshold(project_media, threshold) end end - def isolate_relevant_context(project_media, result) - (result["contexts"]||result["context"]).select{|x| ([x["team_id"]].flatten & [project_media.team_id].flatten).count > 0 && !x["temporary_media"]}.first + def isolate_relevant_context(team_id, result) + [(result["contexts"]||result["context"])].flatten.select{|x| ([x["team_id"]].flatten & [team_id].flatten).count > 0 && !x["temporary_media"]}.first end def get_target_field(project_media, field) @@ -350,18 +350,22 @@ def get_target_field(project_media, field) def parse_similarity_results(project_media, field, results, relationship_type) results ||= [] Hash[results.collect{|result| - result["context"] = isolate_relevant_context(project_media, result) - [ - result["context"] && result["context"]["project_media_id"], - { - score: result["score"], - context: result["context"], - model: result["model"], - source_field: get_target_field(project_media, field), - target_field: get_target_field(project_media, result["field"] || result["context"]["field"]), - relationship_type: relationship_type - } - ] + result["context"] = isolate_relevant_context(project_media.team_id, result) + if result["context"] + [ + result["context"] && result["context"]["project_media_id"], + { + score: result["score"], + context: result["context"], + model: result["model"], + source_field: get_target_field(project_media, field), + target_field: get_target_field(project_media, result["field"] || result["context"]["field"]), + relationship_type: relationship_type + } + ] + else + raise ActiveRecord::RecordInvalid.new, "Related items must exist in the same workspace" + end }.reject{ |k,_| k == project_media.id }] end diff --git a/app/models/explainer.rb b/app/models/explainer.rb index aa25ea9e4..47cc5748d 100644 --- a/app/models/explainer.rb +++ b/app/models/explainer.rb @@ -118,8 +118,10 @@ def self.search_by_similarity(text, language, team_id) language: language } } - response = Bot::Alegre.query_sync_with_params(params, "text") - results = response['result'].to_a.sort_by{ |result| result['_score'] } + response = Bot::Alegre.query_sync_with_params(params, "text")["result"].collect{|result| + result["context"] = Bot::Alegre.isolate_relevant_context(team_id, result) + } + results = response.to_a.sort_by{ |result| result['_score'] } explainer_ids = results.collect{ |result| result.dig('context', 'explainer_id').to_i }.uniq.first(3) explainer_ids.empty? ? Explainer.none : Explainer.where(team_id: team_id, id: explainer_ids) end diff --git a/test/models/bot/alegre_v2_test.rb b/test/models/bot/alegre_v2_test.rb index 79e7ac4a3..031a2eca7 100644 --- a/test/models/bot/alegre_v2_test.rb +++ b/test/models/bot/alegre_v2_test.rb @@ -280,22 +280,22 @@ def teardown test "should isolate relevant_context for text" do pm1 = create_project_media team: @team, quote: 'This is a long text that creates a text-based item' - assert_equal Bot::Alegre.isolate_relevant_context(pm1, {"context"=>[{"team_id"=>pm1.team_id}]}), {"team_id"=>pm1.team_id} + assert_equal Bot::Alegre.isolate_relevant_context(pm1.team_id, {"context"=>[{"team_id"=>pm1.team_id}]}), {"team_id"=>pm1.team_id} end test "should isolate relevant_context for audio" do pm1 = create_project_media team: @team, media: create_uploaded_audio - assert_equal Bot::Alegre.isolate_relevant_context(pm1, {"context"=>[{"team_id"=>pm1.team_id}]}), {"team_id"=>pm1.team_id} + assert_equal Bot::Alegre.isolate_relevant_context(pm1.team_id, {"context"=>[{"team_id"=>pm1.team_id}]}), {"team_id"=>pm1.team_id} end test "should isolate relevant_context for image" do pm1 = create_project_media team: @team, media: create_uploaded_image - assert_equal Bot::Alegre.isolate_relevant_context(pm1, {"context"=>[{"team_id"=>pm1.team_id}]}), {"team_id"=>pm1.team_id} + assert_equal Bot::Alegre.isolate_relevant_context(pm1.team_id, {"context"=>[{"team_id"=>pm1.team_id}]}), {"team_id"=>pm1.team_id} end test "should isolate relevant_context for video" do pm1 = create_project_media team: @team, media: create_uploaded_video - assert_equal Bot::Alegre.isolate_relevant_context(pm1, {"context"=>[{"team_id"=>pm1.team_id}]}), {"team_id"=>pm1.team_id} + assert_equal Bot::Alegre.isolate_relevant_context(pm1.team_id, {"context"=>[{"team_id"=>pm1.team_id}]}), {"team_id"=>pm1.team_id} end test "should return field or type on get_target_field for text" do