@8wave/ai-elements 0.115.0-beta.34 → 0.115.0-beta.47

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (152) hide show
  1. package/dist/_chunks/{Agent-Cu04vBnd.js → Agent-D3cVY0pk.js} +121 -110
  2. package/dist/_chunks/Agent-D3cVY0pk.js.map +1 -0
  3. package/dist/_chunks/PkHeldImage-BtaPh0Jr.js +42 -0
  4. package/dist/_chunks/PkHeldImage-BtaPh0Jr.js.map +1 -0
  5. package/dist/_chunks/{PkStreamingMarkdown-Qk9Tk_N7.js → PkStreamingMarkdown-DyvZ5xKK.js} +782 -741
  6. package/dist/_chunks/PkStreamingMarkdown-DyvZ5xKK.js.map +1 -0
  7. package/dist/_chunks/{PkToolRequestGeolocation-BoKYkQ-Z.js → PkToolRequestGeolocation-DjRmmYMk.js} +2 -2
  8. package/dist/_chunks/{PkToolRequestGeolocation-BoKYkQ-Z.js.map → PkToolRequestGeolocation-DjRmmYMk.js.map} +1 -1
  9. package/dist/_chunks/{PkToolRequestOAuthConnection-CDzpfBg6.js → PkToolRequestOAuthConnection-CJ8dg2RY.js} +2 -2
  10. package/dist/_chunks/{PkToolRequestOAuthConnection-CDzpfBg6.js.map → PkToolRequestOAuthConnection-CJ8dg2RY.js.map} +1 -1
  11. package/dist/_chunks/{PkToolShowArtifact-DB8JjN-b.js → PkToolShowArtifact-Bk-xmGxl.js} +2 -2
  12. package/dist/_chunks/{PkToolShowArtifact-DB8JjN-b.js.map → PkToolShowArtifact-Bk-xmGxl.js.map} +1 -1
  13. package/dist/_chunks/{PkToolShowContactForm-DHviNxDk.js → PkToolShowContactForm-B0o6CY0Q.js} +2 -2
  14. package/dist/_chunks/{PkToolShowContactForm-DHviNxDk.js.map → PkToolShowContactForm-B0o6CY0Q.js.map} +1 -1
  15. package/dist/_chunks/{PkToolShowForm-B-R9fh3R.js → PkToolShowForm-C4-KAKPL.js} +3 -3
  16. package/dist/_chunks/{PkToolShowForm-B-R9fh3R.js.map → PkToolShowForm-C4-KAKPL.js.map} +1 -1
  17. package/dist/_chunks/PkToolShowImageGallery-Jdo7p2mZ.js +88 -0
  18. package/dist/_chunks/PkToolShowImageGallery-Jdo7p2mZ.js.map +1 -0
  19. package/dist/_chunks/PkToolShowProductList-Cfk865KB.js +72 -0
  20. package/dist/_chunks/PkToolShowProductList-Cfk865KB.js.map +1 -0
  21. package/dist/_chunks/{PkToolShowSources-CfZEfleZ.js → PkToolShowSources-qqUbdWzN.js} +3 -3
  22. package/dist/_chunks/{PkToolShowSources-CfZEfleZ.js.map → PkToolShowSources-qqUbdWzN.js.map} +1 -1
  23. package/dist/_chunks/{PkToolShowSuggestedReply-DsB35hRR.js → PkToolShowSuggestedReply-Dk6Nu9cG.js} +2 -2
  24. package/dist/_chunks/{PkToolShowSuggestedReply-DsB35hRR.js.map → PkToolShowSuggestedReply-Dk6Nu9cG.js.map} +1 -1
  25. package/dist/_chunks/PkToolShowVideo-D07i4hVd.js +142 -0
  26. package/dist/_chunks/PkToolShowVideo-D07i4hVd.js.map +1 -0
  27. package/dist/_chunks/{PkToolShowWebPages-BOxbTe2X.js → PkToolShowWebPages-ksXRNsDK.js} +31 -24
  28. package/dist/_chunks/PkToolShowWebPages-ksXRNsDK.js.map +1 -0
  29. package/dist/_chunks/chatImagePolicy-B1iRRLAB.js +46 -0
  30. package/dist/_chunks/chatImagePolicy-B1iRRLAB.js.map +1 -0
  31. package/dist/_chunks/{markdown-_p-gd9w8.js → markdown-DOitQ2jz.js} +13 -13
  32. package/dist/_chunks/{markdown-_p-gd9w8.js.map → markdown-DOitQ2jz.js.map} +1 -1
  33. package/dist/ai-elements.es.js +1720 -1713
  34. package/dist/ai-elements.es.js.map +1 -1
  35. package/dist-vue/PkChatbot.js +1 -1
  36. package/dist-vue/PkChatbotEmptyState.js +1 -1
  37. package/dist-vue/PkChatbotInput.js +1 -1
  38. package/dist-vue/PkChatbotMessages.js +1 -1
  39. package/dist-vue/PkChatbotStepPayload.js +1 -1
  40. package/dist-vue/PkChatbotStepToolDetail.js +1 -1
  41. package/dist-vue/PkChatbotSteps.js +1 -1
  42. package/dist-vue/PkChatbotViewChat.js +1 -1
  43. package/dist-vue/PkChatbotViewConversations.js +1 -1
  44. package/dist-vue/PkChatbotViewFiles.js +1 -1
  45. package/dist-vue/PkChatbotViewProfile.js +1 -1
  46. package/dist-vue/_chunks/{Agent-KbZm8GvA.js → Agent-C4p46YGt.js} +67 -56
  47. package/dist-vue/_chunks/Agent-C4p46YGt.js.map +1 -0
  48. package/dist-vue/_chunks/{Document-DCSWwcRE.js → Document-B9QaYHKT.js} +10 -10
  49. package/dist-vue/_chunks/{Document-DCSWwcRE.js.map → Document-B9QaYHKT.js.map} +1 -1
  50. package/dist-vue/_chunks/PkChatbot-BkMe7zxp.js +275 -0
  51. package/dist-vue/_chunks/PkChatbot-BkMe7zxp.js.map +1 -0
  52. package/dist-vue/_chunks/{PkChatbotEmptyState-CO7-vlsZ.js → PkChatbotEmptyState-HElKT2OO.js} +2 -2
  53. package/dist-vue/_chunks/{PkChatbotEmptyState-CO7-vlsZ.js.map → PkChatbotEmptyState-HElKT2OO.js.map} +1 -1
  54. package/dist-vue/_chunks/{PkChatbotInput-D8ykcHKJ.js → PkChatbotInput-BykvFqbm.js} +2 -2
  55. package/dist-vue/_chunks/{PkChatbotInput-D8ykcHKJ.js.map → PkChatbotInput-BykvFqbm.js.map} +1 -1
  56. package/dist-vue/_chunks/{PkChatbotMessages-UT72KC_z.js → PkChatbotMessages-wH9wxc6Y.js} +19 -19
  57. package/dist-vue/_chunks/{PkChatbotMessages-UT72KC_z.js.map → PkChatbotMessages-wH9wxc6Y.js.map} +1 -1
  58. package/dist-vue/_chunks/{PkChatbotStepPayload-CSVHe7DP.js → PkChatbotStepPayload-DY0AzM6s.js} +2 -2
  59. package/dist-vue/_chunks/{PkChatbotStepPayload-CSVHe7DP.js.map → PkChatbotStepPayload-DY0AzM6s.js.map} +1 -1
  60. package/dist-vue/_chunks/{PkChatbotStepToolDetail-ixte-rGB.js → PkChatbotStepToolDetail-AXtXQVQY.js} +3 -3
  61. package/dist-vue/_chunks/{PkChatbotStepToolDetail-ixte-rGB.js.map → PkChatbotStepToolDetail-AXtXQVQY.js.map} +1 -1
  62. package/dist-vue/_chunks/{PkChatbotSteps-Y6kQ00ui.js → PkChatbotSteps-B-yrfTat.js} +5 -5
  63. package/dist-vue/_chunks/{PkChatbotSteps-Y6kQ00ui.js.map → PkChatbotSteps-B-yrfTat.js.map} +1 -1
  64. package/dist-vue/_chunks/{PkChatbotViewChat-D3PwREDw.js → PkChatbotViewChat-CCcMnVkM.js} +7 -7
  65. package/dist-vue/_chunks/{PkChatbotViewChat-D3PwREDw.js.map → PkChatbotViewChat-CCcMnVkM.js.map} +1 -1
  66. package/dist-vue/_chunks/{PkChatbotViewConversations-dpwDFyr_.js → PkChatbotViewConversations-C9h_bBIc.js} +2 -2
  67. package/dist-vue/_chunks/{PkChatbotViewConversations-dpwDFyr_.js.map → PkChatbotViewConversations-C9h_bBIc.js.map} +1 -1
  68. package/dist-vue/_chunks/{PkChatbotViewFiles-BStYLY2B.js → PkChatbotViewFiles-BkoXgGE6.js} +3 -3
  69. package/dist-vue/_chunks/{PkChatbotViewFiles-BStYLY2B.js.map → PkChatbotViewFiles-BkoXgGE6.js.map} +1 -1
  70. package/dist-vue/_chunks/{PkChatbotViewProfile-Brylm3We.js → PkChatbotViewProfile-CFR0B99Z.js} +2 -2
  71. package/dist-vue/_chunks/{PkChatbotViewProfile-Brylm3We.js.map → PkChatbotViewProfile-CFR0B99Z.js.map} +1 -1
  72. package/dist-vue/_chunks/PkHeldImage-BqnlurT_.js +41 -0
  73. package/dist-vue/_chunks/PkHeldImage-BqnlurT_.js.map +1 -0
  74. package/dist-vue/_chunks/{PkStreamingMarkdown-CJlfq7ub.js → PkStreamingMarkdown-XJBXdSG2.js} +792 -780
  75. package/dist-vue/_chunks/PkStreamingMarkdown-XJBXdSG2.js.map +1 -0
  76. package/dist-vue/_chunks/{PkToolRequestGeolocation-C8sLjD6g.js → PkToolRequestGeolocation-DpvsFEga.js} +2 -2
  77. package/dist-vue/_chunks/{PkToolRequestGeolocation-C8sLjD6g.js.map → PkToolRequestGeolocation-DpvsFEga.js.map} +1 -1
  78. package/dist-vue/_chunks/{PkToolRequestOAuthConnection-rbjNi_l0.js → PkToolRequestOAuthConnection-DRefs-S1.js} +2 -2
  79. package/dist-vue/_chunks/{PkToolRequestOAuthConnection-rbjNi_l0.js.map → PkToolRequestOAuthConnection-DRefs-S1.js.map} +1 -1
  80. package/dist-vue/_chunks/{PkToolShowArtifact-hBmAAfsd.js → PkToolShowArtifact-BopCMkyZ.js} +2 -2
  81. package/dist-vue/_chunks/{PkToolShowArtifact-hBmAAfsd.js.map → PkToolShowArtifact-BopCMkyZ.js.map} +1 -1
  82. package/dist-vue/_chunks/{PkToolShowContactForm-BHsm_W2R.js → PkToolShowContactForm-C6F_DdBu.js} +2 -2
  83. package/dist-vue/_chunks/{PkToolShowContactForm-BHsm_W2R.js.map → PkToolShowContactForm-C6F_DdBu.js.map} +1 -1
  84. package/dist-vue/_chunks/{PkToolShowDiagram-De2XvRnq.js → PkToolShowDiagram-7-m7VrED.js} +2 -2
  85. package/dist-vue/_chunks/{PkToolShowDiagram-De2XvRnq.js.map → PkToolShowDiagram-7-m7VrED.js.map} +1 -1
  86. package/dist-vue/_chunks/{PkToolShowEmail-D1mXZrT-.js → PkToolShowEmail-C591LR5N.js} +2 -2
  87. package/dist-vue/_chunks/{PkToolShowEmail-D1mXZrT-.js.map → PkToolShowEmail-C591LR5N.js.map} +1 -1
  88. package/dist-vue/_chunks/{PkToolShowForm-Ce_GpcBt.js → PkToolShowForm-DEr8wDJi.js} +4 -4
  89. package/dist-vue/_chunks/{PkToolShowForm-Ce_GpcBt.js.map → PkToolShowForm-DEr8wDJi.js.map} +1 -1
  90. package/dist-vue/_chunks/PkToolShowImageGallery-D44wf_u3.js +88 -0
  91. package/dist-vue/_chunks/PkToolShowImageGallery-D44wf_u3.js.map +1 -0
  92. package/dist-vue/_chunks/{PkToolShowMessage-lNPZxw2v.js → PkToolShowMessage-CbXERPHI.js} +2 -2
  93. package/dist-vue/_chunks/{PkToolShowMessage-lNPZxw2v.js.map → PkToolShowMessage-CbXERPHI.js.map} +1 -1
  94. package/dist-vue/_chunks/PkToolShowProductList-C6CVRUlD.js +72 -0
  95. package/dist-vue/_chunks/PkToolShowProductList-C6CVRUlD.js.map +1 -0
  96. package/dist-vue/_chunks/{PkToolShowSources-B1Nhrk7O.js → PkToolShowSources-DzUNanmK.js} +4 -4
  97. package/dist-vue/_chunks/{PkToolShowSources-B1Nhrk7O.js.map → PkToolShowSources-DzUNanmK.js.map} +1 -1
  98. package/dist-vue/_chunks/{PkToolShowSuggestedReply-Bmzygdww.js → PkToolShowSuggestedReply-DhNtI5gJ.js} +2 -2
  99. package/dist-vue/_chunks/{PkToolShowSuggestedReply-Bmzygdww.js.map → PkToolShowSuggestedReply-DhNtI5gJ.js.map} +1 -1
  100. package/dist-vue/_chunks/PkToolShowVideo-HbQzTMh5.js +141 -0
  101. package/dist-vue/_chunks/PkToolShowVideo-HbQzTMh5.js.map +1 -0
  102. package/dist-vue/_chunks/PkToolShowWebPages-Ct1HaCSq.js +86 -0
  103. package/dist-vue/_chunks/PkToolShowWebPages-Ct1HaCSq.js.map +1 -0
  104. package/dist-vue/_chunks/{PkUrl-E12f7rn_.js → PkUrl-CN1kkZiH.js} +2 -2
  105. package/dist-vue/_chunks/{PkUrl-E12f7rn_.js.map → PkUrl-CN1kkZiH.js.map} +1 -1
  106. package/dist-vue/_chunks/{createChatbotApiClient-B_mkyrEl.js → createChatbotApiClient-B2PvUG07.js} +16 -16
  107. package/dist-vue/_chunks/{createChatbotApiClient-B_mkyrEl.js.map → createChatbotApiClient-B2PvUG07.js.map} +1 -1
  108. package/dist-vue/_chunks/{useChatbotStore-DEELIJ89.js → useChatbotStore-Cj_UmNH3.js} +3 -3
  109. package/dist-vue/_chunks/{useChatbotStore-DEELIJ89.js.map → useChatbotStore-Cj_UmNH3.js.map} +1 -1
  110. package/dist-vue/_chunks/useShortUrlResolver-DI8ycJiO.js +71 -0
  111. package/dist-vue/_chunks/useShortUrlResolver-DI8ycJiO.js.map +1 -0
  112. package/dist-vue/_chunks/{utils-CtD8DCrq.js → utils-DXXzMVU3.js} +2 -2
  113. package/dist-vue/_chunks/{utils-CtD8DCrq.js.map → utils-DXXzMVU3.js.map} +1 -1
  114. package/dist-vue/api.js +1 -1
  115. package/dist-vue/apps/web-component/src/composables/useChatbotAgent.d.ts +2 -0
  116. package/dist-vue/composables.js +11 -7
  117. package/dist-vue/composables.js.map +1 -1
  118. package/dist-vue/index.js +3444 -3400
  119. package/dist-vue/index.js.map +1 -1
  120. package/dist-vue/locales.js +12 -0
  121. package/dist-vue/packages/components/src/chat/PkAgentSettingsPanel.d.ts +6 -2
  122. package/dist-vue/packages/components/src/chat/PkHeldImage.d.ts +21 -0
  123. package/dist-vue/packages/components/src/chat/chatImagePolicy.d.ts +55 -0
  124. package/dist-vue/packages/components/src/chat/index.d.ts +1 -0
  125. package/dist-vue/packages/components/src/chat/markdownHtml.d.ts +17 -1
  126. package/dist-vue/packages/composable/src/chatbot/useChatbotStore.d.ts +6 -0
  127. package/dist-vue/packages/models/src/schema/Agent.d.ts +14 -0
  128. package/dist-vue/packages/models/src/schema/ReasoningChat.d.ts +2 -0
  129. package/dist-vue/packages/models/src/schema/SubAgent.d.ts +2 -0
  130. package/dist-vue/style.css +1 -1
  131. package/package.json +1 -1
  132. package/dist/_chunks/Agent-Cu04vBnd.js.map +0 -1
  133. package/dist/_chunks/PkStreamingMarkdown-Qk9Tk_N7.js.map +0 -1
  134. package/dist/_chunks/PkToolShowImageGallery-FubPWFCb.js +0 -75
  135. package/dist/_chunks/PkToolShowImageGallery-FubPWFCb.js.map +0 -1
  136. package/dist/_chunks/PkToolShowProductList-DFy2jxn4.js +0 -65
  137. package/dist/_chunks/PkToolShowProductList-DFy2jxn4.js.map +0 -1
  138. package/dist/_chunks/PkToolShowVideo-DClps9oP.js +0 -123
  139. package/dist/_chunks/PkToolShowVideo-DClps9oP.js.map +0 -1
  140. package/dist/_chunks/PkToolShowWebPages-BOxbTe2X.js.map +0 -1
  141. package/dist-vue/_chunks/Agent-KbZm8GvA.js.map +0 -1
  142. package/dist-vue/_chunks/PkChatbot-CRb-U8e3.js +0 -272
  143. package/dist-vue/_chunks/PkChatbot-CRb-U8e3.js.map +0 -1
  144. package/dist-vue/_chunks/PkStreamingMarkdown-CJlfq7ub.js.map +0 -1
  145. package/dist-vue/_chunks/PkToolShowImageGallery-DmhZLnBk.js +0 -75
  146. package/dist-vue/_chunks/PkToolShowImageGallery-DmhZLnBk.js.map +0 -1
  147. package/dist-vue/_chunks/PkToolShowProductList-BW5pRFe4.js +0 -65
  148. package/dist-vue/_chunks/PkToolShowProductList-BW5pRFe4.js.map +0 -1
  149. package/dist-vue/_chunks/PkToolShowVideo-BZOTu2Qe.js +0 -122
  150. package/dist-vue/_chunks/PkToolShowVideo-BZOTu2Qe.js.map +0 -1
  151. package/dist-vue/_chunks/PkToolShowWebPages-BiIBRV_n.js +0 -79
  152. package/dist-vue/_chunks/PkToolShowWebPages-BiIBRV_n.js.map +0 -1
