@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.
Files changed (231) hide show
  1. package/dist/_chunks/{Agent-D8YrsP52.js → Agent-Gdgpd3LA.js} +66 -66
  2. package/dist/_chunks/Agent-Gdgpd3LA.js.map +1 -0
  3. package/dist/_chunks/{PkChatbotFilePreview-DAhN8TyL.js → PkChatbotFilePreview-DiuzVVKH.js} +2 -2
  4. package/dist/_chunks/{PkChatbotFilePreview-DAhN8TyL.js.map → PkChatbotFilePreview-DiuzVVKH.js.map} +1 -1
  5. package/dist/_chunks/{PkStreamingMarkdown-Bry3y6Ru.js → PkStreamingMarkdown-DKyHYHUN.js} +890 -853
  6. package/dist/_chunks/{PkStreamingMarkdown-Bry3y6Ru.js.map → PkStreamingMarkdown-DKyHYHUN.js.map} +1 -1
  7. package/dist/_chunks/{PkToolEditSpreadsheet-5vHzEy4P.js → PkToolEditSpreadsheet-CfJ3BWMe.js} +3 -3
  8. package/dist/_chunks/{PkToolEditSpreadsheet-5vHzEy4P.js.map → PkToolEditSpreadsheet-CfJ3BWMe.js.map} +1 -1
  9. package/dist/_chunks/{PkToolRequestGeolocation-Cj8hTfNF.js → PkToolRequestGeolocation-PxhQxMP1.js} +2 -2
  10. package/dist/_chunks/{PkToolRequestGeolocation-Cj8hTfNF.js.map → PkToolRequestGeolocation-PxhQxMP1.js.map} +1 -1
  11. package/dist/_chunks/{PkToolRequestOAuthConnection-BWxR1hV4.js → PkToolRequestOAuthConnection-klmrRZWz.js} +6 -5
  12. package/dist/_chunks/PkToolRequestOAuthConnection-klmrRZWz.js.map +1 -0
  13. package/dist/_chunks/{PkToolShowArtifact-CfJLe8vD.js → PkToolShowArtifact-ChDm6ZEK.js} +3 -3
  14. package/dist/_chunks/PkToolShowArtifact-ChDm6ZEK.js.map +1 -0
  15. package/dist/_chunks/{PkToolShowCalendarEvent-Bp_yv8S7.js → PkToolShowCalendarEvent-CRVtR3oP.js} +5 -4
  16. package/dist/_chunks/PkToolShowCalendarEvent-CRVtR3oP.js.map +1 -0
  17. package/dist/_chunks/{PkToolShowComparison-Bvd4f4tJ.js → PkToolShowComparison-DLC22e1W.js} +4 -3
  18. package/dist/_chunks/PkToolShowComparison-DLC22e1W.js.map +1 -0
  19. package/dist/_chunks/{PkToolShowContactForm--9XOVqNB.js → PkToolShowContactForm-CfCy-b8w.js} +6 -6
  20. package/dist/_chunks/PkToolShowContactForm-CfCy-b8w.js.map +1 -0
  21. package/dist/_chunks/{PkToolShowDiagram-C-pNbC9n.js → PkToolShowDiagram-JpRMa4Jj.js} +11 -10
  22. package/dist/_chunks/PkToolShowDiagram-JpRMa4Jj.js.map +1 -0
  23. package/dist/_chunks/{PkToolShowEmail-BKel_O29.js → PkToolShowEmail-C7mUCqGL.js} +4 -3
  24. package/dist/_chunks/PkToolShowEmail-C7mUCqGL.js.map +1 -0
  25. package/dist/_chunks/{PkToolShowForm-CGAc1O6K.js → PkToolShowForm-DnIwTGl4.js} +6 -5
  26. package/dist/_chunks/PkToolShowForm-DnIwTGl4.js.map +1 -0
  27. package/dist/_chunks/{PkToolShowImageGallery-CIhIrIcY.js → PkToolShowImageGallery-Ab8fJ9jY.js} +4 -4
  28. package/dist/_chunks/{PkToolShowImageGallery-CIhIrIcY.js.map → PkToolShowImageGallery-Ab8fJ9jY.js.map} +1 -1
  29. package/dist/_chunks/{PkToolShowLocation-78C7jFiV.js → PkToolShowLocation-D5d6bbP-.js} +5 -4
  30. package/dist/_chunks/PkToolShowLocation-D5d6bbP-.js.map +1 -0
  31. package/dist/_chunks/{PkToolShowMessage-BScy-w4J.js → PkToolShowMessage-vw4XS4TR.js} +4 -3
  32. package/dist/_chunks/PkToolShowMessage-vw4XS4TR.js.map +1 -0
  33. package/dist/_chunks/{PkToolShowProductList-BjWKnbyD.js → PkToolShowProductList-DztzZVDd.js} +2 -2
  34. package/dist/_chunks/{PkToolShowProductList-BjWKnbyD.js.map → PkToolShowProductList-DztzZVDd.js.map} +1 -1
  35. package/dist/_chunks/{PkToolShowQrCode-B70jPHDw.js → PkToolShowQrCode-BhcAUXSZ.js} +4 -3
  36. package/dist/_chunks/PkToolShowQrCode-BhcAUXSZ.js.map +1 -0
  37. package/dist/_chunks/{PkToolShowSources-BJ-XFrLD.js → PkToolShowSources-Bvg3f3GC.js} +52 -51
  38. package/dist/_chunks/PkToolShowSources-Bvg3f3GC.js.map +1 -0
  39. package/dist/_chunks/{PkToolShowSuggestedReply-0KahUIlw.js → PkToolShowSuggestedReply-BISQY1ce.js} +2 -2
  40. package/dist/_chunks/{PkToolShowSuggestedReply-0KahUIlw.js.map → PkToolShowSuggestedReply-BISQY1ce.js.map} +1 -1
  41. package/dist/_chunks/{PkToolShowVideo-_V_d-PDr.js → PkToolShowVideo-DdoYLl7R.js} +3 -3
  42. package/dist/_chunks/{PkToolShowVideo-_V_d-PDr.js.map → PkToolShowVideo-DdoYLl7R.js.map} +1 -1
  43. package/dist/_chunks/{PkToolShowWeather-DfLsFayn.js → PkToolShowWeather-CnpPZCLm.js} +2 -2
  44. package/dist/_chunks/{PkToolShowWeather-DfLsFayn.js.map → PkToolShowWeather-CnpPZCLm.js.map} +1 -1
  45. package/dist/_chunks/{PkToolShowWebPages-D55VEPjK.js → PkToolShowWebPages-BooCEJrs.js} +3 -3
  46. package/dist/_chunks/{PkToolShowWebPages-D55VEPjK.js.map → PkToolShowWebPages-BooCEJrs.js.map} +1 -1
  47. package/dist/_chunks/VvButtonLocalized-DV-zbH9b.js +21 -0
  48. package/dist/_chunks/VvButtonLocalized-DV-zbH9b.js.map +1 -0
  49. package/dist/_chunks/{chatImagePolicy-DXkhb-N_.js → chatImagePolicy-CfJt8_9Z.js} +3 -3
  50. package/dist/_chunks/{chatImagePolicy-DXkhb-N_.js.map → chatImagePolicy-CfJt8_9Z.js.map} +1 -1
  51. package/dist/_chunks/{index.es-BrsciU25.js → index.es-oI6RqNZW.js} +2 -2
  52. package/dist/_chunks/{index.es-BrsciU25.js.map → index.es-oI6RqNZW.js.map} +1 -1
  53. package/dist/_chunks/{markdown-DpoAzJSk.js → markdown-BbaLt57-.js} +8 -8
  54. package/dist/_chunks/{markdown-DpoAzJSk.js.map → markdown-BbaLt57-.js.map} +1 -1
  55. package/dist/_chunks/{src-Dt4rhhPN.js → src-DL9TKN-Z.js} +2 -2
  56. package/dist/_chunks/src-DL9TKN-Z.js.map +1 -0
  57. package/dist/_chunks/text-BHCGblDQ.js +6 -0
  58. package/dist/_chunks/text-BHCGblDQ.js.map +1 -0
  59. package/dist/_chunks/{useLightbox-pPBe746W.js → useLightbox-1KKLemEE.js} +2 -2
  60. package/dist/_chunks/{useLightbox-pPBe746W.js.map → useLightbox-1KKLemEE.js.map} +1 -1
  61. package/dist/ai-elements.es.js +2792 -2529
  62. package/dist/ai-elements.es.js.map +1 -1
  63. package/dist-vue/PkChatbot.js +1 -1
  64. package/dist-vue/PkChatbotAudioTranscript.js +1 -1
  65. package/dist-vue/PkChatbotAuth.js +1 -1
  66. package/dist-vue/PkChatbotEmptyState.js +1 -1
  67. package/dist-vue/PkChatbotError.js +1 -1
  68. package/dist-vue/PkChatbotFeedbackForm.js +1 -1
  69. package/dist-vue/PkChatbotFilePreview.js +1 -1
  70. package/dist-vue/PkChatbotInput.js +1 -1
  71. package/dist-vue/PkChatbotMessages.js +1 -1
  72. package/dist-vue/PkChatbotStepPayload.js +1 -1
  73. package/dist-vue/PkChatbotStepToolDetail.js +1 -1
  74. package/dist-vue/PkChatbotSteps.js +1 -1
  75. package/dist-vue/PkChatbotViewChat.js +1 -1
  76. package/dist-vue/PkChatbotViewConversations.js +1 -1
  77. package/dist-vue/PkChatbotViewFiles.js +1 -1
  78. package/dist-vue/PkChatbotViewProfile.js +1 -1
  79. package/dist-vue/PkChatbotWakeupBar.js +1 -1
  80. package/dist-vue/_chunks/{Agent-dGF8mkG9.js → Agent-DU1WWaHR.js} +87 -87
  81. package/dist-vue/_chunks/Agent-DU1WWaHR.js.map +1 -0
  82. package/dist-vue/_chunks/{Document-CV-RJu_p.js → Document-Cto-Qws0.js} +2 -2
  83. package/dist-vue/_chunks/{Document-CV-RJu_p.js.map → Document-Cto-Qws0.js.map} +1 -1
  84. package/dist-vue/_chunks/{PkChatbot-536vsOfp.js → PkChatbot-C18mnGJ9.js} +86 -85
  85. package/dist-vue/_chunks/PkChatbot-C18mnGJ9.js.map +1 -0
  86. package/dist-vue/_chunks/{PkChatbotAudioTranscript-BUxBHanA.js → PkChatbotAudioTranscript-0rvrhSRQ.js} +2 -2
  87. package/dist-vue/_chunks/{PkChatbotAudioTranscript-BUxBHanA.js.map → PkChatbotAudioTranscript-0rvrhSRQ.js.map} +1 -1
  88. package/dist-vue/_chunks/{PkChatbotAuth-BMLLTSwK.js → PkChatbotAuth-BVZzjbK9.js} +4 -3
  89. package/dist-vue/_chunks/PkChatbotAuth-BVZzjbK9.js.map +1 -0
  90. package/dist-vue/_chunks/{PkChatbotEmptyState-Toj4CqXV.js → PkChatbotEmptyState-BKiyP0Ga.js} +2 -2
  91. package/dist-vue/_chunks/{PkChatbotEmptyState-Toj4CqXV.js.map → PkChatbotEmptyState-BKiyP0Ga.js.map} +1 -1
  92. package/dist-vue/_chunks/{PkChatbotError-CRGbK09-.js → PkChatbotError-BV5ga7hk.js} +4 -3
  93. package/dist-vue/_chunks/PkChatbotError-BV5ga7hk.js.map +1 -0
  94. package/dist-vue/_chunks/{PkChatbotFeedbackForm-CMFXjoKR.js → PkChatbotFeedbackForm-B5cYsWBr.js} +8 -7
  95. package/dist-vue/_chunks/PkChatbotFeedbackForm-B5cYsWBr.js.map +1 -0
  96. package/dist-vue/_chunks/{PkChatbotFilePreview-DIP8KLkS.js → PkChatbotFilePreview-D5H-RIk2.js} +2 -2
  97. package/dist-vue/_chunks/{PkChatbotFilePreview-DIP8KLkS.js.map → PkChatbotFilePreview-D5H-RIk2.js.map} +1 -1
  98. package/dist-vue/_chunks/{PkChatbotInput-BfZqRpQ2.js → PkChatbotInput-GvgsYsUw.js} +8 -7
  99. package/dist-vue/_chunks/PkChatbotInput-GvgsYsUw.js.map +1 -0
  100. package/dist-vue/_chunks/PkChatbotMessages-CDLsj7qw.js +876 -0
  101. package/dist-vue/_chunks/PkChatbotMessages-CDLsj7qw.js.map +1 -0
  102. package/dist-vue/_chunks/{PkChatbotStepPayload-D0eoPBQ8.js → PkChatbotStepPayload-Dm-HCHcG.js} +2 -2
  103. package/dist-vue/_chunks/{PkChatbotStepPayload-D0eoPBQ8.js.map → PkChatbotStepPayload-Dm-HCHcG.js.map} +1 -1
  104. package/dist-vue/_chunks/{PkChatbotStepToolDetail-CMx4cw1D.js → PkChatbotStepToolDetail-Bpd_cZEO.js} +16 -16
  105. package/dist-vue/_chunks/{PkChatbotStepToolDetail-CMx4cw1D.js.map → PkChatbotStepToolDetail-Bpd_cZEO.js.map} +1 -1
  106. package/dist-vue/_chunks/{PkChatbotSteps-DeZQhGRU.js → PkChatbotSteps-C4qBM3_t.js} +40 -40
  107. package/dist-vue/_chunks/{PkChatbotSteps-DeZQhGRU.js.map → PkChatbotSteps-C4qBM3_t.js.map} +1 -1
  108. package/dist-vue/_chunks/{PkChatbotViewChat-CVT6OUIv.js → PkChatbotViewChat-By2TY72m.js} +13 -13
  109. package/dist-vue/_chunks/{PkChatbotViewChat-CVT6OUIv.js.map → PkChatbotViewChat-By2TY72m.js.map} +1 -1
  110. package/dist-vue/_chunks/PkChatbotViewConversations-CU5NfEO4.js +199 -0
  111. package/dist-vue/_chunks/PkChatbotViewConversations-CU5NfEO4.js.map +1 -0
  112. package/dist-vue/_chunks/{PkChatbotViewFiles-CA20TBFY.js → PkChatbotViewFiles-CD-UZPT5.js} +18 -17
  113. package/dist-vue/_chunks/PkChatbotViewFiles-CD-UZPT5.js.map +1 -0
  114. package/dist-vue/_chunks/{PkChatbotViewProfile-CyzRxE3D.js → PkChatbotViewProfile-DPlb_Wca.js} +11 -10
  115. package/dist-vue/_chunks/PkChatbotViewProfile-DPlb_Wca.js.map +1 -0
  116. package/dist-vue/_chunks/{PkChatbotWakeupBar-jBti21FQ.js → PkChatbotWakeupBar-Cjgarxnw.js} +3 -2
  117. package/dist-vue/_chunks/PkChatbotWakeupBar-Cjgarxnw.js.map +1 -0
  118. package/dist-vue/_chunks/{PkStreamingMarkdown-C55Fi0Pd.js → PkStreamingMarkdown-CsHzdW69.js} +24 -24
  119. package/dist-vue/_chunks/{PkStreamingMarkdown-C55Fi0Pd.js.map → PkStreamingMarkdown-CsHzdW69.js.map} +1 -1
  120. package/dist-vue/_chunks/{PkSvgViewer-Ts3gQ1hB.js → PkSvgViewer-D6DJ2jVO.js} +7 -6
  121. package/dist-vue/_chunks/PkSvgViewer-D6DJ2jVO.js.map +1 -0
  122. package/dist-vue/_chunks/{PkToolEditSpreadsheet-HAskd6d3.js → PkToolEditSpreadsheet-D8Zp9gzW.js} +3 -3
  123. package/dist-vue/_chunks/{PkToolEditSpreadsheet-HAskd6d3.js.map → PkToolEditSpreadsheet-D8Zp9gzW.js.map} +1 -1
  124. package/dist-vue/_chunks/{PkToolRequestGeolocation-BE22qwxB.js → PkToolRequestGeolocation-JZYgc-2X.js} +2 -2
  125. package/dist-vue/_chunks/{PkToolRequestGeolocation-BE22qwxB.js.map → PkToolRequestGeolocation-JZYgc-2X.js.map} +1 -1
  126. package/dist-vue/_chunks/{PkToolRequestOAuthConnection-GfSalEJG.js → PkToolRequestOAuthConnection-DosWR9I4.js} +11 -10
  127. package/dist-vue/_chunks/PkToolRequestOAuthConnection-DosWR9I4.js.map +1 -0
  128. package/dist-vue/_chunks/{PkToolShowArtifact-z1qTnFkA.js → PkToolShowArtifact-BVofKJ7b.js} +5 -5
  129. package/dist-vue/_chunks/PkToolShowArtifact-BVofKJ7b.js.map +1 -0
  130. package/dist-vue/_chunks/{PkToolShowCalendarEvent-Dv_rss26.js → PkToolShowCalendarEvent-u9O_Sl3-.js} +8 -7
  131. package/dist-vue/_chunks/PkToolShowCalendarEvent-u9O_Sl3-.js.map +1 -0
  132. package/dist-vue/_chunks/{PkToolShowComparison-DQs3E6-k.js → PkToolShowComparison-c2e239T4.js} +3 -2
  133. package/dist-vue/_chunks/PkToolShowComparison-c2e239T4.js.map +1 -0
  134. package/dist-vue/_chunks/{PkToolShowContactForm-Y0lrHXhr.js → PkToolShowContactForm-BzdIFTnC.js} +13 -13
  135. package/dist-vue/_chunks/PkToolShowContactForm-BzdIFTnC.js.map +1 -0
  136. package/dist-vue/_chunks/{PkToolShowDiagram-7WxDObZ6.js → PkToolShowDiagram-CaoB4k6y.js} +11 -10
  137. package/dist-vue/_chunks/PkToolShowDiagram-CaoB4k6y.js.map +1 -0
  138. package/dist-vue/_chunks/{PkToolShowEmail-C591LR5N.js → PkToolShowEmail-CUgZN0J5.js} +8 -7
  139. package/dist-vue/_chunks/PkToolShowEmail-CUgZN0J5.js.map +1 -0
  140. package/dist-vue/_chunks/{PkToolShowForm-CZFWZub7.js → PkToolShowForm-vYuaPtu0.js} +14 -13
  141. package/dist-vue/_chunks/PkToolShowForm-vYuaPtu0.js.map +1 -0
  142. package/dist-vue/_chunks/{PkToolShowImageGallery-CkfXP_lD.js → PkToolShowImageGallery-ooygXk7j.js} +4 -4
  143. package/dist-vue/_chunks/{PkToolShowImageGallery-CkfXP_lD.js.map → PkToolShowImageGallery-ooygXk7j.js.map} +1 -1
  144. package/dist-vue/_chunks/{PkToolShowLocation-Dyz6h_0n.js → PkToolShowLocation-DVMpFdRk.js} +14 -13
  145. package/dist-vue/_chunks/PkToolShowLocation-DVMpFdRk.js.map +1 -0
  146. package/dist-vue/_chunks/{PkToolShowMessage-CbXERPHI.js → PkToolShowMessage-ATTN5Hac.js} +8 -7
  147. package/dist-vue/_chunks/PkToolShowMessage-ATTN5Hac.js.map +1 -0
  148. package/dist-vue/_chunks/{PkToolShowProductList-De-PtmD-.js → PkToolShowProductList-D-HJ9a_h.js} +2 -2
  149. package/dist-vue/_chunks/{PkToolShowProductList-De-PtmD-.js.map → PkToolShowProductList-D-HJ9a_h.js.map} +1 -1
  150. package/dist-vue/_chunks/{PkToolShowQrCode-DEAvfLFu.js → PkToolShowQrCode-D_5VUtEB.js} +3 -2
  151. package/dist-vue/_chunks/PkToolShowQrCode-D_5VUtEB.js.map +1 -0
  152. package/dist-vue/_chunks/{PkToolShowSources-CSN7S0zo.js → PkToolShowSources-DJ35l3Z3.js} +58 -57
  153. package/dist-vue/_chunks/PkToolShowSources-DJ35l3Z3.js.map +1 -0
  154. package/dist-vue/_chunks/{PkToolShowSuggestedReply-DjutyiEi.js → PkToolShowSuggestedReply-I6FBos-F.js} +2 -2
  155. package/dist-vue/_chunks/{PkToolShowSuggestedReply-DjutyiEi.js.map → PkToolShowSuggestedReply-I6FBos-F.js.map} +1 -1
  156. package/dist-vue/_chunks/{PkToolShowVideo-B_Q93E2y.js → PkToolShowVideo-xcg1gdIE.js} +3 -3
  157. package/dist-vue/_chunks/{PkToolShowVideo-B_Q93E2y.js.map → PkToolShowVideo-xcg1gdIE.js.map} +1 -1
  158. package/dist-vue/_chunks/{PkToolShowWeather-BOuNrvY2.js → PkToolShowWeather-DJxKxVp_.js} +2 -2
  159. package/dist-vue/_chunks/{PkToolShowWeather-BOuNrvY2.js.map → PkToolShowWeather-DJxKxVp_.js.map} +1 -1
  160. package/dist-vue/_chunks/{PkToolShowWebPages-D3CdjJUc.js → PkToolShowWebPages-BuaRjavD.js} +3 -3
  161. package/dist-vue/_chunks/{PkToolShowWebPages-D3CdjJUc.js.map → PkToolShowWebPages-BuaRjavD.js.map} +1 -1
  162. package/dist-vue/_chunks/VvButtonLocalized-BuzLsXp3.js +20 -0
  163. package/dist-vue/_chunks/VvButtonLocalized-BuzLsXp3.js.map +1 -0
  164. package/dist-vue/_chunks/{createChatbotApiClient-DSLxswr4.js → createChatbotApiClient-G3Tt1I67.js} +18 -18
  165. package/dist-vue/_chunks/{createChatbotApiClient-DSLxswr4.js.map → createChatbotApiClient-G3Tt1I67.js.map} +1 -1
  166. package/dist-vue/_chunks/{mcpOAuthReport-BeZDTl87.js → mcpOAuthReport-3A9v_gW_.js} +2 -2
  167. package/dist-vue/_chunks/{mcpOAuthReport-BeZDTl87.js.map → mcpOAuthReport-3A9v_gW_.js.map} +1 -1
  168. package/dist-vue/_chunks/{src-DCfvejyT.js → src-DpkuiHam.js} +2 -2
  169. package/dist-vue/_chunks/src-DpkuiHam.js.map +1 -0
  170. package/dist-vue/_chunks/{useChatbotStore-rtl-oKqU.js → useChatbotStore-C1sgxgD1.js} +5 -5
  171. package/dist-vue/_chunks/{useChatbotStore-rtl-oKqU.js.map → useChatbotStore-C1sgxgD1.js.map} +1 -1
  172. package/dist-vue/_chunks/{useSafeLocalStorage-OwzVTZud.js → useSafeLocalStorage-DLIc8pkn.js} +2 -2
  173. package/dist-vue/_chunks/{useSafeLocalStorage-OwzVTZud.js.map → useSafeLocalStorage-DLIc8pkn.js.map} +1 -1
  174. package/dist-vue/_chunks/{utils-CwIMEuAv.js → utils-DsnEcdW3.js} +143 -79
  175. package/dist-vue/_chunks/utils-DsnEcdW3.js.map +1 -0
  176. package/dist-vue/api.js +1 -1
  177. package/dist-vue/composables.js +279 -27
  178. package/dist-vue/composables.js.map +1 -1
  179. package/dist-vue/index.js +3909 -3881
  180. package/dist-vue/index.js.map +1 -1
  181. package/dist-vue/locales.js +42 -6
  182. package/dist-vue/packages/components/src/PkEditorMarkdown.d.ts +3 -2
  183. package/dist-vue/packages/components/src/VvButtonLocalized.d.ts +11 -0
  184. package/dist-vue/packages/components/src/chat/index.d.ts +1 -0
  185. package/dist-vue/packages/components/src/chat/utils.d.ts +30 -0
  186. package/dist-vue/packages/components/src/index.d.ts +1 -0
  187. package/package.json +1 -1
  188. package/dist/_chunks/Agent-D8YrsP52.js.map +0 -1
  189. package/dist/_chunks/PkToolRequestOAuthConnection-BWxR1hV4.js.map +0 -1
  190. package/dist/_chunks/PkToolShowArtifact-CfJLe8vD.js.map +0 -1
  191. package/dist/_chunks/PkToolShowCalendarEvent-Bp_yv8S7.js.map +0 -1
  192. package/dist/_chunks/PkToolShowComparison-Bvd4f4tJ.js.map +0 -1
  193. package/dist/_chunks/PkToolShowContactForm--9XOVqNB.js.map +0 -1
  194. package/dist/_chunks/PkToolShowDiagram-C-pNbC9n.js.map +0 -1
  195. package/dist/_chunks/PkToolShowEmail-BKel_O29.js.map +0 -1
  196. package/dist/_chunks/PkToolShowForm-CGAc1O6K.js.map +0 -1
  197. package/dist/_chunks/PkToolShowLocation-78C7jFiV.js.map +0 -1
  198. package/dist/_chunks/PkToolShowMessage-BScy-w4J.js.map +0 -1
  199. package/dist/_chunks/PkToolShowQrCode-B70jPHDw.js.map +0 -1
  200. package/dist/_chunks/PkToolShowSources-BJ-XFrLD.js.map +0 -1
  201. package/dist/_chunks/src-Dt4rhhPN.js.map +0 -1
  202. package/dist/_chunks/text-DbSEK8si.js +0 -6
  203. package/dist/_chunks/text-DbSEK8si.js.map +0 -1
  204. package/dist-vue/_chunks/Agent-dGF8mkG9.js.map +0 -1
  205. package/dist-vue/_chunks/PkChatbot-536vsOfp.js.map +0 -1
  206. package/dist-vue/_chunks/PkChatbotAuth-BMLLTSwK.js.map +0 -1
  207. package/dist-vue/_chunks/PkChatbotError-CRGbK09-.js.map +0 -1
  208. package/dist-vue/_chunks/PkChatbotFeedbackForm-CMFXjoKR.js.map +0 -1
  209. package/dist-vue/_chunks/PkChatbotInput-BfZqRpQ2.js.map +0 -1
  210. package/dist-vue/_chunks/PkChatbotMessages-CnI3e9wF.js +0 -869
  211. package/dist-vue/_chunks/PkChatbotMessages-CnI3e9wF.js.map +0 -1
  212. package/dist-vue/_chunks/PkChatbotViewConversations-DHeFtAfN.js +0 -197
  213. package/dist-vue/_chunks/PkChatbotViewConversations-DHeFtAfN.js.map +0 -1
  214. package/dist-vue/_chunks/PkChatbotViewFiles-CA20TBFY.js.map +0 -1
  215. package/dist-vue/_chunks/PkChatbotViewProfile-CyzRxE3D.js.map +0 -1
  216. package/dist-vue/_chunks/PkChatbotWakeupBar-jBti21FQ.js.map +0 -1
  217. package/dist-vue/_chunks/PkSvgViewer-Ts3gQ1hB.js.map +0 -1
  218. package/dist-vue/_chunks/PkToolRequestOAuthConnection-GfSalEJG.js.map +0 -1
  219. package/dist-vue/_chunks/PkToolShowArtifact-z1qTnFkA.js.map +0 -1
  220. package/dist-vue/_chunks/PkToolShowCalendarEvent-Dv_rss26.js.map +0 -1
  221. package/dist-vue/_chunks/PkToolShowComparison-DQs3E6-k.js.map +0 -1
  222. package/dist-vue/_chunks/PkToolShowContactForm-Y0lrHXhr.js.map +0 -1
  223. package/dist-vue/_chunks/PkToolShowDiagram-7WxDObZ6.js.map +0 -1
  224. package/dist-vue/_chunks/PkToolShowEmail-C591LR5N.js.map +0 -1
  225. package/dist-vue/_chunks/PkToolShowForm-CZFWZub7.js.map +0 -1
  226. package/dist-vue/_chunks/PkToolShowLocation-Dyz6h_0n.js.map +0 -1
  227. package/dist-vue/_chunks/PkToolShowMessage-CbXERPHI.js.map +0 -1
  228. package/dist-vue/_chunks/PkToolShowQrCode-DEAvfLFu.js.map +0 -1
  229. package/dist-vue/_chunks/PkToolShowSources-CSN7S0zo.js.map +0 -1
  230. package/dist-vue/_chunks/src-DCfvejyT.js.map +0 -1
  231. package/dist-vue/_chunks/utils-CwIMEuAv.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PkToolShowComparison-c2e239T4.js","names":["$t","__unplugin_components_0","__unplugin_components_1","__unplugin_components_2","_openBlock","_createElementBlock","_createElementVNode","_createVNode","_toDisplayString","_withCtx","_unref","_Fragment","_renderList","_normalizeClass","_createTextVNode","_createCommentVNode","_sfc_main","__exportAll","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","PkToolShowComparison_vue_vue_type_script_setup_true_lang_default","props","__props","useClipboard","toolPart","computed","features","items","valueColorClass","value","copyTable","header","i","rows","f","_component_VvIcon","VvIcon","_component_VvButton","VvButtonLocalized","_component_VvButtonGroup","VvButtonGroup","openBlock","createElementBlock","createElementVNode","createVNode","toDisplayString","_ctx","withCtx","unref","copied","_cache","Fragment","renderList","item","normalizeClass","createTextVNode","createCommentVNode","feature","PkToolShowComparison_exports","PkToolShowComparison_default"],"sources":["../../../../packages/components/src/chat/PkToolShowComparison.vue","../../../../packages/components/src/chat/PkToolShowComparison.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useClipboard } from '@vueuse/core'\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const { copy, copied } = useClipboard()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n title?: string\n items: Array<{\n name: string\n values: Record<string, string>\n highlighted?: boolean\n }>\n }\n }\n return part\n })\n\n const features = computed(() => {\n const items = toolPart.value.input?.items\n if (!items || items.length === 0) {\n return []\n }\n return Object.keys(items[0].values)\n })\n\n // The tool contract asks for \"✓\" and \"✗\" on boolean features: the pair is\n // a verdict, so it wears one and the table reads by eye (DESIGN.md).\n const valueColorClass = (value?: string) => {\n if (value === '✓') {\n return 'text-success'\n }\n if (value === '✗') {\n return 'text-danger'\n }\n return 'text-word-2'\n }\n\n const copyTable = () => {\n const items = toolPart.value.input?.items\n if (!items) {\n return\n }\n const header = ['', ...items.map((i) => i.name)].join('\\t')\n const rows = features.value.map((f) =>\n [f.replace(/_/g, ' '), ...items.map((i) => i.values[f] ?? '')].join(\n '\\t',\n ),\n )\n copy([header, ...rows].join('\\n'))\n }\n</script>\n\n<template>\n <div\n v-if=\"toolPart?.input?.items?.length\"\n class=\"pk-tool-comparison border border-surface-3 rounded-xl w-full overflow-hidden\">\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\">\n <VvIcon name=\"ri:scales-line\" class=\"text-16\" />\n <strong class=\"font-bold\">{{\n toolPart.input.title ?? $t('label.comparison')\n }}</strong>\n <VvButtonGroup modifiers=\"compact\" class=\"ml-auto shrink-0\">\n <VvButton\n modifiers=\"action-quiet-small\"\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n @click=\"copyTable\" />\n </VvButtonGroup>\n </div>\n <!-- One row per feature, one column per item. In a narrow message\n each feature becomes a block that lists every item beside its\n value (`u-table--stack`), so a comparison still reads across. -->\n <div class=\"u-table-scroll\">\n <table class=\"u-table u-table--stack\" role=\"table\">\n <thead role=\"rowgroup\">\n <tr role=\"row\">\n <td></td>\n <th\n v-for=\"item in toolPart.input.items\"\n :key=\"item.name\"\n role=\"columnheader\"\n scope=\"col\"\n class=\"pk-tool-comparison__item\"\n :class=\"{\n 'pk-tool-comparison__cell--highlighted':\n item.highlighted,\n }\">\n {{ item.name }}\n <small\n v-if=\"item.highlighted\"\n class=\"pk-tool-comparison__recommended\">\n {{ $t('label.recommended') }}\n </small>\n </th>\n </tr>\n </thead>\n <tbody role=\"rowgroup\">\n <tr v-for=\"feature in features\" :key=\"feature\" role=\"row\">\n <th\n role=\"rowheader\"\n scope=\"row\"\n class=\"pk-tool-comparison__feature\">\n {{ feature.replace(/_/g, ' ') }}\n </th>\n <td\n v-for=\"item in toolPart.input.items\"\n :key=\"item.name\"\n role=\"cell\"\n :data-label=\"item.name\"\n :class=\"[\n valueColorClass(item.values[feature]),\n {\n 'pk-tool-comparison__cell--highlighted':\n item.highlighted,\n },\n ]\">\n {{ item.values[feature] ?? '-' }}\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n</template>\n\n<style lang=\"scss\">\n // Written under the block so it outweighs the `.u-table` rules.\n .pk-tool-comparison {\n // Stacked, the labels are the names of the items, longer than the\n // headings of a data table.\n --u-table-label-width: 8rem;\n\n // The items are what the table compares: their names are the titles\n // of the columns, not the small headings of a data table.\n & &__item {\n font-size: var(--text-14);\n color: var(--color-word-1);\n }\n\n & &__feature {\n font-weight: var(--font-medium);\n color: var(--color-word-3);\n }\n\n // The recommended item: a ground down its column and a word under its\n // name, no accent colour (DESIGN.md). Stacked, its name weighs more\n // than the others beside its value.\n & &__cell--highlighted {\n background-color: var(--color-surface-1);\n }\n\n &__recommended {\n display: block;\n font-size: var(--text-12);\n font-weight: var(--font-normal);\n color: var(--color-word-3);\n }\n\n @container (width < 30rem) {\n & &__cell--highlighted {\n background-color: transparent;\n\n &::before {\n font-weight: var(--font-semibold);\n color: var(--color-word-1);\n }\n }\n }\n }\n</style>\n","<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useClipboard } from '@vueuse/core'\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const { copy, copied } = useClipboard()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n title?: string\n items: Array<{\n name: string\n values: Record<string, string>\n highlighted?: boolean\n }>\n }\n }\n return part\n })\n\n const features = computed(() => {\n const items = toolPart.value.input?.items\n if (!items || items.length === 0) {\n return []\n }\n return Object.keys(items[0].values)\n })\n\n // The tool contract asks for \"✓\" and \"✗\" on boolean features: the pair is\n // a verdict, so it wears one and the table reads by eye (DESIGN.md).\n const valueColorClass = (value?: string) => {\n if (value === '✓') {\n return 'text-success'\n }\n if (value === '✗') {\n return 'text-danger'\n }\n return 'text-word-2'\n }\n\n const copyTable = () => {\n const items = toolPart.value.input?.items\n if (!items) {\n return\n }\n const header = ['', ...items.map((i) => i.name)].join('\\t')\n const rows = features.value.map((f) =>\n [f.replace(/_/g, ' '), ...items.map((i) => i.values[f] ?? '')].join(\n '\\t',\n ),\n )\n copy([header, ...rows].join('\\n'))\n }\n</script>\n\n<template>\n <div\n v-if=\"toolPart?.input?.items?.length\"\n class=\"pk-tool-comparison border border-surface-3 rounded-xl w-full overflow-hidden\">\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\">\n <VvIcon name=\"ri:scales-line\" class=\"text-16\" />\n <strong class=\"font-bold\">{{\n toolPart.input.title ?? $t('label.comparison')\n }}</strong>\n <VvButtonGroup modifiers=\"compact\" class=\"ml-auto shrink-0\">\n <VvButton\n modifiers=\"action-quiet-small\"\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n @click=\"copyTable\" />\n </VvButtonGroup>\n </div>\n <!-- One row per feature, one column per item. In a narrow message\n each feature becomes a block that lists every item beside its\n value (`u-table--stack`), so a comparison still reads across. -->\n <div class=\"u-table-scroll\">\n <table class=\"u-table u-table--stack\" role=\"table\">\n <thead role=\"rowgroup\">\n <tr role=\"row\">\n <td></td>\n <th\n v-for=\"item in toolPart.input.items\"\n :key=\"item.name\"\n role=\"columnheader\"\n scope=\"col\"\n class=\"pk-tool-comparison__item\"\n :class=\"{\n 'pk-tool-comparison__cell--highlighted':\n item.highlighted,\n }\">\n {{ item.name }}\n <small\n v-if=\"item.highlighted\"\n class=\"pk-tool-comparison__recommended\">\n {{ $t('label.recommended') }}\n </small>\n </th>\n </tr>\n </thead>\n <tbody role=\"rowgroup\">\n <tr v-for=\"feature in features\" :key=\"feature\" role=\"row\">\n <th\n role=\"rowheader\"\n scope=\"row\"\n class=\"pk-tool-comparison__feature\">\n {{ feature.replace(/_/g, ' ') }}\n </th>\n <td\n v-for=\"item in toolPart.input.items\"\n :key=\"item.name\"\n role=\"cell\"\n :data-label=\"item.name\"\n :class=\"[\n valueColorClass(item.values[feature]),\n {\n 'pk-tool-comparison__cell--highlighted':\n item.highlighted,\n },\n ]\">\n {{ item.values[feature] ?? '-' }}\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n</template>\n\n<style lang=\"scss\">\n // Written under the block so it outweighs the `.u-table` rules.\n .pk-tool-comparison {\n // Stacked, the labels are the names of the items, longer than the\n // headings of a data table.\n --u-table-label-width: 8rem;\n\n // The items are what the table compares: their names are the titles\n // of the columns, not the small headings of a data table.\n & &__item {\n font-size: var(--text-14);\n color: var(--color-word-1);\n }\n\n & &__feature {\n font-weight: var(--font-medium);\n color: var(--color-word-3);\n }\n\n // The recommended item: a ground down its column and a word under its\n // name, no accent colour (DESIGN.md). Stacked, its name weighs more\n // than the others beside its value.\n & &__cell--highlighted {\n background-color: var(--color-surface-1);\n }\n\n &__recommended {\n display: block;\n font-size: var(--text-12);\n font-weight: var(--font-normal);\n color: var(--color-word-3);\n }\n\n @container (width < 30rem) {\n & &__cell--highlighted {\n background-color: transparent;\n\n &::before {\n font-weight: var(--font-semibold);\n color: var(--color-word-1);\n }\n }\n }\n }\n</style>\n"],"mappings":"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"}
