From e0e679e7a3176f3a76c7739cb0994333b725effd Mon Sep 17 00:00:00 2001 From: Julie Huang <julhuang@gitlab.com> Date: Fri, 26 Jul 2024 15:44:10 +0000 Subject: [PATCH] Initialise NewSelfHostedModel Vue app - Adds graphql mutation definition - Initialises NewSelfHostedModel vue app if FF is enabled - Adds heading and description to page, but does not include form content --- .../components/new_self_hosted_model.vue | 42 +++++++++++++++++++ .../create_self_hosted_model.mutation.graphql | 5 +++ .../admin/ai/self_hosted_models/new/index.js | 4 ++ .../admin/ai/self_hosted_models/new.html.haml | 13 ++++-- .../admin/ai/self_hosted_models/mock_data.js | 8 ++++ .../new_self_hosted_model_spec.js | 30 +++++++++++++ locale/gitlab.pot | 6 +++ 7 files changed, 104 insertions(+), 4 deletions(-) create mode 100644 ee/app/assets/javascripts/pages/admin/ai/self_hosted_models/components/new_self_hosted_model.vue create mode 100644 ee/app/assets/javascripts/pages/admin/ai/self_hosted_models/graphql/mutations/create_self_hosted_model.mutation.graphql create mode 100644 ee/app/assets/javascripts/pages/admin/ai/self_hosted_models/new/index.js create mode 100644 ee/spec/frontend/pages/admin/ai/self_hosted_models/new_self_hosted_model_spec.js diff --git a/ee/app/assets/javascripts/pages/admin/ai/self_hosted_models/components/new_self_hosted_model.vue b/ee/app/assets/javascripts/pages/admin/ai/self_hosted_models/components/new_self_hosted_model.vue new file mode 100644 index 0000000000000..fb18c1fbdec60 --- /dev/null +++ b/ee/app/assets/javascripts/pages/admin/ai/self_hosted_models/components/new_self_hosted_model.vue @@ -0,0 +1,42 @@ +<script> +import { s__ } from '~/locale'; +import selfHostedModelCreateMutation from '../graphql/mutations/create_self_hosted_model.mutation.graphql'; + +const MUTATION_NAME = 'aiSelfHostedModelCreate'; + +export default { + name: 'NewSelfHostedModel', + props: { + basePath: { + type: String, + required: true, + }, + modelOptions: { + type: Array, + required: true, + }, + }, + i18n: { + title: s__('AdminSelfHostedModels|Add self-hosted models'), + description: s__( + 'AdminSelfHostedModels|Add a new AI model that can be used for GitLab Duo features.', + ), + }, + mutationData: { + name: MUTATION_NAME, + mutation: selfHostedModelCreateMutation, + }, +}; +</script> +<template> + <div> + <h1>{{ $options.i18n.title }}</h1> + <p class="gl-pt-3 gl-pb-2"> + {{ $options.i18n.description }} + </p> + <!-- + TODO: Add form for creating self hosted model. + The form will be passed props basePath, modelOptions and mutationData. + --> + </div> +</template> diff --git a/ee/app/assets/javascripts/pages/admin/ai/self_hosted_models/graphql/mutations/create_self_hosted_model.mutation.graphql b/ee/app/assets/javascripts/pages/admin/ai/self_hosted_models/graphql/mutations/create_self_hosted_model.mutation.graphql new file mode 100644 index 0000000000000..e6f0e8284fc64 --- /dev/null +++ b/ee/app/assets/javascripts/pages/admin/ai/self_hosted_models/graphql/mutations/create_self_hosted_model.mutation.graphql @@ -0,0 +1,5 @@ +mutation createSelfHostedModel($input: AiSelfHostedModelCreateInput!) { + aiSelfHostedModelCreate(input: $input) { + errors + } +} diff --git a/ee/app/assets/javascripts/pages/admin/ai/self_hosted_models/new/index.js b/ee/app/assets/javascripts/pages/admin/ai/self_hosted_models/new/index.js new file mode 100644 index 0000000000000..62b85bcbeb23b --- /dev/null +++ b/ee/app/assets/javascripts/pages/admin/ai/self_hosted_models/new/index.js @@ -0,0 +1,4 @@ +import { initSimpleApp } from '~/helpers/init_simple_app_helper'; +import NewSelfHostedModel from '../components/new_self_hosted_model.vue'; + +initSimpleApp('#js-new-self-hosted-model', NewSelfHostedModel, { withApolloProvider: true }); diff --git a/ee/app/views/admin/ai/self_hosted_models/new.html.haml b/ee/app/views/admin/ai/self_hosted_models/new.html.haml index e9ec43849e0dc..949a5422b0c40 100644 --- a/ee/app/views/admin/ai/self_hosted_models/new.html.haml +++ b/ee/app/views/admin/ai/self_hosted_models/new.html.haml @@ -1,4 +1,9 @@ -- page_title s_('AdminSelfHostedModels|New self-hosted model') -%h1.page-title.gl-font-size-h-display - = s_('AdminSelfHostedModels|New self-hosted model') -= render 'form', url: admin_ai_self_hosted_models_path, back_path: admin_ai_self_hosted_models_path +- page_title s_('AdminSelfHostedModels|Add self-hosted models') +- if Feature.enabled?(:custom_models_vue_app, current_user) + - model_options = Ai::SelfHostedModel.models.map { |name, _| { modelValue: name.upcase, modelName: name.capitalize } } + + #js-new-self-hosted-model{ data: { view_model: { basePath: admin_ai_self_hosted_models_path, modelOptions: model_options }.to_json } } +- else + %h1.page-title.gl-text-size-h-display + = s_('AdminSelfHostedModels|Add self-hosted models') + = render 'form', url: admin_ai_self_hosted_models_path, back_path: admin_ai_self_hosted_models_path diff --git a/ee/spec/frontend/pages/admin/ai/self_hosted_models/mock_data.js b/ee/spec/frontend/pages/admin/ai/self_hosted_models/mock_data.js index f2c81b39806bf..740226620b4de 100644 --- a/ee/spec/frontend/pages/admin/ai/self_hosted_models/mock_data.js +++ b/ee/spec/frontend/pages/admin/ai/self_hosted_models/mock_data.js @@ -30,3 +30,11 @@ export const mockAiSelfHostedModelsQueryResponse = { }, }, }; + +export const SELF_HOSTED_MODEL_OPTIONS = [ + { modelValue: 'MIXTRAL', modelName: 'Mixtral' }, + { modelValue: 'MISTRAL', modelName: 'Mistral' }, + { modelValue: 'CODEGEMMA', modelName: 'Codegemma' }, + { modelValue: 'CODESTRAL', modelName: 'Codestral' }, + { modelValue: 'CODELLAMA', modelName: 'Codellama' }, +]; diff --git a/ee/spec/frontend/pages/admin/ai/self_hosted_models/new_self_hosted_model_spec.js b/ee/spec/frontend/pages/admin/ai/self_hosted_models/new_self_hosted_model_spec.js new file mode 100644 index 0000000000000..c9a506bb01ac4 --- /dev/null +++ b/ee/spec/frontend/pages/admin/ai/self_hosted_models/new_self_hosted_model_spec.js @@ -0,0 +1,30 @@ +import { mountExtended } from 'helpers/vue_test_utils_helper'; +import NewSelfHostedModel from 'ee/pages/admin/ai/self_hosted_models/components/new_self_hosted_model.vue'; +import { SELF_HOSTED_MODEL_OPTIONS } from './mock_data'; + +describe('NewSelfHostedModel', () => { + let wrapper; + + const basePath = '/admin/ai/self_hosted_models'; + + const createComponent = () => { + wrapper = mountExtended(NewSelfHostedModel, { + propsData: { + basePath, + modelOptions: SELF_HOSTED_MODEL_OPTIONS, + }, + }); + }; + + beforeEach(() => { + createComponent(); + }); + + it('has a title', () => { + expect(wrapper.text()).toMatch('Add self-hosted models'); + }); + + it('has a description', () => { + expect(wrapper.text()).toMatch('Add a new AI model that can be used for GitLab Duo features.'); + }); +}); diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 061390a3cb11e..fe0826fcd7c5d 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -3729,9 +3729,15 @@ msgstr "" msgid "AdminSelfHostedModels|API token (if needed)" msgstr "" +msgid "AdminSelfHostedModels|Add a new AI model that can be used for GitLab Duo features." +msgstr "" + msgid "AdminSelfHostedModels|Add self-hosted language models to use as backups for GitLab Duo features." msgstr "" +msgid "AdminSelfHostedModels|Add self-hosted models" +msgstr "" + msgid "AdminSelfHostedModels|An API key is set" msgstr "" -- GitLab