@@ -0,0 +1,88 @@
1
+ import { t as e } from "./rolldown-runtime-Dy4uBu1J.js";
2
+ import { r as t } from "./PkStreamingMarkdown-XJBXdSG2.js";
3
+ import "./src-DT8FLE4_.js";
4
+ import { n } from "./url-validation-9DstIfq2.js";
5
+ import { t as r } from "./useImageFallback-5vQIO0pC.js";
6
+ import { n as i, r as a } from "./PkChatbotFilePreview-CwiVQDF2.js";
7
+ import { t as o } from "./PkHeldImage-BqnlurT_.js";
8
+ import { VvIcon as s } from "@volverjs/ui-vue/components";
9
+ import { Fragment as c, computed as l, createBlock as u, createCommentVNode as d, createElementBlock as f, createElementVNode as p, createVNode as m, defineComponent as h, normalizeClass as g, onMounted as _, openBlock as v, ref as y, renderList as b, toDisplayString as x, unref as S, watchEffect as C } from "vue";
10
+ //#region ../../packages/components/src/chat/PkToolShowImageGallery.vue?vue&type=script&setup=true&lang.ts
11
+ var w = {
12
+ key: 0,
13
+ class: "border border-surface-3 rounded-xl w-full overflow-hidden bg-surface"
14
+ }, T = { class: "px-sm py-6 bg-surface-1 min-h-40 text-12 border-b border-surface-3 text-word-3 flex items-center gap-8 min-h-40" }, E = { class: "font-bold" }, D = { class: "p-sm" }, O = [
15
+ "href",
16
+ "data-pswp-src",
17
+ "data-pswp-width",
18
+ "data-pswp-height",
19
+ "data-pswp-caption",
20
+ "title",
21
+ "target",
22
+ "rel"
23
+ ], k = [
24
+ "src",
25
+ "alt",
26
+ "onError"
27
+ ], A = {
28
+ key: 2,
29
+ class: "w-full h-full flex flex-col items-center justify-center gap-4 bg-surface-1 text-word-3"
30
+ }, j = { class: "text-12" }, M = /*@__PURE__*/ h({
31
+ __name: "PkToolShowImageGallery",
32
+ props: { part: {} },
33
+ setup(e) {
34
+ let h = e, M = l(() => h.part), N = y(), { preload: P, getSize: F } = i(), I = l(() => M.value.input?.images ?? []), { canShowImage: L, onImageError: R } = r(), z = t(), B = (e) => z.canLoad(e) && L(e), V = /* @__PURE__ */ new Set();
35
+ C(() => {
36
+ let e = I.value.filter((e) => !V.has(e.url) && z.canLoad(e.url));
37
+ for (let t of e) V.add(t.url);
38
+ P(e);
39
+ });
40
+ let H = l(() => {
41
+ let e = I.value.length;
42
+ return e === 1 ? "grid-cols-1 justify-items-center" : e === 2 ? "grid-cols-2" : "grid-cols-3";
43
+ }), { init: U } = a({ gallery: N });
44
+ return _(async () => {
45
+ await U();
46
+ }), (e, t) => {
47
+ let r = s;
48
+ return I.value.length ? (v(), f("div", w, [p("div", T, [m(r, {
49
+ name: "ri:image-line",
50
+ class: "text-16"
51
+ }), p("strong", E, x(e.$t("label.gallery", { count: I.value.length })), 1)]), p("div", D, [p("div", {
52
+ ref_key: "galleryRef",
53
+ ref: N,
54
+ class: g(["grid gap-8", H.value])
55
+ }, [(v(!0), f(c, null, b(I.value, (t) => (v(), f("a", {
56
+ key: t.url,
57
+ href: B(t.url) ? t.url : void 0,
58
+ "data-pswp-src": B(t.url) ? t.url : void 0,
59
+ "data-pswp-width": S(F)(t.url).width,
60
+ "data-pswp-height": S(F)(t.url).height,
61
+ "data-pswp-caption": t.caption ?? t.alt ?? "",
62
+ "data-cropped": !0,
63
+ class: g(["relative block aspect-square overflow-hidden rounded-xl group max-h-384", [{ "w-384 max-w-full": I.value.length === 1 }, S(L)(t.url) ? "cursor-pointer" : "pointer-events-none"]]),
64
+ title: t.caption ?? t.alt ?? "",
65
+ target: S(n)(t.url) ? void 0 : "_blank",
66
+ rel: S(n)(t.url) ? void 0 : "noopener noreferrer"
67
+ }, [S(z).canLoad(t.url) ? S(L)(t.url) ? (v(), f("img", {
68
+ key: 1,
69
+ src: t.url,
70
+ alt: t.alt ?? t.caption ?? "",
71
+ class: "w-full h-full object-cover transition-opacity group-hover:opacity-80",
72
+ onError: (e) => S(R)(t.url)
73
+ }, null, 40, k)) : (v(), f("div", A, [m(r, {
74
+ name: "ri:camera-off-line",
75
+ class: "text-24"
76
+ }), p("span", j, x(e.$t("label.imageLoadError")), 1)])) : (v(), u(o, {
77
+ key: 0,
78
+ host: S(z).hostOf(t.url),
79
+ fill: "",
80
+ onRelease: (e) => S(z).release(t.url)
81
+ }, null, 8, ["host", "onRelease"]))], 10, O))), 128))], 2)])])) : d("", !0);
82
+ };
83
+ }
84
+ }), N = /* @__PURE__ */ e({ default: () => P }), P = M;
85
+ //#endregion
86
+ export { N as n, P as t };
87
+
88
+ //# sourceMappingURL=PkToolShowImageGallery-D44wf_u3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PkToolShowImageGallery-D44wf_u3.js","names":["$t","__unplugin_components_0","_openBlock","_createElementBlock","_createElementVNode","_createVNode","_toDisplayString","_normalizeClass","_Fragment","_renderList","_unref","_createBlock","PkHeldImage","_createCommentVNode","_sfc_main","__exportAll","useChatImageGate","useImageFallback","useImageSizes","useLightbox","PkHeldImage_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","PkToolShowImageGallery_vue_vue_type_script_setup_true_lang_default","props","__props","toolPart","computed","galleryRef","ref","images","imageGate","isShown","url","canShowImage","measured","ready","image","gridCols","count","onMounted","init","_component_VvIcon","VvIcon","openBlock","createElementBlock","createElementVNode","createVNode","toDisplayString","_ctx","normalizeClass","Fragment","renderList","unref","getSize","isSameSite","onImageError","createBlock","createCommentVNode","PkToolShowImageGallery_exports","PkToolShowImageGallery_default"],"sources":["../../../../packages/components/src/chat/PkToolShowImageGallery.vue","../../../../packages/components/src/chat/PkToolShowImageGallery.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, ref, onMounted, watchEffect } from 'vue'\n import { isSameSite } from 'utils'\n import { useImageFallback } from 'composables'\n import { useLightbox, useImageSizes } from '../composables/useLightbox'\n import { useChatImageGate } from './chatImagePolicy'\n import PkHeldImage from './PkHeldImage.vue'\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n images: Array<{\n url: string\n caption?: string\n alt?: string\n }>\n }\n }\n return part\n })\n\n const galleryRef = ref<HTMLElement>()\n const { preload, getSize } = useImageSizes()\n\n const images = computed(() => toolPart.value.input?.images ?? [])\n\n const { canShowImage, onImageError } = useImageFallback()\n // The model writes these urls: one from a host the agent does not list\n // waits for a click (chatImagePolicy.ts). Until then it is not measured,\n // linked or handed to the lightbox, which would all fetch it.\n const imageGate = useChatImageGate()\n const isShown = (url: string) => imageGate.canLoad(url) && canShowImage(url)\n\n // Measured once it may load: a held image when it is released, a short\n // link when it resolves to a listed host.\n const measured = new Set<string>()\n watchEffect(() => {\n const ready = images.value.filter(\n (image) => !measured.has(image.url) && imageGate.canLoad(image.url),\n )\n for (const image of ready) {\n measured.add(image.url)\n }\n preload(ready)\n })\n\n const gridCols = computed(() => {\n const count = images.value.length\n if (count === 1) {\n return 'grid-cols-1 justify-items-center'\n }\n if (count === 2) {\n return 'grid-cols-2'\n }\n return 'grid-cols-3'\n })\n\n const { init } = useLightbox({ gallery: galleryRef })\n\n onMounted(async () => {\n await init()\n })\n</script>\n\n<template>\n <div\n v-if=\"images.length\"\n class=\"border border-surface-3 rounded-xl w-full overflow-hidden bg-surface\">\n <div\n class=\"px-sm py-6 bg-surface-1 min-h-40 text-12 border-b border-surface-3 text-word-3 flex items-center gap-8 min-h-40\">\n <VvIcon name=\"ri:image-line\" class=\"text-16\" />\n <strong class=\"font-bold\">\n {{ $t('label.gallery', { count: images.length }) }}\n </strong>\n </div>\n <div class=\"p-sm\">\n <div ref=\"galleryRef\" class=\"grid gap-8\" :class=\"gridCols\">\n <a\n v-for=\"image in images\"\n :key=\"image.url\"\n :href=\"isShown(image.url) ? image.url : undefined\"\n :data-pswp-src=\"isShown(image.url) ? image.url : undefined\"\n :data-pswp-width=\"getSize(image.url).width\"\n :data-pswp-height=\"getSize(image.url).height\"\n :data-pswp-caption=\"image.caption ?? image.alt ?? ''\"\n :data-cropped=\"true\"\n class=\"relative block aspect-square overflow-hidden rounded-xl group max-h-384\"\n :class=\"[\n { 'w-384 max-w-full': images.length === 1 },\n canShowImage(image.url)\n ? 'cursor-pointer'\n : 'pointer-events-none',\n ]\"\n :title=\"image.caption ?? image.alt ?? ''\"\n :target=\"isSameSite(image.url) ? undefined : '_blank'\"\n :rel=\"\n isSameSite(image.url)\n ? undefined\n : 'noopener noreferrer'\n \">\n <PkHeldImage\n v-if=\"!imageGate.canLoad(image.url)\"\n :host=\"imageGate.hostOf(image.url)\"\n fill\n @release=\"imageGate.release(image.url)\" />\n <img\n v-else-if=\"canShowImage(image.url)\"\n :src=\"image.url\"\n :alt=\"image.alt ?? image.caption ?? ''\"\n class=\"w-full h-full object-cover transition-opacity group-hover:opacity-80\"\n @error=\"onImageError(image.url)\" />\n <div\n v-else\n class=\"w-full h-full flex flex-col items-center justify-center gap-4 bg-surface-1 text-word-3\">\n <VvIcon name=\"ri:camera-off-line\" class=\"text-24\" />\n <span class=\"text-12\">{{\n $t('label.imageLoadError')\n }}</span>\n </div>\n </a>\n </div>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed, ref, onMounted, watchEffect } from 'vue'\n import { isSameSite } from 'utils'\n import { useImageFallback } from 'composables'\n import { useLightbox, useImageSizes } from '../composables/useLightbox'\n import { useChatImageGate } from './chatImagePolicy'\n import PkHeldImage from './PkHeldImage.vue'\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n images: Array<{\n url: string\n caption?: string\n alt?: string\n }>\n }\n }\n return part\n })\n\n const galleryRef = ref<HTMLElement>()\n const { preload, getSize } = useImageSizes()\n\n const images = computed(() => toolPart.value.input?.images ?? [])\n\n const { canShowImage, onImageError } = useImageFallback()\n // The model writes these urls: one from a host the agent does not list\n // waits for a click (chatImagePolicy.ts). Until then it is not measured,\n // linked or handed to the lightbox, which would all fetch it.\n const imageGate = useChatImageGate()\n const isShown = (url: string) => imageGate.canLoad(url) && canShowImage(url)\n\n // Measured once it may load: a held image when it is released, a short\n // link when it resolves to a listed host.\n const measured = new Set<string>()\n watchEffect(() => {\n const ready = images.value.filter(\n (image) => !measured.has(image.url) && imageGate.canLoad(image.url),\n )\n for (const image of ready) {\n measured.add(image.url)\n }\n preload(ready)\n })\n\n const gridCols = computed(() => {\n const count = images.value.length\n if (count === 1) {\n return 'grid-cols-1 justify-items-center'\n }\n if (count === 2) {\n return 'grid-cols-2'\n }\n return 'grid-cols-3'\n })\n\n const { init } = useLightbox({ gallery: galleryRef })\n\n onMounted(async () => {\n await init()\n })\n</script>\n\n<template>\n <div\n v-if=\"images.length\"\n class=\"border border-surface-3 rounded-xl w-full overflow-hidden bg-surface\">\n <div\n class=\"px-sm py-6 bg-surface-1 min-h-40 text-12 border-b border-surface-3 text-word-3 flex items-center gap-8 min-h-40\">\n <VvIcon name=\"ri:image-line\" class=\"text-16\" />\n <strong class=\"font-bold\">\n {{ $t('label.gallery', { count: images.length }) }}\n </strong>\n </div>\n <div class=\"p-sm\">\n <div ref=\"galleryRef\" class=\"grid gap-8\" :class=\"gridCols\">\n <a\n v-for=\"image in images\"\n :key=\"image.url\"\n :href=\"isShown(image.url) ? image.url : undefined\"\n :data-pswp-src=\"isShown(image.url) ? image.url : undefined\"\n :data-pswp-width=\"getSize(image.url).width\"\n :data-pswp-height=\"getSize(image.url).height\"\n :data-pswp-caption=\"image.caption ?? image.alt ?? ''\"\n :data-cropped=\"true\"\n class=\"relative block aspect-square overflow-hidden rounded-xl group max-h-384\"\n :class=\"[\n { 'w-384 max-w-full': images.length === 1 },\n canShowImage(image.url)\n ? 'cursor-pointer'\n : 'pointer-events-none',\n ]\"\n :title=\"image.caption ?? image.alt ?? ''\"\n :target=\"isSameSite(image.url) ? undefined : '_blank'\"\n :rel=\"\n isSameSite(image.url)\n ? undefined\n : 'noopener noreferrer'\n \">\n <PkHeldImage\n v-if=\"!imageGate.canLoad(image.url)\"\n :host=\"imageGate.hostOf(image.url)\"\n fill\n @release=\"imageGate.release(image.url)\" />\n <img\n v-else-if=\"canShowImage(image.url)\"\n :src=\"image.url\"\n :alt=\"image.alt ?? image.caption ?? ''\"\n class=\"w-full h-full object-cover transition-opacity group-hover:opacity-80\"\n @error=\"onImageError(image.url)\" />\n <div\n v-else\n class=\"w-full h-full flex flex-col items-center justify-center gap-4 bg-surface-1 text-word-3\">\n <VvIcon name=\"ri:camera-off-line\" class=\"text-24\" />\n <span class=\"text-12\">{{\n $t('label.imageLoadError')\n }}</span>\n </div>\n </a>\n </div>\n </div>\n </div>\n</template>\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { t as e } from "./rolldown-runtime-Dy4uBu1J.js";
2
- import { r as t } from "./PkStreamingMarkdown-CJlfq7ub.js";
2
+ import { n as t } from "./useShortUrlResolver-DI8ycJiO.js";
3
3
  import { VvButton as n, VvButtonGroup as r, VvDropdown as i, VvDropdownAction as a, VvIcon as o } from "@volverjs/ui-vue/components";
