diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 5d6b63cb..55d324f2 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -1,6 +1,12 @@ en: admin_js: admin: + api: + scopes: + descriptions: + discourse_ai: + search: "Allows semantic search via the /discourse-ai/embeddings/semantic-search endpoint." + site_settings: categories: discourse_ai: "Discourse AI" diff --git a/lib/embeddings/entry_point.rb b/lib/embeddings/entry_point.rb index 2ee65376..47df06fc 100644 --- a/lib/embeddings/entry_point.rb +++ b/lib/embeddings/entry_point.rb @@ -67,6 +67,11 @@ module DiscourseAi plugin.on(:topic_edited, &callback) plugin.on(:post_created, &callback) plugin.on(:post_edited, &callback) + + plugin.add_api_key_scope( + :discourse_ai, + { search: { actions: %w[discourse_ai/embeddings/embeddings#search] } }, + ) end end end diff --git a/spec/requests/embeddings/embeddings_controller_spec.rb b/spec/requests/embeddings/embeddings_controller_spec.rb index a62b9e01..01d9d11b 100644 --- a/spec/requests/embeddings/embeddings_controller_spec.rb +++ b/spec/requests/embeddings/embeddings_controller_spec.rb @@ -36,6 +36,30 @@ describe DiscourseAi::Embeddings::EmbeddingsController do EmbeddingsGenerationStubs.openai_service(SiteSetting.ai_embeddings_model, query, embedding) end + def create_api_key(user) + key = ApiKey.create!(user: user) + ApiKeyScope.create!(resource: "discourse_ai", action: "search", api_key_id: key.id) + key + end + + it "is able to make API requests using a scoped API key" do + index(topic) + query = "test" + stub_embedding(query) + user = topic.user + + api_key = create_api_key(user) + + get "/discourse-ai/embeddings/semantic-search.json?q=#{query}&hyde=false", + headers: { + "Api-Key" => api_key.key, + "Api-Username" => user.username, + } + + expect(response.status).to eq(200) + expect(response.parsed_body["topics"].map { |t| t["id"] }).to contain_exactly(topic.id) + end + it "returns results correctly when performing a non Hyde search" do index(topic) index(topic_in_subcategory)