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

Commit 883e098

Browse files
committed
WIP: improve embeddings config styles
1 parent faa8e6e commit 883e098

File tree

5 files changed

+136
-33
lines changed

5 files changed

+136
-33
lines changed

app/models/embedding_definition.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ def presets
7777
# indexes, so we downsample to 2000 via API.
7878
{
7979
preset_id: "text-embedding-3-large",
80-
display_name: "OpenAI's text-embedding-3-large",
80+
display_name: "text-embedding-3-large",
8181
dimensions: 2000,
8282
max_sequence_length: 8191,
8383
pg_function: "<=>",
@@ -91,7 +91,7 @@ def presets
9191
},
9292
{
9393
preset_id: "text-embedding-3-small",
94-
display_name: "OpenAI's text-embedding-3-small",
94+
display_name: "text-embedding-3-small",
9595
dimensions: 1536,
9696
max_sequence_length: 8191,
9797
pg_function: "<=>",
@@ -105,7 +105,7 @@ def presets
105105
},
106106
{
107107
preset_id: "text-embedding-ada-002",
108-
display_name: "OpenAI's text-embedding-ada-002",
108+
display_name: "text-embedding-ada-002",
109109
dimensions: 1536,
110110
max_sequence_length: 8191,
111111
pg_function: "<=>",

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

Lines changed: 83 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import Component from "@glimmer/component";
22
import { tracked } from "@glimmer/tracking";
33
import { Input } from "@ember/component";
4-
import { concat, get } from "@ember/helper";
4+
import { concat, fn, get } from "@ember/helper";
55
import { on } from "@ember/modifier";
66
import { action, computed } from "@ember/object";
77
import didInsert from "@ember/render-modifiers/modifiers/did-insert";
@@ -13,6 +13,8 @@ import DButton from "discourse/components/d-button";
1313
import icon from "discourse/helpers/d-icon";
1414
import { popupAjaxError } from "discourse/lib/ajax-error";
1515
import { i18n } from "discourse-i18n";
16+
import AdminSectionLandingItem from "admin/components/admin-section-landing-item";
17+
import AdminSectionLandingWrapper from "admin/components/admin-section-landing-wrapper";
1618
import ComboBox from "select-kit/components/combo-box";
1719
import DTooltip from "float-kit/components/d-tooltip";
1820
import not from "truth-helpers/helpers/not";
@@ -48,7 +50,19 @@ export default class AiEmbeddingEditor extends Component {
4850
};
4951

5052
return this.args.embeddings.resultSetMeta.distance_functions.map((df) => {
51-
return { id: df, name: t(df) };
53+
let iconName;
54+
55+
if (df === "<=>") {
56+
iconName = "discourse-spaceship-operator";
57+
} else if (df === "<#>") {
58+
iconName = "discourse-negative-inner-product";
59+
}
60+
61+
return {
62+
id: df,
63+
name: t(df),
64+
icon: iconName, // Generate the icon helper output
65+
};
5266
});
5367
}
5468

@@ -57,12 +71,14 @@ export default class AiEmbeddingEditor extends Component {
5771
return {
5872
name: preset.display_name,
5973
id: preset.preset_id,
74+
provider: preset.provider,
6075
};
6176
});
6277