4
4
  import { computed as s, createElementBlock as c, createElementVNode as l, createTextVNode as u, createVNode as d, defineComponent as f, guardReactiveProps as p, normalizeProps as m, openBlock as h, toDisplayString as g, unref as _, withCtx as v } from "vue";
5
5
  import { useClipboard as y } from "@vueuse/core";
@@ -75,4 +75,4 @@ var b = { class: "border border-surface-3 rounded-xl w-full overflow-hidden bg-s
75
75
  //#endregion
76
76
  export { D as n, O as t };
77
77
 
78
- //# sourceMappingURL=PkToolShowMessage-lNPZxw2v.js.map
78
+ //# sourceMappingURL=PkToolShowMessage-CbXERPHI.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PkToolShowMessage-lNPZxw2v.js","names":["$t","__unplugin_components_0","__unplugin_components_1","__unplugin_components_2","__unplugin_components_3","__unplugin_components_4","_openBlock","_createElementBlock","_createElementVNode","_createVNode","_toDisplayString","_withCtx","_unref","_normalizeProps","_guardReactiveProps","_createTextVNode","_sfc_main","__exportAll","useShortUrlResolver","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","PkToolShowMessage_vue_vue_type_script_setup_true_lang_default","props","__props","useClipboard","toolPart","computed","body","resolveText","openInWhatsApp","url","openInTelegram","openInSms","_component_VvIcon","VvIcon","_component_VvButton","VvButton","_component_VvDropdownAction","VvDropdownAction","_component_VvDropdown","VvDropdown","_component_VvButtonGroup","VvButtonGroup","openBlock","createElementBlock","createElementVNode","createVNode","toDisplayString","_ctx","withCtx","unref","copied","_cache","copy","normalizeProps","guardReactiveProps","createTextVNode","PkToolShowMessage_exports","PkToolShowMessage_default"],"sources":["../../../../packages/components/src/chat/PkToolShowMessage.vue","../../../../packages/components/src/chat/PkToolShowMessage.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useClipboard } from '@vueuse/core'\n import { useShortUrlResolver } from 'composables'\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const { copy, copied } = useClipboard()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n body: string\n }\n }\n return part\n })\n\n // Messages leave the app (WhatsApp/Telegram/SMS/clipboard), so expand short\n // urls to their real target rather than keeping the fragile `/api/r/` link.\n const { resolveText } = useShortUrlResolver()\n const body = resolveText(() => toolPart.value.input?.body)\n\n const openInWhatsApp = () => {\n if (!toolPart.value.input) {\n return\n }\n const url = `https://wa.me/?text=${encodeURIComponent(body.value)}`\n window.open(url, '_blank')\n }\n\n const openInTelegram = () => {\n if (!toolPart.value.input) {\n return\n }\n const url = `https://t.me/share/url?text=${encodeURIComponent(body.value)}`\n window.open(url, '_blank')\n }\n\n const openInSms = () => {\n if (!toolPart.value.input) {\n return\n }\n const url = `sms:?body=${encodeURIComponent(body.value)}`\n window.open(url)\n }\n</script>\n\n<template>\n <div\n class=\"border border-surface-3 rounded-xl w-full overflow-hidden bg-surface\">\n <div\n class=\"px-sm py-6 bg-surface-1 min-h-40 text-12 border-b border-surface-3 text-word-3 flex items-center gap-8\">\n <VvIcon name=\"ri:chat-1-line\" class=\"text-16\" />\n <strong class=\"font-bold\">\n {{ $t('label.message') }}\n </strong>\n <VvButtonGroup modifiers=\"compact\" class=\"ml-auto shrink-0\">\n <VvButton\n modifiers=\"action-quiet-small\"\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n @click=\"copy(body)\" />\n <VvDropdown\n v-bind=\"{\n placement: 'bottom-end',\n modifiers: 'menu',\n flip: true,\n offset: 3,\n strategy: 'fixed',\n }\">\n <VvButton\n icon=\"ri:send-plane-line\"\n modifiers=\"action-quiet-small\"\n :label=\"$t('action.send')\" />\n <template #items>\n <VvDropdownAction @click=\"openInWhatsApp\">\n <VvIcon name=\"ri:whatsapp-line\" />\n {{ $t('action.openInWhatsApp') }}\n </VvDropdownAction>\n <VvDropdownAction @click=\"openInTelegram\">\n <VvIcon name=\"ri:telegram-line\" />\n {{ $t('action.openInTelegram') }}\n </VvDropdownAction>\n <VvDropdownAction @click=\"openInSms\">\n <VvIcon name=\"ri:message-2-line\" />\n {{ $t('action.openInSms') }}\n </VvDropdownAction>\n </template>\n </VvDropdown>\n </VvButtonGroup>\n </div>\n <div class=\"p-sm\">\n <div class=\"text-12 text-word-4 mb-4\">\n {{ $t('label.body') }}\n </div>\n <pre class=\"text-word-2 whitespace-pre-wrap break-words\">{{\n body\n }}</pre>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useClipboard } from '@vueuse/core'\n import { useShortUrlResolver } from 'composables'\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const { copy, copied } = useClipboard()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n body: string\n }\n }\n return part\n })\n\n // Messages leave the app (WhatsApp/Telegram/SMS/clipboard), so expand short\n // urls to their real target rather than keeping the fragile `/api/r/` link.\n const { resolveText } = useShortUrlResolver()\n const body = resolveText(() => toolPart.value.input?.body)\n\n const openInWhatsApp = () => {\n if (!toolPart.value.input) {\n return\n }\n const url = `https://wa.me/?text=${encodeURIComponent(body.value)}`\n window.open(url, '_blank')\n }\n\n const openInTelegram = () => {\n if (!toolPart.value.input) {\n return\n }\n const url = `https://t.me/share/url?text=${encodeURIComponent(body.value)}`\n window.open(url, '_blank')\n }\n\n const openInSms = () => {\n if (!toolPart.value.input) {\n return\n }\n const url = `sms:?body=${encodeURIComponent(body.value)}`\n window.open(url)\n }\n</script>\n\n<template>\n <div\n class=\"border border-surface-3 rounded-xl w-full overflow-hidden bg-surface\">\n <div\n class=\"px-sm py-6 bg-surface-1 min-h-40 text-12 border-b border-surface-3 text-word-3 flex items-center gap-8\">\n <VvIcon name=\"ri:chat-1-line\" class=\"text-16\" />\n <strong class=\"font-bold\">\n {{ $t('label.message') }}\n </strong>\n <VvButtonGroup modifiers=\"compact\" class=\"ml-auto shrink-0\">\n <VvButton\n modifiers=\"action-quiet-small\"\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n @click=\"copy(body)\" />\n <VvDropdown\n v-bind=\"{\n placement: 'bottom-end',\n modifiers: 'menu',\n flip: true,\n offset: 3,\n strategy: 'fixed',\n }\">\n <VvButton\n icon=\"ri:send-plane-line\"\n modifiers=\"action-quiet-small\"\n :label=\"$t('action.send')\" />\n <template #items>\n <VvDropdownAction @click=\"openInWhatsApp\">\n <VvIcon name=\"ri:whatsapp-line\" />\n {{ $t('action.openInWhatsApp') }}\n </VvDropdownAction>\n <VvDropdownAction @click=\"openInTelegram\">\n <VvIcon name=\"ri:telegram-line\" />\n {{ $t('action.openInTelegram') }}\n </VvDropdownAction>\n <VvDropdownAction @click=\"openInSms\">\n <VvIcon name=\"ri:message-2-line\" />\n {{ $t('action.openInSms') }}\n </VvDropdownAction>\n </template>\n </VvDropdown>\n </VvButtonGroup>\n </div>\n <div class=\"p-sm\">\n <div class=\"text-12 text-word-4 mb-4\">\n {{ $t('label.body') }}\n </div>\n <pre class=\"text-word-2 whitespace-pre-wrap break-words\">{{\n body\n }}</pre>\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;EAKI,IAAM0B,IAAQC,GAIR,EAAE,SAAM,cAAWC,EAAa,GAEhCC,IAAWC,QACAJ,EAAM,IAMtB,GAIK,EAAE,mBAAgBR,EAAoB,GACtCa,IAAOC,QAAkBH,EAAS,MAAM,OAAO,IAAI,GAEnDI,UAAuB;GACzB,IAAI,CAACJ,EAAS,MAAM,OAChB;GAEJ,IAAMK,IAAM,uBAAuB,mBAAmBH,EAAK,KAAK;GAChE,OAAO,KAAKG,GAAK,QAAQ;EAC7B,GAEMC,UAAuB;GACzB,IAAI,CAACN,EAAS,MAAM,OAChB;GAEJ,IAAMK,IAAM,+BAA+B,mBAAmBH,EAAK,KAAK;GACxE,OAAO,KAAKG,GAAK,QAAQ;EAC7B,GAEME,UAAkB;GACpB,IAAI,CAACP,EAAS,MAAM,OAChB;GAEJ,IAAMK,IAAM,aAAa,mBAAmBH,EAAK,KAAK;GACtD,OAAO,KAAKG,CAAG;EACnB;;;GAIA,OAAA5B,EAAA,GAAAC,EAmDM,OAnDNY,GAmDM,CAjDFX,EAwCM,OAxCNY,GAwCM;IAtCFX,EAAgD4B,GAAA;KAAxC,MAAK;KAAiB,OAAM;;IACpC7B,EAES,UAFTa,GAESX,EADFV,EAAAA,GAAE,eAAA,CAAA,GAAA,CAAA;IAETS,EAiCgBoC,GAAA;KAjCD,WAAU;KAAU,OAAM;;KACrC,SAAAlC,QAI0B,CAJ1BF,EAI0B8B,GAAA;MAHtB,WAAU;MACT,MAAM3B,EAAA2C,CAAA,IAAM,kBAAA;MACZ,OAAO3C,EAAA2C,CAAA,IAASvD,EAAAA,GAAE,eAAA,IAAoBA,EAAAA,GAAE,aAAA;MACxC,SAAK,AAAAwD,EAAA,QAAA,MAAE5C,EAAA6C,CAAA,CAAI,CAAC7C,EAAAmB,CAAA,CAAI;KACrBtB,GAAAA,MAAAA,GAAAA,CAAAA,QAAAA,OAAAA,CAAAA,GAAAA,EA0BakC,GAAA9B,EAAAC,EAzBD;;;;;;KAMP,CAAA,CAAA,GAAA;MAKU,OAAKH,QAIO;OAHnBF,EAGmBgC,GAAA,EAHA,SAAOR,EAAc,GAAA;QACpC,SAAAtB,QAAkC,CAAlCF,EAAkC4B,GAAA,EAA1B,MAAK,mBAAkB,CAAA,GAAGtB,EAAA,MAClCL,EAAGV,EAAAA,GAAE,uBAAA,CAAA,GAAA,CAAA,CAAA,CAAA;;;OAETS,EAGmBgC,GAAA,EAHA,SAAON,EAAc,GAAA;QACpC,SAAAxB,QAAkC,CAAlCF,EAAkC4B,GAAA,EAA1B,MAAK,mBAAkB,CAAA,GAAGtB,EAAA,MAClCL,EAAGV,EAAAA,GAAE,uBAAA,CAAA,GAAA,CAAA,CAAA,CAAA;;;OAETS,EAGmBgC,GAAA,EAHA,SAAOL,EAAS,GAAA;QAC/B,SAAAzB,QAAmC,CAAnCF,EAAmC4B,GAAA,EAA3B,MAAK,oBAAmB,CAAA,GAAGtB,EAAA,MACnCL,EAAGV,EAAAA,GAAE,kBAAA,CAAA,GAAA,CAAA,CAAA,CAAA;;;;MAfb,SAAAW,QAGiC,CAHjCF,EAGiC8B,GAAA;OAF7B,MAAK;OACL,WAAU;OACT,OAAOvC,EAAAA,GAAE,aAAA;;;;;;GAkB1BQ,CAAAA,GAAAA,EAOM,OAPNc,GAOM,CANFd,EAEM,OAFNe,GAEMb,EADCV,EAAAA,GAAE,YAAA,CAAA,GAAA,CAAA,GAETQ,EAEQ,OAFRgB,GAEQd,EADJE,EAAAmB,CAAA,CAAI,GAAA,CAAA,CAAA,CAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"PkToolShowMessage-CbXERPHI.js","names":["$t","__unplugin_components_0","__unplugin_components_1","__unplugin_components_2","__unplugin_components_3","__unplugin_components_4","_openBlock","_createElementBlock","_createElementVNode","_createVNode","_toDisplayString","_withCtx","_unref","_normalizeProps","_guardReactiveProps","_createTextVNode","_sfc_main","__exportAll","useShortUrlResolver","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","PkToolShowMessage_vue_vue_type_script_setup_true_lang_default","props","__props","useClipboard","toolPart","computed","body","resolveText","openInWhatsApp","url","openInTelegram","openInSms","_component_VvIcon","VvIcon","_component_VvButton","VvButton","_component_VvDropdownAction","VvDropdownAction","_component_VvDropdown","VvDropdown","_component_VvButtonGroup","VvButtonGroup","openBlock","createElementBlock","createElementVNode","createVNode","toDisplayString","_ctx","withCtx","unref","copied","_cache","copy","normalizeProps","guardReactiveProps","createTextVNode","PkToolShowMessage_exports","PkToolShowMessage_default"],"sources":["../../../../packages/components/src/chat/PkToolShowMessage.vue","../../../../packages/components/src/chat/PkToolShowMessage.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useClipboard } from '@vueuse/core'\n import { useShortUrlResolver } from 'composables'\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const { copy, copied } = useClipboard()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n body: string\n }\n }\n return part\n })\n\n // Messages leave the app (WhatsApp/Telegram/SMS/clipboard), so expand short\n // urls to their real target rather than keeping the fragile `/api/r/` link.\n const { resolveText } = useShortUrlResolver()\n const body = resolveText(() => toolPart.value.input?.body)\n\n const openInWhatsApp = () => {\n if (!toolPart.value.input) {\n return\n }\n const url = `https://wa.me/?text=${encodeURIComponent(body.value)}`\n window.open(url, '_blank')\n }\n\n const openInTelegram = () => {\n if (!toolPart.value.input) {\n return\n }\n const url = `https://t.me/share/url?text=${encodeURIComponent(body.value)}`\n window.open(url, '_blank')\n }\n\n const openInSms = () => {\n if (!toolPart.value.input) {\n return\n }\n const url = `sms:?body=${encodeURIComponent(body.value)}`\n window.open(url)\n }\n</script>\n\n<template>\n <div\n class=\"border border-surface-3 rounded-xl w-full overflow-hidden bg-surface\">\n <div\n class=\"px-sm py-6 bg-surface-1 min-h-40 text-12 border-b border-surface-3 text-word-3 flex items-center gap-8\">\n <VvIcon name=\"ri:chat-1-line\" class=\"text-16\" />\n <strong class=\"font-bold\">\n {{ $t('label.message') }}\n </strong>\n <VvButtonGroup modifiers=\"compact\" class=\"ml-auto shrink-0\">\n <VvButton\n modifiers=\"action-quiet-small\"\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n @click=\"copy(body)\" />\n <VvDropdown\n v-bind=\"{\n placement: 'bottom-end',\n modifiers: 'menu',\n flip: true,\n offset: 3,\n strategy: 'fixed',\n }\">\n <VvButton\n icon=\"ri:send-plane-line\"\n modifiers=\"action-quiet-small\"\n :label=\"$t('action.send')\" />\n <template #items>\n <VvDropdownAction @click=\"openInWhatsApp\">\n <VvIcon name=\"ri:whatsapp-line\" />\n {{ $t('action.openInWhatsApp') }}\n </VvDropdownAction>\n <VvDropdownAction @click=\"openInTelegram\">\n <VvIcon name=\"ri:telegram-line\" />\n {{ $t('action.openInTelegram') }}\n </VvDropdownAction>\n <VvDropdownAction @click=\"openInSms\">\n <VvIcon name=\"ri:message-2-line\" />\n {{ $t('action.openInSms') }}\n </VvDropdownAction>\n </template>\n </VvDropdown>\n </VvButtonGroup>\n </div>\n <div class=\"p-sm\">\n <div class=\"text-12 text-word-4 mb-4\">\n {{ $t('label.body') }}\n </div>\n <pre class=\"text-word-2 whitespace-pre-wrap break-words\">{{\n body\n }}</pre>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useClipboard } from '@vueuse/core'\n import { useShortUrlResolver } from 'composables'\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const { copy, copied } = useClipboard()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n body: string\n }\n }\n return part\n })\n\n // Messages leave the app (WhatsApp/Telegram/SMS/clipboard), so expand short\n // urls to their real target rather than keeping the fragile `/api/r/` link.\n const { resolveText } = useShortUrlResolver()\n const body = resolveText(() => toolPart.value.input?.body)\n\n const openInWhatsApp = () => {\n if (!toolPart.value.input) {\n return\n }\n const url = `https://wa.me/?text=${encodeURIComponent(body.value)}`\n window.open(url, '_blank')\n }\n\n const openInTelegram = () => {\n if (!toolPart.value.input) {\n return\n }\n const url = `https://t.me/share/url?text=${encodeURIComponent(body.value)}`\n window.open(url, '_blank')\n }\n\n const openInSms = () => {\n if (!toolPart.value.input) {\n return\n }\n const url = `sms:?body=${encodeURIComponent(body.value)}`\n window.open(url)\n }\n</script>\n\n<template>\n <div\n class=\"border border-surface-3 rounded-xl w-full overflow-hidden bg-surface\">\n <div\n class=\"px-sm py-6 bg-surface-1 min-h-40 text-12 border-b border-surface-3 text-word-3 flex items-center gap-8\">\n <VvIcon name=\"ri:chat-1-line\" class=\"text-16\" />\n <strong class=\"font-bold\">\n {{ $t('label.message') }}\n </strong>\n <VvButtonGroup modifiers=\"compact\" class=\"ml-auto shrink-0\">\n <VvButton\n modifiers=\"action-quiet-small\"\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n @click=\"copy(body)\" />\n <VvDropdown\n v-bind=\"{\n placement: 'bottom-end',\n modifiers: 'menu',\n flip: true,\n offset: 3,\n strategy: 'fixed',\n }\">\n <VvButton\n icon=\"ri:send-plane-line\"\n modifiers=\"action-quiet-small\"\n :label=\"$t('action.send')\" />\n <template #items>\n <VvDropdownAction @click=\"openInWhatsApp\">\n <VvIcon name=\"ri:whatsapp-line\" />\n {{ $t('action.openInWhatsApp') }}\n </VvDropdownAction>\n <VvDropdownAction @click=\"openInTelegram\">\n <VvIcon name=\"ri:telegram-line\" />\n {{ $t('action.openInTelegram') }}\n </VvDropdownAction>\n <VvDropdownAction @click=\"openInSms\">\n <VvIcon name=\"ri:message-2-line\" />\n {{ $t('action.openInSms') }}\n </VvDropdownAction>\n </template>\n </VvDropdown>\n </VvButtonGroup>\n </div>\n <div class=\"p-sm\">\n <div class=\"text-12 text-word-4 mb-4\">\n {{ $t('label.body') }}\n </div>\n <pre class=\"text-word-2 whitespace-pre-wrap break-words\">{{\n body\n }}</pre>\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;EAKI,IAAM0B,IAAQC,GAIR,EAAE,SAAM,cAAWC,EAAa,GAEhCC,IAAWC,QACAJ,EAAM,IAMtB,GAIK,EAAE,mBAAgBR,EAAoB,GACtCa,IAAOC,QAAkBH,EAAS,MAAM,OAAO,IAAI,GAEnDI,UAAuB;GACzB,IAAI,CAACJ,EAAS,MAAM,OAChB;GAEJ,IAAMK,IAAM,uBAAuB,mBAAmBH,EAAK,KAAK;GAChE,OAAO,KAAKG,GAAK,QAAQ;EAC7B,GAEMC,UAAuB;GACzB,IAAI,CAACN,EAAS,MAAM,OAChB;GAEJ,IAAMK,IAAM,+BAA+B,mBAAmBH,EAAK,KAAK;GACxE,OAAO,KAAKG,GAAK,QAAQ;EAC7B,GAEME,UAAkB;GACpB,IAAI,CAACP,EAAS,MAAM,OAChB;GAEJ,IAAMK,IAAM,aAAa,mBAAmBH,EAAK,KAAK;GACtD,OAAO,KAAKG,CAAG;EACnB;;;GAIA,OAAA5B,EAAA,GAAAC,EAmDM,OAnDNY,GAmDM,CAjDFX,EAwCM,OAxCNY,GAwCM;IAtCFX,EAAgD4B,GAAA;KAAxC,MAAK;KAAiB,OAAM;;IACpC7B,EAES,UAFTa,GAESX,EADFV,EAAAA,GAAE,eAAA,CAAA,GAAA,CAAA;IAETS,EAiCgBoC,GAAA;KAjCD,WAAU;KAAU,OAAM;;KACrC,SAAAlC,QAI0B,CAJ1BF,EAI0B8B,GAAA;MAHtB,WAAU;MACT,MAAM3B,EAAA2C,CAAA,IAAM,kBAAA;MACZ,OAAO3C,EAAA2C,CAAA,IAASvD,EAAAA,GAAE,eAAA,IAAoBA,EAAAA,GAAE,aAAA;MACxC,SAAK,AAAAwD,EAAA,QAAA,MAAE5C,EAAA6C,CAAA,CAAI,CAAC7C,EAAAmB,CAAA,CAAI;KACrBtB,GAAAA,MAAAA,GAAAA,CAAAA,QAAAA,OAAAA,CAAAA,GAAAA,EA0BakC,GAAA9B,EAAAC,EAzBD;;;;;;KAMP,CAAA,CAAA,GAAA;MAKU,OAAKH,QAIO;OAHnBF,EAGmBgC,GAAA,EAHA,SAAOR,EAAc,GAAA;QACpC,SAAAtB,QAAkC,CAAlCF,EAAkC4B,GAAA,EAA1B,MAAK,mBAAkB,CAAA,GAAGtB,EAAA,MAClCL,EAAGV,EAAAA,GAAE,uBAAA,CAAA,GAAA,CAAA,CAAA,CAAA;;;OAETS,EAGmBgC,GAAA,EAHA,SAAON,EAAc,GAAA;QACpC,SAAAxB,QAAkC,CAAlCF,EAAkC4B,GAAA,EAA1B,MAAK,mBAAkB,CAAA,GAAGtB,EAAA,MAClCL,EAAGV,EAAAA,GAAE,uBAAA,CAAA,GAAA,CAAA,CAAA,CAAA;;;OAETS,EAGmBgC,GAAA,EAHA,SAAOL,EAAS,GAAA;QAC/B,SAAAzB,QAAmC,CAAnCF,EAAmC4B,GAAA,EAA3B,MAAK,oBAAmB,CAAA,GAAGtB,EAAA,MACnCL,EAAGV,EAAAA,GAAE,kBAAA,CAAA,GAAA,CAAA,CAAA,CAAA;;;;MAfb,SAAAW,QAGiC,CAHjCF,EAGiC8B,GAAA;OAF7B,MAAK;OACL,WAAU;OACT,OAAOvC,EAAAA,GAAE,aAAA;;;;;;GAkB1BQ,CAAAA,GAAAA,EAOM,OAPNc,GAOM,CANFd,EAEM,OAFNe,GAEMb,EADCV,EAAAA,GAAE,YAAA,CAAA,GAAA,CAAA,GAETQ,EAEQ,OAFRgB,GAEQd,EADJE,EAAAmB,CAAA,CAAI,GAAA,CAAA,CAAA,CAAA,CAAA,CAAA"}
@@ -0,0 +1,72 @@
1
+ import { t as e } from "./rolldown-runtime-Dy4uBu1J.js";
2
+ import { r as t } from "./PkStreamingMarkdown-XJBXdSG2.js";
3
+ import { t as n } from "./PkLazyImg-CDxX9xnq.js";
4
+ import { t as r } from "./PkUrl-CN1kkZiH.js";
5
+ import { t as i } from "./PkHeldImage-BqnlurT_.js";
6
+ import { VvIcon as a } from "@volverjs/ui-vue/components";
7
+ import { Fragment as o, computed as s, createBlock as c, createCommentVNode as l, createElementBlock as u, createElementVNode as d, createVNode as f, defineComponent as p, openBlock as m, renderList as h, resolveDynamicComponent as g, toDisplayString as _, unref as v, withCtx as y } from "vue";
8
+ //#region ../../packages/components/src/chat/PkToolShowProductList.vue?vue&type=script&setup=true&lang.ts
9
+ var b = {
10
+ key: 0,
11
+ class: "u-pick-list w-full"
12
+ }, x = { class: "flex flex-col gap-4 min-w-0 flex-1" }, S = { class: "font-bold text-12 text-word-1 truncate" }, C = {
13
+ key: 0,
14
+ class: "text-10 text-word-4 truncate flex items-center gap-4"
15
+ }, w = { class: "flex items-center gap-sm flex-wrap text-12" }, T = {
16
+ key: 0,
17
+ class: "font-semibold text-word-1"
18
+ }, E = {
19
+ key: 1,
20
+ class: "text-10 text-word-3"
21
+ }, D = {
22
+ key: 1,
23
+ class: "text-12 text-word-3 line-clamp-2"
24
+ }, O = /*@__PURE__*/ p({
25
+ __name: "PkToolShowProductList",
26
+ props: { part: {} },
27
+ setup(e) {
28
+ let p = e, O = s(() => p.part), k = t();
29
+ return (e, t) => {
30
+ let s = a;
31
+ return O.value?.input?.products?.length ? (m(), u("ul", b, [(m(!0), u(o, null, h(O.value.input.products, (e, t) => (m(), u("li", {
32
+ key: t,
33
+ class: "u-pick-list__row"
34
+ }, [(m(), c(g(e.url ? "a" : "div"), {
35
+ href: e.url,
36
+ target: e.url ? "_blank" : void 0,
37
+ rel: e.url ? "noopener noreferrer" : void 0,
38
+ class: "u-pick-list__entry"
39
+ }, {
40
+ default: y(() => [e.image && !v(k).canLoad(e.image) ? (m(), c(i, {
41
+ key: 0,
42
+ host: v(k).hostOf(e.image),
43
+ class: "w-48 h-48 rounded-lg shrink-0 border border-surface-3 bg-surface",
44
+ onRelease: (t) => v(k).release(e.image)
45
+ }, null, 8, ["host", "onRelease"])) : e.image ? (m(), c(n, {
46
+ key: 1,
47
+ src: e.image,
48
+ alt: e.name,
49
+ "fallback-icon": "ri:image-off-line",
50
+ class: "w-48 h-48 object-contain rounded-lg shrink-0 border border-surface-3 bg-surface"
51
+ }, null, 8, ["src", "alt"])) : l("", !0), d("div", x, [
52
+ d("strong", S, _(e.name), 1),
53
+ e.url ? (m(), u("span", C, [f(s, {
54
+ name: "ri:link",
55
+ class: "shrink-0 text-12"
56
+ }), f(r, { url: e.url }, null, 8, ["url"])])) : l("", !0),
57
+ d("div", w, [e.price ? (m(), u("span", T, _(e.price), 1)) : l("", !0), e.availability ? (m(), u("span", E, _(e.availability), 1)) : l("", !0)]),
58
+ e.description ? (m(), u("p", D, _(e.description), 1)) : l("", !0)
59
+ ])]),
60
+ _: 2
61
+ }, 1032, [
62
+ "href",
63
+ "target",
64
+ "rel"
65
+ ]))]))), 128))])) : l("", !0);
66
+ };
67
+ }
68
+ }), k = /* @__PURE__ */ e({ default: () => A }), A = O;
69
+ //#endregion
70
+ export { k as n, A as t };
71
+
72
+ //# sourceMappingURL=PkToolShowProductList-C6CVRUlD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PkToolShowProductList-C6CVRUlD.js","names":["__unplugin_components_0","_openBlock","_createElementBlock","_Fragment","_renderList","_createBlock","_resolveDynamicComponent","_withCtx","_unref","PkHeldImage","PkLazyImg","_createCommentVNode","_createElementVNode","_toDisplayString","_createVNode","PkUrl","_sfc_main","__exportAll","useChatImageGate","PkLazyImg_default","PkUrl_default","PkHeldImage_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","PkToolShowProductList_vue_vue_type_script_setup_true_lang_default","props","__props","toolPart","computed","imageGate","_component_VvIcon","VvIcon","openBlock","createElementBlock","Fragment","renderList","index","createBlock","resolveDynamicComponent","product","withCtx","unref","createCommentVNode","createElementVNode","toDisplayString","createVNode","PkToolShowProductList_exports","PkToolShowProductList_default"],"sources":["../../../../packages/components/src/chat/PkToolShowProductList.vue","../../../../packages/components/src/chat/PkToolShowProductList.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed } from 'vue'\n import PkLazyImg from '../PkLazyImg.vue'\n import { useChatImageGate } from './chatImagePolicy'\n import PkHeldImage from './PkHeldImage.vue'\n import PkUrl from '../PkUrl.vue'\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n products: Array<{\n name: string\n url?: string\n image?: string\n price?: string\n availability?: string\n description?: string\n }>\n }\n }\n return part\n })\n\n // The model writes these urls: one from a host the agent does not list\n // waits for a click (chatImagePolicy.ts).\n const imageGate = useChatImageGate()\n</script>\n\n<template>\n <ul v-if=\"toolPart?.input?.products?.length\" class=\"u-pick-list w-full\">\n <li\n v-for=\"(product, index) in toolPart.input.products\"\n :key=\"index\"\n class=\"u-pick-list__row\">\n <component\n :is=\"product.url ? 'a' : 'div'\"\n :href=\"product.url\"\n :target=\"product.url ? '_blank' : undefined\"\n :rel=\"product.url ? 'noopener noreferrer' : undefined\"\n class=\"u-pick-list__entry\">\n <!-- Merchant images rot over time: a dead one degrades to an icon\n so the row keeps its thumbnail slot -->\n <PkHeldImage\n v-if=\"product.image && !imageGate.canLoad(product.image)\"\n :host=\"imageGate.hostOf(product.image)\"\n class=\"w-48 h-48 rounded-lg shrink-0 border border-surface-3 bg-surface\"\n @release=\"imageGate.release(product.image)\" />\n <PkLazyImg\n v-else-if=\"product.image\"\n :src=\"product.image\"\n :alt=\"product.name\"\n fallback-icon=\"ri:image-off-line\"\n class=\"w-48 h-48 object-contain rounded-lg shrink-0 border border-surface-3 bg-surface\" />\n <div class=\"flex flex-col gap-4 min-w-0 flex-1\">\n <strong class=\"font-bold text-12 text-word-1 truncate\">\n {{ product.name }}\n </strong>\n <span\n v-if=\"product.url\"\n class=\"text-10 text-word-4 truncate flex items-center gap-4\">\n <VvIcon name=\"ri:link\" class=\"shrink-0 text-12\" />\n <PkUrl :url=\"product.url\" />\n </span>\n <div class=\"flex items-center gap-sm flex-wrap text-12\">\n <span\n v-if=\"product.price\"\n class=\"font-semibold text-word-1\">\n {{ product.price }}\n </span>\n <!-- Free text from the merchant: it was colour-coded by\n substring, which only ever matched English and\n Italian. It reads as the note it is. -->\n <span\n v-if=\"product.availability\"\n class=\"text-10 text-word-3\">\n {{ product.availability }}\n </span>\n </div>\n <p\n v-if=\"product.description\"\n class=\"text-12 text-word-3 line-clamp-2\">\n {{ product.description }}\n </p>\n </div>\n </component>\n </li>\n </ul>\n</template>\n","<script setup lang=\"ts\">\n import { computed } from 'vue'\n import PkLazyImg from '../PkLazyImg.vue'\n import { useChatImageGate } from './chatImagePolicy'\n import PkHeldImage from './PkHeldImage.vue'\n import PkUrl from '../PkUrl.vue'\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n products: Array<{\n name: string\n url?: string\n image?: string\n price?: string\n availability?: string\n description?: string\n }>\n }\n }\n return part\n })\n\n // The model writes these urls: one from a host the agent does not list\n // waits for a click (chatImagePolicy.ts).\n const imageGate = useChatImageGate()\n</script>\n\n<template>\n <ul v-if=\"toolPart?.input?.products?.length\" class=\"u-pick-list w-full\">\n <li\n v-for=\"(product, index) in toolPart.input.products\"\n :key=\"index\"\n class=\"u-pick-list__row\">\n <component\n :is=\"product.url ? 'a' : 'div'\"\n :href=\"product.url\"\n :target=\"product.url ? '_blank' : undefined\"\n :rel=\"product.url ? 'noopener noreferrer' : undefined\"\n class=\"u-pick-list__entry\">\n <!-- Merchant images rot over time: a dead one degrades to an icon\n so the row keeps its thumbnail slot -->\n <PkHeldImage\n v-if=\"product.image && !imageGate.canLoad(product.image)\"\n :host=\"imageGate.hostOf(product.image)\"\n class=\"w-48 h-48 rounded-lg shrink-0 border border-surface-3 bg-surface\"\n @release=\"imageGate.release(product.image)\" />\n <PkLazyImg\n v-else-if=\"product.image\"\n :src=\"product.image\"\n :alt=\"product.name\"\n fallback-icon=\"ri:image-off-line\"\n class=\"w-48 h-48 object-contain rounded-lg shrink-0 border border-surface-3 bg-surface\" />\n <div class=\"flex flex-col gap-4 min-w-0 flex-1\">\n <strong class=\"font-bold text-12 text-word-1 truncate\">\n {{ product.name }}\n </strong>\n <span\n v-if=\"product.url\"\n class=\"text-10 text-word-4 truncate flex items-center gap-4\">\n <VvIcon name=\"ri:link\" class=\"shrink-0 text-12\" />\n <PkUrl :url=\"product.url\" />\n </span>\n <div class=\"flex items-center gap-sm flex-wrap text-12\">\n <span\n v-if=\"product.price\"\n class=\"font-semibold text-word-1\">\n {{ product.price }}\n </span>\n <!-- Free text from the merchant: it was colour-coded by\n substring, which only ever matched English and\n Italian. It reads as the note it is. -->\n <span\n v-if=\"product.availability\"\n class=\"text-10 text-word-3\">\n {{ product.availability }}\n </span>\n </div>\n <p\n v-if=\"product.description\"\n class=\"text-12 text-word-3 line-clamp-2\">\n {{ product.description }}\n </p>\n </div>\n </component>\n </li>\n </ul>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;EAOI,IAAM+B,IAAQC,GAIRC,IAAWC,QACAH,EAAM,IAatB,GAIKI,IAAYjB,EAAiB;;;GAIzB,OAAAe,EAAA,OAAU,OAAO,UAAU,UAArChC,EAAA,GAAAC,EAyDK,MAzDLoB,GAyDK,EAxDDrB,EAAA,EAAA,GAAAC,EAuDKC,GAAA,MAAAC,EAtD0B6B,EAAA,MAAS,MAAM,WAAlC,GAAS,OADrBhC,EAAA,GAAAC,EAuDK,MAAA;IArDA,KAAKwC;IACN,OAAM;GACNzC,GAAAA,EAAAA,EAAA,GAAAI,EAkDYC,EAjDHuC,EAAQ,MAAG,MAAA,KAAA,GAAA;IACf,MAAMA,EAAQ;IACd,QAAQA,EAAQ,MAAG,WAAc,KAAA;IACjC,KAAKA,EAAQ,MAAG,wBAA2B,KAAA;IAC5C,OAAM;;IAGN,SAAAtC,QAIkD,CAHxCsC,EAAQ,SAAK,CAAKrC,EAAA2B,CAAA,CAAS,CAAC,QAAQU,EAAQ,KAAK,KAD3D5C,EAAA,GAAAI,EAIkDI,GAAA;;KAF7C,MAAMD,EAAA2B,CAAA,CAAS,CAAC,OAAOU,EAAQ,KAAK;KACrC,OAAM;KACL,YAAO,MAAErC,EAAA2B,CAAA,CAAS,CAAC,QAAQU,EAAQ,KAAK;IAE9B,GAAA,MAAA,GAAA,CAAA,QAAA,WAAA,CAAA,KAAAA,EAAQ,SADvB5C,EAAA,GAAAI,EAK8FK,GAAA;;KAHzF,KAAKmC,EAAQ;KACb,KAAKA,EAAQ;KACd,iBAAc;KACd,OAAM;IACVjC,GAAAA,MAAAA,GAAAA,CAAAA,OAAAA,KAAAA,CAAAA,KAAAA,EAAAA,IAAAA,EAAAA,GAAAA,EA8BM,OA9BNW,GA8BM;KA7BFX,EAES,UAFTY,GAESX,EADFgC,EAAQ,IAAI,GAAA,CAAA;KAGTA,EAAQ,OADlB5C,EAAA,GAAAC,EAKO,QALPuB,GAKO,CAFHX,EAAkDsB,GAAA;MAA1C,MAAK;MAAU,OAAM;KAC7BtB,CAAAA,GAAAA,EAA4BC,GAAA,EAApB,KAAK8B,EAAQ,IAAA,GAAA,MAAA,GAAA,CAAA,KAAA,CAAA,CAAA,CAAA,KAAAG,EAAA,IAAA,EAAA;KAEzBpC,EAcM,OAdNc,GAcM,CAZQmB,EAAQ,SADlB5C,EAAA,GAAAC,EAIO,QAJPyB,GAIOd,EADAgC,EAAQ,KAAK,GAAA,CAAA,KAAAG,EAAA,IAAA,EAAA,GAMVH,EAAQ,gBADlB5C,EAAA,GAAAC,EAIO,QAJP0B,GAIOf,EADAgC,EAAQ,YAAY,GAAA,CAAA,KAAAG,EAAA,IAAA,EAAA,CAAA,CAAA;KAIrBH,EAAQ,eADlB5C,EAAA,GAAAC,EAII,KAJJ2B,GAIIhB,EADGgC,EAAQ,WAAW,GAAA,CAAA,KAAAG,EAAA,IAAA,EAAA"}
@@ -1,9 +1,9 @@
1
1
  import { t as e } from "./rolldown-runtime-Dy4uBu1J.js";
2
- import { i as t } from "./Document-DCSWwcRE.js";
3
- import { t as n } from "./PkStreamingMarkdown-CJlfq7ub.js";
2
+ import { i as t } from "./Document-B9QaYHKT.js";
3
+ import { t as n } from "./PkStreamingMarkdown-XJBXdSG2.js";
4
4
  import "./src-DT8FLE4_.js";
5
5
  import { t as r } from "./markdown-CCMpGUA7.js";
6
- import { t as i } from "./PkUrl-E12f7rn_.js";
6
+ import { t as i } from "./PkUrl-CN1kkZiH.js";
7
7
  import { VvIcon as a } from "@volverjs/ui-vue/components";
8
8
  import { Fragment as o, Transition as s, computed as c, createBlock as l, createCommentVNode as u, createElementBlock as d, createElementVNode as f, createTextVNode as p, createVNode as m, defineComponent as h, normalizeClass as g, openBlock as _, reactive as v, ref as y, renderList as b, toDisplayString as x, unref as S, withCtx as C } from "vue";
9
9
  //#region ../../packages/components/src/chat/PkChunkPreview.vue?vue&type=script&setup=true&lang.ts
@@ -239,4 +239,4 @@ var w = ["title"], T = {
239
239
  //#endregion
240
240
  export { E as i, X as n, j as r, Z as t };
241
241
 
242
- //# sourceMappingURL=PkToolShowSources-B1Nhrk7O.js.map
242
+ //# sourceMappingURL=PkToolShowSources-DzUNanmK.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PkToolShowSources-B1Nhrk7O.js","names":["_hoisted_1","_hoisted_2","__unplugin_components_0","_openBlock","_createElementBlock","_Fragment","_createVNode","_createElementVNode","_toDisplayString","_unref","_createCommentVNode","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","__unplugin_components_0","_openBlock","_createElementBlock","_Fragment","_createVNode","_unref","_createElementVNode","_toDisplayString","_createCommentVNode","PkUrl","_sfc_main","$t","__unplugin_components_0","_openBlock","_createElementBlock","_createElementVNode","_createVNode","_createTextVNode","_toDisplayString","_Fragment","_renderList","PkDocumentHeader","_createCommentVNode","_createBlock","PkStreamingMarkdown","PkChunkPreview","_Transition","_withCtx","_normalizeClass","_sfc_main","__exportAll","getTypeIcon","PkStreamingMarkdown_default","stripMarkdown","PkUrl_default","_hoisted_1$2","_hoisted_2$2","PkChunkPreview_default","defineComponent","props","__props","similarityPercent","computed","max","_component_VvIcon","VvIcon","openBlock","createElementBlock","Fragment","createVNode","createElementVNode","toDisplayString","unref","createCommentVNode","_hoisted_1$1","_hoisted_2$1","_hoisted_3$1","_hoisted_4$1","PkDocumentHeader_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","_hoisted_15","_hoisted_16","_hoisted_17","PkToolShowSources_vue_vue_type_script_setup_true_lang_default","toolPart","sources","groupedSources","groups","source","existing","maxSimilarity","s","expandedDocuments","reactive","expandedChunks","contextData","loadingContext","toggleDocument","documentId","toggleChunk","chunkId","handleExpandContext","content","clearContext","showMore","ref","visibleGroups","hasMore","createTextVNode","_ctx","renderList","group","createBlock","chunk","Transition","withCtx","normalizeClass","_cache","PkToolShowSources_exports","PkToolShowSources_default"],"sources":["../../../../packages/components/src/chat/PkChunkPreview.vue","../../../../packages/components/src/chat/PkChunkPreview.vue","../../../../packages/components/src/chat/PkDocumentHeader.vue","../../../../packages/components/src/chat/PkDocumentHeader.vue","../../../../packages/components/src/chat/PkToolShowSources.vue","../../../../packages/components/src/chat/PkToolShowSources.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { stripMarkdown } from 'utils'\n\n const props = defineProps<{\n content: string\n similarity?: number\n maxSimilarity?: number\n expanded: boolean\n }>()\n\n const similarityPercent = computed(() => {\n if (props.similarity == null) {\n return null\n }\n const max =\n props.maxSimilarity && props.maxSimilarity > 0\n ? props.maxSimilarity\n : 1\n return Math.round((props.similarity / max) * 100)\n })\n</script>\n\n<template>\n <VvIcon name=\"ri:text-snippet\" class=\"shrink-0 text-12 text-word-4\" />\n <span class=\"text-10 text-word-2 truncate flex-1\" :title=\"content\">\n {{ stripMarkdown(content) }}\n </span>\n <span v-if=\"similarityPercent != null\" class=\"text-10 text-word-4 shrink-0\">\n {{ similarityPercent }}%\n </span>\n <VvIcon\n :name=\"expanded ? 'ri:arrow-up-s-line' : 'ri:arrow-down-s-line'\"\n class=\"text-14 text-word-4 shrink-0\" />\n</template>\n","<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { stripMarkdown } from 'utils'\n\n const props = defineProps<{\n content: string\n similarity?: number\n maxSimilarity?: number\n expanded: boolean\n }>()\n\n const similarityPercent = computed(() => {\n if (props.similarity == null) {\n return null\n }\n const max =\n props.maxSimilarity && props.maxSimilarity > 0\n ? props.maxSimilarity\n : 1\n return Math.round((props.similarity / max) * 100)\n })\n</script>\n\n<template>\n <VvIcon name=\"ri:text-snippet\" class=\"shrink-0 text-12 text-word-4\" />\n <span class=\"text-10 text-word-2 truncate flex-1\" :title=\"content\">\n {{ stripMarkdown(content) }}\n </span>\n <span v-if=\"similarityPercent != null\" class=\"text-10 text-word-4 shrink-0\">\n {{ similarityPercent }}%\n </span>\n <VvIcon\n :name=\"expanded ? 'ri:arrow-up-s-line' : 'ri:arrow-down-s-line'\"\n class=\"text-14 text-word-4 shrink-0\" />\n</template>\n","<script setup lang=\"ts\">\n import type { DocumentType } from 'models'\n import { getTypeIcon } from 'models'\n import PkUrl from '../PkUrl.vue'\n\n defineProps<{\n type: string\n name: string\n url?: string\n filename?: string\n }>()\n</script>\n\n<template>\n <VvIcon\n :name=\"getTypeIcon(type as DocumentType)\"\n class=\"shrink-0 text-14 text-word-3\" />\n <div class=\"flex flex-col gap-2 min-w-0 flex-1\">\n <strong class=\"font-bold text-12 text-word-1 truncate block\">\n {{ name }}\n </strong>\n <span v-if=\"filename\" class=\"text-10 text-word-4 truncate\">\n {{ filename }}\n </span>\n <span\n v-if=\"url\"\n class=\"text-10 text-word-4 truncate flex items-center gap-4\">\n <VvIcon name=\"ri:link\" class=\"shrink-0 text-10\" />\n <PkUrl :url=\"url\" />\n </span>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import type { DocumentType } from 'models'\n import { getTypeIcon } from 'models'\n import PkUrl from '../PkUrl.vue'\n\n defineProps<{\n type: string\n name: string\n url?: string\n filename?: string\n }>()\n</script>\n\n<template>\n <VvIcon\n :name=\"getTypeIcon(type as DocumentType)\"\n class=\"shrink-0 text-14 text-word-3\" />\n <div class=\"flex flex-col gap-2 min-w-0 flex-1\">\n <strong class=\"font-bold text-12 text-word-1 truncate block\">\n {{ name }}\n </strong>\n <span v-if=\"filename\" class=\"text-10 text-word-4 truncate\">\n {{ filename }}\n </span>\n <span\n v-if=\"url\"\n class=\"text-10 text-word-4 truncate flex items-center gap-4\">\n <VvIcon name=\"ri:link\" class=\"shrink-0 text-10\" />\n <PkUrl :url=\"url\" />\n </span>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed, ref, reactive } from 'vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n import PkChunkPreview from './PkChunkPreview.vue'\n import PkDocumentHeader from './PkDocumentHeader.vue'\n\n interface SourceItem {\n chunkId: string\n documentId: string\n documentName: string\n documentType: string\n language: string\n content: string\n chunkIndex?: number | null\n similarity?: number\n sourceUrl?: string\n sourceFilename?: string\n sourceDescription?: string\n sourceImageUrl?: string\n }\n\n const props = defineProps<{\n part: unknown\n onExpandContext?: (payload: {\n documentId: string\n chunkIndex: number\n }) => Promise<string>\n onDownload?: (documentId: string) => void\n }>()\n\n const toolPart = computed(() => {\n return props.part as {\n input?: {\n sources: SourceItem[]\n }\n }\n })\n\n const sources = computed(() => toolPart.value.input?.sources || [])\n\n const groupedSources = computed(() => {\n const groups = new Map<\n string,\n { document: SourceItem; chunks: SourceItem[] }\n >()\n for (const source of sources.value) {\n const existing = groups.get(source.documentId)\n if (existing) {\n existing.chunks.push(source)\n } else {\n groups.set(source.documentId, {\n document: source,\n chunks: [source],\n })\n }\n }\n return [...groups.values()]\n })\n\n const maxSimilarity = computed(() => {\n return Math.max(...sources.value.map((s) => s.similarity ?? 0), 0)\n })\n\n const expandedDocuments = reactive(new Set<string>())\n const expandedChunks = reactive(new Set<string>())\n const contextData = reactive(new Map<string, string>())\n const loadingContext = reactive(new Set<string>())\n\n const toggleDocument = (documentId: string) => {\n if (expandedDocuments.has(documentId)) {\n expandedDocuments.delete(documentId)\n } else {\n expandedDocuments.add(documentId)\n }\n }\n\n const toggleChunk = (chunkId: string) => {\n if (expandedChunks.has(chunkId)) {\n expandedChunks.delete(chunkId)\n } else {\n expandedChunks.add(chunkId)\n }\n }\n\n const handleExpandContext = async (source: SourceItem) => {\n if (source.chunkIndex == null || !props.onExpandContext) {\n return\n }\n loadingContext.add(source.chunkId)\n try {\n const content = await props.onExpandContext({\n documentId: source.documentId,\n chunkIndex: source.chunkIndex,\n })\n contextData.set(source.chunkId, content)\n } finally {\n loadingContext.delete(source.chunkId)\n }\n }\n\n const clearContext = (chunkId: string) => {\n contextData.delete(chunkId)\n }\n\n const showMore = ref(false)\n const visibleGroups = computed(() => {\n if (showMore.value) {\n return groupedSources.value\n }\n return groupedSources.value.slice(0, 3)\n })\n const hasMore = computed(() => groupedSources.value.length > 3)\n</script>\n\n<template>\n <div v-if=\"sources.length\" class=\"flex flex-col gap-xs w-full\">\n <div class=\"flex items-center gap-4 text-12 text-word-3 font-semibold\">\n <VvIcon name=\"ri:article-line\" class=\"text-14\" />\n {{ $t('label.sources') }}\n <span class=\"text-word-4 font-normal\">\n ({{ groupedSources.length }})\n </span>\n </div>\n\n <ul class=\"flex flex-col gap-xs\">\n <li\n v-for=\"group in visibleGroups\"\n :key=\"group.document.documentId\"\n class=\"border border-surface-3 rounded-xl overflow-hidden\">\n <!-- Document header -->\n <button\n class=\"flex items-center gap-8 p-8 w-full text-left hover:bg-surface-1 transition-colors cursor-pointer\"\n @click=\"toggleDocument(group.document.documentId)\">\n <PkDocumentHeader\n :type=\"group.document.documentType\"\n :name=\"group.document.documentName\"\n :url=\"group.document.sourceUrl\"\n :filename=\"group.document.sourceFilename\" />\n <div class=\"flex items-center gap-4 shrink-0\">\n <span\n v-if=\"group.chunks.length > 1\"\n class=\"text-10 text-word-4 bg-surface-2 rounded px-4 py-2\">\n {{ group.chunks.length }}\n </span>\n <span\n class=\"text-10 text-word-4 bg-surface-2 rounded px-4 py-2 uppercase\">\n {{ group.document.language }}\n </span>\n <VvIcon\n :name=\"\n expandedDocuments.has(group.document.documentId)\n ? 'ri:arrow-up-s-line'\n : 'ri:arrow-down-s-line'\n \"\n class=\"text-16 text-word-3\" />\n </div>\n </button>\n\n <!-- Expanded content -->\n <div\n v-if=\"expandedDocuments.has(group.document.documentId)\"\n class=\"border-t border-surface-3\">\n <PkStreamingMarkdown\n v-if=\"group.document.sourceDescription\"\n :markdown=\"group.document.sourceDescription\"\n class=\"px-8 py-4 text-10 text-word-3 bg-surface-1 border-b border-surface-3\" />\n\n <!-- Chunk excerpts -->\n <div\n v-for=\"chunk in group.chunks\"\n :key=\"chunk.chunkId\"\n class=\"border-b border-surface-3 last:border-b-0\">\n <button\n class=\"flex items-center gap-8 px-8 py-6 w-full text-left hover:bg-surface-1 transition-colors cursor-pointer\"\n @click=\"toggleChunk(chunk.chunkId)\">\n <PkChunkPreview\n :content=\"chunk.content\"\n :similarity=\"chunk.similarity\"\n :max-similarity=\"maxSimilarity\"\n :expanded=\"expandedChunks.has(chunk.chunkId)\" />\n </button>\n\n <!-- Expanded chunk content -->\n <div\n v-if=\"expandedChunks.has(chunk.chunkId)\"\n class=\"bg-surface-1 border-t border-surface-3\">\n <div class=\"p-8 text-10 text-word-3\">\n <transition mode=\"out-in\">\n <!-- Context expansion -->\n <PkStreamingMarkdown\n v-if=\"contextData.has(chunk.chunkId)\"\n :markdown=\"\n contextData.get(chunk.chunkId)!\n \"\n class=\"wysiwyg\" />\n\n <!-- Chunk content -->\n <PkStreamingMarkdown\n v-else\n :markdown=\"chunk.content\"\n class=\"wysiwyg\" />\n </transition>\n </div>\n\n <!-- Actions bar -->\n <div\n class=\"flex items-center gap-8 px-8 py-6 border-t border-surface-3 bg-surface\">\n <!-- Expand / collapse context -->\n <button\n v-if=\"\n onExpandContext &&\n chunk.chunkIndex != null &&\n !contextData.has(chunk.chunkId)\n \"\n class=\"text-10 text-word-3 hover:text-word flex items-center gap-4 cursor-pointer\"\n :disabled=\"\n loadingContext.has(chunk.chunkId)\n \"\n @click=\"handleExpandContext(chunk)\">\n <VvIcon\n :name=\"\n loadingContext.has(chunk.chunkId)\n ? 'loading-loop'\n : 'ri:expand-up-down-line'\n \"\n class=\"text-12\" />\n {{ $t('label.expandContext') }}\n </button>\n <button\n v-else-if=\"contextData.has(chunk.chunkId)\"\n class=\"text-10 text-word-3 hover:text-word-1 flex items-center gap-4 cursor-pointer\"\n @click=\"clearContext(chunk.chunkId)\">\n <VvIcon\n name=\"ri:collapse-vertical-line\"\n class=\"text-12\" />\n {{ $t('label.collapseContext') }}\n </button>\n\n <!-- Open source URL -->\n <a\n v-if=\"chunk.sourceUrl\"\n :href=\"chunk.sourceUrl\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"text-10 text-word-3 hover:text-word-1 flex items-center gap-4 ml-auto\">\n <VvIcon\n name=\"ri:external-link-line\"\n class=\"text-12\" />\n {{ $t('label.openSource') }}\n </a>\n\n <!-- Download file -->\n <button\n v-if=\"\n onDownload &&\n chunk.documentType === 'file'\n \"\n class=\"text-10 text-word-3 hover:text-word-1 flex items-center gap-4 cursor-pointer\"\n :class=\"{\n 'ml-auto': !chunk.sourceUrl,\n }\"\n @click=\"onDownload(chunk.documentId)\">\n <VvIcon\n name=\"ri:download-line\"\n class=\"text-12\" />\n {{ $t('label.downloadFile') }}\n </button>\n </div>\n </div>\n </div>\n </div>\n </li>\n </ul>\n\n <!-- Show more -->\n <button\n v-if=\"hasMore\"\n class=\"text-12 text-word-3 cursor-pointer hover:underline flex items-center gap-4 mx-auto\"\n @click=\"showMore = !showMore\">\n <VvIcon\n :name=\"showMore ? 'ri:arrow-up-s-line' : 'ri:arrow-down-s-line'\"\n class=\"text-16\" />\n {{\n showMore\n ? $t('action.showLess')\n : $t('action.showMore', {\n count: groupedSources.length - 3,\n })\n }}\n </button>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed, ref, reactive } from 'vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n import PkChunkPreview from './PkChunkPreview.vue'\n import PkDocumentHeader from './PkDocumentHeader.vue'\n\n interface SourceItem {\n chunkId: string\n documentId: string\n documentName: string\n documentType: string\n language: string\n content: string\n chunkIndex?: number | null\n similarity?: number\n sourceUrl?: string\n sourceFilename?: string\n sourceDescription?: string\n sourceImageUrl?: string\n }\n\n const props = defineProps<{\n part: unknown\n onExpandContext?: (payload: {\n documentId: string\n chunkIndex: number\n }) => Promise<string>\n onDownload?: (documentId: string) => void\n }>()\n\n const toolPart = computed(() => {\n return props.part as {\n input?: {\n sources: SourceItem[]\n }\n }\n })\n\n const sources = computed(() => toolPart.value.input?.sources || [])\n\n const groupedSources = computed(() => {\n const groups = new Map<\n string,\n { document: SourceItem; chunks: SourceItem[] }\n >()\n for (const source of sources.value) {\n const existing = groups.get(source.documentId)\n if (existing) {\n existing.chunks.push(source)\n } else {\n groups.set(source.documentId, {\n document: source,\n chunks: [source],\n })\n }\n }\n return [...groups.values()]\n })\n\n const maxSimilarity = computed(() => {\n return Math.max(...sources.value.map((s) => s.similarity ?? 0), 0)\n })\n\n const expandedDocuments = reactive(new Set<string>())\n const expandedChunks = reactive(new Set<string>())\n const contextData = reactive(new Map<string, string>())\n const loadingContext = reactive(new Set<string>())\n\n const toggleDocument = (documentId: string) => {\n if (expandedDocuments.has(documentId)) {\n expandedDocuments.delete(documentId)\n } else {\n expandedDocuments.add(documentId)\n }\n }\n\n const toggleChunk = (chunkId: string) => {\n if (expandedChunks.has(chunkId)) {\n expandedChunks.delete(chunkId)\n } else {\n expandedChunks.add(chunkId)\n }\n }\n\n const handleExpandContext = async (source: SourceItem) => {\n if (source.chunkIndex == null || !props.onExpandContext) {\n return\n }\n loadingContext.add(source.chunkId)\n try {\n const content = await props.onExpandContext({\n documentId: source.documentId,\n chunkIndex: source.chunkIndex,\n })\n contextData.set(source.chunkId, content)\n } finally {\n loadingContext.delete(source.chunkId)\n }\n }\n\n const clearContext = (chunkId: string) => {\n contextData.delete(chunkId)\n }\n\n const showMore = ref(false)\n const visibleGroups = computed(() => {\n if (showMore.value) {\n return groupedSources.value\n }\n return groupedSources.value.slice(0, 3)\n })\n const hasMore = computed(() => groupedSources.value.length > 3)\n</script>\n\n<template>\n <div v-if=\"sources.length\" class=\"flex flex-col gap-xs w-full\">\n <div class=\"flex items-center gap-4 text-12 text-word-3 font-semibold\">\n <VvIcon name=\"ri:article-line\" class=\"text-14\" />\n {{ $t('label.sources') }}\n <span class=\"text-word-4 font-normal\">\n ({{ groupedSources.length }})\n </span>\n </div>\n\n <ul class=\"flex flex-col gap-xs\">\n <li\n v-for=\"group in visibleGroups\"\n :key=\"group.document.documentId\"\n class=\"border border-surface-3 rounded-xl overflow-hidden\">\n <!-- Document header -->\n <button\n class=\"flex items-center gap-8 p-8 w-full text-left hover:bg-surface-1 transition-colors cursor-pointer\"\n @click=\"toggleDocument(group.document.documentId)\">\n <PkDocumentHeader\n :type=\"group.document.documentType\"\n :name=\"group.document.documentName\"\n :url=\"group.document.sourceUrl\"\n :filename=\"group.document.sourceFilename\" />\n <div class=\"flex items-center gap-4 shrink-0\">\n <span\n v-if=\"group.chunks.length > 1\"\n class=\"text-10 text-word-4 bg-surface-2 rounded px-4 py-2\">\n {{ group.chunks.length }}\n </span>\n <span\n class=\"text-10 text-word-4 bg-surface-2 rounded px-4 py-2 uppercase\">\n {{ group.document.language }}\n </span>\n <VvIcon\n :name=\"\n expandedDocuments.has(group.document.documentId)\n ? 'ri:arrow-up-s-line'\n : 'ri:arrow-down-s-line'\n \"\n class=\"text-16 text-word-3\" />\n </div>\n </button>\n\n <!-- Expanded content -->\n <div\n v-if=\"expandedDocuments.has(group.document.documentId)\"\n class=\"border-t border-surface-3\">\n <PkStreamingMarkdown\n v-if=\"group.document.sourceDescription\"\n :markdown=\"group.document.sourceDescription\"\n class=\"px-8 py-4 text-10 text-word-3 bg-surface-1 border-b border-surface-3\" />\n\n <!-- Chunk excerpts -->\n <div\n v-for=\"chunk in group.chunks\"\n :key=\"chunk.chunkId\"\n class=\"border-b border-surface-3 last:border-b-0\">\n <button\n class=\"flex items-center gap-8 px-8 py-6 w-full text-left hover:bg-surface-1 transition-colors cursor-pointer\"\n @click=\"toggleChunk(chunk.chunkId)\">\n <PkChunkPreview\n :content=\"chunk.content\"\n :similarity=\"chunk.similarity\"\n :max-similarity=\"maxSimilarity\"\n :expanded=\"expandedChunks.has(chunk.chunkId)\" />\n </button>\n\n <!-- Expanded chunk content -->\n <div\n v-if=\"expandedChunks.has(chunk.chunkId)\"\n class=\"bg-surface-1 border-t border-surface-3\">\n <div class=\"p-8 text-10 text-word-3\">\n <transition mode=\"out-in\">\n <!-- Context expansion -->\n <PkStreamingMarkdown\n v-if=\"contextData.has(chunk.chunkId)\"\n :markdown=\"\n contextData.get(chunk.chunkId)!\n \"\n class=\"wysiwyg\" />\n\n <!-- Chunk content -->\n <PkStreamingMarkdown\n v-else\n :markdown=\"chunk.content\"\n class=\"wysiwyg\" />\n </transition>\n </div>\n\n <!-- Actions bar -->\n <div\n class=\"flex items-center gap-8 px-8 py-6 border-t border-surface-3 bg-surface\">\n <!-- Expand / collapse context -->\n <button\n v-if=\"\n onExpandContext &&\n chunk.chunkIndex != null &&\n !contextData.has(chunk.chunkId)\n \"\n class=\"text-10 text-word-3 hover:text-word flex items-center gap-4 cursor-pointer\"\n :disabled=\"\n loadingContext.has(chunk.chunkId)\n \"\n @click=\"handleExpandContext(chunk)\">\n <VvIcon\n :name=\"\n loadingContext.has(chunk.chunkId)\n ? 'loading-loop'\n : 'ri:expand-up-down-line'\n \"\n class=\"text-12\" />\n {{ $t('label.expandContext') }}\n </button>\n <button\n v-else-if=\"contextData.has(chunk.chunkId)\"\n class=\"text-10 text-word-3 hover:text-word-1 flex items-center gap-4 cursor-pointer\"\n @click=\"clearContext(chunk.chunkId)\">\n <VvIcon\n name=\"ri:collapse-vertical-line\"\n class=\"text-12\" />\n {{ $t('label.collapseContext') }}\n </button>\n\n <!-- Open source URL -->\n <a\n v-if=\"chunk.sourceUrl\"\n :href=\"chunk.sourceUrl\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"text-10 text-word-3 hover:text-word-1 flex items-center gap-4 ml-auto\">\n <VvIcon\n name=\"ri:external-link-line\"\n class=\"text-12\" />\n {{ $t('label.openSource') }}\n </a>\n\n <!-- Download file -->\n <button\n v-if=\"\n onDownload &&\n chunk.documentType === 'file'\n \"\n class=\"text-10 text-word-3 hover:text-word-1 flex items-center gap-4 cursor-pointer\"\n :class=\"{\n 'ml-auto': !chunk.sourceUrl,\n }\"\n @click=\"onDownload(chunk.documentId)\">\n <VvIcon\n name=\"ri:download-line\"\n class=\"text-12\" />\n {{ $t('label.downloadFile') }}\n </button>\n </div>\n </div>\n </div>\n </div>\n </li>\n </ul>\n\n <!-- Show more -->\n <button\n v-if=\"hasMore\"\n class=\"text-12 text-word-3 cursor-pointer hover:underline flex items-center gap-4 mx-auto\"\n @click=\"showMore = !showMore\">\n <VvIcon\n :name=\"showMore ? 'ri:arrow-up-s-line' : 'ri:arrow-down-s-line'\"\n class=\"text-16\" />\n {{\n showMore\n ? $t('action.showLess')\n : $t('action.showMore', {\n count: groupedSources.length - 3,\n })\n }}\n </button>\n </div>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"PkToolShowSources-DzUNanmK.js","names":["_hoisted_1","_hoisted_2","__unplugin_components_0","_openBlock","_createElementBlock","_Fragment","_createVNode","_createElementVNode","_toDisplayString","_unref","_createCommentVNode","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","__unplugin_components_0","_openBlock","_createElementBlock","_Fragment","_createVNode","_unref","_createElementVNode","_toDisplayString","_createCommentVNode","PkUrl","_sfc_main","$t","__unplugin_components_0","_openBlock","_createElementBlock","_createElementVNode","_createVNode","_createTextVNode","_toDisplayString","_Fragment","_renderList","PkDocumentHeader","_createCommentVNode","_createBlock","PkStreamingMarkdown","PkChunkPreview","_Transition","_withCtx","_normalizeClass","_sfc_main","__exportAll","getTypeIcon","PkStreamingMarkdown_default","stripMarkdown","PkUrl_default","_hoisted_1$2","_hoisted_2$2","PkChunkPreview_default","defineComponent","props","__props","similarityPercent","computed","max","_component_VvIcon","VvIcon","openBlock","createElementBlock","Fragment","createVNode","createElementVNode","toDisplayString","unref","createCommentVNode","_hoisted_1$1","_hoisted_2$1","_hoisted_3$1","_hoisted_4$1","PkDocumentHeader_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","_hoisted_15","_hoisted_16","_hoisted_17","PkToolShowSources_vue_vue_type_script_setup_true_lang_default","toolPart","sources","groupedSources","groups","source","existing","maxSimilarity","s","expandedDocuments","reactive","expandedChunks","contextData","loadingContext","toggleDocument","documentId","toggleChunk","chunkId","handleExpandContext","content","clearContext","showMore","ref","visibleGroups","hasMore","createTextVNode","_ctx","renderList","group","createBlock","chunk","Transition","withCtx","normalizeClass","_cache","PkToolShowSources_exports","PkToolShowSources_default"],"sources":["../../../../packages/components/src/chat/PkChunkPreview.vue","../../../../packages/components/src/chat/PkChunkPreview.vue","../../../../packages/components/src/chat/PkDocumentHeader.vue","../../../../packages/components/src/chat/PkDocumentHeader.vue","../../../../packages/components/src/chat/PkToolShowSources.vue","../../../../packages/components/src/chat/PkToolShowSources.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { stripMarkdown } from 'utils'\n\n const props = defineProps<{\n content: string\n similarity?: number\n maxSimilarity?: number\n expanded: boolean\n }>()\n\n const similarityPercent = computed(() => {\n if (props.similarity == null) {\n return null\n }\n const max =\n props.maxSimilarity && props.maxSimilarity > 0\n ? props.maxSimilarity\n : 1\n return Math.round((props.similarity / max) * 100)\n })\n</script>\n\n<template>\n <VvIcon name=\"ri:text-snippet\" class=\"shrink-0 text-12 text-word-4\" />\n <span class=\"text-10 text-word-2 truncate flex-1\" :title=\"content\">\n {{ stripMarkdown(content) }}\n </span>\n <span v-if=\"similarityPercent != null\" class=\"text-10 text-word-4 shrink-0\">\n {{ similarityPercent }}%\n </span>\n <VvIcon\n :name=\"expanded ? 'ri:arrow-up-s-line' : 'ri:arrow-down-s-line'\"\n class=\"text-14 text-word-4 shrink-0\" />\n</template>\n","<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { stripMarkdown } from 'utils'\n\n const props = defineProps<{\n content: string\n similarity?: number\n maxSimilarity?: number\n expanded: boolean\n }>()\n\n const similarityPercent = computed(() => {\n if (props.similarity == null) {\n return null\n }\n const max =\n props.maxSimilarity && props.maxSimilarity > 0\n ? props.maxSimilarity\n : 1\n return Math.round((props.similarity / max) * 100)\n })\n</script>\n\n<template>\n <VvIcon name=\"ri:text-snippet\" class=\"shrink-0 text-12 text-word-4\" />\n <span class=\"text-10 text-word-2 truncate flex-1\" :title=\"content\">\n {{ stripMarkdown(content) }}\n </span>\n <span v-if=\"similarityPercent != null\" class=\"text-10 text-word-4 shrink-0\">\n {{ similarityPercent }}%\n </span>\n <VvIcon\n :name=\"expanded ? 'ri:arrow-up-s-line' : 'ri:arrow-down-s-line'\"\n class=\"text-14 text-word-4 shrink-0\" />\n</template>\n","<script setup lang=\"ts\">\n import type { DocumentType } from 'models'\n import { getTypeIcon } from 'models'\n import PkUrl from '../PkUrl.vue'\n\n defineProps<{\n type: string\n name: string\n url?: string\n filename?: string\n }>()\n</script>\n\n<template>\n <VvIcon\n :name=\"getTypeIcon(type as DocumentType)\"\n class=\"shrink-0 text-14 text-word-3\" />\n <div class=\"flex flex-col gap-2 min-w-0 flex-1\">\n <strong class=\"font-bold text-12 text-word-1 truncate block\">\n {{ name }}\n </strong>\n <span v-if=\"filename\" class=\"text-10 text-word-4 truncate\">\n {{ filename }}\n </span>\n <span\n v-if=\"url\"\n class=\"text-10 text-word-4 truncate flex items-center gap-4\">\n <VvIcon name=\"ri:link\" class=\"shrink-0 text-10\" />\n <PkUrl :url=\"url\" />\n </span>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import type { DocumentType } from 'models'\n import { getTypeIcon } from 'models'\n import PkUrl from '../PkUrl.vue'\n\n defineProps<{\n type: string\n name: string\n url?: string\n filename?: string\n }>()\n</script>\n\n<template>\n <VvIcon\n :name=\"getTypeIcon(type as DocumentType)\"\n class=\"shrink-0 text-14 text-word-3\" />\n <div class=\"flex flex-col gap-2 min-w-0 flex-1\">\n <strong class=\"font-bold text-12 text-word-1 truncate block\">\n {{ name }}\n </strong>\n <span v-if=\"filename\" class=\"text-10 text-word-4 truncate\">\n {{ filename }}\n </span>\n <span\n v-if=\"url\"\n class=\"text-10 text-word-4 truncate flex items-center gap-4\">\n <VvIcon name=\"ri:link\" class=\"shrink-0 text-10\" />\n <PkUrl :url=\"url\" />\n </span>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed, ref, reactive } from 'vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n import PkChunkPreview from './PkChunkPreview.vue'\n import PkDocumentHeader from './PkDocumentHeader.vue'\n\n interface SourceItem {\n chunkId: string\n documentId: string\n documentName: string\n documentType: string\n language: string\n content: string\n chunkIndex?: number | null\n similarity?: number\n sourceUrl?: string\n sourceFilename?: string\n sourceDescription?: string\n sourceImageUrl?: string\n }\n\n const props = defineProps<{\n part: unknown\n onExpandContext?: (payload: {\n documentId: string\n chunkIndex: number\n }) => Promise<string>\n onDownload?: (documentId: string) => void\n }>()\n\n const toolPart = computed(() => {\n return props.part as {\n input?: {\n sources: SourceItem[]\n }\n }\n })\n\n const sources = computed(() => toolPart.value.input?.sources || [])\n\n const groupedSources = computed(() => {\n const groups = new Map<\n string,\n { document: SourceItem; chunks: SourceItem[] }\n >()\n for (const source of sources.value) {\n const existing = groups.get(source.documentId)\n if (existing) {\n existing.chunks.push(source)\n } else {\n groups.set(source.documentId, {\n document: source,\n chunks: [source],\n })\n }\n }\n return [...groups.values()]\n })\n\n const maxSimilarity = computed(() => {\n return Math.max(...sources.value.map((s) => s.similarity ?? 0), 0)\n })\n\n const expandedDocuments = reactive(new Set<string>())\n const expandedChunks = reactive(new Set<string>())\n const contextData = reactive(new Map<string, string>())\n const loadingContext = reactive(new Set<string>())\n\n const toggleDocument = (documentId: string) => {\n if (expandedDocuments.has(documentId)) {\n expandedDocuments.delete(documentId)\n } else {\n expandedDocuments.add(documentId)\n }\n }\n\n const toggleChunk = (chunkId: string) => {\n if (expandedChunks.has(chunkId)) {\n expandedChunks.delete(chunkId)\n } else {\n expandedChunks.add(chunkId)\n }\n }\n\n const handleExpandContext = async (source: SourceItem) => {\n if (source.chunkIndex == null || !props.onExpandContext) {\n return\n }\n loadingContext.add(source.chunkId)\n try {\n const content = await props.onExpandContext({\n documentId: source.documentId,\n chunkIndex: source.chunkIndex,\n })\n contextData.set(source.chunkId, content)\n } finally {\n loadingContext.delete(source.chunkId)\n }\n }\n\n const clearContext = (chunkId: string) => {\n contextData.delete(chunkId)\n }\n\n const showMore = ref(false)\n const visibleGroups = computed(() => {\n if (showMore.value) {\n return groupedSources.value\n }\n return groupedSources.value.slice(0, 3)\n })\n const hasMore = computed(() => groupedSources.value.length > 3)\n</script>\n\n<template>\n <div v-if=\"sources.length\" class=\"flex flex-col gap-xs w-full\">\n <div class=\"flex items-center gap-4 text-12 text-word-3 font-semibold\">\n <VvIcon name=\"ri:article-line\" class=\"text-14\" />\n {{ $t('label.sources') }}\n <span class=\"text-word-4 font-normal\">\n ({{ groupedSources.length }})\n </span>\n </div>\n\n <ul class=\"flex flex-col gap-xs\">\n <li\n v-for=\"group in visibleGroups\"\n :key=\"group.document.documentId\"\n class=\"border border-surface-3 rounded-xl overflow-hidden\">\n <!-- Document header -->\n <button\n class=\"flex items-center gap-8 p-8 w-full text-left hover:bg-surface-1 transition-colors cursor-pointer\"\n @click=\"toggleDocument(group.document.documentId)\">\n <PkDocumentHeader\n :type=\"group.document.documentType\"\n :name=\"group.document.documentName\"\n :url=\"group.document.sourceUrl\"\n :filename=\"group.document.sourceFilename\" />\n <div class=\"flex items-center gap-4 shrink-0\">\n <span\n v-if=\"group.chunks.length > 1\"\n class=\"text-10 text-word-4 bg-surface-2 rounded px-4 py-2\">\n {{ group.chunks.length }}\n </span>\n <span\n class=\"text-10 text-word-4 bg-surface-2 rounded px-4 py-2 uppercase\">\n {{ group.document.language }}\n </span>\n <VvIcon\n :name=\"\n expandedDocuments.has(group.document.documentId)\n ? 'ri:arrow-up-s-line'\n : 'ri:arrow-down-s-line'\n \"\n class=\"text-16 text-word-3\" />\n </div>\n </button>\n\n <!-- Expanded content -->\n <div\n v-if=\"expandedDocuments.has(group.document.documentId)\"\n class=\"border-t border-surface-3\">\n <PkStreamingMarkdown\n v-if=\"group.document.sourceDescription\"\n :markdown=\"group.document.sourceDescription\"\n class=\"px-8 py-4 text-10 text-word-3 bg-surface-1 border-b border-surface-3\" />\n\n <!-- Chunk excerpts -->\n <div\n v-for=\"chunk in group.chunks\"\n :key=\"chunk.chunkId\"\n class=\"border-b border-surface-3 last:border-b-0\">\n <button\n class=\"flex items-center gap-8 px-8 py-6 w-full text-left hover:bg-surface-1 transition-colors cursor-pointer\"\n @click=\"toggleChunk(chunk.chunkId)\">\n <PkChunkPreview\n :content=\"chunk.content\"\n :similarity=\"chunk.similarity\"\n :max-similarity=\"maxSimilarity\"\n :expanded=\"expandedChunks.has(chunk.chunkId)\" />\n </button>\n\n <!-- Expanded chunk content -->\n <div\n v-if=\"expandedChunks.has(chunk.chunkId)\"\n class=\"bg-surface-1 border-t border-surface-3\">\n <div class=\"p-8 text-10 text-word-3\">\n <transition mode=\"out-in\">\n <!-- Context expansion -->\n <PkStreamingMarkdown\n v-if=\"contextData.has(chunk.chunkId)\"\n :markdown=\"\n contextData.get(chunk.chunkId)!\n \"\n class=\"wysiwyg\" />\n\n <!-- Chunk content -->\n <PkStreamingMarkdown\n v-else\n :markdown=\"chunk.content\"\n class=\"wysiwyg\" />\n </transition>\n </div>\n\n <!-- Actions bar -->\n <div\n class=\"flex items-center gap-8 px-8 py-6 border-t border-surface-3 bg-surface\">\n <!-- Expand / collapse context -->\n <button\n v-if=\"\n onExpandContext &&\n chunk.chunkIndex != null &&\n !contextData.has(chunk.chunkId)\n \"\n class=\"text-10 text-word-3 hover:text-word flex items-center gap-4 cursor-pointer\"\n :disabled=\"\n loadingContext.has(chunk.chunkId)\n \"\n @click=\"handleExpandContext(chunk)\">\n <VvIcon\n :name=\"\n loadingContext.has(chunk.chunkId)\n ? 'loading-loop'\n : 'ri:expand-up-down-line'\n \"\n class=\"text-12\" />\n {{ $t('label.expandContext') }}\n </button>\n <button\n v-else-if=\"contextData.has(chunk.chunkId)\"\n class=\"text-10 text-word-3 hover:text-word-1 flex items-center gap-4 cursor-pointer\"\n @click=\"clearContext(chunk.chunkId)\">\n <VvIcon\n name=\"ri:collapse-vertical-line\"\n class=\"text-12\" />\n {{ $t('label.collapseContext') }}\n </button>\n\n <!-- Open source URL -->\n <a\n v-if=\"chunk.sourceUrl\"\n :href=\"chunk.sourceUrl\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"text-10 text-word-3 hover:text-word-1 flex items-center gap-4 ml-auto\">\n <VvIcon\n name=\"ri:external-link-line\"\n class=\"text-12\" />\n {{ $t('label.openSource') }}\n </a>\n\n <!-- Download file -->\n <button\n v-if=\"\n onDownload &&\n chunk.documentType === 'file'\n \"\n class=\"text-10 text-word-3 hover:text-word-1 flex items-center gap-4 cursor-pointer\"\n :class=\"{\n 'ml-auto': !chunk.sourceUrl,\n }\"\n @click=\"onDownload(chunk.documentId)\">\n <VvIcon\n name=\"ri:download-line\"\n class=\"text-12\" />\n {{ $t('label.downloadFile') }}\n </button>\n </div>\n </div>\n </div>\n </div>\n </li>\n </ul>\n\n <!-- Show more -->\n <button\n v-if=\"hasMore\"\n class=\"text-12 text-word-3 cursor-pointer hover:underline flex items-center gap-4 mx-auto\"\n @click=\"showMore = !showMore\">\n <VvIcon\n :name=\"showMore ? 'ri:arrow-up-s-line' : 'ri:arrow-down-s-line'\"\n class=\"text-16\" />\n {{\n showMore\n ? $t('action.showLess')\n : $t('action.showMore', {\n count: groupedSources.length - 3,\n })\n }}\n </button>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed, ref, reactive } from 'vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n import PkChunkPreview from './PkChunkPreview.vue'\n import PkDocumentHeader from './PkDocumentHeader.vue'\n\n interface SourceItem {\n chunkId: string\n documentId: string\n documentName: string\n documentType: string\n language: string\n content: string\n chunkIndex?: number | null\n similarity?: number\n sourceUrl?: string\n sourceFilename?: string\n sourceDescription?: string\n sourceImageUrl?: string\n }\n\n const props = defineProps<{\n part: unknown\n onExpandContext?: (payload: {\n documentId: string\n chunkIndex: number\n }) => Promise<string>\n onDownload?: (documentId: string) => void\n }>()\n\n const toolPart = computed(() => {\n return props.part as {\n input?: {\n sources: SourceItem[]\n }\n }\n })\n\n const sources = computed(() => toolPart.value.input?.sources || [])\n\n const groupedSources = computed(() => {\n const groups = new Map<\n string,\n { document: SourceItem; chunks: SourceItem[] }\n >()\n for (const source of sources.value) {\n const existing = groups.get(source.documentId)\n if (existing) {\n existing.chunks.push(source)\n } else {\n groups.set(source.documentId, {\n document: source,\n chunks: [source],\n })\n }\n }\n return [...groups.values()]\n })\n\n const maxSimilarity = computed(() => {\n return Math.max(...sources.value.map((s) => s.similarity ?? 0), 0)\n })\n\n const expandedDocuments = reactive(new Set<string>())\n const expandedChunks = reactive(new Set<string>())\n const contextData = reactive(new Map<string, string>())\n const loadingContext = reactive(new Set<string>())\n\n const toggleDocument = (documentId: string) => {\n if (expandedDocuments.has(documentId)) {\n expandedDocuments.delete(documentId)\n } else {\n expandedDocuments.add(documentId)\n }\n }\n\n const toggleChunk = (chunkId: string) => {\n if (expandedChunks.has(chunkId)) {\n expandedChunks.delete(chunkId)\n } else {\n expandedChunks.add(chunkId)\n }\n }\n\n const handleExpandContext = async (source: SourceItem) => {\n if (source.chunkIndex == null || !props.onExpandContext) {\n return\n }\n loadingContext.add(source.chunkId)\n try {\n const content = await props.onExpandContext({\n documentId: source.documentId,\n chunkIndex: source.chunkIndex,\n })\n contextData.set(source.chunkId, content)\n } finally {\n loadingContext.delete(source.chunkId)\n }\n }\n\n const clearContext = (chunkId: string) => {\n contextData.delete(chunkId)\n }\n\n const showMore = ref(false)\n const visibleGroups = computed(() => {\n if (showMore.value) {\n return groupedSources.value\n }\n return groupedSources.value.slice(0, 3)\n })\n const hasMore = computed(() => groupedSources.value.length > 3)\n</script>\n\n<template>\n <div v-if=\"sources.length\" class=\"flex flex-col gap-xs w-full\">\n <div class=\"flex items-center gap-4 text-12 text-word-3 font-semibold\">\n <VvIcon name=\"ri:article-line\" class=\"text-14\" />\n {{ $t('label.sources') }}\n <span class=\"text-word-4 font-normal\">\n ({{ groupedSources.length }})\n </span>\n </div>\n\n <ul class=\"flex flex-col gap-xs\">\n <li\n v-for=\"group in visibleGroups\"\n :key=\"group.document.documentId\"\n class=\"border border-surface-3 rounded-xl overflow-hidden\">\n <!-- Document header -->\n <button\n class=\"flex items-center gap-8 p-8 w-full text-left hover:bg-surface-1 transition-colors cursor-pointer\"\n @click=\"toggleDocument(group.document.documentId)\">\n <PkDocumentHeader\n :type=\"group.document.documentType\"\n :name=\"group.document.documentName\"\n :url=\"group.document.sourceUrl\"\n :filename=\"group.document.sourceFilename\" />\n <div class=\"flex items-center gap-4 shrink-0\">\n <span\n v-if=\"group.chunks.length > 1\"\n class=\"text-10 text-word-4 bg-surface-2 rounded px-4 py-2\">\n {{ group.chunks.length }}\n </span>\n <span\n class=\"text-10 text-word-4 bg-surface-2 rounded px-4 py-2 uppercase\">\n {{ group.document.language }}\n </span>\n <VvIcon\n :name=\"\n expandedDocuments.has(group.document.documentId)\n ? 'ri:arrow-up-s-line'\n : 'ri:arrow-down-s-line'\n \"\n class=\"text-16 text-word-3\" />\n </div>\n </button>\n\n <!-- Expanded content -->\n <div\n v-if=\"expandedDocuments.has(group.document.documentId)\"\n class=\"border-t border-surface-3\">\n <PkStreamingMarkdown\n v-if=\"group.document.sourceDescription\"\n :markdown=\"group.document.sourceDescription\"\n class=\"px-8 py-4 text-10 text-word-3 bg-surface-1 border-b border-surface-3\" />\n\n <!-- Chunk excerpts -->\n <div\n v-for=\"chunk in group.chunks\"\n :key=\"chunk.chunkId\"\n class=\"border-b border-surface-3 last:border-b-0\">\n <button\n class=\"flex items-center gap-8 px-8 py-6 w-full text-left hover:bg-surface-1 transition-colors cursor-pointer\"\n @click=\"toggleChunk(chunk.chunkId)\">\n <PkChunkPreview\n :content=\"chunk.content\"\n :similarity=\"chunk.similarity\"\n :max-similarity=\"maxSimilarity\"\n :expanded=\"expandedChunks.has(chunk.chunkId)\" />\n </button>\n\n <!-- Expanded chunk content -->\n <div\n v-if=\"expandedChunks.has(chunk.chunkId)\"\n class=\"bg-surface-1 border-t border-surface-3\">\n <div class=\"p-8 text-10 text-word-3\">\n <transition mode=\"out-in\">\n <!-- Context expansion -->\n <PkStreamingMarkdown\n v-if=\"contextData.has(chunk.chunkId)\"\n :markdown=\"\n contextData.get(chunk.chunkId)!\n \"\n class=\"wysiwyg\" />\n\n <!-- Chunk content -->\n <PkStreamingMarkdown\n v-else\n :markdown=\"chunk.content\"\n class=\"wysiwyg\" />\n </transition>\n </div>\n\n <!-- Actions bar -->\n <div\n class=\"flex items-center gap-8 px-8 py-6 border-t border-surface-3 bg-surface\">\n <!-- Expand / collapse context -->\n <button\n v-if=\"\n onExpandContext &&\n chunk.chunkIndex != null &&\n !contextData.has(chunk.chunkId)\n \"\n class=\"text-10 text-word-3 hover:text-word flex items-center gap-4 cursor-pointer\"\n :disabled=\"\n loadingContext.has(chunk.chunkId)\n \"\n @click=\"handleExpandContext(chunk)\">\n <VvIcon\n :name=\"\n loadingContext.has(chunk.chunkId)\n ? 'loading-loop'\n : 'ri:expand-up-down-line'\n \"\n class=\"text-12\" />\n {{ $t('label.expandContext') }}\n </button>\n <button\n v-else-if=\"contextData.has(chunk.chunkId)\"\n class=\"text-10 text-word-3 hover:text-word-1 flex items-center gap-4 cursor-pointer\"\n @click=\"clearContext(chunk.chunkId)\">\n <VvIcon\n name=\"ri:collapse-vertical-line\"\n class=\"text-12\" />\n {{ $t('label.collapseContext') }}\n </button>\n\n <!-- Open source URL -->\n <a\n v-if=\"chunk.sourceUrl\"\n :href=\"chunk.sourceUrl\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"text-10 text-word-3 hover:text-word-1 flex items-center gap-4 ml-auto\">\n <VvIcon\n name=\"ri:external-link-line\"\n class=\"text-12\" />\n {{ $t('label.openSource') }}\n </a>\n\n <!-- Download file -->\n <button\n v-if=\"\n onDownload &&\n chunk.documentType === 'file'\n \"\n class=\"text-10 text-word-3 hover:text-word-1 flex items-center gap-4 cursor-pointer\"\n :class=\"{\n 'ml-auto': !chunk.sourceUrl,\n }\"\n @click=\"onDownload(chunk.documentId)\">\n <VvIcon\n name=\"ri:download-line\"\n class=\"text-12\" />\n {{ $t('label.downloadFile') }}\n </button>\n </div>\n </div>\n </div>\n </div>\n </li>\n </ul>\n\n <!-- Show more -->\n <button\n v-if=\"hasMore\"\n class=\"text-12 text-word-3 cursor-pointer hover:underline flex items-center gap-4 mx-auto\"\n @click=\"showMore = !showMore\">\n <VvIcon\n :name=\"showMore ? 'ri:arrow-up-s-line' : 'ri:arrow-down-s-line'\"\n class=\"text-16\" />\n {{\n showMore\n ? $t('action.showLess')\n : $t('action.showMore', {\n count: groupedSources.length - 3,\n })\n }}\n </button>\n </div>\n</template>\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { t as e } from "./rolldown-runtime-Dy4uBu1J.js";
2
- import { O as t } from "./Agent-KbZm8GvA.js";
2
+ import { O as t } from "./Agent-C4p46YGt.js";
3
3
  import { VvIcon as n } from "@volverjs/ui-vue/components";
4
4
  import { Fragment as r, computed as i, createCommentVNode as a, createElementBlock as o, createElementVNode as s, createVNode as c, defineComponent as l, normalizeClass as u, openBlock as d, ref as f, renderList as p, toDisplayString as m, withModifiers as h } from "vue";
5
5
  //#region ../../packages/components/src/chat/PkToolShowSuggestedReply.vue?vue&type=script&setup=true&lang.ts
@@ -45,4 +45,4 @@ var g = {
45
45
  //#endregion
46
46
  export { y as n, b as t };
47
47
 
48
- //# sourceMappingURL=PkToolShowSuggestedReply-Bmzygdww.js.map
48
+ //# sourceMappingURL=PkToolShowSuggestedReply-DhNtI5gJ.js.map