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

[8.18] [Security Assistant] Fix use default inference endpoint (#212191) #213182

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 0 additions & 4 deletions oas_docs/output/kibana.serverless.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36273,14 +36273,10 @@ paths:
properties:
elser_exists:
type: boolean
index_exists:
type: boolean
is_setup_available:
type: boolean
is_setup_in_progress:
type: boolean
pipeline_exists:
type: boolean
product_documentation_status:
type: string
security_labs_exists:
Expand Down
4 changes: 0 additions & 4 deletions oas_docs/output/kibana.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20366,14 +20366,10 @@ paths:
properties:
elser_exists:
type: boolean
index_exists:
type: boolean
is_setup_available:
type: boolean
is_setup_in_progress:
type: boolean
pipeline_exists:
type: boolean
product_documentation_status:
type: string
security_labs_exists:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -437,14 +437,10 @@ paths:
properties:
elser_exists:
type: boolean
index_exists:
type: boolean
is_setup_available:
type: boolean
is_setup_in_progress:
type: boolean
pipeline_exists:
type: boolean
product_documentation_status:
type: string
security_labs_exists:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -437,14 +437,10 @@ paths:
properties:
elser_exists:
type: boolean
index_exists:
type: boolean
is_setup_available:
type: boolean
is_setup_in_progress:
type: boolean
pipeline_exists:
type: boolean
product_documentation_status:
type: string
security_labs_exists:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,8 @@ export type ReadKnowledgeBaseRequestParamsInput = z.input<typeof ReadKnowledgeBa
export type ReadKnowledgeBaseResponse = z.infer<typeof ReadKnowledgeBaseResponse>;
export const ReadKnowledgeBaseResponse = z.object({
elser_exists: z.boolean().optional(),
index_exists: z.boolean().optional(),
is_setup_available: z.boolean().optional(),
is_setup_in_progress: z.boolean().optional(),
pipeline_exists: z.boolean().optional(),
security_labs_exists: z.boolean().optional(),
user_data_exists: z.boolean().optional(),
product_documentation_status: z.string().optional(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,10 @@ paths:
properties:
elser_exists:
type: boolean
index_exists:
type: boolean
is_setup_available:
type: boolean
is_setup_in_progress:
type: boolean
pipeline_exists:
type: boolean
security_labs_exists:
type: boolean
user_data_exists:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ jest.mock('@tanstack/react-query', () => ({

const statusResponse = {
elser_exists: true,
index_exists: true,
pipeline_exists: true,
security_labs_exists: true,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,6 @@ export const useInvalidateKnowledgeBaseStatus = () => {
*/
export const isKnowledgeBaseSetup = (kbStatus: ReadKnowledgeBaseResponse | undefined): boolean =>
(kbStatus?.elser_exists &&
kbStatus?.index_exists &&
kbStatus?.pipeline_exists &&
// Allows to use UI while importing Security Labs docs
(kbStatus?.security_labs_exists ||
kbStatus?.is_setup_in_progress ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,7 @@ export const useChatSend = ({
const { isLoading, sendMessage, abortStream } = useSendMessage();
const { clearConversation, removeLastMessage } = useConversation();
const { data: kbStatus } = useKnowledgeBaseStatus({ http, enabled: isAssistantEnabled });
const isSetupComplete =
kbStatus?.elser_exists &&
kbStatus?.index_exists &&
kbStatus?.pipeline_exists &&
kbStatus?.security_labs_exists;
const isSetupComplete = kbStatus?.elser_exists && kbStatus?.security_labs_exists;

// Handles sending latest user prompt to API
const handleSendMessage = useCallback(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,6 @@ jest.mock('../assistant/api/knowledge_base/use_knowledge_base_status', () => ({
return {
data: {
elser_exists: true,
index_exists: true,
pipeline_exists: true,
},
isLoading: false,
isFetching: false,
Expand All @@ -88,8 +86,6 @@ describe('Knowledge base settings', () => {
return {
data: {
elser_exists: true,
index_exists: false,
pipeline_exists: false,
is_setup_available: true,
},
isLoading: false,
Expand All @@ -111,8 +107,6 @@ describe('Knowledge base settings', () => {
return {
data: {
elser_exists: false,
index_exists: false,
pipeline_exists: false,
},
isLoading: false,
isFetching: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,7 @@ export const KnowledgeBaseSettings: React.FC<Props> = React.memo(
const isElserEnabled = kbStatus?.elser_exists ?? false;
const isSecurityLabsEnabled = kbStatus?.security_labs_exists ?? false;
const isKnowledgeBaseSetup =
(isElserEnabled &&
kbStatus?.index_exists &&
kbStatus?.pipeline_exists &&
(isSecurityLabsEnabled || kbStatus?.user_data_exists)) ??
false;
(isElserEnabled && (isSecurityLabsEnabled || kbStatus?.user_data_exists)) ?? false;
const isSetupInProgress = kbStatus?.is_setup_in_progress ?? false;
const isSetupAvailable = kbStatus?.is_setup_available ?? false;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export const DocumentEntryEditor: React.FC<Props> = React.memo(
setEntry((prevEntry) => ({
...prevEntry,
users: value === i18n.SHARING_GLOBAL_OPTION_LABEL ? [] : privateUsers,
global: value === i18n.SHARING_GLOBAL_OPTION_LABEL ? true : false,
})),
[privateUsers, setEntry]
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { useKnowledgeBaseIndices } from '../../assistant/api/knowledge_base/use_knowledge_base_indices';
import { Router } from '@kbn/shared-ux-router';
import { createMemoryHistory, History } from 'history';
import { userProfileServiceMock } from '@kbn/core-user-profile-browser-mocks';

const mockContext = {
basePromptContexts: MOCK_QUICK_PROMPTS,
Expand All @@ -39,6 +40,7 @@ const mockContext = {
isAssistantEnabled: true,
hasManageGlobalKnowledgeBase: true,
},
userProfileService: userProfileServiceMock.createStart(),
};
jest.mock('../../assistant_context');
jest.mock('../../assistant/api/knowledge_base/entries/use_create_knowledge_base_entry');
Expand Down Expand Up @@ -157,8 +159,6 @@ describe('KnowledgeBaseSettingsManagement', () => {
data: {
elser_exists: true,
security_labs_exists: true,
index_exists: true,
pipeline_exists: true,
},
isFetched: true,
});
Expand Down Expand Up @@ -202,8 +202,6 @@ describe('KnowledgeBaseSettingsManagement', () => {
data: {
elser_exists: false,
security_labs_exists: false,
index_exists: false,
pipeline_exists: false,
},
isFetched: true,
});
Expand Down Expand Up @@ -458,9 +456,11 @@ describe('KnowledgeBaseSettingsManagement', () => {
});

const updatedName = 'New Entry Name';
await waitFor(() => {

await waitFor(async () => {
const nameInput = screen.getByTestId('entryNameInput');
fireEvent.change(nameInput, { target: { value: updatedName } });
await userEvent.clear(nameInput);
await userEvent.type(nameInput, updatedName);
});

await waitFor(() => {
Expand All @@ -476,7 +476,7 @@ describe('KnowledgeBaseSettingsManagement', () => {
});
expect(mockCreateEntry).toHaveBeenCalledTimes(0);
expect(mockUpdateEntry).toHaveBeenCalledWith([{ ...mockData[0], name: updatedName }]);
}, 100000000);
});

it('does not create a duplicate index entry when switching sharing option twice', async () => {
(useFlyoutModalVisibility as jest.Mock).mockReturnValue({
Expand Down Expand Up @@ -553,7 +553,11 @@ describe('KnowledgeBaseSettingsManagement', () => {
expect(mockCreateEntry).toHaveBeenCalledTimes(1);
});
expect(mockUpdateEntry).toHaveBeenCalledTimes(0);
expect(mockCreateEntry).toHaveBeenCalledWith({ ...mockData[3], users: undefined });
expect(mockCreateEntry).toHaveBeenCalledWith({
...mockData[3],
global: false,
users: undefined,
});
});

it('does not show duplicate entry modal on new document entry creation', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export const IndexEntryEditor: React.FC<Props> = React.memo(
setEntry((prevEntry) => ({
...prevEntry,
users: value === i18n.SHARING_GLOBAL_OPTION_LABEL ? [] : privateUsers,
global: value === i18n.SHARING_GLOBAL_OPTION_LABEL ? true : false,
})),
[privateUsers, setEntry]
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,36 +22,46 @@ import {
IndexEntryType,
KnowledgeBaseEntryResponse,
} from '@kbn/elastic-assistant-common';

import useAsync from 'react-use/lib/useAsync';
import { UserProfileAvatarData } from '@kbn/user-profile-components';
import { useQuery } from '@tanstack/react-query';
import { useAssistantContext } from '../../..';
import * as i18n from './translations';
import { BadgesColumn } from '../../assistant/common/components/assistant_settings_management/badges';
import { useInlineActions } from '../../assistant/common/components/assistant_settings_management/inline_actions';
import { isSystemEntry } from './helpers';
import { SetupKnowledgeBaseButton } from '../setup_knowledge_base_button';

const AuthorColumn = ({ entry }: { entry: KnowledgeBaseEntryResponse }) => {
const useUserProfile = ({ username, enabled = true }: { username: string; enabled: boolean }) => {
const { userProfileService } = useAssistantContext();

const userProfile = useAsync(async () => {
if (isSystemEntry(entry) || entry.createdBy === 'unknown') {
return;
}
return useQuery({
queryKey: ['userProfile', username],
queryFn: async () => {
const data = await userProfileService?.bulkGet<{ avatar: UserProfileAvatarData }>({
uids: new Set([username]),
dataPath: 'avatar',
});

const profile = await userProfileService?.bulkGet<{ avatar: UserProfileAvatarData }>({
uids: new Set([entry.createdBy]),
dataPath: 'avatar',
});
return { username: profile?.[0].user.username, avatar: profile?.[0].data.avatar };
}, [entry.createdBy]);
return data ?? null;
},
select: (profile) => {
return {
username: profile?.[0]?.user.username ?? 'Unknown',
avatar: profile?.[0]?.data.avatar,
};
},
enabled: !!(enabled && username?.length),
});
};

const userName = useMemo(
() => userProfile?.value?.username ?? 'Unknown',
[userProfile?.value?.username]
);
const userAvatar = userProfile?.value?.avatar;
const AuthorColumn = ({ entry }: { entry: KnowledgeBaseEntryResponse }) => {
const { data: userProfile } = useUserProfile({
username: entry.createdBy,
enabled: !(isSystemEntry(entry) || entry.createdBy === 'unknown'),
});

const userName = useMemo(() => userProfile?.username ?? 'Unknown', [userProfile?.username]);
const userAvatar = userProfile?.avatar;
const badgeItem = isSystemEntry(entry) ? 'Elastic' : userName;
const userImage = isSystemEntry(entry) ? (
<EuiIcon
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,7 @@ export const SetupKnowledgeBaseButton: React.FC<Props> = React.memo(({ display }
const { mutate: setupKB, isLoading: isSettingUpKB } = useSetupKnowledgeBase({ http, toasts });

const isSetupInProgress = kbStatus?.is_setup_in_progress || isSettingUpKB;
const isSetupComplete =
kbStatus?.elser_exists &&
kbStatus?.index_exists &&
kbStatus?.pipeline_exists &&
kbStatus?.security_labs_exists;
const isSetupComplete = kbStatus?.elser_exists && kbStatus?.security_labs_exists;

const onInstallKnowledgeBase = useCallback(() => {
setupKB();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,6 @@
"@kbn/spaces-plugin",
"@kbn/shared-ux-router",
"@kbn/inference-endpoint-ui-common",
"@kbn/core-user-profile-browser-mocks",
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
*/
import { FieldMap } from '@kbn/data-stream-adapter';

export const ELSER_MODEL_2 = ['.elser_model_2', '.elser_model_2_linux-x86_64'];
export const ASSISTANT_ELSER_INFERENCE_ID = 'elastic-security-ai-assistant-elser2';
export const ELASTICSEARCH_ELSER_INFERENCE_ID = '.elser-2-elasticsearch';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,12 @@ describe('AIAssistantKnowledgeBaseDataClient', () => {
kibanaVersion: '8.8.0',
ml,
getElserId: getElserId.mockResolvedValue('elser-id'),
modelIdOverride: false,
getIsKBSetupInProgress: mockGetIsKBSetupInProgress.mockReturnValue(false),
getProductDocumentationStatus: jest.fn().mockResolvedValue('installed'),
ingestPipelineResourceName: 'something',
setIsKBSetupInProgress: jest.fn().mockImplementation(() => {}),
manageGlobalKnowledgeBaseAIAssistant: true,
assistantDefaultInferenceEndpoint: false,
trainedModelsProvider: trainedModelsProviderMock,
};
esClientMock.search.mockReturnValue(
Expand Down Expand Up @@ -332,7 +332,7 @@ describe('AIAssistantKnowledgeBaseDataClient', () => {
{ fully_defined: false, model_id: '', tags: [], input: { field_names: ['content'] } },
],
});
mockLoadSecurityLabs.mockRejectedValue(new Error('Installation error'));
(getMlNodeCount as jest.Mock).mockRejectedValue(new Error('Installation error'));
const client = new AIAssistantKnowledgeBaseDataClient(mockOptions);

await expect(client.setupKnowledgeBase({})).rejects.toThrow(
Expand Down
Loading