UX: QoL impromevements to the admin LLM models page. (#674)
API Key value is secret by default, and we include a link to the AI bot user.
This commit is contained in:
parent
c4d9fab8e7
commit
ed3d5521a8
|
@ -14,6 +14,8 @@ class LlmModelSerializer < ApplicationSerializer
|
||||||
:enabled_chat_bot,
|
:enabled_chat_bot,
|
||||||
:url_editable
|
:url_editable
|
||||||
|
|
||||||
|
has_one :user, serializer: BasicUserSerializer, embed: :object
|
||||||
|
|
||||||
def url_editable
|
def url_editable
|
||||||
object.url != LlmModel::RESERVED_VLLM_SRV_URL
|
object.url != LlmModel::RESERVED_VLLM_SRV_URL
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,15 +3,18 @@ import { tracked } from "@glimmer/tracking";
|
||||||
import { Input } from "@ember/component";
|
import { Input } from "@ember/component";
|
||||||
import { on } from "@ember/modifier";
|
import { on } from "@ember/modifier";
|
||||||
import { action } from "@ember/object";
|
import { action } from "@ember/object";
|
||||||
|
import { LinkTo } from "@ember/routing";
|
||||||
import { later } from "@ember/runloop";
|
import { later } from "@ember/runloop";
|
||||||
import { inject as service } from "@ember/service";
|
import { inject as service } from "@ember/service";
|
||||||
import BackButton from "discourse/components/back-button";
|
import BackButton from "discourse/components/back-button";
|
||||||
import DButton from "discourse/components/d-button";
|
import DButton from "discourse/components/d-button";
|
||||||
import DToggleSwitch from "discourse/components/d-toggle-switch";
|
import DToggleSwitch from "discourse/components/d-toggle-switch";
|
||||||
|
import Avatar from "discourse/helpers/bound-avatar-template";
|
||||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||||
import icon from "discourse-common/helpers/d-icon";
|
import icon from "discourse-common/helpers/d-icon";
|
||||||
import i18n from "discourse-common/helpers/i18n";
|
import i18n from "discourse-common/helpers/i18n";
|
||||||
import I18n from "discourse-i18n";
|
import I18n from "discourse-i18n";
|
||||||
|
import AdminUser from "admin/models/admin-user";
|
||||||
import ComboBox from "select-kit/components/combo-box";
|
import ComboBox from "select-kit/components/combo-box";
|
||||||
import DTooltip from "float-kit/components/d-tooltip";
|
import DTooltip from "float-kit/components/d-tooltip";
|
||||||
|
|
||||||
|
@ -25,6 +28,7 @@ export default class AiLlmEditor extends Component {
|
||||||
@tracked testRunning = false;
|
@tracked testRunning = false;
|
||||||
@tracked testResult = null;
|
@tracked testResult = null;
|
||||||
@tracked testError = null;
|
@tracked testError = null;
|
||||||
|
@tracked apiKeySecret = true;
|
||||||
|
|
||||||
get selectedProviders() {
|
get selectedProviders() {
|
||||||
const t = (provName) => {
|
const t = (provName) => {
|
||||||
|
@ -36,6 +40,10 @@ export default class AiLlmEditor extends Component {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get adminUser() {
|
||||||
|
return AdminUser.create(this.args.model?.user);
|
||||||
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async save() {
|
async save() {
|
||||||
this.isSaving = true;
|
this.isSaving = true;
|
||||||
|
@ -94,6 +102,16 @@ export default class AiLlmEditor extends Component {
|
||||||
return this.testRunning || this.testResult !== null;
|
return this.testRunning || this.testResult !== null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
makeApiKeySecret() {
|
||||||
|
this.apiKeySecret = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
toggleApiKeySecret() {
|
||||||
|
this.apiKeySecret = !this.apiKeySecret;
|
||||||
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
delete() {
|
delete() {
|
||||||
return this.dialog.confirm({
|
return this.dialog.confirm({
|
||||||
|
@ -177,11 +195,19 @@ export default class AiLlmEditor extends Component {
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<label>{{I18n.t "discourse_ai.llms.api_key"}}</label>
|
<label>{{I18n.t "discourse_ai.llms.api_key"}}</label>
|
||||||
<Input
|
<div class="ai-llm-editor__secret-api-key-group">
|
||||||
class="ai-llm-editor-input ai-llm-editor__api-key"
|
<Input
|
||||||
@type="text"
|
@value={{@model.api_key}}
|
||||||
@value={{@model.api_key}}
|
class="ai-llm-editor-input ai-llm-editor__api-key"
|
||||||
/>
|
@type={{if this.apiKeySecret "password" "text"}}
|
||||||
|
{{on "focusout" this.makeApiKeySecret}}
|
||||||
|
/>
|
||||||
|
<DButton
|
||||||
|
@action={{this.toggleApiKeySecret}}
|
||||||
|
@icon="far-eye-slash"
|
||||||
|
{{on "focusout" this.makeApiKeySecret}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<label>{{I18n.t "discourse_ai.llms.tokenizer"}}</label>
|
<label>{{I18n.t "discourse_ai.llms.tokenizer"}}</label>
|
||||||
|
@ -213,6 +239,21 @@ export default class AiLlmEditor extends Component {
|
||||||
{{on "click" this.toggleEnabledChatBot}}
|
{{on "click" this.toggleEnabledChatBot}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
{{#if @model.user}}
|
||||||
|
<div class="control-group">
|
||||||
|
<label>{{i18n "discourse_ai.llms.ai_bot_user"}}</label>
|
||||||
|
<a
|
||||||
|
class="avatar"
|
||||||
|
href={{@model.user.path}}
|
||||||
|
data-user-card={{@model.user.username}}
|
||||||
|
>
|
||||||
|
{{Avatar @model.user.avatar_template "small"}}
|
||||||
|
</a>
|
||||||
|
<LinkTo @route="adminUser" @model={{this.adminUser}}>
|
||||||
|
{{@model.user.username}}
|
||||||
|
</LinkTo>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
<div class="control-group ai-llm-editor__action_panel">
|
<div class="control-group ai-llm-editor__action_panel">
|
||||||
<DButton
|
<DButton
|
||||||
class="ai-llm-editor__test"
|
class="ai-llm-editor__test"
|
||||||
|
|
|
@ -32,4 +32,13 @@
|
||||||
color: var(--success);
|
color: var(--success);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__api-key {
|
||||||
|
margin-right: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__secret-api-key-group {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -211,6 +211,7 @@ en:
|
||||||
url: "URL of the service hosting the model"
|
url: "URL of the service hosting the model"
|
||||||
api_key: "API Key of the service hosting the model"
|
api_key: "API Key of the service hosting the model"
|
||||||
enabled_chat_bot: "Allow AI Bot"
|
enabled_chat_bot: "Allow AI Bot"
|
||||||
|
ai_bot_user: "AI Bot User"
|
||||||
save: "Save"
|
save: "Save"
|
||||||
edit: "Edit"
|
edit: "Edit"
|
||||||
saved: "LLM Model Saved"
|
saved: "LLM Model Saved"
|
||||||
|
|
Loading…
Reference in New Issue