moving rag UI to a central spot

This commit is contained in:
Sam Saffron 2024-09-16 18:52:36 +10:00
parent f8dfe67970
commit a7da343a13
No known key found for this signature in database
GPG Key ID: B9606168D2FFD9F5
7 changed files with 143 additions and 130 deletions

View File

@ -75,32 +75,6 @@ module DiscourseAi
end
end
def upload_file
file = params[:file] || params[:files].first
if !SiteSetting.ai_embeddings_enabled?
raise Discourse::InvalidAccess.new("Embeddings not enabled")
end
validate_extension!(file.original_filename)
validate_file_size!(file.tempfile.size)
hijack do
upload =
UploadCreator.new(
file.tempfile,
file.original_filename,
type: "discourse_ai_rag_upload",
skip_validations: true,
).create_for(current_user.id)
if upload.persisted?
render json: UploadSerializer.new(upload)
else
render json: failed_json.merge(errors: upload.errors.full_messages), status: 422
end
end
end
def indexing_status_check
render json: RagDocumentFragment.indexing_status(@ai_persona, @ai_persona.uploads)
@ -164,30 +138,6 @@ module DiscourseAi
end
end
def validate_extension!(filename)
extension = File.extname(filename)[1..-1] || ""
authorized_extensions = %w[txt md]
if !authorized_extensions.include?(extension)
raise Discourse::InvalidParameters.new(
I18n.t(
"upload.unauthorized",
authorized_extensions: authorized_extensions.join(" "),
),
)
end
end
def validate_file_size!(filesize)
max_size_bytes = 20.megabytes
if filesize > max_size_bytes
raise Discourse::InvalidParameters.new(
I18n.t(
"upload.attachments.too_large_humanized",
max_size: ActiveSupport::NumberHelper.number_to_human_size(max_size_bytes),
),
)
end
end
end
end
end

View File

@ -0,0 +1,64 @@
# frozen_string_literal: true
module DiscourseAi
module Admin
class RagDocumentFragmentsController < ::Admin::AdminController
requires_plugin ::DiscourseAi::PLUGIN_NAME
def upload_file
file = params[:file] || params[:files].first
if !SiteSetting.ai_embeddings_enabled?
raise Discourse::InvalidAccess.new("Embeddings not enabled")
end
validate_extension!(file.original_filename)
validate_file_size!(file.tempfile.size)
hijack do
upload =
UploadCreator.new(
file.tempfile,
file.original_filename,
type: "discourse_ai_rag_upload",
skip_validations: true,
).create_for(current_user.id)
if upload.persisted?
render json: UploadSerializer.new(upload)
else
render json: failed_json.merge(errors: upload.errors.full_messages), status: 422
end
end
end
private
def validate_extension!(filename)
extension = File.extname(filename)[1..-1] || ""
authorized_extensions = %w[txt md]
if !authorized_extensions.include?(extension)
raise Discourse::InvalidParameters.new(
I18n.t(
"upload.unauthorized",
authorized_extensions: authorized_extensions.join(" "),
),
)
end
end
def validate_file_size!(filesize)
max_size_bytes = 20.megabytes
if filesize > max_size_bytes
raise Discourse::InvalidParameters.new(
I18n.t(
"upload.attachments.too_large_humanized",
max_size: ActiveSupport::NumberHelper.number_to_human_size(max_size_bytes),
),
)
end
end
end
end
end

View File

