@8wave/ai-elements 0.111.0-beta.7 → 0.111.0-beta.8

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 (125) hide show
  1. package/dist/_chunks/{PkLazyImg-ClL4nr95.js → PkLazyImg-Dbj2dDXA.js} +2 -2
  2. package/dist/_chunks/{PkLazyImg-ClL4nr95.js.map → PkLazyImg-Dbj2dDXA.js.map} +1 -1
  3. package/dist/_chunks/{PkStreamingMarkdown-DgBS4Ebc.js → PkStreamingMarkdown-CNI8aV8t.js} +617 -418
  4. package/dist/_chunks/PkStreamingMarkdown-CNI8aV8t.js.map +1 -0
  5. package/dist/_chunks/{PkToolRequestGeolocation-pVys3x9M.js → PkToolRequestGeolocation-Bzy4IYSp.js} +2 -2
  6. package/dist/_chunks/{PkToolRequestGeolocation-pVys3x9M.js.map → PkToolRequestGeolocation-Bzy4IYSp.js.map} +1 -1
  7. package/dist/_chunks/{PkToolRequestOAuthConnection-BGChb_eC.js → PkToolRequestOAuthConnection-CWEKoD71.js} +2 -2
  8. package/dist/_chunks/{PkToolRequestOAuthConnection-BGChb_eC.js.map → PkToolRequestOAuthConnection-CWEKoD71.js.map} +1 -1
  9. package/dist/_chunks/{PkToolShowArtifact-CkTBIdQd.js → PkToolShowArtifact-CGbHDEie.js} +4 -4
  10. package/dist/_chunks/{PkToolShowArtifact-CkTBIdQd.js.map → PkToolShowArtifact-CGbHDEie.js.map} +1 -1
  11. package/dist/_chunks/{PkToolShowCalendarEvent-C41JgOUA.js → PkToolShowCalendarEvent-DIFX_rUz.js} +3 -3
  12. package/dist/_chunks/{PkToolShowCalendarEvent-C41JgOUA.js.map → PkToolShowCalendarEvent-DIFX_rUz.js.map} +1 -1
  13. package/dist/_chunks/{PkToolShowComparison-DbbUD9pg.js → PkToolShowComparison-B38hHWq2.js} +3 -3
  14. package/dist/_chunks/{PkToolShowComparison-DbbUD9pg.js.map → PkToolShowComparison-B38hHWq2.js.map} +1 -1
  15. package/dist/_chunks/{PkToolShowContactForm-Du7jX7K5.js → PkToolShowContactForm-DUw_bZiJ.js} +4 -4
  16. package/dist/_chunks/{PkToolShowContactForm-Du7jX7K5.js.map → PkToolShowContactForm-DUw_bZiJ.js.map} +1 -1
  17. package/dist/_chunks/{PkToolShowDiagram-BdmG9gm8.js → PkToolShowDiagram-Dx1Ba0PG.js} +3 -3
  18. package/dist/_chunks/{PkToolShowDiagram-BdmG9gm8.js.map → PkToolShowDiagram-Dx1Ba0PG.js.map} +1 -1
  19. package/dist/_chunks/{PkToolShowEmail-Dn3JHYIR.js → PkToolShowEmail-DnFFgzom.js} +3 -3
  20. package/dist/_chunks/{PkToolShowEmail-Dn3JHYIR.js.map → PkToolShowEmail-DnFFgzom.js.map} +1 -1
  21. package/dist/_chunks/{PkToolShowForm-Du2nk7pq.js → PkToolShowForm-CKQQltJ6.js} +5 -6
  22. package/dist/_chunks/{PkToolShowForm-Du2nk7pq.js.map → PkToolShowForm-CKQQltJ6.js.map} +1 -1
  23. package/dist/_chunks/{PkToolShowImageGallery-C1lzlO0y.js → PkToolShowImageGallery-D99N_Plf.js} +2 -2
  24. package/dist/_chunks/{PkToolShowImageGallery-C1lzlO0y.js.map → PkToolShowImageGallery-D99N_Plf.js.map} +1 -1
  25. package/dist/_chunks/{PkToolShowLocation-CKhPxKFA.js → PkToolShowLocation-AfnrtFVJ.js} +3 -3
  26. package/dist/_chunks/{PkToolShowLocation-CKhPxKFA.js.map → PkToolShowLocation-AfnrtFVJ.js.map} +1 -1
  27. package/dist/_chunks/{PkToolShowMessage-U9CCU7eG.js → PkToolShowMessage-DUo2c-im.js} +3 -3
  28. package/dist/_chunks/{PkToolShowMessage-U9CCU7eG.js.map → PkToolShowMessage-DUo2c-im.js.map} +1 -1
  29. package/dist/_chunks/{PkToolShowProductList-UeiRMLHu.js → PkToolShowProductList-BN6Qk1_y.js} +3 -3
  30. package/dist/_chunks/{PkToolShowProductList-UeiRMLHu.js.map → PkToolShowProductList-BN6Qk1_y.js.map} +1 -1
  31. package/dist/_chunks/{PkToolShowQrCode-CypLrfh5.js → PkToolShowQrCode-BLqeBecX.js} +3 -3
  32. package/dist/_chunks/{PkToolShowQrCode-CypLrfh5.js.map → PkToolShowQrCode-BLqeBecX.js.map} +1 -1
  33. package/dist/_chunks/{PkToolShowSources-CsHLUF4L.js → PkToolShowSources-DpZb5FUP.js} +3 -3
  34. package/dist/_chunks/{PkToolShowSources-CsHLUF4L.js.map → PkToolShowSources-DpZb5FUP.js.map} +1 -1
  35. package/dist/_chunks/{PkToolShowSuggestedReply-D7g_qymH.js → PkToolShowSuggestedReply-C10nNgBs.js} +2 -2
  36. package/dist/_chunks/{PkToolShowSuggestedReply-D7g_qymH.js.map → PkToolShowSuggestedReply-C10nNgBs.js.map} +1 -1
  37. package/dist/_chunks/{PkToolShowVideo-BgKxdBcC.js → PkToolShowVideo-S9b4QHUj.js} +2 -2
  38. package/dist/_chunks/{PkToolShowVideo-BgKxdBcC.js.map → PkToolShowVideo-S9b4QHUj.js.map} +1 -1
  39. package/dist/_chunks/{PkToolShowWeather-LPd3tC77.js → PkToolShowWeather-CqhG430w.js} +2 -2
  40. package/dist/_chunks/{PkToolShowWeather-LPd3tC77.js.map → PkToolShowWeather-CqhG430w.js.map} +1 -1
  41. package/dist/_chunks/{PkToolShowWebPages-ep_erFF0.js → PkToolShowWebPages-txAZi_iG.js} +3 -3
  42. package/dist/_chunks/{PkToolShowWebPages-ep_erFF0.js.map → PkToolShowWebPages-txAZi_iG.js.map} +1 -1
  43. package/dist/_chunks/{VvCheckboxGroup.es-Bdu2gFLN.js → VvCheckboxGroup.es-CTrF3pue.js} +2 -2
  44. package/dist/_chunks/{VvCheckboxGroup.es-Bdu2gFLN.js.map → VvCheckboxGroup.es-CTrF3pue.js.map} +1 -1
  45. package/dist/_chunks/{VvCombobox.es-C0wpJIr_.js → VvCombobox.es-BWiXmQ_S.js} +10 -10
  46. package/dist/_chunks/{VvCombobox.es-C0wpJIr_.js.map → VvCombobox.es-BWiXmQ_S.js.map} +1 -1
  47. package/dist/_chunks/{VvInputText.es-Zgtw2YNw.js → VvInputText.es-Bo9I6g8H.js} +6 -6
  48. package/dist/_chunks/{VvInputText.es-Zgtw2YNw.js.map → VvInputText.es-Bo9I6g8H.js.map} +1 -1
  49. package/dist/_chunks/{VvRadioGroup.es-DZLL19SC.js → VvRadioGroup.es-9ooHCuik.js} +2 -2
  50. package/dist/_chunks/{VvRadioGroup.es-DZLL19SC.js.map → VvRadioGroup.es-9ooHCuik.js.map} +1 -1
  51. package/dist/_chunks/{VvSelect.es-ovnZRHG5.js → VvSelect.es-DG0VuWtP.js} +2 -2
  52. package/dist/_chunks/{VvSelect.es-ovnZRHG5.js.map → VvSelect.es-DG0VuWtP.js.map} +1 -1
  53. package/dist/_chunks/{VvTextarea.es-DbP5Lt2T.js → VvTextarea.es-Dg3pxdZy.js} +6 -6
  54. package/dist/_chunks/{VvTextarea.es-DbP5Lt2T.js.map → VvTextarea.es-Dg3pxdZy.js.map} +1 -1
  55. package/dist/_chunks/{dist-n5iFNYf-.js → dist-QdjZA6MJ.js} +143 -133
  56. package/dist/_chunks/{dist-n5iFNYf-.js.map → dist-QdjZA6MJ.js.map} +1 -1
  57. package/dist/_chunks/{index.es-dtdl3VFG.js → index.es-0YpCa4c5.js} +6 -6
  58. package/dist/_chunks/{index.es-dtdl3VFG.js.map → index.es-0YpCa4c5.js.map} +1 -1
  59. package/dist/_chunks/{index.es-BJnUA_36.js → index.es-CHkJ2TMJ.js} +10 -10
  60. package/dist/_chunks/{index.es-BJnUA_36.js.map → index.es-CHkJ2TMJ.js.map} +1 -1
  61. package/dist/ai-elements.es.js +1956 -1944
  62. package/dist/ai-elements.es.js.map +1 -1
  63. package/dist-vue/PkChatbot.js +1 -1
  64. package/dist-vue/PkChatbotEmptyState.js +1 -1
  65. package/dist-vue/PkChatbotInput.js +1 -1
  66. package/dist-vue/PkChatbotMessages.js +1 -1
  67. package/dist-vue/PkChatbotStepPayload.js +1 -1
  68. package/dist-vue/PkChatbotStepToolDetail.js +1 -1
  69. package/dist-vue/PkChatbotSteps.js +1 -1
  70. package/dist-vue/PkChatbotViewChat.js +1 -1
  71. package/dist-vue/_chunks/{PkChatbot-Di7R2CWN.js → PkChatbot-DE1bKmDi.js} +57 -57
  72. package/dist-vue/_chunks/{PkChatbot-Di7R2CWN.js.map → PkChatbot-DE1bKmDi.js.map} +1 -1
  73. package/dist-vue/_chunks/{PkChatbotEmptyState-C_ITdvH7.js → PkChatbotEmptyState-BtzBYOHJ.js} +2 -2
  74. package/dist-vue/_chunks/{PkChatbotEmptyState-C_ITdvH7.js.map → PkChatbotEmptyState-BtzBYOHJ.js.map} +1 -1
  75. package/dist-vue/_chunks/{PkChatbotInput-pEl3D2O-.js → PkChatbotInput-MSpF6SB6.js} +2 -2
  76. package/dist-vue/_chunks/{PkChatbotInput-pEl3D2O-.js.map → PkChatbotInput-MSpF6SB6.js.map} +1 -1
  77. package/dist-vue/_chunks/PkChatbotMessages-B6ONEJnZ.js +776 -0
  78. package/dist-vue/_chunks/PkChatbotMessages-B6ONEJnZ.js.map +1 -0
  79. package/dist-vue/_chunks/{PkChatbotStepPayload-BH6piqOi.js → PkChatbotStepPayload-XW4gT9AZ.js} +2 -2
  80. package/dist-vue/_chunks/{PkChatbotStepPayload-BH6piqOi.js.map → PkChatbotStepPayload-XW4gT9AZ.js.map} +1 -1
  81. package/dist-vue/_chunks/{PkChatbotStepToolDetail-BJ7xUvgi.js → PkChatbotStepToolDetail-C4-K6Glw.js} +3 -3
  82. package/dist-vue/_chunks/{PkChatbotStepToolDetail-BJ7xUvgi.js.map → PkChatbotStepToolDetail-C4-K6Glw.js.map} +1 -1
  83. package/dist-vue/_chunks/PkChatbotSteps-CrqjWpv0.js +190 -0
  84. package/dist-vue/_chunks/PkChatbotSteps-CrqjWpv0.js.map +1 -0
  85. package/dist-vue/_chunks/{PkChatbotViewChat-DT-rAU_r.js → PkChatbotViewChat-BMQtx1Gi.js} +9 -9
  86. package/dist-vue/_chunks/{PkChatbotViewChat-DT-rAU_r.js.map → PkChatbotViewChat-BMQtx1Gi.js.map} +1 -1
  87. package/dist-vue/_chunks/{PkStreamingMarkdown-DIaZEedG.js → PkStreamingMarkdown-D0IOaETI.js} +362 -359
  88. package/dist-vue/_chunks/PkStreamingMarkdown-D0IOaETI.js.map +1 -0
  89. package/dist-vue/_chunks/{PkToolShowArtifact-BCCUucVQ.js → PkToolShowArtifact-DHdJuzDi.js} +2 -2
  90. package/dist-vue/_chunks/{PkToolShowArtifact-BCCUucVQ.js.map → PkToolShowArtifact-DHdJuzDi.js.map} +1 -1
  91. package/dist-vue/_chunks/{PkToolShowContactForm-BXGxWSc2.js → PkToolShowContactForm-BB2X4UdQ.js} +2 -2
  92. package/dist-vue/_chunks/{PkToolShowContactForm-BXGxWSc2.js.map → PkToolShowContactForm-BB2X4UdQ.js.map} +1 -1
  93. package/dist-vue/_chunks/{PkToolShowDiagram-CZgrWvBr.js → PkToolShowDiagram-BH6ihikd.js} +2 -2
  94. package/dist-vue/_chunks/{PkToolShowDiagram-CZgrWvBr.js.map → PkToolShowDiagram-BH6ihikd.js.map} +1 -1
  95. package/dist-vue/_chunks/{PkToolShowEmail-DpC517Vn.js → PkToolShowEmail-DF__nKpR.js} +2 -2
  96. package/dist-vue/_chunks/{PkToolShowEmail-DpC517Vn.js.map → PkToolShowEmail-DF__nKpR.js.map} +1 -1
  97. package/dist-vue/_chunks/{PkToolShowForm-CIZpfAGK.js → PkToolShowForm-DUKIyj9V.js} +5 -5
  98. package/dist-vue/_chunks/{PkToolShowForm-CIZpfAGK.js.map → PkToolShowForm-DUKIyj9V.js.map} +1 -1
  99. package/dist-vue/_chunks/{PkToolShowMessage-B7flxVCU.js → PkToolShowMessage-Ck6VP-gw.js} +2 -2
  100. package/dist-vue/_chunks/{PkToolShowMessage-B7flxVCU.js.map → PkToolShowMessage-Ck6VP-gw.js.map} +1 -1
  101. package/dist-vue/_chunks/{PkToolShowProductList-B6fRtIpx.js → PkToolShowProductList-zfM8cx-l.js} +2 -2
  102. package/dist-vue/_chunks/{PkToolShowProductList-B6fRtIpx.js.map → PkToolShowProductList-zfM8cx-l.js.map} +1 -1
  103. package/dist-vue/_chunks/{PkToolShowSources-DDZokZow.js → PkToolShowSources-Dlaz2Y77.js} +3 -3
  104. package/dist-vue/_chunks/{PkToolShowSources-DDZokZow.js.map → PkToolShowSources-Dlaz2Y77.js.map} +1 -1
  105. package/dist-vue/_chunks/{PkToolShowWebPages-DY48ee6V.js → PkToolShowWebPages-CosBYLrE.js} +2 -2
  106. package/dist-vue/_chunks/{PkToolShowWebPages-DY48ee6V.js.map → PkToolShowWebPages-CosBYLrE.js.map} +1 -1
  107. package/dist-vue/_chunks/{PkUrl-DSGxrEM7.js → PkUrl-B5CNTQj9.js} +2 -2
  108. package/dist-vue/_chunks/{PkUrl-DSGxrEM7.js.map → PkUrl-B5CNTQj9.js.map} +1 -1
  109. package/dist-vue/_chunks/{utils-Coqik0XI.js → utils-C1666_6C.js} +58 -43
  110. package/dist-vue/_chunks/utils-C1666_6C.js.map +1 -0
  111. package/dist-vue/composables.js +1 -1
  112. package/dist-vue/index.js +38 -38
  113. package/dist-vue/packages/components/src/chat/PkStreamingMarkdown.d.ts +6 -0
  114. package/dist-vue/packages/components/src/chat/PkStreamingMarkdownAutoscroll.d.ts +1 -0
  115. package/dist-vue/packages/components/src/chat/utils.d.ts +16 -0
  116. package/package.json +1 -1
  117. package/dist/_chunks/PkStreamingMarkdown-DgBS4Ebc.js.map +0 -1
  118. package/dist/_chunks/utils-YJ0ZOLDG.js +0 -185
  119. package/dist/_chunks/utils-YJ0ZOLDG.js.map +0 -1
  120. package/dist-vue/_chunks/PkChatbotMessages-CGALOKwe.js +0 -771
  121. package/dist-vue/_chunks/PkChatbotMessages-CGALOKwe.js.map +0 -1
  122. package/dist-vue/_chunks/PkChatbotSteps-BhFupvbz.js +0 -180
  123. package/dist-vue/_chunks/PkChatbotSteps-BhFupvbz.js.map +0 -1
  124. package/dist-vue/_chunks/PkStreamingMarkdown-DIaZEedG.js.map +0 -1
  125. package/dist-vue/_chunks/utils-Coqik0XI.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PkChatbotSteps-CrqjWpv0.js","names":[],"sources":["../../../../packages/components/src/chat/PkStreamingMarkdownAutoscroll.vue","../../../../packages/components/src/chat/PkStreamingMarkdownAutoscroll.vue","../../../../packages/components/src/chat/PkChatbotSteps.vue","../../../../packages/components/src/chat/PkChatbotSteps.vue"],"sourcesContent":["<script lang=\"ts\" setup>\n import { ref } from 'vue'\n import { useResizeObserver } from '@vueuse/core'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n\n defineProps<{\n markdown?: string\n innerClass?: string\n isDark?: boolean\n tailLength?: number\n }>()\n\n // Within this distance of the bottom the reader counts as being there.\n const NEAR_BOTTOM_PX = 8\n\n const scrollEl = ref<HTMLDivElement>()\n const contentEl = ref<InstanceType<typeof PkStreamingMarkdown>>()\n let stopAutoScroll = false\n // Where the last follow left the box: a scroll event reporting it is the\n // box's own, even when the content grew in the meantime.\n let followedTop: number | undefined\n\n // The follow stops when the reader leaves the bottom and resumes when they\n // are back. Measured from the bottom, not from the previous position: a\n // tail slides, so its height shrinks as often as it grows, and a shrink\n // moves the position up without the reader doing anything.\n const handleScroll = () => {\n const el = scrollEl.value\n if (!el || el.scrollTop === followedTop) {\n return\n }\n followedTop = undefined\n stopAutoScroll =\n el.scrollHeight - el.clientHeight - el.scrollTop > NEAR_BOTTOM_PX\n }\n\n // Driven by sizes, not by the prop: the markdown renders at most once per\n // interval, code, formulas and images grow after it, and the box itself\n // can be resized.\n const scrollToBottom = () => {\n const el = scrollEl.value\n if (!el) {\n return\n }\n // Content that fits leaves nothing to have scrolled away from, and no\n // scroll event would ever say the reader is back.\n if (el.scrollHeight <= el.clientHeight) {\n stopAutoScroll = false\n }\n if (stopAutoScroll) {\n return\n }\n el.scrollTop = el.scrollHeight\n followedTop = el.scrollTop\n }\n\n useResizeObserver([scrollEl, contentEl], scrollToBottom)\n</script>\n\n<template>\n <div\n ref=\"scrollEl\"\n class=\"overflow-auto light-scrollbar\"\n @scroll=\"handleScroll\">\n <PkStreamingMarkdown\n ref=\"contentEl\"\n :markdown\n :is-dark\n :tail-length\n :class=\"innerClass\" />\n </div>\n</template>\n","<script lang=\"ts\" setup>\n import { ref } from 'vue'\n import { useResizeObserver } from '@vueuse/core'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n\n defineProps<{\n markdown?: string\n innerClass?: string\n isDark?: boolean\n tailLength?: number\n }>()\n\n // Within this distance of the bottom the reader counts as being there.\n const NEAR_BOTTOM_PX = 8\n\n const scrollEl = ref<HTMLDivElement>()\n const contentEl = ref<InstanceType<typeof PkStreamingMarkdown>>()\n let stopAutoScroll = false\n // Where the last follow left the box: a scroll event reporting it is the\n // box's own, even when the content grew in the meantime.\n let followedTop: number | undefined\n\n // The follow stops when the reader leaves the bottom and resumes when they\n // are back. Measured from the bottom, not from the previous position: a\n // tail slides, so its height shrinks as often as it grows, and a shrink\n // moves the position up without the reader doing anything.\n const handleScroll = () => {\n const el = scrollEl.value\n if (!el || el.scrollTop === followedTop) {\n return\n }\n followedTop = undefined\n stopAutoScroll =\n el.scrollHeight - el.clientHeight - el.scrollTop > NEAR_BOTTOM_PX\n }\n\n // Driven by sizes, not by the prop: the markdown renders at most once per\n // interval, code, formulas and images grow after it, and the box itself\n // can be resized.\n const scrollToBottom = () => {\n const el = scrollEl.value\n if (!el) {\n return\n }\n // Content that fits leaves nothing to have scrolled away from, and no\n // scroll event would ever say the reader is back.\n if (el.scrollHeight <= el.clientHeight) {\n stopAutoScroll = false\n }\n if (stopAutoScroll) {\n return\n }\n el.scrollTop = el.scrollHeight\n followedTop = el.scrollTop\n }\n\n useResizeObserver([scrollEl, contentEl], scrollToBottom)\n</script>\n\n<template>\n <div\n ref=\"scrollEl\"\n class=\"overflow-auto light-scrollbar\"\n @scroll=\"handleScroll\">\n <PkStreamingMarkdown\n ref=\"contentEl\"\n :markdown\n :is-dark\n :tail-length\n :class=\"innerClass\" />\n </div>\n</template>\n","<script lang=\"ts\" setup>\n import { computed, reactive, ref, watch } from 'vue'\n import { useI18n } from 'vue-i18n'\n import type { UIChatMessage } from 'models'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n import PkStreamingMarkdownAutoscroll from './PkStreamingMarkdownAutoscroll.vue'\n import PkChatbotStepToolDetail from './PkChatbotStepToolDetail.vue'\n import PkChatbotStepPayload from './PkChatbotStepPayload.vue'\n import {\n isReasoningPart,\n isToolPart,\n getPartIcon,\n getPartState,\n getToolPartLabel,\n getToolPartSummary,\n hasRichToolDetail,\n hasPayload,\n formatDuration as formatDurationWith,\n LIVE_REASONING_TAIL_LENGTH,\n } from './utils'\n\n const props = defineProps<{\n message: UIChatMessage\n isStreaming?: boolean\n isDark?: boolean\n }>()\n\n const { t: $t, n: $n } = useI18n({\n useScope: 'global',\n })\n\n type MessagePart = UIChatMessage['parts'][number]\n\n interface Step {\n key: string\n part: MessagePart\n icon?: string\n label?: string\n summary?: string\n durationMs?: number\n isActive: boolean\n text?: string\n error?: string\n hasRichDetail: boolean\n hasBody: boolean\n toolInput?: unknown\n toolOutput?: unknown\n }\n\n const getStepError = (part: MessagePart) =>\n getPartState(part) === 'output-error' &&\n 'errorText' in part &&\n typeof part.errorText === 'string'\n ? part.errorText\n : undefined\n\n // What the step header needs is decided here, once per recomputation.\n // `hasBody` was a function the template called six times per step, and\n // `steps` recomputes at every delta of the stream: on a tool answering\n // hundreds of kilobytes, where the answer comes from `hasPayload` and\n // `hasPayload` serializes the whole payload to find out, that is the same\n // JSON.stringify six times for one boolean.\n //\n // The two payload blocks keep asking for themselves, because they render\n // only inside an expanded step: deciding here whether to show the output\n // would serialize it for every step the reader never opens, which is all\n // of them by default.\n const steps = computed<Step[]>(() => {\n const parts = props.message.parts\n const partTimings = props.message.metadata?.partTimings\n const result: Step[] = []\n for (const [index, part] of parts.entries()) {\n const isReasoning = isReasoningPart(part)\n const isTool = isToolPart(part)\n if (!isReasoning && !isTool) {\n continue\n }\n const toolCallId =\n 'toolCallId' in part ? (part.toolCallId as string) : undefined\n const text = isReasoning && part.text.trim() ? part.text : undefined\n const error = getStepError(part)\n const hasRichDetail = hasRichToolDetail(part)\n const toolInput = isTool && 'input' in part ? part.input : undefined\n const toolOutput =\n isTool && 'output' in part ? part.output : undefined\n result.push({\n key: toolCallId ?? `${part.type}-${index}`,\n part,\n icon: getPartIcon(part),\n label: getToolPartLabel($t, part),\n summary: getToolPartSummary(part),\n durationMs: toolCallId ? partTimings?.[toolCallId] : undefined,\n isActive:\n Boolean(props.isStreaming) && index === parts.length - 1,\n text,\n error,\n hasRichDetail,\n // The `||` short-circuits as the old function did: a tool\n // with an input never serializes its output to answer this.\n hasBody: Boolean(\n text ||\n error ||\n (hasRichDetail\n ? toolInput !== undefined || toolOutput !== undefined\n : hasPayload(toolInput) || hasPayload(toolOutput)),\n ),\n toolInput,\n toolOutput,\n })\n }\n return result\n })\n\n const totalDurationMs = computed(() => {\n const { createdAt, completedAt } = props.message.metadata ?? {}\n if (!createdAt || !completedAt) {\n return undefined\n }\n return completedAt - createdAt\n })\n\n const formatDuration = (ms?: number) => formatDurationWith($n, ms)\n\n // --- Expand / collapse ---\n // Every step starts closed, the running one included: the timeline says\n // what the answer is doing, the body is opened only when asked for. The\n // reasoning of the active step still follows the stream once opened.\n const manualSteps = reactive(new Map<string, boolean>())\n const isStepExpanded = (step: Step) => manualSteps.get(step.key) ?? false\n const toggleStep = (step: Step) => {\n manualSteps.set(step.key, !isStepExpanded(step))\n }\n\n // The group is open while streaming and collapses to its header once the\n // answer is complete, unless the user toggled it manually.\n const manualGroup = ref<boolean | undefined>(undefined)\n const isGroupExpanded = computed(\n () => manualGroup.value ?? Boolean(props.isStreaming),\n )\n // Reset the manual override when a new stream starts so the timeline\n // opens again on regenerate.\n watch(\n () => props.isStreaming,\n (streaming) => {\n if (streaming) {\n manualGroup.value = undefined\n manualSteps.clear()\n }\n },\n )\n</script>\n\n<template>\n <div v-if=\"steps.length\" class=\"pk-chatbot-steps\">\n <button\n type=\"button\"\n class=\"pk-chatbot-steps__header\"\n :aria-expanded=\"isGroupExpanded\"\n @click=\"manualGroup = !isGroupExpanded\">\n <VvIcon v-if=\"isStreaming\" name=\"loading-loop\" class=\"shrink-0\" />\n <VvIcon v-else name=\"ri:route-line\" class=\"shrink-0\" />\n <span class=\"pk-chatbot-steps__title\">\n {{ $t('messagePart.steps') }}\n </span>\n <span class=\"pk-chatbot-steps__meta\">\n {{ $t('messagePart.stepCount', steps.length) }}\n <template v-if=\"formatDuration(totalDurationMs)\">\n · {{ formatDuration(totalDurationMs) }}\n </template>\n </span>\n <VvIcon\n :name=\"\n isGroupExpanded\n ? 'ri:arrow-up-s-line'\n : 'ri:arrow-down-s-line'\n \"\n class=\"pk-chatbot-steps__chevron shrink-0 ml-auto\" />\n </button>\n <ol v-if=\"isGroupExpanded\" class=\"pk-chatbot-steps__list\">\n <li\n v-for=\"step in steps\"\n :key=\"step.key\"\n class=\"pk-chatbot-steps__step\"\n :class=\"{\n 'pk-chatbot-steps__step--active': step.isActive,\n }\">\n <component\n :is=\"step.hasBody ? 'button' : 'div'\"\n :type=\"step.hasBody ? 'button' : undefined\"\n class=\"pk-chatbot-steps__step-header\"\n :aria-expanded=\"\n step.hasBody ? isStepExpanded(step) : undefined\n \"\n @click=\"step.hasBody ? toggleStep(step) : undefined\">\n <span\n class=\"pk-chatbot-steps-marker\"\n :class=\"{\n 'pk-chatbot-steps-marker--active': step.isActive,\n }\">\n <VvIcon v-if=\"step.isActive\" name=\"loading-loop\" />\n <VvIcon v-else-if=\"step.icon\" :name=\"step.icon\" />\n </span>\n <span class=\"pk-chatbot-steps__step-label\">\n {{ step.label }}\n </span>\n <span class=\"pk-chatbot-steps__step-summary\">\n {{ step.summary }}\n </span>\n <span\n v-if=\"formatDuration(step.durationMs)\"\n class=\"pk-chatbot-steps__step-duration\">\n {{ formatDuration(step.durationMs) }}\n </span>\n <VvIcon\n v-if=\"step.hasBody\"\n :name=\"\n isStepExpanded(step)\n ? 'ri:arrow-up-s-line'\n : 'ri:arrow-down-s-line'\n \"\n class=\"pk-chatbot-steps__chevron shrink-0 ml-auto\" />\n </component>\n <div\n v-if=\"step.hasBody && isStepExpanded(step)\"\n class=\"pk-chatbot-steps__step-body\">\n <PkStreamingMarkdownAutoscroll\n v-if=\"step.text && step.isActive\"\n :markdown=\"step.text\"\n :is-dark\n :tail-length=\"LIVE_REASONING_TAIL_LENGTH\"\n inner-class=\"wysiwyg\"\n class=\"pk-chatbot-steps__step-content pk-chatbot-steps__step-content--scroll\" />\n <div\n v-else-if=\"step.text\"\n class=\"pk-chatbot-steps__step-content pk-chatbot-steps__step-content--scroll light-scrollbar\">\n <PkStreamingMarkdown\n :markdown=\"step.text\"\n :is-dark\n class=\"wysiwyg\" />\n </div>\n <div\n v-else-if=\"step.error\"\n class=\"pk-chatbot-steps__step-payload pk-chatbot-steps__step-payload--error\">\n <span class=\"pk-chatbot-steps__step-payload-label\">\n {{ $t('messagePart.stepError') }}\n </span>\n <pre>{{ step.error }}</pre>\n </div>\n <PkChatbotStepToolDetail\n v-else-if=\"step.hasRichDetail\"\n :part=\"step.part\" />\n <template v-else>\n <PkChatbotStepPayload\n v-if=\"hasPayload(step.toolInput)\"\n :label=\"$t('messagePart.stepInput')\"\n :value=\"step.toolInput\" />\n <PkChatbotStepPayload\n v-if=\"hasPayload(step.toolOutput)\"\n :label=\"$t('messagePart.stepOutput')\"\n :value=\"step.toolOutput\" />\n </template>\n </div>\n </li>\n </ol>\n </div>\n</template>\n\n<style lang=\"scss\">\n .pk-chatbot-steps {\n width: 100%;\n border: var(--spacing-px) solid var(--color-surface-3);\n border-radius: var(--rounded-lg);\n background-color: var(--color-surface-1);\n font-size: var(--text-12);\n color: var(--color-word-3);\n overflow: hidden;\n\n &__header {\n display: flex;\n align-items: center;\n gap: var(--spacing-8);\n width: 100%;\n min-height: var(--spacing-40);\n padding: var(--spacing-8) var(--spacing-sm);\n text-align: left;\n cursor: pointer;\n transition: background-color 0.2s ease;\n\n &:hover {\n background-color: var(--color-surface-2);\n }\n }\n\n &__chevron {\n font-size: var(--text-16);\n }\n\n &__title {\n font-weight: 600;\n color: var(--color-word-2);\n flex-grow: 1;\n }\n\n &__meta {\n color: var(--color-word-4);\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n }\n\n &__list {\n background-color: var(--color-surface);\n border-top: var(--spacing-px) solid var(--color-surface-3);\n padding: var(--spacing-8) var(--spacing-sm);\n display: flex;\n flex-direction: column;\n }\n\n &__step {\n position: relative;\n\n // Vertical connector between step markers\n &:not(:last-child)::before {\n content: '';\n position: absolute;\n left: var(--spacing-10);\n top: var(--spacing-28);\n bottom: calc(var(--spacing-8) * -1);\n width: var(--spacing-px);\n background-color: var(--color-surface-4);\n }\n }\n\n &__step-header {\n display: flex;\n align-items: center;\n gap: var(--spacing-8);\n width: calc(100% + var(--spacing-16));\n min-height: var(--spacing-36);\n margin-inline: calc(var(--spacing-8) * -1);\n padding: var(--spacing-4) var(--spacing-8);\n text-align: left;\n\n &:is(button) {\n cursor: pointer;\n border-radius: var(--rounded);\n transition: background-color 0.2s ease;\n\n &:hover {\n background-color: var(--color-surface-2);\n }\n }\n }\n\n &-marker {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--spacing-20);\n height: var(--spacing-20);\n flex-shrink: 0;\n position: relative;\n z-index: 1;\n background-color: var(--color-surface-1);\n border-radius: var(--rounded-full);\n border: var(--spacing-px) solid var(--color-surface-4);\n\n &--active {\n background-color: var(\n --chatbot-main-color,\n var(--color-surface-4)\n );\n border-color: transparent;\n color: var(--chatbot-contrast-color, var(--color-word-1));\n }\n }\n\n &__step-label {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--color-word-2);\n }\n\n &__step-summary {\n flex: 1 1 0;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--color-word-4);\n }\n\n &__step-duration {\n color: var(--color-word-4);\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n }\n\n &__step--active &__step-label {\n color: var(--color-word-1);\n }\n\n &__step-body {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-4);\n margin-left: var(--spacing-28);\n margin-block: var(--spacing-4) var(--spacing-8);\n }\n\n &__step-content {\n border: var(--spacing-px) solid var(--color-surface-3);\n border-radius: var(--rounded);\n padding: var(--spacing-8);\n background-color: var(--color-surface-1);\n\n // The finished reasoning keeps the cap the streaming one had:\n // `.wysiwyg` hides its own overflow, so the scroll belongs to the\n // wrapper, exactly as in the autoscroll variant.\n &--scroll {\n max-height: var(--spacing-256);\n overflow: auto;\n }\n }\n\n &__step-payload {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-2);\n\n pre {\n border: var(--spacing-px) solid var(--color-surface-3);\n border-radius: var(--rounded);\n padding: var(--spacing-8);\n font-size: var(--text-10);\n max-height: var(--spacing-160);\n overflow: auto;\n white-space: pre-wrap;\n word-break: break-word;\n font-family: var(--font-mono);\n background-color: var(--color-surface-1);\n }\n }\n\n &__step-payload-label {\n font-weight: 600;\n color: var(--color-word-3);\n text-transform: uppercase;\n font-size: var(--text-10);\n letter-spacing: 0.05em;\n }\n\n &__step-payload--error {\n .pk-chatbot-steps__step-payload-label,\n pre {\n color: var(--color-danger);\n }\n\n pre {\n border-color: var(--color-danger-lighten-5);\n }\n }\n }\n</style>\n","<script lang=\"ts\" setup>\n import { computed, reactive, ref, watch } from 'vue'\n import { useI18n } from 'vue-i18n'\n import type { UIChatMessage } from 'models'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n import PkStreamingMarkdownAutoscroll from './PkStreamingMarkdownAutoscroll.vue'\n import PkChatbotStepToolDetail from './PkChatbotStepToolDetail.vue'\n import PkChatbotStepPayload from './PkChatbotStepPayload.vue'\n import {\n isReasoningPart,\n isToolPart,\n getPartIcon,\n getPartState,\n getToolPartLabel,\n getToolPartSummary,\n hasRichToolDetail,\n hasPayload,\n formatDuration as formatDurationWith,\n LIVE_REASONING_TAIL_LENGTH,\n } from './utils'\n\n const props = defineProps<{\n message: UIChatMessage\n isStreaming?: boolean\n isDark?: boolean\n }>()\n\n const { t: $t, n: $n } = useI18n({\n useScope: 'global',\n })\n\n type MessagePart = UIChatMessage['parts'][number]\n\n interface Step {\n key: string\n part: MessagePart\n icon?: string\n label?: string\n summary?: string\n durationMs?: number\n isActive: boolean\n text?: string\n error?: string\n hasRichDetail: boolean\n hasBody: boolean\n toolInput?: unknown\n toolOutput?: unknown\n }\n\n const getStepError = (part: MessagePart) =>\n getPartState(part) === 'output-error' &&\n 'errorText' in part &&\n typeof part.errorText === 'string'\n ? part.errorText\n : undefined\n\n // What the step header needs is decided here, once per recomputation.\n // `hasBody` was a function the template called six times per step, and\n // `steps` recomputes at every delta of the stream: on a tool answering\n // hundreds of kilobytes, where the answer comes from `hasPayload` and\n // `hasPayload` serializes the whole payload to find out, that is the same\n // JSON.stringify six times for one boolean.\n //\n // The two payload blocks keep asking for themselves, because they render\n // only inside an expanded step: deciding here whether to show the output\n // would serialize it for every step the reader never opens, which is all\n // of them by default.\n const steps = computed<Step[]>(() => {\n const parts = props.message.parts\n const partTimings = props.message.metadata?.partTimings\n const result: Step[] = []\n for (const [index, part] of parts.entries()) {\n const isReasoning = isReasoningPart(part)\n const isTool = isToolPart(part)\n if (!isReasoning && !isTool) {\n continue\n }\n const toolCallId =\n 'toolCallId' in part ? (part.toolCallId as string) : undefined\n const text = isReasoning && part.text.trim() ? part.text : undefined\n const error = getStepError(part)\n const hasRichDetail = hasRichToolDetail(part)\n const toolInput = isTool && 'input' in part ? part.input : undefined\n const toolOutput =\n isTool && 'output' in part ? part.output : undefined\n result.push({\n key: toolCallId ?? `${part.type}-${index}`,\n part,\n icon: getPartIcon(part),\n label: getToolPartLabel($t, part),\n summary: getToolPartSummary(part),\n durationMs: toolCallId ? partTimings?.[toolCallId] : undefined,\n isActive:\n Boolean(props.isStreaming) && index === parts.length - 1,\n text,\n error,\n hasRichDetail,\n // The `||` short-circuits as the old function did: a tool\n // with an input never serializes its output to answer this.\n hasBody: Boolean(\n text ||\n error ||\n (hasRichDetail\n ? toolInput !== undefined || toolOutput !== undefined\n : hasPayload(toolInput) || hasPayload(toolOutput)),\n ),\n toolInput,\n toolOutput,\n })\n }\n return result\n })\n\n const totalDurationMs = computed(() => {\n const { createdAt, completedAt } = props.message.metadata ?? {}\n if (!createdAt || !completedAt) {\n return undefined\n }\n return completedAt - createdAt\n })\n\n const formatDuration = (ms?: number) => formatDurationWith($n, ms)\n\n // --- Expand / collapse ---\n // Every step starts closed, the running one included: the timeline says\n // what the answer is doing, the body is opened only when asked for. The\n // reasoning of the active step still follows the stream once opened.\n const manualSteps = reactive(new Map<string, boolean>())\n const isStepExpanded = (step: Step) => manualSteps.get(step.key) ?? false\n const toggleStep = (step: Step) => {\n manualSteps.set(step.key, !isStepExpanded(step))\n }\n\n // The group is open while streaming and collapses to its header once the\n // answer is complete, unless the user toggled it manually.\n const manualGroup = ref<boolean | undefined>(undefined)\n const isGroupExpanded = computed(\n () => manualGroup.value ?? Boolean(props.isStreaming),\n )\n // Reset the manual override when a new stream starts so the timeline\n // opens again on regenerate.\n watch(\n () => props.isStreaming,\n (streaming) => {\n if (streaming) {\n manualGroup.value = undefined\n manualSteps.clear()\n }\n },\n )\n</script>\n\n<template>\n <div v-if=\"steps.length\" class=\"pk-chatbot-steps\">\n <button\n type=\"button\"\n class=\"pk-chatbot-steps__header\"\n :aria-expanded=\"isGroupExpanded\"\n @click=\"manualGroup = !isGroupExpanded\">\n <VvIcon v-if=\"isStreaming\" name=\"loading-loop\" class=\"shrink-0\" />\n <VvIcon v-else name=\"ri:route-line\" class=\"shrink-0\" />\n <span class=\"pk-chatbot-steps__title\">\n {{ $t('messagePart.steps') }}\n </span>\n <span class=\"pk-chatbot-steps__meta\">\n {{ $t('messagePart.stepCount', steps.length) }}\n <template v-if=\"formatDuration(totalDurationMs)\">\n · {{ formatDuration(totalDurationMs) }}\n </template>\n </span>\n <VvIcon\n :name=\"\n isGroupExpanded\n ? 'ri:arrow-up-s-line'\n : 'ri:arrow-down-s-line'\n \"\n class=\"pk-chatbot-steps__chevron shrink-0 ml-auto\" />\n </button>\n <ol v-if=\"isGroupExpanded\" class=\"pk-chatbot-steps__list\">\n <li\n v-for=\"step in steps\"\n :key=\"step.key\"\n class=\"pk-chatbot-steps__step\"\n :class=\"{\n 'pk-chatbot-steps__step--active': step.isActive,\n }\">\n <component\n :is=\"step.hasBody ? 'button' : 'div'\"\n :type=\"step.hasBody ? 'button' : undefined\"\n class=\"pk-chatbot-steps__step-header\"\n :aria-expanded=\"\n step.hasBody ? isStepExpanded(step) : undefined\n \"\n @click=\"step.hasBody ? toggleStep(step) : undefined\">\n <span\n class=\"pk-chatbot-steps-marker\"\n :class=\"{\n 'pk-chatbot-steps-marker--active': step.isActive,\n }\">\n <VvIcon v-if=\"step.isActive\" name=\"loading-loop\" />\n <VvIcon v-else-if=\"step.icon\" :name=\"step.icon\" />\n </span>\n <span class=\"pk-chatbot-steps__step-label\">\n {{ step.label }}\n </span>\n <span class=\"pk-chatbot-steps__step-summary\">\n {{ step.summary }}\n </span>\n <span\n v-if=\"formatDuration(step.durationMs)\"\n class=\"pk-chatbot-steps__step-duration\">\n {{ formatDuration(step.durationMs) }}\n </span>\n <VvIcon\n v-if=\"step.hasBody\"\n :name=\"\n isStepExpanded(step)\n ? 'ri:arrow-up-s-line'\n : 'ri:arrow-down-s-line'\n \"\n class=\"pk-chatbot-steps__chevron shrink-0 ml-auto\" />\n </component>\n <div\n v-if=\"step.hasBody && isStepExpanded(step)\"\n class=\"pk-chatbot-steps__step-body\">\n <PkStreamingMarkdownAutoscroll\n v-if=\"step.text && step.isActive\"\n :markdown=\"step.text\"\n :is-dark\n :tail-length=\"LIVE_REASONING_TAIL_LENGTH\"\n inner-class=\"wysiwyg\"\n class=\"pk-chatbot-steps__step-content pk-chatbot-steps__step-content--scroll\" />\n <div\n v-else-if=\"step.text\"\n class=\"pk-chatbot-steps__step-content pk-chatbot-steps__step-content--scroll light-scrollbar\">\n <PkStreamingMarkdown\n :markdown=\"step.text\"\n :is-dark\n class=\"wysiwyg\" />\n </div>\n <div\n v-else-if=\"step.error\"\n class=\"pk-chatbot-steps__step-payload pk-chatbot-steps__step-payload--error\">\n <span class=\"pk-chatbot-steps__step-payload-label\">\n {{ $t('messagePart.stepError') }}\n </span>\n <pre>{{ step.error }}</pre>\n </div>\n <PkChatbotStepToolDetail\n v-else-if=\"step.hasRichDetail\"\n :part=\"step.part\" />\n <template v-else>\n <PkChatbotStepPayload\n v-if=\"hasPayload(step.toolInput)\"\n :label=\"$t('messagePart.stepInput')\"\n :value=\"step.toolInput\" />\n <PkChatbotStepPayload\n v-if=\"hasPayload(step.toolOutput)\"\n :label=\"$t('messagePart.stepOutput')\"\n :value=\"step.toolOutput\" />\n </template>\n </div>\n </li>\n </ol>\n </div>\n</template>\n\n<style lang=\"scss\">\n .pk-chatbot-steps {\n width: 100%;\n border: var(--spacing-px) solid var(--color-surface-3);\n border-radius: var(--rounded-lg);\n background-color: var(--color-surface-1);\n font-size: var(--text-12);\n color: var(--color-word-3);\n overflow: hidden;\n\n &__header {\n display: flex;\n align-items: center;\n gap: var(--spacing-8);\n width: 100%;\n min-height: var(--spacing-40);\n padding: var(--spacing-8) var(--spacing-sm);\n text-align: left;\n cursor: pointer;\n transition: background-color 0.2s ease;\n\n &:hover {\n background-color: var(--color-surface-2);\n }\n }\n\n &__chevron {\n font-size: var(--text-16);\n }\n\n &__title {\n font-weight: 600;\n color: var(--color-word-2);\n flex-grow: 1;\n }\n\n &__meta {\n color: var(--color-word-4);\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n }\n\n &__list {\n background-color: var(--color-surface);\n border-top: var(--spacing-px) solid var(--color-surface-3);\n padding: var(--spacing-8) var(--spacing-sm);\n display: flex;\n flex-direction: column;\n }\n\n &__step {\n position: relative;\n\n // Vertical connector between step markers\n &:not(:last-child)::before {\n content: '';\n position: absolute;\n left: var(--spacing-10);\n top: var(--spacing-28);\n bottom: calc(var(--spacing-8) * -1);\n width: var(--spacing-px);\n background-color: var(--color-surface-4);\n }\n }\n\n &__step-header {\n display: flex;\n align-items: center;\n gap: var(--spacing-8);\n width: calc(100% + var(--spacing-16));\n min-height: var(--spacing-36);\n margin-inline: calc(var(--spacing-8) * -1);\n padding: var(--spacing-4) var(--spacing-8);\n text-align: left;\n\n &:is(button) {\n cursor: pointer;\n border-radius: var(--rounded);\n transition: background-color 0.2s ease;\n\n &:hover {\n background-color: var(--color-surface-2);\n }\n }\n }\n\n &-marker {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--spacing-20);\n height: var(--spacing-20);\n flex-shrink: 0;\n position: relative;\n z-index: 1;\n background-color: var(--color-surface-1);\n border-radius: var(--rounded-full);\n border: var(--spacing-px) solid var(--color-surface-4);\n\n &--active {\n background-color: var(\n --chatbot-main-color,\n var(--color-surface-4)\n );\n border-color: transparent;\n color: var(--chatbot-contrast-color, var(--color-word-1));\n }\n }\n\n &__step-label {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--color-word-2);\n }\n\n &__step-summary {\n flex: 1 1 0;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--color-word-4);\n }\n\n &__step-duration {\n color: var(--color-word-4);\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n }\n\n &__step--active &__step-label {\n color: var(--color-word-1);\n }\n\n &__step-body {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-4);\n margin-left: var(--spacing-28);\n margin-block: var(--spacing-4) var(--spacing-8);\n }\n\n &__step-content {\n border: var(--spacing-px) solid var(--color-surface-3);\n border-radius: var(--rounded);\n padding: var(--spacing-8);\n background-color: var(--color-surface-1);\n\n // The finished reasoning keeps the cap the streaming one had:\n // `.wysiwyg` hides its own overflow, so the scroll belongs to the\n // wrapper, exactly as in the autoscroll variant.\n &--scroll {\n max-height: var(--spacing-256);\n overflow: auto;\n }\n }\n\n &__step-payload {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-2);\n\n pre {\n border: var(--spacing-px) solid var(--color-surface-3);\n border-radius: var(--rounded);\n padding: var(--spacing-8);\n font-size: var(--text-10);\n max-height: var(--spacing-160);\n overflow: auto;\n white-space: pre-wrap;\n word-break: break-word;\n font-family: var(--font-mono);\n background-color: var(--color-surface-1);\n }\n }\n\n &__step-payload-label {\n font-weight: 600;\n color: var(--color-word-3);\n text-transform: uppercase;\n font-size: var(--text-10);\n letter-spacing: 0.05em;\n }\n\n &__step-payload--error {\n .pk-chatbot-steps__step-payload-label,\n pre {\n color: var(--color-danger);\n }\n\n pre {\n border-color: var(--color-danger-lighten-5);\n }\n }\n }\n</style>\n"],"mappings":"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"}
