import Component from "@glimmer/component"; import { tracked } from "@glimmer/tracking"; import { concat, fn, hash } from "@ember/helper"; import { action } from "@ember/object"; import { service } from "@ember/service"; import { and, gt } from "truth-helpers"; import Form from "discourse/components/form"; import { popupAjaxError } from "discourse/lib/ajax-error"; import { i18n } from "discourse-i18n"; import AiToolTestModal from "./modal/ai-tool-test-modal"; import RagOptionsFk from "./rag-options-fk"; import RagUploader from "./rag-uploader"; export default class AiToolEditorForm extends Component { @service modal; @service siteSettings; @service dialog; @service router; @service toasts; @tracked uploadedFiles = []; @tracked isSaving = false; PARAMETER_TYPES = [ { name: "string", id: "string" }, { name: "number", id: "number" }, { name: "boolean", id: "boolean" }, { name: "array", id: "array" }, ]; get formData() { const parameters = (this.args.editingModel.parameters ?? []).map( (parameter) => ({ ...parameter, isEnum: !!parameter.enum?.length, enum: (parameter.enum ??= []), }) ); return { name: this.args.editingModel.name || "", tool_name: this.args.editingModel.tool_name || "", description: this.args.editingModel.description || "", summary: this.args.editingModel.summary || "", parameters, script: this.args.editingModel.script || "", rag_uploads: this.args.editingModel.rag_uploads || [], }; } @action toggleIsEnum(value, { name, parentName, set }) { if (value) { set(`${parentName}.enum`, [""]); } else { set(`${parentName}.enum`, []); } set(name, value); } @action async save(data) { this.isSaving = true; try { await this.args.model.save(data); this.toasts.success({ data: { message: i18n("discourse_ai.tools.saved") }, duration: 2000, }); if (!this.args.tools.any((tool) => tool.id === this.args.model.id)) { this.args.tools.pushObject(this.args.model); } this.router.transitionTo( "adminPlugins.show.discourse-ai-tools.edit", this.args.model ); } catch (e) { popupAjaxError(e); } finally { this.isSaving = false; } } @action delete() { return this.dialog.confirm({ message: i18n("discourse_ai.tools.confirm_delete"), didConfirm: async () => { await this.args.model.destroyRecord(); this.args.tools.removeObject(this.args.model); this.router.transitionTo("adminPlugins.show.discourse-ai-tools.index"); }, }); } @action updateUploads(addItemToCollection, uploads) { const uniqueUploads = uploads.filter( (upload) => !this.uploadedFiles.some((file) => file.id === upload.id) ); addItemToCollection("rag_uploads", uniqueUploads); this.uploadedFiles = [...this.uploadedFiles, ...uniqueUploads]; } @action removeUpload(form, upload) { this.uploadedFiles = this.uploadedFiles.filter( (file) => file.id !== upload.id ); form.set("rag_uploads", this.uploadedFiles); } @action openTestModal() { this.modal.show(AiToolTestModal, { model: { tool: this.args.editingModel, }, }); } currentParameterSelection(data, index) { return data.parameters[index].type; } get ragUploadsDescription() { return this.siteSettings.rag_images_enabled ? i18n("discourse_ai.rag.uploads.description_with_images") : i18n("discourse_ai.rag.uploads.description"); } }