-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
[Obs AI Assistant] Share conversations #211854
base: main
Are you sure you want to change the base?
Conversation
5e7a5ff
to
b487cf0
Compare
…nd other updates) (elastic#206590)
f467bed
to
e6bdd08
Compare
🤖 GitHub commentsExpand to view the GitHub comments
Just comment with:
|
Project deployed, see credentials at: https://buildkite.com/elastic/kibana-deploy-project-from-pr/builds/354 |
@@ -408,7 +379,6 @@ export default function ApiTest({ getService, getPageObjects }: FtrProviderConte | |||
'And what are SLIs?' | |||
); | |||
await testSubjects.pressEnter(ui.pages.conversations.chatInput); | |||
log.info('SQREN: Waiting for the message to be displayed'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sorenlouv Let me know if these were left intentionally.. I can add it back
Pinging @elastic/obs-ai-assistant (Team:Obs AI Assistant) |
💔 Build Failed
Failed CI StepsTest Failures
Metrics [docs]Module Count
Public APIs missing comments
Async chunks
Page load bundle
Unknown metric groupsAPI count
History
cc @viduni94 |
@@ -625,5 +625,156 @@ export default function ApiTest({ getService }: DeploymentAgnosticFtrProviderCon | |||
}); | |||
}); | |||
}); | |||
|
|||
describe('conversation sharing', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've verified these in stateful and serverless local. Will be testing on MKI tomorrow.
@@ -351,6 +346,65 @@ export function ChatBody({ | |||
} | |||
}; | |||
|
|||
const handleConversationAccessUpdate = async (access: ConversationAccess) => { | |||
await updateConversationAccess(access); | |||
conversation.refresh(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need an additional call to refresh the conversation after changing access?
The UI is already updated, but should we refresh the conversation if there’s an error when calling updateConversationAccess(access)
/> | ||
); | ||
} | ||
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These two cases are functionally identical:
- "Public, conversation has a user, but current user is not the owner. Don't show prompt editor, only show the banner with Duplicate button"
- "Public, but conversation doesn't have a user (for backwards compatibility with old conversations generated by the rule connector). Don't show prompt editor, only show the banner with Duplicate button"
Since isConversationOwnedByCurrentUser
already checks if the conversation has no user (returning false in both cases), the UI behavior remains the same (showPromptEditor
and sharedBanner
).
You can delete one of them, avoiding duplicated code.
@@ -216,12 +216,46 @@ const deleteConversationRoute = createObservabilityAIAssistantServerRoute({ | |||
}, | |||
}); | |||
|
|||
const updateConversationAccessRoute = createObservabilityAIAssistantServerRoute({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don’t think we should add a separate router for each conversation property update. We already have an update router that we can use, and we can also remove the dedicated update Title
router.
We have two possible approaches:
- Only keep
PUT
conversation router. UsePUT
to update the entire conversation. The request must contain the full updated conversation document. - Remove
title
andaccess
routers, keepPUT
conversation, addPATCH
conversation. UsePATCH
to update specific fields, The request includes only the properties being modified (e.g., title and access).
what do you think?
access: ConversationAccess; | ||
}) => { | ||
if (![ConversationAccess.SHARED, ConversationAccess.PRIVATE].includes(access)) { | ||
throw badRequest('Invalid access value. Allowed values are SHARED and PRIVATE.'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This validation/error seems more appropriate at the router level rather than in the client method.
} | ||
|
||
const conversation = await this.get(conversationId); | ||
if (!conversation) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use either getConversationWithMetaFields
or get
, as both methods query the document. The get
method internally calls getConversationWithMetaFields
and also validates if the document exists.
conversationId: t.string, | ||
}), | ||
body: t.type({ | ||
access: t.string, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
enum? (t.literal)
access: params.body.access as ConversationAccess, | ||
}); | ||
|
||
return Promise.resolve(conversation); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we need Promise.resolve here?
@@ -140,7 +141,7 @@ export class ObservabilityAIAssistantClient { | |||
return false; | |||
} | |||
|
|||
return conversation.user.id | |||
return conversation.user.id && user.id |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In what case is user.id not set, but does the current user still have access to the conversation?
const updatedConversation: Conversation = merge({}, conversation, { | ||
public: isPublic, | ||
conversation: { | ||
last_updated: new Date().toISOString(), | ||
}, | ||
}); | ||
|
||
await this.dependencies.esClient.asInternalUser.update({ | ||
id: document._id!, | ||
index: document._index, | ||
doc: updatedConversation, | ||
refresh: true, | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we use the .update
function on the AI Assistant client instead?
Closes #206590
Closes #211710
Closes #211604
Closes https://github.com/elastic/obs-ai-assistant-team/issues/215
Summary
This PR implements conversation sharing for Obs AI Assistant conversations.
The features included are as follows:
ChatActionsMenu
- Removed Copy Conversation and Duplicate optionsPromptEditor
), if the user who is viewing the conversation cannot continue it.ChatBanner
- This will show whether a conversation is shared with the team (The banner content differs based on who is viewing the conversation)ChatContextMenu
for conversation specific actions. This includes "Duplicate", "Copy conversation", "Copy URL" and "Delete". "Delete" functionality is only available to the conversation owner. (This menu is only included in theChatHeader
at the moment becauseEui
doesn't support passing a node toEuiListGroupItem
to include this in theConversationList
. This will be refactored in [Obs AI Assistant] Archiving conversations #209386)useConversationContextMenu
for "copy" and "delete" functionalities.ChatSharingMenu
to mark a conversation asshared/private
. This is only enabled for the owner of the conversation. For other users, a disabled badge will be shown stating whether the conversation is Private or Shared.updateConversationAccess
route.Inspect
. This waseye
before.ConversationListItemLabel
to show the shared icon inConversationList
.Note: If a conversation started from contextual insights, and then the user continue the conversation --> The conversation will be stored. However, if the user deletes the continued conversation, they will be reverted to the initial messages from the contextual insights.
Screen recording
sharing-conversations.mov
Checklist
release_note:*
label is applied per the guidelines