@@ -1,10 +1,11 @@
1
1
  import { t as e } from "./rolldown-runtime-Dy4uBu1J.js";
2
2
  import { S as t, d as n, v as r } from "./schemas-Bu1lick6.js";
3
- import { t as i } from "./PkStreamingMarkdown-C55Fi0Pd.js";
4
- import { t as a } from "./useSafeLocalStorage-OwzVTZud.js";
5
- import { t as o } from "./useLocalizedString-PfaKjIQY.js";
6
- import { t as s } from "./index.es-C1u3kP7i.js";
7
- import { VvButton as c, VvIcon as l } from "@volverjs/ui-vue/components";
3
+ import { t as i } from "./VvButtonLocalized-BuzLsXp3.js";
4
+ import { t as a } from "./PkStreamingMarkdown-CsHzdW69.js";
5
+ import { t as o } from "./useSafeLocalStorage-DLIc8pkn.js";
6
+ import { t as s } from "./useLocalizedString-PfaKjIQY.js";
7
+ import { t as c } from "./index.es-C1u3kP7i.js";
8
+ import { VvIcon as l } from "@volverjs/ui-vue/components";
8
9
  import { Transition as u, computed as d, createElementBlock as f, createElementVNode as p, createVNode as m, defineComponent as h, isRef as g, openBlock as _, toDisplayString as v, unref as y, watch as b, withCtx as x } from "vue";
