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 0000000000000000000000000000000000000000..fb18c1fbdec604ca14ad51d06dbf4929ff70c3a3 --- /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 0000000000000000000000000000000000000000..e6f0e8284fc64d719de3bd838aa2a6808bf46c9c --- /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 0000000000000000000000000000000000000000..62b85bcbeb23b4bddf44b5360def0b701b2feb9c --- /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 e9ec43849e0dc580574e08cd8b07c323a2a83976..949a5422b0c4088c0fc2857be2ad3f9d8a32c930 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 f2c81b39806bff2f990fdad79c042b2b3b898c2e..740226620b4de2125385b7384022a9b58c24950d 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 0000000000000000000000000000000000000000..c9a506bb01ac4f8341b881ed40930220c451c117 --- /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 9fd674b6547f45e00d4a2ed157e6f6b1b97c3246..aafbd38dca6567c1df4c9a062acd5f15a5c2983b 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 ""