@8wave/ai-elements 0.98.0 → 0.99.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -5
- package/dist/_chunks/{PkToolShowForm-BNV4Ja6g.js → PkToolShowForm-dFuoqTPs.js} +84 -80
- package/dist/_chunks/PkToolShowForm-dFuoqTPs.js.map +1 -0
- package/dist/ai-elements.es.js +3153 -2982
- package/dist/ai-elements.es.js.map +1 -1
- package/dist-vue/PkChatbot.js +1 -1
- package/dist-vue/PkChatbotMessages.js +1 -1
- package/dist-vue/PkChatbotStepToolDetail.js +1 -1
- package/dist-vue/PkChatbotSteps.js +1 -1
- package/dist-vue/PkChatbotViewChat.js +1 -1
- package/dist-vue/PkChatbotViewConversations.js +1 -1
- package/dist-vue/PkChatbotViewFiles.js +1 -1
- package/dist-vue/PkChatbotViewProfile.js +1 -1
- package/dist-vue/_chunks/{PkChatbot-DHkhT0Jf.js → PkChatbot-BlG1WlAO.js} +7 -7
- package/dist-vue/_chunks/{PkChatbot-DHkhT0Jf.js.map → PkChatbot-BlG1WlAO.js.map} +1 -1
- package/dist-vue/_chunks/PkChatbotMessages-BrufA7o1.js +752 -0
- package/dist-vue/_chunks/PkChatbotMessages-BrufA7o1.js.map +1 -0
- package/dist-vue/_chunks/{PkChatbotStepToolDetail-ldThv0t5.js → PkChatbotStepToolDetail-BVI72gyx.js} +2 -2
- package/dist-vue/_chunks/{PkChatbotStepToolDetail-ldThv0t5.js.map → PkChatbotStepToolDetail-BVI72gyx.js.map} +1 -1
- package/dist-vue/_chunks/PkChatbotSteps-Dv9NkYER.js +172 -0
- package/dist-vue/_chunks/{PkChatbotSteps-BpqdFhsG.js.map → PkChatbotSteps-Dv9NkYER.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotViewChat-C08TsXiL.js → PkChatbotViewChat-CAqvbbfN.js} +66 -66
- package/dist-vue/_chunks/PkChatbotViewChat-CAqvbbfN.js.map +1 -0
- package/dist-vue/_chunks/{PkChatbotViewConversations-BQZi5kSC.js → PkChatbotViewConversations-Cq41H-tc.js} +2 -2
- package/dist-vue/_chunks/{PkChatbotViewConversations-BQZi5kSC.js.map → PkChatbotViewConversations-Cq41H-tc.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotViewFiles-TLKE_tRw.js → PkChatbotViewFiles-DNuzmBJc.js} +2 -2
- package/dist-vue/_chunks/{PkChatbotViewFiles-TLKE_tRw.js.map → PkChatbotViewFiles-DNuzmBJc.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotViewProfile-B6ANZY96.js → PkChatbotViewProfile-C0BXIY2N.js} +2 -2
- package/dist-vue/_chunks/{PkChatbotViewProfile-B6ANZY96.js.map → PkChatbotViewProfile-C0BXIY2N.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowForm-C-mWyeka.js → PkToolShowForm-CQuX08lk.js} +62 -58
- package/dist-vue/_chunks/PkToolShowForm-CQuX08lk.js.map +1 -0
- package/dist-vue/_chunks/{createChatbotApiClient-BOBdBxmf.js → createChatbotApiClient-BMZltBLh.js} +367 -363
- package/dist-vue/_chunks/createChatbotApiClient-BMZltBLh.js.map +1 -0
- package/dist-vue/_chunks/{useChatbotStore-BJ-EDmND.js → useChatbotStore-DZiorgLW.js} +113 -103
- package/dist-vue/_chunks/{useChatbotStore-BJ-EDmND.js.map → useChatbotStore-DZiorgLW.js.map} +1 -1
- package/dist-vue/_chunks/{utils-BMa8jwJS.js → utils-Cru8TJxe.js} +48 -30
- package/dist-vue/_chunks/utils-Cru8TJxe.js.map +1 -0
- package/dist-vue/api.js +1 -1
- package/dist-vue/composables.js +3 -3
- package/dist-vue/index.js +4351 -4041
- package/dist-vue/index.js.map +1 -1
- package/dist-vue/locales.js +16 -0
- package/dist-vue/packages/components/src/PkCheckboxField.d.ts +45 -0
- package/dist-vue/packages/components/src/PkEditorRepeater.d.ts +2 -2
- package/dist-vue/packages/components/src/PkPwaInstallPrompt.d.ts +4 -0
- package/dist-vue/packages/components/src/PkPwaOfflineNotice.d.ts +4 -0
- package/dist-vue/packages/components/src/chat/PkAgentSettingsPanel.d.ts +11 -2
- package/dist-vue/packages/components/src/chat/PkChatbotMessages.d.ts +24 -2
- package/dist-vue/packages/components/src/chat/PkToolApprovalBadge.d.ts +4 -0
- package/dist-vue/packages/components/src/chat/PkToolApprovalCard.d.ts +35 -0
- package/dist-vue/packages/components/src/chat/PkToolApprovalPreviewMessage.d.ts +11 -0
- package/dist-vue/packages/components/src/chat/index.d.ts +2 -1
- package/dist-vue/packages/components/src/chat/toolApprovalPreviews.d.ts +12 -0
- package/dist-vue/packages/components/src/chat/toolComponentMap.d.ts +5 -3
- package/dist-vue/packages/components/src/chat/useChatScroll.d.ts +6 -0
- package/dist-vue/packages/components/src/chat/utils.d.ts +13 -0
- package/dist-vue/packages/components/src/index.d.ts +4 -1
- package/dist-vue/packages/composable/src/chatbot/useChatbotStore.d.ts +34 -1
- package/dist-vue/packages/models/src/schema/Agent.d.ts +48 -0
- package/dist-vue/packages/models/src/schema/ReasoningChat.d.ts +6 -0
- package/dist-vue/packages/models/src/schema/SubAgent.d.ts +6 -0
- package/dist-vue/style.css +1 -1
- package/package.json +1 -1
- package/dist/_chunks/PkToolRequestConfirm-FQ9nDFXy.js +0 -48
- package/dist/_chunks/PkToolRequestConfirm-FQ9nDFXy.js.map +0 -1
- package/dist/_chunks/PkToolShowForm-BNV4Ja6g.js.map +0 -1
- package/dist-vue/_chunks/PkChatbotMessages-B4qfTNOJ.js +0 -630
- package/dist-vue/_chunks/PkChatbotMessages-B4qfTNOJ.js.map +0 -1
- package/dist-vue/_chunks/PkChatbotSteps-BpqdFhsG.js +0 -172
- package/dist-vue/_chunks/PkChatbotViewChat-C08TsXiL.js.map +0 -1
- package/dist-vue/_chunks/PkToolRequestConfirm-CQNa3seA.js +0 -48
- package/dist-vue/_chunks/PkToolRequestConfirm-CQNa3seA.js.map +0 -1
- package/dist-vue/_chunks/PkToolShowForm-C-mWyeka.js.map +0 -1
- package/dist-vue/_chunks/createChatbotApiClient-BOBdBxmf.js.map +0 -1
- package/dist-vue/_chunks/utils-BMa8jwJS.js.map +0 -1
- package/dist-vue/packages/components/src/chat/PkToolRequestConfirm.d.ts +0 -11
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PkChatbotSteps-BpqdFhsG.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 { nextTick, ref, watch } from 'vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n\n const props = defineProps<{\n markdown?: string\n innerClass?: string\n isDark?: boolean\n }>()\n\n const scrollEl = ref<HTMLDivElement>()\n const lastScrollTop = ref<number>(0)\n const stopAutoScroll = ref<boolean>(false)\n\n const handleScroll = () => {\n if (!scrollEl.value) {\n return\n }\n const currentScrollTop = scrollEl.value.scrollTop\n if (currentScrollTop < lastScrollTop.value) {\n const delta = lastScrollTop.value - currentScrollTop\n if (delta < 50) {\n stopAutoScroll.value = true\n }\n }\n if (currentScrollTop > lastScrollTop.value) {\n if (\n currentScrollTop ===\n scrollEl.value.scrollHeight - scrollEl.value.clientHeight\n ) {\n stopAutoScroll.value = false\n }\n }\n lastScrollTop.value = currentScrollTop\n }\n\n watch(\n () => props.markdown,\n async () => {\n await nextTick()\n if (scrollEl.value && !stopAutoScroll.value) {\n scrollEl.value.scrollTop = scrollEl.value.scrollHeight\n }\n },\n { immediate: true },\n )\n</script>\n\n<template>\n <div\n ref=\"scrollEl\"\n class=\"overflow-auto light-scrollbar\"\n @scroll=\"handleScroll\">\n <PkStreamingMarkdown :markdown :is-dark :class=\"innerClass\" />\n </div>\n</template>\n","<script lang=\"ts\" setup>\n import { nextTick, ref, watch } from 'vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n\n const props = defineProps<{\n markdown?: string\n innerClass?: string\n isDark?: boolean\n }>()\n\n const scrollEl = ref<HTMLDivElement>()\n const lastScrollTop = ref<number>(0)\n const stopAutoScroll = ref<boolean>(false)\n\n const handleScroll = () => {\n if (!scrollEl.value) {\n return\n }\n const currentScrollTop = scrollEl.value.scrollTop\n if (currentScrollTop < lastScrollTop.value) {\n const delta = lastScrollTop.value - currentScrollTop\n if (delta < 50) {\n stopAutoScroll.value = true\n }\n }\n if (currentScrollTop > lastScrollTop.value) {\n if (\n currentScrollTop ===\n scrollEl.value.scrollHeight - scrollEl.value.clientHeight\n ) {\n stopAutoScroll.value = false\n }\n }\n lastScrollTop.value = currentScrollTop\n }\n\n watch(\n () => props.markdown,\n async () => {\n await nextTick()\n if (scrollEl.value && !stopAutoScroll.value) {\n scrollEl.value.scrollTop = scrollEl.value.scrollHeight\n }\n },\n { immediate: true },\n )\n</script>\n\n<template>\n <div\n ref=\"scrollEl\"\n class=\"overflow-auto light-scrollbar\"\n @scroll=\"handleScroll\">\n <PkStreamingMarkdown :markdown :is-dark :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 {\n isReasoningPart,\n isToolPart,\n getPartIcon,\n getPartState,\n getToolPartLabel,\n getToolPartSummary,\n hasRichToolDetail,\n stringifyPayload,\n formatDuration as formatDurationWith,\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 toolInput?: unknown\n toolOutput?: unknown\n }\n\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 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: isReasoning && part.text.trim() ? part.text : undefined,\n toolInput: isTool && 'input' in part ? part.input : undefined,\n toolOutput:\n isTool && 'output' in part ? part.output : undefined,\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 const getStepError = (step: Step) =>\n getPartState(step.part) === 'output-error' &&\n 'errorText' in step.part &&\n typeof step.part.errorText === 'string'\n ? step.part.errorText\n : undefined\n\n const hasBody = (step: Step) => {\n if (step.text || getStepError(step)) {\n return true\n }\n if (hasRichToolDetail(step.part)) {\n return step.toolInput !== undefined || step.toolOutput !== undefined\n }\n return Boolean(\n stringifyPayload(step.toolInput) ??\n stringifyPayload(step.toolOutput),\n )\n }\n\n // --- Expand / collapse ---\n // The active (streaming) step is auto-expanded; a manual toggle always\n // wins over the automatic behavior.\n const manualSteps = reactive(new Map<string, boolean>())\n const isStepExpanded = (step: Step) =>\n manualSteps.get(step.key) ?? step.isActive\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\n v-if=\"isStreaming\"\n name=\"line-md:loading-loop\"\n 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=\"hasBody(step) ? 'button' : 'div'\"\n :type=\"hasBody(step) ? 'button' : undefined\"\n class=\"pk-chatbot-steps__step-header\"\n :aria-expanded=\"\n hasBody(step) ? isStepExpanded(step) : undefined\n \"\n @click=\"hasBody(step) ? toggleStep(step) : undefined\">\n <span\n class=\"pk-chatbot-steps-marker\"\n :class=\"{\n 'pk-chatbot-steps-marker--active': step.isActive,\n }\">\n <VvIcon\n v-if=\"step.isActive\"\n name=\"line-md: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=\"hasBody(step)\"\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=\"hasBody(step) && 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 inner-class=\"wysiwyg\"\n class=\"pk-chatbot-steps__step-content pk-chatbot-steps__step-content--scroll\" />\n <PkStreamingMarkdown\n v-else-if=\"step.text\"\n :markdown=\"step.text\"\n :is-dark\n class=\"wysiwyg pk-chatbot-steps__step-content\" />\n <div\n v-else-if=\"getStepError(step)\"\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>{{ getStepError(step) }}</pre>\n </div>\n <PkChatbotStepToolDetail\n v-else-if=\"hasRichToolDetail(step.part)\"\n :part=\"step.part\" />\n <template v-else>\n <div\n v-if=\"stringifyPayload(step.toolInput)\"\n class=\"pk-chatbot-steps__step-payload\">\n <span class=\"pk-chatbot-steps__step-payload-label\">\n {{ $t('messagePart.stepInput') }}\n </span>\n <pre>{{ stringifyPayload(step.toolInput) }}</pre>\n </div>\n <div\n v-if=\"stringifyPayload(step.toolOutput)\"\n class=\"pk-chatbot-steps__step-payload\">\n <span class=\"pk-chatbot-steps__step-payload-label\">\n {{ $t('messagePart.stepOutput') }}\n </span>\n <pre>{{ stringifyPayload(step.toolOutput) }}</pre>\n </div>\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 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-4);\n border-radius: var(--rounded);\n padding: var(--spacing-8);\n background-color: var(--color-surface-1);\n\n &--scroll {\n max-height: var(--spacing-256);\n }\n }\n\n &__step-payload {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-2);\n\n & + & {\n margin-top: var(--spacing-8);\n }\n\n pre {\n border: var(--spacing-px) solid var(--color-surface-4);\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 {\n isReasoningPart,\n isToolPart,\n getPartIcon,\n getPartState,\n getToolPartLabel,\n getToolPartSummary,\n hasRichToolDetail,\n stringifyPayload,\n formatDuration as formatDurationWith,\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 toolInput?: unknown\n toolOutput?: unknown\n }\n\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 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: isReasoning && part.text.trim() ? part.text : undefined,\n toolInput: isTool && 'input' in part ? part.input : undefined,\n toolOutput:\n isTool && 'output' in part ? part.output : undefined,\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 const getStepError = (step: Step) =>\n getPartState(step.part) === 'output-error' &&\n 'errorText' in step.part &&\n typeof step.part.errorText === 'string'\n ? step.part.errorText\n : undefined\n\n const hasBody = (step: Step) => {\n if (step.text || getStepError(step)) {\n return true\n }\n if (hasRichToolDetail(step.part)) {\n return step.toolInput !== undefined || step.toolOutput !== undefined\n }\n return Boolean(\n stringifyPayload(step.toolInput) ??\n stringifyPayload(step.toolOutput),\n )\n }\n\n // --- Expand / collapse ---\n // The active (streaming) step is auto-expanded; a manual toggle always\n // wins over the automatic behavior.\n const manualSteps = reactive(new Map<string, boolean>())\n const isStepExpanded = (step: Step) =>\n manualSteps.get(step.key) ?? step.isActive\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\n v-if=\"isStreaming\"\n name=\"line-md:loading-loop\"\n 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=\"hasBody(step) ? 'button' : 'div'\"\n :type=\"hasBody(step) ? 'button' : undefined\"\n class=\"pk-chatbot-steps__step-header\"\n :aria-expanded=\"\n hasBody(step) ? isStepExpanded(step) : undefined\n \"\n @click=\"hasBody(step) ? toggleStep(step) : undefined\">\n <span\n class=\"pk-chatbot-steps-marker\"\n :class=\"{\n 'pk-chatbot-steps-marker--active': step.isActive,\n }\">\n <VvIcon\n v-if=\"step.isActive\"\n name=\"line-md: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=\"hasBody(step)\"\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=\"hasBody(step) && 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 inner-class=\"wysiwyg\"\n class=\"pk-chatbot-steps__step-content pk-chatbot-steps__step-content--scroll\" />\n <PkStreamingMarkdown\n v-else-if=\"step.text\"\n :markdown=\"step.text\"\n :is-dark\n class=\"wysiwyg pk-chatbot-steps__step-content\" />\n <div\n v-else-if=\"getStepError(step)\"\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>{{ getStepError(step) }}</pre>\n </div>\n <PkChatbotStepToolDetail\n v-else-if=\"hasRichToolDetail(step.part)\"\n :part=\"step.part\" />\n <template v-else>\n <div\n v-if=\"stringifyPayload(step.toolInput)\"\n class=\"pk-chatbot-steps__step-payload\">\n <span class=\"pk-chatbot-steps__step-payload-label\">\n {{ $t('messagePart.stepInput') }}\n </span>\n <pre>{{ stringifyPayload(step.toolInput) }}</pre>\n </div>\n <div\n v-if=\"stringifyPayload(step.toolOutput)\"\n class=\"pk-chatbot-steps__step-payload\">\n <span class=\"pk-chatbot-steps__step-payload-label\">\n {{ $t('messagePart.stepOutput') }}\n </span>\n <pre>{{ stringifyPayload(step.toolOutput) }}</pre>\n </div>\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 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-4);\n border-radius: var(--rounded);\n padding: var(--spacing-8);\n background-color: var(--color-surface-1);\n\n &--scroll {\n max-height: var(--spacing-256);\n }\n }\n\n &__step-payload {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-2);\n\n & + & {\n margin-top: var(--spacing-8);\n }\n\n pre {\n border: var(--spacing-px) solid var(--color-surface-4);\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
|
+
{"version":3,"file":"PkChatbotSteps-Dv9NkYER.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 { nextTick, ref, watch } from 'vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n\n const props = defineProps<{\n markdown?: string\n innerClass?: string\n isDark?: boolean\n }>()\n\n const scrollEl = ref<HTMLDivElement>()\n const lastScrollTop = ref<number>(0)\n const stopAutoScroll = ref<boolean>(false)\n\n const handleScroll = () => {\n if (!scrollEl.value) {\n return\n }\n const currentScrollTop = scrollEl.value.scrollTop\n if (currentScrollTop < lastScrollTop.value) {\n const delta = lastScrollTop.value - currentScrollTop\n if (delta < 50) {\n stopAutoScroll.value = true\n }\n }\n if (currentScrollTop > lastScrollTop.value) {\n if (\n currentScrollTop ===\n scrollEl.value.scrollHeight - scrollEl.value.clientHeight\n ) {\n stopAutoScroll.value = false\n }\n }\n lastScrollTop.value = currentScrollTop\n }\n\n watch(\n () => props.markdown,\n async () => {\n await nextTick()\n if (scrollEl.value && !stopAutoScroll.value) {\n scrollEl.value.scrollTop = scrollEl.value.scrollHeight\n }\n },\n { immediate: true },\n )\n</script>\n\n<template>\n <div\n ref=\"scrollEl\"\n class=\"overflow-auto light-scrollbar\"\n @scroll=\"handleScroll\">\n <PkStreamingMarkdown :markdown :is-dark :class=\"innerClass\" />\n </div>\n</template>\n","<script lang=\"ts\" setup>\n import { nextTick, ref, watch } from 'vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n\n const props = defineProps<{\n markdown?: string\n innerClass?: string\n isDark?: boolean\n }>()\n\n const scrollEl = ref<HTMLDivElement>()\n const lastScrollTop = ref<number>(0)\n const stopAutoScroll = ref<boolean>(false)\n\n const handleScroll = () => {\n if (!scrollEl.value) {\n return\n }\n const currentScrollTop = scrollEl.value.scrollTop\n if (currentScrollTop < lastScrollTop.value) {\n const delta = lastScrollTop.value - currentScrollTop\n if (delta < 50) {\n stopAutoScroll.value = true\n }\n }\n if (currentScrollTop > lastScrollTop.value) {\n if (\n currentScrollTop ===\n scrollEl.value.scrollHeight - scrollEl.value.clientHeight\n ) {\n stopAutoScroll.value = false\n }\n }\n lastScrollTop.value = currentScrollTop\n }\n\n watch(\n () => props.markdown,\n async () => {\n await nextTick()\n if (scrollEl.value && !stopAutoScroll.value) {\n scrollEl.value.scrollTop = scrollEl.value.scrollHeight\n }\n },\n { immediate: true },\n )\n</script>\n\n<template>\n <div\n ref=\"scrollEl\"\n class=\"overflow-auto light-scrollbar\"\n @scroll=\"handleScroll\">\n <PkStreamingMarkdown :markdown :is-dark :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 {\n isReasoningPart,\n isToolPart,\n getPartIcon,\n getPartState,\n getToolPartLabel,\n getToolPartSummary,\n hasRichToolDetail,\n stringifyPayload,\n formatDuration as formatDurationWith,\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 toolInput?: unknown\n toolOutput?: unknown\n }\n\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 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: isReasoning && part.text.trim() ? part.text : undefined,\n toolInput: isTool && 'input' in part ? part.input : undefined,\n toolOutput:\n isTool && 'output' in part ? part.output : undefined,\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 const getStepError = (step: Step) =>\n getPartState(step.part) === 'output-error' &&\n 'errorText' in step.part &&\n typeof step.part.errorText === 'string'\n ? step.part.errorText\n : undefined\n\n const hasBody = (step: Step) => {\n if (step.text || getStepError(step)) {\n return true\n }\n if (hasRichToolDetail(step.part)) {\n return step.toolInput !== undefined || step.toolOutput !== undefined\n }\n return Boolean(\n stringifyPayload(step.toolInput) ??\n stringifyPayload(step.toolOutput),\n )\n }\n\n // --- Expand / collapse ---\n // The active (streaming) step is auto-expanded; a manual toggle always\n // wins over the automatic behavior.\n const manualSteps = reactive(new Map<string, boolean>())\n const isStepExpanded = (step: Step) =>\n manualSteps.get(step.key) ?? step.isActive\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\n v-if=\"isStreaming\"\n name=\"line-md:loading-loop\"\n 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=\"hasBody(step) ? 'button' : 'div'\"\n :type=\"hasBody(step) ? 'button' : undefined\"\n class=\"pk-chatbot-steps__step-header\"\n :aria-expanded=\"\n hasBody(step) ? isStepExpanded(step) : undefined\n \"\n @click=\"hasBody(step) ? toggleStep(step) : undefined\">\n <span\n class=\"pk-chatbot-steps-marker\"\n :class=\"{\n 'pk-chatbot-steps-marker--active': step.isActive,\n }\">\n <VvIcon\n v-if=\"step.isActive\"\n name=\"line-md: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=\"hasBody(step)\"\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=\"hasBody(step) && 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 inner-class=\"wysiwyg\"\n class=\"pk-chatbot-steps__step-content pk-chatbot-steps__step-content--scroll\" />\n <PkStreamingMarkdown\n v-else-if=\"step.text\"\n :markdown=\"step.text\"\n :is-dark\n class=\"wysiwyg pk-chatbot-steps__step-content\" />\n <div\n v-else-if=\"getStepError(step)\"\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>{{ getStepError(step) }}</pre>\n </div>\n <PkChatbotStepToolDetail\n v-else-if=\"hasRichToolDetail(step.part)\"\n :part=\"step.part\" />\n <template v-else>\n <div\n v-if=\"stringifyPayload(step.toolInput)\"\n class=\"pk-chatbot-steps__step-payload\">\n <span class=\"pk-chatbot-steps__step-payload-label\">\n {{ $t('messagePart.stepInput') }}\n </span>\n <pre>{{ stringifyPayload(step.toolInput) }}</pre>\n </div>\n <div\n v-if=\"stringifyPayload(step.toolOutput)\"\n class=\"pk-chatbot-steps__step-payload\">\n <span class=\"pk-chatbot-steps__step-payload-label\">\n {{ $t('messagePart.stepOutput') }}\n </span>\n <pre>{{ stringifyPayload(step.toolOutput) }}</pre>\n </div>\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 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-4);\n border-radius: var(--rounded);\n padding: var(--spacing-8);\n background-color: var(--color-surface-1);\n\n &--scroll {\n max-height: var(--spacing-256);\n }\n }\n\n &__step-payload {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-2);\n\n & + & {\n margin-top: var(--spacing-8);\n }\n\n pre {\n border: var(--spacing-px) solid var(--color-surface-4);\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 {\n isReasoningPart,\n isToolPart,\n getPartIcon,\n getPartState,\n getToolPartLabel,\n getToolPartSummary,\n hasRichToolDetail,\n stringifyPayload,\n formatDuration as formatDurationWith,\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 toolInput?: unknown\n toolOutput?: unknown\n }\n\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 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: isReasoning && part.text.trim() ? part.text : undefined,\n toolInput: isTool && 'input' in part ? part.input : undefined,\n toolOutput:\n isTool && 'output' in part ? part.output : undefined,\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 const getStepError = (step: Step) =>\n getPartState(step.part) === 'output-error' &&\n 'errorText' in step.part &&\n typeof step.part.errorText === 'string'\n ? step.part.errorText\n : undefined\n\n const hasBody = (step: Step) => {\n if (step.text || getStepError(step)) {\n return true\n }\n if (hasRichToolDetail(step.part)) {\n return step.toolInput !== undefined || step.toolOutput !== undefined\n }\n return Boolean(\n stringifyPayload(step.toolInput) ??\n stringifyPayload(step.toolOutput),\n )\n }\n\n // --- Expand / collapse ---\n // The active (streaming) step is auto-expanded; a manual toggle always\n // wins over the automatic behavior.\n const manualSteps = reactive(new Map<string, boolean>())\n const isStepExpanded = (step: Step) =>\n manualSteps.get(step.key) ?? step.isActive\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\n v-if=\"isStreaming\"\n name=\"line-md:loading-loop\"\n 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=\"hasBody(step) ? 'button' : 'div'\"\n :type=\"hasBody(step) ? 'button' : undefined\"\n class=\"pk-chatbot-steps__step-header\"\n :aria-expanded=\"\n hasBody(step) ? isStepExpanded(step) : undefined\n \"\n @click=\"hasBody(step) ? toggleStep(step) : undefined\">\n <span\n class=\"pk-chatbot-steps-marker\"\n :class=\"{\n 'pk-chatbot-steps-marker--active': step.isActive,\n }\">\n <VvIcon\n v-if=\"step.isActive\"\n name=\"line-md: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=\"hasBody(step)\"\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=\"hasBody(step) && 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 inner-class=\"wysiwyg\"\n class=\"pk-chatbot-steps__step-content pk-chatbot-steps__step-content--scroll\" />\n <PkStreamingMarkdown\n v-else-if=\"step.text\"\n :markdown=\"step.text\"\n :is-dark\n class=\"wysiwyg pk-chatbot-steps__step-content\" />\n <div\n v-else-if=\"getStepError(step)\"\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>{{ getStepError(step) }}</pre>\n </div>\n <PkChatbotStepToolDetail\n v-else-if=\"hasRichToolDetail(step.part)\"\n :part=\"step.part\" />\n <template v-else>\n <div\n v-if=\"stringifyPayload(step.toolInput)\"\n class=\"pk-chatbot-steps__step-payload\">\n <span class=\"pk-chatbot-steps__step-payload-label\">\n {{ $t('messagePart.stepInput') }}\n </span>\n <pre>{{ stringifyPayload(step.toolInput) }}</pre>\n </div>\n <div\n v-if=\"stringifyPayload(step.toolOutput)\"\n class=\"pk-chatbot-steps__step-payload\">\n <span class=\"pk-chatbot-steps__step-payload-label\">\n {{ $t('messagePart.stepOutput') }}\n </span>\n <pre>{{ stringifyPayload(step.toolOutput) }}</pre>\n </div>\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 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-4);\n border-radius: var(--rounded);\n padding: var(--spacing-8);\n background-color: var(--color-surface-1);\n\n &--scroll {\n max-height: var(--spacing-256);\n }\n }\n\n &__step-payload {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-2);\n\n & + & {\n margin-top: var(--spacing-8);\n }\n\n pre {\n border: var(--spacing-px) solid var(--color-surface-4);\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,7 +1,7 @@
|
|
|
1
|
-
import { t as e } from "./useChatbotStore-
|
|
1
|
+
import { t as e } from "./useChatbotStore-DZiorgLW.js";
|
|
2
2
|
import { t } from "./useLocalizedString-PfaKjIQY.js";
|
|
3
3
|
import { t as n } from "./PkAvatar-CyIgsndA.js";
|
|
4
|
-
import { t as r } from "./PkChatbotMessages-
|
|
4
|
+
import { t as r } from "./PkChatbotMessages-BrufA7o1.js";
|
|
5
5
|
import { t as i } from "./PkChatbotInput-DTazYlPd.js";
|
|
6
6
|
import { t as a } from "./PkChatbotEmptyState-BGOC6vxr.js";
|
|
7
7
|
import { VvIcon as o } from "@volverjs/ui-vue/components";
|
|
@@ -28,7 +28,7 @@ var j = {
|
|
|
28
28
|
}, M = {
|
|
29
29
|
key: 1,
|
|
30
30
|
class: "pk-aurora__fallback"
|
|
31
|
-
}, N = "\nattribute vec2 a_position;\nvoid main() {\n gl_Position = vec4(a_position, 0.0, 1.0);\n}", P = "\nprecision mediump float;\nuniform vec2 u_resolution;\nuniform float u_time;\nuniform vec3 u_color;\nuniform vec2 u_center;\nuniform vec2 u_half;\nuniform float u_spread;\n\nvec3 permute(vec3 x) { return mod(((x * 34.0) + 1.0) * x, 289.0); }\n\nfloat snoise(vec2 v) {\n const vec4 C = vec4(0.211324865405187, 0.366025403784439,\n -0.577350269189626, 0.024390243902439);\n vec2 i = floor(v + dot(v, C.yy));\n vec2 x0 = v - i + dot(i, C.xx);\n vec2 i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\n vec4 x12 = x0.xyxy + C.xxzz;\n x12.xy -= i1;\n i = mod(i, 289.0);\n vec3 p = permute(permute(i.y + vec3(0.0, i1.y, 1.0))\n + i.x + vec3(0.0, i1.x, 1.0));\n vec3 m = max(0.5 - vec3(dot(x0, x0), dot(x12.xy, x12.xy),\n dot(x12.zw, x12.zw)), 0.0);\n m = m * m;\n m = m * m;\n vec3 x = 2.0 * fract(p * C.www) - 1.0;\n vec3 h = abs(x) - 0.5;\n vec3 ox = floor(x + 0.5);\n vec3 a0 = x - ox;\n m *= 1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h);\n vec3 g;\n g.x = a0.x * x0.x + h.x * x0.y;\n g.yz = a0.yz * x12.xz + h.yz * x12.yw;\n return 130.0 * dot(m, g);\n}\n\nvoid main() {\n vec2 px = gl_FragCoord.xy;\n vec2 rel = px - u_center;\n\n // Ignition: the ellipse lights up expanding from the center on mount\n float intro = smoothstep(0.0, 1.4, u_time);\n\n // Breathing: size and brightness oscillate gently but visibly\n float breath = 1.0\n + 0.12 * sin(u_time * 0.55)\n + 0.06 * snoise(vec2(u_time * 0.1, 3.7));\n float pulse = 1.0 + 0.2 * sin(u_time * 0.55 + 1.3);\n\n // Keep it simple (Gemini-style): one huge soft elliptical glow\n // centered on the pill\n vec2 radii = vec2(u_half.x * 0.95, u_half.y * 6.5)\n * u_spread\n * breath\n * mix(0.15, 1.0, intro);\n float r = length(rel / max(radii, vec2(1.0)));\n float glow = exp(-r * r * 2.2);\n\n // Never cut hard against the canvas bounds\n vec2 m = min(px, u_resolution - px);\n glow *= smoothstep(0.0, 32.0, min(m.x, m.y));\n\n // Dither: breaks the 8-bit banding rings of the very soft gradient\n // (no CSS blur on the canvas, the noise must fully mask the bands)\n glow = max(glow + (snoise(px * 0.9) - 0.5) * 0.03, 0.0);\n\n float alpha = glow * 0.2 * pulse * intro;\n\n // Premultiplied alpha (default canvas compositing)\n gl_FragColor = vec4(u_color * alpha, alpha);\n}",
|
|
31
|
+
}, N = "\nattribute vec2 a_position;\nvoid main() {\n gl_Position = vec4(a_position, 0.0, 1.0);\n}", P = "\nprecision mediump float;\nuniform vec2 u_resolution;\nuniform float u_time;\nuniform vec3 u_color;\nuniform vec2 u_center;\nuniform vec2 u_half;\nuniform float u_spread;\n\nvec3 permute(vec3 x) { return mod(((x * 34.0) + 1.0) * x, 289.0); }\n\nfloat snoise(vec2 v) {\n const vec4 C = vec4(0.211324865405187, 0.366025403784439,\n -0.577350269189626, 0.024390243902439);\n vec2 i = floor(v + dot(v, C.yy));\n vec2 x0 = v - i + dot(i, C.xx);\n vec2 i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\n vec4 x12 = x0.xyxy + C.xxzz;\n x12.xy -= i1;\n i = mod(i, 289.0);\n vec3 p = permute(permute(i.y + vec3(0.0, i1.y, 1.0))\n + i.x + vec3(0.0, i1.x, 1.0));\n vec3 m = max(0.5 - vec3(dot(x0, x0), dot(x12.xy, x12.xy),\n dot(x12.zw, x12.zw)), 0.0);\n m = m * m;\n m = m * m;\n vec3 x = 2.0 * fract(p * C.www) - 1.0;\n vec3 h = abs(x) - 0.5;\n vec3 ox = floor(x + 0.5);\n vec3 a0 = x - ox;\n m *= 1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h);\n vec3 g;\n g.x = a0.x * x0.x + h.x * x0.y;\n g.yz = a0.yz * x12.xz + h.yz * x12.yw;\n return 130.0 * dot(m, g);\n}\n\nvoid main() {\n vec2 px = gl_FragCoord.xy;\n vec2 rel = px - u_center;\n\n // Ignition: the ellipse lights up expanding from the center on mount\n float intro = smoothstep(0.0, 1.4, u_time);\n\n // Breathing: size and brightness oscillate gently but visibly\n float breath = 1.0\n + 0.12 * sin(u_time * 0.55)\n + 0.06 * snoise(vec2(u_time * 0.1, 3.7));\n float pulse = 1.0 + 0.2 * sin(u_time * 0.55 + 1.3);\n\n // Keep it simple (Gemini-style): one huge soft elliptical glow\n // centered on the pill\n vec2 radii = vec2(u_half.x * 0.95, u_half.y * 6.5)\n * u_spread\n * breath\n * mix(0.15, 1.0, intro);\n float r = length(rel / max(radii, vec2(1.0)));\n float glow = exp(-r * r * 2.2);\n\n // Never cut hard against the canvas bounds\n vec2 m = min(px, u_resolution - px);\n glow *= smoothstep(0.0, 32.0, min(m.x, m.y));\n\n // Dither: breaks the 8-bit banding rings of the very soft gradient\n // (no CSS blur on the canvas, the noise must fully mask the bands)\n glow = max(glow + (snoise(px * 0.9) - 0.5) * 0.03, 0.0);\n\n float alpha = glow * 0.2 * pulse * intro;\n\n // Premultiplied alpha (default canvas compositing)\n gl_FragColor = vec4(u_color * alpha, alpha);\n}", F = /* @__PURE__ */ g({
|
|
32
32
|
__name: "PkAuroraCanvas",
|
|
33
33
|
props: { sourceSelector: {} },
|
|
34
34
|
setup(e) {
|
|
@@ -110,16 +110,16 @@ var j = {
|
|
|
110
110
|
class: "pk-aurora__canvas"
|
|
111
111
|
}, null, 512))]));
|
|
112
112
|
}
|
|
113
|
-
}),
|
|
113
|
+
}), re = { class: "pk-chatbot-view-chat__input-stage" }, ie = {
|
|
114
114
|
key: 0,
|
|
115
115
|
class: "p-md border-t border-surface-3 text-center text-12 text-danger-darken-2 bg-surface-danger"
|
|
116
|
-
},
|
|
116
|
+
}, ae = { class: "pk-chatbot-view-chat__agent-chip" }, oe = {
|
|
117
117
|
key: 0,
|
|
118
118
|
class: "pk-chatbot-view-chat__agent-chip-name"
|
|
119
|
-
},
|
|
119
|
+
}, se = {
|
|
120
120
|
key: 0,
|
|
121
121
|
class: "pk-chatbot-view-chat__drop-overlay"
|
|
122
|
-
},
|
|
122
|
+
}, I = /* @__PURE__ */ g({
|
|
123
123
|
__name: "PkChatbotViewChat",
|
|
124
124
|
props: {
|
|
125
125
|
agentId: {},
|
|
@@ -128,13 +128,13 @@ var j = {
|
|
|
128
128
|
},
|
|
129
129
|
emits: ["show-info", "revise"],
|
|
130
130
|
setup(g, { emit: y }) {
|
|
131
|
-
let b = h(() => import("./PkToolShowForm-
|
|
132
|
-
let e =
|
|
131
|
+
let b = h(() => import("./PkToolShowForm-CQuX08lk.js").then((e) => e.n)), x = h(() => import("./PkToolShowContactForm-B6-MsExL.js").then((e) => e.n)), C = h(() => import("./PkToolShowSuggestedReply-DoCHIEzz.js").then((e) => e.n)), T = h(() => import("./PkToolShowSources-CFh-i60o.js").then((e) => e.n)), A = h(() => import("./PkToolRequestGeolocation-aw2-ecEn.js")), j = h(() => import("./PkToolRequestOAuthConnection-lo7hCSBC.js")), M = h(() => import("./PkToolShowLocation-5G8p9mED.js").then((e) => e.n)), N = h(() => import("./PkToolShowDiagram-G0hdi_Vf.js")), P = g, I = y, L = e(P.agentId), { agentInterface: R, agentFileUpload: z, actions: ce, revisedAnswers: le, messages: B, chat: V, messageFeedbacks: ue, feedbackDialogMessage: H, isFeedbackSubmitting: de, isFeedbackSubmitted: fe, feedbackSubmitError: pe, isLeadSubmitted: me, isLoadingSubmitLead: he, submitLeadError: ge, input: U, inputMessagePlaceholder: _e, isConversationBlocked: ve, baseUrl: ye, pendingAttachments: W, isAttachmentLimitReached: be, fileLimitError: xe, apiClient: G, isDark: K } = te(L), { handleSubmit: q, stopGeneration: Se, regenerate: J, onUpvote: Ce, onDownvote: we, onFeedback: Te, onFeedbackSubmit: Ee, onLeadSubmit: De, startNewChat: Oe, addToolOutput: Y, addToolApprovalResponse: ke, handleFileSelect: X, clearFileLimitError: Ae } = L, { t: Z } = k({ useScope: "global" }), je = c(() => {
|
|
132
|
+
let e = xe.value;
|
|
133
133
|
if (e) return e.reason === "per-chat" ? Z("message.fileLimitPerChat", { max: e.max }) : Z("message.fileLimitPerMessage", { max: e.max });
|
|
134
|
-
}),
|
|
135
|
-
let t = await G.value.downloadSourceDocument(
|
|
134
|
+
}), Q = t(() => R.value?.dismissableNotice), Me = c(() => B.value.some((e) => e.role === "user")), $ = c(() => P.modifier === "fullscreen" && !Me.value), Ne = ne(R, () => P.userName), Pe = D("chatViewEl"), Fe = async (e) => (await G.value.expandSourceContext(P.agentId, e.documentId, e.chunkIndex)).content, Ie = async (e) => {
|
|
135
|
+
let t = await G.value.downloadSourceDocument(P.agentId, e);
|
|
136
136
|
window.open(t.downloadUrl, "_blank");
|
|
137
|
-
}, { isOverDropZone:
|
|
137
|
+
}, { isOverDropZone: Le } = ee(Pe, {
|
|
138
138
|
dataTypes: c(() => z.value?.allowedMimeTypes ?? []),
|
|
139
139
|
onDrop: (e) => {
|
|
140
140
|
if (!(!z.value?.enabled || !e)) for (let t of e) X(t);
|
|
@@ -144,19 +144,19 @@ var j = {
|
|
|
144
144
|
let c = o;
|
|
145
145
|
return S(), d("div", {
|
|
146
146
|
ref_key: "chatViewEl",
|
|
147
|
-
ref:
|
|
147
|
+
ref: Pe,
|
|
148
148
|
class: v(["pk-chatbot-view-chat", {
|
|
149
|
-
"pk-chatbot-view-chat--dragover": E(
|
|
150
|
-
"pk-chatbot-view-chat--empty":
|
|
149
|
+
"pk-chatbot-view-chat--dragover": E(Le) && E(z)?.enabled,
|
|
150
|
+
"pk-chatbot-view-chat--empty": $.value
|
|
151
151
|
}])
|
|
152
152
|
}, [
|
|
153
153
|
m(s, {
|
|
154
154
|
name: "pk-chatbot-view-chat-fade",
|
|
155
155
|
mode: "out-in"
|
|
156
156
|
}, {
|
|
157
|
-
default: O(() => [
|
|
157
|
+
default: O(() => [$.value ? (S(), l(a, {
|
|
158
158
|
key: 0,
|
|
159
|
-
greeting: E(
|
|
159
|
+
greeting: E(Ne),
|
|
160
160
|
logo: E(R)?.logo,
|
|
161
161
|
name: E(L).name
|
|
162
162
|
}, null, 8, [
|
|
@@ -166,40 +166,47 @@ var j = {
|
|
|
166
166
|
])) : (S(), l(r, {
|
|
167
167
|
key: 1,
|
|
168
168
|
class: "flex flex-col flex-1 min-h-0 p-md overflow-y-auto",
|
|
169
|
+
interactive: "",
|
|
169
170
|
messages: E(B),
|
|
170
171
|
status: E(V).status,
|
|
171
172
|
error: E(V).error,
|
|
172
173
|
"main-color": E(R)?.mainColor,
|
|
173
174
|
"text-color": E(R)?.textColor,
|
|
174
|
-
"revised-answers": E(
|
|
175
|
-
actions: E(
|
|
176
|
-
"message-feedbacks": E(
|
|
175
|
+
"revised-answers": E(le),
|
|
176
|
+
actions: E(ce),
|
|
177
|
+
"message-feedbacks": E(ue),
|
|
177
178
|
"feedback-message-id": E(H)?.id,
|
|
178
|
-
"feedback-loading": E(
|
|
179
|
-
"feedback-submitted": E(
|
|
180
|
-
"feedback-error": E(
|
|
179
|
+
"feedback-loading": E(de),
|
|
180
|
+
"feedback-submitted": E(fe),
|
|
181
|
+
"feedback-error": E(pe),
|
|
181
182
|
"show-extended-steps": E(R)?.showExtendedSteps,
|
|
182
183
|
"is-dark": E(K),
|
|
183
184
|
"show-scroll-to-bottom": g.modifier === "fullscreen",
|
|
184
|
-
onFeedbackSubmit: t[1] ||= (e) => E(
|
|
185
|
+
onFeedbackSubmit: t[1] ||= (e) => E(Ee)(e),
|
|
185
186
|
onFeedbackClose: t[2] ||= (e) => H.value = void 0,
|
|
186
187
|
onRegenerate: E(J),
|
|
187
188
|
onAutoRetry: E(J),
|
|
188
|
-
onResetChat: E(
|
|
189
|
+
onResetChat: E(Oe),
|
|
189
190
|
onShowInfo: t[3] ||= (e) => I("show-info", e),
|
|
190
191
|
onRevise: t[4] ||= (e) => I("revise", e),
|
|
191
|
-
onUpvote: E(
|
|
192
|
-
onDownvote: E(
|
|
193
|
-
onFeedback: E(
|
|
192
|
+
onUpvote: E(Ce),
|
|
193
|
+
onDownvote: E(we),
|
|
194
|
+
onFeedback: E(Te),
|
|
195
|
+
onApprovalRespond: E(ke),
|
|
196
|
+
onConfirmRespond: t[5] ||= ({ toolCallId: e, confirmed: t }) => E(Y)({
|
|
197
|
+
tool: "requestConfirm",
|
|
198
|
+
toolCallId: e,
|
|
199
|
+
output: t ? "confirmed" : "cancelled"
|
|
200
|
+
})
|
|
194
201
|
}, {
|
|
195
|
-
"tool-showContactForm": O(({ part: e }) => [m(E(
|
|
202
|
+
"tool-showContactForm": O(({ part: e }) => [m(E(x), {
|
|
196
203
|
part: e,
|
|
197
|
-
readonly: !E(
|
|
198
|
-
submitted: E(
|
|
199
|
-
loading: E(
|
|
200
|
-
error: E(
|
|
204
|
+
readonly: !E(ye),
|
|
205
|
+
submitted: E(me),
|
|
206
|
+
loading: E(he),
|
|
207
|
+
error: E(ge),
|
|
201
208
|
"privacy-policy-notice": E(R)?.privacyPolicyNotice,
|
|
202
|
-
onSubmit: E(
|
|
209
|
+
onSubmit: E(De)
|
|
203
210
|
}, null, 8, [
|
|
204
211
|
"part",
|
|
205
212
|
"readonly",
|
|
@@ -209,16 +216,16 @@ var j = {
|
|
|
209
216
|
"privacy-policy-notice",
|
|
210
217
|
"onSubmit"
|
|
211
218
|
])]),
|
|
212
|
-
"tool-showSuggestedReply": O(({ part: e }) => [m(E(
|
|
219
|
+
"tool-showSuggestedReply": O(({ part: e }) => [m(E(C), {
|
|
213
220
|
part: e,
|
|
214
221
|
onSelect: t[0] ||= (e) => {
|
|
215
222
|
U.value = e, E(q)();
|
|
216
223
|
}
|
|
217
224
|
}, null, 8, ["part"])]),
|
|
218
|
-
"tool-showSources": O(({ part: e }) => [m(E(
|
|
225
|
+
"tool-showSources": O(({ part: e }) => [m(E(T), {
|
|
219
226
|
part: e,
|
|
220
|
-
"on-expand-context":
|
|
221
|
-
"on-download":
|
|
227
|
+
"on-expand-context": Fe,
|
|
228
|
+
"on-download": Ie
|
|
222
229
|
}, null, 8, ["part"])]),
|
|
223
230
|
"tool-showForm": O(({ part: e }) => [m(s, { mode: "out-in" }, {
|
|
224
231
|
default: O(() => [m(E(b), {
|
|
@@ -243,17 +250,9 @@ var j = {
|
|
|
243
250
|
}, null, 8, ["part", "onSelect"])]),
|
|
244
251
|
_: 2
|
|
245
252
|
}, 1024)]),
|
|
246
|
-
"tool-
|
|
253
|
+
"tool-requestOAuthConnection": O(({ part: e }) => [m(E(j), {
|
|
247
254
|
part: e,
|
|
248
|
-
|
|
249
|
-
tool: "requestConfirm",
|
|
250
|
-
toolCallId: e.toolCallId,
|
|
251
|
-
output: t ? "confirmed" : "cancelled"
|
|
252
|
-
})
|
|
253
|
-
}, null, 8, ["part", "onConfirm"])]),
|
|
254
|
-
"tool-requestOAuthConnection": O(({ part: e }) => [m(E(M), {
|
|
255
|
-
part: e,
|
|
256
|
-
"resolve-connection": (e) => E(G).getOAuthAuthorizeUrl(F.agentId, e),
|
|
255
|
+
"resolve-connection": (e) => E(G).getOAuthAuthorizeUrl(P.agentId, e),
|
|
257
256
|
onConnected: (t) => E(Y)({
|
|
258
257
|
tool: "requestOAuthConnection",
|
|
259
258
|
toolCallId: e.toolCallId,
|
|
@@ -267,7 +266,7 @@ var j = {
|
|
|
267
266
|
"resolve-connection",
|
|
268
267
|
"onConnected"
|
|
269
268
|
])]),
|
|
270
|
-
"tool-requestGeolocation": O(({ part: e }) => [m(E(
|
|
269
|
+
"tool-requestGeolocation": O(({ part: e }) => [m(E(A), {
|
|
271
270
|
part: e,
|
|
272
271
|
"reverse-geocode": (e, t) => E(G).reverseGeocode(e, t),
|
|
273
272
|
onResult: (t) => E(Y)({
|
|
@@ -280,7 +279,7 @@ var j = {
|
|
|
280
279
|
"reverse-geocode",
|
|
281
280
|
"onResult"
|
|
282
281
|
])]),
|
|
283
|
-
"tool-showLocation": O(({ part: e }) => [m(E(
|
|
282
|
+
"tool-showLocation": O(({ part: e }) => [m(E(M), {
|
|
284
283
|
part: e,
|
|
285
284
|
"is-dark": E(K),
|
|
286
285
|
"main-color": E(R)?.mainColor,
|
|
@@ -291,7 +290,7 @@ var j = {
|
|
|
291
290
|
"main-color",
|
|
292
291
|
"forward-geocode"
|
|
293
292
|
])]),
|
|
294
|
-
"tool-showDiagram": O(({ part: e }) => [m(E(
|
|
293
|
+
"tool-showDiagram": O(({ part: e }) => [m(E(N), {
|
|
295
294
|
part: e,
|
|
296
295
|
"is-dark": E(K)
|
|
297
296
|
}, null, 8, ["part", "is-dark"])]),
|
|
@@ -317,42 +316,43 @@ var j = {
|
|
|
317
316
|
"onResetChat",
|
|
318
317
|
"onUpvote",
|
|
319
318
|
"onDownvote",
|
|
320
|
-
"onFeedback"
|
|
319
|
+
"onFeedback",
|
|
320
|
+
"onApprovalRespond"
|
|
321
321
|
]))]),
|
|
322
322
|
_: 1
|
|
323
323
|
}),
|
|
324
|
-
f("div",
|
|
325
|
-
default: O(() => [
|
|
324
|
+
f("div", re, [m(s, { name: "pk-chatbot-view-chat-fade" }, {
|
|
325
|
+
default: O(() => [$.value ? (S(), l(F, {
|
|
326
326
|
key: 0,
|
|
327
327
|
class: "pk-chatbot-view-chat__aurora",
|
|
328
328
|
"source-selector": ".pk-chatbot-input__form"
|
|
329
329
|
})) : u("", !0)]),
|
|
330
330
|
_: 1
|
|
331
|
-
}), E(
|
|
331
|
+
}), E(ve) ? (S(), d("div", ie, w(E(Z)("message.chatErrorConversationBlocked")), 1)) : (S(), l(i, {
|
|
332
332
|
key: 1,
|
|
333
333
|
modelValue: E(U),
|
|
334
|
-
"onUpdate:modelValue": t[
|
|
334
|
+
"onUpdate:modelValue": t[6] ||= (e) => _(U) ? U.value = e : null,
|
|
335
335
|
"pending-attachments": E(W),
|
|
336
|
-
"onUpdate:pendingAttachments": t[
|
|
337
|
-
placeholder: E(
|
|
338
|
-
"dismissable-notice": E(
|
|
336
|
+
"onUpdate:pendingAttachments": t[7] ||= (e) => _(W) ? W.value = e : null,
|
|
337
|
+
placeholder: E(_e),
|
|
338
|
+
"dismissable-notice": E(Q) && E(V).messages.length <= 1 ? E(Q) : void 0,
|
|
339
339
|
status: E(V).status,
|
|
340
340
|
"max-message-length": E(R)?.maxMessageLength,
|
|
341
341
|
"file-upload": E(z),
|
|
342
|
-
"attachment-limit-reached": E(
|
|
342
|
+
"attachment-limit-reached": E(be),
|
|
343
343
|
"attachment-notice": je.value,
|
|
344
|
-
onStopGeneration: E(
|
|
344
|
+
onStopGeneration: E(Se),
|
|
345
345
|
onSubmit: E(q),
|
|
346
346
|
onFileSelect: E(X),
|
|
347
347
|
onDismissAttachmentNotice: E(Ae)
|
|
348
348
|
}, p({ _: 2 }, [g.modifier === "fullscreen" ? {
|
|
349
349
|
name: "prepend",
|
|
350
|
-
fn: O(() => [f("span",
|
|
350
|
+
fn: O(() => [f("span", ae, [m(n, {
|
|
351
351
|
modifiers: "surface",
|
|
352
352
|
class: "pk-chatbot-view-chat__agent-chip-avatar",
|
|
353
353
|
"img-src": E(R)?.logo,
|
|
354
354
|
name: E(L).name
|
|
355
|
-
}, null, 8, ["img-src", "name"]), E(L).name ? (S(), d("strong",
|
|
355
|
+
}, null, 8, ["img-src", "name"]), E(L).name ? (S(), d("strong", oe, w(E(L).name), 1)) : u("", !0)])]),
|
|
356
356
|
key: "0"
|
|
357
357
|
} : void 0]), 1032, [
|
|
358
358
|
"modelValue",
|
|
@@ -370,7 +370,7 @@ var j = {
|
|
|
370
370
|
"onDismissAttachmentNotice"
|
|
371
371
|
]))]),
|
|
372
372
|
m(s, null, {
|
|
373
|
-
default: O(() => [E(
|
|
373
|
+
default: O(() => [E(Le) && E(z)?.enabled ? (S(), d("div", se, [m(c, {
|
|
374
374
|
name: "ri:upload-cloud-2-line",
|
|
375
375
|
class: "pk-chatbot-view-chat__drop-overlay-icon"
|
|
376
376
|
}), f("span", null, w(E(Z)("action.dropFile")), 1)])) : u("", !0)]),
|
|
@@ -381,6 +381,6 @@ var j = {
|
|
|
381
381
|
}
|
|
382
382
|
});
|
|
383
383
|
//#endregion
|
|
384
|
-
export {
|
|
384
|
+
export { F as n, I as t };
|
|
385
385
|
|
|
386
|
-
//# sourceMappingURL=PkChatbotViewChat-
|
|
386
|
+
//# sourceMappingURL=PkChatbotViewChat-CAqvbbfN.js.map
|