9
10
  import { useI18n as S } from "vue-i18n";
10
11
  //#region ../../packages/components/src/chat/PkToolShowContactForm.vue?vue&type=script&setup=true&lang.ts
@@ -26,11 +27,11 @@ var C = { class: "border border-surface-3 rounded-xl w-full overflow-hidden bg-s
26
27
  },
27
28
  emits: ["submit"],
28
29
  setup(e, { emit: h }) {
29
- let { t: N } = S({ useScope: "global" }), P = e, F = d(() => P.part), I = d(() => F.value.input), L = a(d(() => `${F.value.toolCallId}-${F.value.type}-submitted`), !1), R = r({
30
+ let { t: N } = S({ useScope: "global" }), P = e, F = d(() => P.part), I = d(() => F.value.input), L = o(d(() => `${F.value.toolCallId}-${F.value.type}-submitted`), !1), R = r({
30
31
  name: t().min(1).max(255).default(""),
31
32
  email: n().max(255).default(""),
32
33
  phone: t().max(50).regex(/^[+0-9\s\-.()]*$/, N("validation.invalidPhoneNumber")).optional()
33
- }), z = h, { VvForm: B, VvFormField: V, formData: H } = s(R, { lazyLoad: !0 });
34
+ }), z = h, { VvForm: B, VvFormField: V, formData: H } = c(R, { lazyLoad: !0 });
34
35
  b(I, (e) => {
35
36
  H.value = {
36
37
  name: e?.name || "",
@@ -45,9 +46,9 @@ var C = { class: "border border-surface-3 rounded-xl w-full overflow-hidden bg-s
45
46
  ...e,
46
47
  metadata: I.value?.conversationContext
47
48
  });
48
- }, G = o(() => P.privacyPolicyNotice, "message.defaultPrivacyPolicyNotice");
49
+ }, G = s(() => P.privacyPolicyNotice, "message.defaultPrivacyPolicyNotice");
49
50
  return (t, n) => {
50
- let r = l, a = c;
51
+ let r = l, o = i;
51
52
  return _(), f("div", C, [p("div", w, [m(r, {
52
53
  name: "ri:send-plane-2-line",
53
54
  class: "text-16"
@@ -92,12 +93,11 @@ var C = { class: "border border-surface-3 rounded-xl w-full overflow-hidden bg-s
92
93
  p("div", D, [p("div", O, [m(r, {
93
94
  name: "ri:shield-check-line",
94
95
  class: "text-16 shrink-0"
95
- }), m(i, {
96
+ }), m(a, {
96
97
  markdown: y(G),
97
98
  class: "wysiwyg"
98
- }, null, 8, ["markdown"])]), m(a, {
99
+ }, null, 8, ["markdown"])]), m(o, {
99
100
  type: "submit",
100
- modifiers: "primary",
101
101
  loading: e.loading,
102
102
  disabled: e.loading || e.readonly,
103
103
  "icon-position": "right",
@@ -119,4 +119,4 @@ var C = { class: "border border-surface-3 rounded-xl w-full overflow-hidden bg-s
119
119
  //#endregion
120
120
  export { P as n, F as t };
121
121
 
122
- //# sourceMappingURL=PkToolShowContactForm-Y0lrHXhr.js.map
122
+ //# sourceMappingURL=PkToolShowContactForm-BzdIFTnC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PkToolShowContactForm-BzdIFTnC.js","names":["z.object","z.string","z.email","useForm","__unplugin_components_0","__unplugin_components_1","_openBlock","_createElementBlock","_createElementVNode","_createVNode","_toDisplayString","_unref","_Transition","_withCtx","_isRef","PkStreamingMarkdown","_sfc_main","__exportAll","string","email","object","VvButtonLocalized","PkStreamingMarkdown_default","useSafeLocalStorage","useLocalizedString","Se","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","PkToolShowContactForm_vue_vue_type_script_setup_true_lang_default","__emit","$t","useI18n","props","__props","toolPart","computed","input","localSubmitted","LeadFormSchema","emit","watch","newInput","submitted","isSubmitted","submitLead","data","privacyNotice","_component_VvIcon","VvIcon","_component_VvButton","openBlock","createElementBlock","createElementVNode","createVNode","toDisplayString","unref","Transition","withCtx","VvForm","formData","_cache","isRef","$event","VvFormField","PkToolShowContactForm_exports","PkToolShowContactForm_default"],"sources":["../../../../packages/components/src/chat/PkToolShowContactForm.vue","../../../../packages/components/src/chat/PkToolShowContactForm.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, watch } from 'vue'\n import { useI18n } from 'vue-i18n'\n import { useForm } from '@volverjs/form-vue'\n import * as z from 'zod'\n import { useSafeLocalStorage, useLocalizedString } from 'composables'\n import type { LocalizedString } from 'models'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n\n const { t: $t } = useI18n({ useScope: 'global' })\n\n const props = defineProps<{\n part: unknown\n submitted?: boolean\n loading?: boolean\n error?: string\n readonly?: boolean\n privacyPolicyNotice?: LocalizedString\n }>()\n\n const toolPart = computed(() => {\n const part = props.part as {\n type: string\n toolCallId: string\n input?: {\n name: string\n email: string\n phone?: string\n conversationContext?: Record<string, unknown>\n }\n }\n return part\n })\n\n const input = computed(() => toolPart.value.input)\n\n const localSubmitted = useSafeLocalStorage<boolean>(\n computed(\n () =>\n `${toolPart.value.toolCallId}-${toolPart.value.type}-submitted`,\n ),\n false,\n )\n\n const LeadFormSchema = z.object({\n name: z.string().min(1).max(255).default(''),\n email: z.email().max(255).default(''),\n phone: z\n .string()\n .max(50)\n .regex(/^[+0-9\\s\\-.()]*$/, $t('validation.invalidPhoneNumber'))\n .optional(),\n })\n\n const emit = defineEmits<{\n submit: [data: Record<string, unknown>]\n }>()\n\n const { VvForm, VvFormField, formData } = useForm(LeadFormSchema, {\n lazyLoad: true,\n })\n\n // Pre-populate form with input values\n watch(\n input,\n (newInput) => {\n formData.value = {\n name: newInput?.name || '',\n email: newInput?.email || '',\n phone: newInput?.phone || '',\n }\n },\n { immediate: true },\n )\n\n watch(\n () => props.submitted,\n (submitted) => {\n if (submitted) {\n localSubmitted.value = true\n }\n },\n { immediate: true },\n )\n\n const isSubmitted = computed(() => {\n return props.submitted || localSubmitted.value\n })\n\n const submitLead = async (data: Record<string, unknown>): Promise<void> => {\n emit('submit', { ...data, metadata: input.value?.conversationContext })\n }\n\n const privacyNotice = useLocalizedString(\n () => props.privacyPolicyNotice,\n 'message.defaultPrivacyPolicyNotice',\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:send-plane-2-line\" class=\"text-16\" />\n <strong class=\"font-bold\">{{ $t('label.contactUs') }}</strong>\n </div>\n\n <Transition mode=\"out-in\">\n <div v-if=\"!isSubmitted\" class=\"p-sm\">\n <VvForm v-model=\"formData\" :readonly @submit=\"submitLead\">\n <VvFormField\n name=\"name\"\n type=\"text\"\n :label=\"$t('label.name')\"\n :placeholder=\"$t('placeholder.name')\"\n icon=\"ri:user-line\"\n modifiers=\"compact\"\n class=\"mb-md\" />\n <VvFormField\n name=\"email\"\n type=\"email\"\n :label=\"$t('label.email')\"\n :placeholder=\"$t('placeholder.email')\"\n icon=\"ri:mail-line\"\n modifiers=\"compact\"\n class=\"mb-md\" />\n <VvFormField\n name=\"phone\"\n type=\"tel\"\n :label=\"$t('label.phone')\"\n :placeholder=\"$t('placeholder.phone')\"\n icon=\"ri:phone-line\"\n class=\"mb-md\"\n modifiers=\"compact\" />\n\n <div class=\"flex justify-between items-center gap-16 mt-xs\">\n <div\n class=\"text-smaller text-word-3 flex items-center gap-8\">\n <VvIcon\n name=\"ri:shield-check-line\"\n class=\"text-16 shrink-0\" />\n <PkStreamingMarkdown\n :markdown=\"privacyNotice\"\n class=\"wysiwyg\" />\n </div>\n <!-- The library's default button is the brand, and in\n the chat the brand is the agent's color, as on the\n rest of the card: `primary` drew it neutral dark -->\n <VvButton\n type=\"submit\"\n :loading\n :disabled=\"loading || readonly\"\n icon-position=\"right\"\n class=\"shrink-0\"\n :label=\"$t('action.submit')\" />\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.leadSubmittedTitle') }}\n </strong>\n <p class=\"text-word-3\">\n {{ $t('message.leadSubmittedMessage') }}\n </p>\n </div>\n </div>\n </div>\n </Transition>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed, watch } from 'vue'\n import { useI18n } from 'vue-i18n'\n import { useForm } from '@volverjs/form-vue'\n import * as z from 'zod'\n import { useSafeLocalStorage, useLocalizedString } from 'composables'\n import type { LocalizedString } from 'models'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n\n const { t: $t } = useI18n({ useScope: 'global' })\n\n const props = defineProps<{\n part: unknown\n submitted?: boolean\n loading?: boolean\n error?: string\n readonly?: boolean\n privacyPolicyNotice?: LocalizedString\n }>()\n\n const toolPart = computed(() => {\n const part = props.part as {\n type: string\n toolCallId: string\n input?: {\n name: string\n email: string\n phone?: string\n conversationContext?: Record<string, unknown>\n }\n }\n return part\n })\n\n const input = computed(() => toolPart.value.input)\n\n const localSubmitted = useSafeLocalStorage<boolean>(\n computed(\n () =>\n `${toolPart.value.toolCallId}-${toolPart.value.type}-submitted`,\n ),\n false,\n )\n\n const LeadFormSchema = z.object({\n name: z.string().min(1).max(255).default(''),\n email: z.email().max(255).default(''),\n phone: z\n .string()\n .max(50)\n .regex(/^[+0-9\\s\\-.()]*$/, $t('validation.invalidPhoneNumber'))\n .optional(),\n })\n\n const emit = defineEmits<{\n submit: [data: Record<string, unknown>]\n }>()\n\n const { VvForm, VvFormField, formData } = useForm(LeadFormSchema, {\n lazyLoad: true,\n })\n\n // Pre-populate form with input values\n watch(\n input,\n (newInput) => {\n formData.value = {\n name: newInput?.name || '',\n email: newInput?.email || '',\n phone: newInput?.phone || '',\n }\n },\n { immediate: true },\n )\n\n watch(\n () => props.submitted,\n (submitted) => {\n if (submitted) {\n localSubmitted.value = true\n }\n },\n { immediate: true },\n )\n\n const isSubmitted = computed(() => {\n return props.submitted || localSubmitted.value\n })\n\n const submitLead = async (data: Record<string, unknown>): Promise<void> => {\n emit('submit', { ...data, metadata: input.value?.conversationContext })\n }\n\n const privacyNotice = useLocalizedString(\n () => props.privacyPolicyNotice,\n 'message.defaultPrivacyPolicyNotice',\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:send-plane-2-line\" class=\"text-16\" />\n <strong class=\"font-bold\">{{ $t('label.contactUs') }}</strong>\n </div>\n\n <Transition mode=\"out-in\">\n <div v-if=\"!isSubmitted\" class=\"p-sm\">\n <VvForm v-model=\"formData\" :readonly @submit=\"submitLead\">\n <VvFormField\n name=\"name\"\n type=\"text\"\n :label=\"$t('label.name')\"\n :placeholder=\"$t('placeholder.name')\"\n icon=\"ri:user-line\"\n modifiers=\"compact\"\n class=\"mb-md\" />\n <VvFormField\n name=\"email\"\n type=\"email\"\n :label=\"$t('label.email')\"\n :placeholder=\"$t('placeholder.email')\"\n icon=\"ri:mail-line\"\n modifiers=\"compact\"\n class=\"mb-md\" />\n <VvFormField\n name=\"phone\"\n type=\"tel\"\n :label=\"$t('label.phone')\"\n :placeholder=\"$t('placeholder.phone')\"\n icon=\"ri:phone-line\"\n class=\"mb-md\"\n modifiers=\"compact\" />\n\n <div class=\"flex justify-between items-center gap-16 mt-xs\">\n <div\n class=\"text-smaller text-word-3 flex items-center gap-8\">\n <VvIcon\n name=\"ri:shield-check-line\"\n class=\"text-16 shrink-0\" />\n <PkStreamingMarkdown\n :markdown=\"privacyNotice\"\n class=\"wysiwyg\" />\n </div>\n <!-- The library's default button is the brand, and in\n the chat the brand is the agent's color, as on the\n rest of the card: `primary` drew it neutral dark -->\n <VvButton\n type=\"submit\"\n :loading\n :disabled=\"loading || readonly\"\n icon-position=\"right\"\n class=\"shrink-0\"\n :label=\"$t('action.submit')\" />\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.leadSubmittedTitle') }}\n </strong>\n <p class=\"text-word-3\">\n {{ $t('message.leadSubmittedMessage') }}\n </p>\n </div>\n </div>\n </div>\n </Transition>\n </div>\n</template>\n"],"mappings":"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"}
@@ -1,7 +1,8 @@
1
- import { a as e } from "./PkChatbotMessages-CnI3e9wF.js";
2
- import "./src-DCfvejyT.js";
3
- import { t } from "./PkSvgViewer-Ts3gQ1hB.js";
4
- import { VvButton as n, VvButtonGroup as r, VvIcon as i } from "@volverjs/ui-vue/components";
1
+ import { t as e } from "./VvButtonLocalized-BuzLsXp3.js";
2
+ import "./src-DpkuiHam.js";
3
+ import { P as t } from "./utils-DsnEcdW3.js";
4
+ import { t as n } from "./PkSvgViewer-D6DJ2jVO.js";
5
+ import { VvButtonGroup as r, VvIcon as i } from "@volverjs/ui-vue/components";
5
6
  import { computed as a, createBlock as o, createCommentVNode as s, createElementBlock as c, createElementVNode as l, createVNode as u, defineComponent as d, onMounted as f, openBlock as p, ref as m, toDisplayString as h, unref as g, watch as _, withCtx as v } from "vue";
6
7
  import { useI18n as y } from "vue-i18n";
7
8
  import { useClipboard as b } from "@vueuse/core";
@@ -68,14 +69,14 @@ var x = {
68
69
  });
69
70
  let V = () => {
70
71
  if (!I.value) return;
71
- let t = new Blob([I.value], { type: "image/svg+xml;charset=utf-8" }), n = URL.createObjectURL(t), r = document.createElement("a");
72
- r.href = n, r.download = `${e(P.value.input?.title || "diagram")}.svg`, document.body.appendChild(r), r.click(), document.body.removeChild(r), URL.revokeObjectURL(n);
72
+ let e = new Blob([I.value], { type: "image/svg+xml;charset=utf-8" }), n = URL.createObjectURL(e), r = document.createElement("a");
73
+ r.href = n, r.download = `${t(P.value.input?.title || "diagram")}.svg`, document.body.appendChild(r), r.click(), document.body.removeChild(r), URL.revokeObjectURL(n);
73
74
  }, H = () => {
74
75
  let e = P.value.input?.code;
75
76
  e && M(e);
76
77
  };
77
- return (e, a) => {
78
- let d = i, f = n, m = r;
78
+ return (t, a) => {
79
+ let d = i, f = e, m = r;
79
80
  return P.value?.input?.code ? (p(), c("div", x, [
80
81
  l("div", S, [
81
82
  u(d, {
@@ -102,7 +103,7 @@ var x = {
102
103
  _: 1
103
104
  })
104
105
  ]),
105
- F.value ? (p(), c("div", T, h(g(A)("message.diagramRenderError")), 1)) : I.value ? (p(), o(t, {
106
+ F.value ? (p(), c("div", T, h(g(A)("message.diagramRenderError")), 1)) : I.value ? (p(), o(n, {
106
107
  key: 1,
107
108
  class: "pk-tool-show-diagram__stage",
108
109
  svg: I.value,
@@ -119,4 +120,4 @@ var x = {
119
120
  //#endregion
120
121
  export { k as default };
121
122
 
122
- //# sourceMappingURL=PkToolShowDiagram-7WxDObZ6.js.map
123
+ //# sourceMappingURL=PkToolShowDiagram-CaoB4k6y.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PkToolShowDiagram-CaoB4k6y.js","names":["__unplugin_components_0","__unplugin_components_1","__unplugin_components_2","_openBlock","_createElementBlock","_createElementVNode","_createVNode","_toDisplayString","_unref","_withCtx","_createBlock","_createCommentVNode","PkSvgViewer","_sfc_main","VvButtonLocalized","toSnakeCase","PkSvgViewer_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","DiagramType","\"Sequence\"","\"Class\"","\"State\"","\"ER\"","\"XYChart\"","\"Flowchart\"","\"Graph\"","PkToolShowDiagram_default","defineComponent","props","__props","$t","$te","useI18n","useClipboard","toolPart","computed","svgError","ref","svgContent","diagramType","code","diagramTypeLabel","diagramTypeIcon","renderDiagram","theme","THEMES","renderMermaidSVG","watch","onMounted","downloadSvg","blob","url","anchor","copyCode","copy","_component_VvIcon","VvIcon","_component_VvButton","_component_VvButtonGroup","VvButtonGroup","openBlock","createElementBlock","createElementVNode","createVNode","toDisplayString","unref","withCtx","copied","createBlock","createCommentVNode"],"sources":["../../../../packages/components/src/chat/PkToolShowDiagram.vue","../../../../packages/components/src/chat/PkToolShowDiagram.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, onMounted, ref, watch } from 'vue'\n import { useClipboard } from '@vueuse/core'\n import { useI18n } from 'vue-i18n'\n import { toSnakeCase } from 'utils'\n import PkSvgViewer from '../PkSvgViewer.vue'\n\n const props = defineProps<{\n part: unknown\n isDark?: boolean\n }>()\n\n const { t: $t, te: $te } = useI18n({\n useScope: 'global',\n })\n\n const { copy, copied } = useClipboard()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n code: string\n title?: string\n caption?: string\n }\n }\n return part\n })\n\n const svgError = ref(false)\n\n // Serialized SVG content\n const svgContent = ref('')\n\n enum DiagramType {\n Sequence = 'sequenceDiagram',\n Class = 'classDiagram',\n State = 'stateDiagram',\n ER = 'erDiagram',\n XYChart = 'xychart',\n Flowchart = 'flowchart',\n Graph = 'graph',\n }\n\n const diagramType = computed<DiagramType | undefined>(() => {\n const code = toolPart.value.input?.code?.trimStart()\n if (!code) {\n return undefined\n }\n const firstWord = code.match(/^[A-Za-z-]+/)?.[0]\n switch (firstWord) {\n case 'sequenceDiagram':\n return DiagramType.Sequence\n case 'classDiagram':\n return DiagramType.Class\n case 'stateDiagram':\n return DiagramType.State\n case 'erDiagram':\n return DiagramType.ER\n case 'xychart-beta':\n return DiagramType.XYChart\n case 'flowchart':\n return DiagramType.Flowchart\n case 'graph':\n return DiagramType.Graph\n default:\n return undefined\n }\n })\n\n const diagramTypeLabel = computed(() => {\n if (!diagramType.value) {\n return ''\n }\n return $te(`diagram.${diagramType.value}`)\n ? $t(`diagram.${diagramType.value}`)\n : diagramType.value\n })\n\n const diagramTypeIcon = computed(() => {\n switch (diagramType.value) {\n case DiagramType.Sequence:\n return 'ri:timeline-view'\n case DiagramType.Class:\n return 'ri:organization-chart'\n case DiagramType.State:\n return 'ri:organization-chart'\n case DiagramType.ER:\n return 'ri:organization-chart'\n case DiagramType.XYChart:\n return 'ri:line-chart-line'\n case DiagramType.Flowchart:\n return 'ri:flow-chart'\n case DiagramType.Graph:\n return 'ri:flow-chart'\n default:\n return 'ri:flow-chart'\n }\n })\n\n async function renderDiagram() {\n const code = toolPart.value.input?.code\n if (!code) {\n return\n }\n\n svgError.value = false\n try {\n const { renderMermaidSVG, THEMES } =\n await import('beautiful-mermaid')\n const theme = props.isDark\n ? THEMES['github-dark']\n : THEMES['github-light']\n svgContent.value = renderMermaidSVG(code, theme)\n } catch {\n svgError.value = true\n }\n }\n\n watch([() => toolPart.value.input?.code, () => props.isDark], renderDiagram)\n onMounted(async () => {\n await renderDiagram()\n })\n\n const downloadSvg = () => {\n if (!svgContent.value) {\n return\n }\n const blob = new Blob([svgContent.value], {\n type: 'image/svg+xml;charset=utf-8',\n })\n const url = URL.createObjectURL(blob)\n const anchor = document.createElement('a')\n anchor.href = url\n anchor.download = `${toSnakeCase(toolPart.value.input?.title || 'diagram')}.svg`\n document.body.appendChild(anchor)\n anchor.click()\n document.body.removeChild(anchor)\n URL.revokeObjectURL(url)\n }\n\n const copyCode = () => {\n const code = toolPart.value.input?.code\n if (code) {\n copy(code)\n }\n }\n</script>\n\n<template>\n <div\n v-if=\"toolPart?.input?.code\"\n class=\"border border-surface-3 rounded-xl w-full overflow-hidden\">\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\">\n <VvIcon :name=\"diagramTypeIcon\" class=\"text-16\" />\n <div class=\"flex flex-col items-start gap-2\">\n <strong class=\"font-bold\">{{\n diagramTypeLabel ?? $t('label.diagram')\n }}</strong>\n </div>\n <VvButtonGroup modifiers=\"compact\" class=\"ml-auto shrink-0\">\n <VvButton\n modifiers=\"action-quiet-small\"\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n @click=\"copyCode\" />\n <VvButton\n v-if=\"svgContent\"\n modifiers=\"action-quiet-small\"\n icon=\"ri:download-line\"\n :label=\"$t('action.download')\"\n @click=\"downloadSvg\" />\n </VvButtonGroup>\n </div>\n <div v-if=\"svgError\" class=\"text-12 text-danger py-8 px-sm\">\n {{ $t('message.diagramRenderError') }}\n </div>\n <PkSvgViewer\n v-else-if=\"svgContent\"\n class=\"pk-tool-show-diagram__stage\"\n :svg=\"svgContent\"\n :title=\"toolPart.input?.title\" />\n <div\n v-else\n class=\"pk-tool-show-diagram__stage flex justify-center items-center\">\n <VvIcon name=\"loading-loop\" class=\"w-24 h-24 text-word-5\" />\n </div>\n <div\n v-if=\"toolPart.input.caption\"\n class=\"px-sm py-6 bg-surface-1 min-h-40 text-12 border-t border-surface-3 text-word-3\">\n {{ toolPart.input.caption }}\n </div>\n </div>\n</template>\n\n<style lang=\"scss\">\n .pk-tool-show-diagram {\n // Fixed stage height: the diagram renders lazily (async chunk +\n // dynamic mermaid import), so the loader and the rendered SVG must\n // occupy the same space or the chat scroll position jumps around.\n // The SVG scales to fit; zoom/pan and the lightbox cover the rest.\n &__stage {\n height: 384px;\n\n .pk-svg-viewer__stage,\n .pk-svg-viewer__content {\n height: 100%;\n }\n }\n }\n</style>\n","<script setup lang=\"ts\">\n import { computed, onMounted, ref, watch } from 'vue'\n import { useClipboard } from '@vueuse/core'\n import { useI18n } from 'vue-i18n'\n import { toSnakeCase } from 'utils'\n import PkSvgViewer from '../PkSvgViewer.vue'\n\n const props = defineProps<{\n part: unknown\n isDark?: boolean\n }>()\n\n const { t: $t, te: $te } = useI18n({\n useScope: 'global',\n })\n\n const { copy, copied } = useClipboard()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n code: string\n title?: string\n caption?: string\n }\n }\n return part\n })\n\n const svgError = ref(false)\n\n // Serialized SVG content\n const svgContent = ref('')\n\n enum DiagramType {\n Sequence = 'sequenceDiagram',\n Class = 'classDiagram',\n State = 'stateDiagram',\n ER = 'erDiagram',\n XYChart = 'xychart',\n Flowchart = 'flowchart',\n Graph = 'graph',\n }\n\n const diagramType = computed<DiagramType | undefined>(() => {\n const code = toolPart.value.input?.code?.trimStart()\n if (!code) {\n return undefined\n }\n const firstWord = code.match(/^[A-Za-z-]+/)?.[0]\n switch (firstWord) {\n case 'sequenceDiagram':\n return DiagramType.Sequence\n case 'classDiagram':\n return DiagramType.Class\n case 'stateDiagram':\n return DiagramType.State\n case 'erDiagram':\n return DiagramType.ER\n case 'xychart-beta':\n return DiagramType.XYChart\n case 'flowchart':\n return DiagramType.Flowchart\n case 'graph':\n return DiagramType.Graph\n default:\n return undefined\n }\n })\n\n const diagramTypeLabel = computed(() => {\n if (!diagramType.value) {\n return ''\n }\n return $te(`diagram.${diagramType.value}`)\n ? $t(`diagram.${diagramType.value}`)\n : diagramType.value\n })\n\n const diagramTypeIcon = computed(() => {\n switch (diagramType.value) {\n case DiagramType.Sequence:\n return 'ri:timeline-view'\n case DiagramType.Class:\n return 'ri:organization-chart'\n case DiagramType.State:\n return 'ri:organization-chart'\n case DiagramType.ER:\n return 'ri:organization-chart'\n case DiagramType.XYChart:\n return 'ri:line-chart-line'\n case DiagramType.Flowchart:\n return 'ri:flow-chart'\n case DiagramType.Graph:\n return 'ri:flow-chart'\n default:\n return 'ri:flow-chart'\n }\n })\n\n async function renderDiagram() {\n const code = toolPart.value.input?.code\n if (!code) {\n return\n }\n\n svgError.value = false\n try {\n const { renderMermaidSVG, THEMES } =\n await import('beautiful-mermaid')\n const theme = props.isDark\n ? THEMES['github-dark']\n : THEMES['github-light']\n svgContent.value = renderMermaidSVG(code, theme)\n } catch {\n svgError.value = true\n }\n }\n\n watch([() => toolPart.value.input?.code, () => props.isDark], renderDiagram)\n onMounted(async () => {\n await renderDiagram()\n })\n\n const downloadSvg = () => {\n if (!svgContent.value) {\n return\n }\n const blob = new Blob([svgContent.value], {\n type: 'image/svg+xml;charset=utf-8',\n })\n const url = URL.createObjectURL(blob)\n const anchor = document.createElement('a')\n anchor.href = url\n anchor.download = `${toSnakeCase(toolPart.value.input?.title || 'diagram')}.svg`\n document.body.appendChild(anchor)\n anchor.click()\n document.body.removeChild(anchor)\n URL.revokeObjectURL(url)\n }\n\n const copyCode = () => {\n const code = toolPart.value.input?.code\n if (code) {\n copy(code)\n }\n }\n</script>\n\n<template>\n <div\n v-if=\"toolPart?.input?.code\"\n class=\"border border-surface-3 rounded-xl w-full overflow-hidden\">\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\">\n <VvIcon :name=\"diagramTypeIcon\" class=\"text-16\" />\n <div class=\"flex flex-col items-start gap-2\">\n <strong class=\"font-bold\">{{\n diagramTypeLabel ?? $t('label.diagram')\n }}</strong>\n </div>\n <VvButtonGroup modifiers=\"compact\" class=\"ml-auto shrink-0\">\n <VvButton\n modifiers=\"action-quiet-small\"\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n @click=\"copyCode\" />\n <VvButton\n v-if=\"svgContent\"\n modifiers=\"action-quiet-small\"\n icon=\"ri:download-line\"\n :label=\"$t('action.download')\"\n @click=\"downloadSvg\" />\n </VvButtonGroup>\n </div>\n <div v-if=\"svgError\" class=\"text-12 text-danger py-8 px-sm\">\n {{ $t('message.diagramRenderError') }}\n </div>\n <PkSvgViewer\n v-else-if=\"svgContent\"\n class=\"pk-tool-show-diagram__stage\"\n :svg=\"svgContent\"\n :title=\"toolPart.input?.title\" />\n <div\n v-else\n class=\"pk-tool-show-diagram__stage flex justify-center items-center\">\n <VvIcon name=\"loading-loop\" class=\"w-24 h-24 text-word-5\" />\n </div>\n <div\n v-if=\"toolPart.input.caption\"\n class=\"px-sm py-6 bg-surface-1 min-h-40 text-12 border-t border-surface-3 text-word-3\">\n {{ toolPart.input.caption }}\n </div>\n </div>\n</template>\n\n<style lang=\"scss\">\n .pk-tool-show-diagram {\n // Fixed stage height: the diagram renders lazily (async chunk +\n // dynamic mermaid import), so the loader and the rendered SVG must\n // occupy the same space or the chat scroll position jumps around.\n // The SVG scales to fit; zoom/pan and the lightbox cover the rest.\n &__stage {\n height: 384px;\n\n .pk-svg-viewer__stage,\n .pk-svg-viewer__content {\n height: 100%;\n }\n }\n }\n</style>\n"],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import { t as e } from "./rolldown-runtime-Dy4uBu1J.js";
2
- import { n as t } from "./useShortUrlResolver-DI8ycJiO.js";
3
- import { VvButton as n, VvButtonGroup as r, VvDropdown as i, VvDropdownAction as a, VvIcon as o } from "@volverjs/ui-vue/components";
2
+ import { t } from "./VvButtonLocalized-BuzLsXp3.js";
3
+ import { n } from "./useShortUrlResolver-DI8ycJiO.js";
4
+ import { VvButtonGroup as r, VvDropdown as i, VvDropdownAction as a, VvIcon as o } from "@volverjs/ui-vue/components";
4
5
  import { computed as s, createElementBlock as c, createElementVNode as l, createTextVNode as u, createVNode as d, defineComponent as f, guardReactiveProps as p, normalizeProps as m, openBlock as h, toDisplayString as g, unref as _, withCtx as v } from "vue";
5
6
  import { useClipboard as y } from "@vueuse/core";
6
7
  //#region ../../packages/components/src/chat/PkToolShowEmail.vue?vue&type=script&setup=true&lang.ts
@@ -8,7 +9,7 @@ var b = { class: "border border-surface-3 rounded-xl w-full overflow-hidden bg-s
8
9
  __name: "PkToolShowEmail",
9
10
  props: { part: {} },
10
11
  setup(e) {
11
- let f = e, { copy: k, copied: A } = y(), j = s(() => f.part), { resolveText: M } = t(), N = M(() => j.value.input?.subject), P = M(() => j.value.input?.body), F = () => {
12
+ let f = e, { copy: k, copied: A } = y(), j = s(() => f.part), { resolveText: M } = n(), N = M(() => j.value.input?.subject), P = M(() => j.value.input?.body), F = () => {
12
13
  if (!j.value.input) return;
13
14
  let e = `mailto:?subject=${encodeURIComponent(N.value)}&body=${encodeURIComponent(P.value)}`;
14
15
  window.open(e);
@@ -25,8 +26,8 @@ var b = { class: "border border-surface-3 rounded-xl w-full overflow-hidden bg-s
25
26
  let e = `https://compose.mail.yahoo.com/?to=&subject=${encodeURIComponent(N.value)}&body=${encodeURIComponent(P.value)}`;
26
27
  window.open(e, "_blank");
27
28
  };
28
- return (e, t) => {
29
- let s = o, f = n, y = a, j = i, M = r;
29
+ return (e, n) => {
30
+ let s = o, f = t, y = a, j = i, M = r;
30
31
  return h(), c("div", b, [
31
32
  l("div", x, [
32
33
  d(s, {
@@ -42,7 +43,7 @@ var b = { class: "border border-surface-3 rounded-xl w-full overflow-hidden bg-s
42
43
  modifiers: "action-quiet-small",
43
44
  icon: _(A) ? "ri:check-line" : "ri:file-copy-line",
44
45
  label: _(A) ? e.$t("action.copied") : e.$t("action.copy"),
45
- onClick: t[0] ||= (e) => _(k)(`${_(N)}\n\n${_(P)}`)
46
+ onClick: n[0] ||= (e) => _(k)(`${_(N)}\n\n${_(P)}`)
46
47
  }, null, 8, ["icon", "label"]), d(j, m(p({
47
48
  placement: "bottom-end",
48
49
  modifiers: "menu",
@@ -87,4 +88,4 @@ var b = { class: "border border-surface-3 rounded-xl w-full overflow-hidden bg-s
87
88
  //#endregion
88
89
  export { A as n, j as t };
89
90
 
90
- //# sourceMappingURL=PkToolShowEmail-C591LR5N.js.map
91
+ //# sourceMappingURL=PkToolShowEmail-CUgZN0J5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PkToolShowEmail-CUgZN0J5.js","names":["$t","__unplugin_components_0","__unplugin_components_1","__unplugin_components_2","__unplugin_components_3","__unplugin_components_4","_openBlock","_createElementBlock","_createElementVNode","_createVNode","_toDisplayString","_withCtx","_unref","_normalizeProps","_guardReactiveProps","_createTextVNode","_sfc_main","__exportAll","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","PkToolShowEmail_vue_vue_type_script_setup_true_lang_default","props","__props","useClipboard","toolPart","computed","useShortUrlResolver","subject","resolveText","body","openInMailApp","mailtoLink","openInOutlook","url","openInGmail","openInYahooMail","_component_VvIcon","VvIcon","_component_VvButton","VvButtonLocalized","_component_VvDropdownAction","VvDropdownAction","_component_VvDropdown","VvDropdown","_component_VvButtonGroup","VvButtonGroup","openBlock","createElementBlock","createElementVNode","createVNode","toDisplayString","_ctx","withCtx","unref","copied","_cache","copy","normalizeProps","guardReactiveProps","createTextVNode","PkToolShowEmail_exports","PkToolShowEmail_default"],"sources":["../../../../packages/components/src/chat/PkToolShowEmail.vue","../../../../packages/components/src/chat/PkToolShowEmail.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useClipboard } from '@vueuse/core'\n import { useShortUrlResolver } from 'composables'\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const { copy, copied } = useClipboard()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n subject: string\n body: string\n }\n }\n return part\n })\n\n // Emails leave the app (mailto/webmail/clipboard), so expand short urls to\n // their real target rather than keeping the fragile `/api/r/` redirect.\n const { resolveText } = useShortUrlResolver()\n const subject = resolveText(() => toolPart.value.input?.subject)\n const body = resolveText(() => toolPart.value.input?.body)\n\n const openInMailApp = () => {\n if (!toolPart.value.input) {\n return\n }\n const mailtoLink = `mailto:?subject=${encodeURIComponent(\n subject.value,\n )}&body=${encodeURIComponent(body.value)}`\n window.open(mailtoLink)\n }\n\n const openInOutlook = () => {\n if (!toolPart.value.input) {\n return\n }\n const url = `https://outlook.office.com/mail/deeplink/compose?to=&subject=${encodeURIComponent(\n subject.value,\n )}&body=${encodeURIComponent(body.value)}`\n window.open(url, '_blank')\n }\n\n const openInGmail = () => {\n if (!toolPart.value.input) {\n return\n }\n const url = `https://mail.google.com/mail/u/0/?tf=cm&to=&su=${encodeURIComponent(\n subject.value,\n )}&body=${encodeURIComponent(body.value)}`\n window.open(url, '_blank')\n }\n\n const openInYahooMail = () => {\n if (!toolPart.value.input) {\n return\n }\n const url = `https://compose.mail.yahoo.com/?to=&subject=${encodeURIComponent(\n subject.value,\n )}&body=${encodeURIComponent(body.value)}`\n window.open(url, '_blank')\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\">\n <VvIcon name=\"ri:mail-line\" class=\"text-16\" />\n <strong class=\"font-bold\">\n {{ $t('label.email') }}\n </strong>\n <VvButtonGroup modifiers=\"compact\" class=\"ml-auto shrink-0\">\n <VvButton\n modifiers=\"action-quiet-small\"\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n @click=\"copy(`${subject}\\n\\n${body}`)\" />\n <VvDropdown\n v-bind=\"{\n placement: 'bottom-end',\n modifiers: 'menu',\n flip: true,\n offset: 3,\n strategy: 'fixed',\n }\">\n <VvButton\n icon=\"ri:mail-send-line\"\n modifiers=\"action-quiet-small\"\n :label=\"$t('action.send')\" />\n <template #items>\n <VvDropdownAction @click=\"openInOutlook\">\n <VvIcon name=\"mdi:outlook\" />\n {{ $t('action.openInOutlook') }}\n </VvDropdownAction>\n <VvDropdownAction @click=\"openInGmail\">\n <VvIcon name=\"mdi:gmail\" />\n {{ $t('action.openInGmail') }}\n </VvDropdownAction>\n <VvDropdownAction @click=\"openInYahooMail\">\n <VvIcon name=\"mdi:yahoo\" />\n {{ $t('action.openInYahooMail') }}\n </VvDropdownAction>\n <VvDropdownAction @click=\"openInMailApp\">\n <VvIcon name=\"ri:mail-open-line\" />\n {{ $t('action.openInMailApp') }}\n </VvDropdownAction>\n </template>\n </VvDropdown>\n </VvButtonGroup>\n </div>\n <div class=\"border-b border-surface-3 p-sm\">\n <div class=\"text-12 text-word-4 mb-4\">\n {{ $t('label.subject') }}\n </div>\n <div class=\"text-word-2 font-semibold\">\n {{ subject }}\n </div>\n </div>\n <div class=\"p-sm\">\n <div class=\"text-12 text-word-4 mb-4\">\n {{ $t('label.body') }}\n </div>\n <pre class=\"text-word-2 whitespace-pre-wrap break-words\">{{\n body\n }}</pre>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useClipboard } from '@vueuse/core'\n import { useShortUrlResolver } from 'composables'\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const { copy, copied } = useClipboard()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n subject: string\n body: string\n }\n }\n return part\n })\n\n // Emails leave the app (mailto/webmail/clipboard), so expand short urls to\n // their real target rather than keeping the fragile `/api/r/` redirect.\n const { resolveText } = useShortUrlResolver()\n const subject = resolveText(() => toolPart.value.input?.subject)\n const body = resolveText(() => toolPart.value.input?.body)\n\n const openInMailApp = () => {\n if (!toolPart.value.input) {\n return\n }\n const mailtoLink = `mailto:?subject=${encodeURIComponent(\n subject.value,\n )}&body=${encodeURIComponent(body.value)}`\n window.open(mailtoLink)\n }\n\n const openInOutlook = () => {\n if (!toolPart.value.input) {\n return\n }\n const url = `https://outlook.office.com/mail/deeplink/compose?to=&subject=${encodeURIComponent(\n subject.value,\n )}&body=${encodeURIComponent(body.value)}`\n window.open(url, '_blank')\n }\n\n const openInGmail = () => {\n if (!toolPart.value.input) {\n return\n }\n const url = `https://mail.google.com/mail/u/0/?tf=cm&to=&su=${encodeURIComponent(\n subject.value,\n )}&body=${encodeURIComponent(body.value)}`\n window.open(url, '_blank')\n }\n\n const openInYahooMail = () => {\n if (!toolPart.value.input) {\n return\n }\n const url = `https://compose.mail.yahoo.com/?to=&subject=${encodeURIComponent(\n subject.value,\n )}&body=${encodeURIComponent(body.value)}`\n window.open(url, '_blank')\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\">\n <VvIcon name=\"ri:mail-line\" class=\"text-16\" />\n <strong class=\"font-bold\">\n {{ $t('label.email') }}\n </strong>\n <VvButtonGroup modifiers=\"compact\" class=\"ml-auto shrink-0\">\n <VvButton\n modifiers=\"action-quiet-small\"\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n @click=\"copy(`${subject}\\n\\n${body}`)\" />\n <VvDropdown\n v-bind=\"{\n placement: 'bottom-end',\n modifiers: 'menu',\n flip: true,\n offset: 3,\n strategy: 'fixed',\n }\">\n <VvButton\n icon=\"ri:mail-send-line\"\n modifiers=\"action-quiet-small\"\n :label=\"$t('action.send')\" />\n <template #items>\n <VvDropdownAction @click=\"openInOutlook\">\n <VvIcon name=\"mdi:outlook\" />\n {{ $t('action.openInOutlook') }}\n </VvDropdownAction>\n <VvDropdownAction @click=\"openInGmail\">\n <VvIcon name=\"mdi:gmail\" />\n {{ $t('action.openInGmail') }}\n </VvDropdownAction>\n <VvDropdownAction @click=\"openInYahooMail\">\n <VvIcon name=\"mdi:yahoo\" />\n {{ $t('action.openInYahooMail') }}\n </VvDropdownAction>\n <VvDropdownAction @click=\"openInMailApp\">\n <VvIcon name=\"ri:mail-open-line\" />\n {{ $t('action.openInMailApp') }}\n </VvDropdownAction>\n </template>\n </VvDropdown>\n </VvButtonGroup>\n </div>\n <div class=\"border-b border-surface-3 p-sm\">\n <div class=\"text-12 text-word-4 mb-4\">\n {{ $t('label.subject') }}\n </div>\n <div class=\"text-word-2 font-semibold\">\n {{ subject }}\n </div>\n </div>\n <div class=\"p-sm\">\n <div class=\"text-12 text-word-4 mb-4\">\n {{ $t('label.body') }}\n </div>\n <pre class=\"text-word-2 whitespace-pre-wrap break-words\">{{\n body\n }}</pre>\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;EAKI,IAAM4B,IAAQC,GAIR,EAAE,SAAM,cAAWC,EAAa,GAEhCC,IAAWC,QACAJ,EAAM,IAOtB,GAIK,EAAE,mBAAgBK,EAAoB,GACtCC,IAAUC,QAAkBJ,EAAS,MAAM,OAAO,OAAO,GACzDK,IAAOD,QAAkBJ,EAAS,MAAM,OAAO,IAAI,GAEnDM,UAAsB;GACxB,IAAI,CAACN,EAAS,MAAM,OAChB;GAEJ,IAAMO,IAAa,mBAAmB,mBAClCJ,EAAQ,KACZ,EAAE,QAAQ,mBAAmBE,EAAK,KAAK;GACvC,OAAO,KAAKE,CAAU;EAC1B,GAEMC,UAAsB;GACxB,IAAI,CAACR,EAAS,MAAM,OAChB;GAEJ,IAAMS,IAAM,gEAAgE,mBACxEN,EAAQ,KACZ,EAAE,QAAQ,mBAAmBE,EAAK,KAAK;GACvC,OAAO,KAAKI,GAAK,QAAQ;EAC7B,GAEMC,UAAoB;GACtB,IAAI,CAACV,EAAS,MAAM,OAChB;GAEJ,IAAMS,IAAM,kDAAkD,mBAC1DN,EAAQ,KACZ,EAAE,QAAQ,mBAAmBE,EAAK,KAAK;GACvC,OAAO,KAAKI,GAAK,QAAQ;EAC7B,GAEME,UAAwB;GAC1B,IAAI,CAACX,EAAS,MAAM,OAChB;GAEJ,IAAMS,IAAM,+CAA+C,mBACvDN,EAAQ,KACZ,EAAE,QAAQ,mBAAmBE,EAAK,KAAK;GACvC,OAAO,KAAKI,GAAK,QAAQ;EAC7B;;;GAIA,OAAAlC,EAAA,GAAAC,EA+DM,OA/DNW,GA+DM;IA7DFV,EA4CM,OA5CNW,GA4CM;KA1CFV,EAA8CkC,GAAA;MAAtC,MAAK;MAAe,OAAM;;KAClCnC,EAES,UAFTY,GAESV,EADFV,EAAAA,GAAE,aAAA,CAAA,GAAA,CAAA;KAETS,EAqCgB0C,GAAA;MArCD,WAAU;MAAU,OAAM;;MACrC,SAAAxC,QAI6C,CAJ7CF,EAI6CoC,GAAA;OAHzC,WAAU;OACT,MAAMjC,EAAAiD,CAAA,IAAM,kBAAA;OACZ,OAAOjD,EAAAiD,CAAA,IAAS7D,EAAAA,GAAE,eAAA,IAAoBA,EAAAA,GAAE,aAAA;OACxC,SAAK,AAAA8D,EAAA,QAAA,MAAElD,EAAAmD,CAAA,CAAI,CAAA,GAAInD,EAAAsB,CAAA,EAAO,MAAOtB,EAAAwB,CAAA,GAAI;MACtC3B,GAAAA,MAAAA,GAAAA,CAAAA,QAAAA,OAAAA,CAAAA,GAAAA,EA8BawC,GAAApC,EAAAC,EA7BD;;;;;;MAMP,CAAA,CAAA,GAAA;OAKU,OAAKH,QAIO;QAHnBF,EAGmBsC,GAAA,EAHA,SAAOR,EAAa,GAAA;SACnC,SAAA5B,QAA6B,CAA7BF,EAA6BkC,GAAA,EAArB,MAAK,cAAa,CAAA,GAAG5B,EAAA,MAC7BL,EAAGV,EAAAA,GAAE,sBAAA,CAAA,GAAA,CAAA,CAAA,CAAA;;;QAETS,EAGmBsC,GAAA,EAHA,SAAON,EAAW,GAAA;SACjC,SAAA9B,QAA2B,CAA3BF,EAA2BkC,GAAA,EAAnB,MAAK,YAAW,CAAA,GAAG5B,EAAA,MAC3BL,EAAGV,EAAAA,GAAE,oBAAA,CAAA,GAAA,CAAA,CAAA,CAAA;;;QAETS,EAGmBsC,GAAA,EAHA,SAAOL,EAAe,GAAA;SACrC,SAAA/B,QAA2B,CAA3BF,EAA2BkC,GAAA,EAAnB,MAAK,YAAW,CAAA,GAAG5B,EAAA,MAC3BL,EAAGV,EAAAA,GAAE,wBAAA,CAAA,GAAA,CAAA,CAAA,CAAA;;;QAETS,EAGmBsC,GAAA,EAHA,SAAOV,EAAa,GAAA;SACnC,SAAA1B,QAAmC,CAAnCF,EAAmCkC,GAAA,EAA3B,MAAK,oBAAmB,CAAA,GAAG5B,EAAA,MACnCL,EAAGV,EAAAA,GAAE,sBAAA,CAAA,GAAA,CAAA,CAAA,CAAA;;;;OAnBb,SAAAW,QAGiC,CAHjCF,EAGiCoC,GAAA;QAF7B,MAAK;QACL,WAAU;QACT,OAAO7C,EAAAA,GAAE,aAAA;;;;;;;IAsB1BQ,EAOM,OAPNa,GAOM,CANFb,EAEM,OAFNc,GAEMZ,EADCV,EAAAA,GAAE,eAAA,CAAA,GAAA,CAAA,GAETQ,EAEM,OAFNe,GAEMb,EADCE,EAAAsB,CAAA,CAAO,GAAA,CAAA,CAAA,CAAA;IAGlB1B,EAOM,OAPNgB,GAOM,CANFhB,EAEM,OAFNiB,GAEMf,EADCV,EAAAA,GAAE,YAAA,CAAA,GAAA,CAAA,GAETQ,EAEQ,OAFRkB,GAEQhB,EADJE,EAAAwB,CAAA,CAAI,GAAA,CAAA,CAAA,CAAA"}
@@ -1,8 +1,9 @@
1
1
  import { t as e } from "./rolldown-runtime-Dy4uBu1J.js";
2
- import { j as t } from "./Agent-dGF8mkG9.js";
3
- import { t as n } from "./PkStreamingMarkdown-C55Fi0Pd.js";
4
- import { c as r, l as i } from "./utils-CwIMEuAv.js";
5
- import { VvButton as a, VvCheckbox as o, VvCheckboxGroup as s, VvIcon as ee, VvInputText as te, VvRadio as c, VvRadioGroup as l } from "@volverjs/ui-vue/components";
2
+ import { P as t } from "./Agent-DU1WWaHR.js";
3
+ import { t as n } from "./VvButtonLocalized-BuzLsXp3.js";
4
+ import { t as r } from "./PkStreamingMarkdown-CsHzdW69.js";
5
+ import { c as i, l as a } from "./utils-DsnEcdW3.js";
6
+ import { VvCheckbox as o, VvCheckboxGroup as s, VvIcon as ee, VvInputText as te, VvRadio as c, VvRadioGroup as l } from "@volverjs/ui-vue/components";
6
7
  import { Fragment as u, computed as d, createBlock as f, createCommentVNode as p, createElementBlock as m, createElementVNode as h, createSlots as g, createTextVNode as _, createVNode as v, defineComponent as y, mergeModels as b, mergeProps as x, normalizeClass as ne, normalizeStyle as re, openBlock as S, reactive as ie, ref as C, renderList as w, renderSlot as T, toDisplayString as E, unref as D, useId as O, useModel as k, watch as A, withCtx as j, withKeys as ae, withModifiers as M } from "vue";
7
8
  import { useI18n as oe } from "vue-i18n";
8
9
  //#endregion
@@ -198,7 +199,7 @@ var N = /* @__PURE__ */ y({
198
199
  return Array.isArray(t) ? t : void 0;
199
200
  }
200
201
  A(() => y.value.output, (e) => {
201
- e && !t(e) && Object.assign(G, r(z.value, e));
202
+ e && !t(e) && Object.assign(G, i(z.value, e));
202
203
  }, { immediate: !0 });
203
204
  let Y = d(() => {
204
205
  let e = y.value.output;
@@ -213,7 +214,7 @@ var N = /* @__PURE__ */ y({
213
214
  A(Y, (e) => {
214
215
  e && V.value && ((V.value.options ?? []).map((e) => e.label).includes(e) || (K.value = e));
215
216
  }, { immediate: !0 });
216
- let X = d(() => i(V.value));
217
+ let X = d(() => a(V.value));
217
218
  function Z() {
218
219
  K.value.trim() ? $() : U.value ? B.value++ : Q();
219
220
  }
@@ -243,8 +244,8 @@ var N = /* @__PURE__ */ y({
243
244
  return n == null ? "—" : Array.isArray(n) ? n.join(", ") : e.type === "date" ? _(new Date(n), "short") : n;
244
245
  }
245
246
  return (e, t) => {
246
- let r = ee, i = te, o = a;
247
- return Me.value ? (S(), m("div", se, [v(r, {
247
+ let i = ee, a = te, o = n;
248
+ return Me.value ? (S(), m("div", se, [v(i, {
248
249
  name: "ri:error-warning-line",
249
250
  class: "w-16 h-16 shrink-0"
250
251
  }), h("span", null, E(D(l)("message.formRenderError")), 1)])) : z.value.length ? (S(), m("div", ce, [y.value.input?.title || k.value && z.value.length > 1 ? (S(), m("div", le, [y.value.input?.title ? (S(), m("div", {
@@ -260,7 +261,7 @@ var N = /* @__PURE__ */ y({
260
261
  h("div", pe, [h("div", me, [h("strong", {
261
262
  id: D(b),
262
263
  class: "font-semibold"
263
- }, E(V.value.question), 9, he), V.value.message ? (S(), f(n, {
264
+ }, E(V.value.question), 9, he), V.value.message ? (S(), f(r, {
264
265
  key: 0,
265
266
  markdown: V.value.message,
266
267
  class: "text-word-2 mt-4"
@@ -298,7 +299,7 @@ var N = /* @__PURE__ */ y({
298
299
  "name",
299
300
  "options",
300
301
  "readonly"
301
- ])) : V.value.options ? p("", !0) : (S(), m("div", xe, [(S(), f(i, {
302
+ ])) : V.value.options ? p("", !0) : (S(), m("div", xe, [(S(), f(a, {
302
303
  key: V.value.id,
303
304
  modelValue: q.value,
304
305
  "onUpdate:modelValue": t[2] ||= (e) => q.value = e,
@@ -321,7 +322,7 @@ var N = /* @__PURE__ */ y({
321
322
  V.value.allowFreeformInput && V.value.options ? (S(), m("div", Se, [h("form", {
322
323
  class: "flex gap-xs pt-sm",
323
324
  onSubmit: M($, ["prevent"])
324
- }, [(S(), f(i, {
325
+ }, [(S(), f(a, {
325
326
  key: `${V.value.id}-custom`,
326
327
  modelValue: K.value,
327
328
  "onUpdate:modelValue": t[3] ||= (e) => K.value = e,
@@ -358,7 +359,7 @@ var N = /* @__PURE__ */ y({
358
359
  ], 64)) : (S(), m(u, { key: 2 }, [h("div", Te, [h("ul", Ee, [(S(!0), m(u, null, w(z.value, (e, t) => (S(), m("li", {
359
360
  key: t,
360
361
  class: "leading-normal"
361
- }, [h("div", De, E(e.question), 1), h("span", Oe, E(Le(e, t)), 1)]))), 128))])]), h("div", ke, [v(r, {
362
+ }, [h("div", De, E(e.question), 1), h("span", Oe, E(Le(e, t)), 1)]))), 128))])]), h("div", ke, [v(i, {
362
363
  name: "ri:check-line",
363
364
  class: "text-16 text-success"
364
365
  }), h("div", Ae, [h("span", je, E(D(l)("showForm.completed")), 1)])])], 64))])) : p("", !0);
@@ -368,4 +369,4 @@ var N = /* @__PURE__ */ y({
368
369
  //#endregion
369
370
  export { N as i, L as n, P as r, R as t };
370
371
 
371
- //# sourceMappingURL=PkToolShowForm-CZFWZub7.js.map
372
+ //# sourceMappingURL=PkToolShowForm-vYuaPtu0.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PkToolShowForm-vYuaPtu0.js","names":["_useModel","__unplugin_components_0","__unplugin_components_1","_openBlock","_createBlock","_withCtx","_createElementBlock","_Fragment","_renderList","_renderSlot","_mergeProps","_createTextVNode","_toDisplayString","_sfc_main","_useModel","__unplugin_components_0","__unplugin_components_1","_openBlock","_createBlock","_withCtx","_createElementBlock","_Fragment","_renderList","_renderSlot","_mergeProps","_createTextVNode","_toDisplayString","_sfc_main","__unplugin_components_0","__unplugin_components_1","__unplugin_components_2","_openBlock","_createElementBlock","_createVNode","_createElementVNode","_toDisplayString","_unref","_normalizeClass","_createCommentVNode","_normalizeStyle","_Fragment","_createBlock","PkStreamingMarkdown","PkEditorCheckboxButtons","_createSlots","_renderList","_withCtx","PkEditorRadioButtons","_withKeys","_withModifiers","_sfc_main","__exportAll","isVoiceRenderAck","VvButtonLocalized","PkStreamingMarkdown_default","formAnswerSlots","formStepOptions","PkEditorRadioButtons_default","defineComponent","\"modelValue\"","\"modelModifiers\"","props","__props","modelValue","useModel","uid","useId","groupName","computed","radioModifiers","_component_VvRadio","VvRadio","_component_VvRadioGroup","VvRadioGroup","openBlock","createBlock","_cache","$event","withCtx","createElementBlock","Fragment","renderList","option","renderSlot","_ctx","mergeProps","createTextVNode","toDisplayString","PkEditorCheckboxButtons_default","_component_VvCheckbox","VvCheckbox","_component_VvCheckboxGroup","VvCheckboxGroup","_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","_hoisted_19","_hoisted_20","_hoisted_21","_hoisted_22","_hoisted_23","_hoisted_24","_hoisted_25","_hoisted_26","PkToolShowForm_vue_vue_type_script_setup_true_lang_default","__emit","emit","$t","$d","useI18n","toolPart","questionId","isLegacy","isRenderAck","isInteractive","isAutoSubmitStep","step","currentStep","steps","isLegacyAutoSubmit","isSelfSubmitting","input","o","hasFailed","currentStepIndex","ref","canGoBack","canGoNext","isMultiStep","progress","answers","reactive","customAnswer","scalarValue","val","activeCheckboxValue","outputAnswers","output","list","normalizedOutput","out","value","radioOptions","goNext","submitCustomAnswer","submitForm","goBack","finalAnswers","index","onRadioChange","getSummaryValue","_component_VvIcon","VvIcon","_component_VvInputText","VvInputText","_component_VvButton","createVNode","createElementVNode","unref","normalizeClass","createCommentVNode","normalizeStyle","createSlots","withKeys","withModifiers","PkToolShowForm_exports","PkToolShowForm_default"],"sources":["../../../../packages/components/src/PkEditorRadioButtons.vue","../../../../packages/components/src/PkEditorRadioButtons.vue","../../../../packages/components/src/PkEditorCheckboxButtons.vue","../../../../packages/components/src/PkEditorCheckboxButtons.vue","../../../../packages/components/src/chat/PkToolShowForm.vue","../../../../packages/components/src/chat/PkToolShowForm.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import type { Option } from '@volverjs/ui-vue'\n import { computed, useId } from 'vue'\n\n const props = defineProps<{\n name: string\n label?: string\n hintLabel?: string\n invalid?: boolean\n invalidLabel?: string | string[]\n required?: boolean\n options: Option[]\n readonly?: boolean\n disabled?: boolean\n modifiers?: string | string[]\n /**\n * Render the options as one segmented control (a recessed track with\n * the chosen option raised) instead of a row of boxed cards. Suits a\n * choice between a few short named states, such as a level or a mode.\n */\n segmented?: boolean\n }>()\n\n const modelValue = defineModel<\n string | number | boolean | symbol | unknown[] | undefined\n >({ default: undefined })\n\n // Native radios group by their name attribute across the whole document, so\n // two instances sharing one name become a single group: the browser unchecks\n // the other instance's inputs and Vue never puts them back, because its own\n // model did not change. It happened with \"theme\", offered by the profile\n // menu and the agent settings panel at the same time, and it can happen to\n // any two tool forms with the same step id. Scope the name to the instance.\n const uid = useId()\n const groupName = computed(() => `${props.name}-${uid}`)\n\n const radioModifiers = computed(() => {\n const toReturn = props.modifiers\n ? Array.isArray(props.modifiers)\n ? props.modifiers\n : [props.modifiers]\n : []\n return [...toReturn, props.segmented ? 'segment' : 'card']\n })\n</script>\n\n<template>\n <VvRadioGroup\n v-model=\"modelValue\"\n :name=\"groupName\"\n :label\n :hint-label=\"hintLabel\"\n :invalid\n :invalid-label=\"invalidLabel\"\n :modifiers=\"segmented ? 'segmented' : 'cards'\">\n <VvRadio\n v-for=\"(option, key) in options\"\n :key\n :name=\"groupName\"\n :required\n :readonly\n :disabled\n :value=\"option.value\"\n :modifiers=\"radioModifiers\">\n <slot :name=\"option.value\" v-bind=\"{ option }\">\n {{ option.label }}\n </slot>\n </VvRadio>\n </VvRadioGroup>\n</template>\n","<script setup lang=\"ts\">\n import type { Option } from '@volverjs/ui-vue'\n import { computed, useId } from 'vue'\n\n const props = defineProps<{\n name: string\n label?: string\n hintLabel?: string\n invalid?: boolean\n invalidLabel?: string | string[]\n required?: boolean\n options: Option[]\n readonly?: boolean\n disabled?: boolean\n modifiers?: string | string[]\n /**\n * Render the options as one segmented control (a recessed track with\n * the chosen option raised) instead of a row of boxed cards. Suits a\n * choice between a few short named states, such as a level or a mode.\n */\n segmented?: boolean\n }>()\n\n const modelValue = defineModel<\n string | number | boolean | symbol | unknown[] | undefined\n >({ default: undefined })\n\n // Native radios group by their name attribute across the whole document, so\n // two instances sharing one name become a single group: the browser unchecks\n // the other instance's inputs and Vue never puts them back, because its own\n // model did not change. It happened with \"theme\", offered by the profile\n // menu and the agent settings panel at the same time, and it can happen to\n // any two tool forms with the same step id. Scope the name to the instance.\n const uid = useId()\n const groupName = computed(() => `${props.name}-${uid}`)\n\n const radioModifiers = computed(() => {\n const toReturn = props.modifiers\n ? Array.isArray(props.modifiers)\n ? props.modifiers\n : [props.modifiers]\n : []\n return [...toReturn, props.segmented ? 'segment' : 'card']\n })\n</script>\n\n<template>\n <VvRadioGroup\n v-model=\"modelValue\"\n :name=\"groupName\"\n :label\n :hint-label=\"hintLabel\"\n :invalid\n :invalid-label=\"invalidLabel\"\n :modifiers=\"segmented ? 'segmented' : 'cards'\">\n <VvRadio\n v-for=\"(option, key) in options\"\n :key\n :name=\"groupName\"\n :required\n :readonly\n :disabled\n :value=\"option.value\"\n :modifiers=\"radioModifiers\">\n <slot :name=\"option.value\" v-bind=\"{ option }\">\n {{ option.label }}\n </slot>\n </VvRadio>\n </VvRadioGroup>\n</template>\n","<script setup lang=\"ts\">\n import type { Option } from '@volverjs/ui-vue'\n\n defineProps<{\n name: string\n required?: boolean\n options: Option[]\n readonly?: boolean\n disabled?: boolean\n }>()\n\n const modelValue = defineModel<unknown[] | undefined>({\n default: undefined,\n })\n</script>\n\n<template>\n <VvCheckboxGroup v-model=\"modelValue\" :name modifiers=\"cards\">\n <VvCheckbox\n v-for=\"(option, key) in options\"\n :key\n :name\n :required\n :readonly\n :disabled\n :value=\"option.value\"\n modifiers=\"card\">\n <slot :name=\"String(option.value)\" v-bind=\"{ option }\">\n {{ option.label }}\n </slot>\n </VvCheckbox>\n </VvCheckboxGroup>\n</template>\n","<script setup lang=\"ts\">\n import type { Option } from '@volverjs/ui-vue'\n\n defineProps<{\n name: string\n required?: boolean\n options: Option[]\n readonly?: boolean\n disabled?: boolean\n }>()\n\n const modelValue = defineModel<unknown[] | undefined>({\n default: undefined,\n })\n</script>\n\n<template>\n <VvCheckboxGroup v-model=\"modelValue\" :name modifiers=\"cards\">\n <VvCheckbox\n v-for=\"(option, key) in options\"\n :key\n :name\n :required\n :readonly\n :disabled\n :value=\"option.value\"\n modifiers=\"card\">\n <slot :name=\"String(option.value)\" v-bind=\"{ option }\">\n {{ option.label }}\n </slot>\n </VvCheckbox>\n </VvCheckboxGroup>\n</template>\n","<script setup lang=\"ts\">\n import { computed, ref, reactive, watch, useId } from 'vue'\n import { useI18n } from 'vue-i18n'\n import { isVoiceRenderAck } from 'models'\n import { formAnswerSlots, formStepOptions } from './utils'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n import PkEditorRadioButtons from '../PkEditorRadioButtons.vue'\n import PkEditorCheckboxButtons from '../PkEditorCheckboxButtons.vue'\n\n // --- Types ---\n\n interface FormOption {\n label: string\n description?: string\n }\n\n interface FormStep {\n id: string\n question: string\n message?: string\n type?: 'text' | 'number' | 'date'\n options?: FormOption[]\n multiSelect?: boolean\n allowFreeformInput?: boolean\n placeholder?: string\n }\n\n interface FormAnswer {\n id: string\n value: string | string[] | number | null\n }\n\n interface ToolPartShape {\n state?: 'input-available' | 'output-available' | 'output-error'\n toolCallId?: string\n // AI SDK v5 encodes the tool name in `type` (e.g. 'tool-showMultipleChoice').\n // `toolName` is kept for backward compatibility but is normally absent.\n type?: string\n toolName?: string\n input?: {\n title?: string\n steps?: FormStep[]\n // Legacy showMultipleChoice fields\n question?: string\n options?: (string | FormOption)[]\n }\n // The web card submits `{ answers: [...] }`; the platform channels\n // (Teams modal) submit a flat record keyed by step id.\n output?: string | { answers: FormAnswer[] } | Record<string, unknown>\n }\n\n type AnswerValue = string | string[] | number | null\n\n // --- Props & Emits ---\n\n const props = defineProps<{\n part: unknown\n allowCustomAnswer?: boolean\n /**\n * Answered during a call. Nothing in the part says so (the answer went\n * to the agent as speech, not to the tool call), so the surface that\n * sent it is the only one that knows, and without it the same form\n * could be submitted again and again.\n */\n answered?: boolean\n }>()\n\n const emit = defineEmits<{\n select: [answer: string | { answers: FormAnswer[] }]\n }>()\n\n const { t: $t, d: $d } = useI18n({ useScope: 'global' })\n\n // --- Parsed tool part ---\n\n const toolPart = computed(\n () => JSON.parse(JSON.stringify(props.part)) as ToolPartShape,\n )\n\n // The question names the free answer field: its placeholder only said\n // \"Insert…\", so a screen reader could not tell which answer was asked for\n const questionId = useId()\n\n const isLegacy = computed(\n () =>\n toolPart.value.toolName === 'showMultipleChoice' ||\n toolPart.value.type === 'tool-showMultipleChoice',\n )\n\n /**\n * A form drawn during a CALL is already \"answered\" as far as the tool loop\n * is concerned: the turn could not wait for it, so the backend closed it\n * with a note saying the widget was drawn (see `isVoiceRenderAck`). That\n * note is not an answer, and the caller still has to give one.\n */\n const isRenderAck = computed(() => isVoiceRenderAck(toolPart.value.output))\n\n const isInteractive = computed(\n () =>\n !props.answered &&\n (toolPart.value.state === 'input-available' || isRenderAck.value),\n )\n\n /** Single-step with no custom-answer and no freeform → auto-submit on option pick */\n const isAutoSubmitStep = computed(() => {\n const step = currentStep.value\n if (!step) {\n return false\n }\n return (\n steps.value.length === 1 &&\n !step.allowFreeformInput &&\n !props.allowCustomAnswer\n )\n })\n\n /** Legacy tool should auto-submit on option pick regardless of allowCustomAnswer */\n const isLegacyAutoSubmit = computed(\n () =>\n isLegacy.value &&\n steps.value.length === 1 &&\n !currentStep.value?.multiSelect,\n )\n\n /**\n * True only for the steps that send themselves as soon as an option is\n * picked: the single case where the footer button would be redundant.\n * Every other shape needs it, single-step forms included: with\n * `allowFreeformInput` (or `allowCustomAnswer`) the radio pick no longer\n * auto-submits, so without the footer the user was left with a chosen\n * option and no way to send it.\n */\n const isSelfSubmitting = computed(\n () =>\n Boolean(currentStep.value?.options) &&\n !currentStep.value?.multiSelect &&\n (isAutoSubmitStep.value || isLegacyAutoSubmit.value),\n )\n\n // --- Steps ---\n\n const steps = computed<FormStep[]>(() => {\n const input = toolPart.value.input\n if (input?.steps?.length) {\n return input.steps\n }\n // Legacy showMultipleChoice → normalize into a single step\n if (input?.question && input?.options) {\n return [\n {\n id: 'legacy',\n question: input.question,\n options: input.options.map((o) =>\n typeof o === 'string' ? { label: o } : o,\n ),\n },\n ]\n }\n return []\n })\n\n /**\n * The reason the card has nothing to draw. A call the SDK rejected keeps\n * `state: 'output-error'` and moves the arguments it could not validate to\n * `rawInput`, so `input` is empty and there are no steps: without this the\n * component rendered NOTHING, and the user was left with a question that\n * had been announced and never appeared.\n */\n const hasFailed = computed(\n () => toolPart.value.state === 'output-error' && !steps.value.length,\n )\n\n // --- Navigation state ---\n\n const currentStepIndex = ref(0)\n const currentStep = computed(() => steps.value[currentStepIndex.value])\n const canGoBack = computed(() => currentStepIndex.value > 0)\n const canGoNext = computed(\n () => currentStepIndex.value < steps.value.length - 1,\n )\n const isMultiStep = computed(() => steps.value.length > 1)\n\n const progress = computed(() => {\n if (!isMultiStep.value) {\n return null\n }\n return Math.round(\n ((currentStepIndex.value + 1) / steps.value.length) * 100,\n )\n })\n\n // --- Answers ---\n\n /**\n * One slot PER STEP, keyed by position and not by step id: the ids come\n * from the model and nothing enforces they are unique, and keyed by id two\n * steps sharing one collapsed onto a single answer. See `formAnswerSlots`.\n */\n const answers = reactive<Record<number, AnswerValue>>({})\n const customAnswer = ref('')\n\n // The freeform field belongs to the step showing it: text left behind\n // (unsubmitted, or arriving from a late input update) must not follow the\n // user to the next or previous question.\n watch(currentStepIndex, () => {\n customAnswer.value = ''\n })\n\n // Single scalar answer shared by radio buttons and freeform text/number/date inputs.\n const scalarValue = computed<string | number | undefined>({\n get: () => {\n const val = currentStep.value\n ? answers[currentStepIndex.value]\n : undefined\n if (val == null || Array.isArray(val)) {\n return undefined\n }\n return val\n },\n set: (val) => {\n if (currentStep.value) {\n answers[currentStepIndex.value] = val ?? null\n }\n },\n })\n\n const activeCheckboxValue = computed<unknown[] | undefined>({\n get: () => {\n const val = currentStep.value\n ? answers[currentStepIndex.value]\n : undefined\n return Array.isArray(val) ? val : []\n },\n set: (val) => {\n if (currentStep.value) {\n answers[currentStepIndex.value] = (val as string[]) ?? []\n }\n },\n })\n\n // --- Initialize answers from existing output ---\n\n /** The `{ answers: [...] }` list, when the output carries one. */\n function outputAnswers(output: ToolPartShape['output']) {\n if (!output || typeof output === 'string') {\n return undefined\n }\n const list = (output as { answers?: unknown }).answers\n return Array.isArray(list) ? (list as FormAnswer[]) : undefined\n }\n\n watch(\n () => toolPart.value.output,\n (output) => {\n if (!output || isVoiceRenderAck(output)) {\n return\n }\n // Every shape an answered form comes back in (the web card's list,\n // a legacy plain string, the flat record a platform channel posts)\n // lands on the same per-position slots: see `formAnswerSlots`.\n Object.assign(\n answers,\n formAnswerSlots(steps.value, output) as Record<\n number,\n AnswerValue\n >,\n )\n },\n { immediate: true },\n )\n\n // --- Restore custom answer from output when it doesn't match any option ---\n\n const normalizedOutput = computed(() => {\n const out = toolPart.value.output\n if (!out || isVoiceRenderAck(out)) {\n return undefined\n }\n if (typeof out === 'string') {\n return out\n }\n const list = outputAnswers(out)\n if (list?.length === 1) {\n const val = list[0].value\n return Array.isArray(val) ? val.join(', ') : String(val)\n }\n return undefined\n })\n\n watch(\n normalizedOutput,\n (value) => {\n if (!value || !currentStep.value) {\n return\n }\n const optionLabels = (currentStep.value.options ?? []).map(\n (o) => o.label,\n )\n if (!optionLabels.includes(value)) {\n customAnswer.value = value\n }\n },\n { immediate: true },\n )\n\n // --- Option mapping for radio/checkbox components ---\n\n const radioOptions = computed(() => formStepOptions(currentStep.value))\n\n // --- Navigation & Submission ---\n\n /** Footer button, and Enter on a pure freeform step. */\n function goNext() {\n // A typed freeform answer wins over the picked option: it is the more\n // recent intent, and the footer button is now the visible way to send\n // it (the freeform field only submits on Enter).\n if (customAnswer.value.trim()) {\n submitCustomAnswer()\n return\n }\n if (canGoNext.value) {\n currentStepIndex.value++\n } else {\n submitForm()\n }\n }\n\n function goBack() {\n if (canGoBack.value) {\n currentStepIndex.value--\n }\n }\n\n function submitForm() {\n if (!isInteractive.value) {\n return\n }\n\n const finalAnswers: FormAnswer[] = steps.value.map((step, index) => ({\n id: step.id,\n value: answers[index] ?? null,\n }))\n\n // Legacy backward compatibility: single-step, single-select → return plain string\n if (\n isLegacyAutoSubmit.value &&\n !currentStep.value?.allowFreeformInput\n ) {\n const val = finalAnswers[0].value\n emit('select', Array.isArray(val) ? val[0] : (val as string))\n } else {\n emit('select', { answers: finalAnswers })\n }\n }\n\n /** Enter inside the freeform field shown alongside the options. */\n function submitCustomAnswer() {\n const value = customAnswer.value.trim()\n if (!value) {\n return\n }\n\n answers[currentStepIndex.value] = value\n // Cleared before navigating: `goNext()` reads it back to route a typed\n // answer here, so leaving it set would recurse.\n customAnswer.value = ''\n if (steps.value.length === 1) {\n submitForm()\n } else {\n goNext()\n }\n }\n\n function onRadioChange() {\n if (!isInteractive.value) {\n return\n }\n if (isAutoSubmitStep.value || isLegacyAutoSubmit.value) {\n submitForm()\n }\n }\n\n // --- Summary helpers ---\n\n function getSummaryValue(step: FormStep, index: number) {\n const val = answers[index]\n if (val == null) {\n return '—'\n }\n if (Array.isArray(val)) {\n return val.join(', ')\n }\n if (step.type === 'date') {\n return $d(new Date(val), 'short')\n }\n return val\n }\n</script>\n\n<template>\n <div\n v-if=\"hasFailed\"\n class=\"text-12 text-danger flex items-center gap-6 py-8\">\n <VvIcon name=\"ri:error-warning-line\" class=\"w-16 h-16 shrink-0\" />\n <span>{{ $t('message.formRenderError') }}</span>\n </div>\n <div\n v-else-if=\"steps.length\"\n class=\"border border-surface-3 rounded-xl w-full overflow-hidden flex flex-col bg-surface\">\n <!-- Header -->\n <div\n v-if=\"toolPart.input?.title || (isInteractive && steps.length > 1)\"\n class=\"text-12 border-b border-surface-3 text-word-3 bg-surface-1\">\n <div\n v-if=\"toolPart.input?.title\"\n class=\"px-sm py-10 font-bold\"\n :class=\"{\n 'border-b border-surface-3':\n isInteractive && steps.length > 1,\n }\">\n {{ toolPart.input?.title }}\n </div>\n <!-- Progress for multi-step -->\n <div\n v-if=\"isInteractive && steps.length > 1\"\n class=\"flex flex-col gap-4 p-sm\">\n <div class=\"flex justify-between text-10 text-word-3\">\n <span>\n {{\n $t('showForm.step', {\n current: currentStepIndex + 1,\n total: steps.length,\n })\n }}\n </span>\n <span>{{ progress }}%</span>\n </div>\n <div class=\"h-4 bg-surface-3 rounded-full overflow-hidden\">\n <div\n class=\"h-full bg-word-4 transition-all duration-300\"\n :style=\"{ width: `${progress}%` }\"></div>\n </div>\n </div>\n </div>\n\n <!-- Input Available State -->\n <template v-if=\"isInteractive\">\n <!-- Current Step Content -->\n <div class=\"px-sm py-16 flex flex-col gap-12\">\n <div class=\"leading-normal text-12\">\n <strong :id=\"questionId\" class=\"font-semibold\">\n {{ currentStep.question }}\n </strong>\n <PkStreamingMarkdown\n v-if=\"currentStep.message\"\n :markdown=\"currentStep.message\"\n class=\"text-word-2 mt-4\" />\n </div>\n\n <!-- Checkbox list for multi-select -->\n <PkEditorCheckboxButtons\n v-if=\"currentStep.options && currentStep.multiSelect\"\n v-model=\"activeCheckboxValue\"\n :name=\"currentStep.id\"\n :options=\"radioOptions\"\n :readonly=\"!isInteractive\"\n class=\"mb-0\"\n vertical>\n <template\n v-for=\"option in radioOptions\"\n :key=\"option.value\"\n #[option.value]>\n <!-- Shared option layout: label + optional description -->\n <div class=\"text-12\">\n <div class=\"font-semibold\">{{ option.label }}</div>\n <div v-if=\"option.description\" class=\"text-word-3\">\n {{ option.description }}\n </div>\n </div>\n </template>\n </PkEditorCheckboxButtons>\n\n <!-- Radio buttons for single-select -->\n <PkEditorRadioButtons\n v-else-if=\"currentStep.options && !currentStep.multiSelect\"\n v-model=\"scalarValue\"\n :name=\"currentStep.id\"\n :options=\"radioOptions\"\n :readonly=\"!isInteractive\"\n vertical\n class=\"mb-0\"\n @update:model-value=\"onRadioChange\">\n <template\n v-for=\"option in radioOptions\"\n :key=\"option.value\"\n #[option.value]>\n <!-- Shared option layout: label + optional description -->\n <div class=\"text-12\">\n <div class=\"font-semibold\">{{ option.label }}</div>\n <div v-if=\"option.description\" class=\"text-word-3\">\n {{ option.description }}\n </div>\n </div>\n </template>\n </PkEditorRadioButtons>\n\n <!-- Pure Freeform Input (text, number, date) -->\n <div\n v-else-if=\"!currentStep.options\"\n class=\"flex flex-col gap-6 w-full\">\n <VvInputText\n :key=\"currentStep.id\"\n v-model=\"scalarValue\"\n :aria-labelledby=\"questionId\"\n :placeholder=\"\n currentStep.placeholder || $t('placeholder.insert')\n \"\n :type=\"currentStep.type\"\n class=\"w-full\"\n :name=\"currentStep.id\"\n modifiers=\"compact\"\n :disabled=\"!isInteractive\"\n @keyup.enter=\"goNext\" />\n </div>\n </div>\n\n <!-- Custom footer freeform input (shown alongside options when allowFreeformInput) -->\n <div\n v-if=\"currentStep.allowFreeformInput && currentStep.options\"\n class=\"px-sm pb-sm border-t border-surface-3\">\n <form\n class=\"flex gap-xs pt-sm\"\n @submit.prevent=\"submitCustomAnswer\">\n <VvInputText\n :key=\"`${currentStep.id}-custom`\"\n v-model=\"customAnswer\"\n class=\"flex-1\"\n :name=\"`${currentStep.id}-custom`\"\n modifiers=\"compact\"\n :disabled=\"!isInteractive\"\n :aria-label=\"\n currentStep.placeholder ||\n $t('showForm.otherPlaceholder')\n \"\n :placeholder=\"\n currentStep.placeholder ||\n $t('showForm.otherPlaceholder')\n \" />\n </form>\n </div>\n\n <!-- Footer navigation: shown for every step that does not submit\n itself on option pick (see `isSelfSubmitting`). -->\n <div\n v-if=\"!isSelfSubmitting\"\n class=\"px-sm py-10 bg-surface border-t border-surface-3 flex justify-between gap-12\">\n <VvButton\n v-if=\"canGoBack\"\n modifiers=\"action-quiet\"\n icon=\"ri:arrow-left-s-line\"\n :label=\"$t('action.back')\"\n @click.stop=\"goBack\" />\n <div v-else></div>\n\n <VvButton\n :modifiers=\"canGoNext ? 'action-quiet' : 'action-primary'\"\n :icon=\"\n canGoNext\n ? 'ri:arrow-right-s-line'\n : 'ri:send-plane-2-line'\n \"\n icon-position=\"right\"\n :label=\"canGoNext ? $t('action.next') : $t('action.submit')\"\n @click.stop=\"goNext\" />\n </div>\n </template>\n\n <!-- Output Available State (Multi-step Summary) -->\n <template v-else>\n <div class=\"px-sm py-12 bg-surface flex flex-col gap-10\">\n <ul class=\"flex flex-col gap-8\">\n <li\n v-for=\"(step, index) in steps\"\n :key=\"index\"\n class=\"leading-normal\">\n <div class=\"text-12 text-word-3\">\n {{ step.question }}\n </div>\n <span class=\"text-12 text-word-2 font-semibold\">\n {{ getSummaryValue(step, index) }}\n </span>\n </li>\n </ul>\n </div>\n <div\n class=\"px-sm py-12 bg-surface border-t border-surface-3 flex items-center gap-10\">\n <VvIcon name=\"ri:check-line\" class=\"text-16 text-success\" />\n <div class=\"flex flex-col\">\n <span class=\"font-medium text-12 text-word-1 leading-tight\">\n {{ $t('showForm.completed') }}\n </span>\n </div>\n </div>\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed, ref, reactive, watch, useId } from 'vue'\n import { useI18n } from 'vue-i18n'\n import { isVoiceRenderAck } from 'models'\n import { formAnswerSlots, formStepOptions } from './utils'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n import PkEditorRadioButtons from '../PkEditorRadioButtons.vue'\n import PkEditorCheckboxButtons from '../PkEditorCheckboxButtons.vue'\n\n // --- Types ---\n\n interface FormOption {\n label: string\n description?: string\n }\n\n interface FormStep {\n id: string\n question: string\n message?: string\n type?: 'text' | 'number' | 'date'\n options?: FormOption[]\n multiSelect?: boolean\n allowFreeformInput?: boolean\n placeholder?: string\n }\n\n interface FormAnswer {\n id: string\n value: string | string[] | number | null\n }\n\n interface ToolPartShape {\n state?: 'input-available' | 'output-available' | 'output-error'\n toolCallId?: string\n // AI SDK v5 encodes the tool name in `type` (e.g. 'tool-showMultipleChoice').\n // `toolName` is kept for backward compatibility but is normally absent.\n type?: string\n toolName?: string\n input?: {\n title?: string\n steps?: FormStep[]\n // Legacy showMultipleChoice fields\n question?: string\n options?: (string | FormOption)[]\n }\n // The web card submits `{ answers: [...] }`; the platform channels\n // (Teams modal) submit a flat record keyed by step id.\n output?: string | { answers: FormAnswer[] } | Record<string, unknown>\n }\n\n type AnswerValue = string | string[] | number | null\n\n // --- Props & Emits ---\n\n const props = defineProps<{\n part: unknown\n allowCustomAnswer?: boolean\n /**\n * Answered during a call. Nothing in the part says so (the answer went\n * to the agent as speech, not to the tool call), so the surface that\n * sent it is the only one that knows, and without it the same form\n * could be submitted again and again.\n */\n answered?: boolean\n }>()\n\n const emit = defineEmits<{\n select: [answer: string | { answers: FormAnswer[] }]\n }>()\n\n const { t: $t, d: $d } = useI18n({ useScope: 'global' })\n\n // --- Parsed tool part ---\n\n const toolPart = computed(\n () => JSON.parse(JSON.stringify(props.part)) as ToolPartShape,\n )\n\n // The question names the free answer field: its placeholder only said\n // \"Insert…\", so a screen reader could not tell which answer was asked for\n const questionId = useId()\n\n const isLegacy = computed(\n () =>\n toolPart.value.toolName === 'showMultipleChoice' ||\n toolPart.value.type === 'tool-showMultipleChoice',\n )\n\n /**\n * A form drawn during a CALL is already \"answered\" as far as the tool loop\n * is concerned: the turn could not wait for it, so the backend closed it\n * with a note saying the widget was drawn (see `isVoiceRenderAck`). That\n * note is not an answer, and the caller still has to give one.\n */\n const isRenderAck = computed(() => isVoiceRenderAck(toolPart.value.output))\n\n const isInteractive = computed(\n () =>\n !props.answered &&\n (toolPart.value.state === 'input-available' || isRenderAck.value),\n )\n\n /** Single-step with no custom-answer and no freeform → auto-submit on option pick */\n const isAutoSubmitStep = computed(() => {\n const step = currentStep.value\n if (!step) {\n return false\n }\n return (\n steps.value.length === 1 &&\n !step.allowFreeformInput &&\n !props.allowCustomAnswer\n )\n })\n\n /** Legacy tool should auto-submit on option pick regardless of allowCustomAnswer */\n const isLegacyAutoSubmit = computed(\n () =>\n isLegacy.value &&\n steps.value.length === 1 &&\n !currentStep.value?.multiSelect,\n )\n\n /**\n * True only for the steps that send themselves as soon as an option is\n * picked: the single case where the footer button would be redundant.\n * Every other shape needs it, single-step forms included: with\n * `allowFreeformInput` (or `allowCustomAnswer`) the radio pick no longer\n * auto-submits, so without the footer the user was left with a chosen\n * option and no way to send it.\n */\n const isSelfSubmitting = computed(\n () =>\n Boolean(currentStep.value?.options) &&\n !currentStep.value?.multiSelect &&\n (isAutoSubmitStep.value || isLegacyAutoSubmit.value),\n )\n\n // --- Steps ---\n\n const steps = computed<FormStep[]>(() => {\n const input = toolPart.value.input\n if (input?.steps?.length) {\n return input.steps\n }\n // Legacy showMultipleChoice → normalize into a single step\n if (input?.question && input?.options) {\n return [\n {\n id: 'legacy',\n question: input.question,\n options: input.options.map((o) =>\n typeof o === 'string' ? { label: o } : o,\n ),\n },\n ]\n }\n return []\n })\n\n /**\n * The reason the card has nothing to draw. A call the SDK rejected keeps\n * `state: 'output-error'` and moves the arguments it could not validate to\n * `rawInput`, so `input` is empty and there are no steps: without this the\n * component rendered NOTHING, and the user was left with a question that\n * had been announced and never appeared.\n */\n const hasFailed = computed(\n () => toolPart.value.state === 'output-error' && !steps.value.length,\n )\n\n // --- Navigation state ---\n\n const currentStepIndex = ref(0)\n const currentStep = computed(() => steps.value[currentStepIndex.value])\n const canGoBack = computed(() => currentStepIndex.value > 0)\n const canGoNext = computed(\n () => currentStepIndex.value < steps.value.length - 1,\n )\n const isMultiStep = computed(() => steps.value.length > 1)\n\n const progress = computed(() => {\n if (!isMultiStep.value) {\n return null\n }\n return Math.round(\n ((currentStepIndex.value + 1) / steps.value.length) * 100,\n )\n })\n\n // --- Answers ---\n\n /**\n * One slot PER STEP, keyed by position and not by step id: the ids come\n * from the model and nothing enforces they are unique, and keyed by id two\n * steps sharing one collapsed onto a single answer. See `formAnswerSlots`.\n */\n const answers = reactive<Record<number, AnswerValue>>({})\n const customAnswer = ref('')\n\n // The freeform field belongs to the step showing it: text left behind\n // (unsubmitted, or arriving from a late input update) must not follow the\n // user to the next or previous question.\n watch(currentStepIndex, () => {\n customAnswer.value = ''\n })\n\n // Single scalar answer shared by radio buttons and freeform text/number/date inputs.\n const scalarValue = computed<string | number | undefined>({\n get: () => {\n const val = currentStep.value\n ? answers[currentStepIndex.value]\n : undefined\n if (val == null || Array.isArray(val)) {\n return undefined\n }\n return val\n },\n set: (val) => {\n if (currentStep.value) {\n answers[currentStepIndex.value] = val ?? null\n }\n },\n })\n\n const activeCheckboxValue = computed<unknown[] | undefined>({\n get: () => {\n const val = currentStep.value\n ? answers[currentStepIndex.value]\n : undefined\n return Array.isArray(val) ? val : []\n },\n set: (val) => {\n if (currentStep.value) {\n answers[currentStepIndex.value] = (val as string[]) ?? []\n }\n },\n })\n\n // --- Initialize answers from existing output ---\n\n /** The `{ answers: [...] }` list, when the output carries one. */\n function outputAnswers(output: ToolPartShape['output']) {\n if (!output || typeof output === 'string') {\n return undefined\n }\n const list = (output as { answers?: unknown }).answers\n return Array.isArray(list) ? (list as FormAnswer[]) : undefined\n }\n\n watch(\n () => toolPart.value.output,\n (output) => {\n if (!output || isVoiceRenderAck(output)) {\n return\n }\n // Every shape an answered form comes back in (the web card's list,\n // a legacy plain string, the flat record a platform channel posts)\n // lands on the same per-position slots: see `formAnswerSlots`.\n Object.assign(\n answers,\n formAnswerSlots(steps.value, output) as Record<\n number,\n AnswerValue\n >,\n )\n },\n { immediate: true },\n )\n\n // --- Restore custom answer from output when it doesn't match any option ---\n\n const normalizedOutput = computed(() => {\n const out = toolPart.value.output\n if (!out || isVoiceRenderAck(out)) {\n return undefined\n }\n if (typeof out === 'string') {\n return out\n }\n const list = outputAnswers(out)\n if (list?.length === 1) {\n const val = list[0].value\n return Array.isArray(val) ? val.join(', ') : String(val)\n }\n return undefined\n })\n\n watch(\n normalizedOutput,\n (value) => {\n if (!value || !currentStep.value) {\n return\n }\n const optionLabels = (currentStep.value.options ?? []).map(\n (o) => o.label,\n )\n if (!optionLabels.includes(value)) {\n customAnswer.value = value\n }\n },\n { immediate: true },\n )\n\n // --- Option mapping for radio/checkbox components ---\n\n const radioOptions = computed(() => formStepOptions(currentStep.value))\n\n // --- Navigation & Submission ---\n\n /** Footer button, and Enter on a pure freeform step. */\n function goNext() {\n // A typed freeform answer wins over the picked option: it is the more\n // recent intent, and the footer button is now the visible way to send\n // it (the freeform field only submits on Enter).\n if (customAnswer.value.trim()) {\n submitCustomAnswer()\n return\n }\n if (canGoNext.value) {\n currentStepIndex.value++\n } else {\n submitForm()\n }\n }\n\n function goBack() {\n if (canGoBack.value) {\n currentStepIndex.value--\n }\n }\n\n function submitForm() {\n if (!isInteractive.value) {\n return\n }\n\n const finalAnswers: FormAnswer[] = steps.value.map((step, index) => ({\n id: step.id,\n value: answers[index] ?? null,\n }))\n\n // Legacy backward compatibility: single-step, single-select → return plain string\n if (\n isLegacyAutoSubmit.value &&\n !currentStep.value?.allowFreeformInput\n ) {\n const val = finalAnswers[0].value\n emit('select', Array.isArray(val) ? val[0] : (val as string))\n } else {\n emit('select', { answers: finalAnswers })\n }\n }\n\n /** Enter inside the freeform field shown alongside the options. */\n function submitCustomAnswer() {\n const value = customAnswer.value.trim()\n if (!value) {\n return\n }\n\n answers[currentStepIndex.value] = value\n // Cleared before navigating: `goNext()` reads it back to route a typed\n // answer here, so leaving it set would recurse.\n customAnswer.value = ''\n if (steps.value.length === 1) {\n submitForm()\n } else {\n goNext()\n }\n }\n\n function onRadioChange() {\n if (!isInteractive.value) {\n return\n }\n if (isAutoSubmitStep.value || isLegacyAutoSubmit.value) {\n submitForm()\n }\n }\n\n // --- Summary helpers ---\n\n function getSummaryValue(step: FormStep, index: number) {\n const val = answers[index]\n if (val == null) {\n return '—'\n }\n if (Array.isArray(val)) {\n return val.join(', ')\n }\n if (step.type === 'date') {\n return $d(new Date(val), 'short')\n }\n return val\n }\n</script>\n\n<template>\n <div\n v-if=\"hasFailed\"\n class=\"text-12 text-danger flex items-center gap-6 py-8\">\n <VvIcon name=\"ri:error-warning-line\" class=\"w-16 h-16 shrink-0\" />\n <span>{{ $t('message.formRenderError') }}</span>\n </div>\n <div\n v-else-if=\"steps.length\"\n class=\"border border-surface-3 rounded-xl w-full overflow-hidden flex flex-col bg-surface\">\n <!-- Header -->\n <div\n v-if=\"toolPart.input?.title || (isInteractive && steps.length > 1)\"\n class=\"text-12 border-b border-surface-3 text-word-3 bg-surface-1\">\n <div\n v-if=\"toolPart.input?.title\"\n class=\"px-sm py-10 font-bold\"\n :class=\"{\n 'border-b border-surface-3':\n isInteractive && steps.length > 1,\n }\">\n {{ toolPart.input?.title }}\n </div>\n <!-- Progress for multi-step -->\n <div\n v-if=\"isInteractive && steps.length > 1\"\n class=\"flex flex-col gap-4 p-sm\">\n <div class=\"flex justify-between text-10 text-word-3\">\n <span>\n {{\n $t('showForm.step', {\n current: currentStepIndex + 1,\n total: steps.length,\n })\n }}\n </span>\n <span>{{ progress }}%</span>\n </div>\n <div class=\"h-4 bg-surface-3 rounded-full overflow-hidden\">\n <div\n class=\"h-full bg-word-4 transition-all duration-300\"\n :style=\"{ width: `${progress}%` }\"></div>\n </div>\n </div>\n </div>\n\n <!-- Input Available State -->\n <template v-if=\"isInteractive\">\n <!-- Current Step Content -->\n <div class=\"px-sm py-16 flex flex-col gap-12\">\n <div class=\"leading-normal text-12\">\n <strong :id=\"questionId\" class=\"font-semibold\">\n {{ currentStep.question }}\n </strong>\n <PkStreamingMarkdown\n v-if=\"currentStep.message\"\n :markdown=\"currentStep.message\"\n class=\"text-word-2 mt-4\" />\n </div>\n\n <!-- Checkbox list for multi-select -->\n <PkEditorCheckboxButtons\n v-if=\"currentStep.options && currentStep.multiSelect\"\n v-model=\"activeCheckboxValue\"\n :name=\"currentStep.id\"\n :options=\"radioOptions\"\n :readonly=\"!isInteractive\"\n class=\"mb-0\"\n vertical>\n <template\n v-for=\"option in radioOptions\"\n :key=\"option.value\"\n #[option.value]>\n <!-- Shared option layout: label + optional description -->\n <div class=\"text-12\">\n <div class=\"font-semibold\">{{ option.label }}</div>\n <div v-if=\"option.description\" class=\"text-word-3\">\n {{ option.description }}\n </div>\n </div>\n </template>\n </PkEditorCheckboxButtons>\n\n <!-- Radio buttons for single-select -->\n <PkEditorRadioButtons\n v-else-if=\"currentStep.options && !currentStep.multiSelect\"\n v-model=\"scalarValue\"\n :name=\"currentStep.id\"\n :options=\"radioOptions\"\n :readonly=\"!isInteractive\"\n vertical\n class=\"mb-0\"\n @update:model-value=\"onRadioChange\">\n <template\n v-for=\"option in radioOptions\"\n :key=\"option.value\"\n #[option.value]>\n <!-- Shared option layout: label + optional description -->\n <div class=\"text-12\">\n <div class=\"font-semibold\">{{ option.label }}</div>\n <div v-if=\"option.description\" class=\"text-word-3\">\n {{ option.description }}\n </div>\n </div>\n </template>\n </PkEditorRadioButtons>\n\n <!-- Pure Freeform Input (text, number, date) -->\n <div\n v-else-if=\"!currentStep.options\"\n class=\"flex flex-col gap-6 w-full\">\n <VvInputText\n :key=\"currentStep.id\"\n v-model=\"scalarValue\"\n :aria-labelledby=\"questionId\"\n :placeholder=\"\n currentStep.placeholder || $t('placeholder.insert')\n \"\n :type=\"currentStep.type\"\n class=\"w-full\"\n :name=\"currentStep.id\"\n modifiers=\"compact\"\n :disabled=\"!isInteractive\"\n @keyup.enter=\"goNext\" />\n </div>\n </div>\n\n <!-- Custom footer freeform input (shown alongside options when allowFreeformInput) -->\n <div\n v-if=\"currentStep.allowFreeformInput && currentStep.options\"\n class=\"px-sm pb-sm border-t border-surface-3\">\n <form\n class=\"flex gap-xs pt-sm\"\n @submit.prevent=\"submitCustomAnswer\">\n <VvInputText\n :key=\"`${currentStep.id}-custom`\"\n v-model=\"customAnswer\"\n class=\"flex-1\"\n :name=\"`${currentStep.id}-custom`\"\n modifiers=\"compact\"\n :disabled=\"!isInteractive\"\n :aria-label=\"\n currentStep.placeholder ||\n $t('showForm.otherPlaceholder')\n \"\n :placeholder=\"\n currentStep.placeholder ||\n $t('showForm.otherPlaceholder')\n \" />\n </form>\n </div>\n\n <!-- Footer navigation: shown for every step that does not submit\n itself on option pick (see `isSelfSubmitting`). -->\n <div\n v-if=\"!isSelfSubmitting\"\n class=\"px-sm py-10 bg-surface border-t border-surface-3 flex justify-between gap-12\">\n <VvButton\n v-if=\"canGoBack\"\n modifiers=\"action-quiet\"\n icon=\"ri:arrow-left-s-line\"\n :label=\"$t('action.back')\"\n @click.stop=\"goBack\" />\n <div v-else></div>\n\n <VvButton\n :modifiers=\"canGoNext ? 'action-quiet' : 'action-primary'\"\n :icon=\"\n canGoNext\n ? 'ri:arrow-right-s-line'\n : 'ri:send-plane-2-line'\n \"\n icon-position=\"right\"\n :label=\"canGoNext ? $t('action.next') : $t('action.submit')\"\n @click.stop=\"goNext\" />\n </div>\n </template>\n\n <!-- Output Available State (Multi-step Summary) -->\n <template v-else>\n <div class=\"px-sm py-12 bg-surface flex flex-col gap-10\">\n <ul class=\"flex flex-col gap-8\">\n <li\n v-for=\"(step, index) in steps\"\n :key=\"index\"\n class=\"leading-normal\">\n <div class=\"text-12 text-word-3\">\n {{ step.question }}\n </div>\n <span class=\"text-12 text-word-2 font-semibold\">\n {{ getSummaryValue(step, index) }}\n </span>\n </li>\n </ul>\n </div>\n <div\n class=\"px-sm py-12 bg-surface border-t border-surface-3 flex items-center gap-10\">\n <VvIcon name=\"ri:check-line\" class=\"text-16 text-success\" />\n <div class=\"flex flex-col\">\n <span class=\"font-medium text-12 text-word-1 leading-tight\">\n {{ $t('showForm.completed') }}\n </span>\n </div>\n </div>\n </template>\n </div>\n</template>\n"],"mappings":"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"}