@@ -1,11 +1,11 @@
1
1
  import { a as e, n as t, t as n } from "./useChatbotStore-BzfqjiYz.js";
2
2
  import { t as r } from "./src-DT8FLE4_.js";
3
- import { t as i } from "./PkChatbotMessages-CGALOKwe.js";
3
+ import { t as i } from "./PkChatbotMessages-B6ONEJnZ.js";
4
4
  import { t as a } from "./useLocalizedString-PfaKjIQY.js";
5
- import { t as o } from "./PkAvatar-paEJByEA.js";
6
- import { r as s } from "./utils-Coqik0XI.js";
7
- import { n as c, t as l } from "./PkChatbotInput-pEl3D2O-.js";
8
- import { t as u } from "./PkChatbotEmptyState-C_ITdvH7.js";
5
+ import { i as o } from "./utils-C1666_6C.js";
6
+ import { t as s } from "./PkAvatar-paEJByEA.js";
7
+ import { n as c, t as l } from "./PkChatbotInput-MSpF6SB6.js";
8
+ import { t as u } from "./PkChatbotEmptyState-BtzBYOHJ.js";
9
9
  import { VvIcon as d } from "@volverjs/ui-vue/components";
10
10
  import { Fragment as f, Transition as p, computed as m, createBlock as h, createCommentVNode as g, createElementBlock as _, createElementVNode as v, createSlots as y, createTextVNode as b, createVNode as x, defineAsyncComponent as S, defineComponent as C, isRef as w, nextTick as ee, normalizeClass as T, onBeforeUnmount as te, onMounted as ne, onScopeDispose as re, onUnmounted as ie, openBlock as E, ref as D, renderList as ae, shallowRef as O, toDisplayString as k, toValue as A, unref as j, useTemplateRef as oe, watch as se, withCtx as M } from "vue";
