diff --git a/x-pack/platform/packages/shared/kbn-ai-assistant/src/chat/chat_actions_menu.tsx b/x-pack/platform/packages/shared/kbn-ai-assistant/src/chat/chat_actions_menu.tsx index dfe3fc8ff1b2f..c9451f025f7aa 100644 --- a/x-pack/platform/packages/shared/kbn-ai-assistant/src/chat/chat_actions_menu.tsx +++ b/x-pack/platform/packages/shared/kbn-ai-assistant/src/chat/chat_actions_menu.tsx @@ -22,14 +22,10 @@ import { useKnowledgeBase } from '../hooks'; export function ChatActionsMenu({ connectors, - conversationId, disabled, - onCopyConversationClick, }: { connectors: UseGenAIConnectorsResult; - conversationId?: string; disabled: boolean; - onCopyConversationClick: () => void; }) { const { application, http } = useKibana().services; const knowledgeBase = useKnowledgeBase(); diff --git a/x-pack/platform/packages/shared/kbn-ai-assistant/src/chat/chat_body.tsx b/x-pack/platform/packages/shared/kbn-ai-assistant/src/chat/chat_body.tsx index 8c10e7c096b85..cae3085d0f3ca 100644 --- a/x-pack/platform/packages/shared/kbn-ai-assistant/src/chat/chat_body.tsx +++ b/x-pack/platform/packages/shared/kbn-ai-assistant/src/chat/chat_body.tsx @@ -140,7 +140,7 @@ export function ChatBody({ const chatService = useAIAssistantChatService(); const { - services: { uiSettings, notifications }, + services: { uiSettings, notifications, http }, } = useKibana(); const simulateFunctionCalling = uiSettings!.get( @@ -251,7 +251,7 @@ export function ChatBody({ } }); - const handleCopyConversation = () => { + const handleCopyConversationToClipboard = () => { try { const deserializedMessages = (conversation.value?.messages ?? messages).map( deserializeMessage @@ -280,16 +280,21 @@ export function ChatBody({ const handleCopyUrl = () => { try { - const deserializedMessages = (conversation.value?.messages ?? messages).map( - deserializeMessage + const conversationId = conversation.value?.conversation?.id; + if (!conversationId) { + throw new Error('Cannot copy URL if the conversation is not stored'); + } + + const conversationUrl = http?.basePath.prepend( + `/app/observabilityAIAssistant/conversations/${conversationId}` ); - const content = JSON.stringify({ - title: initialTitle, - messages: deserializedMessages, - }); + if (!conversationUrl) { + throw new Error('Conversation URL does not exist'); + } - navigator.clipboard?.writeText(content || ''); + const urlToCopy = new URL(conversationUrl, window.location.origin).toString(); + navigator.clipboard?.writeText(urlToCopy); notifications!.toasts.addSuccess({ title: i18n.translate('xpack.aiAssistant.copyUrlSuccessToast', { @@ -566,7 +571,8 @@ export function ChatBody({ licenseInvalid={!hasCorrectLicense && !initialConversationId} loading={isLoading} title={title} - onCopyConversation={handleCopyConversation} + onCopyConversationToClipboard={handleCopyConversationToClipboard} + onCopyUrl={handleCopyUrl} onSaveTitle={(newTitle) => { saveTitle(newTitle); }} diff --git a/x-pack/platform/packages/shared/kbn-ai-assistant/src/chat/chat_context_menu.tsx b/x-pack/platform/packages/shared/kbn-ai-assistant/src/chat/chat_context_menu.tsx index 3ebd3cab3cb8e..7383aa48a1481 100644 --- a/x-pack/platform/packages/shared/kbn-ai-assistant/src/chat/chat_context_menu.tsx +++ b/x-pack/platform/packages/shared/kbn-ai-assistant/src/chat/chat_context_menu.tsx @@ -16,10 +16,12 @@ import { import { i18n } from '@kbn/i18n'; export function ChatContextMenu({ - onCopyConversationClick, + onCopyToClipboardClick, + onCopyUrlClick, disabled, }: { - onCopyConversationClick: () => void; + onCopyToClipboardClick: () => void; + onCopyUrlClick: () => void; disabled: boolean; }) { const [isPopoverOpen, setIsPopoverOpen] = useState(false); @@ -53,26 +55,26 @@ export function ChatContextMenu({ size="s" items={[ { - onCopyConversationClick(); + onCopyToClipboardClick(); setIsPopoverOpen(false); }} > - {i18n.translate('xpack.aiAssistant.chatHeader.contextMenu.copyConversation', { - defaultMessage: 'Copy conversation', + {i18n.translate('xpack.aiAssistant.chatHeader.contextMenu.copyToClipboard', { + defaultMessage: 'Copy to clipboard', })} , { - navigator.clipboard.writeText(window.location.href); + onCopyUrlClick(); setIsPopoverOpen(false); }} > - {i18n.translate('xpack.aiAssistant.chatHeader.contextMenu.copyURL', { + {i18n.translate('xpack.aiAssistant.chatHeader.contextMenu.copyUrl', { defaultMessage: 'Copy URL', })} , diff --git a/x-pack/platform/packages/shared/kbn-ai-assistant/src/chat/chat_header.tsx b/x-pack/platform/packages/shared/kbn-ai-assistant/src/chat/chat_header.tsx index 007c63341016e..4ba7e0841d3f9 100644 --- a/x-pack/platform/packages/shared/kbn-ai-assistant/src/chat/chat_header.tsx +++ b/x-pack/platform/packages/shared/kbn-ai-assistant/src/chat/chat_header.tsx @@ -49,10 +49,11 @@ export function ChatHeader({ licenseInvalid, loading, title, - onCopyConversation, + onCopyConversationToClipboard, onSaveTitle, onToggleFlyoutPositionMode, navigateToConversation, + onCopyUrl, }: { connectors: UseGenAIConnectorsResult; conversationId?: string; @@ -60,10 +61,11 @@ export function ChatHeader({ licenseInvalid: boolean; loading: boolean; title: string; - onCopyConversation: () => void; + onCopyConversationToClipboard: () => void; onSaveTitle: (title: string) => void; onToggleFlyoutPositionMode?: (newFlyoutPositionMode: FlyoutPositionMode) => void; navigateToConversation?: (nextConversationId?: string) => void; + onCopyUrl: () => void; }) { const theme = useEuiTheme(); const breakpoint = useCurrentEuiBreakpoint(); @@ -152,7 +154,8 @@ export function ChatHeader({ {conversationId ? ( @@ -224,12 +227,7 @@ export function ChatHeader({ ) : null} - + diff --git a/x-pack/solutions/observability/plugins/observability_ai_assistant_app/public/plugin.tsx b/x-pack/solutions/observability/plugins/observability_ai_assistant_app/public/plugin.tsx index 3de4dad23ec4c..76d5c783302e7 100644 --- a/x-pack/solutions/observability/plugins/observability_ai_assistant_app/public/plugin.tsx +++ b/x-pack/solutions/observability/plugins/observability_ai_assistant_app/public/plugin.tsx @@ -107,7 +107,9 @@ export class ObservabilityAIAssistantAppPlugin const appService = (this.appService = createAppService({ pluginsStart, })); + const isEnabled = appService.isEnabled(); + if (isEnabled) { coreStart.chrome.navControls.registerRight({ mount: (element) => { diff --git a/x-pack/solutions/observability/plugins/observability_ai_assistant_app/public/routes/conversations/conversation_view_with_props.tsx b/x-pack/solutions/observability/plugins/observability_ai_assistant_app/public/routes/conversations/conversation_view_with_props.tsx index 2d28ee0adbaa6..b04e8bac24370 100644 --- a/x-pack/solutions/observability/plugins/observability_ai_assistant_app/public/routes/conversations/conversation_view_with_props.tsx +++ b/x-pack/solutions/observability/plugins/observability_ai_assistant_app/public/routes/conversations/conversation_view_with_props.tsx @@ -14,6 +14,7 @@ export function ConversationViewWithProps() { const { path } = useObservabilityAIAssistantParams('/conversations/*'); const conversationId = 'conversationId' in path ? path.conversationId : undefined; const observabilityAIAssistantRouter = useObservabilityAIAssistantRouter(); + function navigateToConversation(nextConversationId?: string) { if (nextConversationId) { observabilityAIAssistantRouter.push('/conversations/{conversationId}', { @@ -26,6 +27,7 @@ export function ConversationViewWithProps() { observabilityAIAssistantRouter.push('/conversations/new', { path: {}, query: {} }); } } + return (