Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Enterprise Search] Support for starting ELSER model deployment #156080

Merged
merged 19 commits into from
May 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { ELSER_MODEL_ID } from '../../../../../../common/ml_inference_pipeline';
import { Actions, createApiLogic } from '../../../../shared/api_logic/create_api_logic';
import { HttpLogic } from '../../../../shared/http';

export type StartTextExpansionModelArgs = undefined;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick(non-blocking): Best practice is to specify an empty object rather than undefined.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, this is breaking the type checks:

/var/lib/buildkite-agent/builds/kb-n2-2-spot-a440796eab9fe2c4/elastic/kibana-pull-request/kibana/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/ml_models/text_expansion/create_text_expansion_model_api_logic.ts
--
  | 2023-04-28 11:19:48 EDT | 11:18  error  An empty interface is equivalent to `{}`  @typescript-eslint/no-empty-interface

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sphilipse I reverted to undefined because I couldn't find a way to fix the CI error.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, what you want to do instead is use {} wherever you're using StartTextExpansionModelArgs. But this is a nitpick anyway.


export interface StartTextExpansionModelResponse {
deploymentState: string;
modelId: string;
}

export const startTextExpansionModel = async (): Promise<StartTextExpansionModelResponse> => {
const route = `/internal/enterprise_search/ml/models/${ELSER_MODEL_ID}/deploy`;
return await HttpLogic.values.http.post<StartTextExpansionModelResponse>(route, {
body: undefined,
});
};

export const StartTextExpansionModelApiLogic = createApiLogic(
['start_text_expansion_model_api_logic'],
startTextExpansionModel
);

export type StartTextExpansionModelApiLogicActions = Actions<
StartTextExpansionModelArgs,
StartTextExpansionModelResponse
>;
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,12 @@ export const InferencePipelineCard: React.FC<InferencePipeline> = (pipeline) =>
)}
>
<EuiButtonIcon
aria-label={i18n.translate(
'xpack.enterpriseSearch.inferencePipelineCard.modelState.notDeployed.fixLink',
{
defaultMessage: 'Fix issue in Trained Models',
}
)}
data-telemetry-id={`entSearchContent-${ingestionMethod}-pipelines-inferencePipeline-fixIssueInTrainedModels`}
href={http.basePath.prepend(ML_MANAGE_TRAINED_MODELS_PATH)}
display="base"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ import {
ModelDeploymentInProgress,
ModelDeployed,
TextExpansionDismissButton,
ModelStarted,
} from './text_expansion_callout';

jest.mock('./text_expansion_callout_data', () => ({
useTextExpansionCallOutData: jest.fn(() => ({
dismiss: jest.fn(),
isCreateButtonDisabled: false,
isDismissable: false,
isStartButtonDisabled: false,
show: true,
})),
}));
Expand All @@ -34,6 +36,8 @@ const DEFAULT_VALUES = {
isCreateButtonDisabled: false,
isModelDownloadInProgress: false,
isModelDownloaded: false,
isModelStarted: false,
isStartButtonDisabled: false,
};

describe('TextExpansionCallOut', () => {
Expand Down Expand Up @@ -63,6 +67,15 @@ describe('TextExpansionCallOut', () => {
const wrapper = shallow(<TextExpansionCallOut />);
expect(wrapper.find(ModelDeployed).length).toBe(1);
});
it('renders panel with deployment in progress status if the model has been started', () => {
setMockValues({
...DEFAULT_VALUES,
isModelStarted: true,
});

const wrapper = shallow(<TextExpansionCallOut />);
expect(wrapper.find(ModelStarted).length).toBe(1);
});

describe('DeployModel', () => {
it('renders deploy button', () => {
Expand Down Expand Up @@ -109,12 +122,43 @@ describe('TextExpansionCallOut', () => {
});

describe('ModelDeployed', () => {
it('renders start button', () => {
const wrapper = shallow(
<ModelDeployed dismiss={() => {}} isDismissable={false} isStartButtonDisabled={false} />
);
expect(wrapper.find(EuiButton).length).toBe(1);
const button = wrapper.find(EuiButton);
expect(button.prop('disabled')).toBe(false);
});
it('renders disabled start button if it is set to disabled', () => {
const wrapper = shallow(
<ModelDeployed dismiss={() => {}} isDismissable={false} isStartButtonDisabled />
);
expect(wrapper.find(EuiButton).length).toBe(1);
const button = wrapper.find(EuiButton);
expect(button.prop('disabled')).toBe(true);
});
it('renders dismiss button if it is set to dismissable', () => {
const wrapper = shallow(
<ModelDeployed dismiss={() => {}} isDismissable isStartButtonDisabled={false} />
);
expect(wrapper.find(TextExpansionDismissButton).length).toBe(1);
});
it('does not render dismiss button if it is set to non-dismissable', () => {
const wrapper = shallow(
<ModelDeployed dismiss={() => {}} isDismissable={false} isStartButtonDisabled={false} />
);
expect(wrapper.find(TextExpansionDismissButton).length).toBe(0);
});
});

describe('ModelStarted', () => {
it('renders dismiss button if it is set to dismissable', () => {
const wrapper = shallow(<ModelDeployed dismiss={() => {}} isDismissable />);
const wrapper = shallow(<ModelStarted dismiss={() => {}} isDismissable />);
expect(wrapper.find(TextExpansionDismissButton).length).toBe(1);
});
it('does not render dismiss button if it is set to non-dismissable', () => {
const wrapper = shallow(<ModelDeployed dismiss={() => {}} isDismissable={false} />);
const wrapper = shallow(<ModelStarted dismiss={() => {}} isDismissable={false} />);
expect(wrapper.find(TextExpansionDismissButton).length).toBe(0);
});
});
Expand Down
Loading