import Component from "@glimmer/component"; import { action } from "@ember/object"; import I18n from "I18n"; import { tracked } from "@glimmer/tracking"; import { ajax } from "discourse/lib/ajax"; import { isValidSearchTerm, translateResults } from "discourse/lib/search"; import discourseDebounce from "discourse-common/lib/debounce"; import { inject as service } from "@ember/service"; import { bind } from "discourse-common/utils/decorators"; import { SEARCH_TYPE_DEFAULT } from "discourse/controllers/full-page-search"; import DToggleSwitch from "discourse/components/d-toggle-switch"; import { on } from "@ember/modifier"; import didInsert from "@ember/render-modifiers/modifiers/did-insert"; import willDestroy from "@ember/render-modifiers/modifiers/will-destroy"; import icon from "discourse-common/helpers/d-icon"; import { popupAjaxError } from "discourse/lib/ajax-error"; import { withPluginApi } from "discourse/lib/plugin-api"; export default class SemanticSearch extends Component { static shouldRender(_args, { siteSettings }) { return siteSettings.ai_embeddings_semantic_search_enabled; } @service appEvents; @service siteSettings; @tracked searching = false; @tracked AIResults = []; @tracked showingAIResults = false; get disableToggleSwitch() { if (this.searching || this.AIResults.length === 0) { return true; } } get searchStateText() { if (this.searching) { return I18n.t("discourse_ai.embeddings.semantic_search_loading"); } if (this.AIResults.length === 0) { return I18n.t("discourse_ai.embeddings.semantic_search_results.none"); } if (this.AIResults.length > 0) { if (this.showingAIResults) { return I18n.t( "discourse_ai.embeddings.semantic_search_results.toggle", { count: this.AIResults.length, } ); } else { return I18n.t( "discourse_ai.embeddings.semantic_search_results.toggle_hidden", { count: this.AIResults.length, } ); } } } get searchTerm() { return this.args.outletArgs.search; } get searchEnabled() { return ( this.args.outletArgs.type === SEARCH_TYPE_DEFAULT && isValidSearchTerm(this.searchTerm, this.siteSettings) ); } @action toggleAIResults() { if (this.showingAIResults) { this.args.outletArgs.addSearchResults([], "topic_id"); } else { this.args.outletArgs.addSearchResults(this.AIResults, "topic_id"); } this.showingAIResults = !this.showingAIResults; } @action resetAIResults() { this.AIResults = []; this.showingAIResults = false; } @action performHyDESearch() { if (!this.searchEnabled) { return; } withPluginApi("1.15.0", (api) => { api.onAppEvent("full-page-search:trigger-search", () => { this.searching = true; this.resetAIResults(); ajax("/discourse-ai/embeddings/semantic-search", { data: { q: this.searchTerm }, }) .then(async (results) => { const model = (await translateResults(results)) || {}; if (model.posts?.length === 0) { this.searching = false; return; } model.posts.forEach((post) => { post.generatedByAI = true; }); this.AIResults = model.posts; }) .catch(popupAjaxError) .finally(() => (this.searching = false)); }); }); } }