[Obs AI Assistant] Fix editing prompt from contextual insights (#206673)

Closes https://github.com/elastic/kibana/issues/201642

## Summary

### Problem
1. Before a conversation is generated from contextual insights (before
`Help me understand this alert` is clicked), if the user clicks on `Edit
Prompt`, the prompt to edit is not loaded. An empty input box is loaded.
2. When a new prompt is typed in the empty input box and submitted, it
throws an error (because the way the new prompt is assigned to the
conversation errors out)
3. After clicking on "Help me understand this alert", if the user clicks
on `Edit Prompt`, a large string is loaded with contextual information,
as the prompt to edit. This is not user-friendly.

(All of the above can be seen in the screen recording before the changes
- attached below)

### Solution
1. Wait for the messages to be generated and then load the correct
initial prompt to edit.
2. When re-assigning the new prompt to the messages, make sure to parse
it and then assign correctly so that editing the prompt is user
friendly.

### Checklist

- [x] The PR description includes the appropriate Release Notes section,
and the correct `release_note:*` label is applied per the
[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
This commit is contained in:
Viduni Wickramarachchi 2025-01-16 11:52:44 -05:00 committed by GitHub
parent 1d493c0a8d
commit 10a221553a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -14,6 +14,7 @@ import {
EuiText,
EuiTextArea,
EuiCallOut,
EuiLoadingSpinner,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { cloneDeep, isArray, isEmpty, last, once } from 'lodash';
@ -288,16 +289,47 @@ export function Insight({
[service]
);
const getPromptToEdit = () => {
const clonedMessages = cloneDeep(messages.messages);
const lastUserPrompt = getLastMessageOfType(clonedMessages, MessageRole.User)?.message.content;
if (!lastUserPrompt) {
return '';
}
try {
const { instructions = '' } = JSON.parse(lastUserPrompt);
return instructions.trim();
} catch (e) {
return '';
}
};
const onEditPrompt = (newPrompt: string) => {
const clonedMessages = cloneDeep(messages.messages);
const userMessage = getLastMessageOfType(clonedMessages, MessageRole.User);
if (!userMessage) return false;
userMessage.message.content = newPrompt;
setIsPromptUpdated(true);
setMessages({ messages: clonedMessages, status: FETCH_STATUS.SUCCESS });
setEditingPrompt(false);
return true;
try {
const parsedContent = JSON.parse(userMessage.message.content || '');
if (!parsedContent.instructions) {
return false;
}
// Assign the updated instructions
parsedContent.instructions = newPrompt;
userMessage.message.content = JSON.stringify(parsedContent);
setIsPromptUpdated(true);
setMessages({ messages: clonedMessages, status: FETCH_STATUS.SUCCESS });
setEditingPrompt(false);
return true;
} catch (e) {
// eslint-disable-next-line no-console
console.error('Failed to edit prompt:', e);
return false;
}
};
const handleCancel = () => {
@ -372,15 +404,15 @@ export function Insight({
</>
);
} else if (isEditingPrompt) {
children = (
<PromptEdit
initialPrompt={
getLastMessageOfType(messages.messages, MessageRole.User)?.message.content || ''
}
onSend={onEditPrompt}
onCancel={handleCancel}
/>
);
const promptToEdit = getPromptToEdit();
if (messages.status === FETCH_STATUS.SUCCESS && promptToEdit) {
children = (
<PromptEdit initialPrompt={promptToEdit} onSend={onEditPrompt} onCancel={handleCancel} />
);
} else {
children = <EuiLoadingSpinner size="m" />;
}
} else if (!connectors.loading && !connectors.connectors?.length) {
children = (
<MissingCredentialsCallout connectorsManagementHref={getConnectorsManagementHref(http!)} />