diff --git a/app/models/ai_persona.rb b/app/models/ai_persona.rb index 92919fa2..acc6fbc8 100644 --- a/app/models/ai_persona.rb +++ b/app/models/ai_persona.rb @@ -31,38 +31,8 @@ class AiPersona < ActiveRecord::Base before_update :regenerate_rag_fragments - class MultisiteHash - def initialize(id) - @hash = Hash.new { |h, k| h[k] = {} } - @id = id - - MessageBus.subscribe(channel_name) { |message| @hash[message.data] = {} } - end - - def channel_name - "/multisite-hash-#{@id}" - end - - def current_db - RailsMultisite::ConnectionManagement.current_db - end - - def [](key) - @hash.dig(current_db, key) - end - - def []=(key, val) - @hash[current_db][key] = val - end - - def flush! - @hash[current_db] = {} - MessageBus.publish(channel_name, current_db) - end - end - def self.persona_cache - @persona_cache ||= MultisiteHash.new("persona_cache") + @persona_cache ||= ::DiscourseAi::MultisiteHash.new("persona_cache") end scope :ordered, -> { order("priority DESC, lower(name) ASC") } diff --git a/lib/ai_helper/assistant.rb b/lib/ai_helper/assistant.rb index c12671f8..cbb16e3c 100644 --- a/lib/ai_helper/assistant.rb +++ b/lib/ai_helper/assistant.rb @@ -3,16 +3,20 @@ module DiscourseAi module AiHelper class Assistant - AI_HELPER_PROMPTS_CACHE_KEY = "ai_helper_prompts" + def self.prompt_cache + @prompt_cache ||= ::DiscourseAi::MultisiteHash.new("prompt_cache") + end def self.clear_prompt_cache! - Discourse.cache.delete(AI_HELPER_PROMPTS_CACHE_KEY) + prompt_cache.flush! end def available_prompts - Discourse - .cache - .fetch(AI_HELPER_PROMPTS_CACHE_KEY, expires_in: 30.minutes) do + key = "prompt_cache_#{I18n.locale}" + self + .class + .prompt_cache + .fetch(key) do prompts = CompletionPrompt.where(enabled: true) # Hide illustrate_post if disabled diff --git a/lib/multisite_hash.rb b/lib/multisite_hash.rb new file mode 100644 index 00000000..16cf646a --- /dev/null +++ b/lib/multisite_hash.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +module DiscourseAi + class MultisiteHash + def initialize(id) + @hash = Hash.new { |h, k| h[k] = {} } + @id = id + + MessageBus.subscribe(channel_name) { |message| @hash[message.data] = {} } + end + + def channel_name + "/multisite-hash-#{@id}" + end + + def current_db + RailsMultisite::ConnectionManagement.current_db + end + + def fetch(key) + @hash[current_db][key] ||= yield + end + + def [](key) + @hash.dig(current_db, key) + end + + def []=(key, val) + @hash[current_db][key] = val + end + + def flush! + @hash[current_db] = {} + MessageBus.publish(channel_name, current_db) + end + + # TODO implement a GC so we don't retain too much memory + end +end diff --git a/spec/lib/modules/ai_helper/entry_point_spec.rb b/spec/lib/modules/ai_helper/entry_point_spec.rb new file mode 100644 index 00000000..4f5ff677 --- /dev/null +++ b/spec/lib/modules/ai_helper/entry_point_spec.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +describe DiscourseAi::AiHelper::EntryPoint do + fab!(:english_user) { Fabricate(:user) } + fab!(:french_user) { Fabricate(:user, locale: "fr") } + + it "will correctly localize available prompts" do + SiteSetting.ai_helper_model = "fake:fake" + SiteSetting.default_locale = "en" + SiteSetting.allow_user_locale = true + SiteSetting.composer_ai_helper_enabled = true + SiteSetting.ai_helper_allowed_groups = "10" # tl0 + DiscourseAi::AiHelper::Assistant.clear_prompt_cache! + + Group.refresh_automatic_groups! + + serializer = CurrentUserSerializer.new(english_user, scope: Guardian.new(english_user)) + parsed = JSON.parse(serializer.to_json) + + translate_prompt = + parsed["current_user"]["ai_helper_prompts"].find { |prompt| prompt["name"] == "translate" } + + expect(translate_prompt["translated_name"]).to eq( + I18n.t("discourse_ai.ai_helper.prompts.translate"), + ) + + I18n.with_locale("fr") do + serializer = CurrentUserSerializer.new(french_user, scope: Guardian.new(french_user)) + parsed = JSON.parse(serializer.to_json) + + translate_prompt = + parsed["current_user"]["ai_helper_prompts"].find { |prompt| prompt["name"] == "translate" } + + expect(translate_prompt["translated_name"]).to eq( + I18n.t("discourse_ai.ai_helper.prompts.translate", locale: "fr"), + ) + end + end +end