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

Commit 80b7f84

Browse files
committed
system specs
1 parent 31fe3ce commit 80b7f84

File tree

6 files changed

+113
-17
lines changed

6 files changed

+113
-17
lines changed

admin/assets/javascripts/discourse/routes/admin-plugins-show-discourse-ai-embeddings-edit.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ import DiscourseRoute from "discourse/routes/discourse";
22

33
export default class AdminPluginsShowDiscourseAiEmbeddingsEdit extends DiscourseRoute {
44
async model(params) {
5-
const allEmbeddings = this.modelFor("adminPlugins.show.discourse-ai-embeddings");
5+
const allEmbeddings = this.modelFor(
6+
"adminPlugins.show.discourse-ai-embeddings"
7+
);
68
const id = parseInt(params.id, 10);
79
const record = allEmbeddings.findBy("id", id);
810
record.provider_params = record.provider_params || {};

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

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -51,23 +51,30 @@ export default class AiEmbeddingEditor extends Component {
5151
}
5252

5353
get presets() {
54-
return this.args.embeddings.resultSetMeta.presets.map((preset) => {
54+
const presets = this.args.embeddings.resultSetMeta.presets.map((preset) => {
5555
return {
5656
name: preset.display_name,
5757
id: preset.preset_id,
5858
};
5959
});
60+
61+
presets.pushObject({
62+
name: i18n("discourse_ai.embeddings.configure_manually"),
63+
id: "manual",
64+
});
65+
66+
return presets;
6067
}
6168

6269
get showPresets() {
6370
return !this.selectedPreset && this.args.model.isNew;
6471
}
6572

66-
@computed("args.model.provider")
73+
@computed("editingModel.provider")
6774
get metaProviderParams() {
6875
return (
6976
this.args.embeddings.resultSetMeta.provider_params[
70-
this.args?.model?.provider
77+
this.editingModel?.provider
7178
] || {}
7279
);
7380
}
@@ -82,10 +89,11 @@ export default class AiEmbeddingEditor extends Component {
8289

8390
@action
8491
configurePreset() {
85-
this.selectedPreset = this.args.embeddings.resultSetMeta.presets.findBy(
86-
"preset_id",
87-
this.presetId
88-
);
92+
this.selectedPreset =
93+
this.args.embeddings.resultSetMeta.presets.findBy(
94+
"preset_id",
95+
this.presetId
96+
) || {};
8997

9098
this.editingModel = this.store
9199
.createRecord("ai-embedding", this.selectedPreset)
@@ -192,15 +200,15 @@ export default class AiEmbeddingEditor extends Component {
192200
<ComboBox
193201
@value={{this.presetId}}
194202
@content={{this.presets}}
195-
class="ai-tool-editor__presets"
203+
class="ai-embedding-editor__presets"
196204
/>
197205
</div>
198206

199207
<div class="control-group ai-llm-editor__action_panel">
200208
<DButton
201209
@action={{this.configurePreset}}
202210
@label="discourse_ai.tools.next.title"
203-
class="ai-tool-editor__next"
211+
class="ai-embedding-editor__next"
204212
/>
205213
</div>
206214
{{else}}
@@ -253,7 +261,7 @@ export default class AiEmbeddingEditor extends Component {
253261
<label>{{i18n "discourse_ai.embeddings.tokenizer"}}</label>
254262
<ComboBox
255263
@value={{this.editingModel.tokenizer_class}}
256-
@content={{this.editingModel.resultSetMeta.tokenizers}}
264+
@content={{@embeddings.resultSetMeta.tokenizers}}
257265
@class="ai-embedding-editor__tokenizer"
258266
/>
259267
</div>
@@ -302,6 +310,7 @@ export default class AiEmbeddingEditor extends Component {
302310
</label>
303311
<Input
304312
@type="text"
313+
class="ai-embedding-editor-input ai-embedding-editor__{{field}}"
305314
@value={{mut (get this.editingModel.provider_params field)}}
306315
/>
307316
</div>

assets/javascripts/discourse/components/ai-embeddings-list-editor.gjs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { service } from "@ember/service";
44
import DBreadcrumbsItem from "discourse/components/d-breadcrumbs-item";
55
import DButton from "discourse/components/d-button";
66
import DPageSubheader from "discourse/components/d-page-subheader";
7-
import I18n, { i18n } from "discourse-i18n";
7+
import { i18n } from "discourse-i18n";
88
import AdminConfigAreaEmptyList from "admin/components/admin-config-area-empty-list";
99
import AiEmbeddingEditor from "./ai-embedding-editor";
1010

@@ -53,10 +53,7 @@ export default class AiEmbeddingsListEditor extends Component {
5353
</thead>
5454
<tbody>
5555
{{#each @embeddings as |embedding|}}
56-
<tr
57-
data-embedding-name={{embedding.display_name}}
58-
class="ai-embeddings-list__row d-admin-row__content"
59-
>
56+
<tr class="ai-embeddings-list__row d-admin-row__content">
6057
<td class="d-admin-row__overview">
6158
<div class="ai-embeddings-list__name">
6259
<strong>

assets/stylesheets/modules/embeddings/common/ai-embedding-editor.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,4 @@
2323
display: flex;
2424
align-items: center;
2525
}
26-
}
26+
}

config/locales/client.en.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,7 @@ en:
512512
confirm_delete: Are you sure you want to remove this embedding configuration?
513513
empty: "You haven't setup embeddings yet"
514514
presets: "Select a preset..."
515+
configure_manually: "Configure manually"
515516
edit: "Edit"
516517
tests:
517518
title: "Run test"
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# frozen_string_literal: true
2+
3+
RSpec.describe "Managing Embeddings configurations", type: :system, js: true do
4+
fab!(:admin)
5+
let(:page_header) { PageObjects::Components::DPageHeader.new }
6+
7+
before { sign_in(admin) }
8+
9+
it "correctly sets defaults" do
10+
preset = "text-embedding-3-small"
11+
api_key = "abcd"
12+
13+
visit "/admin/plugins/discourse-ai/ai-embeddings"
14+
15+
find(".ai-embeddings-list-editor__new-button").click()
16+
select_kit = PageObjects::Components::SelectKit.new(".ai-embedding-editor__presets")
17+
select_kit.expand
18+
select_kit.select_row_by_value(preset)
19+
find(".ai-embedding-editor__next").click
20+
find("input.ai-embedding-editor__api-key").fill_in(with: api_key)
21+
find(".ai-embedding-editor__save").click()
22+
23+
expect(page).to have_current_path("/admin/plugins/discourse-ai/ai-embeddings")
24+
25+
embedding_def = EmbeddingDefinition.order(:id).last
26+
expect(embedding_def.api_key).to eq(api_key)
27+
28+
preset = EmbeddingDefinition.presets.find { |p| p[:preset_id] == preset }
29+
30+
expect(embedding_def.display_name).to eq(preset[:display_name])
31+
expect(embedding_def.url).to eq(preset[:url])
32+
expect(embedding_def.tokenizer_class).to eq(preset[:tokenizer_class])
33+
expect(embedding_def.dimensions).to eq(preset[:dimensions])
34+
expect(embedding_def.max_sequence_length).to eq(preset[:max_sequence_length])
35+
expect(embedding_def.pg_function).to eq(preset[:pg_function])
36+
expect(embedding_def.provider).to eq(preset[:provider])
37+
expect(embedding_def.provider_params.symbolize_keys).to eq(preset[:provider_params])
38+
end
39+
40+
it "supports manual config" do
41+
api_key = "abcd"
42+
43+
visit "/admin/plugins/discourse-ai/ai-embeddings"
44+
45+
find(".ai-embeddings-list-editor__new-button").click()
46+
select_kit = PageObjects::Components::SelectKit.new(".ai-embedding-editor__presets")
47+
select_kit.expand
48+
select_kit.select_row_by_value("manual")
49+
find(".ai-embedding-editor__next").click
50+
51+
find("input.ai-embedding-editor__display-name").fill_in(with: "OpenAI's text-embedding-3-small")
52+
53+
select_kit = PageObjects::Components::SelectKit.new(".ai-embedding-editor__provider")
54+
select_kit.expand
55+
select_kit.select_row_by_value(EmbeddingDefinition::OPEN_AI)
56+
57+
find("input.ai-embedding-editor__url").fill_in(with: "https://api.openai.com/v1/embeddings")
58+
find("input.ai-embedding-editor__api-key").fill_in(with: api_key)
59+
60+
select_kit = PageObjects::Components::SelectKit.new(".ai-embedding-editor__tokenizer")
61+
select_kit.expand
62+
select_kit.select_row_by_value("DiscourseAi::Tokenizer::OpenAiTokenizer")
63+
64+
find("input.ai-embedding-editor__dimensions").fill_in(with: 1536)
65+
find("input.ai-embedding-editor__max_sequence_length").fill_in(with: 8191)
66+
67+
select_kit = PageObjects::Components::SelectKit.new(".ai-embedding-editor__distance_functions")
68+
select_kit.expand
69+
select_kit.select_row_by_value("<=>")
70+
find(".ai-embedding-editor__save").click()
71+
72+
expect(page).to have_current_path("/admin/plugins/discourse-ai/ai-embeddings")
73+
74+
embedding_def = EmbeddingDefinition.order(:id).last
75+
expect(embedding_def.api_key).to eq(api_key)
76+
77+
preset = EmbeddingDefinition.presets.find { |p| p[:preset_id] == "text-embedding-3-small" }
78+
79+
expect(embedding_def.display_name).to eq(preset[:display_name])
80+
expect(embedding_def.url).to eq(preset[:url])
81+
expect(embedding_def.tokenizer_class).to eq(preset[:tokenizer_class])
82+
expect(embedding_def.dimensions).to eq(preset[:dimensions])
83+
expect(embedding_def.max_sequence_length).to eq(preset[:max_sequence_length])
84+
expect(embedding_def.pg_function).to eq(preset[:pg_function])
85+
expect(embedding_def.provider).to eq(preset[:provider])
86+
end
87+
end

0 commit comments

Comments
 (0)