[Security solution] AI Assistant prompt clean up (#217058)

This commit is contained in:
Steph Milovic 2025-04-04 10:06:40 -06:00 committed by GitHub
parent 9488bff6b8
commit df86cbbd72
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 342 additions and 316 deletions

View file

@ -20,7 +20,7 @@ export const bulkUpdatePrompts = async (
http: HttpSetup,
prompts: PerformPromptsBulkActionRequestBody,
toasts?: IToasts
) => {
): Promise<PerformPromptsBulkActionResponse | { success: false }> => {
try {
const result = await http.fetch<PerformPromptsBulkActionResponse>(
ELASTIC_AI_ASSISTANT_PROMPTS_URL_BULK_ACTION,
@ -56,5 +56,6 @@ export const bulkUpdatePrompts = async (
},
}),
});
return { success: false };
}
};

View file

@ -55,8 +55,8 @@ export const SystemPromptEditorComponent: React.FC<Props> = ({
// Prompt
const promptContent = useMemo(
// Fixing Cursor Jump in text area
() => systemPromptSettings.find((sp) => sp.id === selectedSystemPrompt?.id)?.content ?? '',
[selectedSystemPrompt?.id, systemPromptSettings]
() => selectedSystemPrompt?.content ?? '',
[selectedSystemPrompt?.content]
);
// Conversations this system prompt should be a default for
const conversationOptions = useMemo(() => Object.values(conversations), [conversations]);

View file

@ -111,15 +111,17 @@ const SystemPromptSettingsManagementComponent = ({ connectors, defaultConnector
const handleSave = useCallback(
async (param?: { callback?: () => void }) => {
const { conversationUpdates } = await saveSystemPromptSettings();
await saveConversationsSettings(conversationUpdates);
await refetchPrompts();
await refetchSystemPromptConversations();
toasts?.addSuccess({
iconType: 'check',
title: SETTINGS_UPDATED_TOAST_TITLE,
});
param?.callback?.();
const { success, conversationUpdates } = await saveSystemPromptSettings();
if (success) {
await saveConversationsSettings(conversationUpdates);
await refetchPrompts();
await refetchSystemPromptConversations();
toasts?.addSuccess({
iconType: 'check',
title: SETTINGS_UPDATED_TOAST_TITLE,
});
param?.callback?.();
}
},
[
refetchPrompts,

View file

@ -44,8 +44,8 @@ const QuickPromptSettingsEditorComponent = ({
// Prompt
const promptContent = useMemo(
// Fixing Cursor Jump in text area
() => quickPromptSettings.find((p) => p.id === selectedQuickPrompt?.id)?.content ?? '',
[selectedQuickPrompt?.id, quickPromptSettings]
() => selectedQuickPrompt?.content ?? '',
[selectedQuickPrompt?.content]
);
const setDefaultPromptColor = useCallback((): string => {

View file

@ -51,16 +51,19 @@ const QuickPromptSettingsManagementComponent = () => {
currentAppId,
http,
promptsLoaded,
toasts,
});
const handleSave = useCallback(
async (param?: { callback?: () => void }) => {
await saveQuickPromptSettings();
toasts?.addSuccess({
iconType: 'check',
title: SETTINGS_UPDATED_TOAST_TITLE,
});
param?.callback?.();
const didSucceed = await saveQuickPromptSettings();
if (didSucceed) {
toasts?.addSuccess({
iconType: 'check',
title: SETTINGS_UPDATED_TOAST_TITLE,
});
param?.callback?.();
}
},
[saveQuickPromptSettings, toasts]
);

View file

@ -8,9 +8,17 @@
import { renderHook, act } from '@testing-library/react';
import { HttpSetup } from '@kbn/core-http-browser';
import { useQuickPromptUpdater } from './use_quick_prompt_updater';
import { FindPromptsResponse, PromptResponse } from '@kbn/elastic-assistant-common';
import { FindPromptsResponse, PromptResponse, PromptTypeEnum } from '@kbn/elastic-assistant-common';
import { bulkUpdatePrompts } from '../../../..';
import { IToasts } from '@kbn/core-notifications-browser';
const mockHttp = {} as HttpSetup;
jest.mock('../../../..');
jest.mock('../../quick_prompts/quick_prompt_settings/helpers', () => {
return {
getRandomEuiColor: jest.fn(() => '#61A2FF'),
};
});
const mockBulkUpdatePrompts = bulkUpdatePrompts as jest.Mock;
const quickPrompt: PromptResponse = {
timestamp: '2025-02-24T18:13:51.851Z',
users: [{ id: 'u_mGBROF_q5bmFCATbLXAcCwKa0k8JvONAwSruelyKA5E_0', name: 'elastic' }],
@ -57,11 +65,19 @@ const mockAllPrompts: FindPromptsResponse = {
},
],
};
const mockToasts = {
addSuccess: jest.fn(),
addDanger: jest.fn(),
} as unknown as IToasts;
describe('useQuickPromptUpdater', () => {
beforeEach(() => {
jest.clearAllMocks();
});
it('should initialize with quick prompts', () => {
const { result } = renderHook(() =>
useQuickPromptUpdater({
toasts: mockToasts,
allPrompts: mockAllPrompts,
currentAppId: 'securitySolutionUI',
http: mockHttp,
@ -76,6 +92,7 @@ describe('useQuickPromptUpdater', () => {
it('should select a quick prompt by id', () => {
const { result } = renderHook(() =>
useQuickPromptUpdater({
toasts: mockToasts,
allPrompts: mockAllPrompts,
currentAppId: 'securitySolutionUI',
http: mockHttp,
@ -93,6 +110,7 @@ describe('useQuickPromptUpdater', () => {
it('should add a new quick prompt when selecting by name', () => {
const { result } = renderHook(() =>
useQuickPromptUpdater({
toasts: mockToasts,
allPrompts: mockAllPrompts,
currentAppId: 'securitySolutionUI',
http: mockHttp,
@ -104,13 +122,21 @@ describe('useQuickPromptUpdater', () => {
result.current.onQuickPromptSelect('New Quick Prompt');
});
expect(result.current.quickPromptSettings).toHaveLength(3);
expect(result.current.quickPromptSettings[2].name).toBe('New Quick Prompt');
expect(result.current.selectedQuickPrompt).toEqual({
name: 'New Quick Prompt',
id: '',
content: '',
color: '#61A2FF',
categories: [],
promptType: PromptTypeEnum.quick,
consumer: 'securitySolutionUI',
});
});
it('should change the content of a selected quick prompt', () => {
const { result } = renderHook(() =>
useQuickPromptUpdater({
toasts: mockToasts,
allPrompts: mockAllPrompts,
currentAppId: 'securitySolutionUI',
http: mockHttp,
@ -132,6 +158,7 @@ describe('useQuickPromptUpdater', () => {
it('should update prompt color', () => {
const { result } = renderHook(() =>
useQuickPromptUpdater({
toasts: mockToasts,
allPrompts: mockAllPrompts,
currentAppId: 'securitySolutionUI',
http: mockHttp,
@ -156,6 +183,7 @@ describe('useQuickPromptUpdater', () => {
it('should reset quick prompt settings', () => {
const { result } = renderHook(() =>
useQuickPromptUpdater({
toasts: mockToasts,
allPrompts: mockAllPrompts,
currentAppId: 'securitySolutionUI',
http: mockHttp,
@ -167,12 +195,101 @@ describe('useQuickPromptUpdater', () => {
result.current.onQuickPromptSelect('New Quick Prompt');
});
expect(result.current.quickPromptSettings).toHaveLength(3);
expect(result.current.selectedQuickPrompt?.name).toEqual('New Quick Prompt');
act(() => {
result.current.resetQuickPromptSettings();
});
expect(result.current.selectedQuickPrompt).toEqual(undefined);
});
it('should delete a quick prompt by id', async () => {
const { result } = renderHook(() =>
useQuickPromptUpdater({
toasts: mockToasts,
allPrompts: mockAllPrompts,
currentAppId: 'securitySolutionUI',
http: mockHttp,
promptsLoaded: true,
})
);
expect(result.current.quickPromptSettings).toHaveLength(2);
act(() => {
result.current.onQuickPromptDelete('OZ4qOZUBqnYEVX-cWulv');
});
await act(async () => {
await result.current.saveQuickPromptSettings();
});
expect(mockBulkUpdatePrompts).toHaveBeenCalledWith(
mockHttp,
{
delete: { ids: ['OZ4qOZUBqnYEVX-cWulv'] },
},
mockToasts
);
});
it('should change the context of a selected quick prompt', () => {
const { result } = renderHook(() =>
useQuickPromptUpdater({
toasts: mockToasts,
allPrompts: mockAllPrompts,
currentAppId: 'securitySolutionUI',
http: mockHttp,
promptsLoaded: true,
})
);
act(() => {
result.current.onQuickPromptSelect('OZ4qOZUBqnYEVX-cWulv');
});
act(() => {
result.current.onQuickPromptContextChange([
{ category: 'new-category', description: 'text', tooltip: 'hi' },
]);
});
expect(result.current.selectedQuickPrompt?.categories).toEqual(['new-category']);
});
it('should save quick prompt settings', async () => {
const { result } = renderHook(() =>
useQuickPromptUpdater({
toasts: mockToasts,
allPrompts: mockAllPrompts,
currentAppId: 'securitySolutionUI',
http: mockHttp,
promptsLoaded: true,
})
);
act(() => {
result.current.onQuickPromptSelect('OZ4qOZUBqnYEVX-cWulv');
});
act(() => {
result.current.onPromptContentChange('Updated content');
});
await act(async () => {
await result.current.saveQuickPromptSettings();
});
expect(mockBulkUpdatePrompts).toHaveBeenCalledWith(
mockHttp,
{
create: [
{
categories: [],
color: '#61A2FF',
consumer: 'securitySolutionUI',
content: 'Updated content',
id: '',
name: 'OZ4qOZUBqnYEVX-cWulv',
promptType: 'quick',
},
],
},
mockToasts
);
});
});

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { useCallback, useEffect, useMemo, useState } from 'react';
import { useCallback, useEffect, useState } from 'react';
import { FindPromptsResponse, PromptResponse, PromptTypeEnum } from '@kbn/elastic-assistant-common';
import { PerformPromptsBulkActionRequestBody as PromptsPerformBulkActionRequestBody } from '@kbn/elastic-assistant-common/impl/schemas/prompts/bulk_crud_prompts_route.gen';
import { HttpSetup } from '@kbn/core-http-browser';
@ -43,35 +43,24 @@ export const useQuickPromptUpdater = ({
const [promptsBulkActions, setPromptsBulkActions] = useState<PromptsPerformBulkActionRequestBody>(
{}
);
const [selectedQuickPromptId, setSelectedQuickPromptId] = useState<string | undefined>();
const [selectedQuickPrompt, setSelectedQuickPrompt] = useState<PromptResponse | undefined>();
const [quickPromptSettings, setUpdatedQuickPromptSettings] = useState<PromptResponse[]>(
allPrompts.data.filter((p) => p.promptType === PromptTypeEnum.quick)
);
const selectedQuickPrompt: PromptResponse | undefined = useMemo(
() => quickPromptSettings.find((qp) => qp.id === selectedQuickPromptId),
[quickPromptSettings, selectedQuickPromptId]
);
useEffect(() => {
// Update quick prompts settings when prompts are loaded
if (promptsLoaded) {
setUpdatedQuickPromptSettings((prev) => {
const prevIds = prev.map((p) => p.id);
return [
...prev,
...allPrompts.data.filter(
(p) => p.promptType === PromptTypeEnum.quick && !prevIds.includes(p.id)
),
];
});
setUpdatedQuickPromptSettings([
...allPrompts.data.filter((p) => p.promptType === PromptTypeEnum.quick),
]);
}
}, [allPrompts.data, promptsLoaded]);
const onQuickPromptSelect = useCallback(
(quickPrompt?: PromptResponse | string, color?: string) => {
if (quickPrompt == null) {
return setSelectedQuickPromptId(undefined);
return setSelectedQuickPrompt(undefined);
}
const isNew = typeof quickPrompt === 'string';
const qpColor = color ? color : isNew ? getRandomEuiColor() : quickPrompt.color;
@ -87,12 +76,6 @@ export const useQuickPromptUpdater = ({
}
: quickPrompt;
setUpdatedQuickPromptSettings((prev) =>
!prev.some((sp) => sp.id === newSelectedQuickPrompt.id)
? [...prev, newSelectedQuickPrompt]
: prev
);
if (isNew) {
setPromptsBulkActions((prev) => ({
...prev,
@ -105,7 +88,7 @@ export const useQuickPromptUpdater = ({
}));
}
setSelectedQuickPromptId(newSelectedQuickPrompt.id);
setSelectedQuickPrompt(newSelectedQuickPrompt);
},
[currentAppId, promptsBulkActions.create]
);
@ -113,115 +96,82 @@ export const useQuickPromptUpdater = ({
const onPromptContentChange = useCallback(
(newValue: string) => {
if (selectedQuickPrompt != null) {
setUpdatedQuickPromptSettings((prev): PromptResponse[] =>
prev.map((sp): PromptResponse => {
if (sp.id === selectedQuickPrompt.id) {
return {
...sp,
content: newValue,
};
}
return sp;
})
);
const existingPrompt = quickPromptSettings.find((qp) => qp.id === selectedQuickPrompt.id);
if (existingPrompt) {
const newBulkActions = {
...promptsBulkActions,
...(selectedQuickPrompt.id !== ''
? {
update: [
...(promptsBulkActions.update ?? []).filter(
(p) => p.id !== selectedQuickPrompt.id
),
{
...selectedQuickPrompt,
content: newValue,
},
],
}
: {
create: [
...(promptsBulkActions.create ?? []).filter(
(p) => p.name !== selectedQuickPrompt.name
),
{
...selectedQuickPrompt,
content: newValue,
},
],
}),
};
setPromptsBulkActions(newBulkActions);
}
setSelectedQuickPrompt({
...selectedQuickPrompt,
content: newValue,
});
const newBulkActions = {
...promptsBulkActions,
...(selectedQuickPrompt.id !== ''
? {
update: [
...(promptsBulkActions.update ?? []).filter(
(p) => p.id !== selectedQuickPrompt.id
),
{
...selectedQuickPrompt,
content: newValue,
},
],
}
: {
create: [
...(promptsBulkActions.create ?? []).filter(
(p) => p.name !== selectedQuickPrompt.name
),
{
...selectedQuickPrompt,
content: newValue,
},
],
}),
};
setPromptsBulkActions(newBulkActions);
}
},
[promptsBulkActions, selectedQuickPrompt, quickPromptSettings]
[promptsBulkActions, selectedQuickPrompt]
);
const onQuickPromptContextChange = useCallback(
(pc: PromptContextTemplate[]) => {
if (selectedQuickPrompt != null) {
setUpdatedQuickPromptSettings((prev) => {
const alreadyExists = prev.some((qp) => qp.name === selectedQuickPrompt.name);
if (alreadyExists) {
return prev.map((qp) => {
if (qp.name === selectedQuickPrompt.name) {
return {
...qp,
categories: pc.map((p) => p.category),
};
}
return qp;
});
}
return prev;
setSelectedQuickPrompt({
...selectedQuickPrompt,
categories: pc.map((p) => p.category),
});
setPromptsBulkActions({
...promptsBulkActions,
...(selectedQuickPrompt.id !== ''
? {
update: [
...(promptsBulkActions.update ?? []).filter(
(p) => p.id !== selectedQuickPrompt.id
),
{
...selectedQuickPrompt,
categories: pc.map((p) => p.category),
},
],
}
: {
create: [
...(promptsBulkActions.create ?? []).filter(
(p) => p.name !== selectedQuickPrompt.name
),
{
...selectedQuickPrompt,
categories: pc.map((p) => p.category),
},
],
}),
});
const existingPrompt = quickPromptSettings.find((sp) => sp.id === selectedQuickPrompt.id);
if (existingPrompt) {
setPromptsBulkActions({
...promptsBulkActions,
...(selectedQuickPrompt.id !== ''
? {
update: [
...(promptsBulkActions.update ?? []).filter(
(p) => p.id !== selectedQuickPrompt.id
),
{
...selectedQuickPrompt,
categories: pc.map((p) => p.category),
},
],
}
: {
create: [
...(promptsBulkActions.create ?? []).filter(
(p) => p.name !== selectedQuickPrompt.name
),
{
...selectedQuickPrompt,
categories: pc.map((p) => p.category),
},
],
}),
});
}
}
},
[
promptsBulkActions,
quickPromptSettings,
selectedQuickPrompt,
setPromptsBulkActions,
setUpdatedQuickPromptSettings,
]
[promptsBulkActions, selectedQuickPrompt, setPromptsBulkActions]
);
const onQuickPromptDelete = useCallback(
(id: string) => {
setUpdatedQuickPromptSettings((prev) => prev.filter((qp) => qp.id !== id));
setPromptsBulkActions({
...promptsBulkActions,
delete: {
@ -235,68 +185,45 @@ export const useQuickPromptUpdater = ({
const onQuickPromptColorChange = useCallback<EuiSetColorMethod>(
(color) => {
if (selectedQuickPrompt != null) {
setUpdatedQuickPromptSettings((prev) => {
const alreadyExists = prev.some((qp) => qp.name === selectedQuickPrompt.name);
if (alreadyExists) {
return prev.map((qp) => {
if (qp.name === selectedQuickPrompt.name) {
return {
...qp,
color,
};
}
return qp;
});
}
return prev;
setSelectedQuickPrompt({
...selectedQuickPrompt,
color,
});
setPromptsBulkActions({
...promptsBulkActions,
...(selectedQuickPrompt.id !== ''
? {
update: [
...(promptsBulkActions.update ?? []).filter(
(p) => p.id !== selectedQuickPrompt.id
),
{
...selectedQuickPrompt,
color,
},
],
}
: {
create: [
...(promptsBulkActions.create ?? []).filter(
(p) => p.name !== selectedQuickPrompt.name
),
{
...selectedQuickPrompt,
color,
},
],
}),
});
const existingPrompt = quickPromptSettings.find((sp) => sp.id === selectedQuickPrompt.id);
if (existingPrompt) {
setPromptsBulkActions({
...promptsBulkActions,
...(selectedQuickPrompt.id !== ''
? {
update: [
...(promptsBulkActions.update ?? []).filter(
(p) => p.id !== selectedQuickPrompt.id
),
{
...selectedQuickPrompt,
color,
},
],
}
: {
create: [
...(promptsBulkActions.create ?? []).filter(
(p) => p.name !== selectedQuickPrompt.name
),
{
...selectedQuickPrompt,
color,
},
],
}),
});
}
}
},
[
promptsBulkActions,
quickPromptSettings,
selectedQuickPrompt,
setPromptsBulkActions,
setUpdatedQuickPromptSettings,
]
[promptsBulkActions, selectedQuickPrompt, setPromptsBulkActions]
);
const resetQuickPromptSettings = useCallback((): void => {
setPromptsBulkActions({});
setUpdatedQuickPromptSettings(
allPrompts.data.filter((p) => p.promptType === PromptTypeEnum.quick)
);
}, [allPrompts]);
setSelectedQuickPrompt(undefined);
}, []);
const saveQuickPromptSettings = useCallback(async (): Promise<boolean> => {
const hasBulkPrompts =
@ -304,8 +231,9 @@ export const useQuickPromptUpdater = ({
const bulkPromptsResult = hasBulkPrompts
? await bulkUpdatePrompts(http, promptsBulkActions, toasts)
: undefined;
resetQuickPromptSettings();
return bulkPromptsResult?.success ?? false;
}, [http, promptsBulkActions, toasts]);
}, [http, promptsBulkActions, resetQuickPromptSettings, toasts]);
return {
onPromptContentChange,

View file

@ -160,7 +160,7 @@ describe('useSystemPromptUpdater', () => {
});
});
it('should delete a system prompt by ID', () => {
it('should delete a system prompt by ID', async () => {
const { result } = renderHook(() => useSystemPromptUpdater(defaultParams), {
wrapper: TestProviders,
});
@ -169,9 +169,20 @@ describe('useSystemPromptUpdater', () => {
result.current.onSystemPromptSelect({ ...defaultPrompt, id: '1' });
});
expect(result.current.selectedSystemPrompt).toEqual({
consumer: 'app-id',
content: '',
conversations: [],
id: '1',
name: 'New Prompt',
promptType: 'system',
});
act(() => {
result.current.onSystemPromptDelete('1');
});
await act(async () => {
await result.current.saveSystemPromptSettings();
});
expect(result.current.selectedSystemPrompt).toBeUndefined();
});

View file

@ -80,11 +80,9 @@ export const useSystemPromptUpdater = ({
{}
);
// System Prompt Selection State
const [selectedSystemPromptId, setSelectedSystemPromptId] = useState<string | undefined>();
const selectedSystemPrompt: SystemPromptSettings | undefined = useMemo(() => {
return systemPromptSettingsUpdates.find((sp) => sp.id === selectedSystemPromptId);
}, [selectedSystemPromptId, systemPromptSettingsUpdates]);
const [selectedSystemPrompt, setSelectedSystemPrompt] = useState<
SystemPromptSettings | undefined
>();
const systemPrompts = useMemo(() => {
return allPrompts.data.filter((p) => p.promptType === PromptTypeEnum.system);
@ -135,7 +133,7 @@ export const useSystemPromptUpdater = ({
const onSystemPromptSelect = useCallback(
(systemPrompt?: SystemPromptSettings | string) => {
if (systemPrompt == null) {
return setSelectedSystemPromptId(undefined);
return setSelectedSystemPrompt(undefined);
}
const isNew = typeof systemPrompt === 'string';
const newSelectedSystemPrompt: SystemPromptSettings = isNew
@ -149,12 +147,6 @@ export const useSystemPromptUpdater = ({
}
: systemPrompt;
setSystemPromptSettingsUpdates((prev) =>
!prev.some((sp) => sp.id === newSelectedSystemPrompt.id)
? [...prev, newSelectedSystemPrompt]
: prev
);
if (isNew) {
setPromptsBulkActions((prev) => ({
...prev,
@ -163,14 +155,13 @@ export const useSystemPromptUpdater = ({
}));
}
setSelectedSystemPromptId(newSelectedSystemPrompt.id);
setSelectedSystemPrompt(newSelectedSystemPrompt);
},
[currentAppId]
);
const onSystemPromptDelete = useCallback(
(id: string) => {
setSystemPromptSettingsUpdates((prev) => prev.filter((sp) => sp.id !== id));
setPromptsBulkActions({
...promptsBulkActions,
delete: {
@ -184,52 +175,41 @@ export const useSystemPromptUpdater = ({
const onPromptContentChange = useCallback(
(newValue: string) => {
if (selectedSystemPrompt != null) {
setSystemPromptSettingsUpdates((prev): SystemPromptSettings[] =>
prev.map((sp): SystemPromptSettings => {
if (sp.id === selectedSystemPrompt.id) {
return {
...sp,
content: newValue,
};
}
return sp;
})
);
const existingPrompt = systemPromptSettingsUpdates.find(
(sp) => sp.id === selectedSystemPrompt.id
);
if (existingPrompt) {
const newBulkActions = {
...promptsBulkActions,
...(selectedSystemPrompt.id !== ''
? {
update: [
...(promptsBulkActions.update ?? []).filter(
(p) => p.id !== selectedSystemPrompt.id
),
{
...selectedSystemPrompt,
content: newValue,
},
],
}
: {
create: [
...(promptsBulkActions.create ?? []).filter(
(p) => p.name !== selectedSystemPrompt.name
),
{
...selectedSystemPrompt,
content: newValue,
},
],
}),
};
setPromptsBulkActions(newBulkActions);
}
setSelectedSystemPrompt({
...selectedSystemPrompt,
content: newValue,
});
const newBulkActions = {
...promptsBulkActions,
...(selectedSystemPrompt.id !== ''
? {
update: [
...(promptsBulkActions.update ?? []).filter(
(p) => p.id !== selectedSystemPrompt.id
),
{
...selectedSystemPrompt,
content: newValue,
},
],
}
: {
create: [
...(promptsBulkActions.create ?? []).filter(
(p) => p.name !== selectedSystemPrompt.name
),
{
...selectedSystemPrompt,
content: newValue,
},
],
}),
};
setPromptsBulkActions(newBulkActions);
}
},
[promptsBulkActions, selectedSystemPrompt, systemPromptSettingsUpdates]
[promptsBulkActions, selectedSystemPrompt]
);
const onNewConversationDefaultChange = useCallback(
@ -249,13 +229,9 @@ export const useSystemPromptUpdater = ({
const shouldUpdateSelectedSystemPrompt = selectedSystemPrompt?.id !== '';
if (selectedSystemPrompt != null) {
setSystemPromptSettingsUpdates((prev) => {
return prev.map((pp) => {
return {
...pp,
isNewConversationDefault: selectedSystemPrompt.id === pp.id && isChecked,
};
});
setSelectedSystemPrompt({
...selectedSystemPrompt,
isNewConversationDefault: isChecked,
});
// Update and Create prompts can happen at the same time, as we have to unchecked the previous default prompt
// Each prompt can be updated or created
@ -308,12 +284,9 @@ export const useSystemPromptUpdater = ({
const onConversationSelectionChange = useCallback(
(currentPromptConversations: Conversation[]) => {
const originalSelectedSystemPrompt = systemPromptSettings.find(
(sp) => sp.id === selectedSystemPromptId
);
const currentPromptConversationIds = currentPromptConversations.map((convo) => convo.id);
const removals =
originalSelectedSystemPrompt?.conversations.filter(
selectedSystemPrompt?.conversations.filter(
(c) => !currentPromptConversationIds.includes(c.id)
) ?? [];
let cRemovals: Conversation[] = [];
@ -338,17 +311,10 @@ export const useSystemPromptUpdater = ({
convo.apiConfig?.defaultSystemPromptId;
if (selectedSystemPrompt != null) {
setSystemPromptSettingsUpdates((prev) =>
prev.map((sp) => {
if (sp.id === selectedSystemPrompt.id) {
return {
...sp,
conversations: currentPromptConversations,
};
}
return sp;
})
);
setSelectedSystemPrompt({
...selectedSystemPrompt,
conversations: currentPromptConversations,
});
let updatedConversationsSettingsBulkActions = { create: {}, update: {} };
Object.values(currentPromptConversations).forEach((convo) => {
const getApiConfigWithSelectedPrompt = (): ApiConfig | {} => {
@ -439,7 +405,6 @@ export const useSystemPromptUpdater = ({
[
systemPromptSettings,
selectedSystemPrompt,
selectedSystemPromptId,
setConversationsSettingsBulkActions,
defaultConnector,
connectors,
@ -447,9 +412,10 @@ export const useSystemPromptUpdater = ({
);
const resetSystemPromptSettings = useCallback((): void => {
setSystemPromptSettingsUpdates(systemPromptSettings);
setConversationsSettingsBulkActions({});
setPromptsBulkActions({});
}, [systemPromptSettings]);
setSelectedSystemPrompt(undefined);
}, [setConversationsSettingsBulkActions]);
const saveSystemPromptSettings = useCallback(async (): Promise<{
success: boolean;
@ -463,36 +429,30 @@ export const useSystemPromptUpdater = ({
: undefined;
let conversationUpdates;
if (
bulkPromptsResult?.attributes?.results?.created?.length &&
conversationsSettingsBulkActions.update &&
Object.keys(conversationsSettingsBulkActions.update).length &&
bulkPromptsResult?.success
// no prompt update or prompt update succeeded
(!bulkPromptsResult || bulkPromptsResult?.success) &&
conversationsSettingsBulkActions?.update
) {
const updatesWithNewIds = conversationsSettingsBulkActions.update
? Object.entries(conversationsSettingsBulkActions.update).reduce((acc, [key, value]) => {
if (value.apiConfig?.defaultSystemPromptId === '') {
// only creating one at a time
const createdPrompt = bulkPromptsResult?.attributes?.results?.created[0];
if (createdPrompt) {
return {
...acc,
[key]: {
...value,
apiConfig: { ...value.apiConfig, defaultSystemPromptId: createdPrompt.id },
},
};
const updatesWithNewIds =
conversationsSettingsBulkActions.update &&
bulkPromptsResult?.attributes?.results?.created?.length
? Object.entries(conversationsSettingsBulkActions.update).reduce((acc, [key, value]) => {
if (value.apiConfig?.defaultSystemPromptId === '') {
// only creating one at a time
const createdPrompt = bulkPromptsResult?.attributes?.results?.created[0];
if (createdPrompt) {
return {
...acc,
[key]: {
...value,
apiConfig: { ...value.apiConfig, defaultSystemPromptId: createdPrompt.id },
},
};
}
}
}
return acc;
}, {})
: {};
setConversationsSettingsBulkActions({
...conversationsSettingsBulkActions,
update: {
...conversationsSettingsBulkActions.update,
...updatesWithNewIds,
},
});
return acc;
}, {})
: {};
conversationUpdates = {
...conversationsSettingsBulkActions,
update: {
@ -501,13 +461,17 @@ export const useSystemPromptUpdater = ({
},
};
}
setPromptsBulkActions({});
return { success: bulkPromptsResult?.success ?? false, conversationUpdates };
resetSystemPromptSettings();
return {
// if no bulk update status, only conversations need to update so return success === true
success: bulkPromptsResult?.success ?? true,
conversationUpdates,
};
}, [
conversationsSettingsBulkActions,
http,
promptsBulkActions,
setConversationsSettingsBulkActions,
resetSystemPromptSettings,
toasts,
]);