@ -23,7 +23,7 @@ import DTooltip from "float-kit/components/d-tooltip";
import AiLlmSelector from "./ai-llm-selector";
import AiPersonaToolOptions from "./ai-persona-tool-options";
import AiToolSelector from "./ai-tool-selector";
import PersonaRagUploader from "./persona-rag-uploader";
import RagUploader from "./rag-uploader";
export default class PersonaEditor extends Component {
@service router;
@ -487,7 +487,7 @@ export default class PersonaEditor extends Component {
{{/if}}
{{#if this.siteSettings.ai_embeddings_enabled}}
<div class="control-group">
<PersonaRagUploader
<RagUploader
@persona={{this.editingModel}}
@updateUploads={{this.updateUploads}}
@onRemove={{this.removeUpload}}

View File

@ -65,7 +65,7 @@ export default class RagUploadProgress extends Component {
<template>
<td
class="persona-rag-uploader__upload-status"
class="rag-uploader__upload-status"
{{didInsert this.trackProgress}}
>
{{#if this.progress}}

View File

@ -12,7 +12,7 @@ import discourseDebounce from "discourse-common/lib/debounce";
import I18n from "discourse-i18n";
import RagUploadProgress from "./rag-upload-progress";
export default class PersonaRagUploader extends Component.extend(
export default class RagUploader extends Component.extend(
UppyUploadMixin
) {
@service appEvents;
@ -21,9 +21,9 @@ export default class PersonaRagUploader extends Component.extend(
@tracked filteredUploads = null;
@tracked ragIndexingStatuses = null;
@tracked ragUploads = null;
id = "discourse-ai-persona-rag-uploader";
id = "discourse-ai-rag-uploader";
maxFiles = 20;
uploadUrl = "/admin/plugins/discourse-ai/ai-personas/files/upload";
uploadUrl = "/admin/plugins/discourse-ai/rag-document-fragments/files/upload";
preventDirectS3Uploads = true;
didReceiveAttrs() {
@ -112,19 +112,19 @@ export default class PersonaRagUploader extends Component.extend(
}
<template>
<div class="persona-rag-uploader">
<div class="rag-uploader">
<h3>{{I18n.t "discourse_ai.ai_persona.uploads.title"}}</h3>
<p>{{I18n.t "discourse_ai.ai_persona.uploads.description"}}</p>
{{#if this.ragUploads}}
<div class="persona-rag-uploader__search-input-container">
<div class="persona-rag-uploader__search-input">
<div class="rag-uploader__search-input-container">
<div class="rag-uploader__search-input">
{{icon
"search"
class="persona-rag-uploader__search-input__search-icon"
class="rag-uploader__search-input__search-icon"
}}
<Input
class="persona-rag-uploader__search-input__input"
class="rag-uploader__search-input__input"
placeholder={{I18n.t "discourse_ai.ai_persona.uploads.filter"}}
@value={{this.term}}
{{on "keyup" this.debouncedSearch}}
@ -133,12 +133,12 @@ export default class PersonaRagUploader extends Component.extend(
</div>
{{/if}}
<table class="persona-rag-uploader__uploads-list">
<table class="rag-uploader__uploads-list">
<tbody>
{{#each this.filteredUploads as |upload|}}
<tr>
<td>
<span class="persona-rag-uploader__rag-file-icon">{{icon
<span class="rag-uploader__rag-file-icon">{{icon
"file"
}}</span>
{{upload.original_filename}}
@ -147,7 +147,7 @@ export default class PersonaRagUploader extends Component.extend(
@upload={{upload}}
@ragIndexingStatuses={{this.ragIndexingStatuses}}
/>
<td class="persona-rag-uploader__remove-file">
<td class="rag-uploader__remove-file">
<DButton
@icon="times"
@title="discourse_ai.ai_persona.uploads.remove"
@ -159,16 +159,16 @@ export default class PersonaRagUploader extends Component.extend(
{{/each}}
{{#each this.inProgressUploads as |upload|}}
<tr>
<td><span class="persona-rag-uploader__rag-file-icon">{{icon
<td><span class="rag-uploader__rag-file-icon">{{icon
"file"
}}</span>
{{upload.original_filename}}</td>
<td class="persona-rag-uploader__upload-status">
<td class="rag-uploader__upload-status">
<div class="spinner small"></div>
<span>{{I18n.t "discourse_ai.ai_persona.uploads.uploading"}}
{{upload.uploadProgress}}%</span>
</td>
<td class="persona-rag-uploader__remove-file">
<td class="rag-uploader__remove-file">
<DButton
@icon="times"
@title="discourse_ai.ai_persona.uploads.remove"

View File

@ -79,8 +79,8 @@
display: block;
margin-top: 1em;
}
.persona-rag-uploader {
}
.rag-uploader {
width: 500px;
&__search-input {
@ -152,4 +152,3 @@
margin-right: 5px;
}
}
}

View File

@ -54,7 +54,7 @@ Discourse::Application.routes.draw do
) { post :test, on: :collection }
post "/ai-personas/:id/create-user", to: "discourse_ai/admin/ai_personas#create_user"
post "/ai-personas/files/upload", to: "discourse_ai/admin/ai_personas#upload_file"
post "/rag-document-fragments/files/upload", to: "discourse_ai/admin/rag_document_fragments#upload_file"
put "/ai-personas/:id/files/remove", to: "discourse_ai/admin/ai_personas#remove_file"
get "/ai-personas/:id/files/status", to: "discourse_ai/admin/ai_personas#indexing_status_check"