Skip to content
This repository was archived by the owner on Jul 22, 2025. It is now read-only.

Commit a7da343

Browse files
committed
moving rag UI to a central spot
1 parent f8dfe67 commit a7da343

File tree

7 files changed

+138
-125
lines changed

7 files changed

+138
-125
lines changed

app/controllers/discourse_ai/admin/ai_personas_controller.rb

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -75,32 +75,6 @@ def destroy
7575
end
7676
end
7777

78-
def upload_file
79-
file = params[:file] || params[:files].first
80-
81-
if !SiteSetting.ai_embeddings_enabled?
82-
raise Discourse::InvalidAccess.new("Embeddings not enabled")
83-
end
84-
85-
validate_extension!(file.original_filename)
86-
validate_file_size!(file.tempfile.size)
87-
88-
hijack do
89-
upload =
90-
UploadCreator.new(
91-
file.tempfile,
92-
file.original_filename,
93-
type: "discourse_ai_rag_upload",
94-
skip_validations: true,
95-
).create_for(current_user.id)
96-
97-
if upload.persisted?
98-
render json: UploadSerializer.new(upload)
99-
else
100-
render json: failed_json.merge(errors: upload.errors.full_messages), status: 422
101-
end
102-
end
103-
end
10478

10579
def indexing_status_check
10680
render json: RagDocumentFragment.indexing_status(@ai_persona, @ai_persona.uploads)
@@ -164,30 +138,6 @@ def permit_tools(tools)
164138
end
165139
end
166140

167-
def validate_extension!(filename)
168-
extension = File.extname(filename)[1..-1] || ""
169-
authorized_extensions = %w[txt md]
170-
if !authorized_extensions.include?(extension)
171-
raise Discourse::InvalidParameters.new(
172-
I18n.t(
173-
"upload.unauthorized",
174-
authorized_extensions: authorized_extensions.join(" "),
175-
),
176-
)
177-
end
178-
end
179-
180-
def validate_file_size!(filesize)
181-
max_size_bytes = 20.megabytes
182-
if filesize > max_size_bytes
183-
raise Discourse::InvalidParameters.new(
184-
I18n.t(
185-
"upload.attachments.too_large_humanized",
186-
max_size: ActiveSupport::NumberHelper.number_to_human_size(max_size_bytes),
187-
),
188-
)
189-
end
190-
end
191141
end
192142
end
193143
end
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# frozen_string_literal: true
2+
3+
module DiscourseAi
4+
module Admin
5+
class RagDocumentFragmentsController < ::Admin::AdminController
6+
requires_plugin ::DiscourseAi::PLUGIN_NAME
7+
8+
def upload_file
9+
file = params[:file] || params[:files].first
10+
11+
if !SiteSetting.ai_embeddings_enabled?
12+
raise Discourse::InvalidAccess.new("Embeddings not enabled")
13+
end
14+
15+
validate_extension!(file.original_filename)
16+
validate_file_size!(file.tempfile.size)
17+
18+
hijack do
19+
upload =
20+
UploadCreator.new(
21+
file.tempfile,
22+
file.original_filename,
23+
type: "discourse_ai_rag_upload",
24+
skip_validations: true,
25+
).create_for(current_user.id)
26+
27+
if upload.persisted?
28+
render json: UploadSerializer.new(upload)
29+
else
30+
render json: failed_json.merge(errors: upload.errors.full_messages), status: 422
31+
end
32+
end
33+
end
34+
35+
private
36+
37+
def validate_extension!(filename)
38+
extension = File.extname(filename)[1..-1] || ""
39+
authorized_extensions = %w[txt md]
40+
if !authorized_extensions.include?(extension)
41+
raise Discourse::InvalidParameters.new(
42+
I18n.t(
43+
"upload.unauthorized",
44+
authorized_extensions: authorized_extensions.join(" "),
45+
),
46+
)
47+
end
48+
end
49+
50+
def validate_file_size!(filesize)
51+
max_size_bytes = 20.megabytes
52+
if filesize > max_size_bytes
53+
raise Discourse::InvalidParameters.new(
54+
I18n.t(
55+
"upload.attachments.too_large_humanized",
56+
max_size: ActiveSupport::NumberHelper.number_to_human_size(max_size_bytes),
57+
),
58+
)
59+
end
60+
end
61+
62+
end
63+
end
64+
end

assets/javascripts/discourse/components/ai-persona-editor.gjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import DTooltip from "float-kit/components/d-tooltip";
2323
import AiLlmSelector from "./ai-llm-selector";
2424
import AiPersonaToolOptions from "./ai-persona-tool-options";
2525
import AiToolSelector from "./ai-tool-selector";
26-
import PersonaRagUploader from "./persona-rag-uploader";
26+
import RagUploader from "./rag-uploader";
2727

