@flamingo-stack/openframe-frontend-core 0.0.583 → 0.0.584-1973.5420.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chat-protocol/events.d.ts +8 -2
- package/dist/chat-protocol/events.d.ts.map +1 -1
- package/dist/chat-protocol/index.cjs +177 -0
- package/dist/chat-protocol/index.cjs.map +1 -1
- package/dist/chat-protocol/index.js +177 -0
- package/dist/chat-protocol/index.js.map +1 -1
- package/dist/chat-protocol/nats-decoder.d.ts.map +1 -1
- package/dist/chat-protocol/source-metadata.d.ts +3 -0
- package/dist/chat-protocol/source-metadata.d.ts.map +1 -0
- package/dist/{chunk-EATPU5EF.cjs → chunk-3MAG3EG4.cjs} +9 -9
- package/dist/{chunk-EATPU5EF.cjs.map → chunk-3MAG3EG4.cjs.map} +1 -1
- package/dist/{chunk-IKUSKKFZ.cjs → chunk-4TZOFXPH.cjs} +712 -432
- package/dist/chunk-4TZOFXPH.cjs.map +1 -0
- package/dist/{chunk-WMRXB6RS.js → chunk-54WRMPCY.js} +3 -3
- package/dist/{chunk-WTC6QQNX.cjs → chunk-7IVT56YY.cjs} +3 -3
- package/dist/{chunk-WTC6QQNX.cjs.map → chunk-7IVT56YY.cjs.map} +1 -1
- package/dist/{chunk-PFKWJ6PJ.js → chunk-AQW2PDRS.js} +2 -2
- package/dist/{chunk-DROXHJVZ.js → chunk-AVVKXNGI.js} +2 -2
- package/dist/{chunk-YNLIXABT.cjs → chunk-CE6CA6EM.cjs} +43 -43
- package/dist/{chunk-YNLIXABT.cjs.map → chunk-CE6CA6EM.cjs.map} +1 -1
- package/dist/{chunk-TRD2YICZ.cjs → chunk-CGLQLBMQ.cjs} +21 -21
- package/dist/{chunk-TRD2YICZ.cjs.map → chunk-CGLQLBMQ.cjs.map} +1 -1
- package/dist/{chunk-XWBND4G5.js → chunk-CO4WRST6.js} +301 -21
- package/dist/chunk-CO4WRST6.js.map +1 -0
- package/dist/{chunk-IJVWKLJK.cjs → chunk-DHLD3JXN.cjs} +69 -69
- package/dist/{chunk-IJVWKLJK.cjs.map → chunk-DHLD3JXN.cjs.map} +1 -1
- package/dist/{chunk-M6ZUEBDK.cjs → chunk-F2EN6MXN.cjs} +159 -159
- package/dist/{chunk-M6ZUEBDK.cjs.map → chunk-F2EN6MXN.cjs.map} +1 -1
- package/dist/{chunk-J3EEL6YC.js → chunk-FH2FH337.js} +5 -5
- package/dist/{chunk-L26MD32B.js → chunk-GDHI3JN5.js} +3 -3
- package/dist/{chunk-VWHEXQ64.js → chunk-GFIH73Q3.js} +3 -3
- package/dist/{chunk-R5A3MGMY.js → chunk-H6GYY5CB.js} +3 -3
- package/dist/{chunk-FCLM2RXI.js → chunk-HGJAUYHW.js} +2 -2
- package/dist/{chunk-RBDVHLT5.cjs → chunk-HKKQCVVY.cjs} +22 -22
- package/dist/{chunk-RBDVHLT5.cjs.map → chunk-HKKQCVVY.cjs.map} +1 -1
- package/dist/{chunk-KDWNMFX4.cjs → chunk-JEMGFSC2.cjs} +24 -24
- package/dist/{chunk-KDWNMFX4.cjs.map → chunk-JEMGFSC2.cjs.map} +1 -1
- package/dist/{chunk-BTBW4L2W.cjs → chunk-JX6RSSZP.cjs} +33 -33
- package/dist/{chunk-BTBW4L2W.cjs.map → chunk-JX6RSSZP.cjs.map} +1 -1
- package/dist/{chunk-WHNC7C76.js → chunk-KN2ZCZQ7.js} +5 -5
- package/dist/{chunk-WBTKXNKZ.cjs → chunk-MYVHYVQM.cjs} +10 -10
- package/dist/{chunk-WBTKXNKZ.cjs.map → chunk-MYVHYVQM.cjs.map} +1 -1
- package/dist/{chunk-3TNM6SDP.cjs → chunk-PI3BNDCW.cjs} +15 -15
- package/dist/{chunk-3TNM6SDP.cjs.map → chunk-PI3BNDCW.cjs.map} +1 -1
- package/dist/{chunk-XZ3MKTJZ.js → chunk-PWI66GZF.js} +2 -2
- package/dist/{chunk-IFPGXSMZ.cjs → chunk-RTI3TYMX.cjs} +3 -3
- package/dist/{chunk-IFPGXSMZ.cjs.map → chunk-RTI3TYMX.cjs.map} +1 -1
- package/dist/{chunk-6BI3AYBY.cjs → chunk-SS2TCIKA.cjs} +4 -4
- package/dist/{chunk-6BI3AYBY.cjs.map → chunk-SS2TCIKA.cjs.map} +1 -1
- package/dist/{chunk-HIHPWVKP.js → chunk-T35JA5XV.js} +5 -5
- package/dist/{chunk-EZ5VU5WS.js → chunk-TLZ7HTXP.js} +2 -2
- package/dist/{chunk-OCXFFGFA.cjs → chunk-UZUG7QZ3.cjs} +10 -10
- package/dist/{chunk-OCXFFGFA.cjs.map → chunk-UZUG7QZ3.cjs.map} +1 -1
- package/dist/{chunk-3RR67XC2.cjs → chunk-W46U5J3H.cjs} +5 -5
- package/dist/{chunk-3RR67XC2.cjs.map → chunk-W46U5J3H.cjs.map} +1 -1
- package/dist/{chunk-IOP7BCRQ.js → chunk-WFF5JMQ2.js} +6 -6
- package/dist/{chunk-AJLF6MBD.js → chunk-X4HLHN36.js} +3 -3
- package/dist/{chunk-PMA7DVQR.js → chunk-ZWB64HOD.js} +4 -4
- package/dist/components/case-studies/index.cjs +9 -9
- package/dist/components/case-studies/index.js +3 -3
- package/dist/components/chat/chat-message-enhanced.d.ts.map +1 -1
- package/dist/components/chat/chat-message-list.d.ts.map +1 -1
- package/dist/components/chat/entity-cards/dispatch.d.ts.map +1 -1
- package/dist/components/chat/hooks/use-nats-chat-adapter.d.ts +4 -1
- package/dist/components/chat/hooks/use-nats-chat-adapter.d.ts.map +1 -1
- package/dist/components/chat/hooks/use-sse-chat-adapter.d.ts +2 -28
- package/dist/components/chat/hooks/use-sse-chat-adapter.d.ts.map +1 -1
- package/dist/components/chat/index.cjs +2 -2
- package/dist/components/chat/index.js +1 -1
- package/dist/components/chat/stream/chat-stream-reducer.d.ts.map +1 -1
- package/dist/components/chat/tool-execution-display.d.ts.map +1 -1
- package/dist/components/chat/types/component.types.d.ts +2 -0
- package/dist/components/chat/types/component.types.d.ts.map +1 -1
- package/dist/components/chat/types/message.types.d.ts +35 -1
- package/dist/components/chat/types/message.types.d.ts.map +1 -1
- package/dist/components/chat/types/unified-chat-state.types.d.ts +3 -3
- package/dist/components/chat/types/unified-chat-state.types.d.ts.map +1 -1
- package/dist/components/chat/utils/chat-source-metadata.d.ts +5 -0
- package/dist/components/chat/utils/chat-source-metadata.d.ts.map +1 -0
- package/dist/components/chat/utils/process-historical-messages.d.ts.map +1 -1
- package/dist/components/contact/index.cjs +4 -4
- package/dist/components/contact/index.js +3 -3
- package/dist/components/docs/index.cjs +7 -7
- package/dist/components/docs/index.js +6 -6
- package/dist/components/embeds/index.cjs +4 -4
- package/dist/components/embeds/index.js +3 -3
- package/dist/components/faq/index.cjs +4 -4
- package/dist/components/faq/index.js +3 -3
- package/dist/components/features/index.cjs +3 -3
- package/dist/components/features/index.js +2 -2
- package/dist/components/help-center-pages/index.cjs +23 -23
- package/dist/components/help-center-pages/index.js +14 -14
- package/dist/components/index.cjs +36 -36
- package/dist/components/index.js +13 -13
- package/dist/components/meeting-scheduler/index.cjs +21 -21
- package/dist/components/meeting-scheduler/index.js +2 -2
- package/dist/components/navigation/index.cjs +6 -6
- package/dist/components/navigation/index.js +5 -5
- package/dist/components/onboarding-guides/index.cjs +6 -6
- package/dist/components/onboarding-guides/index.js +5 -5
- package/dist/components/tickets/index.cjs +7 -7
- package/dist/components/tickets/index.js +6 -6
- package/dist/components/ui/index.cjs +3 -3
- package/dist/components/ui/index.js +2 -2
- package/dist/index.cjs +7 -7
- package/dist/index.js +6 -6
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.js.map +1 -1
- package/package.json +1 -1
- package/src/chat-protocol/__tests__/nats-decoder-golden.test.ts +130 -0
- package/src/chat-protocol/events.ts +9 -1
- package/src/chat-protocol/nats-decoder.ts +7 -0
- package/src/chat-protocol/source-metadata.ts +187 -0
- package/src/components/chat/__tests__/chat-message-streaming-memo.test.tsx +86 -0
- package/src/components/chat/__tests__/embeddable-chat-sources.test.tsx +171 -0
- package/src/components/chat/__tests__/tool-execution-display.test.tsx +93 -0
- package/src/components/chat/chat-message-enhanced.tsx +28 -13
- package/src/components/chat/chat-message-list.tsx +1 -0
- package/src/components/chat/embeddable-chat.tsx +10 -1
- package/src/components/chat/entity-cards/__tests__/dispatch-video-refs.test.tsx +74 -0
- package/src/components/chat/entity-cards/dispatch.tsx +48 -11
- package/src/components/chat/hooks/use-nats-chat-adapter.ts +7 -0
- package/src/components/chat/hooks/use-sse-chat-adapter.ts +2 -29
- package/src/components/chat/stream/__tests__/chat-stream-reducer.test.ts +56 -0
- package/src/components/chat/stream/chat-stream-reducer.ts +31 -0
- package/src/components/chat/tool-execution-display.tsx +5 -2
- package/src/components/chat/types/component.types.ts +2 -0
- package/src/components/chat/types/message.types.ts +39 -0
- package/src/components/chat/types/unified-chat-state.types.ts +4 -3
- package/src/components/chat/utils/__tests__/process-historical-messages-golden.test.ts +57 -0
- package/src/components/chat/utils/chat-source-metadata.ts +19 -0
- package/src/components/chat/utils/process-historical-messages.ts +19 -1
- package/dist/chunk-IKUSKKFZ.cjs.map +0 -1
- package/dist/chunk-XWBND4G5.js.map +0 -1
- /package/dist/{chunk-WMRXB6RS.js.map → chunk-54WRMPCY.js.map} +0 -0
- /package/dist/{chunk-PFKWJ6PJ.js.map → chunk-AQW2PDRS.js.map} +0 -0
- /package/dist/{chunk-DROXHJVZ.js.map → chunk-AVVKXNGI.js.map} +0 -0
- /package/dist/{chunk-J3EEL6YC.js.map → chunk-FH2FH337.js.map} +0 -0
- /package/dist/{chunk-L26MD32B.js.map → chunk-GDHI3JN5.js.map} +0 -0
- /package/dist/{chunk-VWHEXQ64.js.map → chunk-GFIH73Q3.js.map} +0 -0
- /package/dist/{chunk-R5A3MGMY.js.map → chunk-H6GYY5CB.js.map} +0 -0
- /package/dist/{chunk-FCLM2RXI.js.map → chunk-HGJAUYHW.js.map} +0 -0
- /package/dist/{chunk-WHNC7C76.js.map → chunk-KN2ZCZQ7.js.map} +0 -0
- /package/dist/{chunk-XZ3MKTJZ.js.map → chunk-PWI66GZF.js.map} +0 -0
- /package/dist/{chunk-HIHPWVKP.js.map → chunk-T35JA5XV.js.map} +0 -0
- /package/dist/{chunk-EZ5VU5WS.js.map → chunk-TLZ7HTXP.js.map} +0 -0
- /package/dist/{chunk-IOP7BCRQ.js.map → chunk-WFF5JMQ2.js.map} +0 -0
- /package/dist/{chunk-AJLF6MBD.js.map → chunk-X4HLHN36.js.map} +0 -0
- /package/dist/{chunk-PMA7DVQR.js.map → chunk-ZWB64HOD.js.map} +0 -0
|
@@ -1156,6 +1156,8 @@ import { forwardRef as forwardRef6 } from "react";
|
|
|
1156
1156
|
var MESSAGE_TYPE = {
|
|
1157
1157
|
TEXT: "TEXT",
|
|
1158
1158
|
THINKING: "THINKING",
|
|
1159
|
+
GUIDE: "GUIDE",
|
|
1160
|
+
SOURCES: "SOURCES",
|
|
1159
1161
|
ASK: "ASK",
|
|
1160
1162
|
EXECUTING_TOOL: "EXECUTING_TOOL",
|
|
1161
1163
|
EXECUTED_TOOL: "EXECUTED_TOOL",
|
|
@@ -6854,6 +6856,8 @@ var ToolExecutionDisplay = forwardRef15(
|
|
|
6854
6856
|
}, [message.parameters, variant]);
|
|
6855
6857
|
const hasResult = isExecuted && typeof message.result === "string" && message.result.length > 0;
|
|
6856
6858
|
const hasBody = argEntries.length > 0 || hasResult || isExecuting;
|
|
6859
|
+
const isConciseRemoteRead = !message.integratedToolType && !!message.toolTitle?.trim() && argEntries.length === 0 && !hasResult;
|
|
6860
|
+
const isStaticRow = isClientView || isConciseRemoteRead;
|
|
6857
6861
|
const renderStatusIcon = () => {
|
|
6858
6862
|
if (isExecuting) return /* @__PURE__ */ jsx34(DotsLoaderIcon, { size: 16, className: "text-ods-text-secondary" });
|
|
6859
6863
|
if (isExecuted && message.success === true) return /* @__PURE__ */ jsx34(CheckCircleIcon, { className: "h-4 w-4 text-ods-success" });
|
|
@@ -6873,7 +6877,7 @@ var ToolExecutionDisplay = forwardRef15(
|
|
|
6873
6877
|
}
|
|
6874
6878
|
),
|
|
6875
6879
|
/* @__PURE__ */ jsx34("div", { className: "flex h-5 w-5 shrink-0 items-center justify-center", children: renderStatusIcon() }),
|
|
6876
|
-
!
|
|
6880
|
+
!isStaticRow && /* @__PURE__ */ jsx34("div", { className: "flex h-5 w-5 shrink-0 items-center justify-center", children: /* @__PURE__ */ jsx34(ExpandChevron, { expanded }) })
|
|
6877
6881
|
] });
|
|
6878
6882
|
return /* @__PURE__ */ jsx34(
|
|
6879
6883
|
"div",
|
|
@@ -6886,7 +6890,7 @@ var ToolExecutionDisplay = forwardRef15(
|
|
|
6886
6890
|
className
|
|
6887
6891
|
),
|
|
6888
6892
|
...props,
|
|
6889
|
-
children:
|
|
6893
|
+
children: isStaticRow ? (
|
|
6890
6894
|
// Client (Fae end-user): static, non-expandable row — no chevron, no
|
|
6891
6895
|
// body. Just the explanation + status; command/args/result are hidden.
|
|
6892
6896
|
/* @__PURE__ */ jsx34("div", { className: "flex w-full items-start gap-[var(--spacing-system-xs)] p-[var(--spacing-system-s)] text-left", children: headerContent })
|
|
@@ -6980,6 +6984,7 @@ var ChatMessageEnhanced = forwardRef16(
|
|
|
6980
6984
|
renderContextItem,
|
|
6981
6985
|
renderMention,
|
|
6982
6986
|
renderEntityCard,
|
|
6987
|
+
refs,
|
|
6983
6988
|
onAskSelect,
|
|
6984
6989
|
NavLinkAnchor,
|
|
6985
6990
|
...props
|
|
@@ -6988,6 +6993,10 @@ var ChatMessageEnhanced = forwardRef16(
|
|
|
6988
6993
|
const isError = role === "error";
|
|
6989
6994
|
const authorType = authorTypeProp ?? (isUser ? "user" : assistantType === "mingo" ? "mingo" : "fae");
|
|
6990
6995
|
const hasMarkerSupport = !!renderEntityCard;
|
|
6996
|
+
const refsByKey = useMemo8(
|
|
6997
|
+
() => new Map((refs ?? []).map((reference) => [`${reference.type}:${reference.id}`, reference])),
|
|
6998
|
+
[refs]
|
|
6999
|
+
);
|
|
6991
7000
|
const segments = useMemo8(() => normalizeContent(content), [content]);
|
|
6992
7001
|
const askRuns = useMemo8(() => groupAskRuns(segments), [segments]);
|
|
6993
7002
|
const hasMentionSupport = !!renderMention;
|
|
@@ -7036,14 +7045,15 @@ var ChatMessageEnhanced = forwardRef16(
|
|
|
7036
7045
|
const key = `${cardType}:${cardId}`;
|
|
7037
7046
|
usedKeys.add(key);
|
|
7038
7047
|
let entry = cache.get(key);
|
|
7039
|
-
|
|
7040
|
-
|
|
7041
|
-
|
|
7042
|
-
|
|
7043
|
-
|
|
7044
|
-
|
|
7045
|
-
|
|
7046
|
-
|
|
7048
|
+
const enrichedRef = refsByKey.get(key);
|
|
7049
|
+
const refForRender = enrichedRef ?? {
|
|
7050
|
+
type: cardType,
|
|
7051
|
+
id: cardId,
|
|
7052
|
+
title: cardId,
|
|
7053
|
+
url: null
|
|
7054
|
+
};
|
|
7055
|
+
if (!entry || entry.render !== render || entry.reference !== refForRender) {
|
|
7056
|
+
entry = { render, reference: refForRender, node: render(refForRender) };
|
|
7047
7057
|
cache.set(key, entry);
|
|
7048
7058
|
}
|
|
7049
7059
|
const rendered = entry.node;
|
|
@@ -7077,7 +7087,7 @@ var ChatMessageEnhanced = forwardRef16(
|
|
|
7077
7087
|
}
|
|
7078
7088
|
});
|
|
7079
7089
|
return { inlineByKey, partsBySegment, usedKeys };
|
|
7080
|
-
}, [hasMarkerSupport, renderEntityCard, segments]);
|
|
7090
|
+
}, [hasMarkerSupport, refsByKey, renderEntityCard, segments]);
|
|
7081
7091
|
useEffect6(() => {
|
|
7082
7092
|
const cache = renderedCardNodeCache.current;
|
|
7083
7093
|
const usedKeys = renderingPlan?.usedKeys;
|
|
@@ -7304,7 +7314,7 @@ var MemoizedChatMessageEnhanced = memo2(ChatMessageEnhanced, (prevProps, nextPro
|
|
|
7304
7314
|
// message (it's set once on the optimistic send and never mutated).
|
|
7305
7315
|
prevProps.contextItems === nextProps.contextItems && prevProps.resolveContextIcon === nextProps.resolveContextIcon && prevProps.renderContextItem === nextProps.renderContextItem && // Host keeps this stable (module const / useCallback), so reference
|
|
7306
7316
|
// equality holds across streaming chunks.
|
|
7307
|
-
prevProps.renderMention === nextProps.renderMention && prevProps.renderEntityCard === nextProps.renderEntityCard && // Same stability contract as the renderers above: hosts pass a `useCallback`
|
|
7317
|
+
prevProps.renderMention === nextProps.renderMention && prevProps.renderEntityCard === nextProps.renderEntityCard && prevProps.refs === nextProps.refs && // Same stability contract as the renderers above: hosts pass a `useCallback`
|
|
7308
7318
|
// (EmbeddableChat passes its memoized `handleSend`), so this holds across
|
|
7309
7319
|
// streaming chunks instead of re-rendering every ask card per chunk.
|
|
7310
7320
|
prevProps.onAskSelect === nextProps.onAskSelect && prevProps.NavLinkAnchor === nextProps.NavLinkAnchor;
|
|
@@ -7892,6 +7902,7 @@ var ChatMessageList = forwardRef17(
|
|
|
7892
7902
|
renderContextItem,
|
|
7893
7903
|
renderMention,
|
|
7894
7904
|
renderEntityCard,
|
|
7905
|
+
refs: message.refs,
|
|
7895
7906
|
onAskSelect: index > lastUserMessageIndex ? onAskSelect : void 0,
|
|
7896
7907
|
NavLinkAnchor
|
|
7897
7908
|
},
|
|
@@ -14799,6 +14810,14 @@ function hubspotStatusToVariant(status) {
|
|
|
14799
14810
|
if (s === "OPEN") return "warning";
|
|
14800
14811
|
return "grey";
|
|
14801
14812
|
}
|
|
14813
|
+
function validatedHttpsUrl(value) {
|
|
14814
|
+
if (typeof value !== "string") return null;
|
|
14815
|
+
try {
|
|
14816
|
+
return new URL(value).protocol === "https:" ? value : null;
|
|
14817
|
+
} catch {
|
|
14818
|
+
return null;
|
|
14819
|
+
}
|
|
14820
|
+
}
|
|
14802
14821
|
function decodeVideoMarkerId(id) {
|
|
14803
14822
|
const mux = id.match(/^mux-([A-Za-z0-9_-]+)$/);
|
|
14804
14823
|
if (mux) {
|
|
@@ -14811,8 +14830,8 @@ function decodeVideoMarkerId(id) {
|
|
|
14811
14830
|
try {
|
|
14812
14831
|
const b64 = mp4[1].replace(/-/g, "+").replace(/_/g, "/");
|
|
14813
14832
|
const url = atob(b64);
|
|
14814
|
-
|
|
14815
|
-
return { videoUrl:
|
|
14833
|
+
const safeUrl = validatedHttpsUrl(url);
|
|
14834
|
+
return safeUrl ? { videoUrl: safeUrl } : null;
|
|
14816
14835
|
} catch {
|
|
14817
14836
|
return null;
|
|
14818
14837
|
}
|
|
@@ -14820,6 +14839,26 @@ function decodeVideoMarkerId(id) {
|
|
|
14820
14839
|
if (/^[A-Za-z0-9_-]{11}$/.test(id)) return { youtubeUrl: id };
|
|
14821
14840
|
return null;
|
|
14822
14841
|
}
|
|
14842
|
+
function validatedVideoMetadata(chatRef) {
|
|
14843
|
+
const input = chatRef.metadata ?? {};
|
|
14844
|
+
const metadata = {};
|
|
14845
|
+
for (const key of ["videoUrl", "highlightVideoUrl", "videoPoster", "highlightVideoPoster"]) {
|
|
14846
|
+
const url = validatedHttpsUrl(input[key]);
|
|
14847
|
+
if (url) metadata[key] = url;
|
|
14848
|
+
}
|
|
14849
|
+
const youtubeUrl = input.youtubeUrl;
|
|
14850
|
+
if (typeof youtubeUrl === "string" && /^[A-Za-z0-9_-]{11}$/.test(youtubeUrl)) {
|
|
14851
|
+
metadata.youtubeUrl = youtubeUrl;
|
|
14852
|
+
}
|
|
14853
|
+
const safeUrl = validatedHttpsUrl(chatRef.url);
|
|
14854
|
+
if (safeUrl) {
|
|
14855
|
+
const youtubeId2 = extractYouTubeId(safeUrl);
|
|
14856
|
+
delete metadata.videoUrl;
|
|
14857
|
+
delete metadata.youtubeUrl;
|
|
14858
|
+
metadata[youtubeId2 ? "youtubeUrl" : "videoUrl"] = youtubeId2 ?? safeUrl;
|
|
14859
|
+
}
|
|
14860
|
+
return Object.keys(metadata).length > 0 ? metadata : null;
|
|
14861
|
+
}
|
|
14823
14862
|
function itemVideoMetadata(item) {
|
|
14824
14863
|
const pick = (...vals) => {
|
|
14825
14864
|
for (const v of vals) if (typeof v === "string" && v.length > 0) return v;
|
|
@@ -15757,13 +15796,15 @@ function renderChatInlineEntityCard(chatRef, options = {}) {
|
|
|
15757
15796
|
}
|
|
15758
15797
|
);
|
|
15759
15798
|
if (chatRef.type === "video") {
|
|
15799
|
+
const enrichedMetadata = validatedVideoMetadata(chatRef);
|
|
15760
15800
|
const decoded = decodeVideoMarkerId(chatRef.id);
|
|
15761
|
-
|
|
15801
|
+
const playableMetadata = enrichedMetadata ?? decoded;
|
|
15802
|
+
if (playableMetadata) {
|
|
15762
15803
|
const displayRef = {
|
|
15763
15804
|
...chatRef,
|
|
15764
15805
|
title: chatRef.title && chatRef.title !== chatRef.id ? chatRef.title : "Video",
|
|
15765
|
-
url: chatRef.url ??
|
|
15766
|
-
metadata:
|
|
15806
|
+
url: chatRef.url ?? (typeof playableMetadata.videoUrl === "string" ? playableMetadata.videoUrl : null) ?? (typeof playableMetadata.youtubeUrl === "string" ? `https://www.youtube.com/watch?v=${playableMetadata.youtubeUrl}` : null),
|
|
15807
|
+
metadata: playableMetadata
|
|
15767
15808
|
};
|
|
15768
15809
|
return /* @__PURE__ */ jsx93(BlockCard, { inline: /* @__PURE__ */ jsx93(ChatInlineVideoPill, { chatRef: displayRef }), children: /* @__PURE__ */ jsx93(ChatVideoEntityCard, { chatRef: displayRef }) });
|
|
15769
15810
|
}
|
|
@@ -17862,6 +17903,23 @@ function approvalDisplaysInline(approvalType, displayApprovalTypes) {
|
|
|
17862
17903
|
return !displayApprovalTypes || displayApprovalTypes.includes(approvalType);
|
|
17863
17904
|
}
|
|
17864
17905
|
|
|
17906
|
+
// src/components/chat/utils/chat-source-metadata.ts
|
|
17907
|
+
function mergeChatSources(current, incoming) {
|
|
17908
|
+
const sourcesByIndex = new Map((current ?? []).map((source) => [source.index, source]));
|
|
17909
|
+
incoming.forEach((source) => {
|
|
17910
|
+
if (!sourcesByIndex.has(source.index)) sourcesByIndex.set(source.index, source);
|
|
17911
|
+
});
|
|
17912
|
+
return Array.from(sourcesByIndex.values());
|
|
17913
|
+
}
|
|
17914
|
+
function mergeChatRefs(current, incoming) {
|
|
17915
|
+
const refsByIdentity = new Map((current ?? []).map((ref) => [`${ref.type}:${ref.id}`, ref]));
|
|
17916
|
+
incoming.forEach((ref) => {
|
|
17917
|
+
const identity = `${ref.type}:${ref.id}`;
|
|
17918
|
+
if (!refsByIdentity.has(identity)) refsByIdentity.set(identity, ref);
|
|
17919
|
+
});
|
|
17920
|
+
return Array.from(refsByIdentity.values());
|
|
17921
|
+
}
|
|
17922
|
+
|
|
17865
17923
|
// src/components/chat/stream/message-mutations.ts
|
|
17866
17924
|
function nextId(role) {
|
|
17867
17925
|
return `${role}-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
|
|
@@ -18721,6 +18779,8 @@ function createChatStreamReducer(options = {}) {
|
|
|
18721
18779
|
const sourcesMap = /* @__PURE__ */ new Map();
|
|
18722
18780
|
let sendCount = 0;
|
|
18723
18781
|
let sseCurrentText = "";
|
|
18782
|
+
let pendingSources;
|
|
18783
|
+
let pendingRefs;
|
|
18724
18784
|
let stateCache = null;
|
|
18725
18785
|
function invalidate() {
|
|
18726
18786
|
stateCache = null;
|
|
@@ -18782,6 +18842,17 @@ function createChatStreamReducer(options = {}) {
|
|
|
18782
18842
|
}
|
|
18783
18843
|
setMessagesInternal(stampTrailingAssistantSeq(updateTrailingAssistant(messages, segments), seq));
|
|
18784
18844
|
}
|
|
18845
|
+
function attachPendingSourceMetadata() {
|
|
18846
|
+
if (!pendingSources && !pendingRefs) return;
|
|
18847
|
+
const last = messages[messages.length - 1];
|
|
18848
|
+
if (!last || last.role !== "assistant") return;
|
|
18849
|
+
const next = {
|
|
18850
|
+
...last,
|
|
18851
|
+
...pendingSources ? { sources: pendingSources } : {},
|
|
18852
|
+
...pendingRefs ? { refs: pendingRefs } : {}
|
|
18853
|
+
};
|
|
18854
|
+
setMessagesInternal([...messages.slice(0, -1), next]);
|
|
18855
|
+
}
|
|
18785
18856
|
function applyStreamStartToState() {
|
|
18786
18857
|
setPhaseInternal("streaming");
|
|
18787
18858
|
const adoptTail = adoptTrailingAssistant;
|
|
@@ -18900,6 +18971,8 @@ function createChatStreamReducer(options = {}) {
|
|
|
18900
18971
|
}
|
|
18901
18972
|
switch (event.type) {
|
|
18902
18973
|
case "turn-start": {
|
|
18974
|
+
pendingSources = void 0;
|
|
18975
|
+
pendingRefs = void 0;
|
|
18903
18976
|
isInStream = true;
|
|
18904
18977
|
hasEverStreamed = true;
|
|
18905
18978
|
turnStartedAt = Date.now();
|
|
@@ -18914,6 +18987,14 @@ function createChatStreamReducer(options = {}) {
|
|
|
18914
18987
|
emit("onStreamEnd");
|
|
18915
18988
|
setPhaseInternal("idle");
|
|
18916
18989
|
accumulator.resetSegments();
|
|
18990
|
+
pendingSources = void 0;
|
|
18991
|
+
pendingRefs = void 0;
|
|
18992
|
+
break;
|
|
18993
|
+
}
|
|
18994
|
+
case "sources": {
|
|
18995
|
+
pendingSources = mergeChatSources(pendingSources, event.sources);
|
|
18996
|
+
if (event.refs) pendingRefs = mergeChatRefs(pendingRefs, event.refs);
|
|
18997
|
+
attachPendingSourceMetadata();
|
|
18917
18998
|
break;
|
|
18918
18999
|
}
|
|
18919
19000
|
case "metadata": {
|
|
@@ -18942,10 +19023,12 @@ function createChatStreamReducer(options = {}) {
|
|
|
18942
19023
|
if (isInStream || !hasEverStreamed) {
|
|
18943
19024
|
emitSegments(segments);
|
|
18944
19025
|
applySegmentsToState(segments, withSeqMeta(void 0));
|
|
19026
|
+
attachPendingSourceMetadata();
|
|
18945
19027
|
} else {
|
|
18946
19028
|
const delta = [{ type: kind, text: event.text }];
|
|
18947
19029
|
emitSegments(delta, { append: true });
|
|
18948
19030
|
applySegmentsToState(delta, withSeqMeta({ append: true }));
|
|
19031
|
+
attachPendingSourceMetadata();
|
|
18949
19032
|
}
|
|
18950
19033
|
break;
|
|
18951
19034
|
}
|
|
@@ -20565,6 +20648,176 @@ function useSseChatAdapter(options, runtimeOptions = {}) {
|
|
|
20565
20648
|
// src/components/chat/hooks/use-nats-chat-adapter.ts
|
|
20566
20649
|
import { useCallback as useCallback21, useEffect as useEffect34, useMemo as useMemo26, useRef as useRef29, useState as useState40 } from "react";
|
|
20567
20650
|
|
|
20651
|
+
// src/chat-protocol/source-metadata.ts
|
|
20652
|
+
var CARD_REFERENCE = /^\[card:\/\/([a-zA-Z0-9_-]+):([a-zA-Z0-9_-]+)\]$/;
|
|
20653
|
+
function requiredString(value) {
|
|
20654
|
+
if (typeof value !== "string") return null;
|
|
20655
|
+
const normalized = value.trim();
|
|
20656
|
+
return normalized ? normalized : null;
|
|
20657
|
+
}
|
|
20658
|
+
function optionalString(value) {
|
|
20659
|
+
return requiredString(value) ?? void 0;
|
|
20660
|
+
}
|
|
20661
|
+
function httpsUrl(value) {
|
|
20662
|
+
const candidate = optionalString(value);
|
|
20663
|
+
if (!candidate) return void 0;
|
|
20664
|
+
try {
|
|
20665
|
+
return new URL(candidate).protocol === "https:" ? candidate : void 0;
|
|
20666
|
+
} catch {
|
|
20667
|
+
return void 0;
|
|
20668
|
+
}
|
|
20669
|
+
}
|
|
20670
|
+
function youtubeId(value) {
|
|
20671
|
+
const candidate = optionalString(value);
|
|
20672
|
+
if (!candidate) return void 0;
|
|
20673
|
+
if (/^[A-Za-z0-9_-]{11}$/.test(candidate)) return candidate;
|
|
20674
|
+
const url = httpsUrl(candidate);
|
|
20675
|
+
if (!url) return void 0;
|
|
20676
|
+
const parsed = new URL(url);
|
|
20677
|
+
const hostname = parsed.hostname.toLowerCase();
|
|
20678
|
+
const youtubeHost = hostname === "youtu.be" || hostname === "youtube.com" || hostname.endsWith(".youtube.com");
|
|
20679
|
+
if (!youtubeHost) return void 0;
|
|
20680
|
+
const pathId = hostname === "youtu.be" ? parsed.pathname.split("/").filter(Boolean)[0] : parsed.pathname.match(/^\/(?:embed|v|shorts)\/([A-Za-z0-9_-]{11})(?:\/|$)/)?.[1];
|
|
20681
|
+
const id = pathId ?? parsed.searchParams.get("v") ?? void 0;
|
|
20682
|
+
return id && /^[A-Za-z0-9_-]{11}$/.test(id) ? id : void 0;
|
|
20683
|
+
}
|
|
20684
|
+
function nullableString(value) {
|
|
20685
|
+
return value === null ? null : optionalString(value);
|
|
20686
|
+
}
|
|
20687
|
+
function normalizeSourceItems(value) {
|
|
20688
|
+
if (!Array.isArray(value)) return void 0;
|
|
20689
|
+
const items = value.flatMap((candidate) => {
|
|
20690
|
+
if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) return [];
|
|
20691
|
+
const item = candidate;
|
|
20692
|
+
const id = requiredString(item.id);
|
|
20693
|
+
const documentType = requiredString(item.documentType);
|
|
20694
|
+
const name = requiredString(item.name);
|
|
20695
|
+
if (!id || !documentType || !name) return [];
|
|
20696
|
+
const externalUrl = httpsUrl(item.externalUrl);
|
|
20697
|
+
const targetPlatform = nullableString(item.targetPlatform);
|
|
20698
|
+
const path = nullableString(item.path);
|
|
20699
|
+
return [
|
|
20700
|
+
{
|
|
20701
|
+
id,
|
|
20702
|
+
documentType,
|
|
20703
|
+
name,
|
|
20704
|
+
...externalUrl ? { externalUrl } : {},
|
|
20705
|
+
...targetPlatform !== void 0 ? { targetPlatform } : {},
|
|
20706
|
+
...path !== void 0 ? { path } : {}
|
|
20707
|
+
}
|
|
20708
|
+
];
|
|
20709
|
+
});
|
|
20710
|
+
return items.length > 0 ? items : void 0;
|
|
20711
|
+
}
|
|
20712
|
+
function normalizeSources(value) {
|
|
20713
|
+
if (!Array.isArray(value)) return [];
|
|
20714
|
+
const seen = /* @__PURE__ */ new Set();
|
|
20715
|
+
const sources = [];
|
|
20716
|
+
for (const candidate of value) {
|
|
20717
|
+
if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) continue;
|
|
20718
|
+
const source = candidate;
|
|
20719
|
+
const index = source.index;
|
|
20720
|
+
const name = requiredString(source.name);
|
|
20721
|
+
const path = requiredString(source.path);
|
|
20722
|
+
const documentType = requiredString(source.documentType);
|
|
20723
|
+
const validIndex = typeof index === "number" && Number.isFinite(index) && Number.isInteger(index) && index > 0 && !seen.has(index);
|
|
20724
|
+
if (!validIndex || !name || !path || !documentType) continue;
|
|
20725
|
+
seen.add(index);
|
|
20726
|
+
const externalUrl = httpsUrl(source.externalUrl);
|
|
20727
|
+
const targetPlatform = nullableString(source.targetPlatform);
|
|
20728
|
+
const id = optionalString(source.id);
|
|
20729
|
+
const sourceRepo = optionalString(source.sourceRepo);
|
|
20730
|
+
const label = optionalString(source.label);
|
|
20731
|
+
const items = normalizeSourceItems(source.items);
|
|
20732
|
+
sources.push({
|
|
20733
|
+
index,
|
|
20734
|
+
name,
|
|
20735
|
+
path,
|
|
20736
|
+
documentType,
|
|
20737
|
+
...externalUrl ? { externalUrl } : {},
|
|
20738
|
+
...targetPlatform !== void 0 ? { targetPlatform } : {},
|
|
20739
|
+
...id ? { id } : {},
|
|
20740
|
+
...sourceRepo ? { sourceRepo } : {},
|
|
20741
|
+
...label ? { label } : {},
|
|
20742
|
+
...items ? { items } : {}
|
|
20743
|
+
});
|
|
20744
|
+
}
|
|
20745
|
+
return sources;
|
|
20746
|
+
}
|
|
20747
|
+
function normalizeVideoMetadata(value) {
|
|
20748
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
20749
|
+
const input = value;
|
|
20750
|
+
const metadata = {};
|
|
20751
|
+
for (const key of ["videoUrl", "highlightVideoUrl", "videoPoster", "highlightVideoPoster"]) {
|
|
20752
|
+
const url = httpsUrl(input[key]);
|
|
20753
|
+
if (url) metadata[key] = url;
|
|
20754
|
+
}
|
|
20755
|
+
const id = youtubeId(input.youtubeUrl);
|
|
20756
|
+
if (id) metadata.youtubeUrl = id;
|
|
20757
|
+
return metadata;
|
|
20758
|
+
}
|
|
20759
|
+
function normalizeVideos(value) {
|
|
20760
|
+
if (!Array.isArray(value)) return [];
|
|
20761
|
+
return value.flatMap((candidate) => {
|
|
20762
|
+
if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) return [];
|
|
20763
|
+
const video = candidate;
|
|
20764
|
+
const match = typeof video.ref === "string" ? CARD_REFERENCE.exec(video.ref) : null;
|
|
20765
|
+
if (!match || match[1] !== "video") return [];
|
|
20766
|
+
const id = match[2];
|
|
20767
|
+
const title = optionalString(video.title) ?? id;
|
|
20768
|
+
const url = httpsUrl(video.url) ?? null;
|
|
20769
|
+
const sourceRepo = optionalString(video.sourceRepo);
|
|
20770
|
+
const metadata = normalizeVideoMetadata(video.metadata);
|
|
20771
|
+
if (url) {
|
|
20772
|
+
const idFromUrl = youtubeId(url);
|
|
20773
|
+
if (idFromUrl) {
|
|
20774
|
+
metadata.youtubeUrl = idFromUrl;
|
|
20775
|
+
delete metadata.videoUrl;
|
|
20776
|
+
} else {
|
|
20777
|
+
metadata.videoUrl = url;
|
|
20778
|
+
delete metadata.youtubeUrl;
|
|
20779
|
+
}
|
|
20780
|
+
}
|
|
20781
|
+
return [
|
|
20782
|
+
{
|
|
20783
|
+
type: "video",
|
|
20784
|
+
id,
|
|
20785
|
+
title,
|
|
20786
|
+
url,
|
|
20787
|
+
...sourceRepo ? { sourceRepo } : {},
|
|
20788
|
+
...Object.keys(metadata).length > 0 ? { metadata } : {}
|
|
20789
|
+
}
|
|
20790
|
+
];
|
|
20791
|
+
});
|
|
20792
|
+
}
|
|
20793
|
+
function normalizeCards(value) {
|
|
20794
|
+
if (!Array.isArray(value)) return [];
|
|
20795
|
+
return value.flatMap((candidate) => {
|
|
20796
|
+
if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) return [];
|
|
20797
|
+
const card = candidate;
|
|
20798
|
+
const match = typeof card.ref === "string" ? CARD_REFERENCE.exec(card.ref) : null;
|
|
20799
|
+
if (!match || match[1] === "video") return [];
|
|
20800
|
+
const type = requiredString(card.entityType);
|
|
20801
|
+
const id = requiredString(card.entityId);
|
|
20802
|
+
if (!type || !id || type !== match[1] || id !== match[2]) return [];
|
|
20803
|
+
return [{ type, id, title: id, url: null }];
|
|
20804
|
+
});
|
|
20805
|
+
}
|
|
20806
|
+
function sourceMetadataEvent(payload) {
|
|
20807
|
+
if (!payload || typeof payload !== "object" || Array.isArray(payload)) return null;
|
|
20808
|
+
const metadata = payload;
|
|
20809
|
+
const sources = normalizeSources(metadata.sources);
|
|
20810
|
+
const refs = [...normalizeVideos(metadata.videos), ...normalizeCards(metadata.cards)];
|
|
20811
|
+
const refsByIdentity = /* @__PURE__ */ new Map();
|
|
20812
|
+
refs.forEach((ref) => {
|
|
20813
|
+
const identity = `${ref.type}:${ref.id}`;
|
|
20814
|
+
if (!refsByIdentity.has(identity)) refsByIdentity.set(identity, ref);
|
|
20815
|
+
});
|
|
20816
|
+
const uniqueRefs = Array.from(refsByIdentity.values());
|
|
20817
|
+
if (sources.length === 0 && uniqueRefs.length === 0) return null;
|
|
20818
|
+
return { type: "sources", sources, ...uniqueRefs.length > 0 ? { refs: uniqueRefs } : {} };
|
|
20819
|
+
}
|
|
20820
|
+
|
|
20568
20821
|
// src/chat-protocol/nats-decoder.ts
|
|
20569
20822
|
function isRecord2(value) {
|
|
20570
20823
|
return typeof value === "object" && value !== null;
|
|
@@ -20633,6 +20886,11 @@ function decodeNatsChunk(chunk) {
|
|
|
20633
20886
|
return { type: "thinking-delta", text: data.text, ...seq };
|
|
20634
20887
|
}
|
|
20635
20888
|
return null;
|
|
20889
|
+
case MESSAGE_TYPE.GUIDE:
|
|
20890
|
+
case MESSAGE_TYPE.SOURCES: {
|
|
20891
|
+
const event = sourceMetadataEvent(data.payload);
|
|
20892
|
+
return event ? { ...event, ...seq } : null;
|
|
20893
|
+
}
|
|
20636
20894
|
// An ask card is only an ask card with something to pick: a question and at
|
|
20637
20895
|
// least one option. Anything less is dropped rather than rendered as an
|
|
20638
20896
|
// empty card the user can't answer — the backend already falls back to a
|
|
@@ -20984,6 +21242,9 @@ function decodeHistoricalMessageData(data) {
|
|
|
20984
21242
|
return { type: "thinking-delta", text: data.text };
|
|
20985
21243
|
}
|
|
20986
21244
|
return null;
|
|
21245
|
+
case MESSAGE_TYPE.GUIDE:
|
|
21246
|
+
case MESSAGE_TYPE.SOURCES:
|
|
21247
|
+
return decodeNatsChunk({ type: data.type, payload: data.payload });
|
|
20987
21248
|
// Same completeness gate as the live decoder (`decodeNatsChunk`): a
|
|
20988
21249
|
// persisted row without a question or without options is not a card the
|
|
20989
21250
|
// user can answer, so it replays as nothing rather than as empty chrome.
|
|
@@ -21339,6 +21600,8 @@ function processHistoricalMessages(messages, options = {}) {
|
|
|
21339
21600
|
let currentAssistantTimestamp = null;
|
|
21340
21601
|
let lastAssistantId = null;
|
|
21341
21602
|
let currentAssistantStreamSeq;
|
|
21603
|
+
let currentAssistantSources;
|
|
21604
|
+
let currentAssistantRefs;
|
|
21342
21605
|
const flushAssistantMessage = () => {
|
|
21343
21606
|
const idToUse = lastAssistantId || currentAssistantId;
|
|
21344
21607
|
if (idToUse && accumulator.hasContent()) {
|
|
@@ -21351,6 +21614,8 @@ function processHistoricalMessages(messages, options = {}) {
|
|
|
21351
21614
|
authorType: assistantType,
|
|
21352
21615
|
timestamp: currentAssistantTimestamp || /* @__PURE__ */ new Date(),
|
|
21353
21616
|
avatar: assistantAvatar,
|
|
21617
|
+
...currentAssistantSources ? { sources: currentAssistantSources } : {},
|
|
21618
|
+
...currentAssistantRefs ? { refs: currentAssistantRefs } : {},
|
|
21354
21619
|
...currentAssistantStreamSeq !== void 0 ? { streamSeq: currentAssistantStreamSeq } : {}
|
|
21355
21620
|
});
|
|
21356
21621
|
accumulator.resetSegments();
|
|
@@ -21359,6 +21624,8 @@ function processHistoricalMessages(messages, options = {}) {
|
|
|
21359
21624
|
currentAssistantTimestamp = null;
|
|
21360
21625
|
lastAssistantId = null;
|
|
21361
21626
|
currentAssistantStreamSeq = void 0;
|
|
21627
|
+
currentAssistantSources = void 0;
|
|
21628
|
+
currentAssistantRefs = void 0;
|
|
21362
21629
|
};
|
|
21363
21630
|
messages.forEach((msg, index) => {
|
|
21364
21631
|
if (chatTypeFilter && msg.chatType !== chatTypeFilter) return;
|
|
@@ -21402,6 +21669,11 @@ function processHistoricalMessages(messages, options = {}) {
|
|
|
21402
21669
|
messageDataArray.forEach((data) => {
|
|
21403
21670
|
const event = decodeHistoricalMessageData(data);
|
|
21404
21671
|
if (!event) return;
|
|
21672
|
+
if (event.type === "sources") {
|
|
21673
|
+
currentAssistantSources = mergeChatSources(currentAssistantSources, event.sources);
|
|
21674
|
+
if (event.refs) currentAssistantRefs = mergeChatRefs(currentAssistantRefs, event.refs);
|
|
21675
|
+
return;
|
|
21676
|
+
}
|
|
21405
21677
|
applyHistoryEvent(
|
|
21406
21678
|
event,
|
|
21407
21679
|
accumulator,
|
|
@@ -21494,13 +21766,17 @@ function mapProcessedToUnified(processed) {
|
|
|
21494
21766
|
id: m.id,
|
|
21495
21767
|
role: m.role,
|
|
21496
21768
|
content: "",
|
|
21497
|
-
segments: m.content
|
|
21769
|
+
segments: m.content,
|
|
21770
|
+
...m.sources ? { sources: m.sources } : {},
|
|
21771
|
+
...m.refs ? { refs: m.refs } : {}
|
|
21498
21772
|
});
|
|
21499
21773
|
} else {
|
|
21500
21774
|
out.push({
|
|
21501
21775
|
id: m.id,
|
|
21502
21776
|
role: m.role,
|
|
21503
|
-
content: m.content
|
|
21777
|
+
content: m.content,
|
|
21778
|
+
...m.sources ? { sources: m.sources } : {},
|
|
21779
|
+
...m.refs ? { refs: m.refs } : {}
|
|
21504
21780
|
});
|
|
21505
21781
|
}
|
|
21506
21782
|
}
|
|
@@ -23755,6 +24031,10 @@ function EmbeddableChatInner({
|
|
|
23755
24031
|
// explicitly — see `Message.hidden` and `chat-message-list`'s skip.
|
|
23756
24032
|
...m.hidden ? { hidden: true } : {},
|
|
23757
24033
|
...m.scrollAnchor ? { scrollAnchor: m.scrollAnchor } : {},
|
|
24034
|
+
// Preserve same-turn rich metadata. Source chips and entity-card
|
|
24035
|
+
// renderers consume it after this raw-to-Message projection.
|
|
24036
|
+
...m.sources && m.sources.length > 0 ? { sources: m.sources } : {},
|
|
24037
|
+
...m.refs && m.refs.length > 0 ? { refs: m.refs } : {},
|
|
23758
24038
|
// Forward attached context items so the user bubble renders its chips.
|
|
23759
24039
|
...m.contextItems && m.contextItems.length > 0 ? { contextItems: m.contextItems } : {}
|
|
23760
24040
|
};
|
|
@@ -23911,7 +24191,7 @@ function EmbeddableChatInner({
|
|
|
23911
24191
|
if (chatLoading) return void 0;
|
|
23912
24192
|
const sources = lastAssistantMsg?.sources;
|
|
23913
24193
|
if (!sources || sources.length === 0) return void 0;
|
|
23914
|
-
const content = lastAssistantMsg
|
|
24194
|
+
const content = lastAssistantMsg.content || (lastAssistantMsg.segments ?? []).filter((segment) => segment.type === "text").map((segment) => segment.text).join("\n");
|
|
23915
24195
|
const citationOrder = [...content.matchAll(/\[(\d+)\]/g)].map((m) => parseInt(m[1], 10));
|
|
23916
24196
|
const seenOrder = /* @__PURE__ */ new Map();
|
|
23917
24197
|
citationOrder.forEach((idx) => {
|
|
@@ -24848,4 +25128,4 @@ export {
|
|
|
24848
25128
|
buildStreamFrames,
|
|
24849
25129
|
EmbeddableChat
|
|
24850
25130
|
};
|
|
24851
|
-
//# sourceMappingURL=chunk-
|
|
25131
|
+
//# sourceMappingURL=chunk-CO4WRST6.js.map
|