63-
presets.pushObject({
78+
presets.unshiftObject({
6479
name: i18n("discourse_ai.embeddings.configure_manually"),
6580
id: "manual",
81+
provider: "fake",
6682
});
6783

6884
return presets;
@@ -90,11 +106,11 @@ export default class AiEmbeddingEditor extends Component {
90106
}
91107

92108
@action
93-
configurePreset() {
109+
configurePreset(preset) {
94110
this.selectedPreset =
95111
this.args.embeddings.resultSetMeta.presets.findBy(
96112
"preset_id",
97-
this.presetId
113+
preset.id
98114
) || {};
99115

100116
this.editingModel = this.store
@@ -185,35 +201,56 @@ export default class AiEmbeddingEditor extends Component {
185201
});
186202
}
187203

188-
<template>
189-
<BackButton
190-
@route="adminPlugins.show.discourse-ai-embeddings"
191-
@label="discourse_ai.embeddings.back"
192-
/>
204+
@action
205+
resetForm() {
206+
this.selectedPreset = null;
207+
this.editingModel = null;
208+
}
193209

210+
<template>
194211
<form
195212
{{didInsert this.updateModel @model.id}}
196213
{{didUpdate this.updateModel @model.id}}
197214
class="form-horizontal ai-embedding-editor"
198215
>
199216
{{#if this.showPresets}}
217+
<BackButton
218+
@route="adminPlugins.show.discourse-ai-embeddings"
219+
@label="discourse_ai.embeddings.back"
220+
/>
200221
<div class="control-group">
201-
<label>{{i18n "discourse_ai.embeddings.presets"}}</label>
202-
<ComboBox
203-
@value={{this.presetId}}
204-
@content={{this.presets}}
205-
class="ai-embedding-editor__presets"
206-
/>
207-
</div>
222+
<h2>{{i18n "discourse_ai.embeddings.presets"}}</h2>
223+
<AdminSectionLandingWrapper>
224+
{{#each this.presets as |preset|}}
225+
{{log preset}}
226+
<AdminSectionLandingItem
227+
@titleLabelTranslated={{preset.name}}
228+
@taglineLabel={{concat
229+
"discourse_ai.embeddings.providers."
230+
preset.provider
231+
}}
232+
data-preset-id={{preset.id}}
233+
class="ai-llms-list-editor__templates-list-item"
234+
>
235+
<:buttons as |buttons|>
236+
<buttons.Default
237+
@action={{fn this.configurePreset preset}}
238+
@icon="gear"
239+
@label="discourse_ai.llms.preconfigured.button"
240+
/>
241+
</:buttons>
242+
</AdminSectionLandingItem>
243+
244+
{{/each}}
245+
</AdminSectionLandingWrapper>
208246

209-
<div class="control-group ai-llm-editor__action_panel">
210-
<DButton
211-
@action={{this.configurePreset}}
212-
@label="discourse_ai.tools.next.title"
213-
class="ai-embedding-editor__next"
214-
/>
215247
</div>
248+
216249
{{else}}
250+
<div class="btn btn-flat back-button" {{on "click" this.resetForm}}>
251+
{{icon "chevron-left"}}
252+
{{i18n "back_button"}}
253+
</div>
217254
<div class="control-group">
218255
<label>{{i18n "discourse_ai.embeddings.display_name"}}</label>
219256
<Input
@@ -298,14 +335,24 @@ export default class AiEmbeddingEditor extends Component {
298335
<label>{{i18n
299336
"discourse_ai.embeddings.matryoshka_dimensions"
300337
}}</label>
338+
<DTooltip
339+
@icon="circle-question"
340+
@content={{i18n
341+
"discourse_ai.embeddings.hints.matryoshka_dimensions"
342+
}}
343+
/>
301344
</div>
302345

303346
<div class="control-group">
304347
<label>{{i18n "discourse_ai.embeddings.embed_prompt"}}</label>
305348
<Input
306349
@type="text"
307-
class="ai-embedding-editor-input ai-embedding-editor__embed_prompt"
308350
@value={{this.editingModel.embed_prompt}}
351+
class="ai-embedding-editor-input ai-embedding-editor__embed_prompt"
352+
/>
353+
<DTooltip
354+
@icon="circle-question"
355+
@content={{i18n "discourse_ai.embeddings.hints.embed_prompt"}}
309356
/>
310357
</div>
311358

@@ -316,6 +363,10 @@ export default class AiEmbeddingEditor extends Component {
316363
class="ai-embedding-editor-input ai-embedding-editor__search_prompt"
317364
@value={{this.editingModel.search_prompt}}
318365
/>
366+
<DTooltip
367+
@icon="circle-question"
368+
@content={{i18n "discourse_ai.embeddings.hints.search_prompt"}}
369+
/>
319370
</div>
320371

321372
<div class="control-group">
@@ -329,6 +380,10 @@ export default class AiEmbeddingEditor extends Component {
329380
@value={{this.editingModel.max_sequence_length}}
330381
required="true"
331382
/>
383+
<DTooltip
384+
@icon="circle-question"
385+
@content={{i18n "discourse_ai.embeddings.hints.sequence_length"}}
386+
/>
332387
</div>
333388

334389
<div class="control-group">
@@ -338,6 +393,10 @@ export default class AiEmbeddingEditor extends Component {
338393
@content={{this.distanceFunctions}}
339394
@class="ai-embedding-editor__distance_functions"
340395
/>
396+
<DTooltip
397+
@icon="circle-question"
398+
@content={{i18n "discourse_ai.embeddings.hints.distance_function"}}
399+
/>
341400
</div>
342401

343402
{{#each-in this.metaProviderParams as |field type|}}

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,34 @@
2828
display: flex;
2929
align-items: flex-start;
3030
}
31+
32+
&__distance_functions.select-kit {
33+
.selected-name {
34+
.d-icon {
35+
width: 2em;
36+
height: 2em;
37+
position: absolute;
38+
39+
+ .name {
40+
margin-left: 2.25em;
41+
}
42+
}
43+
}
44+
45+
.svg-icon-title {
46+
width: 2em;
47+
top: -0.5em;
48+
49+
svg {
50+
width: 2em;
51+
height: 2em;
52+
}
53+
}
54+
}
55+
}
56+
57+
.discourse-ai-embeddings {
58+
.btn-flat.back-button {
59+
padding-left: 0;
60+
}
3161
}

config/locales/client.en.yml

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -515,14 +515,18 @@ en:
515515
configure_manually: "Configure manually"
516516
edit: "Edit"
517517
seeded_warning: "This is pre-configured on your site and cannot be edited."
518-
tests:
518+
tests:
519519
title: "Run test"
520520
running: "Running test..."
521521
success: "Success!"
522522
failure: "Attempting to generate an embedding resulted in: %{error}"
523523
hints:
524524
dimensions_warning: "Once saved, this value can't be changed."
525-
525+
matryoshka_dimensions: "Defines the size of nested embeddings used for hierarchical or multi-layered representation of data, similar to how nested dolls fit within each other."
526+
embed_prompt: "Explains how to process text to create its numerical summary (embedding) for analysis or comparison."
527+
search_prompt: "Explains how to process a search query to compare it with existing embeddings and find the best matches."
528+
sequence_length: "The maximum number of words or tokens the system can process at once when creating embeddings or handling a query."
529+
distance_function: "Determines how similarity between embeddings is calculated, using either cosine distance (measuring the angle between vectors) or negative inner product (measuring overlap of vector values)."
526530
display_name: "Name"
527531
provider: "Provider"
528532
url: "Embeddings service URL"
@@ -536,18 +540,18 @@ en:
536540

537541
distance_function: "Distance function"
538542
distance_functions:
539-
<#>: "Negative inner product (<#>)"
540-
<=>: "Cosine distance (<=>)"
543+
<#>: "Negative inner product"
544+
<=>: "Cosine distance"
541545
providers:
542546
hugging_face: "Hugging Face"
543547
open_ai: "OpenAI"
544548
google: "Google"
545549
cloudflare: "Cloudflare"
546550
CDCK: "CDCK"
551+
fake: "Custom"
547552
provider_fields:
548553
model_name: "Model name"
549554

550-
551555
semantic_search: "Topics (Semantic)"
552556
semantic_search_loading: "Searching for more results using AI"
553557
semantic_search_results:

svg-icons/icons-sprite.svg

Lines changed: 11 additions & 1 deletion
Loading

0 commit comments

Comments
 (0)