2828
export default class PersonaEditor extends Component {
2929
@service router;
@@ -487,7 +487,7 @@ export default class PersonaEditor extends Component {
487487
{{/if}}
488488
{{#if this.siteSettings.ai_embeddings_enabled}}
489489
<div class="control-group">
490-
<PersonaRagUploader
490+
<RagUploader
491491
@persona={{this.editingModel}}
492492
@updateUploads={{this.updateUploads}}
493493
@onRemove={{this.removeUpload}}

assets/javascripts/discourse/components/rag-upload-progress.gjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export default class RagUploadProgress extends Component {
6565

6666
<template>
6767
<td
68-
class="persona-rag-uploader__upload-status"
68+
class="rag-uploader__upload-status"
6969
{{didInsert this.trackProgress}}
7070
>
7171
{{#if this.progress}}

assets/javascripts/discourse/components/persona-rag-uploader.gjs renamed to assets/javascripts/discourse/components/rag-uploader.gjs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import discourseDebounce from "discourse-common/lib/debounce";
1212
import I18n from "discourse-i18n";
1313
import RagUploadProgress from "./rag-upload-progress";
1414

15-
export default class PersonaRagUploader extends Component.extend(
15+
export default class RagUploader extends Component.extend(
1616
UppyUploadMixin
1717
) {
1818
@service appEvents;
@@ -21,9 +21,9 @@ export default class PersonaRagUploader extends Component.extend(
2121
@tracked filteredUploads = null;
2222
@tracked ragIndexingStatuses = null;
2323
@tracked ragUploads = null;
24-
id = "discourse-ai-persona-rag-uploader";
24+
id = "discourse-ai-rag-uploader";
2525
maxFiles = 20;
26-
uploadUrl = "/admin/plugins/discourse-ai/ai-personas/files/upload";
26+
uploadUrl = "/admin/plugins/discourse-ai/rag-document-fragments/files/upload";
2727
preventDirectS3Uploads = true;
2828

2929
didReceiveAttrs() {
@@ -112,19 +112,19 @@ export default class PersonaRagUploader extends Component.extend(
112112
}
113113

114114
<template>
115-
<div class="persona-rag-uploader">
115+
<div class="rag-uploader">
116116
<h3>{{I18n.t "discourse_ai.ai_persona.uploads.title"}}</h3>
117117
<p>{{I18n.t "discourse_ai.ai_persona.uploads.description"}}</p>
118118

119119
{{#if this.ragUploads}}
120-
<div class="persona-rag-uploader__search-input-container">
121-
<div class="persona-rag-uploader__search-input">
120+
<div class="rag-uploader__search-input-container">
121+
<div class="rag-uploader__search-input">
122122
{{icon
123123
"search"
124-
class="persona-rag-uploader__search-input__search-icon"
124+
class="rag-uploader__search-input__search-icon"
125125
}}
126126
<Input
127-
class="persona-rag-uploader__search-input__input"
127+
class="rag-uploader__search-input__input"
128128
placeholder={{I18n.t "discourse_ai.ai_persona.uploads.filter"}}
129129
@value={{this.term}}
130130
{{on "keyup" this.debouncedSearch}}
@@ -133,12 +133,12 @@ export default class PersonaRagUploader extends Component.extend(
133133
</div>
134134
{{/if}}
135135

136-
<table class="persona-rag-uploader__uploads-list">
136+
<table class="rag-uploader__uploads-list">
137137
<tbody>
138138
{{#each this.filteredUploads as |upload|}}
139139
<tr>
140140
<td>
141-
<span class="persona-rag-uploader__rag-file-icon">{{icon
141+
<span class="rag-uploader__rag-file-icon">{{icon
142142
"file"
143143
}}</span>
144144
{{upload.original_filename}}
@@ -147,7 +147,7 @@ export default class PersonaRagUploader extends Component.extend(
147147
@upload={{upload}}
148148
@ragIndexingStatuses={{this.ragIndexingStatuses}}
149149
/>
150-
<td class="persona-rag-uploader__remove-file">
150+
<td class="rag-uploader__remove-file">
151151
<DButton
152152
@icon="times"
153153
@title="discourse_ai.ai_persona.uploads.remove"
@@ -159,16 +159,16 @@ export default class PersonaRagUploader extends Component.extend(
159159
{{/each}}
160160
{{#each this.inProgressUploads as |upload|}}
161161
<tr>
162-
<td><span class="persona-rag-uploader__rag-file-icon">{{icon
162+
<td><span class="rag-uploader__rag-file-icon">{{icon
163163
"file"
164164
}}</span>
165165
{{upload.original_filename}}</td>
166-
<td class="persona-rag-uploader__upload-status">
166+
<td class="rag-uploader__upload-status">
167167
<div class="spinner small"></div>
168168
<span>{{I18n.t "discourse_ai.ai_persona.uploads.uploading"}}
169169
{{upload.uploadProgress}}%</span>
170170
</td>
171-
<td class="persona-rag-uploader__remove-file">
171+
<td class="rag-uploader__remove-file">
172172
<DButton
173173
@icon="times"
174174
@title="discourse_ai.ai_persona.uploads.remove"

assets/stylesheets/modules/ai-bot/common/ai-persona.scss

Lines changed: 56 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -79,77 +79,76 @@
7979
display: block;
8080
margin-top: 1em;
8181
}
82+
}
83+
.rag-uploader {
84+
width: 500px;
8285

83-
.persona-rag-uploader {
84-
width: 500px;
86+
&__search-input {
87+
display: flex;
88+
align-items: center;
89+
border: 1px solid var(--primary-400);
90+
width: 100%;
91+
box-sizing: border-box;
92+
height: 35px;
93+
padding: 0 0.5rem;
94+
95+
&:focus,
96+
&:focus-within {
97+
@include default-focus();
98+
}
8599

86-
&__search-input {
100+
&-container {
87101
display: flex;
88-
align-items: center;
89-
border: 1px solid var(--primary-400);
90-
width: 100%;
91-
box-sizing: border-box;
92-
height: 35px;
93-
padding: 0 0.5rem;
94-
95-
&:focus,
96-
&:focus-within {
97-
@include default-focus();
98-
}
99-
100-
&-container {
101-
display: flex;
102-
flex-grow: 1;
103-
}
104-
105-
&__search-icon {
106-
background: none !important;
107-
color: var(--primary-medium);
108-
}
109-
110-
&__input {
111-
width: 100% !important;
112-
}
113-
114-
&__input,
115-
&__input:focus {
116-
margin: 0 !important;
117-
border: 0 !important;
118-
appearance: none !important;
119-
outline: none !important;
120-
background: none !important;
121-
}
102+
flex-grow: 1;
122103
}
123104

124-
&__uploads-list {
125-
margin-bottom: 20px;
105+
&__search-icon {
106+
background: none !important;
107+
color: var(--primary-medium);
108+
}
126109

127-
tbody {
128-
border-top: none;
129-
}
110+
&__input {
111+
width: 100% !important;
130112
}
131113

132-
&__upload-status {
133-
text-align: right;
134-
padding-right: 0;
114+
&__input,
115+
&__input:focus {
116+
margin: 0 !important;
117+
border: 0 !important;
118+
appearance: none !important;
119+
outline: none !important;
120+
background: none !important;
121+
}
122+
}
135123

136-
.indexed {
137-
color: var(--success);
138-
}
124+
&__uploads-list {
125+
margin-bottom: 20px;
139126

140-
.uploaded,
141-
.indexing {
142-
color: var(--primary-low-mid);
143-
}
127+
tbody {
128+
border-top: none;
144129
}
130+
}
145131

146-
&__remove-file {
147-
text-align: right;
148-
padding-left: 0;
132+
&__upload-status {
133+
text-align: right;
134+
padding-right: 0;
135+
136+
.indexed {
137+
color: var(--success);
149138
}
150139

151-
&__rag-file-icon {
152-
margin-right: 5px;
140+
.uploaded,
141+
.indexing {
142+
color: var(--primary-low-mid);
153143
}
154144
}
145+
146+
&__remove-file {
147+
text-align: right;
148+
padding-left: 0;
149+
}
150+
151+
&__rag-file-icon {
152+
margin-right: 5px;
153+
}
155154
}

config/routes.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
) { post :test, on: :collection }
5555

5656
post "/ai-personas/:id/create-user", to: "discourse_ai/admin/ai_personas#create_user"
57-
post "/ai-personas/files/upload", to: "discourse_ai/admin/ai_personas#upload_file"
57+
post "/rag-document-fragments/files/upload", to: "discourse_ai/admin/rag_document_fragments#upload_file"
5858
put "/ai-personas/:id/files/remove", to: "discourse_ai/admin/ai_personas#remove_file"
5959
get "/ai-personas/:id/files/status", to: "discourse_ai/admin/ai_personas#indexing_status_check"
6060

0 commit comments

Comments
 (0)