Skip to content

Commit

Permalink
[Security Solution][Security Assistant] Fixes relationship between sy…
Browse files Browse the repository at this point in the history
…stem prompts & conversations (#161039)

## Summary
This PR handles bugs 
- elastic/security-team#6977 
- elastic/security-team#6978 
- elastic/security-team#6979.

Currently, below operations between System Prompts and Conversarions do
not work.

1. When a prompt is set as default for all conversation, it should be
automatically selected for any new conversation user creates.
2. When a new prompt is creates and set as default for all conversation,
it should be automatically selected for any new conversation user
creates.
3. When a prompt is edited such that, it is default for only certain
conversation, it should be automatically selected for that conversation.
4. When a prompt is edited such that conversations are removed to have
that default prompt, it should be automatically removed from
conversation default system prompt list.

In addition to above scenarios, this PR also handles one more bug.

Consider below interface of Conversation which has a property
`apiConfig.defaultSystemPrompt` is of type Prompt. It has been changed
from `defaultSystemPrompt?: Prompt` to `defaultSystemPrompt?: string`
where it will store `promptId` instead of complete prompt.

The current model was posing a problem where, if a prompt was updated,
all its copies in `Conversation` were needed to be updated leading to
inconsistencies. This is now resolved.

```typescript
export interface Conversation {
  apiConfig: {
    connectorId?: string;
    defaultSystemPrompt?: Prompt;
    provider?: OpenAiProviderType;
  };
  id: string;
  messages: Message[];
  replacements?: Record<string, string>;
  theme?: ConversationTheme;
  isDefault?: boolean;
}

```
  • Loading branch information
logeekal authored Jul 6, 2023
1 parent f82588b commit 75bd6dd
Show file tree
Hide file tree
Showing 13 changed files with 500 additions and 58 deletions.
21 changes: 21 additions & 0 deletions x-pack/packages/kbn-elastic-assistant/impl/assistant/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* 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.
*/

export const TEST_IDS = {
SYSTEM_PROMPT_SELECTOR: 'systemPromptSelector',
CONVERSATIONS_MULTISELECTOR: 'conversationMultiSelector',
ADD_SYSTEM_PROMPT: 'addSystemPrompt',
PROMPT_SUPERSELECT: 'promptSuperSelect',
CONVERSATIONS_MULTISELECTOR_OPTION: (id: string) => `conversationMultiSelectorOption-${id}`,
SYSTEM_PROMPT_MODAL: {
ID: 'systemPromptModal',
PROMPT_TEXT: 'systemPromptModalPromptText',
TOGGLE_ALL_DEFAULT_CONVERSATIONS: 'systemPromptModalToggleDefaultConversations',
SAVE: 'systemPromptModalSave',
CANCEL: 'systemPromptModalCancel',
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ export const ConversationSelector: React.FC<Props> = React.memo(
apiConfig: {
connectorId: defaultConnectorId,
provider: defaultProvider,
defaultSystemPrompt,
defaultSystemPromptId: defaultSystemPrompt?.id,
},
};
setConversation({ conversation: newConversation });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,11 @@ export interface ConversationSettingsPopoverProps {
conversation: Conversation;
http: HttpSetup;
isDisabled?: boolean;
allSystemPrompts: Prompt[];
}

export const ConversationSettingsPopover: React.FC<ConversationSettingsPopoverProps> = React.memo(
({ actionTypeRegistry, conversation, http, isDisabled = false }) => {
({ actionTypeRegistry, conversation, http, isDisabled = false, allSystemPrompts }) => {
const [isSettingsOpen, setIsSettingsOpen] = useState(false);
// So we can hide the settings popover when the connector modal is displayed
const popoverPanelRef = useRef<HTMLElement | null>(null);
Expand All @@ -41,10 +42,13 @@ export const ConversationSettingsPopover: React.FC<ConversationSettingsPopoverPr
return conversation.apiConfig?.provider;
}, [conversation.apiConfig]);

const selectedPrompt: Prompt | undefined = useMemo(
() => conversation?.apiConfig.defaultSystemPrompt,
[conversation]
);
const selectedPrompt: Prompt | undefined = useMemo(() => {
const convoDefaultSystemPromptId = conversation?.apiConfig.defaultSystemPromptId;
if (convoDefaultSystemPromptId && allSystemPrompts) {
return allSystemPrompts.find((prompt) => prompt.id === convoDefaultSystemPromptId);
}
return allSystemPrompts.find((prompt) => prompt.isNewConversationDefault);
}, [conversation, allSystemPrompts]);

const closeSettingsHandler = useCallback(() => {
setIsSettingsOpen(false);
Expand Down
15 changes: 14 additions & 1 deletion x-pack/packages/kbn-elastic-assistant/impl/assistant/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ const AssistantComponent: React.FC<Props> = ({
http,
promptContexts,
title,
allSystemPrompts,
} = useAssistantContext();
const [selectedPromptContexts, setSelectedPromptContexts] = useState<
Record<string, SelectedPromptContext>
Expand Down Expand Up @@ -170,6 +171,7 @@ const AssistantComponent: React.FC<Props> = ({

// For auto-focusing prompt within timeline
const promptTextAreaRef = useRef<HTMLTextAreaElement>(null);

useEffect(() => {
if (shouldRefocusPrompt && promptTextAreaRef.current) {
promptTextAreaRef?.current.focus();
Expand All @@ -187,6 +189,15 @@ const AssistantComponent: React.FC<Props> = ({
}, 0);
}, [currentConversation.messages.length, selectedPromptContextsCount]);
////
//

const selectedSystemPrompt = useMemo(() => {
if (currentConversation.apiConfig.defaultSystemPromptId) {
return allSystemPrompts.find(
(prompt) => prompt.id === currentConversation.apiConfig.defaultSystemPromptId
);
}
}, [allSystemPrompts, currentConversation.apiConfig.defaultSystemPromptId]);

// Handles sending latest user prompt to API
const handleSendMessage = useCallback(
Expand All @@ -203,7 +214,7 @@ const AssistantComponent: React.FC<Props> = ({
onNewReplacements,
promptText,
selectedPromptContexts,
selectedSystemPrompt: currentConversation.apiConfig.defaultSystemPrompt,
selectedSystemPrompt,
});

const updatedMessages = appendMessage({
Expand All @@ -224,6 +235,7 @@ const AssistantComponent: React.FC<Props> = ({
appendMessage({ conversationId: selectedConversationId, message: responseMessage });
},
[
selectedSystemPrompt,
appendMessage,
appendReplacements,
currentConversation.apiConfig,
Expand Down Expand Up @@ -561,6 +573,7 @@ const AssistantComponent: React.FC<Props> = ({
conversation={currentConversation}
isDisabled={isWelcomeSetup}
http={http}
allSystemPrompts={allSystemPrompts}
/>
</EuiFlexItem>
</EuiFlexGroup>
Expand Down
Loading

0 comments on commit 75bd6dd

Please sign in to comment.