11
11
  import { useI18n as ce } from "vue-i18n";
@@ -408,7 +408,7 @@ var P = {
408
408
  },
409
409
  emits: ["show-info", "revise"],
410
410
  setup(r, { emit: c }) {
411
- let f = S(() => import("./PkToolShowForm-CIZpfAGK.js").then((e) => e.n)), b = S(() => import("./PkToolShowContactForm-BXGxWSc2.js").then((e) => e.n)), C = S(() => import("./PkToolShowSuggestedReply-DWLkUh2L.js").then((e) => e.n)), ee = S(() => import("./PkToolShowSources-DDZokZow.js").then((e) => e.n)), ne = S(() => import("./PkToolRequestGeolocation-Q3N3jlO8.js")), re = S(() => import("./PkToolRequestOAuthConnection-C0LW5Evp.js")), ie = S(() => import("./PkToolShowLocation-Bv6sLN5P.js").then((e) => e.n)), ae = S(() => import("./PkToolShowDiagram-CZgrWvBr.js")), O = r, A = c, N = t(O.agentId), { agentInterface: P, agentFileUpload: F, agentVoice: fe, actions: pe, revisedAnswers: I, messages: he, chat: L, messageFeedbacks: ge, feedbackDialogMessage: _e, isFeedbackSubmitting: ve, isFeedbackSubmitted: ye, feedbackSubmitError: be, isLeadSubmitted: xe, isLoadingSubmitLead: Ne, submitLeadError: Pe, input: R, inputMessagePlaceholder: Fe, isConversationBlocked: Ie, baseUrl: Le, pendingAttachments: Re, isAttachmentLimitReached: ze, fileLimitError: Be, apiClient: z, isDark: Ve } = ue(N), { handleSubmit: He, stopGeneration: Ue, regenerate: We, onUpvote: Ge, onDownvote: Ke, onFeedback: qe, onFeedbackSubmit: Je, onLeadSubmit: Ye, startNewChat: Xe, addToolOutput: B, addToolApprovalResponse: Ze, handleFileSelect: Qe, clearFileLimitError: $e, refreshMessages: et, appendMessage: tt } = N, { t: V } = ce({ useScope: "global" }), nt = m(() => {
411
+ let f = S(() => import("./PkToolShowForm-DUKIyj9V.js").then((e) => e.n)), b = S(() => import("./PkToolShowContactForm-BB2X4UdQ.js").then((e) => e.n)), C = S(() => import("./PkToolShowSuggestedReply-DWLkUh2L.js").then((e) => e.n)), ee = S(() => import("./PkToolShowSources-Dlaz2Y77.js").then((e) => e.n)), ne = S(() => import("./PkToolRequestGeolocation-Q3N3jlO8.js")), re = S(() => import("./PkToolRequestOAuthConnection-C0LW5Evp.js")), ie = S(() => import("./PkToolShowLocation-Bv6sLN5P.js").then((e) => e.n)), ae = S(() => import("./PkToolShowDiagram-BH6ihikd.js")), O = r, A = c, N = t(O.agentId), { agentInterface: P, agentFileUpload: F, agentVoice: fe, actions: pe, revisedAnswers: I, messages: he, chat: L, messageFeedbacks: ge, feedbackDialogMessage: _e, isFeedbackSubmitting: ve, isFeedbackSubmitted: ye, feedbackSubmitError: be, isLeadSubmitted: xe, isLoadingSubmitLead: Ne, submitLeadError: Pe, input: R, inputMessagePlaceholder: Fe, isConversationBlocked: Ie, baseUrl: Le, pendingAttachments: Re, isAttachmentLimitReached: ze, fileLimitError: Be, apiClient: z, isDark: Ve } = ue(N), { handleSubmit: He, stopGeneration: Ue, regenerate: We, onUpvote: Ge, onDownvote: Ke, onFeedback: qe, onFeedbackSubmit: Je, onLeadSubmit: Ye, startNewChat: Xe, addToolOutput: B, addToolApprovalResponse: Ze, handleFileSelect: Qe, clearFileLimitError: $e, refreshMessages: et, appendMessage: tt } = N, { t: V } = ce({ useScope: "global" }), nt = m(() => {
412
412
  let e = Be.value;
413
413
  if (e) return e.reason === "per-chat" ? V("message.fileLimitPerChat", { max: e.max }) : V("message.fileLimitPerMessage", { max: e.max });
414
414
  }), rt = a(() => P.value?.dismissableNotice), it = m(() => he.value.some((e) => e.role === "user")), at = m(() => O.modifier === "fullscreen" && !it.value), ot = de(P, () => O.userName), st = oe("chatViewEl"), ct = async (e) => (await z.value.expandSourceContext(O.agentId, e.documentId, e.chunkIndex)).content, lt = async (e) => {
@@ -499,7 +499,7 @@ var P = {
499
499
  }, Tt = async () => {
500
500
  X.dismissError(), await X.stop(), await St();
501
501
  }, Z = (e) => e?.toolCallId ?? "", Q = D(/* @__PURE__ */ new Set()), Et = (e) => Q.value.has(Z(e)), Dt = D(/* @__PURE__ */ new Map()), $ = (e, t) => X.isActive.value ? !X.sendUserMessage(t) || (Q.value = new Set(Q.value).add(Z(e)), ht(), !0) : !1, Ot = (e, t, n) => {
502
- $(t, s(t, n)) || B({
502
+ $(t, o(t, n)) || B({
503
503
  tool: e,
504
504
  toolCallId: Z(t),
505
505
  output: n
@@ -740,7 +740,7 @@ var P = {
740
740
  onVoiceStart: St
741
741
  }, y({ _: 2 }, [r.modifier === "fullscreen" ? {
742
742
  name: "prepend",
743
- fn: M(() => [v("span", Ee, [x(o, {
743
+ fn: M(() => [v("span", Ee, [x(s, {
744
744
  modifiers: "surface",
745
745
  class: "pk-chatbot-view-chat__agent-chip-avatar",
746
746
  "img-src": j(P)?.logo,
@@ -799,4 +799,4 @@ var P = {
799
799
  //#endregion
800
800
  export { me as i, Se as n, L as r, Ne as t };
801
801
 
802
- //# sourceMappingURL=PkChatbotViewChat-DT-rAU_r.js.map
802
+ //# sourceMappingURL=PkChatbotViewChat-BMQtx1Gi.js.map