@8wave/ai-elements 0.77.0 → 0.78.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/{PkStreamingMarkdown-COZApJzT.js → PkStreamingMarkdown-gIAvEY1t.js} +370 -301
- package/dist/_chunks/PkStreamingMarkdown-gIAvEY1t.js.map +1 -0
- package/dist/_chunks/{PkToolShowArtifact-BZQixk9z.js → PkToolShowArtifact-BwW4Yn6k.js} +2 -2
- package/dist/_chunks/{PkToolShowArtifact-BZQixk9z.js.map → PkToolShowArtifact-BwW4Yn6k.js.map} +1 -1
- package/dist/_chunks/{PkToolShowContactForm-thS7c8iL.js → PkToolShowContactForm-DTE-iF_c.js} +2 -2
- package/dist/_chunks/{PkToolShowContactForm-thS7c8iL.js.map → PkToolShowContactForm-DTE-iF_c.js.map} +1 -1
- package/dist/_chunks/PkToolShowImageGallery-CGL-HL6v.js +60 -0
- package/dist/_chunks/PkToolShowImageGallery-CGL-HL6v.js.map +1 -0
- package/dist/_chunks/{PkToolShowProductList-DEo7XogW.js → PkToolShowProductList-C8YIh0Dw.js} +2 -2
- package/dist/_chunks/{PkToolShowProductList-DEo7XogW.js.map → PkToolShowProductList-C8YIh0Dw.js.map} +1 -1
- package/dist/_chunks/{PkToolShowSources-BMXftK6O.js → PkToolShowSources-TSjtd1ps.js} +3 -3
- package/dist/_chunks/{PkToolShowSources-BMXftK6O.js.map → PkToolShowSources-TSjtd1ps.js.map} +1 -1
- package/dist/_chunks/{PkToolShowSuggestedReply-CPAnHI0c.js → PkToolShowSuggestedReply-c9sLv4n4.js} +2 -2
- package/dist/_chunks/{PkToolShowSuggestedReply-CPAnHI0c.js.map → PkToolShowSuggestedReply-c9sLv4n4.js.map} +1 -1
- package/dist/_chunks/{PkToolShowWeather-DcSUbzx0.js → PkToolShowWeather-ChJ5lB4K.js} +48 -48
- package/dist/_chunks/PkToolShowWeather-ChJ5lB4K.js.map +1 -0
- package/dist/_chunks/{PkToolShowWebPages-aH_GarEV.js → PkToolShowWebPages-CL2mYxh-.js} +2 -2
- package/dist/_chunks/{PkToolShowWebPages-aH_GarEV.js.map → PkToolShowWebPages-CL2mYxh-.js.map} +1 -1
- package/dist/_chunks/{PkUrl-BHD0_pal.js → PkUrl-CvztUywv.js} +2 -2
- package/dist/_chunks/{PkUrl-BHD0_pal.js.map → PkUrl-CvztUywv.js.map} +1 -1
- package/dist/_chunks/{useLightbox-DL_oVBep.js → useLightbox-Ddvue042.js} +5 -3
- package/{dist-vue/_chunks/useLightbox-1sB7fmFb.js.map → dist/_chunks/useLightbox-Ddvue042.js.map} +1 -1
- package/dist/ai-elements.es.js +3097 -3010
- package/dist/ai-elements.es.js.map +1 -1
- package/dist-vue/PkChatbot.js +1 -1
- package/dist-vue/PkChatbotFilePreview.js +1 -1
- package/dist-vue/PkChatbotInput.js +1 -1
- package/dist-vue/PkChatbotMessages.js +1 -1
- package/dist-vue/PkChatbotViewChat.js +1 -1
- package/dist-vue/_chunks/{PkChatbot-B9RSkQmJ.js → PkChatbot-BEJTYq-D.js} +4 -4
- package/dist-vue/_chunks/{PkChatbot-B9RSkQmJ.js.map → PkChatbot-BEJTYq-D.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotFilePreview-DHzuGtz5.js → PkChatbotFilePreview-hRNtv2OJ.js} +2 -2
- package/dist-vue/_chunks/{PkChatbotFilePreview-DHzuGtz5.js.map → PkChatbotFilePreview-hRNtv2OJ.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotInput-C5QSmt21.js → PkChatbotInput-BbGLBVim.js} +124 -116
- package/dist-vue/_chunks/PkChatbotInput-BbGLBVim.js.map +1 -0
- package/dist-vue/_chunks/PkChatbotMessages-j3ALQmGG.js +467 -0
- package/dist-vue/_chunks/PkChatbotMessages-j3ALQmGG.js.map +1 -0
- package/dist-vue/_chunks/{PkChatbotViewChat-C2FuDayB.js → PkChatbotViewChat-Z05fqNFE.js} +5 -5
- package/dist-vue/_chunks/{PkChatbotViewChat-C2FuDayB.js.map → PkChatbotViewChat-Z05fqNFE.js.map} +1 -1
- package/dist-vue/_chunks/{PkStreamingMarkdown-BAhC3uGK.js → PkStreamingMarkdown-BBTAwHd_.js} +311 -252
- package/dist-vue/_chunks/PkStreamingMarkdown-BBTAwHd_.js.map +1 -0
- package/dist-vue/_chunks/{PkToolShowArtifact-RzrDPcEQ.js → PkToolShowArtifact-CbqpjzCA.js} +2 -2
- package/dist-vue/_chunks/{PkToolShowArtifact-RzrDPcEQ.js.map → PkToolShowArtifact-CbqpjzCA.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowContactForm-5H4jfq1F.js → PkToolShowContactForm-BkgfSyw7.js} +2 -2
- package/dist-vue/_chunks/{PkToolShowContactForm-5H4jfq1F.js.map → PkToolShowContactForm-BkgfSyw7.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowImageGallery-B7Bt6ZGv.js → PkToolShowImageGallery-Ckyxa0mx.js} +18 -21
- package/dist-vue/_chunks/PkToolShowImageGallery-Ckyxa0mx.js.map +1 -0
- package/dist-vue/_chunks/{PkToolShowSources-Dv0uuvqS.js → PkToolShowSources-7Xt3iK2Z.js} +2 -2
- package/dist-vue/_chunks/{PkToolShowSources-Dv0uuvqS.js.map → PkToolShowSources-7Xt3iK2Z.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowWeather-Coq6H0iv.js → PkToolShowWeather-B5Wp8WAt.js} +26 -26
- package/dist-vue/_chunks/PkToolShowWeather-B5Wp8WAt.js.map +1 -0
- package/dist-vue/_chunks/{useLightbox-1sB7fmFb.js → useLightbox-Cl8REkfc.js} +5 -3
- package/{dist/_chunks/useLightbox-DL_oVBep.js.map → dist-vue/_chunks/useLightbox-Cl8REkfc.js.map} +1 -1
- package/dist-vue/index.js +11 -11
- package/dist-vue/packages/components/src/chat/PkChatbotMessages.d.ts +4 -5
- package/dist-vue/packages/components/src/chat/PkStreamingMarkdown.d.ts +9 -1
- package/dist-vue/packages/components/src/chat/useChatScroll.d.ts +15 -0
- package/dist-vue/style.css +1 -1
- package/package.json +1 -1
- package/dist/_chunks/PkStreamingMarkdown-COZApJzT.js.map +0 -1
- package/dist/_chunks/PkToolShowImageGallery-DmJztS-Z.js +0 -63
- package/dist/_chunks/PkToolShowImageGallery-DmJztS-Z.js.map +0 -1
- package/dist/_chunks/PkToolShowWeather-DcSUbzx0.js.map +0 -1
- package/dist-vue/_chunks/PkChatbotInput-C5QSmt21.js.map +0 -1
- package/dist-vue/_chunks/PkChatbotMessages-DOeUT6YL.js +0 -388
- package/dist-vue/_chunks/PkChatbotMessages-DOeUT6YL.js.map +0 -1
- package/dist-vue/_chunks/PkStreamingMarkdown-BAhC3uGK.js.map +0 -1
- package/dist-vue/_chunks/PkToolShowImageGallery-B7Bt6ZGv.js.map +0 -1
- package/dist-vue/_chunks/PkToolShowWeather-Coq6H0iv.js.map +0 -1
- /package/dist/_chunks/{_plugin-vue_export-helper-BI3pHb34.js → _plugin-vue_export-helper-C6kC663S.js} +0 -0
package/dist-vue/PkChatbot.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as e } from "./_chunks/PkChatbot-
|
|
1
|
+
import { t as e } from "./_chunks/PkChatbot-BEJTYq-D.js";
|
|
2
2
|
export { e as default };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as e } from "./_chunks/PkChatbotFilePreview-
|
|
1
|
+
import { t as e } from "./_chunks/PkChatbotFilePreview-hRNtv2OJ.js";
|
|
2
2
|
export { e as default };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as e } from "./_chunks/PkChatbotInput-
|
|
1
|
+
import { t as e } from "./_chunks/PkChatbotInput-BbGLBVim.js";
|
|
2
2
|
export { e as default };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as e } from "./_chunks/PkChatbotMessages-
|
|
1
|
+
import { t as e } from "./_chunks/PkChatbotMessages-j3ALQmGG.js";
|
|
2
2
|
export { e as default };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as e } from "./_chunks/PkChatbotViewChat-
|
|
1
|
+
import { t as e } from "./_chunks/PkChatbotViewChat-Z05fqNFE.js";
|
|
2
2
|
export { e as default };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { t as e } from "./useChatbotStore-DMDbzuub.js";
|
|
2
2
|
import { t } from "./PkChatbotViewConversations-2xc0o-fO.js";
|
|
3
|
-
import { t as n } from "./PkStreamingMarkdown-
|
|
3
|
+
import { t as n } from "./PkStreamingMarkdown-BBTAwHd_.js";
|
|
4
4
|
import { n as r, t as i } from "./PkChatbotViewProfile-CoT1JnMk.js";
|
|
5
5
|
import { o as a } from "./utils-BegUBK7s.js";
|
|
6
|
-
import { r as o } from "./PkToolShowContactForm-
|
|
7
|
-
import { t as s } from "./PkChatbotViewChat-
|
|
6
|
+
import { r as o } from "./PkToolShowContactForm-BkgfSyw7.js";
|
|
7
|
+
import { t as s } from "./PkChatbotViewChat-Z05fqNFE.js";
|
|
8
8
|
import { Fragment as ee, computed as c, createBlock as l, createCommentVNode as u, createElementBlock as d, createElementVNode as f, createSlots as p, createTextVNode as m, createVNode as h, defineComponent as g, guardReactiveProps as _, mergeModels as v, mergeProps as te, normalizeClass as ne, normalizeProps as y, normalizeStyle as b, openBlock as x, renderList as S, renderSlot as C, toDisplayString as w, toRef as T, unref as E, useModel as D, useSlots as O, watch as k, watchEffect as re, withCtx as A } from "vue";
|
|
9
9
|
import { VvAlert as ie, VvButton as ae, VvButtonGroup as oe, VvDropdown as se, VvDropdownAction as ce, VvIcon as j } from "@volverjs/ui-vue/components";
|
|
10
10
|
import { useI18n as le } from "vue-i18n";
|
|
@@ -187,4 +187,4 @@ var de = { class: "pk-chatbot__header-start" }, fe = ["title"], pe = { key: 0 },
|
|
|
187
187
|
//#endregion
|
|
188
188
|
export { N as t };
|
|
189
189
|
|
|
190
|
-
//# sourceMappingURL=PkChatbot-
|
|
190
|
+
//# sourceMappingURL=PkChatbot-BEJTYq-D.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PkChatbot-B9RSkQmJ.js","names":[],"sources":["../../../../packages/components/src/chat/PkChatbot.vue","../../../../packages/components/src/chat/PkChatbot.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, toRef, watch, watchEffect, useSlots } from 'vue'\n import { storeToRefs } from 'pinia'\n import { useI18n } from 'vue-i18n'\n import type {\n AgentInterface,\n AgentModel,\n AgentFileUpload,\n AgentGatewayOptions,\n ChatMessageActions,\n RevisedAnswer,\n UIChatMessage,\n AgentTools,\n } from 'models'\n import { useChatbotStore } from 'composables'\n import PkAvatar from './PkAvatar.vue'\n import PkChatbotViewChat from './PkChatbotViewChat.vue'\n import PkChatbotViewConversations from './PkChatbotViewConversations.vue'\n import PkChatbotViewProfile from './PkChatbotViewProfile.vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n import { resolveContrastColor } from './utils'\n import { useLocalizedString } from '../composables/useLocalizedString'\n\n // Captured in script setup to avoid TS7022 circular inference in template\n const slots = useSlots()\n\n const { t: $t } = useI18n({\n useScope: 'global',\n })\n\n const props = defineProps<{\n baseUrl: string\n basePath?: string\n agentId: string\n agentType?: 'reasoning' | 'chat'\n userId?: string\n name?: string\n model?: string\n agentModel?: AgentModel\n agentTools?: AgentTools\n agentInterface?: AgentInterface\n actions?: ChatMessageActions[]\n revisedAnswers?: RevisedAnswer[]\n headers?: Record<string, string>\n systemTheme?: 'light' | 'dark'\n agentFileUpload?: AgentFileUpload\n fallbackModels?: string[]\n gatewayOptions?: Partial<AgentGatewayOptions>\n }>()\n const emit = defineEmits<{\n 'message-update': [message: UIChatMessage]\n 'show-info': [message: UIChatMessage]\n revise: [message: UIChatMessage]\n error: [error: { type: string; title: string; status: number }]\n }>()\n\n const chatId = defineModel<string | undefined>('chatId', {\n type: String,\n default: undefined,\n })\n\n const store = useChatbotStore(props.agentId)\n\n const { messages, chat, localChatId, activeView, chatError } =\n storeToRefs(store)\n\n // Ref to store.agentId for watchers (avoids duplicate-key with agentId prop)\n const storeAgentId = toRef(store, 'agentId')\n\n const { startNewChat, stopGeneration, regenerate, navigate } = store\n\n // Sync props → store reactively\n watchEffect(() => {\n store.baseUrl = props.baseUrl\n store.basePath = props.basePath\n store.name = props.name\n store.agentType = props.agentType\n store.userId = props.userId\n store.agentInterface = props.agentInterface\n store.agentModel = props.agentModel\n store.agentTools = props.agentTools\n store.headers = props.headers\n store.revisedAnswers = props.revisedAnswers\n store.model = props.model\n store.actionsInput = props.actions\n store.agentFileUpload = props.agentFileUpload\n store.fallbackModels = props.fallbackModels\n store.gatewayOptions = props.gatewayOptions\n })\n\n // Sync chatId v-model ↔ store (bidirectional)\n // Parent → store: if the parent provides an external chatId, push it into\n // the store so the Chat instance picks it up.\n watch(\n () => chatId.value,\n (id) => {\n if (id && id !== store.localChatId) {\n store.localChatId = id\n }\n },\n { immediate: true },\n )\n // Store → parent: keep the v-model in sync whenever the store changes\n // the chatId internally (e.g. startNewChat).\n watch(localChatId, (id) => {\n chatId.value = id\n })\n\n // Emit structured errors from chat to the parent component\n watch(chatError, (error) => {\n if (!error) {\n return\n }\n try {\n const parsedError = JSON.parse(error.message) as {\n type: string\n title: string\n status: number\n }\n emit('error', parsedError)\n } catch {\n // ignore non-JSON errors\n }\n })\n\n // ui\n const isReasoningAgent = computed(() => props.agentType === 'reasoning')\n const useColorsForAgentHeader = computed(\n () => props.agentInterface?.useColorsForAgentHeader,\n )\n const themeClass = computed(() => {\n let theme = props.agentInterface?.theme\n if (!theme || theme === 'auto') {\n theme = props.systemTheme\n }\n if (!theme) {\n return ['theme']\n }\n return ['theme', `theme--${theme}`]\n })\n const mainColor = computed(() => props.agentInterface?.mainColor)\n const contrastColor = computed(() =>\n resolveContrastColor(props.agentInterface?.textColor, mainColor.value),\n )\n const footerMessage = useLocalizedString(\n () => props.agentInterface?.footerMessage,\n )\n const title = computed(() => {\n if (activeView.value === 'conversations') {\n return $t('label.conversations')\n }\n if (activeView.value === 'profile') {\n return $t('label.profile')\n }\n return props.name\n })\n\n // state\n const isReady = computed(() => chat.value.status === 'ready')\n const activeMessage = computed(() => {\n return messages.value?.[messages.value.length - 1]\n })\n\n // expose\n defineExpose({\n startNewChat,\n regenerate,\n stopGeneration,\n })\n\n // load chat, conversations and feedbacks on agent or chat change\n watch(\n [storeAgentId, localChatId],\n async ([newAgentId, newChatId]) => {\n await store.initialize(newAgentId, newChatId)\n },\n {\n immediate: true,\n },\n )\n // update initial message\n watch(\n () => props.agentInterface?.initialMessage,\n () => {\n if (\n chat.value.messages.length === 1 &&\n chat.value.messages[0].role === 'assistant'\n ) {\n chat.value.messages = []\n }\n },\n { deep: true },\n )\n // load conversations when navigating to conversations view\n watch(activeView, (newView) => {\n if (newView === 'conversations') {\n store.loadConversations(storeAgentId.value)\n }\n })\n // emit message updates for up-to-date context in parent components\n watch(\n activeMessage,\n (message) => {\n if (message) {\n emit('message-update', message)\n }\n },\n {\n deep: true,\n immediate: true,\n },\n )\n</script>\n\n<template>\n <div class=\"pk-chatbot\" :class=\"themeClass\">\n <!-- #region title -->\n <div\n class=\"pk-chatbot__header\"\n :style=\"\n useColorsForAgentHeader\n ? {\n backgroundColor: mainColor,\n }\n : undefined\n \">\n <div class=\"pk-chatbot__header-start\">\n <template v-if=\"activeView !== 'chat'\">\n <VvButton\n v-bind=\"{\n modifiers: useColorsForAgentHeader\n ? `action-quiet-${contrastColor}`\n : 'action-quiet',\n icon: 'ri:arrow-left-s-line',\n title: $t('action.goBack'),\n }\"\n @click=\"navigate('chat')\" />\n <VvIcon\n name=\"ri:history-line\"\n class=\"pk-chatbot__nav-icon\"\n :style=\"\n useColorsForAgentHeader\n ? {\n color: contrastColor,\n }\n : undefined\n \" />\n </template>\n <PkAvatar\n v-else\n modifiers=\"surface ring shrink-0\"\n class=\"pk-chatbot__avatar\"\n :name\n :img-src=\"agentInterface?.logo\" />\n <strong\n class=\"pk-chatbot__title\"\n :title=\"title\"\n :style=\"\n useColorsForAgentHeader\n ? {\n color: contrastColor,\n }\n : undefined\n \">\n {{ title }}\n </strong>\n </div>\n <VvButtonGroup class=\"pk-chatbot__header-end\" modifiers=\"compact\">\n <slot\n name=\"header-actions\"\n v-bind=\"{\n mainColor,\n useColorsForAgentHeader,\n contrastColor,\n startNewChat,\n stopGeneration,\n }\" />\n <VvDropdown\n v-bind=\"{\n placement: 'bottom-end',\n modifiers: 'menu',\n flip: true,\n offset: 3,\n }\">\n <VvButton\n v-bind=\"{\n modifiers: useColorsForAgentHeader\n ? `action-quiet-${contrastColor}`\n : 'action-quiet',\n icon: 'ri:more-2-fill',\n disabled: !isReady,\n title: $t('action.moreActions'),\n }\" />\n <template #items>\n <VvDropdownAction @click=\"startNewChat()\">\n <VvIcon name=\"ri:edit-box-line\" />\n {{ $t('action.startNewChat') }}\n </VvDropdownAction>\n <VvDropdownAction\n v-if=\"!isReasoningAgent\"\n @click=\"navigate('conversations')\">\n <VvIcon name=\"ri:history-line\" />\n {{ $t('action.viewRecentChats') }}\n </VvDropdownAction>\n </template>\n </VvDropdown>\n <slot\n name=\"actions\"\n v-bind=\"{\n mainColor,\n useColorsForAgentHeader,\n contrastColor,\n startNewChat,\n stopGeneration,\n }\" />\n </VvButtonGroup>\n </div>\n <!-- #endregion -->\n\n <div v-if=\"isReasoningAgent\">\n <div class=\"pk-chatbot__warning-body\">\n <VvAlert modifiers=\"callout\">\n <div class=\"pk-chatbot__warning-header\">\n <VvIcon\n name=\"ri:alert-line\"\n class=\"pk-chatbot__warning-icon\" />\n <strong class=\"pk-chatbot__warning-title\">\n {{ $t('message.warning') }}\n </strong>\n </div>\n <p class=\"pk-chatbot__warning-text\">\n {{ $t('message.reasoningAgent') }}\n </p>\n </VvAlert>\n </div>\n </div>\n\n <!-- #region views -->\n <PkChatbotViewChat\n v-if=\"activeView === 'chat'\"\n :agent-id\n @show-info=\"emit('show-info', $event)\"\n @revise=\"emit('revise', $event)\">\n <template\n v-for=\"slotName in Object.keys(slots)\"\n #[slotName]=\"slotData\"\n ><slot :name=\"slotName\" v-bind=\"slotData\"\n /></template>\n </PkChatbotViewChat>\n <PkChatbotViewConversations\n v-else-if=\"activeView === 'conversations'\"\n :agent-id>\n <template\n v-for=\"slotName in Object.keys(slots)\"\n #[slotName]=\"slotData\"\n ><slot :name=\"slotName\" v-bind=\"slotData\"\n /></template>\n </PkChatbotViewConversations>\n <PkChatbotViewProfile v-else :agent-id>\n <template\n v-for=\"slotName in Object.keys(slots)\"\n #[slotName]=\"slotData\"\n ><slot :name=\"slotName\" v-bind=\"slotData\"\n /></template>\n </PkChatbotViewProfile>\n <!-- #endregion -->\n\n <!-- #region footer -->\n <div v-if=\"footerMessage\" class=\"pk-chatbot__footer\">\n <PkStreamingMarkdown :markdown=\"footerMessage\" class=\"wysiwyg\" />\n </div>\n <!-- #endregion -->\n </div>\n</template>\n\n<style lang=\"scss\">\n .pk-chatbot {\n display: flex;\n flex-direction: column;\n position: relative;\n height: 100%;\n background-color: var(--color-surface);\n\n &__header {\n position: sticky;\n top: 0;\n z-index: 1;\n display: flex;\n justify-content: space-between;\n gap: var(--spacing-14);\n background-color: var(--color-surface-1);\n padding: var(--spacing-14);\n border-bottom: 1px solid var(--color-surface-4);\n }\n\n &__header-start {\n display: flex;\n align-items: center;\n gap: var(--spacing-sm);\n min-width: 0;\n }\n\n &__nav-icon {\n font-size: var(--text-18);\n }\n\n &__avatar {\n width: var(--spacing-24);\n height: var(--spacing-24);\n }\n\n &__title {\n font-size: var(--text-16);\n font-weight: 700;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n &__header-end {\n flex-shrink: 0;\n }\n\n &__warning-body {\n padding: var(--spacing-md);\n border-bottom: 1px solid var(--color-surface-4);\n }\n\n &__warning-header {\n display: flex;\n align-items: center;\n gap: var(--spacing-4);\n margin-bottom: var(--spacing-4);\n }\n\n &__warning-icon {\n width: var(--spacing-16);\n height: var(--spacing-16);\n }\n\n &__warning-title {\n font-weight: 600;\n font-size: var(--text-14);\n }\n\n &__warning-text {\n font-size: var(--text-12);\n color: var(--color-word-3);\n }\n\n &__footer {\n padding: var(--spacing-md);\n border-top: 1px solid var(--color-surface-4);\n text-align: center;\n font-size: var(--text-12);\n color: var(--color-word-2);\n }\n }\n</style>\n","<script setup lang=\"ts\">\n import { computed, toRef, watch, watchEffect, useSlots } from 'vue'\n import { storeToRefs } from 'pinia'\n import { useI18n } from 'vue-i18n'\n import type {\n AgentInterface,\n AgentModel,\n AgentFileUpload,\n AgentGatewayOptions,\n ChatMessageActions,\n RevisedAnswer,\n UIChatMessage,\n AgentTools,\n } from 'models'\n import { useChatbotStore } from 'composables'\n import PkAvatar from './PkAvatar.vue'\n import PkChatbotViewChat from './PkChatbotViewChat.vue'\n import PkChatbotViewConversations from './PkChatbotViewConversations.vue'\n import PkChatbotViewProfile from './PkChatbotViewProfile.vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n import { resolveContrastColor } from './utils'\n import { useLocalizedString } from '../composables/useLocalizedString'\n\n // Captured in script setup to avoid TS7022 circular inference in template\n const slots = useSlots()\n\n const { t: $t } = useI18n({\n useScope: 'global',\n })\n\n const props = defineProps<{\n baseUrl: string\n basePath?: string\n agentId: string\n agentType?: 'reasoning' | 'chat'\n userId?: string\n name?: string\n model?: string\n agentModel?: AgentModel\n agentTools?: AgentTools\n agentInterface?: AgentInterface\n actions?: ChatMessageActions[]\n revisedAnswers?: RevisedAnswer[]\n headers?: Record<string, string>\n systemTheme?: 'light' | 'dark'\n agentFileUpload?: AgentFileUpload\n fallbackModels?: string[]\n gatewayOptions?: Partial<AgentGatewayOptions>\n }>()\n const emit = defineEmits<{\n 'message-update': [message: UIChatMessage]\n 'show-info': [message: UIChatMessage]\n revise: [message: UIChatMessage]\n error: [error: { type: string; title: string; status: number }]\n }>()\n\n const chatId = defineModel<string | undefined>('chatId', {\n type: String,\n default: undefined,\n })\n\n const store = useChatbotStore(props.agentId)\n\n const { messages, chat, localChatId, activeView, chatError } =\n storeToRefs(store)\n\n // Ref to store.agentId for watchers (avoids duplicate-key with agentId prop)\n const storeAgentId = toRef(store, 'agentId')\n\n const { startNewChat, stopGeneration, regenerate, navigate } = store\n\n // Sync props → store reactively\n watchEffect(() => {\n store.baseUrl = props.baseUrl\n store.basePath = props.basePath\n store.name = props.name\n store.agentType = props.agentType\n store.userId = props.userId\n store.agentInterface = props.agentInterface\n store.agentModel = props.agentModel\n store.agentTools = props.agentTools\n store.headers = props.headers\n store.revisedAnswers = props.revisedAnswers\n store.model = props.model\n store.actionsInput = props.actions\n store.agentFileUpload = props.agentFileUpload\n store.fallbackModels = props.fallbackModels\n store.gatewayOptions = props.gatewayOptions\n })\n\n // Sync chatId v-model ↔ store (bidirectional)\n // Parent → store: if the parent provides an external chatId, push it into\n // the store so the Chat instance picks it up.\n watch(\n () => chatId.value,\n (id) => {\n if (id && id !== store.localChatId) {\n store.localChatId = id\n }\n },\n { immediate: true },\n )\n // Store → parent: keep the v-model in sync whenever the store changes\n // the chatId internally (e.g. startNewChat).\n watch(localChatId, (id) => {\n chatId.value = id\n })\n\n // Emit structured errors from chat to the parent component\n watch(chatError, (error) => {\n if (!error) {\n return\n }\n try {\n const parsedError = JSON.parse(error.message) as {\n type: string\n title: string\n status: number\n }\n emit('error', parsedError)\n } catch {\n // ignore non-JSON errors\n }\n })\n\n // ui\n const isReasoningAgent = computed(() => props.agentType === 'reasoning')\n const useColorsForAgentHeader = computed(\n () => props.agentInterface?.useColorsForAgentHeader,\n )\n const themeClass = computed(() => {\n let theme = props.agentInterface?.theme\n if (!theme || theme === 'auto') {\n theme = props.systemTheme\n }\n if (!theme) {\n return ['theme']\n }\n return ['theme', `theme--${theme}`]\n })\n const mainColor = computed(() => props.agentInterface?.mainColor)\n const contrastColor = computed(() =>\n resolveContrastColor(props.agentInterface?.textColor, mainColor.value),\n )\n const footerMessage = useLocalizedString(\n () => props.agentInterface?.footerMessage,\n )\n const title = computed(() => {\n if (activeView.value === 'conversations') {\n return $t('label.conversations')\n }\n if (activeView.value === 'profile') {\n return $t('label.profile')\n }\n return props.name\n })\n\n // state\n const isReady = computed(() => chat.value.status === 'ready')\n const activeMessage = computed(() => {\n return messages.value?.[messages.value.length - 1]\n })\n\n // expose\n defineExpose({\n startNewChat,\n regenerate,\n stopGeneration,\n })\n\n // load chat, conversations and feedbacks on agent or chat change\n watch(\n [storeAgentId, localChatId],\n async ([newAgentId, newChatId]) => {\n await store.initialize(newAgentId, newChatId)\n },\n {\n immediate: true,\n },\n )\n // update initial message\n watch(\n () => props.agentInterface?.initialMessage,\n () => {\n if (\n chat.value.messages.length === 1 &&\n chat.value.messages[0].role === 'assistant'\n ) {\n chat.value.messages = []\n }\n },\n { deep: true },\n )\n // load conversations when navigating to conversations view\n watch(activeView, (newView) => {\n if (newView === 'conversations') {\n store.loadConversations(storeAgentId.value)\n }\n })\n // emit message updates for up-to-date context in parent components\n watch(\n activeMessage,\n (message) => {\n if (message) {\n emit('message-update', message)\n }\n },\n {\n deep: true,\n immediate: true,\n },\n )\n</script>\n\n<template>\n <div class=\"pk-chatbot\" :class=\"themeClass\">\n <!-- #region title -->\n <div\n class=\"pk-chatbot__header\"\n :style=\"\n useColorsForAgentHeader\n ? {\n backgroundColor: mainColor,\n }\n : undefined\n \">\n <div class=\"pk-chatbot__header-start\">\n <template v-if=\"activeView !== 'chat'\">\n <VvButton\n v-bind=\"{\n modifiers: useColorsForAgentHeader\n ? `action-quiet-${contrastColor}`\n : 'action-quiet',\n icon: 'ri:arrow-left-s-line',\n title: $t('action.goBack'),\n }\"\n @click=\"navigate('chat')\" />\n <VvIcon\n name=\"ri:history-line\"\n class=\"pk-chatbot__nav-icon\"\n :style=\"\n useColorsForAgentHeader\n ? {\n color: contrastColor,\n }\n : undefined\n \" />\n </template>\n <PkAvatar\n v-else\n modifiers=\"surface ring shrink-0\"\n class=\"pk-chatbot__avatar\"\n :name\n :img-src=\"agentInterface?.logo\" />\n <strong\n class=\"pk-chatbot__title\"\n :title=\"title\"\n :style=\"\n useColorsForAgentHeader\n ? {\n color: contrastColor,\n }\n : undefined\n \">\n {{ title }}\n </strong>\n </div>\n <VvButtonGroup class=\"pk-chatbot__header-end\" modifiers=\"compact\">\n <slot\n name=\"header-actions\"\n v-bind=\"{\n mainColor,\n useColorsForAgentHeader,\n contrastColor,\n startNewChat,\n stopGeneration,\n }\" />\n <VvDropdown\n v-bind=\"{\n placement: 'bottom-end',\n modifiers: 'menu',\n flip: true,\n offset: 3,\n }\">\n <VvButton\n v-bind=\"{\n modifiers: useColorsForAgentHeader\n ? `action-quiet-${contrastColor}`\n : 'action-quiet',\n icon: 'ri:more-2-fill',\n disabled: !isReady,\n title: $t('action.moreActions'),\n }\" />\n <template #items>\n <VvDropdownAction @click=\"startNewChat()\">\n <VvIcon name=\"ri:edit-box-line\" />\n {{ $t('action.startNewChat') }}\n </VvDropdownAction>\n <VvDropdownAction\n v-if=\"!isReasoningAgent\"\n @click=\"navigate('conversations')\">\n <VvIcon name=\"ri:history-line\" />\n {{ $t('action.viewRecentChats') }}\n </VvDropdownAction>\n </template>\n </VvDropdown>\n <slot\n name=\"actions\"\n v-bind=\"{\n mainColor,\n useColorsForAgentHeader,\n contrastColor,\n startNewChat,\n stopGeneration,\n }\" />\n </VvButtonGroup>\n </div>\n <!-- #endregion -->\n\n <div v-if=\"isReasoningAgent\">\n <div class=\"pk-chatbot__warning-body\">\n <VvAlert modifiers=\"callout\">\n <div class=\"pk-chatbot__warning-header\">\n <VvIcon\n name=\"ri:alert-line\"\n class=\"pk-chatbot__warning-icon\" />\n <strong class=\"pk-chatbot__warning-title\">\n {{ $t('message.warning') }}\n </strong>\n </div>\n <p class=\"pk-chatbot__warning-text\">\n {{ $t('message.reasoningAgent') }}\n </p>\n </VvAlert>\n </div>\n </div>\n\n <!-- #region views -->\n <PkChatbotViewChat\n v-if=\"activeView === 'chat'\"\n :agent-id\n @show-info=\"emit('show-info', $event)\"\n @revise=\"emit('revise', $event)\">\n <template\n v-for=\"slotName in Object.keys(slots)\"\n #[slotName]=\"slotData\"\n ><slot :name=\"slotName\" v-bind=\"slotData\"\n /></template>\n </PkChatbotViewChat>\n <PkChatbotViewConversations\n v-else-if=\"activeView === 'conversations'\"\n :agent-id>\n <template\n v-for=\"slotName in Object.keys(slots)\"\n #[slotName]=\"slotData\"\n ><slot :name=\"slotName\" v-bind=\"slotData\"\n /></template>\n </PkChatbotViewConversations>\n <PkChatbotViewProfile v-else :agent-id>\n <template\n v-for=\"slotName in Object.keys(slots)\"\n #[slotName]=\"slotData\"\n ><slot :name=\"slotName\" v-bind=\"slotData\"\n /></template>\n </PkChatbotViewProfile>\n <!-- #endregion -->\n\n <!-- #region footer -->\n <div v-if=\"footerMessage\" class=\"pk-chatbot__footer\">\n <PkStreamingMarkdown :markdown=\"footerMessage\" class=\"wysiwyg\" />\n </div>\n <!-- #endregion -->\n </div>\n</template>\n\n<style lang=\"scss\">\n .pk-chatbot {\n display: flex;\n flex-direction: column;\n position: relative;\n height: 100%;\n background-color: var(--color-surface);\n\n &__header {\n position: sticky;\n top: 0;\n z-index: 1;\n display: flex;\n justify-content: space-between;\n gap: var(--spacing-14);\n background-color: var(--color-surface-1);\n padding: var(--spacing-14);\n border-bottom: 1px solid var(--color-surface-4);\n }\n\n &__header-start {\n display: flex;\n align-items: center;\n gap: var(--spacing-sm);\n min-width: 0;\n }\n\n &__nav-icon {\n font-size: var(--text-18);\n }\n\n &__avatar {\n width: var(--spacing-24);\n height: var(--spacing-24);\n }\n\n &__title {\n font-size: var(--text-16);\n font-weight: 700;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n &__header-end {\n flex-shrink: 0;\n }\n\n &__warning-body {\n padding: var(--spacing-md);\n border-bottom: 1px solid var(--color-surface-4);\n }\n\n &__warning-header {\n display: flex;\n align-items: center;\n gap: var(--spacing-4);\n margin-bottom: var(--spacing-4);\n }\n\n &__warning-icon {\n width: var(--spacing-16);\n height: var(--spacing-16);\n }\n\n &__warning-title {\n font-weight: 600;\n font-size: var(--text-14);\n }\n\n &__warning-text {\n font-size: var(--text-12);\n color: var(--color-word-3);\n }\n\n &__footer {\n padding: var(--spacing-md);\n border-top: 1px solid var(--color-surface-4);\n text-align: center;\n font-size: var(--text-12);\n color: var(--color-word-2);\n }\n }\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwBI,IAAM,IAAQ,GAAS,EAEjB,EAAE,GAAG,MAAO,GAAQ,EACtB,UAAU,UACb,CAAA,EAEK,IAAQ,GAmBR,IAAO,GAOP,IAAS,EAA+B,GAAC,SAG9C,EAEK,IAAQ,EAAgB,EAAM,QAAO,EAErC,EAAE,aAAU,SAAM,gBAAa,eAAY,kBAC7C,GAAY,EAAK,EAGf,IAAe,EAAM,GAAO,UAAS,EAErC,EAAE,iBAAc,mBAAgB,gBAAY,gBAAa;AAwC/D,EArCA,SAAkB;AAed,GAdA,EAAM,UAAU,EAAM,SACtB,EAAM,WAAW,EAAM,UACvB,EAAM,OAAO,EAAM,MACnB,EAAM,YAAY,EAAM,WACxB,EAAM,SAAS,EAAM,QACrB,EAAM,iBAAiB,EAAM,gBAC7B,EAAM,aAAa,EAAM,YACzB,EAAM,aAAa,EAAM,YACzB,EAAM,UAAU,EAAM,SACtB,EAAM,iBAAiB,EAAM,gBAC7B,EAAM,QAAQ,EAAM,OACpB,EAAM,eAAe,EAAM,SAC3B,EAAM,kBAAkB,EAAM,iBAC9B,EAAM,iBAAiB,EAAM,gBAC7B,EAAM,iBAAiB,EAAM;IAChC,EAKD,QACU,EAAO,QACZ,MAAO;AACJ,GAAI,KAAM,MAAO,EAAM,gBACnB,EAAM,cAAc;KAG5B,EAAE,WAAW,IAAM,CACvB,EAGA,EAAM,IAAc,MAAO;AACvB,KAAO,QAAQ;IAClB,EAGD,EAAM,KAAY,MAAU;AACnB,SAGL,KAAI;AAMA,MAAK,SALe,KAAK,MAAM,EAAM,QAKvB,CAAW;WACrB;IAGX;EAGD,IAAM,IAAmB,QAAe,EAAM,cAAc,YAAW,EACjE,IAA0B,QACtB,EAAM,gBAAgB,wBAChC,EACM,KAAa,QAAe;GAC9B,IAAI,IAAQ,EAAM,gBAAgB;AAOlC,WANI,CAAC,KAAS,MAAU,YACpB,IAAQ,EAAM,cAEb,IAGE,CAAC,SAAS,UAAU,IAAO,GAFvB,CAAC,QAAO;IAGtB,EACK,IAAY,QAAe,EAAM,gBAAgB,UAAS,EAC1D,IAAgB,QAClB,EAAqB,EAAM,gBAAgB,WAAW,EAAU,MAAM,CAC1E,EACM,IAAgB,QACZ,EAAM,gBAAgB,cAChC,EACM,IAAQ,QACN,EAAW,UAAU,kBACd,EAAG,sBAAqB,GAE/B,EAAW,UAAU,YACd,EAAG,gBAAe,GAEtB,EAAM,KAChB,EAGK,KAAU,QAAe,EAAK,MAAM,WAAW,QAAO,EACtD,KAAgB,QACX,EAAS,QAAQ,EAAS,MAAM,SAAS,GACnD;SAGD,EAAa;GACT;GACA;GACA;GACH,CAAA,EAGD,EACI,CAAC,GAAc,EAAY,EAC3B,OAAO,CAAC,GAAY,OAAe;AAC/B,SAAM,EAAM,WAAW,GAAY,EAAS;KAEhD,EACI,WAAW,IACd,CACL,EAEA,QACU,EAAM,gBAAgB,sBACtB;AACF,GACI,EAAK,MAAM,SAAS,WAAW,KAC/B,EAAK,MAAM,SAAS,GAAG,SAAS,gBAEhC,EAAK,MAAM,WAAW,EAAC;KAG/B,EAAE,MAAM,IAAM,CAClB,EAEA,EAAM,IAAa,MAAY;AAC3B,GAAI,MAAY,mBACZ,EAAM,kBAAkB,EAAa,MAAK;IAEjD,EAED,EACI,KACC,MAAY;AACT,GAAI,KACA,EAAK,kBAAkB,EAAO;KAGtC;GACI,MAAM;GACN,WAAW;GACd,CACL;;eAIA,EA6JM,OAAA,EA7JD,OAAK,GAAA,CAAC,cAAqB,GAAA,MAAU,CAAA,EAAA,EAAA;IAEtC,EAmGM,OAAA;KAlGF,OAAM;KACL,OAAK,EAAmB,EAAA,QAAA,EAAA,iBAA2F,EAAA,OAAA,GAAyD,KAAA,EAAA;QAO7K,EAwCM,OAxCN,IAwCM,CAvCc,EAAA,EAAU,KAAA,eAqB1B,EAKsC,GAAA;;KAHlC,WAAU;KACV,OAAM;KACL,MAAA,EAAA;KACA,WAAS,EAAA,gBAAgB;yCA1BJ,GAAA,EAA1B,EAoBW,IAAA,EAAA,KAAA,GAAA,EAAA,CAnBP,EAQgC,GARhC,GAQgC;gBAPqB,EAAA,QAAA,gBAA0E,EAAA,UAAA;;YAA+J,EAAA,EAAE,CAAA,gBAAA;SAO3R,SAAK,AAAA,EAAA,QAAA,MAAE,EAAA,EAAQ,CAAA,OAAA,EAAA,CAAA,EAAA,MAAA,GAAA,EACpB,EASQ,GAAA;KARJ,MAAK;KACL,OAAM;KACL,OAAK,EAA+B,EAAA,QAAA,EAAA,OAAyG,EAAA,OAAA,GAAqF,KAAA,EAAA;mCAc3O,EAWS,UAAA;KAVL,OAAM;KACL,OAAO,EAAA;KACP,OAAK,EAA2B,EAAA,QAAA,EAAA,OAAiG,EAAA,OAAA,GAA6E,KAAA,EAAA;SAO5M,EAAA,MAAK,EAAA,IAAA,GAAA,CAAA,CAAA,EAGhB,EAgDgB,GAAA;KAhDD,OAAM;KAAyB,WAAU;;sBAS3C;MART,EAQS,EAAA,QAAA,kBAAA,EAAA,EAAA;kBAN6B,EAAA;gCAAmC,EAAA;sBAAiD,EAAA;qBAAuC,EAAA,EAAY;uBAA0B,EAAA,EAAA;;MAOvM,EA4Ba,GAAA,EAAA,EA3BD;;;;;OAKP,CAAA,CAAA,EAAA;OAUU,OAAK,QAIO,CAHnB,EAGmB,GAAA,EAHA,SAAK,AAAA,EAAA,QAAA,MAAE,EAAA,EAAY,EAAA,EAAA,EAAA;yBACA,CAAlC,EAAkC,GAAA,EAA1B,MAAK,oBAAkB,CAAA,EAAA,EAAG,MAClC,EAAG,EAAA,EAAE,CAAA,sBAAA,CAAA,EAAA,EAAA,CAAA,CAAA;;WAGE,EAAA,qBAAA,GAAA,EADX,EAKmB,GAAA;;QAHd,SAAK,AAAA,EAAA,QAAA,MAAE,EAAA,EAAQ,CAAA,gBAAA;;yBACiB,CAAjC,EAAiC,GAAA,EAAzB,MAAK,mBAAiB,CAAA,EAAA,EAAG,MACjC,EAAG,EAAA,EAAE,CAAA,yBAAA,CAAA,EAAA,EAAA,CAAA,CAAA;;;wBAVJ,CART,EAQS,GAAA,EAAA,EAAA;mBAP4C,EAAA,QAAA,gBAA0E,EAAA,UAAA;;mBAA6J,GAAA;eAA4C,EAAA,EAAE,CAAA,qBAAA;;;;MAqB9U,EAQS,EAAA,QAAA,WAAA,EAAA,EAAA;kBAN6B,EAAA;gCAAmC,EAAA;sBAAiD,EAAA;qBAAuC,EAAA,EAAY;uBAA0B,EAAA,EAAA;;;;;IAWpM,EAAA,SAAA,GAAA,EAAX,EAgBM,OAAA,IAAA,CAfF,EAcM,OAdN,IAcM,CAbF,EAYU,GAAA,EAZD,WAAU,WAAS,EAAA;sBAQlB,CAPN,EAOM,OAPN,IAOM,CANF,EAEuC,GAAA;MADnC,MAAK;MACL,OAAM;SACV,EAES,UAFT,IAES,EADF,EAAA,EAAE,CAAA,kBAAA,CAAA,EAAA,EAAA,CAAA,CAAA,EAGb,EAEI,KAFJ,IAEI,EADG,EAAA,EAAE,CAAA,yBAAA,CAAA,EAAA,EAAA,CAAA,CAAA;;;IAQX,EAAA,EAAU,KAAA,UAAA,GAAA,EADpB,EAUoB,GAAA;;KARf,YAAA,EAAA;KACA,YAAS,AAAA,EAAA,QAAA,MAAE,EAAI,aAAc,EAAM;KACnC,UAAM,AAAA,EAAA,QAAA,MAAE,EAAI,UAAW,EAAM;sBAEP,OAAO,KAAK,EAAA,EAAK,CAAA,GAA7B;WACN;YAAY,MAAQ,CACpB,EACH,EAAA,QADgB,GAAQ,EAAA,EAAU,EAAQ,CAAA,CAAA,CAAA,CAAA;kCAIjC,EAAA,EAAU,KAAA,mBAAA,GAAA,EADzB,EAQ6B,GAAA;;KANxB,YAAA,EAAA;sBAEsB,OAAO,KAAK,EAAA,EAAK,CAAA,GAA7B;WACN;YAAY,MAAQ,CACpB,EACH,EAAA,QADgB,GAAQ,EAAA,EAAU,EAAQ,CAAA,CAAA,CAAA,CAAA;wCAGhD,EAMuB,GAAA;;KANO,YAAA,EAAA;sBAEH,OAAO,KAAK,EAAA,EAAK,CAAA,GAA7B;WACN;YAAY,MAAQ,CACpB,EACH,EAAA,QADgB,GAAQ,EAAA,EAAU,EAAQ,CAAA,CAAA,CAAA,CAAA;;IAMrC,EAAA,EAAa,IAAA,GAAA,EAAxB,EAEM,OAFN,GAEM,CADF,EAAiE,GAAA;KAA3C,UAAU,EAAA,EAAa;KAAE,OAAM"}
|
|
1
|
+
{"version":3,"file":"PkChatbot-BEJTYq-D.js","names":[],"sources":["../../../../packages/components/src/chat/PkChatbot.vue","../../../../packages/components/src/chat/PkChatbot.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, toRef, watch, watchEffect, useSlots } from 'vue'\n import { storeToRefs } from 'pinia'\n import { useI18n } from 'vue-i18n'\n import type {\n AgentInterface,\n AgentModel,\n AgentFileUpload,\n AgentGatewayOptions,\n ChatMessageActions,\n RevisedAnswer,\n UIChatMessage,\n AgentTools,\n } from 'models'\n import { useChatbotStore } from 'composables'\n import PkAvatar from './PkAvatar.vue'\n import PkChatbotViewChat from './PkChatbotViewChat.vue'\n import PkChatbotViewConversations from './PkChatbotViewConversations.vue'\n import PkChatbotViewProfile from './PkChatbotViewProfile.vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n import { resolveContrastColor } from './utils'\n import { useLocalizedString } from '../composables/useLocalizedString'\n\n // Captured in script setup to avoid TS7022 circular inference in template\n const slots = useSlots()\n\n const { t: $t } = useI18n({\n useScope: 'global',\n })\n\n const props = defineProps<{\n baseUrl: string\n basePath?: string\n agentId: string\n agentType?: 'reasoning' | 'chat'\n userId?: string\n name?: string\n model?: string\n agentModel?: AgentModel\n agentTools?: AgentTools\n agentInterface?: AgentInterface\n actions?: ChatMessageActions[]\n revisedAnswers?: RevisedAnswer[]\n headers?: Record<string, string>\n systemTheme?: 'light' | 'dark'\n agentFileUpload?: AgentFileUpload\n fallbackModels?: string[]\n gatewayOptions?: Partial<AgentGatewayOptions>\n }>()\n const emit = defineEmits<{\n 'message-update': [message: UIChatMessage]\n 'show-info': [message: UIChatMessage]\n revise: [message: UIChatMessage]\n error: [error: { type: string; title: string; status: number }]\n }>()\n\n const chatId = defineModel<string | undefined>('chatId', {\n type: String,\n default: undefined,\n })\n\n const store = useChatbotStore(props.agentId)\n\n const { messages, chat, localChatId, activeView, chatError } =\n storeToRefs(store)\n\n // Ref to store.agentId for watchers (avoids duplicate-key with agentId prop)\n const storeAgentId = toRef(store, 'agentId')\n\n const { startNewChat, stopGeneration, regenerate, navigate } = store\n\n // Sync props → store reactively\n watchEffect(() => {\n store.baseUrl = props.baseUrl\n store.basePath = props.basePath\n store.name = props.name\n store.agentType = props.agentType\n store.userId = props.userId\n store.agentInterface = props.agentInterface\n store.agentModel = props.agentModel\n store.agentTools = props.agentTools\n store.headers = props.headers\n store.revisedAnswers = props.revisedAnswers\n store.model = props.model\n store.actionsInput = props.actions\n store.agentFileUpload = props.agentFileUpload\n store.fallbackModels = props.fallbackModels\n store.gatewayOptions = props.gatewayOptions\n })\n\n // Sync chatId v-model ↔ store (bidirectional)\n // Parent → store: if the parent provides an external chatId, push it into\n // the store so the Chat instance picks it up.\n watch(\n () => chatId.value,\n (id) => {\n if (id && id !== store.localChatId) {\n store.localChatId = id\n }\n },\n { immediate: true },\n )\n // Store → parent: keep the v-model in sync whenever the store changes\n // the chatId internally (e.g. startNewChat).\n watch(localChatId, (id) => {\n chatId.value = id\n })\n\n // Emit structured errors from chat to the parent component\n watch(chatError, (error) => {\n if (!error) {\n return\n }\n try {\n const parsedError = JSON.parse(error.message) as {\n type: string\n title: string\n status: number\n }\n emit('error', parsedError)\n } catch {\n // ignore non-JSON errors\n }\n })\n\n // ui\n const isReasoningAgent = computed(() => props.agentType === 'reasoning')\n const useColorsForAgentHeader = computed(\n () => props.agentInterface?.useColorsForAgentHeader,\n )\n const themeClass = computed(() => {\n let theme = props.agentInterface?.theme\n if (!theme || theme === 'auto') {\n theme = props.systemTheme\n }\n if (!theme) {\n return ['theme']\n }\n return ['theme', `theme--${theme}`]\n })\n const mainColor = computed(() => props.agentInterface?.mainColor)\n const contrastColor = computed(() =>\n resolveContrastColor(props.agentInterface?.textColor, mainColor.value),\n )\n const footerMessage = useLocalizedString(\n () => props.agentInterface?.footerMessage,\n )\n const title = computed(() => {\n if (activeView.value === 'conversations') {\n return $t('label.conversations')\n }\n if (activeView.value === 'profile') {\n return $t('label.profile')\n }\n return props.name\n })\n\n // state\n const isReady = computed(() => chat.value.status === 'ready')\n const activeMessage = computed(() => {\n return messages.value?.[messages.value.length - 1]\n })\n\n // expose\n defineExpose({\n startNewChat,\n regenerate,\n stopGeneration,\n })\n\n // load chat, conversations and feedbacks on agent or chat change\n watch(\n [storeAgentId, localChatId],\n async ([newAgentId, newChatId]) => {\n await store.initialize(newAgentId, newChatId)\n },\n {\n immediate: true,\n },\n )\n // update initial message\n watch(\n () => props.agentInterface?.initialMessage,\n () => {\n if (\n chat.value.messages.length === 1 &&\n chat.value.messages[0].role === 'assistant'\n ) {\n chat.value.messages = []\n }\n },\n { deep: true },\n )\n // load conversations when navigating to conversations view\n watch(activeView, (newView) => {\n if (newView === 'conversations') {\n store.loadConversations(storeAgentId.value)\n }\n })\n // emit message updates for up-to-date context in parent components\n watch(\n activeMessage,\n (message) => {\n if (message) {\n emit('message-update', message)\n }\n },\n {\n deep: true,\n immediate: true,\n },\n )\n</script>\n\n<template>\n <div class=\"pk-chatbot\" :class=\"themeClass\">\n <!-- #region title -->\n <div\n class=\"pk-chatbot__header\"\n :style=\"\n useColorsForAgentHeader\n ? {\n backgroundColor: mainColor,\n }\n : undefined\n \">\n <div class=\"pk-chatbot__header-start\">\n <template v-if=\"activeView !== 'chat'\">\n <VvButton\n v-bind=\"{\n modifiers: useColorsForAgentHeader\n ? `action-quiet-${contrastColor}`\n : 'action-quiet',\n icon: 'ri:arrow-left-s-line',\n title: $t('action.goBack'),\n }\"\n @click=\"navigate('chat')\" />\n <VvIcon\n name=\"ri:history-line\"\n class=\"pk-chatbot__nav-icon\"\n :style=\"\n useColorsForAgentHeader\n ? {\n color: contrastColor,\n }\n : undefined\n \" />\n </template>\n <PkAvatar\n v-else\n modifiers=\"surface ring shrink-0\"\n class=\"pk-chatbot__avatar\"\n :name\n :img-src=\"agentInterface?.logo\" />\n <strong\n class=\"pk-chatbot__title\"\n :title=\"title\"\n :style=\"\n useColorsForAgentHeader\n ? {\n color: contrastColor,\n }\n : undefined\n \">\n {{ title }}\n </strong>\n </div>\n <VvButtonGroup class=\"pk-chatbot__header-end\" modifiers=\"compact\">\n <slot\n name=\"header-actions\"\n v-bind=\"{\n mainColor,\n useColorsForAgentHeader,\n contrastColor,\n startNewChat,\n stopGeneration,\n }\" />\n <VvDropdown\n v-bind=\"{\n placement: 'bottom-end',\n modifiers: 'menu',\n flip: true,\n offset: 3,\n }\">\n <VvButton\n v-bind=\"{\n modifiers: useColorsForAgentHeader\n ? `action-quiet-${contrastColor}`\n : 'action-quiet',\n icon: 'ri:more-2-fill',\n disabled: !isReady,\n title: $t('action.moreActions'),\n }\" />\n <template #items>\n <VvDropdownAction @click=\"startNewChat()\">\n <VvIcon name=\"ri:edit-box-line\" />\n {{ $t('action.startNewChat') }}\n </VvDropdownAction>\n <VvDropdownAction\n v-if=\"!isReasoningAgent\"\n @click=\"navigate('conversations')\">\n <VvIcon name=\"ri:history-line\" />\n {{ $t('action.viewRecentChats') }}\n </VvDropdownAction>\n </template>\n </VvDropdown>\n <slot\n name=\"actions\"\n v-bind=\"{\n mainColor,\n useColorsForAgentHeader,\n contrastColor,\n startNewChat,\n stopGeneration,\n }\" />\n </VvButtonGroup>\n </div>\n <!-- #endregion -->\n\n <div v-if=\"isReasoningAgent\">\n <div class=\"pk-chatbot__warning-body\">\n <VvAlert modifiers=\"callout\">\n <div class=\"pk-chatbot__warning-header\">\n <VvIcon\n name=\"ri:alert-line\"\n class=\"pk-chatbot__warning-icon\" />\n <strong class=\"pk-chatbot__warning-title\">\n {{ $t('message.warning') }}\n </strong>\n </div>\n <p class=\"pk-chatbot__warning-text\">\n {{ $t('message.reasoningAgent') }}\n </p>\n </VvAlert>\n </div>\n </div>\n\n <!-- #region views -->\n <PkChatbotViewChat\n v-if=\"activeView === 'chat'\"\n :agent-id\n @show-info=\"emit('show-info', $event)\"\n @revise=\"emit('revise', $event)\">\n <template\n v-for=\"slotName in Object.keys(slots)\"\n #[slotName]=\"slotData\"\n ><slot :name=\"slotName\" v-bind=\"slotData\"\n /></template>\n </PkChatbotViewChat>\n <PkChatbotViewConversations\n v-else-if=\"activeView === 'conversations'\"\n :agent-id>\n <template\n v-for=\"slotName in Object.keys(slots)\"\n #[slotName]=\"slotData\"\n ><slot :name=\"slotName\" v-bind=\"slotData\"\n /></template>\n </PkChatbotViewConversations>\n <PkChatbotViewProfile v-else :agent-id>\n <template\n v-for=\"slotName in Object.keys(slots)\"\n #[slotName]=\"slotData\"\n ><slot :name=\"slotName\" v-bind=\"slotData\"\n /></template>\n </PkChatbotViewProfile>\n <!-- #endregion -->\n\n <!-- #region footer -->\n <div v-if=\"footerMessage\" class=\"pk-chatbot__footer\">\n <PkStreamingMarkdown :markdown=\"footerMessage\" class=\"wysiwyg\" />\n </div>\n <!-- #endregion -->\n </div>\n</template>\n\n<style lang=\"scss\">\n .pk-chatbot {\n display: flex;\n flex-direction: column;\n position: relative;\n height: 100%;\n background-color: var(--color-surface);\n\n &__header {\n position: sticky;\n top: 0;\n z-index: 1;\n display: flex;\n justify-content: space-between;\n gap: var(--spacing-14);\n background-color: var(--color-surface-1);\n padding: var(--spacing-14);\n border-bottom: 1px solid var(--color-surface-4);\n }\n\n &__header-start {\n display: flex;\n align-items: center;\n gap: var(--spacing-sm);\n min-width: 0;\n }\n\n &__nav-icon {\n font-size: var(--text-18);\n }\n\n &__avatar {\n width: var(--spacing-24);\n height: var(--spacing-24);\n }\n\n &__title {\n font-size: var(--text-16);\n font-weight: 700;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n &__header-end {\n flex-shrink: 0;\n }\n\n &__warning-body {\n padding: var(--spacing-md);\n border-bottom: 1px solid var(--color-surface-4);\n }\n\n &__warning-header {\n display: flex;\n align-items: center;\n gap: var(--spacing-4);\n margin-bottom: var(--spacing-4);\n }\n\n &__warning-icon {\n width: var(--spacing-16);\n height: var(--spacing-16);\n }\n\n &__warning-title {\n font-weight: 600;\n font-size: var(--text-14);\n }\n\n &__warning-text {\n font-size: var(--text-12);\n color: var(--color-word-3);\n }\n\n &__footer {\n padding: var(--spacing-md);\n border-top: 1px solid var(--color-surface-4);\n text-align: center;\n font-size: var(--text-12);\n color: var(--color-word-2);\n }\n }\n</style>\n","<script setup lang=\"ts\">\n import { computed, toRef, watch, watchEffect, useSlots } from 'vue'\n import { storeToRefs } from 'pinia'\n import { useI18n } from 'vue-i18n'\n import type {\n AgentInterface,\n AgentModel,\n AgentFileUpload,\n AgentGatewayOptions,\n ChatMessageActions,\n RevisedAnswer,\n UIChatMessage,\n AgentTools,\n } from 'models'\n import { useChatbotStore } from 'composables'\n import PkAvatar from './PkAvatar.vue'\n import PkChatbotViewChat from './PkChatbotViewChat.vue'\n import PkChatbotViewConversations from './PkChatbotViewConversations.vue'\n import PkChatbotViewProfile from './PkChatbotViewProfile.vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n import { resolveContrastColor } from './utils'\n import { useLocalizedString } from '../composables/useLocalizedString'\n\n // Captured in script setup to avoid TS7022 circular inference in template\n const slots = useSlots()\n\n const { t: $t } = useI18n({\n useScope: 'global',\n })\n\n const props = defineProps<{\n baseUrl: string\n basePath?: string\n agentId: string\n agentType?: 'reasoning' | 'chat'\n userId?: string\n name?: string\n model?: string\n agentModel?: AgentModel\n agentTools?: AgentTools\n agentInterface?: AgentInterface\n actions?: ChatMessageActions[]\n revisedAnswers?: RevisedAnswer[]\n headers?: Record<string, string>\n systemTheme?: 'light' | 'dark'\n agentFileUpload?: AgentFileUpload\n fallbackModels?: string[]\n gatewayOptions?: Partial<AgentGatewayOptions>\n }>()\n const emit = defineEmits<{\n 'message-update': [message: UIChatMessage]\n 'show-info': [message: UIChatMessage]\n revise: [message: UIChatMessage]\n error: [error: { type: string; title: string; status: number }]\n }>()\n\n const chatId = defineModel<string | undefined>('chatId', {\n type: String,\n default: undefined,\n })\n\n const store = useChatbotStore(props.agentId)\n\n const { messages, chat, localChatId, activeView, chatError } =\n storeToRefs(store)\n\n // Ref to store.agentId for watchers (avoids duplicate-key with agentId prop)\n const storeAgentId = toRef(store, 'agentId')\n\n const { startNewChat, stopGeneration, regenerate, navigate } = store\n\n // Sync props → store reactively\n watchEffect(() => {\n store.baseUrl = props.baseUrl\n store.basePath = props.basePath\n store.name = props.name\n store.agentType = props.agentType\n store.userId = props.userId\n store.agentInterface = props.agentInterface\n store.agentModel = props.agentModel\n store.agentTools = props.agentTools\n store.headers = props.headers\n store.revisedAnswers = props.revisedAnswers\n store.model = props.model\n store.actionsInput = props.actions\n store.agentFileUpload = props.agentFileUpload\n store.fallbackModels = props.fallbackModels\n store.gatewayOptions = props.gatewayOptions\n })\n\n // Sync chatId v-model ↔ store (bidirectional)\n // Parent → store: if the parent provides an external chatId, push it into\n // the store so the Chat instance picks it up.\n watch(\n () => chatId.value,\n (id) => {\n if (id && id !== store.localChatId) {\n store.localChatId = id\n }\n },\n { immediate: true },\n )\n // Store → parent: keep the v-model in sync whenever the store changes\n // the chatId internally (e.g. startNewChat).\n watch(localChatId, (id) => {\n chatId.value = id\n })\n\n // Emit structured errors from chat to the parent component\n watch(chatError, (error) => {\n if (!error) {\n return\n }\n try {\n const parsedError = JSON.parse(error.message) as {\n type: string\n title: string\n status: number\n }\n emit('error', parsedError)\n } catch {\n // ignore non-JSON errors\n }\n })\n\n // ui\n const isReasoningAgent = computed(() => props.agentType === 'reasoning')\n const useColorsForAgentHeader = computed(\n () => props.agentInterface?.useColorsForAgentHeader,\n )\n const themeClass = computed(() => {\n let theme = props.agentInterface?.theme\n if (!theme || theme === 'auto') {\n theme = props.systemTheme\n }\n if (!theme) {\n return ['theme']\n }\n return ['theme', `theme--${theme}`]\n })\n const mainColor = computed(() => props.agentInterface?.mainColor)\n const contrastColor = computed(() =>\n resolveContrastColor(props.agentInterface?.textColor, mainColor.value),\n )\n const footerMessage = useLocalizedString(\n () => props.agentInterface?.footerMessage,\n )\n const title = computed(() => {\n if (activeView.value === 'conversations') {\n return $t('label.conversations')\n }\n if (activeView.value === 'profile') {\n return $t('label.profile')\n }\n return props.name\n })\n\n // state\n const isReady = computed(() => chat.value.status === 'ready')\n const activeMessage = computed(() => {\n return messages.value?.[messages.value.length - 1]\n })\n\n // expose\n defineExpose({\n startNewChat,\n regenerate,\n stopGeneration,\n })\n\n // load chat, conversations and feedbacks on agent or chat change\n watch(\n [storeAgentId, localChatId],\n async ([newAgentId, newChatId]) => {\n await store.initialize(newAgentId, newChatId)\n },\n {\n immediate: true,\n },\n )\n // update initial message\n watch(\n () => props.agentInterface?.initialMessage,\n () => {\n if (\n chat.value.messages.length === 1 &&\n chat.value.messages[0].role === 'assistant'\n ) {\n chat.value.messages = []\n }\n },\n { deep: true },\n )\n // load conversations when navigating to conversations view\n watch(activeView, (newView) => {\n if (newView === 'conversations') {\n store.loadConversations(storeAgentId.value)\n }\n })\n // emit message updates for up-to-date context in parent components\n watch(\n activeMessage,\n (message) => {\n if (message) {\n emit('message-update', message)\n }\n },\n {\n deep: true,\n immediate: true,\n },\n )\n</script>\n\n<template>\n <div class=\"pk-chatbot\" :class=\"themeClass\">\n <!-- #region title -->\n <div\n class=\"pk-chatbot__header\"\n :style=\"\n useColorsForAgentHeader\n ? {\n backgroundColor: mainColor,\n }\n : undefined\n \">\n <div class=\"pk-chatbot__header-start\">\n <template v-if=\"activeView !== 'chat'\">\n <VvButton\n v-bind=\"{\n modifiers: useColorsForAgentHeader\n ? `action-quiet-${contrastColor}`\n : 'action-quiet',\n icon: 'ri:arrow-left-s-line',\n title: $t('action.goBack'),\n }\"\n @click=\"navigate('chat')\" />\n <VvIcon\n name=\"ri:history-line\"\n class=\"pk-chatbot__nav-icon\"\n :style=\"\n useColorsForAgentHeader\n ? {\n color: contrastColor,\n }\n : undefined\n \" />\n </template>\n <PkAvatar\n v-else\n modifiers=\"surface ring shrink-0\"\n class=\"pk-chatbot__avatar\"\n :name\n :img-src=\"agentInterface?.logo\" />\n <strong\n class=\"pk-chatbot__title\"\n :title=\"title\"\n :style=\"\n useColorsForAgentHeader\n ? {\n color: contrastColor,\n }\n : undefined\n \">\n {{ title }}\n </strong>\n </div>\n <VvButtonGroup class=\"pk-chatbot__header-end\" modifiers=\"compact\">\n <slot\n name=\"header-actions\"\n v-bind=\"{\n mainColor,\n useColorsForAgentHeader,\n contrastColor,\n startNewChat,\n stopGeneration,\n }\" />\n <VvDropdown\n v-bind=\"{\n placement: 'bottom-end',\n modifiers: 'menu',\n flip: true,\n offset: 3,\n }\">\n <VvButton\n v-bind=\"{\n modifiers: useColorsForAgentHeader\n ? `action-quiet-${contrastColor}`\n : 'action-quiet',\n icon: 'ri:more-2-fill',\n disabled: !isReady,\n title: $t('action.moreActions'),\n }\" />\n <template #items>\n <VvDropdownAction @click=\"startNewChat()\">\n <VvIcon name=\"ri:edit-box-line\" />\n {{ $t('action.startNewChat') }}\n </VvDropdownAction>\n <VvDropdownAction\n v-if=\"!isReasoningAgent\"\n @click=\"navigate('conversations')\">\n <VvIcon name=\"ri:history-line\" />\n {{ $t('action.viewRecentChats') }}\n </VvDropdownAction>\n </template>\n </VvDropdown>\n <slot\n name=\"actions\"\n v-bind=\"{\n mainColor,\n useColorsForAgentHeader,\n contrastColor,\n startNewChat,\n stopGeneration,\n }\" />\n </VvButtonGroup>\n </div>\n <!-- #endregion -->\n\n <div v-if=\"isReasoningAgent\">\n <div class=\"pk-chatbot__warning-body\">\n <VvAlert modifiers=\"callout\">\n <div class=\"pk-chatbot__warning-header\">\n <VvIcon\n name=\"ri:alert-line\"\n class=\"pk-chatbot__warning-icon\" />\n <strong class=\"pk-chatbot__warning-title\">\n {{ $t('message.warning') }}\n </strong>\n </div>\n <p class=\"pk-chatbot__warning-text\">\n {{ $t('message.reasoningAgent') }}\n </p>\n </VvAlert>\n </div>\n </div>\n\n <!-- #region views -->\n <PkChatbotViewChat\n v-if=\"activeView === 'chat'\"\n :agent-id\n @show-info=\"emit('show-info', $event)\"\n @revise=\"emit('revise', $event)\">\n <template\n v-for=\"slotName in Object.keys(slots)\"\n #[slotName]=\"slotData\"\n ><slot :name=\"slotName\" v-bind=\"slotData\"\n /></template>\n </PkChatbotViewChat>\n <PkChatbotViewConversations\n v-else-if=\"activeView === 'conversations'\"\n :agent-id>\n <template\n v-for=\"slotName in Object.keys(slots)\"\n #[slotName]=\"slotData\"\n ><slot :name=\"slotName\" v-bind=\"slotData\"\n /></template>\n </PkChatbotViewConversations>\n <PkChatbotViewProfile v-else :agent-id>\n <template\n v-for=\"slotName in Object.keys(slots)\"\n #[slotName]=\"slotData\"\n ><slot :name=\"slotName\" v-bind=\"slotData\"\n /></template>\n </PkChatbotViewProfile>\n <!-- #endregion -->\n\n <!-- #region footer -->\n <div v-if=\"footerMessage\" class=\"pk-chatbot__footer\">\n <PkStreamingMarkdown :markdown=\"footerMessage\" class=\"wysiwyg\" />\n </div>\n <!-- #endregion -->\n </div>\n</template>\n\n<style lang=\"scss\">\n .pk-chatbot {\n display: flex;\n flex-direction: column;\n position: relative;\n height: 100%;\n background-color: var(--color-surface);\n\n &__header {\n position: sticky;\n top: 0;\n z-index: 1;\n display: flex;\n justify-content: space-between;\n gap: var(--spacing-14);\n background-color: var(--color-surface-1);\n padding: var(--spacing-14);\n border-bottom: 1px solid var(--color-surface-4);\n }\n\n &__header-start {\n display: flex;\n align-items: center;\n gap: var(--spacing-sm);\n min-width: 0;\n }\n\n &__nav-icon {\n font-size: var(--text-18);\n }\n\n &__avatar {\n width: var(--spacing-24);\n height: var(--spacing-24);\n }\n\n &__title {\n font-size: var(--text-16);\n font-weight: 700;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n &__header-end {\n flex-shrink: 0;\n }\n\n &__warning-body {\n padding: var(--spacing-md);\n border-bottom: 1px solid var(--color-surface-4);\n }\n\n &__warning-header {\n display: flex;\n align-items: center;\n gap: var(--spacing-4);\n margin-bottom: var(--spacing-4);\n }\n\n &__warning-icon {\n width: var(--spacing-16);\n height: var(--spacing-16);\n }\n\n &__warning-title {\n font-weight: 600;\n font-size: var(--text-14);\n }\n\n &__warning-text {\n font-size: var(--text-12);\n color: var(--color-word-3);\n }\n\n &__footer {\n padding: var(--spacing-md);\n border-top: 1px solid var(--color-surface-4);\n text-align: center;\n font-size: var(--text-12);\n color: var(--color-word-2);\n }\n }\n</style>\n"],"mappings":"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"}
|
package/dist-vue/_chunks/{PkChatbotFilePreview-DHzuGtz5.js → PkChatbotFilePreview-hRNtv2OJ.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as e, t } from "./useLightbox-
|
|
1
|
+
import { n as e, t } from "./useLightbox-Cl8REkfc.js";
|
|
2
2
|
import { computed as n, createBlock as r, createCommentVNode as i, createElementBlock as a, createElementVNode as o, createVNode as s, defineComponent as c, onMounted as l, openBlock as u, ref as d, toDisplayString as f, unref as p } from "vue";
|
|
3
3
|
import { VvIcon as m } from "@volverjs/ui-vue/components";
|
|
4
4
|
//#region ../../packages/components/src/chat/PkChatbotFilePreview.vue?vue&type=script&setup=true&lang.ts
|
|
@@ -82,4 +82,4 @@ var h = { class: "pk-chatbot-file-preview" }, g = [
|
|
|
82
82
|
//#endregion
|
|
83
83
|
export { x as t };
|
|
84
84
|
|
|
85
|
-
//# sourceMappingURL=PkChatbotFilePreview-
|
|
85
|
+
//# sourceMappingURL=PkChatbotFilePreview-hRNtv2OJ.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PkChatbotFilePreview-DHzuGtz5.js","names":["$t","$emit"],"sources":["../../../../packages/components/src/chat/PkChatbotFilePreview.vue","../../../../packages/components/src/chat/PkChatbotFilePreview.vue"],"sourcesContent":["<script lang=\"ts\" setup>\n import { computed, ref, onMounted } from 'vue'\n import { useLightbox, useImageSizes } from '../composables/useLightbox'\n\n const props = defineProps<{\n mediaType: string\n url: string\n filename?: string\n loading?: boolean\n error?: string\n removable?: boolean\n }>()\n\n defineEmits<{\n remove: []\n }>()\n\n const isImage = computed(() => props.mediaType.startsWith('image/'))\n\n const galleryRef = ref<HTMLElement>()\n const { preload, getSize } = useImageSizes()\n const { init } = useLightbox({ gallery: galleryRef, loop: false })\n\n onMounted(async () => {\n if (!isImage.value) {\n return\n }\n preload([{ url: props.url }])\n await init()\n })\n</script>\n\n<template>\n <div class=\"pk-chatbot-file-preview\">\n <div v-if=\"isImage\" ref=\"galleryRef\">\n <a\n :href=\"url\"\n :data-pswp-src=\"url\"\n :data-pswp-width=\"getSize(url).width\"\n :data-pswp-height=\"getSize(url).height\"\n :data-pswp-caption=\"filename ?? ''\"\n class=\"pk-chatbot-file-preview__thumb-link\">\n <img\n :src=\"url\"\n :alt=\"filename\"\n class=\"pk-chatbot-file-preview__thumb\" />\n </a>\n </div>\n <a\n v-else\n :href=\"url\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"pk-chatbot-file-preview__icon-link\">\n <VvIcon name=\"ri:file-line\" class=\"pk-chatbot-file-preview__icon\" />\n </a>\n <span v-if=\"filename\" class=\"pk-chatbot-file-preview__name\">{{\n filename\n }}</span>\n <VvIcon\n v-if=\"loading\"\n name=\"line-md:loading-loop\"\n class=\"pk-chatbot-file-preview__loading\" />\n <VvIcon\n v-else-if=\"error\"\n name=\"ri:error-warning-line\"\n :title=\"error\"\n class=\"pk-chatbot-file-preview__error\" />\n <button\n v-if=\"removable && !loading\"\n type=\"button\"\n class=\"pk-chatbot-file-preview__remove\"\n :title=\"$t('action.remove')\"\n @click=\"$emit('remove')\">\n <VvIcon name=\"ri:close-line\" />\n </button>\n </div>\n</template>\n\n<style lang=\"scss\">\n .pk-chatbot-file-preview {\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-4);\n max-width: 160px;\n padding: var(--spacing-4) var(--spacing-xs);\n background-color: var(--color-surface-1);\n border: 1px solid var(--color-surface-3);\n border-radius: var(--rounded-md);\n font-size: var(--text-12);\n color: var(--color-word-2);\n\n &__thumb-link {\n display: flex;\n flex-shrink: 0;\n cursor: pointer;\n }\n\n &__thumb {\n width: var(--spacing-20);\n height: var(--spacing-20);\n object-fit: cover;\n border-radius: var(--rounded-sm);\n flex-shrink: 0;\n }\n\n &__icon-link {\n display: flex;\n flex-shrink: 0;\n color: inherit;\n text-decoration: none;\n }\n\n &__icon {\n width: var(--spacing-16);\n height: var(--spacing-16);\n flex-shrink: 0;\n color: var(--color-word-3);\n }\n\n &__name {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n &__loading,\n &__error {\n width: var(--spacing-14);\n height: var(--spacing-14);\n flex-shrink: 0;\n }\n\n &__error {\n color: var(--color-danger);\n }\n\n &__remove {\n background: none;\n border: none;\n cursor: pointer;\n padding: 0;\n color: var(--color-word-4);\n flex-shrink: 0;\n display: flex;\n align-items: center;\n line-height: 1;\n\n &:hover {\n color: var(--color-word-1);\n }\n }\n }\n</style>\n","<script lang=\"ts\" setup>\n import { computed, ref, onMounted } from 'vue'\n import { useLightbox, useImageSizes } from '../composables/useLightbox'\n\n const props = defineProps<{\n mediaType: string\n url: string\n filename?: string\n loading?: boolean\n error?: string\n removable?: boolean\n }>()\n\n defineEmits<{\n remove: []\n }>()\n\n const isImage = computed(() => props.mediaType.startsWith('image/'))\n\n const galleryRef = ref<HTMLElement>()\n const { preload, getSize } = useImageSizes()\n const { init } = useLightbox({ gallery: galleryRef, loop: false })\n\n onMounted(async () => {\n if (!isImage.value) {\n return\n }\n preload([{ url: props.url }])\n await init()\n })\n</script>\n\n<template>\n <div class=\"pk-chatbot-file-preview\">\n <div v-if=\"isImage\" ref=\"galleryRef\">\n <a\n :href=\"url\"\n :data-pswp-src=\"url\"\n :data-pswp-width=\"getSize(url).width\"\n :data-pswp-height=\"getSize(url).height\"\n :data-pswp-caption=\"filename ?? ''\"\n class=\"pk-chatbot-file-preview__thumb-link\">\n <img\n :src=\"url\"\n :alt=\"filename\"\n class=\"pk-chatbot-file-preview__thumb\" />\n </a>\n </div>\n <a\n v-else\n :href=\"url\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"pk-chatbot-file-preview__icon-link\">\n <VvIcon name=\"ri:file-line\" class=\"pk-chatbot-file-preview__icon\" />\n </a>\n <span v-if=\"filename\" class=\"pk-chatbot-file-preview__name\">{{\n filename\n }}</span>\n <VvIcon\n v-if=\"loading\"\n name=\"line-md:loading-loop\"\n class=\"pk-chatbot-file-preview__loading\" />\n <VvIcon\n v-else-if=\"error\"\n name=\"ri:error-warning-line\"\n :title=\"error\"\n class=\"pk-chatbot-file-preview__error\" />\n <button\n v-if=\"removable && !loading\"\n type=\"button\"\n class=\"pk-chatbot-file-preview__remove\"\n :title=\"$t('action.remove')\"\n @click=\"$emit('remove')\">\n <VvIcon name=\"ri:close-line\" />\n </button>\n </div>\n</template>\n\n<style lang=\"scss\">\n .pk-chatbot-file-preview {\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-4);\n max-width: 160px;\n padding: var(--spacing-4) var(--spacing-xs);\n background-color: var(--color-surface-1);\n border: 1px solid var(--color-surface-3);\n border-radius: var(--rounded-md);\n font-size: var(--text-12);\n color: var(--color-word-2);\n\n &__thumb-link {\n display: flex;\n flex-shrink: 0;\n cursor: pointer;\n }\n\n &__thumb {\n width: var(--spacing-20);\n height: var(--spacing-20);\n object-fit: cover;\n border-radius: var(--rounded-sm);\n flex-shrink: 0;\n }\n\n &__icon-link {\n display: flex;\n flex-shrink: 0;\n color: inherit;\n text-decoration: none;\n }\n\n &__icon {\n width: var(--spacing-16);\n height: var(--spacing-16);\n flex-shrink: 0;\n color: var(--color-word-3);\n }\n\n &__name {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n &__loading,\n &__error {\n width: var(--spacing-14);\n height: var(--spacing-14);\n flex-shrink: 0;\n }\n\n &__error {\n color: var(--color-danger);\n }\n\n &__remove {\n background: none;\n border: none;\n cursor: pointer;\n padding: 0;\n color: var(--color-word-4);\n flex-shrink: 0;\n display: flex;\n align-items: center;\n line-height: 1;\n\n &:hover {\n color: var(--color-word-1);\n }\n }\n }\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;EAII,IAAM,IAAQ,GAaR,IAAU,QAAe,EAAM,UAAU,WAAW,SAAS,CAAA,EAE7D,IAAa,GAAiB,EAC9B,EAAE,YAAS,eAAY,GAAc,EACrC,EAAE,YAAS,EAAY;GAAE,SAAS;GAAY,MAAM;GAAO,CAAA;SAEjE,EAAU,YAAY;AACb,KAAQ,UAGb,EAAQ,CAAC,EAAE,KAAK,EAAM,KAAK,CAAC,CAAA,EAC5B,MAAM,GAAK;IACd;;eAID,EA2CM,OA3CN,GA2CM;IA1CS,EAAA,SAAA,GAAA,EAAX,EAaM,OAAA;;cAbkB;KAAJ,KAAI;QACpB,EAWI,KAAA;KAVC,MAAM,EAAA;KACN,iBAAe,EAAA;KACf,mBAAiB,EAAA,EAAO,CAAC,EAAA,IAAG,CAAE;KAC9B,oBAAkB,EAAA,EAAO,CAAC,EAAA,IAAG,CAAE;KAC/B,qBAAmB,EAAA,YAAQ;KAC5B,OAAM;QACN,EAG6C,OAAA;KAFxC,KAAK,EAAA;KACL,KAAK,EAAA;KACN,OAAM;2CAGlB,EAOI,KAAA;;KALC,MAAM,EAAA;KACP,QAAO;KACP,KAAI;KACJ,OAAM;QACN,EAAoE,GAAA;KAA5D,MAAK;KAAe,OAAM;;IAE1B,EAAA,YAAA,GAAA,EAAZ,EAES,QAFT,GAES,EADL,EAAA,SAAQ,EAAA,EAAA,IAAA,EAAA,IAAA,GAAA;IAGF,EAAA,WAAA,GAAA,EADV,EAG+C,GAAA;;KAD3C,MAAK;KACL,OAAM;UAEK,EAAA,SAAA,GAAA,EADf,EAI6C,GAAA;;KAFzC,MAAK;KACJ,OAAO,EAAA;KACR,OAAM;;IAEA,EAAA,aAAS,CAAK,EAAA,WAAA,GAAA,EADxB,EAOS,UAAA;;KALL,MAAK;KACL,OAAM;KACL,OAAOA,EAAAA,GAAE,gBAAA;KACT,SAAK,AAAA,EAAA,QAAA,MAAEC,EAAAA,MAAK,SAAA;QACb,EAA+B,GAAA,EAAvB,MAAK,iBAAe,CAAA,CAAA,EAAA,GAAA,EAAA,IAAA,EAAA,IAAA,GAAA"}
|
|
1
|
+
{"version":3,"file":"PkChatbotFilePreview-hRNtv2OJ.js","names":["$t","$emit"],"sources":["../../../../packages/components/src/chat/PkChatbotFilePreview.vue","../../../../packages/components/src/chat/PkChatbotFilePreview.vue"],"sourcesContent":["<script lang=\"ts\" setup>\n import { computed, ref, onMounted } from 'vue'\n import { useLightbox, useImageSizes } from '../composables/useLightbox'\n\n const props = defineProps<{\n mediaType: string\n url: string\n filename?: string\n loading?: boolean\n error?: string\n removable?: boolean\n }>()\n\n defineEmits<{\n remove: []\n }>()\n\n const isImage = computed(() => props.mediaType.startsWith('image/'))\n\n const galleryRef = ref<HTMLElement>()\n const { preload, getSize } = useImageSizes()\n const { init } = useLightbox({ gallery: galleryRef, loop: false })\n\n onMounted(async () => {\n if (!isImage.value) {\n return\n }\n preload([{ url: props.url }])\n await init()\n })\n</script>\n\n<template>\n <div class=\"pk-chatbot-file-preview\">\n <div v-if=\"isImage\" ref=\"galleryRef\">\n <a\n :href=\"url\"\n :data-pswp-src=\"url\"\n :data-pswp-width=\"getSize(url).width\"\n :data-pswp-height=\"getSize(url).height\"\n :data-pswp-caption=\"filename ?? ''\"\n class=\"pk-chatbot-file-preview__thumb-link\">\n <img\n :src=\"url\"\n :alt=\"filename\"\n class=\"pk-chatbot-file-preview__thumb\" />\n </a>\n </div>\n <a\n v-else\n :href=\"url\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"pk-chatbot-file-preview__icon-link\">\n <VvIcon name=\"ri:file-line\" class=\"pk-chatbot-file-preview__icon\" />\n </a>\n <span v-if=\"filename\" class=\"pk-chatbot-file-preview__name\">{{\n filename\n }}</span>\n <VvIcon\n v-if=\"loading\"\n name=\"line-md:loading-loop\"\n class=\"pk-chatbot-file-preview__loading\" />\n <VvIcon\n v-else-if=\"error\"\n name=\"ri:error-warning-line\"\n :title=\"error\"\n class=\"pk-chatbot-file-preview__error\" />\n <button\n v-if=\"removable && !loading\"\n type=\"button\"\n class=\"pk-chatbot-file-preview__remove\"\n :title=\"$t('action.remove')\"\n @click=\"$emit('remove')\">\n <VvIcon name=\"ri:close-line\" />\n </button>\n </div>\n</template>\n\n<style lang=\"scss\">\n .pk-chatbot-file-preview {\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-4);\n max-width: 160px;\n padding: var(--spacing-4) var(--spacing-xs);\n background-color: var(--color-surface-1);\n border: 1px solid var(--color-surface-3);\n border-radius: var(--rounded-md);\n font-size: var(--text-12);\n color: var(--color-word-2);\n\n &__thumb-link {\n display: flex;\n flex-shrink: 0;\n cursor: pointer;\n }\n\n &__thumb {\n width: var(--spacing-20);\n height: var(--spacing-20);\n object-fit: cover;\n border-radius: var(--rounded-sm);\n flex-shrink: 0;\n }\n\n &__icon-link {\n display: flex;\n flex-shrink: 0;\n color: inherit;\n text-decoration: none;\n }\n\n &__icon {\n width: var(--spacing-16);\n height: var(--spacing-16);\n flex-shrink: 0;\n color: var(--color-word-3);\n }\n\n &__name {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n &__loading,\n &__error {\n width: var(--spacing-14);\n height: var(--spacing-14);\n flex-shrink: 0;\n }\n\n &__error {\n color: var(--color-danger);\n }\n\n &__remove {\n background: none;\n border: none;\n cursor: pointer;\n padding: 0;\n color: var(--color-word-4);\n flex-shrink: 0;\n display: flex;\n align-items: center;\n line-height: 1;\n\n &:hover {\n color: var(--color-word-1);\n }\n }\n }\n</style>\n","<script lang=\"ts\" setup>\n import { computed, ref, onMounted } from 'vue'\n import { useLightbox, useImageSizes } from '../composables/useLightbox'\n\n const props = defineProps<{\n mediaType: string\n url: string\n filename?: string\n loading?: boolean\n error?: string\n removable?: boolean\n }>()\n\n defineEmits<{\n remove: []\n }>()\n\n const isImage = computed(() => props.mediaType.startsWith('image/'))\n\n const galleryRef = ref<HTMLElement>()\n const { preload, getSize } = useImageSizes()\n const { init } = useLightbox({ gallery: galleryRef, loop: false })\n\n onMounted(async () => {\n if (!isImage.value) {\n return\n }\n preload([{ url: props.url }])\n await init()\n })\n</script>\n\n<template>\n <div class=\"pk-chatbot-file-preview\">\n <div v-if=\"isImage\" ref=\"galleryRef\">\n <a\n :href=\"url\"\n :data-pswp-src=\"url\"\n :data-pswp-width=\"getSize(url).width\"\n :data-pswp-height=\"getSize(url).height\"\n :data-pswp-caption=\"filename ?? ''\"\n class=\"pk-chatbot-file-preview__thumb-link\">\n <img\n :src=\"url\"\n :alt=\"filename\"\n class=\"pk-chatbot-file-preview__thumb\" />\n </a>\n </div>\n <a\n v-else\n :href=\"url\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"pk-chatbot-file-preview__icon-link\">\n <VvIcon name=\"ri:file-line\" class=\"pk-chatbot-file-preview__icon\" />\n </a>\n <span v-if=\"filename\" class=\"pk-chatbot-file-preview__name\">{{\n filename\n }}</span>\n <VvIcon\n v-if=\"loading\"\n name=\"line-md:loading-loop\"\n class=\"pk-chatbot-file-preview__loading\" />\n <VvIcon\n v-else-if=\"error\"\n name=\"ri:error-warning-line\"\n :title=\"error\"\n class=\"pk-chatbot-file-preview__error\" />\n <button\n v-if=\"removable && !loading\"\n type=\"button\"\n class=\"pk-chatbot-file-preview__remove\"\n :title=\"$t('action.remove')\"\n @click=\"$emit('remove')\">\n <VvIcon name=\"ri:close-line\" />\n </button>\n </div>\n</template>\n\n<style lang=\"scss\">\n .pk-chatbot-file-preview {\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-4);\n max-width: 160px;\n padding: var(--spacing-4) var(--spacing-xs);\n background-color: var(--color-surface-1);\n border: 1px solid var(--color-surface-3);\n border-radius: var(--rounded-md);\n font-size: var(--text-12);\n color: var(--color-word-2);\n\n &__thumb-link {\n display: flex;\n flex-shrink: 0;\n cursor: pointer;\n }\n\n &__thumb {\n width: var(--spacing-20);\n height: var(--spacing-20);\n object-fit: cover;\n border-radius: var(--rounded-sm);\n flex-shrink: 0;\n }\n\n &__icon-link {\n display: flex;\n flex-shrink: 0;\n color: inherit;\n text-decoration: none;\n }\n\n &__icon {\n width: var(--spacing-16);\n height: var(--spacing-16);\n flex-shrink: 0;\n color: var(--color-word-3);\n }\n\n &__name {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n &__loading,\n &__error {\n width: var(--spacing-14);\n height: var(--spacing-14);\n flex-shrink: 0;\n }\n\n &__error {\n color: var(--color-danger);\n }\n\n &__remove {\n background: none;\n border: none;\n cursor: pointer;\n padding: 0;\n color: var(--color-word-4);\n flex-shrink: 0;\n display: flex;\n align-items: center;\n line-height: 1;\n\n &:hover {\n color: var(--color-word-1);\n }\n }\n }\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;EAII,IAAM,IAAQ,GAaR,IAAU,QAAe,EAAM,UAAU,WAAW,SAAS,CAAA,EAE7D,IAAa,GAAiB,EAC9B,EAAE,YAAS,eAAY,GAAc,EACrC,EAAE,YAAS,EAAY;GAAE,SAAS;GAAY,MAAM;GAAO,CAAA;SAEjE,EAAU,YAAY;AACb,KAAQ,UAGb,EAAQ,CAAC,EAAE,KAAK,EAAM,KAAK,CAAC,CAAA,EAC5B,MAAM,GAAK;IACd;;eAID,EA2CM,OA3CN,GA2CM;IA1CS,EAAA,SAAA,GAAA,EAAX,EAaM,OAAA;;cAbkB;KAAJ,KAAI;QACpB,EAWI,KAAA;KAVC,MAAM,EAAA;KACN,iBAAe,EAAA;KACf,mBAAiB,EAAA,EAAO,CAAC,EAAA,IAAG,CAAE;KAC9B,oBAAkB,EAAA,EAAO,CAAC,EAAA,IAAG,CAAE;KAC/B,qBAAmB,EAAA,YAAQ;KAC5B,OAAM;QACN,EAG6C,OAAA;KAFxC,KAAK,EAAA;KACL,KAAK,EAAA;KACN,OAAM;2CAGlB,EAOI,KAAA;;KALC,MAAM,EAAA;KACP,QAAO;KACP,KAAI;KACJ,OAAM;QACN,EAAoE,GAAA;KAA5D,MAAK;KAAe,OAAM;;IAE1B,EAAA,YAAA,GAAA,EAAZ,EAES,QAFT,GAES,EADL,EAAA,SAAQ,EAAA,EAAA,IAAA,EAAA,IAAA,GAAA;IAGF,EAAA,WAAA,GAAA,EADV,EAG+C,GAAA;;KAD3C,MAAK;KACL,OAAM;UAEK,EAAA,SAAA,GAAA,EADf,EAI6C,GAAA;;KAFzC,MAAK;KACJ,OAAO,EAAA;KACR,OAAM;;IAEA,EAAA,aAAS,CAAK,EAAA,WAAA,GAAA,EADxB,EAOS,UAAA;;KALL,MAAK;KACL,OAAM;KACL,OAAOA,EAAAA,GAAE,gBAAA;KACT,SAAK,AAAA,EAAA,QAAA,MAAEC,EAAAA,MAAK,SAAA;QACb,EAA+B,GAAA,EAAvB,MAAK,iBAAe,CAAA,CAAA,EAAA,GAAA,EAAA,IAAA,EAAA,IAAA,GAAA"}
|