@8wave/ai-elements 0.119.0-beta.26 → 0.119.0-beta.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/{Agent-D8YrsP52.js → Agent-Gdgpd3LA.js} +66 -66
- package/dist/_chunks/Agent-Gdgpd3LA.js.map +1 -0
- package/dist/_chunks/{PkChatbotFilePreview-DAhN8TyL.js → PkChatbotFilePreview-DiuzVVKH.js} +2 -2
- package/dist/_chunks/{PkChatbotFilePreview-DAhN8TyL.js.map → PkChatbotFilePreview-DiuzVVKH.js.map} +1 -1
- package/dist/_chunks/{PkStreamingMarkdown-Bry3y6Ru.js → PkStreamingMarkdown-DKyHYHUN.js} +890 -853
- package/dist/_chunks/{PkStreamingMarkdown-Bry3y6Ru.js.map → PkStreamingMarkdown-DKyHYHUN.js.map} +1 -1
- package/dist/_chunks/{PkToolEditSpreadsheet-5vHzEy4P.js → PkToolEditSpreadsheet-CfJ3BWMe.js} +3 -3
- package/dist/_chunks/{PkToolEditSpreadsheet-5vHzEy4P.js.map → PkToolEditSpreadsheet-CfJ3BWMe.js.map} +1 -1
- package/dist/_chunks/{PkToolRequestGeolocation-Cj8hTfNF.js → PkToolRequestGeolocation-PxhQxMP1.js} +2 -2
- package/dist/_chunks/{PkToolRequestGeolocation-Cj8hTfNF.js.map → PkToolRequestGeolocation-PxhQxMP1.js.map} +1 -1
- package/dist/_chunks/{PkToolRequestOAuthConnection-BWxR1hV4.js → PkToolRequestOAuthConnection-klmrRZWz.js} +6 -5
- package/dist/_chunks/PkToolRequestOAuthConnection-klmrRZWz.js.map +1 -0
- package/dist/_chunks/{PkToolShowArtifact-CfJLe8vD.js → PkToolShowArtifact-ChDm6ZEK.js} +3 -3
- package/dist/_chunks/PkToolShowArtifact-ChDm6ZEK.js.map +1 -0
- package/dist/_chunks/{PkToolShowCalendarEvent-Bp_yv8S7.js → PkToolShowCalendarEvent-CRVtR3oP.js} +5 -4
- package/dist/_chunks/PkToolShowCalendarEvent-CRVtR3oP.js.map +1 -0
- package/dist/_chunks/{PkToolShowComparison-Bvd4f4tJ.js → PkToolShowComparison-DLC22e1W.js} +4 -3
- package/dist/_chunks/PkToolShowComparison-DLC22e1W.js.map +1 -0
- package/dist/_chunks/{PkToolShowContactForm--9XOVqNB.js → PkToolShowContactForm-CfCy-b8w.js} +6 -6
- package/dist/_chunks/PkToolShowContactForm-CfCy-b8w.js.map +1 -0
- package/dist/_chunks/{PkToolShowDiagram-C-pNbC9n.js → PkToolShowDiagram-JpRMa4Jj.js} +11 -10
- package/dist/_chunks/PkToolShowDiagram-JpRMa4Jj.js.map +1 -0
- package/dist/_chunks/{PkToolShowEmail-BKel_O29.js → PkToolShowEmail-C7mUCqGL.js} +4 -3
- package/dist/_chunks/PkToolShowEmail-C7mUCqGL.js.map +1 -0
- package/dist/_chunks/{PkToolShowForm-CGAc1O6K.js → PkToolShowForm-DnIwTGl4.js} +6 -5
- package/dist/_chunks/PkToolShowForm-DnIwTGl4.js.map +1 -0
- package/dist/_chunks/{PkToolShowImageGallery-CIhIrIcY.js → PkToolShowImageGallery-Ab8fJ9jY.js} +4 -4
- package/dist/_chunks/{PkToolShowImageGallery-CIhIrIcY.js.map → PkToolShowImageGallery-Ab8fJ9jY.js.map} +1 -1
- package/dist/_chunks/{PkToolShowLocation-78C7jFiV.js → PkToolShowLocation-D5d6bbP-.js} +5 -4
- package/dist/_chunks/PkToolShowLocation-D5d6bbP-.js.map +1 -0
- package/dist/_chunks/{PkToolShowMessage-BScy-w4J.js → PkToolShowMessage-vw4XS4TR.js} +4 -3
- package/dist/_chunks/PkToolShowMessage-vw4XS4TR.js.map +1 -0
- package/dist/_chunks/{PkToolShowProductList-BjWKnbyD.js → PkToolShowProductList-DztzZVDd.js} +2 -2
- package/dist/_chunks/{PkToolShowProductList-BjWKnbyD.js.map → PkToolShowProductList-DztzZVDd.js.map} +1 -1
- package/dist/_chunks/{PkToolShowQrCode-B70jPHDw.js → PkToolShowQrCode-BhcAUXSZ.js} +4 -3
- package/dist/_chunks/PkToolShowQrCode-BhcAUXSZ.js.map +1 -0
- package/dist/_chunks/{PkToolShowSources-BJ-XFrLD.js → PkToolShowSources-Bvg3f3GC.js} +52 -51
- package/dist/_chunks/PkToolShowSources-Bvg3f3GC.js.map +1 -0
- package/dist/_chunks/{PkToolShowSuggestedReply-0KahUIlw.js → PkToolShowSuggestedReply-BISQY1ce.js} +2 -2
- package/dist/_chunks/{PkToolShowSuggestedReply-0KahUIlw.js.map → PkToolShowSuggestedReply-BISQY1ce.js.map} +1 -1
- package/dist/_chunks/{PkToolShowVideo-_V_d-PDr.js → PkToolShowVideo-DdoYLl7R.js} +3 -3
- package/dist/_chunks/{PkToolShowVideo-_V_d-PDr.js.map → PkToolShowVideo-DdoYLl7R.js.map} +1 -1
- package/dist/_chunks/{PkToolShowWeather-DfLsFayn.js → PkToolShowWeather-CnpPZCLm.js} +2 -2
- package/dist/_chunks/{PkToolShowWeather-DfLsFayn.js.map → PkToolShowWeather-CnpPZCLm.js.map} +1 -1
- package/dist/_chunks/{PkToolShowWebPages-D55VEPjK.js → PkToolShowWebPages-BooCEJrs.js} +3 -3
- package/dist/_chunks/{PkToolShowWebPages-D55VEPjK.js.map → PkToolShowWebPages-BooCEJrs.js.map} +1 -1
- package/dist/_chunks/VvButtonLocalized-DV-zbH9b.js +21 -0
- package/dist/_chunks/VvButtonLocalized-DV-zbH9b.js.map +1 -0
- package/dist/_chunks/{chatImagePolicy-DXkhb-N_.js → chatImagePolicy-CfJt8_9Z.js} +3 -3
- package/dist/_chunks/{chatImagePolicy-DXkhb-N_.js.map → chatImagePolicy-CfJt8_9Z.js.map} +1 -1
- package/dist/_chunks/{index.es-BrsciU25.js → index.es-oI6RqNZW.js} +2 -2
- package/dist/_chunks/{index.es-BrsciU25.js.map → index.es-oI6RqNZW.js.map} +1 -1
- package/dist/_chunks/{markdown-DpoAzJSk.js → markdown-BbaLt57-.js} +8 -8
- package/dist/_chunks/{markdown-DpoAzJSk.js.map → markdown-BbaLt57-.js.map} +1 -1
- package/dist/_chunks/{src-Dt4rhhPN.js → src-DL9TKN-Z.js} +2 -2
- package/dist/_chunks/src-DL9TKN-Z.js.map +1 -0
- package/dist/_chunks/text-BHCGblDQ.js +6 -0
- package/dist/_chunks/text-BHCGblDQ.js.map +1 -0
- package/dist/_chunks/{useLightbox-pPBe746W.js → useLightbox-1KKLemEE.js} +2 -2
- package/dist/_chunks/{useLightbox-pPBe746W.js.map → useLightbox-1KKLemEE.js.map} +1 -1
- package/dist/ai-elements.es.js +2792 -2529
- package/dist/ai-elements.es.js.map +1 -1
- package/dist-vue/PkChatbot.js +1 -1
- package/dist-vue/PkChatbotAudioTranscript.js +1 -1
- package/dist-vue/PkChatbotAuth.js +1 -1
- package/dist-vue/PkChatbotEmptyState.js +1 -1
- package/dist-vue/PkChatbotError.js +1 -1
- package/dist-vue/PkChatbotFeedbackForm.js +1 -1
- package/dist-vue/PkChatbotFilePreview.js +1 -1
- package/dist-vue/PkChatbotInput.js +1 -1
- package/dist-vue/PkChatbotMessages.js +1 -1
- package/dist-vue/PkChatbotStepPayload.js +1 -1
- package/dist-vue/PkChatbotStepToolDetail.js +1 -1
- package/dist-vue/PkChatbotSteps.js +1 -1
- package/dist-vue/PkChatbotViewChat.js +1 -1
- package/dist-vue/PkChatbotViewConversations.js +1 -1
- package/dist-vue/PkChatbotViewFiles.js +1 -1
- package/dist-vue/PkChatbotViewProfile.js +1 -1
- package/dist-vue/PkChatbotWakeupBar.js +1 -1
- package/dist-vue/_chunks/{Agent-dGF8mkG9.js → Agent-DU1WWaHR.js} +87 -87
- package/dist-vue/_chunks/Agent-DU1WWaHR.js.map +1 -0
- package/dist-vue/_chunks/{Document-CV-RJu_p.js → Document-Cto-Qws0.js} +2 -2
- package/dist-vue/_chunks/{Document-CV-RJu_p.js.map → Document-Cto-Qws0.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbot-536vsOfp.js → PkChatbot-C18mnGJ9.js} +86 -85
- package/dist-vue/_chunks/PkChatbot-C18mnGJ9.js.map +1 -0
- package/dist-vue/_chunks/{PkChatbotAudioTranscript-BUxBHanA.js → PkChatbotAudioTranscript-0rvrhSRQ.js} +2 -2
- package/dist-vue/_chunks/{PkChatbotAudioTranscript-BUxBHanA.js.map → PkChatbotAudioTranscript-0rvrhSRQ.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotAuth-BMLLTSwK.js → PkChatbotAuth-BVZzjbK9.js} +4 -3
- package/dist-vue/_chunks/PkChatbotAuth-BVZzjbK9.js.map +1 -0
- package/dist-vue/_chunks/{PkChatbotEmptyState-Toj4CqXV.js → PkChatbotEmptyState-BKiyP0Ga.js} +2 -2
- package/dist-vue/_chunks/{PkChatbotEmptyState-Toj4CqXV.js.map → PkChatbotEmptyState-BKiyP0Ga.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotError-CRGbK09-.js → PkChatbotError-BV5ga7hk.js} +4 -3
- package/dist-vue/_chunks/PkChatbotError-BV5ga7hk.js.map +1 -0
- package/dist-vue/_chunks/{PkChatbotFeedbackForm-CMFXjoKR.js → PkChatbotFeedbackForm-B5cYsWBr.js} +8 -7
- package/dist-vue/_chunks/PkChatbotFeedbackForm-B5cYsWBr.js.map +1 -0
- package/dist-vue/_chunks/{PkChatbotFilePreview-DIP8KLkS.js → PkChatbotFilePreview-D5H-RIk2.js} +2 -2
- package/dist-vue/_chunks/{PkChatbotFilePreview-DIP8KLkS.js.map → PkChatbotFilePreview-D5H-RIk2.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotInput-BfZqRpQ2.js → PkChatbotInput-GvgsYsUw.js} +8 -7
- package/dist-vue/_chunks/PkChatbotInput-GvgsYsUw.js.map +1 -0
- package/dist-vue/_chunks/PkChatbotMessages-CDLsj7qw.js +876 -0
- package/dist-vue/_chunks/PkChatbotMessages-CDLsj7qw.js.map +1 -0
- package/dist-vue/_chunks/{PkChatbotStepPayload-D0eoPBQ8.js → PkChatbotStepPayload-Dm-HCHcG.js} +2 -2
- package/dist-vue/_chunks/{PkChatbotStepPayload-D0eoPBQ8.js.map → PkChatbotStepPayload-Dm-HCHcG.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotStepToolDetail-CMx4cw1D.js → PkChatbotStepToolDetail-Bpd_cZEO.js} +16 -16
- package/dist-vue/_chunks/{PkChatbotStepToolDetail-CMx4cw1D.js.map → PkChatbotStepToolDetail-Bpd_cZEO.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotSteps-DeZQhGRU.js → PkChatbotSteps-C4qBM3_t.js} +40 -40
- package/dist-vue/_chunks/{PkChatbotSteps-DeZQhGRU.js.map → PkChatbotSteps-C4qBM3_t.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotViewChat-CVT6OUIv.js → PkChatbotViewChat-By2TY72m.js} +13 -13
- package/dist-vue/_chunks/{PkChatbotViewChat-CVT6OUIv.js.map → PkChatbotViewChat-By2TY72m.js.map} +1 -1
- package/dist-vue/_chunks/PkChatbotViewConversations-CU5NfEO4.js +199 -0
- package/dist-vue/_chunks/PkChatbotViewConversations-CU5NfEO4.js.map +1 -0
- package/dist-vue/_chunks/{PkChatbotViewFiles-CA20TBFY.js → PkChatbotViewFiles-CD-UZPT5.js} +18 -17
- package/dist-vue/_chunks/PkChatbotViewFiles-CD-UZPT5.js.map +1 -0
- package/dist-vue/_chunks/{PkChatbotViewProfile-CyzRxE3D.js → PkChatbotViewProfile-DPlb_Wca.js} +11 -10
- package/dist-vue/_chunks/PkChatbotViewProfile-DPlb_Wca.js.map +1 -0
- package/dist-vue/_chunks/{PkChatbotWakeupBar-jBti21FQ.js → PkChatbotWakeupBar-Cjgarxnw.js} +3 -2
- package/dist-vue/_chunks/PkChatbotWakeupBar-Cjgarxnw.js.map +1 -0
- package/dist-vue/_chunks/{PkStreamingMarkdown-C55Fi0Pd.js → PkStreamingMarkdown-CsHzdW69.js} +24 -24
- package/dist-vue/_chunks/{PkStreamingMarkdown-C55Fi0Pd.js.map → PkStreamingMarkdown-CsHzdW69.js.map} +1 -1
- package/dist-vue/_chunks/{PkSvgViewer-Ts3gQ1hB.js → PkSvgViewer-D6DJ2jVO.js} +7 -6
- package/dist-vue/_chunks/PkSvgViewer-D6DJ2jVO.js.map +1 -0
- package/dist-vue/_chunks/{PkToolEditSpreadsheet-HAskd6d3.js → PkToolEditSpreadsheet-D8Zp9gzW.js} +3 -3
- package/dist-vue/_chunks/{PkToolEditSpreadsheet-HAskd6d3.js.map → PkToolEditSpreadsheet-D8Zp9gzW.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolRequestGeolocation-BE22qwxB.js → PkToolRequestGeolocation-JZYgc-2X.js} +2 -2
- package/dist-vue/_chunks/{PkToolRequestGeolocation-BE22qwxB.js.map → PkToolRequestGeolocation-JZYgc-2X.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolRequestOAuthConnection-GfSalEJG.js → PkToolRequestOAuthConnection-DosWR9I4.js} +11 -10
- package/dist-vue/_chunks/PkToolRequestOAuthConnection-DosWR9I4.js.map +1 -0
- package/dist-vue/_chunks/{PkToolShowArtifact-z1qTnFkA.js → PkToolShowArtifact-BVofKJ7b.js} +5 -5
- package/dist-vue/_chunks/PkToolShowArtifact-BVofKJ7b.js.map +1 -0
- package/dist-vue/_chunks/{PkToolShowCalendarEvent-Dv_rss26.js → PkToolShowCalendarEvent-u9O_Sl3-.js} +8 -7
- package/dist-vue/_chunks/PkToolShowCalendarEvent-u9O_Sl3-.js.map +1 -0
- package/dist-vue/_chunks/{PkToolShowComparison-DQs3E6-k.js → PkToolShowComparison-c2e239T4.js} +3 -2
- package/dist-vue/_chunks/PkToolShowComparison-c2e239T4.js.map +1 -0
- package/dist-vue/_chunks/{PkToolShowContactForm-Y0lrHXhr.js → PkToolShowContactForm-BzdIFTnC.js} +13 -13
- package/dist-vue/_chunks/PkToolShowContactForm-BzdIFTnC.js.map +1 -0
- package/dist-vue/_chunks/{PkToolShowDiagram-7WxDObZ6.js → PkToolShowDiagram-CaoB4k6y.js} +11 -10
- package/dist-vue/_chunks/PkToolShowDiagram-CaoB4k6y.js.map +1 -0
- package/dist-vue/_chunks/{PkToolShowEmail-C591LR5N.js → PkToolShowEmail-CUgZN0J5.js} +8 -7
- package/dist-vue/_chunks/PkToolShowEmail-CUgZN0J5.js.map +1 -0
- package/dist-vue/_chunks/{PkToolShowForm-CZFWZub7.js → PkToolShowForm-vYuaPtu0.js} +14 -13
- package/dist-vue/_chunks/PkToolShowForm-vYuaPtu0.js.map +1 -0
- package/dist-vue/_chunks/{PkToolShowImageGallery-CkfXP_lD.js → PkToolShowImageGallery-ooygXk7j.js} +4 -4
- package/dist-vue/_chunks/{PkToolShowImageGallery-CkfXP_lD.js.map → PkToolShowImageGallery-ooygXk7j.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowLocation-Dyz6h_0n.js → PkToolShowLocation-DVMpFdRk.js} +14 -13
- package/dist-vue/_chunks/PkToolShowLocation-DVMpFdRk.js.map +1 -0
- package/dist-vue/_chunks/{PkToolShowMessage-CbXERPHI.js → PkToolShowMessage-ATTN5Hac.js} +8 -7
- package/dist-vue/_chunks/PkToolShowMessage-ATTN5Hac.js.map +1 -0
- package/dist-vue/_chunks/{PkToolShowProductList-De-PtmD-.js → PkToolShowProductList-D-HJ9a_h.js} +2 -2
- package/dist-vue/_chunks/{PkToolShowProductList-De-PtmD-.js.map → PkToolShowProductList-D-HJ9a_h.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowQrCode-DEAvfLFu.js → PkToolShowQrCode-D_5VUtEB.js} +3 -2
- package/dist-vue/_chunks/PkToolShowQrCode-D_5VUtEB.js.map +1 -0
- package/dist-vue/_chunks/{PkToolShowSources-CSN7S0zo.js → PkToolShowSources-DJ35l3Z3.js} +58 -57
- package/dist-vue/_chunks/PkToolShowSources-DJ35l3Z3.js.map +1 -0
- package/dist-vue/_chunks/{PkToolShowSuggestedReply-DjutyiEi.js → PkToolShowSuggestedReply-I6FBos-F.js} +2 -2
- package/dist-vue/_chunks/{PkToolShowSuggestedReply-DjutyiEi.js.map → PkToolShowSuggestedReply-I6FBos-F.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowVideo-B_Q93E2y.js → PkToolShowVideo-xcg1gdIE.js} +3 -3
- package/dist-vue/_chunks/{PkToolShowVideo-B_Q93E2y.js.map → PkToolShowVideo-xcg1gdIE.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowWeather-BOuNrvY2.js → PkToolShowWeather-DJxKxVp_.js} +2 -2
- package/dist-vue/_chunks/{PkToolShowWeather-BOuNrvY2.js.map → PkToolShowWeather-DJxKxVp_.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowWebPages-D3CdjJUc.js → PkToolShowWebPages-BuaRjavD.js} +3 -3
- package/dist-vue/_chunks/{PkToolShowWebPages-D3CdjJUc.js.map → PkToolShowWebPages-BuaRjavD.js.map} +1 -1
- package/dist-vue/_chunks/VvButtonLocalized-BuzLsXp3.js +20 -0
- package/dist-vue/_chunks/VvButtonLocalized-BuzLsXp3.js.map +1 -0
- package/dist-vue/_chunks/{createChatbotApiClient-DSLxswr4.js → createChatbotApiClient-G3Tt1I67.js} +18 -18
- package/dist-vue/_chunks/{createChatbotApiClient-DSLxswr4.js.map → createChatbotApiClient-G3Tt1I67.js.map} +1 -1
- package/dist-vue/_chunks/{mcpOAuthReport-BeZDTl87.js → mcpOAuthReport-3A9v_gW_.js} +2 -2
- package/dist-vue/_chunks/{mcpOAuthReport-BeZDTl87.js.map → mcpOAuthReport-3A9v_gW_.js.map} +1 -1
- package/dist-vue/_chunks/{src-DCfvejyT.js → src-DpkuiHam.js} +2 -2
- package/dist-vue/_chunks/src-DpkuiHam.js.map +1 -0
- package/dist-vue/_chunks/{useChatbotStore-rtl-oKqU.js → useChatbotStore-C1sgxgD1.js} +5 -5
- package/dist-vue/_chunks/{useChatbotStore-rtl-oKqU.js.map → useChatbotStore-C1sgxgD1.js.map} +1 -1
- package/dist-vue/_chunks/{useSafeLocalStorage-OwzVTZud.js → useSafeLocalStorage-DLIc8pkn.js} +2 -2
- package/dist-vue/_chunks/{useSafeLocalStorage-OwzVTZud.js.map → useSafeLocalStorage-DLIc8pkn.js.map} +1 -1
- package/dist-vue/_chunks/{utils-CwIMEuAv.js → utils-DsnEcdW3.js} +143 -79
- package/dist-vue/_chunks/utils-DsnEcdW3.js.map +1 -0
- package/dist-vue/api.js +1 -1
- package/dist-vue/composables.js +279 -27
- package/dist-vue/composables.js.map +1 -1
- package/dist-vue/index.js +3909 -3881
- package/dist-vue/index.js.map +1 -1
- package/dist-vue/locales.js +42 -6
- package/dist-vue/packages/components/src/PkEditorMarkdown.d.ts +3 -2
- package/dist-vue/packages/components/src/VvButtonLocalized.d.ts +11 -0
- package/dist-vue/packages/components/src/chat/index.d.ts +1 -0
- package/dist-vue/packages/components/src/chat/utils.d.ts +30 -0
- package/dist-vue/packages/components/src/index.d.ts +1 -0
- package/package.json +1 -1
- package/dist/_chunks/Agent-D8YrsP52.js.map +0 -1
- package/dist/_chunks/PkToolRequestOAuthConnection-BWxR1hV4.js.map +0 -1
- package/dist/_chunks/PkToolShowArtifact-CfJLe8vD.js.map +0 -1
- package/dist/_chunks/PkToolShowCalendarEvent-Bp_yv8S7.js.map +0 -1
- package/dist/_chunks/PkToolShowComparison-Bvd4f4tJ.js.map +0 -1
- package/dist/_chunks/PkToolShowContactForm--9XOVqNB.js.map +0 -1
- package/dist/_chunks/PkToolShowDiagram-C-pNbC9n.js.map +0 -1
- package/dist/_chunks/PkToolShowEmail-BKel_O29.js.map +0 -1
- package/dist/_chunks/PkToolShowForm-CGAc1O6K.js.map +0 -1
- package/dist/_chunks/PkToolShowLocation-78C7jFiV.js.map +0 -1
- package/dist/_chunks/PkToolShowMessage-BScy-w4J.js.map +0 -1
- package/dist/_chunks/PkToolShowQrCode-B70jPHDw.js.map +0 -1
- package/dist/_chunks/PkToolShowSources-BJ-XFrLD.js.map +0 -1
- package/dist/_chunks/src-Dt4rhhPN.js.map +0 -1
- package/dist/_chunks/text-DbSEK8si.js +0 -6
- package/dist/_chunks/text-DbSEK8si.js.map +0 -1
- package/dist-vue/_chunks/Agent-dGF8mkG9.js.map +0 -1
- package/dist-vue/_chunks/PkChatbot-536vsOfp.js.map +0 -1
- package/dist-vue/_chunks/PkChatbotAuth-BMLLTSwK.js.map +0 -1
- package/dist-vue/_chunks/PkChatbotError-CRGbK09-.js.map +0 -1
- package/dist-vue/_chunks/PkChatbotFeedbackForm-CMFXjoKR.js.map +0 -1
- package/dist-vue/_chunks/PkChatbotInput-BfZqRpQ2.js.map +0 -1
- package/dist-vue/_chunks/PkChatbotMessages-CnI3e9wF.js +0 -869
- package/dist-vue/_chunks/PkChatbotMessages-CnI3e9wF.js.map +0 -1
- package/dist-vue/_chunks/PkChatbotViewConversations-DHeFtAfN.js +0 -197
- package/dist-vue/_chunks/PkChatbotViewConversations-DHeFtAfN.js.map +0 -1
- package/dist-vue/_chunks/PkChatbotViewFiles-CA20TBFY.js.map +0 -1
- package/dist-vue/_chunks/PkChatbotViewProfile-CyzRxE3D.js.map +0 -1
- package/dist-vue/_chunks/PkChatbotWakeupBar-jBti21FQ.js.map +0 -1
- package/dist-vue/_chunks/PkSvgViewer-Ts3gQ1hB.js.map +0 -1
- package/dist-vue/_chunks/PkToolRequestOAuthConnection-GfSalEJG.js.map +0 -1
- package/dist-vue/_chunks/PkToolShowArtifact-z1qTnFkA.js.map +0 -1
- package/dist-vue/_chunks/PkToolShowCalendarEvent-Dv_rss26.js.map +0 -1
- package/dist-vue/_chunks/PkToolShowComparison-DQs3E6-k.js.map +0 -1
- package/dist-vue/_chunks/PkToolShowContactForm-Y0lrHXhr.js.map +0 -1
- package/dist-vue/_chunks/PkToolShowDiagram-7WxDObZ6.js.map +0 -1
- package/dist-vue/_chunks/PkToolShowEmail-C591LR5N.js.map +0 -1
- package/dist-vue/_chunks/PkToolShowForm-CZFWZub7.js.map +0 -1
- package/dist-vue/_chunks/PkToolShowLocation-Dyz6h_0n.js.map +0 -1
- package/dist-vue/_chunks/PkToolShowMessage-CbXERPHI.js.map +0 -1
- package/dist-vue/_chunks/PkToolShowQrCode-DEAvfLFu.js.map +0 -1
- package/dist-vue/_chunks/PkToolShowSources-CSN7S0zo.js.map +0 -1
- package/dist-vue/_chunks/src-DCfvejyT.js.map +0 -1
- package/dist-vue/_chunks/utils-CwIMEuAv.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PkChatbot-536vsOfp.js","names":["_useModel","__unplugin_components_0","__unplugin_components_1","__unplugin_components_2","__unplugin_components_3","__unplugin_components_4","__unplugin_components_5","_openBlock","_createElementBlock","_normalizeClass","_normalizeStyle","_createElementVNode","_unref","_Fragment","_createVNode","_mergeProps","_createBlock","PkAvatar","_createCommentVNode","_toDisplayString","_withCtx","_renderSlot","_normalizeProps","_guardReactiveProps","_createTextVNode","PkChatbotViewChat","_createSlots","_renderList","PkChatbotViewConversations","PkChatbotViewFiles","PkChatbotViewProfile","PkStreamingMarkdown","_sfc_main","provideChatImagePolicy","PkChatbotViewConversations_default","PkChatbotViewChat_default","provideShortUrlResolver","PkChatbotViewFiles_default","useLocalizedString","resolveContrastColor","agentThemeStyle","PkAvatar_default","ChatbotProfileContextKey","PkChatbotViewProfile_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","PkChatbot_default","defineComponent","\"chatId\"","\"chatIdModifiers\"","__expose","__emit","slots","useSlots","$t","useI18n","props","__props","emit","chatId","useModel","store","useChatbotStore","hashes","storeToRefs","storeAgentId","toRef","profile","inject","canManageProfile","computed","canSignIn","watch","canManage","activeView","navigate","watchEffect","id","localChatId","chatError","error","parsedError","isFullscreen","isPanel","chatbotEl","useTemplateRef","chatbotWidth","useElementSize","isPhoneWidth","isTightWidth","isWideWidth","isReasoningAgent","showReasoningNotice","messages","message","useColorsForAgentHeader","showHeaderMenu","themeClass","isDark","mainColor","contrastColor","themeStyle","footerMessage","title","isReady","chat","activeMessage","newAgentId","newChatId","newView","_component_VvButton","VvButton","_component_VvIcon","VvIcon","_component_VvDropdownAction","VvDropdownAction","_component_VvDropdown","VvDropdown","_component_VvButtonGroup","VvButtonGroup","_component_VvAlert","VvAlert","openBlock","createElementBlock","normalizeClass","normalizeStyle","createCommentVNode","createElementVNode","unref","createBlock","Fragment","createVNode","mergeProps","_cache","toDisplayString","withCtx","renderSlot","_ctx","normalizeProps","guardReactiveProps","startNewChat","stopGeneration","createTextVNode","$event","createSlots","renderList","slotName","slotData","PkStreamingMarkdown_default"],"sources":["../../../../packages/components/src/chat/PkChatbot.vue","../../../../packages/components/src/chat/PkChatbot.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import {\n computed,\n inject,\n toRef,\n useTemplateRef,\n watch,\n watchEffect,\n useSlots,\n } from 'vue'\n import { useElementSize } from '@vueuse/core'\n import { storeToRefs } from 'pinia'\n import { useI18n } from 'vue-i18n'\n import type {\n AgentInterface,\n AgentModel,\n AgentFileUpload,\n AgentGatewayOptions,\n AgentVoiceCapability,\n ChatMessageActions,\n RevisedAnswer,\n UIChatMessage,\n AgentTools,\n } from 'models'\n import {\n useChatbotStore,\n useLocalizedString,\n provideShortUrlResolver,\n } from 'composables'\n import PkAvatar from './PkAvatar.vue'\n import PkChatbotViewChat from './PkChatbotViewChat.vue'\n import PkChatbotViewConversations from './PkChatbotViewConversations.vue'\n import PkChatbotViewFiles from './PkChatbotViewFiles.vue'\n import PkChatbotViewProfile from './PkChatbotViewProfile.vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n import { ChatbotProfileContextKey } from './chatbotProfileContext'\n import { provideChatImagePolicy } from './chatImagePolicy'\n import { agentThemeStyle, resolveContrastColor } from './utils'\n\n // Captured in script setup to avoid TS7022 circular inference in template\n const slots = useSlots()\n\n const { t: $t } = useI18n({\n useScope: 'global',\n })\n\n const props = defineProps<{\n baseUrl: string\n basePath?: string\n agentId: string\n agentType?: 'reasoning' | 'chat'\n userId?: string\n name?: string\n model?: string\n agentModel?: AgentModel\n agentTools?: AgentTools\n agentInterface?: AgentInterface\n actions?: ChatMessageActions[]\n revisedAnswers?: RevisedAnswer[]\n headers?: Record<string, string>\n systemTheme?: 'light' | 'dark'\n agentFileUpload?: AgentFileUpload\n /** Voice configuration from the agent settings: enables the talk button. */\n voice?: AgentVoiceCapability\n fallbackModels?: string[]\n gatewayOptions?: Partial<AgentGatewayOptions>\n externalContext?: Record<string, unknown>\n /** Layout modifier: `widget` (default) keeps the contained layout with header, `fullscreen` removes header/background for full-page usage (the page provides the chrome), `panel` keeps the header but slims it down for a docked side panel (the host provides background and border) */\n modifier?: 'widget' | 'fullscreen' | 'panel'\n /** Display name of the current user, used for the `{name}` placeholder in the fullscreen greeting */\n userName?: string\n /** Show the \"Files in this chat\" menu for hosts that don't provide the\n * profile context but whose user is authenticated (e.g. the backoffice\n * playground). The widget host relies on `canManageProfile` instead. */\n userFilesEnabled?: boolean\n }>()\n const emit = defineEmits<{\n 'message-update': [message: UIChatMessage]\n 'show-info': [message: UIChatMessage]\n revise: [message: UIChatMessage]\n error: [error: { type: string; title: string; status: number }]\n }>()\n\n const chatId = defineModel<string | undefined>('chatId', {\n type: String,\n default: undefined,\n })\n\n const store = useChatbotStore(props.agentId)\n\n // Resolve backend short-urls (`/api/r/<hash>`) back to their real target\n // for display in tool components. Batched + cached across the chat tree.\n provideShortUrlResolver((hashes) =>\n store.apiClient.resolveShortUrls(hashes),\n )\n\n const { messages, chat, localChatId, activeView, chatError, isDark } =\n storeToRefs(store)\n\n // Ref to store.agentId for watchers (avoids duplicate-key with agentId prop)\n const storeAgentId = toRef(store, 'agentId')\n\n const { startNewChat, stopGeneration, regenerate, navigate, sendMessage } =\n store\n\n // Images in the answers and the tool cards load by themselves only from\n // the backend this chat talks to and from the hosts the agent lists.\n provideChatImagePolicy(\n () => props.agentInterface?.imageHosts,\n () => props.baseUrl,\n )\n\n // Optional profile-management context provided by the host widget.\n // Present only for authenticated, non-anonymous sessions.\n const profile = inject(ChatbotProfileContextKey, undefined)\n const canManageProfile = computed(\n () => profile?.canManageProfile.value ?? false,\n )\n // Anonymous users get a \"Sign in\" entry instead of the profile one,\n // provided the host filled the `view-auth` slot and the agent has at\n // least one auth method enabled.\n const canSignIn = computed(\n () =>\n !canManageProfile.value &&\n (profile?.canSignIn?.value ?? false) &&\n slots['view-auth'] !== undefined,\n )\n\n // Once the sign-in completes (the session becomes non-anonymous) leave\n // the auth view and return to the conversation.\n watch(canManageProfile, (canManage) => {\n if (canManage && activeView.value === 'auth') {\n navigate('chat')\n }\n })\n\n // Sync props → store reactively\n watchEffect(() => {\n store.baseUrl = props.baseUrl\n store.basePath = props.basePath\n store.name = props.name\n store.agentType = props.agentType\n store.userId = props.userId\n store.agentInterface = props.agentInterface\n store.agentModel = props.agentModel\n store.agentTools = props.agentTools\n store.headers = props.headers\n store.revisedAnswers = props.revisedAnswers\n store.model = props.model\n store.actionsInput = props.actions\n store.agentFileUpload = props.agentFileUpload\n store.agentVoice = props.voice\n store.fallbackModels = props.fallbackModels\n store.gatewayOptions = props.gatewayOptions\n store.externalContext = props.externalContext\n store.systemTheme = props.systemTheme\n store.hideWelcomeMessage = props.modifier === 'fullscreen'\n })\n\n // Sync chatId v-model ↔ store (bidirectional)\n // Parent → store: if the parent provides an external chatId, push it into\n // the store so the Chat instance picks it up.\n watch(\n () => chatId.value,\n (id) => {\n if (id && id !== store.localChatId) {\n store.localChatId = id\n }\n },\n { immediate: true },\n )\n // Store → parent: keep the v-model in sync whenever the store changes\n // the chatId internally (e.g. startNewChat).\n watch(localChatId, (id) => {\n chatId.value = id\n })\n\n // Emit structured errors from chat to the parent component\n watch(chatError, (error) => {\n if (!error) {\n return\n }\n try {\n const parsedError = JSON.parse(error.message) as {\n type: string\n title: string\n status: number\n }\n emit('error', parsedError)\n } catch {\n // ignore non-JSON errors\n }\n })\n\n // ui\n const isFullscreen = computed(() => props.modifier === 'fullscreen')\n const isPanel = computed(() => props.modifier === 'panel')\n\n /**\n * How much room the chat has, measured on the chat and not on the window.\n *\n * The same chat renders in a phone page, in a 408px widget, in a docked\n * panel and in a preview frame that the side panels squeeze to phone width\n * on a desktop screen, so the viewport says nothing about the space the\n * layout actually has. A CSS container query would read the same number\n * with no JavaScript, but `container-type` makes the element a containing\n * block for `position: fixed` descendants on every engine except Chrome\n * 129 and later, which displaces every dropdown in the chat: see\n * docs/agents/gotchas.md, \"The chat measures its own width, and not with a\n * container query\".\n *\n * The thresholds carry the modifiers, so the CSS stays declarative:\n * `--phone` has as much room as a phone page, `--tight` is too tight for\n * the agent chip beside the field, `--wide` has room for the outline rail\n * beside the reading column. Before the first measurement the width is 0\n * and no modifier applies, which is the roomy layout the base CSS writes.\n */\n const chatbotEl = useTemplateRef<HTMLDivElement>('chatbotEl')\n const { width: chatbotWidth } = useElementSize(chatbotEl)\n const isPhoneWidth = computed(\n () => chatbotWidth.value > 0 && chatbotWidth.value < 576,\n )\n const isTightWidth = computed(\n () => chatbotWidth.value > 0 && chatbotWidth.value < 640,\n )\n const isWideWidth = computed(() => chatbotWidth.value >= 848)\n const isReasoningAgent = computed(() => props.agentType === 'reasoning')\n // The notice says how a reasoning agent reads a message: it stands before\n // the first one, then leaves the room to the answers (pinned, it took a\n // third of a phone screen in the reasoning playground)\n const showReasoningNotice = computed(\n () =>\n isReasoningAgent.value &&\n !messages.value.some((message) => message.role === 'user'),\n )\n const useColorsForAgentHeader = computed(\n () => props.agentInterface?.useColorsForAgentHeader,\n )\n // Panel mode promotes the everyday actions (new chat, history) from the\n // dropdown to direct header buttons: the dropdown then only remains for\n // the secondary entries (files, profile, sign-in) and disappears when\n // none of them applies.\n const showHeaderMenu = computed(\n () =>\n !isPanel.value ||\n canManageProfile.value ||\n canSignIn.value ||\n (!!props.userFilesEnabled && !!localChatId.value),\n )\n const themeClass = computed(() => [\n 'theme',\n `theme--${isDark.value ? 'dark' : 'light'}`,\n ])\n const mainColor = computed(() => props.agentInterface?.mainColor)\n const contrastColor = computed(() =>\n resolveContrastColor(props.agentInterface?.textColor, mainColor.value),\n )\n const themeStyle = computed(() =>\n agentThemeStyle(mainColor.value, contrastColor.value),\n )\n const footerMessage = useLocalizedString(\n () => props.agentInterface?.footerMessage,\n )\n const title = computed(() => {\n if (activeView.value === 'conversations') {\n return $t('label.conversations')\n }\n if (activeView.value === 'profile') {\n return $t('label.profile')\n }\n if (activeView.value === 'auth') {\n return $t('label.authentication')\n }\n if (activeView.value === 'files') {\n return $t('userFiles.chatFilesTitle')\n }\n return props.name\n })\n\n // state\n const isReady = computed(() => chat.value.status === 'ready')\n const activeMessage = computed(() => {\n return messages.value?.[messages.value.length - 1]\n })\n\n // expose\n defineExpose({\n startNewChat,\n regenerate,\n stopGeneration,\n sendMessage,\n })\n\n // load chat, conversations and feedbacks on agent or chat change\n watch(\n [storeAgentId, localChatId],\n async ([newAgentId, newChatId]) => {\n await store.initialize(newAgentId, newChatId)\n },\n {\n immediate: true,\n },\n )\n // load conversations when navigating to conversations view\n watch(activeView, (newView) => {\n if (newView === 'conversations') {\n store.loadConversations(storeAgentId.value)\n } else if (newView === 'files') {\n store.loadChatFiles()\n }\n })\n // emit message updates for up-to-date context in parent components\n watch(\n activeMessage,\n (message) => {\n if (message) {\n emit('message-update', message)\n }\n },\n {\n deep: true,\n immediate: true,\n },\n )\n</script>\n\n<template>\n <div\n ref=\"chatbotEl\"\n class=\"pk-chatbot\"\n :class=\"[\n themeClass,\n {\n 'pk-chatbot--fullscreen': isFullscreen,\n 'pk-chatbot--panel': isPanel,\n 'pk-chatbot--phone': isPhoneWidth,\n 'pk-chatbot--tight': isTightWidth,\n 'pk-chatbot--wide': isWideWidth,\n },\n ]\"\n :style=\"themeStyle\">\n <!-- #region title -->\n <div\n v-if=\"!isFullscreen\"\n class=\"pk-chatbot__header\"\n :style=\"\n useColorsForAgentHeader\n ? {\n backgroundColor: mainColor,\n }\n : undefined\n \">\n <div class=\"pk-chatbot__header-start\">\n <template v-if=\"activeView !== 'chat'\">\n <VvButton\n v-bind=\"{\n modifiers: useColorsForAgentHeader\n ? `action-quiet-${contrastColor}`\n : 'action-quiet',\n icon: 'ri:arrow-left-s-line',\n title: $t('action.goBack'),\n }\"\n @click=\"navigate('chat')\" />\n <VvIcon\n :name=\"\n activeView === 'conversations'\n ? 'ri:history-line'\n : activeView === 'files'\n ? 'ri:attachment-2'\n : 'ri:user-line'\n \"\n class=\"pk-chatbot__nav-icon\"\n :style=\"\n useColorsForAgentHeader\n ? {\n color: contrastColor,\n }\n : undefined\n \" />\n </template>\n <!-- Panel mode: no avatar, the docked panel identifies the\n agent with the title alone -->\n <PkAvatar\n v-else-if=\"!isPanel\"\n modifiers=\"surface ring shrink-0\"\n class=\"pk-chatbot__avatar\"\n :name\n :img-src=\"agentInterface?.logo\" />\n <strong\n class=\"pk-chatbot__title\"\n :title=\"title\"\n :style=\"\n useColorsForAgentHeader\n ? {\n color: contrastColor,\n }\n : undefined\n \">\n {{ title }}\n </strong>\n </div>\n <VvButtonGroup class=\"pk-chatbot__header-end\" modifiers=\"compact\">\n <slot\n name=\"header-actions\"\n v-bind=\"{\n mainColor,\n useColorsForAgentHeader,\n contrastColor,\n startNewChat,\n stopGeneration,\n }\" />\n <template v-if=\"isPanel\">\n <VvButton\n :modifiers=\"\n useColorsForAgentHeader\n ? `action-quiet-${contrastColor}`\n : 'action-quiet'\n \"\n icon=\"ri:edit-box-line\"\n :disabled=\"!isReady\"\n :title=\"$t('action.startNewChat')\"\n @click=\"startNewChat()\" />\n <VvButton\n v-if=\"!isReasoningAgent\"\n :modifiers=\"\n useColorsForAgentHeader\n ? `action-quiet-${contrastColor}`\n : 'action-quiet'\n \"\n icon=\"ri:history-line\"\n :disabled=\"!isReady\"\n :title=\"$t('action.viewRecentChats')\"\n @click=\"navigate('conversations')\" />\n </template>\n <VvDropdown\n v-if=\"showHeaderMenu\"\n v-bind=\"{\n placement: 'bottom-end',\n modifiers: 'menu',\n flip: true,\n offset: 3,\n strategy: 'fixed',\n }\">\n <VvButton\n v-bind=\"{\n modifiers: useColorsForAgentHeader\n ? `action-quiet-${contrastColor}`\n : 'action-quiet',\n icon: 'ri:more-2-fill',\n disabled: !isReady,\n title: $t('action.moreActions'),\n }\" />\n <template #items>\n <VvDropdownAction\n v-if=\"!isPanel\"\n @click=\"startNewChat()\">\n <VvIcon name=\"ri:edit-box-line\" />\n {{ $t('action.startNewChat') }}\n </VvDropdownAction>\n <VvDropdownAction\n v-if=\"!isReasoningAgent && !isPanel\"\n @click=\"navigate('conversations')\">\n <VvIcon name=\"ri:history-line\" />\n {{ $t('action.viewRecentChats') }}\n </VvDropdownAction>\n <VvDropdownAction\n v-if=\"\n (canManageProfile || userFilesEnabled) &&\n localChatId\n \"\n @click=\"navigate('files')\">\n <VvIcon name=\"ri:attachment-2\" />\n {{ $t('userFiles.chatFilesTitle') }}\n </VvDropdownAction>\n <VvDropdownAction\n v-if=\"canManageProfile\"\n @click=\"navigate('profile')\">\n <VvIcon name=\"ri:user-line\" />\n {{ $t('label.profile') }}\n </VvDropdownAction>\n <VvDropdownAction\n v-else-if=\"canSignIn\"\n @click=\"navigate('auth')\">\n <VvIcon name=\"ri:account-circle-line\" />\n {{ $t('action.signIn') }}\n </VvDropdownAction>\n </template>\n </VvDropdown>\n <slot\n name=\"actions\"\n v-bind=\"{\n mainColor,\n useColorsForAgentHeader,\n contrastColor,\n startNewChat,\n stopGeneration,\n }\" />\n </VvButtonGroup>\n </div>\n <!-- #endregion -->\n\n <div v-if=\"showReasoningNotice\">\n <div class=\"pk-chatbot__warning-body\">\n <VvAlert modifiers=\"callout\">\n <div class=\"pk-chatbot__warning-header\">\n <VvIcon\n name=\"ri:alert-line\"\n class=\"pk-chatbot__warning-icon\" />\n <strong class=\"pk-chatbot__warning-title\">\n {{ $t('message.warning') }}\n </strong>\n </div>\n <p class=\"pk-chatbot__warning-text\">\n {{ $t('message.reasoningAgent') }}\n </p>\n </VvAlert>\n </div>\n </div>\n\n <!-- #region views -->\n <PkChatbotViewChat\n v-if=\"activeView === 'chat'\"\n :agent-id\n :modifier\n :user-name\n @show-info=\"emit('show-info', $event)\"\n @revise=\"emit('revise', $event)\">\n <template\n v-for=\"slotName in Object.keys(slots)\"\n #[slotName]=\"slotData\"\n ><slot :name=\"slotName\" v-bind=\"slotData\"\n /></template>\n </PkChatbotViewChat>\n <PkChatbotViewConversations\n v-else-if=\"activeView === 'conversations'\"\n :agent-id>\n <template\n v-for=\"slotName in Object.keys(slots)\"\n #[slotName]=\"slotData\"\n ><slot :name=\"slotName\" v-bind=\"slotData\"\n /></template>\n </PkChatbotViewConversations>\n <PkChatbotViewFiles v-else-if=\"activeView === 'files'\" :agent-id />\n <div\n v-else-if=\"activeView === 'auth'\"\n class=\"pk-chatbot__view-auth flex-1 min-h-0 overflow-y-auto\">\n <!-- Sign-in form provided by the host widget (owns the auth client) -->\n <slot name=\"view-auth\" />\n </div>\n <PkChatbotViewProfile v-else :agent-id>\n <template\n v-for=\"slotName in Object.keys(slots)\"\n #[slotName]=\"slotData\"\n ><slot :name=\"slotName\" v-bind=\"slotData\"\n /></template>\n </PkChatbotViewProfile>\n <!-- #endregion -->\n\n <!-- #region footer -->\n <div v-if=\"footerMessage\" class=\"pk-chatbot__footer\">\n <PkStreamingMarkdown :markdown=\"footerMessage\" class=\"wysiwyg\" />\n </div>\n <!-- #endregion -->\n </div>\n</template>\n\n<style lang=\"scss\">\n .pk-chatbot {\n display: flex;\n flex-direction: column;\n position: relative;\n height: 100%;\n background-color: var(--color-surface);\n\n &__header {\n position: sticky;\n top: 0;\n z-index: 1;\n display: flex;\n justify-content: space-between;\n gap: var(--spacing-14);\n background-color: var(--color-surface-1);\n padding: var(--spacing-14);\n border-bottom: 1px solid var(--color-surface-3);\n }\n\n &__header-start {\n display: flex;\n align-items: center;\n gap: var(--spacing-sm);\n min-width: 0;\n }\n\n &__nav-icon {\n font-size: var(--text-18);\n }\n\n &__avatar {\n width: var(--spacing-24);\n height: var(--spacing-24);\n }\n\n &__title {\n font-size: var(--text-16);\n font-weight: var(--font-semibold);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n &__header-end {\n flex-shrink: 0;\n }\n\n &__warning-body {\n padding: var(--spacing-md);\n border-bottom: 1px solid var(--color-surface-3);\n }\n\n &__warning-header {\n display: flex;\n align-items: center;\n gap: var(--spacing-4);\n margin-bottom: var(--spacing-4);\n }\n\n &__warning-icon {\n width: var(--spacing-16);\n height: var(--spacing-16);\n }\n\n &__warning-title {\n font-weight: 600;\n font-size: var(--text-14);\n }\n\n &__warning-text {\n font-size: var(--text-12);\n color: var(--color-word-3);\n }\n\n &__footer {\n padding: var(--spacing-md);\n border-top: 1px solid var(--color-surface-3);\n text-align: center;\n font-size: var(--text-12);\n color: var(--color-word-2);\n }\n\n // Modifier: fullscreen — layout full-page (Gemini-style): nessun\n // header interno, sfondo trasparente, input pill centrato.\n // Il chrome (sidebar, navigazione) è gestito dalla pagina ospite.\n &--fullscreen {\n // The dock, 60px. Declared rather than taken from the agent chip,\n // which the tight layout hides: the pill fell to 54px there and\n // the call bar that takes its place stayed at 60. There is no 60\n // in the spacing scale and a raw `60px` would stop following the\n // root font size, which the labels inside do follow.\n --pk-chat-fullscreen-dock-height: calc(\n var(--spacing-56) + var(--spacing-4)\n );\n // The pill, the notice that tucks into its top corners and the\n // call bar all round their ends on half of it.\n --pk-chat-dock-radius: calc(\n var(--pk-chat-fullscreen-dock-height) / 2\n );\n\n background-color: transparent;\n\n .pk-chatbot__footer {\n border-top: none;\n padding: 0 var(--spacing-md) var(--spacing-sm) var(--spacing-md);\n }\n\n // Reading column aligned with the input (Gemini-style). The\n // constraint lives on the inner wrapper so the scroll container\n // spans the page and the scrollbar sits at its edge.\n .pk-chatbot-messages {\n // Symmetric gutters: a visible scrollbar would otherwise\n // shrink the content box on one side only, shifting the\n // column off the input axis\n scrollbar-gutter: stable both-edges;\n // Dissolve the content at both edges (works on any page\n // background, dots included — a surface-colored fade band\n // would cut through the pattern instead)\n mask-image: linear-gradient(\n to bottom,\n transparent 0,\n #000 var(--spacing-40),\n #000 calc(100% - var(--spacing-40)),\n transparent 100%\n );\n // Resting clearance so the first/last lines sit inside the\n // fully opaque zone\n padding-block: var(--spacing-48);\n }\n\n .pk-chatbot-messages__wrapper {\n width: 100%;\n max-width: 768px;\n margin-inline: auto;\n }\n\n // Outline rail: wide chats only, measured on the chat and not on\n // the viewport, so a preview frame squeezed by side panels loses\n // it like a phone does. The rail sits at the edge of the scroll\n // area beside the reading column: below the `--wide` threshold\n // (768px column plus a 40px rail on each side) it would cover the\n // messages instead.\n .pk-chatbot-messages__outline {\n display: none;\n }\n\n &.pk-chatbot--wide .pk-chatbot-messages__outline {\n display: block;\n }\n\n .pk-chatbot-file-preview {\n background-color: var(--color-surface);\n }\n\n .pk-chatbot-input__notice {\n background-color: var(--color-surface);\n border-inline: 1px solid var(--color-surface-3);\n border-top: 1px solid var(--color-surface-2);\n padding: var(--spacing-10) var(--spacing-16);\n\n // As deep as the pill's corners, or the page shows through\n // where their curve leaves the side\n &::after {\n background-color: var(--color-surface);\n border-inline: 1px solid var(--color-surface-2);\n bottom: calc(-1 * var(--pk-chat-dock-radius));\n height: var(--pk-chat-dock-radius);\n left: -1px;\n right: -1px;\n }\n }\n\n .pk-chatbot-input {\n width: calc(100% - var(--spacing-sm) * 2);\n max-width: 768px;\n margin-inline: auto;\n\n &__form {\n // True semicircles at rest, concentric with the send\n // button, whose center sits 30px in. Not `rounded-full`:\n // once Shift+Enter grows the field the ends would swell\n // with it and cut into the first and last line.\n border-radius: var(--pk-chat-dock-radius);\n min-height: var(--pk-chat-fullscreen-dock-height);\n padding: var(--spacing-12) var(--spacing-16);\n background-color: var(--color-surface-1);\n border-color: var(--color-surface-2);\n box-shadow: none;\n transition:\n border-color var(--duration-200) var(--ease-in-out),\n box-shadow var(--duration-200) var(--ease-in-out);\n\n &:has(:focus-within) {\n border-color: var(--color-surface-4);\n box-shadow: var(--shadow-sm);\n }\n\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n }\n\n &__textarea {\n background-color: transparent;\n }\n }\n\n // A live call takes the place of the input, so it takes its shape,\n // its column and its height: full-bleed here would break the\n // reading axis, and a different height would make the dock jump\n // the moment the call starts.\n .pk-voice-session {\n --pk-chat-dock-height: var(--pk-chat-fullscreen-dock-height);\n --pk-voice-orb-size: var(--spacing-40);\n --pk-voice-orb-bars-height: var(--spacing-20);\n --pk-voice-session-surface: var(--color-surface-1);\n width: calc(100% - var(--spacing-sm) * 2);\n max-width: 768px;\n margin-inline: auto;\n padding-inline: var(--spacing-16);\n border-color: var(--color-surface-2);\n border-radius: var(--pk-chat-dock-radius);\n box-shadow: none;\n\n &__timer {\n font-size: var(--text-14);\n }\n }\n }\n\n // Modifier: panel — compact chrome for a docked side panel: the host\n // container owns background and border, the header slims down and\n // drops its own surface so the chat blends into the panel.\n &--panel {\n background-color: transparent;\n\n .pk-chatbot__header {\n background-color: transparent;\n\n // Fixed height so the panel header lines up with the host's\n // own chrome. Custom properties inherit through the shadow\n // root: an embedding host can override it to match its\n // header (the default matches the platform header, 50px).\n height: var(--pk-chatbot-panel-header-height, 50px);\n align-items: center;\n padding-block: 0;\n padding-inline: var(--spacing-10);\n border-bottom: 1px solid var(--color-surface-3);\n }\n\n .pk-chatbot__title {\n font-size: var(--text-14);\n }\n\n .pk-chatbot__footer {\n border-top: none;\n padding: var(--spacing-6) var(--spacing-md);\n }\n }\n\n // A chat given a whole page without the fullscreen layout (the page\n // an iframe embeds, a widget its host lets fill the screen) keeps the\n // reading column of the fullscreen one: at 1440px an answer ran\n // 1408px wide, some two hundred characters a line. Measured on the\n // chat, like `--wide` itself, so a narrow frame is left alone.\n &--wide:not(.pk-chatbot--fullscreen) {\n .pk-chatbot-messages__wrapper,\n .pk-chatbot-input {\n width: 100%;\n max-width: 768px;\n margin-inline: auto;\n }\n }\n }\n</style>\n","<script setup lang=\"ts\">\n import {\n computed,\n inject,\n toRef,\n useTemplateRef,\n watch,\n watchEffect,\n useSlots,\n } from 'vue'\n import { useElementSize } from '@vueuse/core'\n import { storeToRefs } from 'pinia'\n import { useI18n } from 'vue-i18n'\n import type {\n AgentInterface,\n AgentModel,\n AgentFileUpload,\n AgentGatewayOptions,\n AgentVoiceCapability,\n ChatMessageActions,\n RevisedAnswer,\n UIChatMessage,\n AgentTools,\n } from 'models'\n import {\n useChatbotStore,\n useLocalizedString,\n provideShortUrlResolver,\n } from 'composables'\n import PkAvatar from './PkAvatar.vue'\n import PkChatbotViewChat from './PkChatbotViewChat.vue'\n import PkChatbotViewConversations from './PkChatbotViewConversations.vue'\n import PkChatbotViewFiles from './PkChatbotViewFiles.vue'\n import PkChatbotViewProfile from './PkChatbotViewProfile.vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n import { ChatbotProfileContextKey } from './chatbotProfileContext'\n import { provideChatImagePolicy } from './chatImagePolicy'\n import { agentThemeStyle, resolveContrastColor } from './utils'\n\n // Captured in script setup to avoid TS7022 circular inference in template\n const slots = useSlots()\n\n const { t: $t } = useI18n({\n useScope: 'global',\n })\n\n const props = defineProps<{\n baseUrl: string\n basePath?: string\n agentId: string\n agentType?: 'reasoning' | 'chat'\n userId?: string\n name?: string\n model?: string\n agentModel?: AgentModel\n agentTools?: AgentTools\n agentInterface?: AgentInterface\n actions?: ChatMessageActions[]\n revisedAnswers?: RevisedAnswer[]\n headers?: Record<string, string>\n systemTheme?: 'light' | 'dark'\n agentFileUpload?: AgentFileUpload\n /** Voice configuration from the agent settings: enables the talk button. */\n voice?: AgentVoiceCapability\n fallbackModels?: string[]\n gatewayOptions?: Partial<AgentGatewayOptions>\n externalContext?: Record<string, unknown>\n /** Layout modifier: `widget` (default) keeps the contained layout with header, `fullscreen` removes header/background for full-page usage (the page provides the chrome), `panel` keeps the header but slims it down for a docked side panel (the host provides background and border) */\n modifier?: 'widget' | 'fullscreen' | 'panel'\n /** Display name of the current user, used for the `{name}` placeholder in the fullscreen greeting */\n userName?: string\n /** Show the \"Files in this chat\" menu for hosts that don't provide the\n * profile context but whose user is authenticated (e.g. the backoffice\n * playground). The widget host relies on `canManageProfile` instead. */\n userFilesEnabled?: boolean\n }>()\n const emit = defineEmits<{\n 'message-update': [message: UIChatMessage]\n 'show-info': [message: UIChatMessage]\n revise: [message: UIChatMessage]\n error: [error: { type: string; title: string; status: number }]\n }>()\n\n const chatId = defineModel<string | undefined>('chatId', {\n type: String,\n default: undefined,\n })\n\n const store = useChatbotStore(props.agentId)\n\n // Resolve backend short-urls (`/api/r/<hash>`) back to their real target\n // for display in tool components. Batched + cached across the chat tree.\n provideShortUrlResolver((hashes) =>\n store.apiClient.resolveShortUrls(hashes),\n )\n\n const { messages, chat, localChatId, activeView, chatError, isDark } =\n storeToRefs(store)\n\n // Ref to store.agentId for watchers (avoids duplicate-key with agentId prop)\n const storeAgentId = toRef(store, 'agentId')\n\n const { startNewChat, stopGeneration, regenerate, navigate, sendMessage } =\n store\n\n // Images in the answers and the tool cards load by themselves only from\n // the backend this chat talks to and from the hosts the agent lists.\n provideChatImagePolicy(\n () => props.agentInterface?.imageHosts,\n () => props.baseUrl,\n )\n\n // Optional profile-management context provided by the host widget.\n // Present only for authenticated, non-anonymous sessions.\n const profile = inject(ChatbotProfileContextKey, undefined)\n const canManageProfile = computed(\n () => profile?.canManageProfile.value ?? false,\n )\n // Anonymous users get a \"Sign in\" entry instead of the profile one,\n // provided the host filled the `view-auth` slot and the agent has at\n // least one auth method enabled.\n const canSignIn = computed(\n () =>\n !canManageProfile.value &&\n (profile?.canSignIn?.value ?? false) &&\n slots['view-auth'] !== undefined,\n )\n\n // Once the sign-in completes (the session becomes non-anonymous) leave\n // the auth view and return to the conversation.\n watch(canManageProfile, (canManage) => {\n if (canManage && activeView.value === 'auth') {\n navigate('chat')\n }\n })\n\n // Sync props → store reactively\n watchEffect(() => {\n store.baseUrl = props.baseUrl\n store.basePath = props.basePath\n store.name = props.name\n store.agentType = props.agentType\n store.userId = props.userId\n store.agentInterface = props.agentInterface\n store.agentModel = props.agentModel\n store.agentTools = props.agentTools\n store.headers = props.headers\n store.revisedAnswers = props.revisedAnswers\n store.model = props.model\n store.actionsInput = props.actions\n store.agentFileUpload = props.agentFileUpload\n store.agentVoice = props.voice\n store.fallbackModels = props.fallbackModels\n store.gatewayOptions = props.gatewayOptions\n store.externalContext = props.externalContext\n store.systemTheme = props.systemTheme\n store.hideWelcomeMessage = props.modifier === 'fullscreen'\n })\n\n // Sync chatId v-model ↔ store (bidirectional)\n // Parent → store: if the parent provides an external chatId, push it into\n // the store so the Chat instance picks it up.\n watch(\n () => chatId.value,\n (id) => {\n if (id && id !== store.localChatId) {\n store.localChatId = id\n }\n },\n { immediate: true },\n )\n // Store → parent: keep the v-model in sync whenever the store changes\n // the chatId internally (e.g. startNewChat).\n watch(localChatId, (id) => {\n chatId.value = id\n })\n\n // Emit structured errors from chat to the parent component\n watch(chatError, (error) => {\n if (!error) {\n return\n }\n try {\n const parsedError = JSON.parse(error.message) as {\n type: string\n title: string\n status: number\n }\n emit('error', parsedError)\n } catch {\n // ignore non-JSON errors\n }\n })\n\n // ui\n const isFullscreen = computed(() => props.modifier === 'fullscreen')\n const isPanel = computed(() => props.modifier === 'panel')\n\n /**\n * How much room the chat has, measured on the chat and not on the window.\n *\n * The same chat renders in a phone page, in a 408px widget, in a docked\n * panel and in a preview frame that the side panels squeeze to phone width\n * on a desktop screen, so the viewport says nothing about the space the\n * layout actually has. A CSS container query would read the same number\n * with no JavaScript, but `container-type` makes the element a containing\n * block for `position: fixed` descendants on every engine except Chrome\n * 129 and later, which displaces every dropdown in the chat: see\n * docs/agents/gotchas.md, \"The chat measures its own width, and not with a\n * container query\".\n *\n * The thresholds carry the modifiers, so the CSS stays declarative:\n * `--phone` has as much room as a phone page, `--tight` is too tight for\n * the agent chip beside the field, `--wide` has room for the outline rail\n * beside the reading column. Before the first measurement the width is 0\n * and no modifier applies, which is the roomy layout the base CSS writes.\n */\n const chatbotEl = useTemplateRef<HTMLDivElement>('chatbotEl')\n const { width: chatbotWidth } = useElementSize(chatbotEl)\n const isPhoneWidth = computed(\n () => chatbotWidth.value > 0 && chatbotWidth.value < 576,\n )\n const isTightWidth = computed(\n () => chatbotWidth.value > 0 && chatbotWidth.value < 640,\n )\n const isWideWidth = computed(() => chatbotWidth.value >= 848)\n const isReasoningAgent = computed(() => props.agentType === 'reasoning')\n // The notice says how a reasoning agent reads a message: it stands before\n // the first one, then leaves the room to the answers (pinned, it took a\n // third of a phone screen in the reasoning playground)\n const showReasoningNotice = computed(\n () =>\n isReasoningAgent.value &&\n !messages.value.some((message) => message.role === 'user'),\n )\n const useColorsForAgentHeader = computed(\n () => props.agentInterface?.useColorsForAgentHeader,\n )\n // Panel mode promotes the everyday actions (new chat, history) from the\n // dropdown to direct header buttons: the dropdown then only remains for\n // the secondary entries (files, profile, sign-in) and disappears when\n // none of them applies.\n const showHeaderMenu = computed(\n () =>\n !isPanel.value ||\n canManageProfile.value ||\n canSignIn.value ||\n (!!props.userFilesEnabled && !!localChatId.value),\n )\n const themeClass = computed(() => [\n 'theme',\n `theme--${isDark.value ? 'dark' : 'light'}`,\n ])\n const mainColor = computed(() => props.agentInterface?.mainColor)\n const contrastColor = computed(() =>\n resolveContrastColor(props.agentInterface?.textColor, mainColor.value),\n )\n const themeStyle = computed(() =>\n agentThemeStyle(mainColor.value, contrastColor.value),\n )\n const footerMessage = useLocalizedString(\n () => props.agentInterface?.footerMessage,\n )\n const title = computed(() => {\n if (activeView.value === 'conversations') {\n return $t('label.conversations')\n }\n if (activeView.value === 'profile') {\n return $t('label.profile')\n }\n if (activeView.value === 'auth') {\n return $t('label.authentication')\n }\n if (activeView.value === 'files') {\n return $t('userFiles.chatFilesTitle')\n }\n return props.name\n })\n\n // state\n const isReady = computed(() => chat.value.status === 'ready')\n const activeMessage = computed(() => {\n return messages.value?.[messages.value.length - 1]\n })\n\n // expose\n defineExpose({\n startNewChat,\n regenerate,\n stopGeneration,\n sendMessage,\n })\n\n // load chat, conversations and feedbacks on agent or chat change\n watch(\n [storeAgentId, localChatId],\n async ([newAgentId, newChatId]) => {\n await store.initialize(newAgentId, newChatId)\n },\n {\n immediate: true,\n },\n )\n // load conversations when navigating to conversations view\n watch(activeView, (newView) => {\n if (newView === 'conversations') {\n store.loadConversations(storeAgentId.value)\n } else if (newView === 'files') {\n store.loadChatFiles()\n }\n })\n // emit message updates for up-to-date context in parent components\n watch(\n activeMessage,\n (message) => {\n if (message) {\n emit('message-update', message)\n }\n },\n {\n deep: true,\n immediate: true,\n },\n )\n</script>\n\n<template>\n <div\n ref=\"chatbotEl\"\n class=\"pk-chatbot\"\n :class=\"[\n themeClass,\n {\n 'pk-chatbot--fullscreen': isFullscreen,\n 'pk-chatbot--panel': isPanel,\n 'pk-chatbot--phone': isPhoneWidth,\n 'pk-chatbot--tight': isTightWidth,\n 'pk-chatbot--wide': isWideWidth,\n },\n ]\"\n :style=\"themeStyle\">\n <!-- #region title -->\n <div\n v-if=\"!isFullscreen\"\n class=\"pk-chatbot__header\"\n :style=\"\n useColorsForAgentHeader\n ? {\n backgroundColor: mainColor,\n }\n : undefined\n \">\n <div class=\"pk-chatbot__header-start\">\n <template v-if=\"activeView !== 'chat'\">\n <VvButton\n v-bind=\"{\n modifiers: useColorsForAgentHeader\n ? `action-quiet-${contrastColor}`\n : 'action-quiet',\n icon: 'ri:arrow-left-s-line',\n title: $t('action.goBack'),\n }\"\n @click=\"navigate('chat')\" />\n <VvIcon\n :name=\"\n activeView === 'conversations'\n ? 'ri:history-line'\n : activeView === 'files'\n ? 'ri:attachment-2'\n : 'ri:user-line'\n \"\n class=\"pk-chatbot__nav-icon\"\n :style=\"\n useColorsForAgentHeader\n ? {\n color: contrastColor,\n }\n : undefined\n \" />\n </template>\n <!-- Panel mode: no avatar, the docked panel identifies the\n agent with the title alone -->\n <PkAvatar\n v-else-if=\"!isPanel\"\n modifiers=\"surface ring shrink-0\"\n class=\"pk-chatbot__avatar\"\n :name\n :img-src=\"agentInterface?.logo\" />\n <strong\n class=\"pk-chatbot__title\"\n :title=\"title\"\n :style=\"\n useColorsForAgentHeader\n ? {\n color: contrastColor,\n }\n : undefined\n \">\n {{ title }}\n </strong>\n </div>\n <VvButtonGroup class=\"pk-chatbot__header-end\" modifiers=\"compact\">\n <slot\n name=\"header-actions\"\n v-bind=\"{\n mainColor,\n useColorsForAgentHeader,\n contrastColor,\n startNewChat,\n stopGeneration,\n }\" />\n <template v-if=\"isPanel\">\n <VvButton\n :modifiers=\"\n useColorsForAgentHeader\n ? `action-quiet-${contrastColor}`\n : 'action-quiet'\n \"\n icon=\"ri:edit-box-line\"\n :disabled=\"!isReady\"\n :title=\"$t('action.startNewChat')\"\n @click=\"startNewChat()\" />\n <VvButton\n v-if=\"!isReasoningAgent\"\n :modifiers=\"\n useColorsForAgentHeader\n ? `action-quiet-${contrastColor}`\n : 'action-quiet'\n \"\n icon=\"ri:history-line\"\n :disabled=\"!isReady\"\n :title=\"$t('action.viewRecentChats')\"\n @click=\"navigate('conversations')\" />\n </template>\n <VvDropdown\n v-if=\"showHeaderMenu\"\n v-bind=\"{\n placement: 'bottom-end',\n modifiers: 'menu',\n flip: true,\n offset: 3,\n strategy: 'fixed',\n }\">\n <VvButton\n v-bind=\"{\n modifiers: useColorsForAgentHeader\n ? `action-quiet-${contrastColor}`\n : 'action-quiet',\n icon: 'ri:more-2-fill',\n disabled: !isReady,\n title: $t('action.moreActions'),\n }\" />\n <template #items>\n <VvDropdownAction\n v-if=\"!isPanel\"\n @click=\"startNewChat()\">\n <VvIcon name=\"ri:edit-box-line\" />\n {{ $t('action.startNewChat') }}\n </VvDropdownAction>\n <VvDropdownAction\n v-if=\"!isReasoningAgent && !isPanel\"\n @click=\"navigate('conversations')\">\n <VvIcon name=\"ri:history-line\" />\n {{ $t('action.viewRecentChats') }}\n </VvDropdownAction>\n <VvDropdownAction\n v-if=\"\n (canManageProfile || userFilesEnabled) &&\n localChatId\n \"\n @click=\"navigate('files')\">\n <VvIcon name=\"ri:attachment-2\" />\n {{ $t('userFiles.chatFilesTitle') }}\n </VvDropdownAction>\n <VvDropdownAction\n v-if=\"canManageProfile\"\n @click=\"navigate('profile')\">\n <VvIcon name=\"ri:user-line\" />\n {{ $t('label.profile') }}\n </VvDropdownAction>\n <VvDropdownAction\n v-else-if=\"canSignIn\"\n @click=\"navigate('auth')\">\n <VvIcon name=\"ri:account-circle-line\" />\n {{ $t('action.signIn') }}\n </VvDropdownAction>\n </template>\n </VvDropdown>\n <slot\n name=\"actions\"\n v-bind=\"{\n mainColor,\n useColorsForAgentHeader,\n contrastColor,\n startNewChat,\n stopGeneration,\n }\" />\n </VvButtonGroup>\n </div>\n <!-- #endregion -->\n\n <div v-if=\"showReasoningNotice\">\n <div class=\"pk-chatbot__warning-body\">\n <VvAlert modifiers=\"callout\">\n <div class=\"pk-chatbot__warning-header\">\n <VvIcon\n name=\"ri:alert-line\"\n class=\"pk-chatbot__warning-icon\" />\n <strong class=\"pk-chatbot__warning-title\">\n {{ $t('message.warning') }}\n </strong>\n </div>\n <p class=\"pk-chatbot__warning-text\">\n {{ $t('message.reasoningAgent') }}\n </p>\n </VvAlert>\n </div>\n </div>\n\n <!-- #region views -->\n <PkChatbotViewChat\n v-if=\"activeView === 'chat'\"\n :agent-id\n :modifier\n :user-name\n @show-info=\"emit('show-info', $event)\"\n @revise=\"emit('revise', $event)\">\n <template\n v-for=\"slotName in Object.keys(slots)\"\n #[slotName]=\"slotData\"\n ><slot :name=\"slotName\" v-bind=\"slotData\"\n /></template>\n </PkChatbotViewChat>\n <PkChatbotViewConversations\n v-else-if=\"activeView === 'conversations'\"\n :agent-id>\n <template\n v-for=\"slotName in Object.keys(slots)\"\n #[slotName]=\"slotData\"\n ><slot :name=\"slotName\" v-bind=\"slotData\"\n /></template>\n </PkChatbotViewConversations>\n <PkChatbotViewFiles v-else-if=\"activeView === 'files'\" :agent-id />\n <div\n v-else-if=\"activeView === 'auth'\"\n class=\"pk-chatbot__view-auth flex-1 min-h-0 overflow-y-auto\">\n <!-- Sign-in form provided by the host widget (owns the auth client) -->\n <slot name=\"view-auth\" />\n </div>\n <PkChatbotViewProfile v-else :agent-id>\n <template\n v-for=\"slotName in Object.keys(slots)\"\n #[slotName]=\"slotData\"\n ><slot :name=\"slotName\" v-bind=\"slotData\"\n /></template>\n </PkChatbotViewProfile>\n <!-- #endregion -->\n\n <!-- #region footer -->\n <div v-if=\"footerMessage\" class=\"pk-chatbot__footer\">\n <PkStreamingMarkdown :markdown=\"footerMessage\" class=\"wysiwyg\" />\n </div>\n <!-- #endregion -->\n </div>\n</template>\n\n<style lang=\"scss\">\n .pk-chatbot {\n display: flex;\n flex-direction: column;\n position: relative;\n height: 100%;\n background-color: var(--color-surface);\n\n &__header {\n position: sticky;\n top: 0;\n z-index: 1;\n display: flex;\n justify-content: space-between;\n gap: var(--spacing-14);\n background-color: var(--color-surface-1);\n padding: var(--spacing-14);\n border-bottom: 1px solid var(--color-surface-3);\n }\n\n &__header-start {\n display: flex;\n align-items: center;\n gap: var(--spacing-sm);\n min-width: 0;\n }\n\n &__nav-icon {\n font-size: var(--text-18);\n }\n\n &__avatar {\n width: var(--spacing-24);\n height: var(--spacing-24);\n }\n\n &__title {\n font-size: var(--text-16);\n font-weight: var(--font-semibold);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n &__header-end {\n flex-shrink: 0;\n }\n\n &__warning-body {\n padding: var(--spacing-md);\n border-bottom: 1px solid var(--color-surface-3);\n }\n\n &__warning-header {\n display: flex;\n align-items: center;\n gap: var(--spacing-4);\n margin-bottom: var(--spacing-4);\n }\n\n &__warning-icon {\n width: var(--spacing-16);\n height: var(--spacing-16);\n }\n\n &__warning-title {\n font-weight: 600;\n font-size: var(--text-14);\n }\n\n &__warning-text {\n font-size: var(--text-12);\n color: var(--color-word-3);\n }\n\n &__footer {\n padding: var(--spacing-md);\n border-top: 1px solid var(--color-surface-3);\n text-align: center;\n font-size: var(--text-12);\n color: var(--color-word-2);\n }\n\n // Modifier: fullscreen — layout full-page (Gemini-style): nessun\n // header interno, sfondo trasparente, input pill centrato.\n // Il chrome (sidebar, navigazione) è gestito dalla pagina ospite.\n &--fullscreen {\n // The dock, 60px. Declared rather than taken from the agent chip,\n // which the tight layout hides: the pill fell to 54px there and\n // the call bar that takes its place stayed at 60. There is no 60\n // in the spacing scale and a raw `60px` would stop following the\n // root font size, which the labels inside do follow.\n --pk-chat-fullscreen-dock-height: calc(\n var(--spacing-56) + var(--spacing-4)\n );\n // The pill, the notice that tucks into its top corners and the\n // call bar all round their ends on half of it.\n --pk-chat-dock-radius: calc(\n var(--pk-chat-fullscreen-dock-height) / 2\n );\n\n background-color: transparent;\n\n .pk-chatbot__footer {\n border-top: none;\n padding: 0 var(--spacing-md) var(--spacing-sm) var(--spacing-md);\n }\n\n // Reading column aligned with the input (Gemini-style). The\n // constraint lives on the inner wrapper so the scroll container\n // spans the page and the scrollbar sits at its edge.\n .pk-chatbot-messages {\n // Symmetric gutters: a visible scrollbar would otherwise\n // shrink the content box on one side only, shifting the\n // column off the input axis\n scrollbar-gutter: stable both-edges;\n // Dissolve the content at both edges (works on any page\n // background, dots included — a surface-colored fade band\n // would cut through the pattern instead)\n mask-image: linear-gradient(\n to bottom,\n transparent 0,\n #000 var(--spacing-40),\n #000 calc(100% - var(--spacing-40)),\n transparent 100%\n );\n // Resting clearance so the first/last lines sit inside the\n // fully opaque zone\n padding-block: var(--spacing-48);\n }\n\n .pk-chatbot-messages__wrapper {\n width: 100%;\n max-width: 768px;\n margin-inline: auto;\n }\n\n // Outline rail: wide chats only, measured on the chat and not on\n // the viewport, so a preview frame squeezed by side panels loses\n // it like a phone does. The rail sits at the edge of the scroll\n // area beside the reading column: below the `--wide` threshold\n // (768px column plus a 40px rail on each side) it would cover the\n // messages instead.\n .pk-chatbot-messages__outline {\n display: none;\n }\n\n &.pk-chatbot--wide .pk-chatbot-messages__outline {\n display: block;\n }\n\n .pk-chatbot-file-preview {\n background-color: var(--color-surface);\n }\n\n .pk-chatbot-input__notice {\n background-color: var(--color-surface);\n border-inline: 1px solid var(--color-surface-3);\n border-top: 1px solid var(--color-surface-2);\n padding: var(--spacing-10) var(--spacing-16);\n\n // As deep as the pill's corners, or the page shows through\n // where their curve leaves the side\n &::after {\n background-color: var(--color-surface);\n border-inline: 1px solid var(--color-surface-2);\n bottom: calc(-1 * var(--pk-chat-dock-radius));\n height: var(--pk-chat-dock-radius);\n left: -1px;\n right: -1px;\n }\n }\n\n .pk-chatbot-input {\n width: calc(100% - var(--spacing-sm) * 2);\n max-width: 768px;\n margin-inline: auto;\n\n &__form {\n // True semicircles at rest, concentric with the send\n // button, whose center sits 30px in. Not `rounded-full`:\n // once Shift+Enter grows the field the ends would swell\n // with it and cut into the first and last line.\n border-radius: var(--pk-chat-dock-radius);\n min-height: var(--pk-chat-fullscreen-dock-height);\n padding: var(--spacing-12) var(--spacing-16);\n background-color: var(--color-surface-1);\n border-color: var(--color-surface-2);\n box-shadow: none;\n transition:\n border-color var(--duration-200) var(--ease-in-out),\n box-shadow var(--duration-200) var(--ease-in-out);\n\n &:has(:focus-within) {\n border-color: var(--color-surface-4);\n box-shadow: var(--shadow-sm);\n }\n\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n }\n\n &__textarea {\n background-color: transparent;\n }\n }\n\n // A live call takes the place of the input, so it takes its shape,\n // its column and its height: full-bleed here would break the\n // reading axis, and a different height would make the dock jump\n // the moment the call starts.\n .pk-voice-session {\n --pk-chat-dock-height: var(--pk-chat-fullscreen-dock-height);\n --pk-voice-orb-size: var(--spacing-40);\n --pk-voice-orb-bars-height: var(--spacing-20);\n --pk-voice-session-surface: var(--color-surface-1);\n width: calc(100% - var(--spacing-sm) * 2);\n max-width: 768px;\n margin-inline: auto;\n padding-inline: var(--spacing-16);\n border-color: var(--color-surface-2);\n border-radius: var(--pk-chat-dock-radius);\n box-shadow: none;\n\n &__timer {\n font-size: var(--text-14);\n }\n }\n }\n\n // Modifier: panel — compact chrome for a docked side panel: the host\n // container owns background and border, the header slims down and\n // drops its own surface so the chat blends into the panel.\n &--panel {\n background-color: transparent;\n\n .pk-chatbot__header {\n background-color: transparent;\n\n // Fixed height so the panel header lines up with the host's\n // own chrome. Custom properties inherit through the shadow\n // root: an embedding host can override it to match its\n // header (the default matches the platform header, 50px).\n height: var(--pk-chatbot-panel-header-height, 50px);\n align-items: center;\n padding-block: 0;\n padding-inline: var(--spacing-10);\n border-bottom: 1px solid var(--color-surface-3);\n }\n\n .pk-chatbot__title {\n font-size: var(--text-14);\n }\n\n .pk-chatbot__footer {\n border-top: none;\n padding: var(--spacing-6) var(--spacing-md);\n }\n }\n\n // A chat given a whole page without the fullscreen layout (the page\n // an iframe embeds, a widget its host lets fill the screen) keeps the\n // reading column of the fullscreen one: at 1440px an answer ran\n // 1408px wide, some two hundred characters a line. Measured on the\n // chat, like `--wide` itself, so a narrow frame is left alone.\n &--wide:not(.pk-chatbot--fullscreen) {\n .pk-chatbot-messages__wrapper,\n .pk-chatbot-input {\n width: 100%;\n max-width: 768px;\n margin-inline: auto;\n }\n }\n }\n</style>\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PkChatbotAuth-BMLLTSwK.js","names":["z.enum","z.string","z.object","z.boolean","z.coerce.date","z.email","_useModel","z.object","z.email","z.boolean","useForm","z.string","__unplugin_components_0","__unplugin_components_1","__unplugin_components_2","__unplugin_components_3","_openBlock","_createElementBlock","_createElementVNode","_createVNode","_Transition","_withCtx","_toDisplayString","_unref","_createCommentVNode","_createBlock","_resolveDynamicComponent","_Fragment","_createTextVNode","_sfc_main","string","email","_enum","boolean","object","MediaSchema","useImageFallback","Se","RoleSchema","PasswordSchema","date","PasswordChangeSchema","data","SignUpSchema","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","_hoisted_15","_hoisted_16","_hoisted_17","_hoisted_18","PkChatbotAuth_default","defineComponent","\"errorMessage\"","\"errorMessageModifiers\"","\"success\"","\"successModifiers\"","__emit","$t","useI18n","props","__props","errorMessage","useModel","success","emit","mode","ref","backToSignIn","showSocialButtons","computed","signInSchema","resetSchema","VvSignInForm","VvSignInField","VvSignUpForm","VvSignUpField","clearSignUp","VvResetForm","VvResetField","clearReset","value","successCard","focusSuccessCard","onSignIn","onSignUp","onReset","handleSocial","provider","isTwoFactorStep","twoFactorKind","VvTwoFactorForm","VvTwoFactorField","clearTwoFactor","methods","switchTwoFactorKind","kind","twoFactorDescription","onVerifyTwoFactor","_component_VvIcon","VvIcon","_component_VvButton","VvButton","_component_VvAlert","VvAlert","_component_VvButtonGroup","VvButtonGroup","openBlock","createElementBlock","createElementVNode","createVNode","Transition","withCtx","toDisplayString","unref","canShowImage","_cache","onImageError","createCommentVNode","createBlock","resolveDynamicComponent","Fragment","createTextVNode"],"sources":["../../../../packages/models/src/schema/User.ts","../../../../packages/components/src/chat/PkChatbotAuth.vue","../../../../packages/components/src/chat/PkChatbotAuth.vue"],"sourcesContent":["import * as z from 'zod'\nimport { MediaSchema } from './Media'\n\nconst RoleSchema = z.enum(['user', 'admin'])\n\n/** Shortest password better-auth accepts, see `packages/auth`. */\nexport const PASSWORD_MIN_LENGTH = 8\n\n/**\n * Longest password better-auth accepts. Since better-auth 1.7.6 a longer one\n * is refused on sign-in too (`PASSWORD_TOO_LONG`), so every form checks it\n * before sending and shows the translated validation error instead.\n */\nexport const PASSWORD_MAX_LENGTH = 64\n\n/** A password as better-auth accepts it, for every form that sends one. */\nexport const PasswordSchema = z\n .string()\n .min(PASSWORD_MIN_LENGTH)\n .max(PASSWORD_MAX_LENGTH)\n\nexport const UserSchema = z.object({\n id: z.string(),\n name: z.string(),\n email: z.string(),\n emailVerified: z.boolean(),\n image: z.string().nullable(),\n media: MediaSchema.optional().nullable(),\n createdAt: z.coerce.date(),\n updatedAt: z.coerce.date(),\n banned: z.boolean().nullable(),\n banReason: z.string().nullable(),\n banExpires: z.coerce.date().nullable(),\n isAnonymous: z.boolean().nullable(),\n role: RoleSchema,\n twoFactorEnabled: z.boolean().optional(),\n})\n\nexport type User = z.infer<typeof UserSchema>\n\n/**\n * Trimmed user shape for org-scoped lookups (avatars, chat logs, member\n * lists). Served by GET /:audience/users/:id, which only resolves users\n * visible to the caller's active organization.\n */\nexport const UserPreviewSchema = z.object({\n id: z.string(),\n name: z.string(),\n email: z.string().nullable(),\n image: z.string().nullable(),\n isAnonymous: z.boolean().nullable(),\n banned: z.boolean().nullable(),\n})\n\nexport type UserPreview = z.infer<typeof UserPreviewSchema>\n\nexport const PasswordChangeSchema = z\n .object({\n password: PasswordSchema,\n passwordConfirmation: PasswordSchema,\n })\n .refine((data) => data.password === data.passwordConfirmation, {\n params: {\n i18n: 'errors.passwordsDoNotMatch',\n },\n path: ['passwordConfirmation'],\n })\n\nexport type PasswordChange = z.infer<typeof PasswordChangeSchema>\n\nexport const PasswordChangeWithCurrentSchema = PasswordChangeSchema.extend({\n currentPassword: PasswordSchema,\n})\n\nexport type PasswordChangeWithCurrent = z.infer<\n typeof PasswordChangeWithCurrentSchema\n>\n\nexport const UserCreateSchema = PasswordChangeSchema.extend({\n name: z.string().min(1),\n email: z.email(),\n media: MediaSchema.optional(),\n role: RoleSchema.optional().default('user'),\n})\n\nexport type UserCreate = z.infer<typeof UserCreateSchema>\n\nexport const UserUpdateSchema = z.object({\n id: z.string(),\n name: z.string(),\n email: z.string(),\n emailVerified: z.boolean().optional(),\n image: z.string().nullish(),\n role: RoleSchema,\n media: MediaSchema.optional().nullable(),\n banned: z.boolean().nullish(),\n banReason: z.string().nullish(),\n banExpires: z.string().nullish(),\n isAnonymous: z.boolean().nullish(),\n})\n\nexport type UserUpdate = z.infer<typeof UserUpdateSchema>\n\nexport const SignUpSchema = PasswordChangeSchema.extend({\n name: z.string().min(1),\n email: z.email(),\n rememberMe: z.boolean().optional(),\n})\n\nexport type SignUp = z.infer<typeof SignUpSchema>\n","<script setup lang=\"ts\">\n import { computed, ref, watch } from 'vue'\n import { useI18n } from 'vue-i18n'\n import { useForm } from '@volverjs/form-vue'\n import * as z from 'zod'\n import { PasswordSchema, SignUpSchema } from 'models'\n import type { AgentBranding, AuthMethods } from 'models'\n import { useImageFallback } from 'composables'\n\n const { t: $t } = useI18n({\n useScope: 'global',\n })\n\n const props = withDefaults(\n defineProps<{\n branding?: AgentBranding\n authMethods?: AuthMethods\n loading?: boolean\n /**\n * Set while an email sign-in waits for its second factor: the\n * methods the account has (`totp`, `otp`). The code step replaces\n * the forms until it is answered or cancelled.\n */\n twoFactorMethods?: string[]\n }>(),\n {\n branding: undefined,\n authMethods: undefined,\n loading: false,\n twoFactorMethods: undefined,\n },\n )\n\n // A deleted agent logo would leave a broken glyph above the sign-in form:\n // drop the whole block instead, the agent name below already identifies it.\n const { canShowImage, onImageError } = useImageFallback()\n\n const errorMessage = defineModel<string | undefined>('errorMessage', {\n default: undefined,\n })\n /**\n * Non-error feedback (e.g. \"check your inbox\" after sign-up / reset).\n * When set, a dedicated success screen replaces the form.\n */\n const success = defineModel<{ title: string; message: string } | undefined>(\n 'success',\n { default: undefined },\n )\n\n const emit = defineEmits<{\n (\n e: 'sign-in',\n payload: {\n email: string\n password: string\n rememberMe: boolean\n },\n ): void\n (\n e: 'sign-up',\n payload: { email: string; password: string; name: string },\n ): void\n (e: 'request-reset', payload: { email: string }): void\n (e: 'social', provider: 'google' | 'microsoft'): void\n (\n e: 'verify-two-factor',\n payload: { kind: 'totp' | 'otp' | 'backup'; code: string },\n ): void\n (e: 'send-two-factor-code'): void\n (e: 'cancel-two-factor'): void\n (e: 'update:errorMessage', message?: string): void\n (e: 'update:success', value?: { title: string; message: string }): void\n }>()\n\n type Mode = 'sign-in' | 'sign-up' | 'reset'\n const mode = ref<Mode>('sign-in')\n watch(mode, () => {\n errorMessage.value = undefined\n success.value = undefined\n })\n\n /** Returns to the sign-in form, clearing any success feedback. */\n function backToSignIn() {\n success.value = undefined\n mode.value = 'sign-in'\n }\n\n const showSocialButtons = computed(\n () => props.authMethods?.google || props.authMethods?.microsoft,\n )\n\n const signInSchema = z.object({\n email: z.email(),\n password: PasswordSchema,\n rememberMe: z.boolean().default(false),\n })\n\n const resetSchema = z.object({\n email: z.email(),\n })\n\n const { VvForm: VvSignInForm, VvFormField: VvSignInField } = useForm(\n signInSchema,\n { lazyLoad: true },\n )\n const {\n VvForm: VvSignUpForm,\n VvFormField: VvSignUpField,\n clear: clearSignUp,\n } = useForm(SignUpSchema, { lazyLoad: true })\n const {\n VvForm: VvResetForm,\n VvFormField: VvResetField,\n clear: clearReset,\n } = useForm(resetSchema, { lazyLoad: true })\n\n // Empty the sign-up / reset forms once their submission succeeds so a\n // later \"back to sign in\" doesn't reveal stale input.\n watch(success, (value) => {\n if (value) {\n clearSignUp()\n clearReset()\n }\n })\n\n // Move focus to the success card once the flip animation has finished\n // (the out-in transition mounts it only after the form leaves), so\n // screen-reader/keyboard users are announced the result.\n const successCard = ref<HTMLElement>()\n function focusSuccessCard() {\n if (success.value) {\n successCard.value?.focus()\n }\n }\n\n function onSignIn(data: {\n email: string\n password: string\n rememberMe?: boolean\n }) {\n emit('sign-in', {\n email: data.email,\n password: data.password,\n rememberMe: data.rememberMe ?? false,\n })\n }\n\n function onSignUp(data: { name: string; email: string; password: string }) {\n emit('sign-up', {\n name: data.name.trim(),\n email: data.email,\n password: data.password,\n })\n }\n\n function onReset(data: { email: string }) {\n emit('request-reset', { email: data.email })\n }\n\n function handleSocial(provider: 'google' | 'microsoft') {\n emit('social', provider)\n }\n\n // Two-step verification (docs/specs/released/two-factor-authentication.md)\n type TwoFactorKind = 'totp' | 'otp' | 'backup'\n const isTwoFactorStep = computed(() => !!props.twoFactorMethods?.length)\n const twoFactorKind = ref<TwoFactorKind>('totp')\n const {\n VvForm: VvTwoFactorForm,\n VvFormField: VvTwoFactorField,\n clear: clearTwoFactor,\n } = useForm(z.object({ code: z.string().trim().min(6).max(32) }), {\n lazyLoad: true,\n })\n // A new challenge starts from the factor the account has, and the email\n // one sends its code straight away.\n watch(\n () => props.twoFactorMethods,\n (methods) => {\n if (!methods?.length) {\n return\n }\n twoFactorKind.value = methods.includes('totp') ? 'totp' : 'otp'\n clearTwoFactor()\n if (twoFactorKind.value === 'otp') {\n emit('send-two-factor-code')\n }\n },\n { immediate: true },\n )\n function switchTwoFactorKind(kind: TwoFactorKind) {\n twoFactorKind.value = kind\n errorMessage.value = undefined\n clearTwoFactor()\n }\n const twoFactorDescription = computed(() => {\n if (twoFactorKind.value === 'backup') {\n return $t('twoFactor.challengeBackup')\n }\n return twoFactorKind.value === 'otp'\n ? $t('twoFactor.challengeEmailSent')\n : $t('twoFactor.challengeApp')\n })\n function onVerifyTwoFactor(data: { code: string }) {\n emit('verify-two-factor', {\n kind: twoFactorKind.value,\n code: data.code.trim(),\n })\n }\n</script>\n\n<template>\n <div\n class=\"pk-chatbot-auth flex flex-col items-center justify-center w-full min-h-full p-lg overflow-y-auto\">\n <div class=\"pk-chatbot-auth__flip w-full max-w-384 mx-auto my-auto\">\n <Transition\n name=\"pk-flip\"\n mode=\"out-in\"\n @after-enter=\"focusSuccessCard\">\n <!-- Success screen (sign-up / reset feedback) -->\n <div\n v-if=\"success\"\n ref=\"successCard\"\n key=\"success\"\n tabindex=\"-1\"\n class=\"pk-chatbot-auth__flip-card outline-none flex flex-col text-center leading-normal\">\n <div\n class=\"pk-chatbot-auth__success-icon w-64 h-64 border border-surface-3 rounded-full bg-surface flex items-center justify-center overflow-hidden bg-surface mx-auto mb-md\">\n <VvIcon\n name=\"ri:mail-check-line\"\n aria-hidden=\"true\"\n class=\"text-success w-32 h-32\" />\n </div>\n <h1 class=\"font-bold text-18 mb-xs\">\n {{ success.title }}\n </h1>\n <p class=\"mb-lg text-16 text-word-3\">\n {{ success.message }}\n </p>\n <VvButton\n type=\"button\"\n modifiers=\"link\"\n icon=\"chevron-left\"\n :label=\"$t('action.backToSignIn')\"\n @click=\"backToSignIn\" />\n </div>\n\n <!-- Sign-in / sign-up / reset forms -->\n <div\n v-else\n key=\"form\"\n class=\"pk-chatbot-auth__flip-card flex flex-col\">\n <!-- Form Container -->\n <div class=\"flex flex-col\">\n <!-- Relative Header Logo -->\n <div\n v-if=\"canShowImage(branding?.interface.logo)\"\n class=\"flex justify-center mb-md\">\n <img\n :src=\"branding?.interface.logo\"\n :alt=\"branding?.name\"\n class=\"w-64 h-64 border border-surface-3 rounded-full overflow-hidden bg-surface object-contain\"\n @error=\"\n onImageError(branding?.interface.logo)\n \" />\n </div>\n\n <div class=\"text-center leading-normal mb-lg\">\n <h1\n v-if=\"branding?.name\"\n class=\"font-bold text-20 m-0\">\n {{ branding.name }}\n </h1>\n <component\n :is=\"branding?.name ? 'h2' : 'h1'\"\n class=\"text-word-3 mb-0\">\n <template v-if=\"isTwoFactorStep\">\n {{ $t('twoFactor.challengeTitle') }}\n </template>\n <template v-else-if=\"mode === 'sign-in'\">\n {{ $t('auth.signInTitle') }}\n </template>\n <template v-else-if=\"mode === 'sign-up'\">\n {{ $t('auth.signUpTitle') }}\n </template>\n <template v-else-if=\"mode === 'reset'\">\n {{ $t('auth.resetTitle') }}\n </template>\n </component>\n </div>\n\n <!-- Error message -->\n <VvAlert\n v-if=\"errorMessage\"\n modifiers=\"danger\"\n class=\"mb-md\"\n :content=\"errorMessage\" />\n\n <!-- Two-step verification -->\n <template v-if=\"isTwoFactorStep\">\n <p\n class=\"text-14 text-word-3 text-center leading-normal mb-md\">\n {{ twoFactorDescription }}\n </p>\n <VvTwoFactorForm\n class=\"flex flex-col\"\n :readonly=\"loading\"\n @submit=\"onVerifyTwoFactor\">\n <VvTwoFactorField\n name=\"code\"\n type=\"text\"\n :autocomplete=\"\n twoFactorKind === 'backup'\n ? 'off'\n : 'one-time-code'\n \"\n :label=\"\n twoFactorKind === 'backup'\n ? $t('twoFactor.backupCode')\n : $t('twoFactor.code')\n \"\n floating />\n <VvButton\n type=\"submit\"\n modifiers=\"primary\"\n :loading=\"loading\"\n :disabled=\"loading\"\n :label=\"$t('twoFactor.verify')\" />\n </VvTwoFactorForm>\n <div class=\"flex justify-center mt-md\">\n <VvButton\n v-if=\"twoFactorKind === 'totp'\"\n type=\"button\"\n modifiers=\"link\"\n :label=\"$t('twoFactor.useBackupCode')\"\n @click=\"switchTwoFactorKind('backup')\" />\n <VvButton\n v-else-if=\"twoFactorKind === 'backup'\"\n type=\"button\"\n modifiers=\"link\"\n :label=\"$t('twoFactor.useApp')\"\n @click=\"switchTwoFactorKind('totp')\" />\n <VvButton\n v-else\n type=\"button\"\n modifiers=\"link\"\n :disabled=\"loading\"\n :label=\"$t('twoFactor.sendAgain')\"\n @click=\"emit('send-two-factor-code')\" />\n </div>\n </template>\n\n <!-- Sign In -->\n <VvSignInForm\n v-else-if=\"mode === 'sign-in'\"\n class=\"flex flex-col\"\n :readonly=\"loading\"\n @submit=\"onSignIn\">\n <div class=\"mb-md\">\n <VvSignInField\n name=\"email\"\n type=\"email\"\n autocomplete=\"username\"\n :label=\"$t('label.email')\"\n floating />\n <VvSignInField\n name=\"password\"\n type=\"password\"\n autocomplete=\"current-password\"\n :label=\"$t('label.password')\"\n floating />\n <div class=\"mb-md\">\n <VvButton\n type=\"button\"\n modifiers=\"link\"\n :label=\"$t('action.forgetPassword')\"\n @click=\"mode = 'reset'\" />\n </div>\n <VvSignInField\n name=\"rememberMe\"\n type=\"checkbox\"\n :label=\"$t('label.rememberMe')\"\n switch />\n </div>\n <VvButton\n type=\"submit\"\n modifiers=\"primary\"\n :loading=\"loading\"\n :disabled=\"loading\"\n :label=\"$t('action.signIn')\" />\n </VvSignInForm>\n\n <!-- Sign Up -->\n <VvSignUpForm\n v-else-if=\"mode === 'sign-up'\"\n class=\"flex flex-col\"\n :readonly=\"loading\"\n @submit=\"onSignUp\">\n <div class=\"mb-md\">\n <VvSignUpField\n name=\"name\"\n type=\"text\"\n autocomplete=\"name\"\n :label=\"$t('label.name')\"\n floating />\n <VvSignUpField\n name=\"email\"\n type=\"email\"\n autocomplete=\"username\"\n :label=\"$t('label.email')\"\n floating />\n <VvSignUpField\n name=\"password\"\n type=\"password\"\n autocomplete=\"new-password\"\n :label=\"$t('label.password')\"\n floating />\n <VvSignUpField\n name=\"passwordConfirmation\"\n type=\"password\"\n autocomplete=\"new-password\"\n :label=\"$t('label.confirmPassword')\"\n floating />\n </div>\n <VvButton\n type=\"submit\"\n modifiers=\"primary\"\n :loading=\"loading\"\n :disabled=\"loading\"\n :label=\"$t('action.continue')\" />\n </VvSignUpForm>\n\n <!-- Reset Password -->\n <VvResetForm\n v-else-if=\"mode === 'reset'\"\n class=\"flex flex-col\"\n :readonly=\"loading\"\n @submit=\"onReset\">\n <VvResetField\n name=\"email\"\n type=\"email\"\n autocomplete=\"username\"\n :label=\"$t('label.email')\"\n floating />\n <VvButtonGroup modifiers=\"vertical\">\n <VvButton\n type=\"submit\"\n modifiers=\"primary\"\n :loading=\"loading\"\n :disabled=\"loading\"\n :label=\"$t('action.submit')\" />\n </VvButtonGroup>\n </VvResetForm>\n\n <!-- Social providers (shared by sign-in and sign-up) -->\n <template\n v-if=\"\n !isTwoFactorStep &&\n (mode === 'sign-in' || mode === 'sign-up') &&\n showSocialButtons\n \">\n <div class=\"vv-separator mt-xs py-xs\">\n <span>{{ $t('label.or') }}</span>\n </div>\n <VvButtonGroup\n modifiers=\"vertical\"\n class=\"gap-xs mt-xs\">\n <VvButton\n v-if=\"authMethods?.google\"\n type=\"button\"\n modifiers=\"secondary\"\n icon=\"logos:google-icon\"\n :disabled=\"loading\"\n :label=\"\n $t('action.signInWithSocialProvider', {\n provider: 'Google',\n })\n \"\n @click=\"handleSocial('google')\" />\n <VvButton\n v-if=\"authMethods?.microsoft\"\n type=\"button\"\n modifiers=\"secondary\"\n icon=\"logos:microsoft-icon\"\n :disabled=\"loading\"\n :label=\"\n $t('action.signInWithSocialProvider', {\n provider: 'Microsoft',\n })\n \"\n @click=\"handleSocial('microsoft')\" />\n </VvButtonGroup>\n </template>\n </div>\n\n <!-- Footer below Form -->\n <div class=\"pt-lg text-center text-word-3\">\n <template v-if=\"isTwoFactorStep\">\n <VvButton\n type=\"button\"\n modifiers=\"link\"\n icon=\"chevron-left\"\n :label=\"$t('action.backToSignIn')\"\n @click=\"emit('cancel-two-factor')\" />\n </template>\n <template v-else-if=\"mode === 'sign-in'\">\n {{ $t('auth.noAccount') }}\n <VvButton\n type=\"button\"\n modifiers=\"link\"\n class=\"font-semibold\"\n :label=\"$t('action.signUp')\"\n @click=\"mode = 'sign-up'\" />\n </template>\n <template v-else-if=\"mode === 'sign-up'\">\n {{ $t('auth.haveAccount') }}\n <VvButton\n type=\"button\"\n modifiers=\"link\"\n class=\"font-semibold\"\n :label=\"$t('action.signIn')\"\n @click=\"mode = 'sign-in'\" />\n </template>\n <template v-else>\n <VvButton\n type=\"button\"\n modifiers=\"link\"\n icon=\"chevron-left\"\n :label=\"$t('action.backToSignIn')\"\n @click=\"mode = 'sign-in'\" />\n </template>\n </div>\n </div>\n </Transition>\n </div>\n </div>\n</template>\n\n<style lang=\"scss\">\n .pk-chatbot-auth {\n // Flip-card reveal between the form and the success screen, mirroring\n // the classic login in apps/frontend.\n &__flip {\n display: grid;\n transform-style: preserve-3d;\n perspective: 1000px;\n }\n\n &__flip-card {\n grid-area: 1 / 1;\n backface-visibility: hidden;\n transform-style: preserve-3d;\n }\n\n // Subtle pop on the success check icon once the card has flipped in.\n &__success-icon {\n animation: pk-chatbot-auth-check-pop 0.4s ease-out 0.3s backwards;\n }\n }\n\n .pk-flip-enter-active {\n animation: pk-chatbot-auth-flip-in 0.6s ease-out;\n }\n\n .pk-flip-leave-active {\n animation: pk-chatbot-auth-flip-out 0.6s ease-in;\n }\n\n @keyframes pk-chatbot-auth-flip-in {\n 0% {\n transform: rotateY(-180deg);\n opacity: 0;\n }\n\n 100% {\n transform: rotateY(0deg);\n opacity: 1;\n }\n }\n\n @keyframes pk-chatbot-auth-flip-out {\n 0% {\n transform: rotateY(0deg);\n opacity: 1;\n }\n\n 100% {\n transform: rotateY(180deg);\n opacity: 0;\n }\n }\n\n @keyframes pk-chatbot-auth-check-pop {\n 0% {\n transform: scale(0);\n opacity: 0;\n }\n\n 60% {\n transform: scale(1.15);\n }\n\n 100% {\n transform: scale(1);\n opacity: 1;\n }\n }\n</style>\n","<script setup lang=\"ts\">\n import { computed, ref, watch } from 'vue'\n import { useI18n } from 'vue-i18n'\n import { useForm } from '@volverjs/form-vue'\n import * as z from 'zod'\n import { PasswordSchema, SignUpSchema } from 'models'\n import type { AgentBranding, AuthMethods } from 'models'\n import { useImageFallback } from 'composables'\n\n const { t: $t } = useI18n({\n useScope: 'global',\n })\n\n const props = withDefaults(\n defineProps<{\n branding?: AgentBranding\n authMethods?: AuthMethods\n loading?: boolean\n /**\n * Set while an email sign-in waits for its second factor: the\n * methods the account has (`totp`, `otp`). The code step replaces\n * the forms until it is answered or cancelled.\n */\n twoFactorMethods?: string[]\n }>(),\n {\n branding: undefined,\n authMethods: undefined,\n loading: false,\n twoFactorMethods: undefined,\n },\n )\n\n // A deleted agent logo would leave a broken glyph above the sign-in form:\n // drop the whole block instead, the agent name below already identifies it.\n const { canShowImage, onImageError } = useImageFallback()\n\n const errorMessage = defineModel<string | undefined>('errorMessage', {\n default: undefined,\n })\n /**\n * Non-error feedback (e.g. \"check your inbox\" after sign-up / reset).\n * When set, a dedicated success screen replaces the form.\n */\n const success = defineModel<{ title: string; message: string } | undefined>(\n 'success',\n { default: undefined },\n )\n\n const emit = defineEmits<{\n (\n e: 'sign-in',\n payload: {\n email: string\n password: string\n rememberMe: boolean\n },\n ): void\n (\n e: 'sign-up',\n payload: { email: string; password: string; name: string },\n ): void\n (e: 'request-reset', payload: { email: string }): void\n (e: 'social', provider: 'google' | 'microsoft'): void\n (\n e: 'verify-two-factor',\n payload: { kind: 'totp' | 'otp' | 'backup'; code: string },\n ): void\n (e: 'send-two-factor-code'): void\n (e: 'cancel-two-factor'): void\n (e: 'update:errorMessage', message?: string): void\n (e: 'update:success', value?: { title: string; message: string }): void\n }>()\n\n type Mode = 'sign-in' | 'sign-up' | 'reset'\n const mode = ref<Mode>('sign-in')\n watch(mode, () => {\n errorMessage.value = undefined\n success.value = undefined\n })\n\n /** Returns to the sign-in form, clearing any success feedback. */\n function backToSignIn() {\n success.value = undefined\n mode.value = 'sign-in'\n }\n\n const showSocialButtons = computed(\n () => props.authMethods?.google || props.authMethods?.microsoft,\n )\n\n const signInSchema = z.object({\n email: z.email(),\n password: PasswordSchema,\n rememberMe: z.boolean().default(false),\n })\n\n const resetSchema = z.object({\n email: z.email(),\n })\n\n const { VvForm: VvSignInForm, VvFormField: VvSignInField } = useForm(\n signInSchema,\n { lazyLoad: true },\n )\n const {\n VvForm: VvSignUpForm,\n VvFormField: VvSignUpField,\n clear: clearSignUp,\n } = useForm(SignUpSchema, { lazyLoad: true })\n const {\n VvForm: VvResetForm,\n VvFormField: VvResetField,\n clear: clearReset,\n } = useForm(resetSchema, { lazyLoad: true })\n\n // Empty the sign-up / reset forms once their submission succeeds so a\n // later \"back to sign in\" doesn't reveal stale input.\n watch(success, (value) => {\n if (value) {\n clearSignUp()\n clearReset()\n }\n })\n\n // Move focus to the success card once the flip animation has finished\n // (the out-in transition mounts it only after the form leaves), so\n // screen-reader/keyboard users are announced the result.\n const successCard = ref<HTMLElement>()\n function focusSuccessCard() {\n if (success.value) {\n successCard.value?.focus()\n }\n }\n\n function onSignIn(data: {\n email: string\n password: string\n rememberMe?: boolean\n }) {\n emit('sign-in', {\n email: data.email,\n password: data.password,\n rememberMe: data.rememberMe ?? false,\n })\n }\n\n function onSignUp(data: { name: string; email: string; password: string }) {\n emit('sign-up', {\n name: data.name.trim(),\n email: data.email,\n password: data.password,\n })\n }\n\n function onReset(data: { email: string }) {\n emit('request-reset', { email: data.email })\n }\n\n function handleSocial(provider: 'google' | 'microsoft') {\n emit('social', provider)\n }\n\n // Two-step verification (docs/specs/released/two-factor-authentication.md)\n type TwoFactorKind = 'totp' | 'otp' | 'backup'\n const isTwoFactorStep = computed(() => !!props.twoFactorMethods?.length)\n const twoFactorKind = ref<TwoFactorKind>('totp')\n const {\n VvForm: VvTwoFactorForm,\n VvFormField: VvTwoFactorField,\n clear: clearTwoFactor,\n } = useForm(z.object({ code: z.string().trim().min(6).max(32) }), {\n lazyLoad: true,\n })\n // A new challenge starts from the factor the account has, and the email\n // one sends its code straight away.\n watch(\n () => props.twoFactorMethods,\n (methods) => {\n if (!methods?.length) {\n return\n }\n twoFactorKind.value = methods.includes('totp') ? 'totp' : 'otp'\n clearTwoFactor()\n if (twoFactorKind.value === 'otp') {\n emit('send-two-factor-code')\n }\n },\n { immediate: true },\n )\n function switchTwoFactorKind(kind: TwoFactorKind) {\n twoFactorKind.value = kind\n errorMessage.value = undefined\n clearTwoFactor()\n }\n const twoFactorDescription = computed(() => {\n if (twoFactorKind.value === 'backup') {\n return $t('twoFactor.challengeBackup')\n }\n return twoFactorKind.value === 'otp'\n ? $t('twoFactor.challengeEmailSent')\n : $t('twoFactor.challengeApp')\n })\n function onVerifyTwoFactor(data: { code: string }) {\n emit('verify-two-factor', {\n kind: twoFactorKind.value,\n code: data.code.trim(),\n })\n }\n</script>\n\n<template>\n <div\n class=\"pk-chatbot-auth flex flex-col items-center justify-center w-full min-h-full p-lg overflow-y-auto\">\n <div class=\"pk-chatbot-auth__flip w-full max-w-384 mx-auto my-auto\">\n <Transition\n name=\"pk-flip\"\n mode=\"out-in\"\n @after-enter=\"focusSuccessCard\">\n <!-- Success screen (sign-up / reset feedback) -->\n <div\n v-if=\"success\"\n ref=\"successCard\"\n key=\"success\"\n tabindex=\"-1\"\n class=\"pk-chatbot-auth__flip-card outline-none flex flex-col text-center leading-normal\">\n <div\n class=\"pk-chatbot-auth__success-icon w-64 h-64 border border-surface-3 rounded-full bg-surface flex items-center justify-center overflow-hidden bg-surface mx-auto mb-md\">\n <VvIcon\n name=\"ri:mail-check-line\"\n aria-hidden=\"true\"\n class=\"text-success w-32 h-32\" />\n </div>\n <h1 class=\"font-bold text-18 mb-xs\">\n {{ success.title }}\n </h1>\n <p class=\"mb-lg text-16 text-word-3\">\n {{ success.message }}\n </p>\n <VvButton\n type=\"button\"\n modifiers=\"link\"\n icon=\"chevron-left\"\n :label=\"$t('action.backToSignIn')\"\n @click=\"backToSignIn\" />\n </div>\n\n <!-- Sign-in / sign-up / reset forms -->\n <div\n v-else\n key=\"form\"\n class=\"pk-chatbot-auth__flip-card flex flex-col\">\n <!-- Form Container -->\n <div class=\"flex flex-col\">\n <!-- Relative Header Logo -->\n <div\n v-if=\"canShowImage(branding?.interface.logo)\"\n class=\"flex justify-center mb-md\">\n <img\n :src=\"branding?.interface.logo\"\n :alt=\"branding?.name\"\n class=\"w-64 h-64 border border-surface-3 rounded-full overflow-hidden bg-surface object-contain\"\n @error=\"\n onImageError(branding?.interface.logo)\n \" />\n </div>\n\n <div class=\"text-center leading-normal mb-lg\">\n <h1\n v-if=\"branding?.name\"\n class=\"font-bold text-20 m-0\">\n {{ branding.name }}\n </h1>\n <component\n :is=\"branding?.name ? 'h2' : 'h1'\"\n class=\"text-word-3 mb-0\">\n <template v-if=\"isTwoFactorStep\">\n {{ $t('twoFactor.challengeTitle') }}\n </template>\n <template v-else-if=\"mode === 'sign-in'\">\n {{ $t('auth.signInTitle') }}\n </template>\n <template v-else-if=\"mode === 'sign-up'\">\n {{ $t('auth.signUpTitle') }}\n </template>\n <template v-else-if=\"mode === 'reset'\">\n {{ $t('auth.resetTitle') }}\n </template>\n </component>\n </div>\n\n <!-- Error message -->\n <VvAlert\n v-if=\"errorMessage\"\n modifiers=\"danger\"\n class=\"mb-md\"\n :content=\"errorMessage\" />\n\n <!-- Two-step verification -->\n <template v-if=\"isTwoFactorStep\">\n <p\n class=\"text-14 text-word-3 text-center leading-normal mb-md\">\n {{ twoFactorDescription }}\n </p>\n <VvTwoFactorForm\n class=\"flex flex-col\"\n :readonly=\"loading\"\n @submit=\"onVerifyTwoFactor\">\n <VvTwoFactorField\n name=\"code\"\n type=\"text\"\n :autocomplete=\"\n twoFactorKind === 'backup'\n ? 'off'\n : 'one-time-code'\n \"\n :label=\"\n twoFactorKind === 'backup'\n ? $t('twoFactor.backupCode')\n : $t('twoFactor.code')\n \"\n floating />\n <VvButton\n type=\"submit\"\n modifiers=\"primary\"\n :loading=\"loading\"\n :disabled=\"loading\"\n :label=\"$t('twoFactor.verify')\" />\n </VvTwoFactorForm>\n <div class=\"flex justify-center mt-md\">\n <VvButton\n v-if=\"twoFactorKind === 'totp'\"\n type=\"button\"\n modifiers=\"link\"\n :label=\"$t('twoFactor.useBackupCode')\"\n @click=\"switchTwoFactorKind('backup')\" />\n <VvButton\n v-else-if=\"twoFactorKind === 'backup'\"\n type=\"button\"\n modifiers=\"link\"\n :label=\"$t('twoFactor.useApp')\"\n @click=\"switchTwoFactorKind('totp')\" />\n <VvButton\n v-else\n type=\"button\"\n modifiers=\"link\"\n :disabled=\"loading\"\n :label=\"$t('twoFactor.sendAgain')\"\n @click=\"emit('send-two-factor-code')\" />\n </div>\n </template>\n\n <!-- Sign In -->\n <VvSignInForm\n v-else-if=\"mode === 'sign-in'\"\n class=\"flex flex-col\"\n :readonly=\"loading\"\n @submit=\"onSignIn\">\n <div class=\"mb-md\">\n <VvSignInField\n name=\"email\"\n type=\"email\"\n autocomplete=\"username\"\n :label=\"$t('label.email')\"\n floating />\n <VvSignInField\n name=\"password\"\n type=\"password\"\n autocomplete=\"current-password\"\n :label=\"$t('label.password')\"\n floating />\n <div class=\"mb-md\">\n <VvButton\n type=\"button\"\n modifiers=\"link\"\n :label=\"$t('action.forgetPassword')\"\n @click=\"mode = 'reset'\" />\n </div>\n <VvSignInField\n name=\"rememberMe\"\n type=\"checkbox\"\n :label=\"$t('label.rememberMe')\"\n switch />\n </div>\n <VvButton\n type=\"submit\"\n modifiers=\"primary\"\n :loading=\"loading\"\n :disabled=\"loading\"\n :label=\"$t('action.signIn')\" />\n </VvSignInForm>\n\n <!-- Sign Up -->\n <VvSignUpForm\n v-else-if=\"mode === 'sign-up'\"\n class=\"flex flex-col\"\n :readonly=\"loading\"\n @submit=\"onSignUp\">\n <div class=\"mb-md\">\n <VvSignUpField\n name=\"name\"\n type=\"text\"\n autocomplete=\"name\"\n :label=\"$t('label.name')\"\n floating />\n <VvSignUpField\n name=\"email\"\n type=\"email\"\n autocomplete=\"username\"\n :label=\"$t('label.email')\"\n floating />\n <VvSignUpField\n name=\"password\"\n type=\"password\"\n autocomplete=\"new-password\"\n :label=\"$t('label.password')\"\n floating />\n <VvSignUpField\n name=\"passwordConfirmation\"\n type=\"password\"\n autocomplete=\"new-password\"\n :label=\"$t('label.confirmPassword')\"\n floating />\n </div>\n <VvButton\n type=\"submit\"\n modifiers=\"primary\"\n :loading=\"loading\"\n :disabled=\"loading\"\n :label=\"$t('action.continue')\" />\n </VvSignUpForm>\n\n <!-- Reset Password -->\n <VvResetForm\n v-else-if=\"mode === 'reset'\"\n class=\"flex flex-col\"\n :readonly=\"loading\"\n @submit=\"onReset\">\n <VvResetField\n name=\"email\"\n type=\"email\"\n autocomplete=\"username\"\n :label=\"$t('label.email')\"\n floating />\n <VvButtonGroup modifiers=\"vertical\">\n <VvButton\n type=\"submit\"\n modifiers=\"primary\"\n :loading=\"loading\"\n :disabled=\"loading\"\n :label=\"$t('action.submit')\" />\n </VvButtonGroup>\n </VvResetForm>\n\n <!-- Social providers (shared by sign-in and sign-up) -->\n <template\n v-if=\"\n !isTwoFactorStep &&\n (mode === 'sign-in' || mode === 'sign-up') &&\n showSocialButtons\n \">\n <div class=\"vv-separator mt-xs py-xs\">\n <span>{{ $t('label.or') }}</span>\n </div>\n <VvButtonGroup\n modifiers=\"vertical\"\n class=\"gap-xs mt-xs\">\n <VvButton\n v-if=\"authMethods?.google\"\n type=\"button\"\n modifiers=\"secondary\"\n icon=\"logos:google-icon\"\n :disabled=\"loading\"\n :label=\"\n $t('action.signInWithSocialProvider', {\n provider: 'Google',\n })\n \"\n @click=\"handleSocial('google')\" />\n <VvButton\n v-if=\"authMethods?.microsoft\"\n type=\"button\"\n modifiers=\"secondary\"\n icon=\"logos:microsoft-icon\"\n :disabled=\"loading\"\n :label=\"\n $t('action.signInWithSocialProvider', {\n provider: 'Microsoft',\n })\n \"\n @click=\"handleSocial('microsoft')\" />\n </VvButtonGroup>\n </template>\n </div>\n\n <!-- Footer below Form -->\n <div class=\"pt-lg text-center text-word-3\">\n <template v-if=\"isTwoFactorStep\">\n <VvButton\n type=\"button\"\n modifiers=\"link\"\n icon=\"chevron-left\"\n :label=\"$t('action.backToSignIn')\"\n @click=\"emit('cancel-two-factor')\" />\n </template>\n <template v-else-if=\"mode === 'sign-in'\">\n {{ $t('auth.noAccount') }}\n <VvButton\n type=\"button\"\n modifiers=\"link\"\n class=\"font-semibold\"\n :label=\"$t('action.signUp')\"\n @click=\"mode = 'sign-up'\" />\n </template>\n <template v-else-if=\"mode === 'sign-up'\">\n {{ $t('auth.haveAccount') }}\n <VvButton\n type=\"button\"\n modifiers=\"link\"\n class=\"font-semibold\"\n :label=\"$t('action.signIn')\"\n @click=\"mode = 'sign-in'\" />\n </template>\n <template v-else>\n <VvButton\n type=\"button\"\n modifiers=\"link\"\n icon=\"chevron-left\"\n :label=\"$t('action.backToSignIn')\"\n @click=\"mode = 'sign-in'\" />\n </template>\n </div>\n </div>\n </Transition>\n </div>\n </div>\n</template>\n\n<style lang=\"scss\">\n .pk-chatbot-auth {\n // Flip-card reveal between the form and the success screen, mirroring\n // the classic login in apps/frontend.\n &__flip {\n display: grid;\n transform-style: preserve-3d;\n perspective: 1000px;\n }\n\n &__flip-card {\n grid-area: 1 / 1;\n backface-visibility: hidden;\n transform-style: preserve-3d;\n }\n\n // Subtle pop on the success check icon once the card has flipped in.\n &__success-icon {\n animation: pk-chatbot-auth-check-pop 0.4s ease-out 0.3s backwards;\n }\n }\n\n .pk-flip-enter-active {\n animation: pk-chatbot-auth-flip-in 0.6s ease-out;\n }\n\n .pk-flip-leave-active {\n animation: pk-chatbot-auth-flip-out 0.6s ease-in;\n }\n\n @keyframes pk-chatbot-auth-flip-in {\n 0% {\n transform: rotateY(-180deg);\n opacity: 0;\n }\n\n 100% {\n transform: rotateY(0deg);\n opacity: 1;\n }\n }\n\n @keyframes pk-chatbot-auth-flip-out {\n 0% {\n transform: rotateY(0deg);\n opacity: 1;\n }\n\n 100% {\n transform: rotateY(180deg);\n opacity: 0;\n }\n }\n\n @keyframes pk-chatbot-auth-check-pop {\n 0% {\n transform: scale(0);\n opacity: 0;\n }\n\n 60% {\n transform: scale(1.15);\n }\n\n 100% {\n transform: scale(1);\n opacity: 1;\n }\n }\n</style>\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PkChatbotError-CRGbK09-.js","names":["matchesStreamCode","$emit","__unplugin_components_0","__unplugin_components_1","_openBlock","_createBlock","_unref","_createSlots","_withCtx","_createTextVNode","_toDisplayString","_createCommentVNode","_sfc_main","matchesStreamErrorCode","parseStreamError","matchesCode","error","code","getStreamErrorPayload","useChatbotError","isContextWindowError","computed","toValue","isNotFoundError","isRateLimitError","isOriginNotAllowedError","isCreditExhaustedError","isConversationBlockedError","isBadRequestError","isInternalServerError","isGatewayConfigError","isGatewayDisabledError","isModelUnavailableError","PkChatbotError_default","defineComponent","__emit","props","__props","emit","$t","useI18n","isOutOfUserReach","errorMessage","payload","retryCountdown","ref","retryTimer","watch","isRefreshableError","tick","onBeforeUnmount","_component_VvButton","VvButton","_component_VvAlert","VvAlert","openBlock","createBlock","unref","createSlots","withCtx","createTextVNode","toDisplayString","_cache","_ctx","createCommentVNode"],"sources":["../../../../packages/composable/src/useChatbotError.ts","../../../../packages/components/src/chat/PkChatbotError.vue","../../../../packages/components/src/chat/PkChatbotError.vue"],"sourcesContent":["import { computed, toValue, type MaybeRefOrGetter } from 'vue'\nimport {\n matchesStreamErrorCode as matchesStreamCode,\n parseStreamError,\n type StreamErrorPayload,\n} from 'models'\n\nexport type { StreamErrorPayload }\n\ntype ErrorCode =\n | 'context_length_exceeded'\n | 'entity-not-found'\n | 'rate-limit-exceeded'\n | 'origin-not-allowed'\n | 'credit-exhausted'\n | 'conversation-blocked'\n | 'bad request'\n | 'internal-server-error'\n | 'gateway-disabled'\n | 'model-unavailable'\n\nfunction matchesCode(error: Error | undefined, code: ErrorCode): boolean {\n return error?.message?.toLowerCase().includes(code) ?? false\n}\n\nexport function getStreamErrorPayload(\n error: Error | undefined,\n): StreamErrorPayload | undefined {\n return parseStreamError(error?.message)?.payload\n}\n\nexport function useChatbotError(error: MaybeRefOrGetter<Error | undefined>) {\n const isContextWindowError = computed(() =>\n matchesCode(toValue(error), 'context_length_exceeded'),\n )\n const isNotFoundError = computed(() =>\n matchesCode(toValue(error), 'entity-not-found'),\n )\n const isRateLimitError = computed(() =>\n matchesCode(toValue(error), 'rate-limit-exceeded'),\n )\n const isOriginNotAllowedError = computed(() =>\n matchesCode(toValue(error), 'origin-not-allowed'),\n )\n const isCreditExhaustedError = computed(() =>\n matchesCode(toValue(error), 'credit-exhausted'),\n )\n const isConversationBlockedError = computed(() =>\n matchesCode(toValue(error), 'conversation-blocked'),\n )\n const isBadRequestError = computed(() =>\n matchesCode(toValue(error), 'bad request'),\n )\n const isInternalServerError = computed(() =>\n matchesCode(toValue(error), 'internal-server-error'),\n )\n const isGatewayConfigError = computed(() =>\n matchesStreamCode(toValue(error)?.message, 'GATEWAY_CONFIG'),\n )\n /**\n * The organization does not use the platform gateway and this agent's\n * model is one of its. A decision, not a hiccup: retrying in ten seconds\n * gets the same answer.\n */\n const isGatewayDisabledError = computed(() =>\n matchesCode(toValue(error), 'gateway-disabled'),\n )\n /**\n * The agent's model is on the organization's endpoint, which is off, gone\n * or no longer serves it. It lasts until somebody changes the endpoint or\n * the agent, so it is not retried either.\n */\n const isModelUnavailableError = computed(() =>\n matchesCode(toValue(error), 'model-unavailable'),\n )\n\n /** Errors that trigger an automatic retry countdown */\n const isRefreshableError = computed(\n () =>\n !isContextWindowError.value &&\n !isNotFoundError.value &&\n !isOriginNotAllowedError.value &&\n !isCreditExhaustedError.value &&\n !isConversationBlockedError.value &&\n !isBadRequestError.value &&\n !isInternalServerError.value &&\n !isGatewayConfigError.value &&\n !isGatewayDisabledError.value &&\n !isModelUnavailableError.value,\n )\n\n return {\n isContextWindowError,\n isNotFoundError,\n isRateLimitError,\n isOriginNotAllowedError,\n isCreditExhaustedError,\n isConversationBlockedError,\n isBadRequestError,\n isInternalServerError,\n isGatewayConfigError,\n isGatewayDisabledError,\n isModelUnavailableError,\n isRefreshableError,\n }\n}\n","<script lang=\"ts\" setup>\n import { computed, onBeforeUnmount, ref, watch } from 'vue'\n import { useI18n } from 'vue-i18n'\n import { useChatbotError, getStreamErrorPayload } from 'composables'\n\n const props = defineProps<{\n error?: Error\n }>()\n\n const emit = defineEmits<{\n (e: 'retry'): void\n (e: 'reset'): void\n }>()\n\n const { t: $t } = useI18n({\n useScope: 'global',\n })\n\n const {\n isContextWindowError,\n isNotFoundError,\n isRateLimitError,\n isOriginNotAllowedError,\n isCreditExhaustedError,\n isConversationBlockedError,\n isBadRequestError,\n isInternalServerError,\n isGatewayConfigError,\n isGatewayDisabledError,\n isModelUnavailableError,\n isRefreshableError,\n } = useChatbotError(() => props.error)\n\n /**\n * Nothing the user of the chat can do about: a new conversation meets the\n * same answer, so the alert offers no button, as for exhausted credit.\n */\n const isOutOfUserReach = computed(\n () =>\n isOriginNotAllowedError.value ||\n isCreditExhaustedError.value ||\n isGatewayConfigError.value ||\n isGatewayDisabledError.value ||\n isModelUnavailableError.value,\n )\n\n const errorMessage = computed(() => {\n if (isGatewayConfigError.value) {\n const payload = getStreamErrorPayload(props.error)\n if (payload?.reason === 'disallowPromptTraining') {\n return $t('message.chatErrorGatewayPromptTraining', {\n model: payload.model,\n })\n }\n if (payload?.reason === 'zeroDataRetention') {\n return $t('message.chatErrorGatewayZdr', {\n model: payload.model,\n })\n }\n return $t('message.chatErrorGeneric')\n }\n if (isContextWindowError.value) {\n return $t('message.chatErrorContextWindow')\n }\n if (isNotFoundError.value) {\n return $t('message.chatErrorNotFound')\n }\n if (isRateLimitError.value) {\n return $t('message.chatErrorRateLimit', {\n seconds: retryCountdown.value,\n })\n }\n if (isOriginNotAllowedError.value) {\n return $t('message.chatErrorOriginNotAllowed')\n }\n if (isCreditExhaustedError.value) {\n return $t('message.chatErrorCreditExhausted')\n }\n if (isGatewayDisabledError.value) {\n return $t('message.chatErrorGatewayDisabled')\n }\n if (isModelUnavailableError.value) {\n return $t('message.chatErrorModelUnavailable')\n }\n if (isConversationBlockedError.value) {\n return $t('message.chatErrorConversationBlocked')\n }\n if (isBadRequestError.value) {\n return $t('message.chatErrorBadRequest')\n }\n if (isInternalServerError.value) {\n return $t('message.chatErrorInternalServer')\n }\n return $t('message.chatErrorGeneric', { seconds: retryCountdown.value })\n })\n\n const retryCountdown = ref<number>(0)\n const retryTimer = ref<ReturnType<typeof setTimeout>>()\n\n watch(\n () => props.error,\n (error) => {\n if (retryTimer.value) {\n clearTimeout(retryTimer.value)\n }\n\n if (error && isRefreshableError.value) {\n retryCountdown.value = 10\n const tick = () => {\n retryCountdown.value--\n if (retryCountdown.value <= 0) {\n emit('retry')\n return\n }\n retryTimer.value = setTimeout(tick, 1000)\n }\n retryTimer.value = setTimeout(tick, 1000)\n } else {\n retryCountdown.value = 0\n }\n },\n { immediate: true },\n )\n\n onBeforeUnmount(() => {\n if (retryTimer.value) {\n clearTimeout(retryTimer.value)\n }\n })\n</script>\n\n<template>\n <VvAlert\n :modifiers=\"isRefreshableError ? 'warning' : 'danger'\"\n class=\"rounded-lg\">\n <!-- The modifier already paints the alert and picks its icon: tinting\n the content again, with a 32px glyph nothing else in the chat\n matches, said the same thing three times (DESIGN.md). -->\n {{ errorMessage }}\n <template v-if=\"isRefreshableError || !isOutOfUserReach\" #footer>\n <VvButton\n v-if=\"isRefreshableError\"\n icon=\"ri:reset-right-line\"\n modifiers=\"action\"\n class=\"text-12\"\n :label=\"$t('action.retryNow')\"\n @click=\"$emit('retry')\" />\n <VvButton\n v-else-if=\"!isOutOfUserReach\"\n icon=\"reload\"\n modifiers=\"action\"\n :label=\"$t('label.newChat')\"\n @click=\"$emit('reset')\" />\n </template>\n </VvAlert>\n</template>\n","<script lang=\"ts\" setup>\n import { computed, onBeforeUnmount, ref, watch } from 'vue'\n import { useI18n } from 'vue-i18n'\n import { useChatbotError, getStreamErrorPayload } from 'composables'\n\n const props = defineProps<{\n error?: Error\n }>()\n\n const emit = defineEmits<{\n (e: 'retry'): void\n (e: 'reset'): void\n }>()\n\n const { t: $t } = useI18n({\n useScope: 'global',\n })\n\n const {\n isContextWindowError,\n isNotFoundError,\n isRateLimitError,\n isOriginNotAllowedError,\n isCreditExhaustedError,\n isConversationBlockedError,\n isBadRequestError,\n isInternalServerError,\n isGatewayConfigError,\n isGatewayDisabledError,\n isModelUnavailableError,\n isRefreshableError,\n } = useChatbotError(() => props.error)\n\n /**\n * Nothing the user of the chat can do about: a new conversation meets the\n * same answer, so the alert offers no button, as for exhausted credit.\n */\n const isOutOfUserReach = computed(\n () =>\n isOriginNotAllowedError.value ||\n isCreditExhaustedError.value ||\n isGatewayConfigError.value ||\n isGatewayDisabledError.value ||\n isModelUnavailableError.value,\n )\n\n const errorMessage = computed(() => {\n if (isGatewayConfigError.value) {\n const payload = getStreamErrorPayload(props.error)\n if (payload?.reason === 'disallowPromptTraining') {\n return $t('message.chatErrorGatewayPromptTraining', {\n model: payload.model,\n })\n }\n if (payload?.reason === 'zeroDataRetention') {\n return $t('message.chatErrorGatewayZdr', {\n model: payload.model,\n })\n }\n return $t('message.chatErrorGeneric')\n }\n if (isContextWindowError.value) {\n return $t('message.chatErrorContextWindow')\n }\n if (isNotFoundError.value) {\n return $t('message.chatErrorNotFound')\n }\n if (isRateLimitError.value) {\n return $t('message.chatErrorRateLimit', {\n seconds: retryCountdown.value,\n })\n }\n if (isOriginNotAllowedError.value) {\n return $t('message.chatErrorOriginNotAllowed')\n }\n if (isCreditExhaustedError.value) {\n return $t('message.chatErrorCreditExhausted')\n }\n if (isGatewayDisabledError.value) {\n return $t('message.chatErrorGatewayDisabled')\n }\n if (isModelUnavailableError.value) {\n return $t('message.chatErrorModelUnavailable')\n }\n if (isConversationBlockedError.value) {\n return $t('message.chatErrorConversationBlocked')\n }\n if (isBadRequestError.value) {\n return $t('message.chatErrorBadRequest')\n }\n if (isInternalServerError.value) {\n return $t('message.chatErrorInternalServer')\n }\n return $t('message.chatErrorGeneric', { seconds: retryCountdown.value })\n })\n\n const retryCountdown = ref<number>(0)\n const retryTimer = ref<ReturnType<typeof setTimeout>>()\n\n watch(\n () => props.error,\n (error) => {\n if (retryTimer.value) {\n clearTimeout(retryTimer.value)\n }\n\n if (error && isRefreshableError.value) {\n retryCountdown.value = 10\n const tick = () => {\n retryCountdown.value--\n if (retryCountdown.value <= 0) {\n emit('retry')\n return\n }\n retryTimer.value = setTimeout(tick, 1000)\n }\n retryTimer.value = setTimeout(tick, 1000)\n } else {\n retryCountdown.value = 0\n }\n },\n { immediate: true },\n )\n\n onBeforeUnmount(() => {\n if (retryTimer.value) {\n clearTimeout(retryTimer.value)\n }\n })\n</script>\n\n<template>\n <VvAlert\n :modifiers=\"isRefreshableError ? 'warning' : 'danger'\"\n class=\"rounded-lg\">\n <!-- The modifier already paints the alert and picks its icon: tinting\n the content again, with a 32px glyph nothing else in the chat\n matches, said the same thing three times (DESIGN.md). -->\n {{ errorMessage }}\n <template v-if=\"isRefreshableError || !isOutOfUserReach\" #footer>\n <VvButton\n v-if=\"isRefreshableError\"\n icon=\"ri:reset-right-line\"\n modifiers=\"action\"\n class=\"text-12\"\n :label=\"$t('action.retryNow')\"\n @click=\"$emit('retry')\" />\n <VvButton\n v-else-if=\"!isOutOfUserReach\"\n icon=\"reload\"\n modifiers=\"action\"\n :label=\"$t('label.newChat')\"\n @click=\"$emit('reset')\" />\n </template>\n </VvAlert>\n</template>\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PkChatbotFeedbackForm-CMFXjoKR.js","names":["$emit","z.object","z.string","useForm","__unplugin_components_0","__unplugin_components_1","__unplugin_components_2","__unplugin_components_3","_openBlock","_createElementBlock","_createElementVNode","_createVNode","_toDisplayString","_unref","_withModifiers","_Transition","_withCtx","_isRef","_createBlock","_createCommentVNode","_sfc_main","string","object","Se","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","PkChatbotFeedbackForm_default","defineComponent","__emit","$t","useI18n","emit","FeedbackFormSchema","onSubmit","data","_component_VvIcon","VvIcon","_component_VvButton","VvButton","_component_VvAlert","VvAlert","_component_VvButtonGroup","VvButtonGroup","openBlock","createElementBlock","createElementVNode","createVNode","toDisplayString","unref","_cache","withModifiers","_ctx","Transition","withCtx","__props","VvForm","formData","isRef","$event","createBlock","createCommentVNode","VvFormField"],"sources":["../../../../packages/components/src/chat/PkChatbotFeedbackForm.vue","../../../../packages/components/src/chat/PkChatbotFeedbackForm.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { useI18n } from 'vue-i18n'\n import { useForm } from '@volverjs/form-vue'\n import * as z from 'zod'\n\n const { t: $t } = useI18n({ useScope: 'global' })\n\n defineProps<{\n submitted?: boolean\n loading?: boolean\n error?: string\n }>()\n\n const emit = defineEmits<{\n submit: [comment: string]\n close: []\n }>()\n\n const FeedbackFormSchema = z.object({\n comment: z.string().min(1).default(''),\n })\n\n const { VvForm, VvFormField, formData } = useForm(FeedbackFormSchema, {\n lazyLoad: true,\n })\n\n const onSubmit = (data: { comment: string }) => {\n emit('submit', data.comment)\n }\n</script>\n\n<template>\n <div\n class=\"border border-surface-3 rounded-xl w-full overflow-hidden bg-surface\">\n <div\n class=\"px-sm py-6 bg-surface-1 min-h-40 text-12 border-b border-surface-3 text-word-3 flex items-center gap-8 min-h-40\">\n <VvIcon name=\"ri:feedback-line\" class=\"text-16\" />\n <strong class=\"font-bold\">{{ $t('action.feedback') }}</strong>\n <VvButton\n icon=\"ri:close-line\"\n modifiers=\"action-quiet-small\"\n :title=\"$t('action.close')\"\n class=\"ml-auto\"\n @click.stop=\"$emit('close')\" />\n </div>\n <Transition mode=\"out-in\">\n <div v-if=\"!submitted\">\n <VvForm v-model=\"formData\" @submit=\"onSubmit\">\n <div class=\"p-sm\">\n <VvAlert\n v-if=\"error\"\n modifiers=\"danger\"\n class=\"mb-sm\"\n :content=\"error\" />\n <VvFormField\n name=\"comment\"\n type=\"textarea\"\n rows=\"3\"\n :label=\"$t('label.comment')\"\n :placeholder=\"$t('placeholder.comment')\"\n modifiers=\"compact no-label\"\n class=\"mb-0\" />\n </div>\n <div\n class=\"flex justify-end border-t border-surface-3 px-sm py-10\">\n <VvButtonGroup>\n <VvButton\n type=\"button\"\n modifiers=\"action-quiet\"\n icon=\"ri:close-line\"\n icon-position=\"right\"\n :label=\"$t('action.close')\"\n @click=\"$emit('close')\" />\n <VvButton\n type=\"submit\"\n modifiers=\"action-primary\"\n icon=\"ri:send-plane-2-line\"\n icon-position=\"right\"\n :loading\n :disabled=\"loading\"\n :label=\"$t('action.submit')\" />\n </VvButtonGroup>\n </div>\n </VvForm>\n </div>\n <div v-else class=\"p-sm\">\n <!-- One confirmation row across every tool card: a green\n check, the title in weight, the body quiet. The check is\n the outcome, so it alone carries the colour (DESIGN.md). -->\n <div class=\"flex items-center gap-sm\">\n <VvIcon name=\"ri:check-line\" class=\"text-16 text-success\" />\n <div>\n <strong class=\"font-medium block text-word-1\">\n {{ $t('message.feedbackSubmittedTitle') }}\n </strong>\n <p class=\"text-word-3\">\n {{ $t('message.feedbackSubmittedMessage') }}\n </p>\n </div>\n </div>\n </div>\n </Transition>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { useI18n } from 'vue-i18n'\n import { useForm } from '@volverjs/form-vue'\n import * as z from 'zod'\n\n const { t: $t } = useI18n({ useScope: 'global' })\n\n defineProps<{\n submitted?: boolean\n loading?: boolean\n error?: string\n }>()\n\n const emit = defineEmits<{\n submit: [comment: string]\n close: []\n }>()\n\n const FeedbackFormSchema = z.object({\n comment: z.string().min(1).default(''),\n })\n\n const { VvForm, VvFormField, formData } = useForm(FeedbackFormSchema, {\n lazyLoad: true,\n })\n\n const onSubmit = (data: { comment: string }) => {\n emit('submit', data.comment)\n }\n</script>\n\n<template>\n <div\n class=\"border border-surface-3 rounded-xl w-full overflow-hidden bg-surface\">\n <div\n class=\"px-sm py-6 bg-surface-1 min-h-40 text-12 border-b border-surface-3 text-word-3 flex items-center gap-8 min-h-40\">\n <VvIcon name=\"ri:feedback-line\" class=\"text-16\" />\n <strong class=\"font-bold\">{{ $t('action.feedback') }}</strong>\n <VvButton\n icon=\"ri:close-line\"\n modifiers=\"action-quiet-small\"\n :title=\"$t('action.close')\"\n class=\"ml-auto\"\n @click.stop=\"$emit('close')\" />\n </div>\n <Transition mode=\"out-in\">\n <div v-if=\"!submitted\">\n <VvForm v-model=\"formData\" @submit=\"onSubmit\">\n <div class=\"p-sm\">\n <VvAlert\n v-if=\"error\"\n modifiers=\"danger\"\n class=\"mb-sm\"\n :content=\"error\" />\n <VvFormField\n name=\"comment\"\n type=\"textarea\"\n rows=\"3\"\n :label=\"$t('label.comment')\"\n :placeholder=\"$t('placeholder.comment')\"\n modifiers=\"compact no-label\"\n class=\"mb-0\" />\n </div>\n <div\n class=\"flex justify-end border-t border-surface-3 px-sm py-10\">\n <VvButtonGroup>\n <VvButton\n type=\"button\"\n modifiers=\"action-quiet\"\n icon=\"ri:close-line\"\n icon-position=\"right\"\n :label=\"$t('action.close')\"\n @click=\"$emit('close')\" />\n <VvButton\n type=\"submit\"\n modifiers=\"action-primary\"\n icon=\"ri:send-plane-2-line\"\n icon-position=\"right\"\n :loading\n :disabled=\"loading\"\n :label=\"$t('action.submit')\" />\n </VvButtonGroup>\n </div>\n </VvForm>\n </div>\n <div v-else class=\"p-sm\">\n <!-- One confirmation row across every tool card: a green\n check, the title in weight, the body quiet. The check is\n the outcome, so it alone carries the colour (DESIGN.md). -->\n <div class=\"flex items-center gap-sm\">\n <VvIcon name=\"ri:check-line\" class=\"text-16 text-success\" />\n <div>\n <strong class=\"font-medium block text-word-1\">\n {{ $t('message.feedbackSubmittedTitle') }}\n </strong>\n <p class=\"text-word-3\">\n {{ $t('message.feedbackSubmittedMessage') }}\n </p>\n </div>\n </div>\n </div>\n </Transition>\n </div>\n</template>\n"],"mappings":"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"}
|