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

Commit 36930dd

Browse files
committed
Embeddings CRUD UI
1 parent 9d21f38 commit 36930dd

File tree

20 files changed

+572
-75
lines changed

20 files changed

+572
-75
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import DiscourseRoute from "discourse/routes/discourse";
2+
3+
export default class AdminPluginsShowDiscourseAiEmbeddingsEdit extends DiscourseRoute {
4+
async model(params) {
5+
const allEmbeddings = this.modelFor("adminPlugins.show.discourse-ai-embeddings");
6+
const id = parseInt(params.id, 10);
7+
const record = allEmbeddings.findBy("id", id);
8+
record.provider_params = record.provider_params || {};
9+
return record;
10+
}
11+
12+
setupController(controller, model) {
13+
super.setupController(controller, model);
14+
controller.set(
15+
"allEmbeddings",
16+
this.modelFor("adminPlugins.show.discourse-ai-embeddings")
17+
);
18+
}
19+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import DiscourseRoute from "discourse/routes/discourse";
2+
3+
export default class AdminPluginsShowDiscourseAiEmbeddingsNew extends DiscourseRoute {
4+
async model() {
5+
const record = this.store.createRecord("ai-embedding");
6+
record.provider_params = {};
7+
return record;
8+
}
9+
10+
setupController(controller, model) {
11+
super.setupController(controller, model);
12+
controller.set(
13+
"allEmbeddings",
14+
this.modelFor("adminPlugins.show.discourse-ai-embeddings")
15+
);
16+
}
17+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import DiscourseRoute from "discourse/routes/discourse";
2+
3+
export default class DiscourseAiAiEmbeddingsRoute extends DiscourseRoute {
4+
model() {
5+
return this.store.findAll("ai-embedding");
6+
}
7+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<AiEmbeddingsListEditor
2+
@embeddings={{this.allEmbeddings}}
3+
@currentEmbedding={{this.model}}
4+
/>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<AiEmbeddingsListEditor @embeddings={{this.model}} />
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<AiEmbeddingsListEditor
2+
@embeddings={{this.allEmbeddings}}
3+
@currentEmbedding={{this.model}}
4+
/>

app/controllers/discourse_ai/admin/ai_embeddings_controller.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ def index
1818
meta: {
1919
provider_params: EmbeddingDefinition.provider_params,
2020
providers: EmbeddingDefinition.provider_names,
21+
distance_functions: EmbeddingDefinition.distance_functions,
2122
tokenizers:
2223
EmbeddingDefinition.tokenizer_names.map { |tn|
2324
{ id: tn, name: tn.split("::").last }

app/models/embedding_definition.rb

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@
22

33
class EmbeddingDefinition < ActiveRecord::Base
44
CLOUDFLARE = "cloudflare"
5-
DISCOURSE = "discourse"
65
HUGGING_FACE = "hugging_face"
76
OPEN_AI = "open_ai"
8-
GEMINI = "gemini"
7+
GOOGLE = "google"
98

109
class << self
1110
def provider_names
12-
[CLOUDFLARE, DISCOURSE, HUGGING_FACE, OPEN_AI, GEMINI]
11+
[CLOUDFLARE, HUGGING_FACE, OPEN_AI, GOOGLE]
12+
end
13+
14+
def distance_functions
15+
%w[<#> <=>]
1316
end
1417

1518
def tokenizer_names
@@ -24,7 +27,7 @@ def tokenizer_names
2427
end
2528

2629
def provider_params
27-
{ discourse: { model_name: :text }, open_ai: { model_name: :text } }
30+
{ open_ai: { model_name: :text } }
2831
end
2932
end
3033

@@ -41,13 +44,11 @@ def inference_client
4144
case provider
4245
when CLOUDFLARE
4346
cloudflare_client
44-
when DISCOURSE
45-
discourse_client
4647
when HUGGING_FACE
4748
hugging_face_client
4849
when OPEN_AI
4950
open_ai_client
50-
when GEMINI
51+
when GOOGLE
5152
gemini_client
5253
else
5354
raise "Uknown embeddings provider"
@@ -91,17 +92,6 @@ def cloudflare_client
9192
DiscourseAi::Inference::CloudflareWorkersAi.new(endpoint_url, api_key)
9293
end
9394

94-
def discourse_client
95-
client_url = endpoint_url
96-
client_url = "#{client_url}/api/v1/classify" if url.starts_with?("srv://")
97-
98-
DiscourseAi::Inference::DiscourseClassifier.new(
99-
client_url,
100-
api_key,
101-
lookup_custom_param("model_name"),
102-
)
103-
end
104-
10595
def hugging_face_client
10696
DiscourseAi::Inference::HuggingFaceTextEmbeddings.new(endpoint_url, api_key)
10797
end

assets/javascripts/discourse/admin-discourse-ai-plugin-route-map.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,14 @@ export default {
2020
});
2121
this.route("discourse-ai-spam", { path: "ai-spam" });
2222
this.route("discourse-ai-usage", { path: "ai-usage" });
23+
24+
this.route(
25+
"discourse-ai-embeddings",
26+
{ path: "ai-embeddings" },
27+
function () {
28+
this.route("new");
29+
this.route("edit", { path: "/:id/edit" });
30+
}
31+
);
2332
},
2433
};
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import RestAdapter from "discourse/adapters/rest";
2+
3+
export default class Adapter extends RestAdapter {
4+
jsonMode = true;
5+
6+
basePath() {
7+
return "/admin/plugins/discourse-ai/";
8+
}
9+
10+
pathFor(store, type, findArgs) {
11+
// removes underscores which are implemented in base
12+
let path =
13+
this.basePath(store, type, findArgs) +
14+
store.pluralize(this.apiNameFor(type));
15+
return this.appendQueryParams(path, findArgs);
16+
}
17+
18+
apiNameFor() {
19+
return "ai-embedding";
20+
}
21+
}

0 commit comments

Comments
 (0)