From aeb5d066473f6fbe56a57935442c503cadabc79a Mon Sep 17 00:00:00 2001 From: Samiul Monir <150824886+Samiul-TheSoccerFan@users.noreply.github.com> Date: Tue, 26 Nov 2024 12:01:57 -0500 Subject: [PATCH] [8.x] Remove hardcoded preconfigured ELSER endpoint (#201300) (#201811) # Backport This will backport the following commits from `main` to `8.x`: - [Remove hardcoded preconfigured ELSER endpoint (#201300)](https://github.com/elastic/kibana/pull/201300) ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) --- .../components/search_index/index_error.tsx | 12 +--- .../select_inference_id.test.tsx | 32 +++++++++- .../field_parameters/select_inference_id.tsx | 9 +++ .../semantic_text/use_semantic_text.test.ts | 58 ++++--------------- .../semantic_text/use_semantic_text.ts | 4 -- .../fields/fields_list_item.tsx | 9 +-- .../constants/default_values.ts | 6 -- .../constants/parameters_definition.tsx | 14 +---- .../translations/translations/fr-FR.json | 1 - .../translations/translations/ja-JP.json | 1 - .../translations/translations/zh-CN.json | 1 - 11 files changed, 55 insertions(+), 92 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/index_error.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/index_error.tsx index 1ed3857b2c7ce..9d3daac23111f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/index_error.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/index_error.tsx @@ -31,15 +31,10 @@ export interface IndexErrorProps { } interface SemanticTextProperty extends MappingPropertyBase { - inference_id?: string; + inference_id: string; type: 'semantic_text'; } -/* - This will be repalce once we add default elser inference_id - with the index mapping response. -*/ -const ELSER_PRECONFIGURED_ENDPOINTS = '.elser-2-elasticsearch'; const isInferencePreconfigured = (inferenceId: string) => inferenceId.startsWith('.'); const parseMapping = (mappings: MappingTypeMapping) => { @@ -56,11 +51,6 @@ const getSemanticTextFields = ( ): Array<{ path: string; source: SemanticTextProperty }> => { return Object.entries(fields).flatMap(([key, value]) => { const currentPath: string = path ? `${path}.${key}` : key; - if (value.type === 'semantic_text') { - value = value.inference_id - ? value - : { ...value, inference_id: ELSER_PRECONFIGURED_ENDPOINTS }; - } const currentField: Array<{ path: string; source: SemanticTextProperty }> = value.type === 'semantic_text' ? [{ path: currentPath, source: value }] : []; if (hasProperties(value)) { diff --git a/x-pack/plugins/index_management/__jest__/client_integration/index_details_page/select_inference_id.test.tsx b/x-pack/plugins/index_management/__jest__/client_integration/index_details_page/select_inference_id.test.tsx index 1c9633f829bc3..81272dc1c4c8d 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/index_details_page/select_inference_id.test.tsx +++ b/x-pack/plugins/index_management/__jest__/client_integration/index_details_page/select_inference_id.test.tsx @@ -9,7 +9,7 @@ import { Form, useForm, } from '../../../public/application/components/mappings_editor/shared_imports'; -import { registerTestBed } from '@kbn/test-jest-helpers'; +import { findTestSubject, registerTestBed } from '@kbn/test-jest-helpers'; import { act } from 'react-dom/test-utils'; import { SelectInferenceId, @@ -152,4 +152,34 @@ describe('SelectInferenceId', () => { expect(find('data-inference-endpoint-list').contains('endpoint-2')).toBe(true); expect(find('data-inference-endpoint-list').contains('endpoint-3')).toBe(false); }); + + it('select the first endpoint by default', () => { + find('inferenceIdButton').simulate('click'); + const defaultElser = findTestSubject( + find('data-inference-endpoint-list'), + 'custom-inference_.preconfigured-elser' + ); + expect(defaultElser.prop('aria-checked')).toEqual(true); + }); + + it('does not select the other endpoints by default', () => { + find('inferenceIdButton').simulate('click'); + const defaultE5 = findTestSubject( + find('data-inference-endpoint-list'), + 'custom-inference_.preconfigured-e5' + ); + expect(defaultE5.prop('aria-checked')).toEqual(false); + + const endpoint1 = findTestSubject( + find('data-inference-endpoint-list'), + 'custom-inference_endpoint-1' + ); + expect(endpoint1.prop('aria-checked')).toEqual(false); + + const endpoint2 = findTestSubject( + find('data-inference-endpoint-list'), + 'custom-inference_endpoint-2' + ); + expect(endpoint2.prop('aria-checked')).toEqual(false); + }); }); diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/select_inference_id.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/select_inference_id.tsx index 51cd2b5f14789..813cc1023c06d 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/select_inference_id.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/select_inference_id.tsx @@ -132,6 +132,14 @@ const SelectInferenceIdContent: React.FC = ({ 'data-test-subj': `custom-inference_${endpoint.inference_id}`, checked: value === endpoint.inference_id ? 'on' : undefined, })); + /** + * Adding this check to ensure we have the preconfigured elser endpoint selected by default. + */ + const hasInferenceSelected = newOptions.some((option) => option.checked === 'on'); + if (!hasInferenceSelected && newOptions.length > 0) { + newOptions[0].checked = 'on'; + } + if (value && !newOptions.find((option) => option.label === value)) { // Sometimes we create a new endpoint but the backend is slow in updating so we need to optimistically update const newOption: EuiSelectableOption = { @@ -273,6 +281,7 @@ const SelectInferenceIdContent: React.FC = ({ searchable isLoading={isLoading} singleSelection="always" + defaultChecked searchProps={{ compressed: true, placeholder: i18n.translate( diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/semantic_text/use_semantic_text.test.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/semantic_text/use_semantic_text.test.ts index 15537b0335e0a..e0ce2db2446ee 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/semantic_text/use_semantic_text.test.ts +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/semantic_text/use_semantic_text.test.ts @@ -13,15 +13,15 @@ import { act } from 'react-dom/test-utils'; jest.mock('../../../../../../../../hooks/use_details_page_mappings_model_management', () => ({ useDetailsPageMappingsModelManagement: () => ({ fetchInferenceToModelIdMap: () => ({ - e5: { + '.preconfigured_elser': { isDeployed: false, isDeployable: true, - trainedModelId: '.multilingual-e5-small', + trainedModelId: '.elser_model_2', }, - elser_model_2: { + '.preconfigured_e5': { isDeployed: false, isDeployable: true, - trainedModelId: '.elser_model_2', + trainedModelId: '.multilingual-e5-small', }, openai: { isDeployed: false, @@ -49,13 +49,13 @@ const mockField: Record = { elser_model_2: { name: 'name', type: 'semantic_text', - inference_id: 'elser_model_2', + inference_id: '.preconfigured_elser', reference_field: 'title', }, e5: { name: 'name', type: 'semantic_text', - inference_id: 'e5', + inference_id: '.preconfigured_e5', reference_field: 'title', }, openai: { @@ -100,15 +100,15 @@ const mockDispatch = jest.fn(); jest.mock('../../../../../mappings_state_context', () => ({ useMappingsState: jest.fn().mockReturnValue({ inferenceToModelIdMap: { - e5: { + '.preconfigured_elser': { isDeployed: false, isDeployable: true, - trainedModelId: '.multilingual-e5-small', + trainedModelId: '.elser_model_2', }, - elser_model_2: { + '.preconfigured_e5': { isDeployed: false, isDeployable: true, - trainedModelId: '.elser_model_2', + trainedModelId: '.multilingual-e5-small', }, openai: { isDeployed: false, @@ -142,7 +142,7 @@ jest.mock('../../../../../../../services/api', () => ({ getInferenceEndpoints: jest.fn().mockResolvedValue({ data: [ { - inference_id: 'e5', + inference_id: '.preconfigured_e5', task_type: 'text_embedding', service: 'elasticsearch', service_settings: { @@ -212,28 +212,6 @@ describe('useSemanticText', () => { mockConfig.openai.modelConfig ); }); - it('should handle semantic text with inference endpoint created from flyout correctly', async () => { - const { result } = renderHook(() => - useSemanticText({ - form: mockForm.elasticModelEndpointCreatedfromFlyout, - setErrorsInTrainedModelDeployment: jest.fn(), - ml: mlMock, - }) - ); - await act(async () => { - result.current.handleSemanticText(mockField.my_elser_endpoint, mockConfig.elser); - }); - - expect(mockDispatch).toHaveBeenCalledWith({ - type: 'field.add', - value: mockField.my_elser_endpoint, - }); - expect(mlMock.mlApi.inferenceModels.createInferenceEndpoint).toHaveBeenCalledWith( - 'my_elser_endpoint', - 'sparse_embedding', - mockConfig.elser.modelConfig - ); - }); it('should handle semantic text correctly', async () => { const { result } = renderHook(() => @@ -252,20 +230,6 @@ describe('useSemanticText', () => { type: 'field.add', value: mockField.elser_model_2, }); - expect(mlMock.mlApi.inferenceModels.createInferenceEndpoint).toHaveBeenCalledWith( - 'elser_model_2', - 'sparse_embedding', - { - service: 'elser', - service_settings: { - adaptive_allocations: { - enabled: true, - }, - num_threads: 1, - model_id: '.elser_model_2', - }, - } - ); }); it('does not call create inference endpoint api, if default endpoint already exists', async () => { const { result } = renderHook(() => diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/semantic_text/use_semantic_text.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/semantic_text/use_semantic_text.ts index a464a279a8ddf..a7b380fd120cd 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/semantic_text/use_semantic_text.ts +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/semantic_text/use_semantic_text.ts @@ -19,7 +19,6 @@ import { useMLModelNotificationToasts } from '../../../../../../../../hooks/use_ import { getInferenceEndpoints } from '../../../../../../../services/api'; import { getFieldByPathName } from '../../../../../lib/utils'; -import { ELSER_PRECONFIGURED_ENDPOINTS } from '../../../../../constants'; interface UseSemanticTextProps { form: FormHook; @@ -63,9 +62,6 @@ export function useSemanticText(props: UseSemanticTextProps) { if (!form.getFormData().reference_field) { form.setFieldValue('reference_field', referenceField); } - if (!form.getFormData().inference_id) { - form.setFieldValue('inference_id', ELSER_PRECONFIGURED_ENDPOINTS); - } } // eslint-disable-next-line react-hooks/exhaustive-deps }, [fieldTypeValue]); diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/fields_list_item.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/fields_list_item.tsx index a67a7df0acb7b..33c51a3cb644b 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/fields_list_item.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/fields_list_item.tsx @@ -19,11 +19,7 @@ import { i18n } from '@kbn/i18n'; import { NormalizedField, NormalizedFields, State } from '../../../types'; import { getTypeLabelFromField } from '../../../lib'; -import { - CHILD_FIELD_INDENT_SIZE, - ELSER_PRECONFIGURED_ENDPOINTS, - LEFT_PADDING_SIZE_FIELD_ITEM_WRAPPER, -} from '../../../constants'; +import { CHILD_FIELD_INDENT_SIZE, LEFT_PADDING_SIZE_FIELD_ITEM_WRAPPER } from '../../../constants'; import { FieldsList } from './fields_list'; import { CreateField } from './create_field'; @@ -109,7 +105,6 @@ function FieldListItemComponent( const indent = treeDepth * CHILD_FIELD_INDENT_SIZE - substractIndentAmount; const isSemanticText = source.type === 'semantic_text'; - const inferenceId: string = (source.inference_id as string) ?? ELSER_PRECONFIGURED_ENDPOINTS; const indentCreateField = (treeDepth + 1) * CHILD_FIELD_INDENT_SIZE + @@ -298,7 +293,7 @@ function FieldListItemComponent( {isSemanticText && ( - {inferenceId} + {source.inference_id as string} )} diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/constants/default_values.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/constants/default_values.ts index f8c6da8f7cddb..b839caf75b242 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/constants/default_values.ts +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/constants/default_values.ts @@ -13,9 +13,3 @@ export const INDEX_DEFAULT = 'index_default'; export const STANDARD = 'standard'; - -/* - This will be repalce once we add default elser inference_id - with the index mapping response. -*/ -export const ELSER_PRECONFIGURED_ENDPOINTS = '.elser-2-elasticsearch'; diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/constants/parameters_definition.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/constants/parameters_definition.tsx index 7e10c5d5deaa7..749150cf2d671 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/constants/parameters_definition.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/constants/parameters_definition.tsx @@ -1126,22 +1126,10 @@ export const PARAMETERS_DEFINITION: { [key in ParameterName]: ParameterDefinitio }, inference_id: { fieldConfig: { - defaultValue: 'elser_model_2', + defaultValue: '', label: i18n.translate('xpack.idxMgmt.mappingsEditor.parameters.inferenceIdLabel', { defaultMessage: 'Select an inference endpoint:', }), - validations: [ - { - validator: emptyField( - i18n.translate( - 'xpack.idxMgmt.mappingsEditor.parameters.validations.inferenceIdIsRequiredErrorMessage', - { - defaultMessage: 'Inference ID is required.', - } - ) - ), - }, - ], }, schema: t.string, }, diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index fe5b0c48647c6..e6436557061ec 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -23331,7 +23331,6 @@ "xpack.idxMgmt.mappingsEditor.parameters.validations.fieldDataFrequency.numberGreaterThanOneErrorMessage": "La valeur doit être supérieure à un.", "xpack.idxMgmt.mappingsEditor.parameters.validations.greaterThanZeroErrorMessage": "Le facteur de montée en charge doit être supérieur à 0.", "xpack.idxMgmt.mappingsEditor.parameters.validations.ignoreAboveIsRequiredErrorMessage": "Limite de longueur de caractère obligatoire.", - "xpack.idxMgmt.mappingsEditor.parameters.validations.inferenceIdIsRequiredErrorMessage": "L’ID d’inférence est requis.", "xpack.idxMgmt.mappingsEditor.parameters.validations.localeFieldRequiredErrorMessage": "Spécifiez un paramètre régional.", "xpack.idxMgmt.mappingsEditor.parameters.validations.maxInputLengthFieldRequiredErrorMessage": "Spécifiez une longueur d'entrée maximale.", "xpack.idxMgmt.mappingsEditor.parameters.validations.nameIsRequiredErrorMessage": "Donnez un nom au champ.", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 551c0f80c2bf8..ec09a444ee64c 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -23303,7 +23303,6 @@ "xpack.idxMgmt.mappingsEditor.parameters.validations.fieldDataFrequency.numberGreaterThanOneErrorMessage": "値は1よりも大きい値でなければなりません。", "xpack.idxMgmt.mappingsEditor.parameters.validations.greaterThanZeroErrorMessage": "スケーリングファクターは0よりも大きくなくてはなりません。", "xpack.idxMgmt.mappingsEditor.parameters.validations.ignoreAboveIsRequiredErrorMessage": "文字数制限が必要です。", - "xpack.idxMgmt.mappingsEditor.parameters.validations.inferenceIdIsRequiredErrorMessage": "推論IDは必須です。", "xpack.idxMgmt.mappingsEditor.parameters.validations.localeFieldRequiredErrorMessage": "ロケールを指定します。", "xpack.idxMgmt.mappingsEditor.parameters.validations.maxInputLengthFieldRequiredErrorMessage": "最大入力長さを指定します。", "xpack.idxMgmt.mappingsEditor.parameters.validations.nameIsRequiredErrorMessage": "フィールドに名前を付けます。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 97e6034089571..306686b8c2f71 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -23355,7 +23355,6 @@ "xpack.idxMgmt.mappingsEditor.parameters.validations.fieldDataFrequency.numberGreaterThanOneErrorMessage": "值必须大于 1。", "xpack.idxMgmt.mappingsEditor.parameters.validations.greaterThanZeroErrorMessage": "缩放因数必须大于 0。", "xpack.idxMgmt.mappingsEditor.parameters.validations.ignoreAboveIsRequiredErrorMessage": "字符长度限制必填。", - "xpack.idxMgmt.mappingsEditor.parameters.validations.inferenceIdIsRequiredErrorMessage": "“推理 ID”必填。", "xpack.idxMgmt.mappingsEditor.parameters.validations.localeFieldRequiredErrorMessage": "指定区域设置。", "xpack.idxMgmt.mappingsEditor.parameters.validations.maxInputLengthFieldRequiredErrorMessage": "指定最大输入长度。", "xpack.idxMgmt.mappingsEditor.parameters.validations.nameIsRequiredErrorMessage": "为字段提供名称。",