@flamingo-stack/openframe-frontend-core 0.0.586 → 0.0.587-1973.5528.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 +188 -0
- package/dist/chat-protocol/index.cjs.map +1 -1
- package/dist/chat-protocol/index.js +188 -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 +5 -0
- package/dist/chat-protocol/source-metadata.d.ts.map +1 -0
- package/dist/{chunk-BMORFCT2.cjs → chunk-3UJMZADA.cjs} +43 -43
- package/dist/{chunk-BMORFCT2.cjs.map → chunk-3UJMZADA.cjs.map} +1 -1
- package/dist/{chunk-D7YISHXC.js → chunk-4MVGFYRE.js} +534 -190
- package/dist/chunk-4MVGFYRE.js.map +1 -0
- package/dist/{chunk-3WR5R6H6.cjs → chunk-4S7GMJYA.cjs} +21 -21
- package/dist/{chunk-3WR5R6H6.cjs.map → chunk-4S7GMJYA.cjs.map} +1 -1
- package/dist/{chunk-EAYMX22G.cjs → chunk-5VCDP6UA.cjs} +10 -10
- package/dist/{chunk-EAYMX22G.cjs.map → chunk-5VCDP6UA.cjs.map} +1 -1
- package/dist/{chunk-XMTGLQSD.js → chunk-5X7AJ67N.js} +3 -3
- package/dist/{chunk-OZNFPQT5.js → chunk-7A6J4JTW.js} +3 -3
- package/dist/{chunk-QZYYNBMI.cjs → chunk-7COFWOCJ.cjs} +22 -22
- package/dist/{chunk-QZYYNBMI.cjs.map → chunk-7COFWOCJ.cjs.map} +1 -1
- package/dist/{chunk-6ZNWY6WW.cjs → chunk-AIUIIGO3.cjs} +24 -24
- package/dist/{chunk-6ZNWY6WW.cjs.map → chunk-AIUIIGO3.cjs.map} +1 -1
- package/dist/{chunk-M36XSGZV.cjs → chunk-BLC4JOFC.cjs} +15 -15
- package/dist/{chunk-M36XSGZV.cjs.map → chunk-BLC4JOFC.cjs.map} +1 -1
- package/dist/{chunk-NISAGFEM.cjs → chunk-DSXD77KX.cjs} +3 -3
- package/dist/{chunk-NISAGFEM.cjs.map → chunk-DSXD77KX.cjs.map} +1 -1
- package/dist/{chunk-P2CKLIOM.cjs → chunk-DVMQV3M4.cjs} +69 -69
- package/dist/{chunk-P2CKLIOM.cjs.map → chunk-DVMQV3M4.cjs.map} +1 -1
- package/dist/{chunk-S7YXLZNG.js → chunk-E2QFZDCP.js} +5 -5
- package/dist/{chunk-G45RGWHF.cjs → chunk-EKKR5ZFB.cjs} +887 -543
- package/dist/chunk-EKKR5ZFB.cjs.map +1 -0
- package/dist/{chunk-L4WLYGB4.js → chunk-FDWGO244.js} +2 -2
- package/dist/{chunk-3JVYM4ZN.js → chunk-JQO47UHC.js} +5 -5
- package/dist/{chunk-C3MRLZUI.cjs → chunk-JR37UTA2.cjs} +33 -33
- package/dist/{chunk-C3MRLZUI.cjs.map → chunk-JR37UTA2.cjs.map} +1 -1
- package/dist/{chunk-LV6CORVJ.js → chunk-KQWI25NP.js} +2 -2
- package/dist/{chunk-V7ZJTUV2.cjs → chunk-NEI7XMCM.cjs} +9 -9
- package/dist/{chunk-V7ZJTUV2.cjs.map → chunk-NEI7XMCM.cjs.map} +1 -1
- package/dist/{chunk-YEQAA6I4.js → chunk-OW3FUJ2I.js} +3 -3
- package/dist/{chunk-PLMJVA2H.js → chunk-OZRT3ZI3.js} +3 -3
- package/dist/{chunk-XMK24INA.cjs → chunk-QKAUBYU5.cjs} +3 -3
- package/dist/{chunk-XMK24INA.cjs.map → chunk-QKAUBYU5.cjs.map} +1 -1
- package/dist/{chunk-6EZGJZVH.js → chunk-QSO24MEK.js} +2 -2
- package/dist/{chunk-DQUEVRDU.js → chunk-QYDIVL4X.js} +6 -6
- package/dist/{chunk-3HYHYKNL.js → chunk-RE3KVI2Q.js} +5 -5
- package/dist/{chunk-KLWJRGNN.js → chunk-RQ5PYSRJ.js} +4 -4
- package/dist/{chunk-NYLWMAHP.cjs → chunk-S2UY2C4A.cjs} +10 -10
- package/dist/{chunk-NYLWMAHP.cjs.map → chunk-S2UY2C4A.cjs.map} +1 -1
- package/dist/{chunk-SSGM2NKA.cjs → chunk-SCVIBVFS.cjs} +4 -4
- package/dist/{chunk-SSGM2NKA.cjs.map → chunk-SCVIBVFS.cjs.map} +1 -1
- package/dist/{chunk-4VZFJKPT.cjs → chunk-ULOMJH7C.cjs} +5 -5
- package/dist/{chunk-4VZFJKPT.cjs.map → chunk-ULOMJH7C.cjs.map} +1 -1
- package/dist/{chunk-5OIXAV4P.js → chunk-UODM3HJC.js} +3 -3
- package/dist/{chunk-A6ETQEWK.cjs → chunk-UYHETUX3.cjs} +159 -159
- package/dist/{chunk-A6ETQEWK.cjs.map → chunk-UYHETUX3.cjs.map} +1 -1
- package/dist/{chunk-2Y5UT5VF.js → chunk-WFWWQO2I.js} +2 -2
- package/dist/{chunk-YYC7V7YC.js → chunk-ZRFSUCAH.js} +2 -2
- 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/embeddable-chat.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-slash-commands.d.ts +3 -3
- package/dist/components/chat/hooks/use-slash-commands.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/remark-strip-citations.d.ts.map +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 +4 -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/hover-dropdown.d.ts.map +1 -1
- 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 +2 -1
- package/src/chat-protocol/__tests__/nats-decoder-golden.test.ts +130 -0
- package/src/chat-protocol/__tests__/source-metadata.test.ts +74 -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 +202 -0
- package/src/components/chat/__tests__/chat-message-list.test.tsx +70 -0
- package/src/components/chat/__tests__/chat-message-streaming-memo.test.tsx +86 -0
- package/src/components/chat/__tests__/embeddable-chat-sources.test.tsx +411 -0
- package/src/components/chat/__tests__/remark-strip-citations.test.ts +52 -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 +27 -22
- package/src/components/chat/embeddable-chat.tsx +55 -36
- package/src/components/chat/entity-cards/__tests__/dispatch-video-refs.test.tsx +74 -0
- package/src/components/chat/entity-cards/dispatch.tsx +86 -17
- package/src/components/chat/hooks/__tests__/use-slash-commands.test.ts +64 -0
- package/src/components/chat/hooks/use-nats-chat-adapter.ts +7 -0
- package/src/components/chat/hooks/use-slash-commands.ts +9 -5
- package/src/components/chat/hooks/use-sse-chat-adapter.ts +2 -29
- package/src/components/chat/remark-strip-citations.ts +5 -3
- 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 +4 -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/src/components/ui/hover-dropdown.tsx +8 -3
- package/dist/chunk-D7YISHXC.js.map +0 -1
- package/dist/chunk-G45RGWHF.cjs.map +0 -1
- /package/dist/{chunk-XMTGLQSD.js.map → chunk-5X7AJ67N.js.map} +0 -0
- /package/dist/{chunk-OZNFPQT5.js.map → chunk-7A6J4JTW.js.map} +0 -0
- /package/dist/{chunk-S7YXLZNG.js.map → chunk-E2QFZDCP.js.map} +0 -0
- /package/dist/{chunk-L4WLYGB4.js.map → chunk-FDWGO244.js.map} +0 -0
- /package/dist/{chunk-3JVYM4ZN.js.map → chunk-JQO47UHC.js.map} +0 -0
- /package/dist/{chunk-LV6CORVJ.js.map → chunk-KQWI25NP.js.map} +0 -0
- /package/dist/{chunk-YEQAA6I4.js.map → chunk-OW3FUJ2I.js.map} +0 -0
- /package/dist/{chunk-PLMJVA2H.js.map → chunk-OZRT3ZI3.js.map} +0 -0
- /package/dist/{chunk-6EZGJZVH.js.map → chunk-QSO24MEK.js.map} +0 -0
- /package/dist/{chunk-DQUEVRDU.js.map → chunk-QYDIVL4X.js.map} +0 -0
- /package/dist/{chunk-3HYHYKNL.js.map → chunk-RE3KVI2Q.js.map} +0 -0
- /package/dist/{chunk-KLWJRGNN.js.map → chunk-RQ5PYSRJ.js.map} +0 -0
- /package/dist/{chunk-5OIXAV4P.js.map → chunk-UODM3HJC.js.map} +0 -0
- /package/dist/{chunk-2Y5UT5VF.js.map → chunk-WFWWQO2I.js.map} +0 -0
- /package/dist/{chunk-YYC7V7YC.js.map → chunk-ZRFSUCAH.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",
|
|
@@ -6812,17 +6814,18 @@ var remarkMentionChips = () => {
|
|
|
6812
6814
|
// src/components/chat/remark-strip-citations.ts
|
|
6813
6815
|
import { visit as visit3 } from "unist-util-visit";
|
|
6814
6816
|
var CITATION_REGEX = /(^|\s)\[\d{1,2}(?:\s*,\s*\d{1,2})*\](?=[\s.,;:!?)\]]|$)/g;
|
|
6817
|
+
var CITATION_LIST_REGEX = /(^|\s)(?:\[\d{1,2}(?:\s*,\s*\d{1,2})*\]\s*,\s*)+(?:(?:and|or)\s+)?\[\d{1,2}(?:\s*,\s*\d{1,2})*\](?=[\s.,;:!?)\]]|$)/g;
|
|
6815
6818
|
var remarkStripCitations = () => {
|
|
6816
6819
|
return (tree) => {
|
|
6817
6820
|
visit3(tree, "text", (node, index, parent) => {
|
|
6818
6821
|
if (!parent || typeof index !== "number") return;
|
|
6819
6822
|
if (!node.value || !node.value.includes("[")) return;
|
|
6820
|
-
const
|
|
6823
|
+
const withoutCitationLists = node.value.replace(CITATION_LIST_REGEX, "$1");
|
|
6824
|
+
const withoutCitations = withoutCitationLists.replace(CITATION_REGEX, "$1");
|
|
6821
6825
|
if (withoutCitations === node.value) return;
|
|
6822
6826
|
parent.children.splice(index, 1, {
|
|
6823
6827
|
...node,
|
|
6824
|
-
|
|
6825
|
-
value: withoutCitations.replace(/ {2,}/g, " ")
|
|
6828
|
+
value: withoutCitations.replace(/\s+([.,;:!?])/g, "$1").replace(/ {2,}/g, " ")
|
|
6826
6829
|
});
|
|
6827
6830
|
});
|
|
6828
6831
|
};
|
|
@@ -6854,6 +6857,8 @@ var ToolExecutionDisplay = forwardRef15(
|
|
|
6854
6857
|
}, [message.parameters, variant]);
|
|
6855
6858
|
const hasResult = isExecuted && typeof message.result === "string" && message.result.length > 0;
|
|
6856
6859
|
const hasBody = argEntries.length > 0 || hasResult || isExecuting;
|
|
6860
|
+
const isConciseRemoteRead = !message.integratedToolType && !!message.toolTitle?.trim() && argEntries.length === 0 && !hasResult;
|
|
6861
|
+
const isStaticRow = isClientView || isConciseRemoteRead;
|
|
6857
6862
|
const renderStatusIcon = () => {
|
|
6858
6863
|
if (isExecuting) return /* @__PURE__ */ jsx34(DotsLoaderIcon, { size: 16, className: "text-ods-text-secondary" });
|
|
6859
6864
|
if (isExecuted && message.success === true) return /* @__PURE__ */ jsx34(CheckCircleIcon, { className: "h-4 w-4 text-ods-success" });
|
|
@@ -6873,7 +6878,7 @@ var ToolExecutionDisplay = forwardRef15(
|
|
|
6873
6878
|
}
|
|
6874
6879
|
),
|
|
6875
6880
|
/* @__PURE__ */ jsx34("div", { className: "flex h-5 w-5 shrink-0 items-center justify-center", children: renderStatusIcon() }),
|
|
6876
|
-
!
|
|
6881
|
+
!isStaticRow && /* @__PURE__ */ jsx34("div", { className: "flex h-5 w-5 shrink-0 items-center justify-center", children: /* @__PURE__ */ jsx34(ExpandChevron, { expanded }) })
|
|
6877
6882
|
] });
|
|
6878
6883
|
return /* @__PURE__ */ jsx34(
|
|
6879
6884
|
"div",
|
|
@@ -6886,7 +6891,7 @@ var ToolExecutionDisplay = forwardRef15(
|
|
|
6886
6891
|
className
|
|
6887
6892
|
),
|
|
6888
6893
|
...props,
|
|
6889
|
-
children:
|
|
6894
|
+
children: isStaticRow ? (
|
|
6890
6895
|
// Client (Fae end-user): static, non-expandable row — no chevron, no
|
|
6891
6896
|
// body. Just the explanation + status; command/args/result are hidden.
|
|
6892
6897
|
/* @__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 +6985,7 @@ var ChatMessageEnhanced = forwardRef16(
|
|
|
6980
6985
|
renderContextItem,
|
|
6981
6986
|
renderMention,
|
|
6982
6987
|
renderEntityCard,
|
|
6988
|
+
refs,
|
|
6983
6989
|
onAskSelect,
|
|
6984
6990
|
NavLinkAnchor,
|
|
6985
6991
|
...props
|
|
@@ -6988,6 +6994,10 @@ var ChatMessageEnhanced = forwardRef16(
|
|
|
6988
6994
|
const isError = role === "error";
|
|
6989
6995
|
const authorType = authorTypeProp ?? (isUser ? "user" : assistantType === "mingo" ? "mingo" : "fae");
|
|
6990
6996
|
const hasMarkerSupport = !!renderEntityCard;
|
|
6997
|
+
const refsByKey = useMemo8(
|
|
6998
|
+
() => new Map((refs ?? []).map((reference) => [`${reference.type}:${reference.id}`, reference])),
|
|
6999
|
+
[refs]
|
|
7000
|
+
);
|
|
6991
7001
|
const segments = useMemo8(() => normalizeContent(content), [content]);
|
|
6992
7002
|
const askRuns = useMemo8(() => groupAskRuns(segments), [segments]);
|
|
6993
7003
|
const hasMentionSupport = !!renderMention;
|
|
@@ -7036,14 +7046,15 @@ var ChatMessageEnhanced = forwardRef16(
|
|
|
7036
7046
|
const key = `${cardType}:${cardId}`;
|
|
7037
7047
|
usedKeys.add(key);
|
|
7038
7048
|
let entry = cache.get(key);
|
|
7039
|
-
|
|
7040
|
-
|
|
7041
|
-
|
|
7042
|
-
|
|
7043
|
-
|
|
7044
|
-
|
|
7045
|
-
|
|
7046
|
-
|
|
7049
|
+
const enrichedRef = refsByKey.get(key);
|
|
7050
|
+
const refForRender = enrichedRef ?? {
|
|
7051
|
+
type: cardType,
|
|
7052
|
+
id: cardId,
|
|
7053
|
+
title: cardId,
|
|
7054
|
+
url: null
|
|
7055
|
+
};
|
|
7056
|
+
if (!entry || entry.render !== render || entry.reference !== refForRender) {
|
|
7057
|
+
entry = { render, reference: refForRender, node: render(refForRender) };
|
|
7047
7058
|
cache.set(key, entry);
|
|
7048
7059
|
}
|
|
7049
7060
|
const rendered = entry.node;
|
|
@@ -7077,7 +7088,7 @@ var ChatMessageEnhanced = forwardRef16(
|
|
|
7077
7088
|
}
|
|
7078
7089
|
});
|
|
7079
7090
|
return { inlineByKey, partsBySegment, usedKeys };
|
|
7080
|
-
}, [hasMarkerSupport, renderEntityCard, segments]);
|
|
7091
|
+
}, [hasMarkerSupport, refsByKey, renderEntityCard, segments]);
|
|
7081
7092
|
useEffect6(() => {
|
|
7082
7093
|
const cache = renderedCardNodeCache.current;
|
|
7083
7094
|
const usedKeys = renderingPlan?.usedKeys;
|
|
@@ -7304,7 +7315,7 @@ var MemoizedChatMessageEnhanced = memo2(ChatMessageEnhanced, (prevProps, nextPro
|
|
|
7304
7315
|
// message (it's set once on the optimistic send and never mutated).
|
|
7305
7316
|
prevProps.contextItems === nextProps.contextItems && prevProps.resolveContextIcon === nextProps.resolveContextIcon && prevProps.renderContextItem === nextProps.renderContextItem && // Host keeps this stable (module const / useCallback), so reference
|
|
7306
7317
|
// 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`
|
|
7318
|
+
prevProps.renderMention === nextProps.renderMention && prevProps.renderEntityCard === nextProps.renderEntityCard && prevProps.refs === nextProps.refs && // Same stability contract as the renderers above: hosts pass a `useCallback`
|
|
7308
7319
|
// (EmbeddableChat passes its memoized `handleSend`), so this holds across
|
|
7309
7320
|
// streaming chunks instead of re-rendering every ask card per chunk.
|
|
7310
7321
|
prevProps.onAskSelect === nextProps.onAskSelect && prevProps.NavLinkAnchor === nextProps.NavLinkAnchor;
|
|
@@ -7313,6 +7324,7 @@ MemoizedChatMessageEnhanced.displayName = "MemoizedChatMessageEnhanced";
|
|
|
7313
7324
|
|
|
7314
7325
|
// src/components/chat/chat-message-list.tsx
|
|
7315
7326
|
import {
|
|
7327
|
+
Fragment as Fragment11,
|
|
7316
7328
|
useRef as useRef5,
|
|
7317
7329
|
useState as useState14,
|
|
7318
7330
|
useCallback as useCallback5,
|
|
@@ -7516,6 +7528,7 @@ var ChatMessageList = forwardRef17(
|
|
|
7516
7528
|
renderContextItem,
|
|
7517
7529
|
renderMention,
|
|
7518
7530
|
onAskSelect,
|
|
7531
|
+
renderAfterMessage,
|
|
7519
7532
|
NavLinkAnchor,
|
|
7520
7533
|
...props
|
|
7521
7534
|
}, ref) => {
|
|
@@ -7872,31 +7885,34 @@ var ChatMessageList = forwardRef17(
|
|
|
7872
7885
|
if (message.hidden) return null;
|
|
7873
7886
|
const isEmptyPendingTurn = index === messages.length - 1 && isTyping && message.role === "assistant" && !hasNonEmptyContent(message.content) && (!Array.isArray(message.content) || message.content.every((s) => s.type === "text"));
|
|
7874
7887
|
if (isEmptyPendingTurn) return null;
|
|
7875
|
-
return /* @__PURE__ */
|
|
7876
|
-
|
|
7877
|
-
|
|
7878
|
-
|
|
7879
|
-
|
|
7880
|
-
|
|
7881
|
-
|
|
7882
|
-
|
|
7883
|
-
|
|
7884
|
-
|
|
7885
|
-
|
|
7886
|
-
|
|
7887
|
-
|
|
7888
|
-
|
|
7889
|
-
|
|
7890
|
-
|
|
7891
|
-
|
|
7892
|
-
|
|
7893
|
-
|
|
7894
|
-
|
|
7895
|
-
|
|
7896
|
-
|
|
7897
|
-
|
|
7898
|
-
|
|
7899
|
-
|
|
7888
|
+
return /* @__PURE__ */ jsxs28(Fragment11, { children: [
|
|
7889
|
+
/* @__PURE__ */ jsx38(
|
|
7890
|
+
MemoizedChatMessageEnhanced,
|
|
7891
|
+
{
|
|
7892
|
+
ref: getRegisterMessageEl(message.id),
|
|
7893
|
+
role: message.role,
|
|
7894
|
+
name: message.name,
|
|
7895
|
+
content: message.content,
|
|
7896
|
+
timestamp: message.timestamp,
|
|
7897
|
+
isTyping: index === messages.length - 1 && isTyping && message.role === "assistant",
|
|
7898
|
+
avatar: showAvatars ? message.avatar : null,
|
|
7899
|
+
showAvatar: showAvatars,
|
|
7900
|
+
assistantType: message.assistantType || assistantType,
|
|
7901
|
+
approvalVariant,
|
|
7902
|
+
authorType: message.authorType,
|
|
7903
|
+
assistantIcon: message.role !== "user" ? assistantIcon : void 0,
|
|
7904
|
+
contextItems: message.contextItems,
|
|
7905
|
+
resolveContextIcon,
|
|
7906
|
+
renderContextItem,
|
|
7907
|
+
renderMention,
|
|
7908
|
+
renderEntityCard,
|
|
7909
|
+
refs: message.refs,
|
|
7910
|
+
onAskSelect: index > lastUserMessageIndex ? onAskSelect : void 0,
|
|
7911
|
+
NavLinkAnchor
|
|
7912
|
+
}
|
|
7913
|
+
),
|
|
7914
|
+
renderAfterMessage?.(message, index)
|
|
7915
|
+
] }, message.id);
|
|
7900
7916
|
})
|
|
7901
7917
|
]
|
|
7902
7918
|
}
|
|
@@ -8074,7 +8090,7 @@ function EntityIcon({
|
|
|
8074
8090
|
}
|
|
8075
8091
|
|
|
8076
8092
|
// src/components/chat/quick-action-chip.tsx
|
|
8077
|
-
import { Fragment as
|
|
8093
|
+
import { Fragment as Fragment12, jsx as jsx42, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
8078
8094
|
var AGENT_ACCENTS = { fae: "pink", mingo: "cyan" };
|
|
8079
8095
|
function getAgentAccent(slug) {
|
|
8080
8096
|
return slug === "fae" || slug === "mingo" ? AGENT_ACCENTS[slug] : void 0;
|
|
@@ -8102,7 +8118,7 @@ function renderQuickActionIcon(icon) {
|
|
|
8102
8118
|
}
|
|
8103
8119
|
function composeChipLabel(label, lozenge) {
|
|
8104
8120
|
if (!lozenge) return label;
|
|
8105
|
-
return /* @__PURE__ */ jsxs30(
|
|
8121
|
+
return /* @__PURE__ */ jsxs30(Fragment12, { children: [
|
|
8106
8122
|
/* @__PURE__ */ jsx42(
|
|
8107
8123
|
"span",
|
|
8108
8124
|
{
|
|
@@ -8139,7 +8155,7 @@ function QuickActionChipSkeleton({
|
|
|
8139
8155
|
size: size2,
|
|
8140
8156
|
className,
|
|
8141
8157
|
icon: icon ? /* @__PURE__ */ jsx42(ChipSkelBar, { className: size2 === "large" ? "block size-5" : "block size-4" }) : void 0,
|
|
8142
|
-
label: /* @__PURE__ */ jsxs30(
|
|
8158
|
+
label: /* @__PURE__ */ jsxs30(Fragment12, { children: [
|
|
8143
8159
|
lozenge && /* @__PURE__ */ jsx42(ChipSkelBar, { className: "mr-2 inline-block h-[16px] w-[26px] translate-y-[2px]" }),
|
|
8144
8160
|
/* @__PURE__ */ jsx42(ChipSkelBar, { className: "inline-block h-[0.9em] translate-y-[0.08em]", style: { width: `${labelCh}ch` } })
|
|
8145
8161
|
] })
|
|
@@ -8229,7 +8245,7 @@ import {
|
|
|
8229
8245
|
useState as useState16,
|
|
8230
8246
|
useSyncExternalStore as useSyncExternalStore2
|
|
8231
8247
|
} from "react";
|
|
8232
|
-
import { Fragment as
|
|
8248
|
+
import { Fragment as Fragment13, jsx as jsx43, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
8233
8249
|
function normalizeFades(fade) {
|
|
8234
8250
|
if (fade === void 0) return [];
|
|
8235
8251
|
return typeof fade === "string" ? [fade] : fade;
|
|
@@ -8317,7 +8333,7 @@ function MarqueeWallFades({
|
|
|
8317
8333
|
fadeColor = "var(--color-bg)",
|
|
8318
8334
|
fadeSize
|
|
8319
8335
|
}) {
|
|
8320
|
-
return /* @__PURE__ */ jsx43(
|
|
8336
|
+
return /* @__PURE__ */ jsx43(Fragment13, { children: normalizeFades(fade).map((edge) => {
|
|
8321
8337
|
const size2 = (typeof fadeSize === "object" && fadeSize !== null ? fadeSize[edge] : fadeSize) ?? DEFAULT_FADE_SIZE[edge];
|
|
8322
8338
|
const px = typeof size2 === "number" ? `${size2}px` : size2;
|
|
8323
8339
|
const isY = edge === "top" || edge === "bottom";
|
|
@@ -9406,7 +9422,7 @@ function MingoChatHistory({
|
|
|
9406
9422
|
}
|
|
9407
9423
|
|
|
9408
9424
|
// src/components/chat/mingo-welcome.tsx
|
|
9409
|
-
import { Fragment as
|
|
9425
|
+
import { Fragment as Fragment14, jsx as jsx52, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
9410
9426
|
var DEFAULT_SUBTITLE = "Ready to help with your technical tasks. What can I do for you?";
|
|
9411
9427
|
var DEFAULT_PROMO = {
|
|
9412
9428
|
title: "New to OpenFrame?",
|
|
@@ -9473,7 +9489,7 @@ function MingoWelcome({
|
|
|
9473
9489
|
/* @__PURE__ */ jsx52("p", { className: "text-body-sm text-ods-text-secondary", children: "Something went wrong reaching the server. Check your connection and try again." })
|
|
9474
9490
|
] }),
|
|
9475
9491
|
onRetry && /* @__PURE__ */ jsx52(Button, { variant: "outline", size: "small", leftIcon: /* @__PURE__ */ jsx52(Refresh01RightIcon, {}), onClick: onRetry, children: "Try again" })
|
|
9476
|
-
] }) : isLoadingHistory ? /* @__PURE__ */ jsx52(MingoChatHistorySkeleton, {}) : /* @__PURE__ */ jsx52(
|
|
9492
|
+
] }) : isLoadingHistory ? /* @__PURE__ */ jsx52(MingoChatHistorySkeleton, {}) : /* @__PURE__ */ jsx52(Fragment14, { children: /* @__PURE__ */ jsxs39("div", { className: "relative flex min-h-0 flex-1 flex-col", children: [
|
|
9477
9493
|
/* @__PURE__ */ jsx52(
|
|
9478
9494
|
"div",
|
|
9479
9495
|
{
|
|
@@ -10070,7 +10086,7 @@ var ModalFooter = forwardRef20(({ children, className }, ref) => /* @__PURE__ */
|
|
|
10070
10086
|
ModalFooter.displayName = "ModalV2Footer";
|
|
10071
10087
|
|
|
10072
10088
|
// src/components/chat/mingo-chat-modals.tsx
|
|
10073
|
-
import { Fragment as
|
|
10089
|
+
import { Fragment as Fragment15, jsx as jsx58, jsxs as jsxs45 } from "react/jsx-runtime";
|
|
10074
10090
|
var footerBtn = "flex-1 min-w-0 rounded-md px-[var(--spacing-system-m)] py-[var(--spacing-system-sf)] text-h3 transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-ods-accent disabled:opacity-50 disabled:cursor-not-allowed";
|
|
10075
10091
|
var cancelBtn = cn(footerBtn, "border border-ods-border bg-transparent text-ods-text-primary hover:bg-ods-bg-hover");
|
|
10076
10092
|
var saveBtn = cn(footerBtn, "bg-ods-accent text-ods-text-on-accent hover:bg-ods-accent-hover");
|
|
@@ -10141,7 +10157,7 @@ function ChatDialogModals({
|
|
|
10141
10157
|
setRestoreTarget,
|
|
10142
10158
|
onConfirmRestore
|
|
10143
10159
|
}) {
|
|
10144
|
-
return /* @__PURE__ */ jsxs45(
|
|
10160
|
+
return /* @__PURE__ */ jsxs45(Fragment15, { children: [
|
|
10145
10161
|
/* @__PURE__ */ jsx58(
|
|
10146
10162
|
RenameChatModal,
|
|
10147
10163
|
{
|
|
@@ -10347,7 +10363,7 @@ function ChatPanelHeaderMobile({
|
|
|
10347
10363
|
}
|
|
10348
10364
|
|
|
10349
10365
|
// src/components/chat/chat-panel-header.tsx
|
|
10350
|
-
import { Fragment as
|
|
10366
|
+
import { Fragment as Fragment16, jsx as jsx62, jsxs as jsxs48 } from "react/jsx-runtime";
|
|
10351
10367
|
function ChatPanelHeader({
|
|
10352
10368
|
showBack = false,
|
|
10353
10369
|
title,
|
|
@@ -10374,7 +10390,7 @@ function ChatPanelHeader({
|
|
|
10374
10390
|
onRename && { id: "rename", label: "Rename chat", onClick: onRename },
|
|
10375
10391
|
onArchive && { id: "archive", label: "Archive chat", onClick: onArchive }
|
|
10376
10392
|
].filter(Boolean);
|
|
10377
|
-
return /* @__PURE__ */ jsxs48(
|
|
10393
|
+
return /* @__PURE__ */ jsxs48(Fragment16, { children: [
|
|
10378
10394
|
!compact && /* @__PURE__ */ jsx62(
|
|
10379
10395
|
ChatPanelHeaderMobile,
|
|
10380
10396
|
{
|
|
@@ -10512,7 +10528,7 @@ function stripChatAttachmentMarkdown(text) {
|
|
|
10512
10528
|
}
|
|
10513
10529
|
|
|
10514
10530
|
// src/components/chat/chat-attachment-bar.tsx
|
|
10515
|
-
import { Fragment as
|
|
10531
|
+
import { Fragment as Fragment17, jsx as jsx63, jsxs as jsxs49 } from "react/jsx-runtime";
|
|
10516
10532
|
var CHAT_ATTACHMENT_MIME_TYPES = [
|
|
10517
10533
|
"image/jpeg",
|
|
10518
10534
|
"image/png",
|
|
@@ -10542,7 +10558,7 @@ function ChatAttachmentAddButton({
|
|
|
10542
10558
|
if (!canAddMore) return;
|
|
10543
10559
|
fileInputRef.current?.click();
|
|
10544
10560
|
};
|
|
10545
|
-
return /* @__PURE__ */ jsxs49(
|
|
10561
|
+
return /* @__PURE__ */ jsxs49(Fragment17, { children: [
|
|
10546
10562
|
/* @__PURE__ */ jsx63(
|
|
10547
10563
|
"input",
|
|
10548
10564
|
{
|
|
@@ -11089,11 +11105,11 @@ function ChatComposer({
|
|
|
11089
11105
|
}
|
|
11090
11106
|
|
|
11091
11107
|
// src/components/chat/chat-archive-page.tsx
|
|
11092
|
-
import { Fragment as
|
|
11108
|
+
import { Fragment as Fragment18, jsx as jsx68, jsxs as jsxs53 } from "react/jsx-runtime";
|
|
11093
11109
|
function ChatArchivePage(props) {
|
|
11094
11110
|
const { dialogs, onSelectDialog, isLoading = false, isFetching = false, hasMore = false, onLoadMore } = props;
|
|
11095
11111
|
const suppressEmptyStateWhileFetching = isFetching;
|
|
11096
|
-
return /* @__PURE__ */ jsxs53(
|
|
11112
|
+
return /* @__PURE__ */ jsxs53(Fragment18, { children: [
|
|
11097
11113
|
!props.embedded && /* @__PURE__ */ jsx68(
|
|
11098
11114
|
ChatPanelHeaderMobile,
|
|
11099
11115
|
{
|
|
@@ -11199,7 +11215,7 @@ var ChatSidebarSkeleton = forwardRef23(
|
|
|
11199
11215
|
ChatSidebarSkeleton.displayName = "ChatSidebarSkeleton";
|
|
11200
11216
|
|
|
11201
11217
|
// src/components/chat/chat-sidebar.tsx
|
|
11202
|
-
import { Fragment as
|
|
11218
|
+
import { Fragment as Fragment19, jsx as jsx70, jsxs as jsxs55 } from "react/jsx-runtime";
|
|
11203
11219
|
var DialogListItem = forwardRef24(
|
|
11204
11220
|
({ className, dialog, isActive, onDialogSelect, onClick, ...props }, ref) => {
|
|
11205
11221
|
const handleClick = (e) => {
|
|
@@ -11336,7 +11352,7 @@ var ChatSidebar = forwardRef24(
|
|
|
11336
11352
|
},
|
|
11337
11353
|
dialog.id
|
|
11338
11354
|
)),
|
|
11339
|
-
hasNextPage && /* @__PURE__ */ jsx70("div", { ref: loadMoreRef, children: isFetchingNextPage && /* @__PURE__ */ jsxs55(
|
|
11355
|
+
hasNextPage && /* @__PURE__ */ jsx70("div", { ref: loadMoreRef, children: isFetchingNextPage && /* @__PURE__ */ jsxs55(Fragment19, { children: [
|
|
11340
11356
|
/* @__PURE__ */ jsx70(DialogListItemSkeleton, {}),
|
|
11341
11357
|
/* @__PURE__ */ jsx70(DialogListItemSkeleton, {}),
|
|
11342
11358
|
/* @__PURE__ */ jsx70(DialogListItemSkeleton, {})
|
|
@@ -11581,7 +11597,7 @@ function captionsEntityTypeForDocType(docType) {
|
|
|
11581
11597
|
}
|
|
11582
11598
|
|
|
11583
11599
|
// src/components/layout/page-heading.tsx
|
|
11584
|
-
import { Fragment as
|
|
11600
|
+
import { Fragment as Fragment20, jsx as jsx73, jsxs as jsxs56 } from "react/jsx-runtime";
|
|
11585
11601
|
var PAGE_HEADING_CLASS = "text-h1 text-ods-text-primary";
|
|
11586
11602
|
var SECTION_HEADING_CLASS = "text-h2 text-ods-text-primary";
|
|
11587
11603
|
var DESCRIPTION_CLASS = "mt-6 max-w-[640px] font-body text-[16px] md:text-[18px] leading-[24px] md:leading-[28px] text-ods-text-secondary";
|
|
@@ -11595,7 +11611,7 @@ function PageHeading({
|
|
|
11595
11611
|
const headingClass = className ? `${PAGE_HEADING_CLASS} ${className}` : PAGE_HEADING_CLASS;
|
|
11596
11612
|
const descClass = descriptionClassName ? `${DESCRIPTION_CLASS} ${descriptionClassName}` : DESCRIPTION_CLASS;
|
|
11597
11613
|
const hasDescription = description != null && description !== "" && typeof description !== "boolean";
|
|
11598
|
-
return /* @__PURE__ */ jsxs56(
|
|
11614
|
+
return /* @__PURE__ */ jsxs56(Fragment20, { children: [
|
|
11599
11615
|
/* @__PURE__ */ jsx73(Tag2, { className: headingClass, children }),
|
|
11600
11616
|
hasDescription && /* @__PURE__ */ jsx73("p", { className: descClass, children: description })
|
|
11601
11617
|
] });
|
|
@@ -12776,7 +12792,7 @@ function CardHitLayer({
|
|
|
12776
12792
|
|
|
12777
12793
|
// src/components/features/cards-strip.tsx
|
|
12778
12794
|
import React5, { useCallback as useCallback12, useEffect as useEffect20, useMemo as useMemo21, useRef as useRef16, useState as useState26 } from "react";
|
|
12779
|
-
import { Fragment as
|
|
12795
|
+
import { Fragment as Fragment21, jsx as jsx79, jsxs as jsxs59 } from "react/jsx-runtime";
|
|
12780
12796
|
var TRACK_GAP_PX = 16;
|
|
12781
12797
|
var CHEVRON_SUPPRESS_MS = 4e3;
|
|
12782
12798
|
var USER_SCROLL_SUPPRESS_MS = 3e3;
|
|
@@ -13153,7 +13169,7 @@ function CardsStrip(props) {
|
|
|
13153
13169
|
) })
|
|
13154
13170
|
}
|
|
13155
13171
|
),
|
|
13156
|
-
showChevrons && overflows && /* @__PURE__ */ jsxs59(
|
|
13172
|
+
showChevrons && overflows && /* @__PURE__ */ jsxs59(Fragment21, { children: [
|
|
13157
13173
|
/* @__PURE__ */ jsx79(
|
|
13158
13174
|
Button,
|
|
13159
13175
|
{
|
|
@@ -13187,7 +13203,7 @@ function CardsStrip(props) {
|
|
|
13187
13203
|
|
|
13188
13204
|
// src/components/features/video-hover-preview.tsx
|
|
13189
13205
|
import { useEffect as useEffect21, useRef as useRef17, useState as useState27 } from "react";
|
|
13190
|
-
import { Fragment as
|
|
13206
|
+
import { Fragment as Fragment22, jsx as jsx80, jsxs as jsxs60 } from "react/jsx-runtime";
|
|
13191
13207
|
function VideoHoverPreviewSurface({
|
|
13192
13208
|
url,
|
|
13193
13209
|
posterUrl = null,
|
|
@@ -13226,7 +13242,7 @@ function VideoHoverPreviewSurface({
|
|
|
13226
13242
|
const showMedia = continuation || (gateControlled ? playerMounted : isNear);
|
|
13227
13243
|
const { src: posterSrc, onError: onPosterError } = useCoverImageFallback(posterUrl);
|
|
13228
13244
|
const facadeSkipped = preload === "none" && !posterSrc;
|
|
13229
|
-
return /* @__PURE__ */ jsx80("div", { ref: rootElRef, className: cn("absolute inset-0", className), inert: isClone || void 0, children: showMedia ? /* @__PURE__ */ jsxs60(
|
|
13245
|
+
return /* @__PURE__ */ jsx80("div", { ref: rootElRef, className: cn("absolute inset-0", className), inert: isClone || void 0, children: showMedia ? /* @__PURE__ */ jsxs60(Fragment22, { children: [
|
|
13230
13246
|
posterSrc ? /* @__PURE__ */ jsx80(
|
|
13231
13247
|
next_image_default,
|
|
13232
13248
|
{
|
|
@@ -13275,7 +13291,7 @@ function VideoHoverPreviewSurface({
|
|
|
13275
13291
|
}
|
|
13276
13292
|
|
|
13277
13293
|
// src/components/features/video-ratio-tabs.tsx
|
|
13278
|
-
import { Fragment as
|
|
13294
|
+
import { Fragment as Fragment23, jsx as jsx81, jsxs as jsxs61 } from "react/jsx-runtime";
|
|
13279
13295
|
var TAB_TRIGGER_CLASS = "rounded-none border-b-2 border-transparent data-[state=active]:border-ods-accent data-[state=active]:bg-transparent data-[state=active]:shadow-none px-4 py-2 text-h6 text-ods-text-secondary data-[state=active]:text-ods-text-primary";
|
|
13280
13296
|
var RATIO_GRID_CLASS = {
|
|
13281
13297
|
portrait: "grid grid-cols-2 md:grid-cols-3 gap-4",
|
|
@@ -13296,7 +13312,7 @@ function RatioTabs({ groups, defaultTab, className = "" }) {
|
|
|
13296
13312
|
const activeTabs = RATIO_TAB_CONFIG.filter((t) => groups[t.key].count > 0);
|
|
13297
13313
|
if (activeTabs.length <= 1) {
|
|
13298
13314
|
const active = activeTabs[0];
|
|
13299
|
-
return active ? /* @__PURE__ */ jsx81(
|
|
13315
|
+
return active ? /* @__PURE__ */ jsx81(Fragment23, { children: groups[active.key].render() }) : null;
|
|
13300
13316
|
}
|
|
13301
13317
|
const firstTab = defaultTab && groups[defaultTab].count > 0 ? defaultTab : activeTabs[0].key;
|
|
13302
13318
|
return /* @__PURE__ */ jsxs61(Tabs, { defaultValue: firstTab, className: `w-full ${className}`, children: [
|
|
@@ -13339,7 +13355,7 @@ function groupByAspectRatio(items, getAspectRatio) {
|
|
|
13339
13355
|
}
|
|
13340
13356
|
|
|
13341
13357
|
// src/components/features/video-bites-strip.tsx
|
|
13342
|
-
import { Fragment as
|
|
13358
|
+
import { Fragment as Fragment24, jsx as jsx82, jsxs as jsxs62 } from "react/jsx-runtime";
|
|
13343
13359
|
function VideoBitesStrip({
|
|
13344
13360
|
bites,
|
|
13345
13361
|
title = DEFAULT_VIDEO_BITES_TITLE,
|
|
@@ -13452,7 +13468,7 @@ function VideoBiteCard({
|
|
|
13452
13468
|
if (isTouch && !isActive) activate();
|
|
13453
13469
|
};
|
|
13454
13470
|
const titleClass = "text-h6 text-ods-text-primary";
|
|
13455
|
-
const overlayContent = /* @__PURE__ */ jsxs62(
|
|
13471
|
+
const overlayContent = /* @__PURE__ */ jsxs62(Fragment24, { children: [
|
|
13456
13472
|
titleEditable ? (
|
|
13457
13473
|
// Textarea, not input: the public title wraps to two lines
|
|
13458
13474
|
// (line-clamp-2) and the editor must render identically. rows=1 +
|
|
@@ -13524,7 +13540,7 @@ function VideoBiteCard({
|
|
|
13524
13540
|
// the bottom strip, so the card centre (where the play glyph sits) was
|
|
13525
13541
|
// not clickable and showed no pointer cursor even though the glyph
|
|
13526
13542
|
// accented on hover. One interactive element, no a11y duplication.
|
|
13527
|
-
/* @__PURE__ */ jsxs62(
|
|
13543
|
+
/* @__PURE__ */ jsxs62(Fragment24, { children: [
|
|
13528
13544
|
/* @__PURE__ */ jsx82(
|
|
13529
13545
|
CardHitLayer,
|
|
13530
13546
|
{
|
|
@@ -13570,7 +13586,7 @@ function VideoBiteCard({
|
|
|
13570
13586
|
}
|
|
13571
13587
|
|
|
13572
13588
|
// src/components/features/entity-video-section.tsx
|
|
13573
|
-
import { Fragment as
|
|
13589
|
+
import { Fragment as Fragment25, jsx as jsx83, jsxs as jsxs63 } from "react/jsx-runtime";
|
|
13574
13590
|
function EntityVideoSection({
|
|
13575
13591
|
mainVideoUrl,
|
|
13576
13592
|
youtubeUrl,
|
|
@@ -13606,7 +13622,7 @@ function EntityVideoSection({
|
|
|
13606
13622
|
}
|
|
13607
13623
|
const fullVideoUrl = youtubeUrl || mainVideoUrl || null;
|
|
13608
13624
|
const fullVideoKind = youtubeUrl ? "youtube" : "auto";
|
|
13609
|
-
return /* @__PURE__ */ jsxs63(
|
|
13625
|
+
return /* @__PURE__ */ jsxs63(Fragment25, { children: [
|
|
13610
13626
|
hasVideo && (fullVideoUrl && hasHighlight ? /* @__PURE__ */ jsxs63(Tabs, { defaultValue: "full-video", className: "w-full", children: [
|
|
13611
13627
|
/* @__PURE__ */ jsxs63(TabsList, { className: "inline-flex h-auto justify-start gap-0 rounded-none bg-transparent p-0", children: [
|
|
13612
13628
|
/* @__PURE__ */ jsx83(
|
|
@@ -13719,7 +13735,7 @@ function ChatVideoEntityCard({ chatRef }) {
|
|
|
13719
13735
|
// src/components/chat/entity-cards/github-activity-card.tsx
|
|
13720
13736
|
import { GitPullRequest, Eye, ExternalLink } from "lucide-react";
|
|
13721
13737
|
import React6 from "react";
|
|
13722
|
-
import { Fragment as
|
|
13738
|
+
import { Fragment as Fragment26, jsx as jsx85, jsxs as jsxs64 } from "react/jsx-runtime";
|
|
13723
13739
|
function parseRepoFromUrl(url) {
|
|
13724
13740
|
if (!url) return null;
|
|
13725
13741
|
try {
|
|
@@ -13854,7 +13870,7 @@ function GitHubActivityCard({ item, variant = "compact", className, anchorProps
|
|
|
13854
13870
|
/* @__PURE__ */ jsx85("span", { className: "whitespace-nowrap", children: dateText }, "date")
|
|
13855
13871
|
);
|
|
13856
13872
|
const href = safeHref(item.url);
|
|
13857
|
-
const body = /* @__PURE__ */ jsxs64(
|
|
13873
|
+
const body = /* @__PURE__ */ jsxs64(Fragment26, { children: [
|
|
13858
13874
|
/* @__PURE__ */ jsx85("span", { className: COMPACT_CARD_ICON_SLOT, children: kindIcon(kind, "h-5 w-5") }),
|
|
13859
13875
|
/* @__PURE__ */ jsxs64("span", { className: COMPACT_CARD_TEXT_COL, children: [
|
|
13860
13876
|
/* @__PURE__ */ jsxs64("span", { className: `${COMPACT_CARD_TITLE_ROW} flex-nowrap gap-1.5`, children: [
|
|
@@ -13903,7 +13919,7 @@ function GitHubActivityCardSkeleton({
|
|
|
13903
13919
|
// src/components/chat/entity-cards/slack-message-card.tsx
|
|
13904
13920
|
import { ExternalLink as ExternalLink2, Hash } from "lucide-react";
|
|
13905
13921
|
import React7 from "react";
|
|
13906
|
-
import { Fragment as
|
|
13922
|
+
import { Fragment as Fragment27, jsx as jsx86, jsxs as jsxs65 } from "react/jsx-runtime";
|
|
13907
13923
|
function parseChannelFromUrl(url) {
|
|
13908
13924
|
if (!url) return null;
|
|
13909
13925
|
try {
|
|
@@ -13945,7 +13961,7 @@ function SlackMessageCard({ item, variant = "compact", className, anchorProps })
|
|
|
13945
13961
|
/* @__PURE__ */ jsx86("span", { className: "whitespace-nowrap", children: dateText }, "date")
|
|
13946
13962
|
);
|
|
13947
13963
|
const href = safeHref(item.url);
|
|
13948
|
-
const body = /* @__PURE__ */ jsxs65(
|
|
13964
|
+
const body = /* @__PURE__ */ jsxs65(Fragment27, { children: [
|
|
13949
13965
|
/* @__PURE__ */ jsx86("span", { className: COMPACT_CARD_ICON_SLOT, children: /* @__PURE__ */ jsx86(SlackIcon, { className: "h-5 w-5" }) }),
|
|
13950
13966
|
/* @__PURE__ */ jsxs65("span", { className: COMPACT_CARD_TEXT_COL, children: [
|
|
13951
13967
|
/* @__PURE__ */ jsx86("span", { className: COMPACT_CARD_TITLE_ROW, children: /* @__PURE__ */ jsx86("span", { className: COMPACT_CARD_TITLE, children: item.title }) }),
|
|
@@ -13989,7 +14005,7 @@ function SlackMessageCardSkeleton({
|
|
|
13989
14005
|
// src/components/chat/entity-cards/hubspot-ticket-card.tsx
|
|
13990
14006
|
import { ExternalLink as ExternalLink3 } from "lucide-react";
|
|
13991
14007
|
import React8 from "react";
|
|
13992
|
-
import { Fragment as
|
|
14008
|
+
import { Fragment as Fragment28, jsx as jsx87, jsxs as jsxs66 } from "react/jsx-runtime";
|
|
13993
14009
|
function formatToken(token) {
|
|
13994
14010
|
if (!token) return null;
|
|
13995
14011
|
const lower = token.toLowerCase().replace(/_/g, " ");
|
|
@@ -14031,7 +14047,7 @@ function HubspotTicketCard({ item, variant = "compact", className, anchorProps }
|
|
|
14031
14047
|
/* @__PURE__ */ jsx87("span", { className: "whitespace-nowrap", children: dateText }, "date")
|
|
14032
14048
|
);
|
|
14033
14049
|
const href = safeHref(item.url);
|
|
14034
|
-
const body = /* @__PURE__ */ jsxs66(
|
|
14050
|
+
const body = /* @__PURE__ */ jsxs66(Fragment28, { children: [
|
|
14035
14051
|
/* @__PURE__ */ jsxs66("span", { className: COMPACT_CARD_TEXT_COL, children: [
|
|
14036
14052
|
/* @__PURE__ */ jsxs66("span", { className: "flex min-w-0 flex-wrap items-center gap-1.5", children: [
|
|
14037
14053
|
/* @__PURE__ */ jsx87("span", { className: `${COMPACT_CARD_TITLE} min-w-0 shrink`, children: item.title }),
|
|
@@ -14105,9 +14121,9 @@ function HubspotTicketCardSkeleton({
|
|
|
14105
14121
|
|
|
14106
14122
|
// src/components/chat/entity-cards/data-room-doc-card.tsx
|
|
14107
14123
|
import { ExternalLink as ExternalLink4 } from "lucide-react";
|
|
14108
|
-
import { Fragment as
|
|
14124
|
+
import { Fragment as Fragment29, jsx as jsx88, jsxs as jsxs67 } from "react/jsx-runtime";
|
|
14109
14125
|
function DataRoomDocCard({ item, className, badgeText, anchorProps }) {
|
|
14110
|
-
const body = /* @__PURE__ */ jsxs67(
|
|
14126
|
+
const body = /* @__PURE__ */ jsxs67(Fragment29, { children: [
|
|
14111
14127
|
/* @__PURE__ */ jsxs67("span", { className: COMPACT_CARD_TEXT_COL, children: [
|
|
14112
14128
|
/* @__PURE__ */ jsxs67("span", { className: "flex min-w-0 flex-wrap items-center gap-1.5", children: [
|
|
14113
14129
|
/* @__PURE__ */ jsx88("span", { className: `${COMPACT_CARD_TITLE} min-w-0 shrink`, children: item.title }),
|
|
@@ -14145,10 +14161,10 @@ function DataRoomDocCardSkeleton({ className }) {
|
|
|
14145
14161
|
|
|
14146
14162
|
// src/components/chat/entity-cards/campaign-card-admin.tsx
|
|
14147
14163
|
import { Megaphone as Megaphone3 } from "lucide-react";
|
|
14148
|
-
import { Fragment as
|
|
14164
|
+
import { Fragment as Fragment30, jsx as jsx89, jsxs as jsxs68 } from "react/jsx-runtime";
|
|
14149
14165
|
function CampaignCardAdmin({ campaign, className, anchorProps }) {
|
|
14150
14166
|
const goalsCount = campaign.goals?.length || 0;
|
|
14151
|
-
const innerChildren = /* @__PURE__ */ jsxs68(
|
|
14167
|
+
const innerChildren = /* @__PURE__ */ jsxs68(Fragment30, { children: [
|
|
14152
14168
|
/* @__PURE__ */ jsx89("span", { className: COMPACT_CARD_ICON_SLOT, children: /* @__PURE__ */ jsx89(Megaphone3, { className: "h-5 w-5" }) }),
|
|
14153
14169
|
/* @__PURE__ */ jsxs68("span", { className: COMPACT_CARD_TEXT_COL, children: [
|
|
14154
14170
|
/* @__PURE__ */ jsx89("span", { className: COMPACT_CARD_TITLE_ROW, children: /* @__PURE__ */ jsx89("span", { className: COMPACT_CARD_TITLE, children: campaign.name }) }),
|
|
@@ -14178,11 +14194,11 @@ function CampaignCardAdminSkeleton({ className }) {
|
|
|
14178
14194
|
|
|
14179
14195
|
// src/components/chat/entity-cards/generic-entity-card.tsx
|
|
14180
14196
|
import { ExternalLink as ExternalLink5 } from "lucide-react";
|
|
14181
|
-
import { Fragment as
|
|
14197
|
+
import { Fragment as Fragment31, jsx as jsx90, jsxs as jsxs69 } from "react/jsx-runtime";
|
|
14182
14198
|
function GenericEntityCard({ item, className, anchorProps }) {
|
|
14183
14199
|
const href = safeHref(item.url);
|
|
14184
14200
|
const dateText = formatDateUTC(item.dateUpdated, { fallback: "", timezone: "local" });
|
|
14185
|
-
const body = /* @__PURE__ */ jsxs69(
|
|
14201
|
+
const body = /* @__PURE__ */ jsxs69(Fragment31, { children: [
|
|
14186
14202
|
/* @__PURE__ */ jsxs69("span", { className: COMPACT_CARD_TEXT_COL, children: [
|
|
14187
14203
|
/* @__PURE__ */ jsxs69("span", { className: "flex min-w-0 flex-wrap items-center gap-1.5", children: [
|
|
14188
14204
|
/* @__PURE__ */ jsx90("span", { className: `${COMPACT_CARD_TITLE} min-w-0 shrink`, children: item.title }),
|
|
@@ -14235,6 +14251,190 @@ function GenericEntityCardSkeleton({ className }) {
|
|
|
14235
14251
|
// src/components/chat/entity-cards/dispatch.tsx
|
|
14236
14252
|
import React9 from "react";
|
|
14237
14253
|
|
|
14254
|
+
// src/chat-protocol/source-metadata.ts
|
|
14255
|
+
var CARD_REFERENCE = /^\[card:\/\/([a-zA-Z0-9_-]+):([a-zA-Z0-9_-]+)\]$/;
|
|
14256
|
+
var SOURCE_METADATA_MATCHED = "sourceMetadataMatched";
|
|
14257
|
+
function isSourceMetadataCardRef(ref) {
|
|
14258
|
+
return ref.metadata?.[SOURCE_METADATA_MATCHED] === true;
|
|
14259
|
+
}
|
|
14260
|
+
function requiredString(value) {
|
|
14261
|
+
if (typeof value !== "string") return null;
|
|
14262
|
+
const normalized = value.trim();
|
|
14263
|
+
return normalized ? normalized : null;
|
|
14264
|
+
}
|
|
14265
|
+
function optionalString(value) {
|
|
14266
|
+
return requiredString(value) ?? void 0;
|
|
14267
|
+
}
|
|
14268
|
+
function httpsUrl(value) {
|
|
14269
|
+
const candidate = optionalString(value);
|
|
14270
|
+
if (!candidate) return void 0;
|
|
14271
|
+
try {
|
|
14272
|
+
return new URL(candidate).protocol === "https:" ? candidate : void 0;
|
|
14273
|
+
} catch {
|
|
14274
|
+
return void 0;
|
|
14275
|
+
}
|
|
14276
|
+
}
|
|
14277
|
+
function youtubeId(value) {
|
|
14278
|
+
const candidate = optionalString(value);
|
|
14279
|
+
if (!candidate) return void 0;
|
|
14280
|
+
if (/^[A-Za-z0-9_-]{11}$/.test(candidate)) return candidate;
|
|
14281
|
+
const url = httpsUrl(candidate);
|
|
14282
|
+
if (!url) return void 0;
|
|
14283
|
+
const parsed = new URL(url);
|
|
14284
|
+
const hostname = parsed.hostname.toLowerCase();
|
|
14285
|
+
const youtubeHost = hostname === "youtu.be" || hostname === "youtube.com" || hostname.endsWith(".youtube.com");
|
|
14286
|
+
if (!youtubeHost) return void 0;
|
|
14287
|
+
const pathId = hostname === "youtu.be" ? parsed.pathname.split("/").filter(Boolean)[0] : parsed.pathname.match(/^\/(?:embed|v|shorts)\/([A-Za-z0-9_-]{11})(?:\/|$)/)?.[1];
|
|
14288
|
+
const id = pathId ?? parsed.searchParams.get("v") ?? void 0;
|
|
14289
|
+
return id && /^[A-Za-z0-9_-]{11}$/.test(id) ? id : void 0;
|
|
14290
|
+
}
|
|
14291
|
+
function nullableString(value) {
|
|
14292
|
+
return value === null ? null : optionalString(value);
|
|
14293
|
+
}
|
|
14294
|
+
function normalizeSourceItems(value) {
|
|
14295
|
+
if (!Array.isArray(value)) return void 0;
|
|
14296
|
+
const items = value.flatMap((candidate) => {
|
|
14297
|
+
if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) return [];
|
|
14298
|
+
const item = candidate;
|
|
14299
|
+
const id = requiredString(item.id);
|
|
14300
|
+
const documentType = requiredString(item.documentType);
|
|
14301
|
+
const name = requiredString(item.name);
|
|
14302
|
+
if (!id || !documentType || !name) return [];
|
|
14303
|
+
const externalUrl = httpsUrl(item.externalUrl);
|
|
14304
|
+
const targetPlatform = nullableString(item.targetPlatform);
|
|
14305
|
+
const path = nullableString(item.path);
|
|
14306
|
+
return [
|
|
14307
|
+
{
|
|
14308
|
+
id,
|
|
14309
|
+
documentType,
|
|
14310
|
+
name,
|
|
14311
|
+
...externalUrl ? { externalUrl } : {},
|
|
14312
|
+
...targetPlatform !== void 0 ? { targetPlatform } : {},
|
|
14313
|
+
...path !== void 0 ? { path } : {}
|
|
14314
|
+
}
|
|
14315
|
+
];
|
|
14316
|
+
});
|
|
14317
|
+
return items.length > 0 ? items : void 0;
|
|
14318
|
+
}
|
|
14319
|
+
function normalizeSources(value) {
|
|
14320
|
+
if (!Array.isArray(value)) return [];
|
|
14321
|
+
const seen = /* @__PURE__ */ new Set();
|
|
14322
|
+
const sources = [];
|
|
14323
|
+
for (const candidate of value) {
|
|
14324
|
+
if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) continue;
|
|
14325
|
+
const source = candidate;
|
|
14326
|
+
const index = source.index;
|
|
14327
|
+
const name = requiredString(source.name);
|
|
14328
|
+
const path = requiredString(source.path);
|
|
14329
|
+
const documentType = requiredString(source.documentType);
|
|
14330
|
+
const validIndex = typeof index === "number" && Number.isFinite(index) && Number.isInteger(index) && index > 0 && !seen.has(index);
|
|
14331
|
+
if (!validIndex || !name || !path || !documentType) continue;
|
|
14332
|
+
seen.add(index);
|
|
14333
|
+
const externalUrl = httpsUrl(source.externalUrl);
|
|
14334
|
+
const targetPlatform = nullableString(source.targetPlatform);
|
|
14335
|
+
const id = optionalString(source.id);
|
|
14336
|
+
const sourceRepo = optionalString(source.sourceRepo);
|
|
14337
|
+
const label = optionalString(source.label);
|
|
14338
|
+
const items = normalizeSourceItems(source.items);
|
|
14339
|
+
sources.push({
|
|
14340
|
+
index,
|
|
14341
|
+
name,
|
|
14342
|
+
path,
|
|
14343
|
+
documentType,
|
|
14344
|
+
...externalUrl ? { externalUrl } : {},
|
|
14345
|
+
...targetPlatform !== void 0 ? { targetPlatform } : {},
|
|
14346
|
+
...id ? { id } : {},
|
|
14347
|
+
...sourceRepo ? { sourceRepo } : {},
|
|
14348
|
+
...label ? { label } : {},
|
|
14349
|
+
...items ? { items } : {}
|
|
14350
|
+
});
|
|
14351
|
+
}
|
|
14352
|
+
return sources;
|
|
14353
|
+
}
|
|
14354
|
+
function normalizeVideoMetadata(value) {
|
|
14355
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
14356
|
+
const input = value;
|
|
14357
|
+
const metadata = {};
|
|
14358
|
+
for (const key of ["videoUrl", "highlightVideoUrl", "videoPoster", "highlightVideoPoster"]) {
|
|
14359
|
+
const url = httpsUrl(input[key]);
|
|
14360
|
+
if (url) metadata[key] = url;
|
|
14361
|
+
}
|
|
14362
|
+
const id = youtubeId(input.youtubeUrl);
|
|
14363
|
+
if (id) metadata.youtubeUrl = id;
|
|
14364
|
+
return metadata;
|
|
14365
|
+
}
|
|
14366
|
+
function normalizeVideos(value) {
|
|
14367
|
+
if (!Array.isArray(value)) return [];
|
|
14368
|
+
return value.flatMap((candidate) => {
|
|
14369
|
+
if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) return [];
|
|
14370
|
+
const video = candidate;
|
|
14371
|
+
const match = typeof video.ref === "string" ? CARD_REFERENCE.exec(video.ref) : null;
|
|
14372
|
+
if (!match || match[1] !== "video") return [];
|
|
14373
|
+
const id = match[2];
|
|
14374
|
+
const title = optionalString(video.title) ?? id;
|
|
14375
|
+
const url = httpsUrl(video.url) ?? null;
|
|
14376
|
+
const sourceRepo = optionalString(video.sourceRepo);
|
|
14377
|
+
const metadata = normalizeVideoMetadata(video.metadata);
|
|
14378
|
+
if (url) {
|
|
14379
|
+
const idFromUrl = youtubeId(url);
|
|
14380
|
+
if (idFromUrl) {
|
|
14381
|
+
metadata.youtubeUrl = idFromUrl;
|
|
14382
|
+
delete metadata.videoUrl;
|
|
14383
|
+
} else {
|
|
14384
|
+
metadata.videoUrl = url;
|
|
14385
|
+
delete metadata.youtubeUrl;
|
|
14386
|
+
}
|
|
14387
|
+
}
|
|
14388
|
+
return [
|
|
14389
|
+
{
|
|
14390
|
+
type: "video",
|
|
14391
|
+
id,
|
|
14392
|
+
title,
|
|
14393
|
+
url,
|
|
14394
|
+
...sourceRepo ? { sourceRepo } : {},
|
|
14395
|
+
...Object.keys(metadata).length > 0 ? { metadata } : {}
|
|
14396
|
+
}
|
|
14397
|
+
];
|
|
14398
|
+
});
|
|
14399
|
+
}
|
|
14400
|
+
function normalizeCards(value, sources) {
|
|
14401
|
+
if (!Array.isArray(value)) return [];
|
|
14402
|
+
return value.flatMap((candidate) => {
|
|
14403
|
+
if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) return [];
|
|
14404
|
+
const card = candidate;
|
|
14405
|
+
const match = typeof card.ref === "string" ? CARD_REFERENCE.exec(card.ref) : null;
|
|
14406
|
+
if (!match || match[1] === "video") return [];
|
|
14407
|
+
const type = requiredString(card.entityType);
|
|
14408
|
+
const id = requiredString(card.entityId);
|
|
14409
|
+
if (!type || !id || type !== match[1] || id !== match[2]) return [];
|
|
14410
|
+
const source = sources.find((item) => item.id === id && item.documentType === type);
|
|
14411
|
+
const ref = {
|
|
14412
|
+
type,
|
|
14413
|
+
id,
|
|
14414
|
+
title: source?.name ?? id,
|
|
14415
|
+
url: source?.externalUrl ?? null,
|
|
14416
|
+
...source?.sourceRepo ? { sourceRepo: source.sourceRepo } : {},
|
|
14417
|
+
...source?.targetPlatform !== void 0 ? { targetPlatform: source.targetPlatform } : {},
|
|
14418
|
+
...source?.path ? { metadata: { path: source.path, [SOURCE_METADATA_MATCHED]: true } } : {}
|
|
14419
|
+
};
|
|
14420
|
+
return [ref];
|
|
14421
|
+
});
|
|
14422
|
+
}
|
|
14423
|
+
function sourceMetadataEvent(payload) {
|
|
14424
|
+
if (!payload || typeof payload !== "object" || Array.isArray(payload)) return null;
|
|
14425
|
+
const metadata = payload;
|
|
14426
|
+
const sources = normalizeSources(metadata.sources);
|
|
14427
|
+
const refs = [...normalizeVideos(metadata.videos), ...normalizeCards(metadata.cards, sources)];
|
|
14428
|
+
const refsByIdentity = /* @__PURE__ */ new Map();
|
|
14429
|
+
refs.forEach((ref) => {
|
|
14430
|
+
const identity = `${ref.type}:${ref.id}`;
|
|
14431
|
+
if (!refsByIdentity.has(identity)) refsByIdentity.set(identity, ref);
|
|
14432
|
+
});
|
|
14433
|
+
const uniqueRefs = Array.from(refsByIdentity.values());
|
|
14434
|
+
if (sources.length === 0 && uniqueRefs.length === 0) return null;
|
|
14435
|
+
return { type: "sources", sources, ...uniqueRefs.length > 0 ? { refs: uniqueRefs } : {} };
|
|
14436
|
+
}
|
|
14437
|
+
|
|
14238
14438
|
// src/utils/faq-anchor.ts
|
|
14239
14439
|
function faqSectionSlug(section) {
|
|
14240
14440
|
return "faq-" + section.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
@@ -14295,7 +14495,7 @@ function useChatCardItem(type, id) {
|
|
|
14295
14495
|
}
|
|
14296
14496
|
|
|
14297
14497
|
// src/components/chat/mingo-info-card.tsx
|
|
14298
|
-
import { Fragment as
|
|
14498
|
+
import { Fragment as Fragment32, jsx as jsx91, jsxs as jsxs70 } from "react/jsx-runtime";
|
|
14299
14499
|
function CardMedia({ imageSrc, imageAlt, icon }) {
|
|
14300
14500
|
if (imageSrc) {
|
|
14301
14501
|
return /* @__PURE__ */ jsxs70("span", { className: "relative block size-10 shrink-0", children: [
|
|
@@ -14358,7 +14558,7 @@ function MingoInfoCard({
|
|
|
14358
14558
|
const hasMenu = !!menuGroups && menuGroups.length > 0;
|
|
14359
14559
|
const isAnchor = !!anchorProps;
|
|
14360
14560
|
const isInteractive = isAnchor || !!onClick;
|
|
14361
|
-
const content = /* @__PURE__ */ jsxs70(
|
|
14561
|
+
const content = /* @__PURE__ */ jsxs70(Fragment32, { children: [
|
|
14362
14562
|
hasMedia && /* @__PURE__ */ jsx91(CardMedia, { imageSrc, imageAlt, icon }),
|
|
14363
14563
|
/* @__PURE__ */ jsxs70("span", { className: "flex min-w-0 flex-1 flex-col justify-center", children: [
|
|
14364
14564
|
/* @__PURE__ */ jsx91("span", { className: "truncate text-ods-text-primary text-h4", children: title }),
|
|
@@ -14715,7 +14915,7 @@ function DeletedDataCard({ title, entityLabel, recoveryNote, className }) {
|
|
|
14715
14915
|
}
|
|
14716
14916
|
|
|
14717
14917
|
// src/components/chat/entity-cards/dispatch.tsx
|
|
14718
|
-
import { Fragment as
|
|
14918
|
+
import { Fragment as Fragment33, jsx as jsx93, jsxs as jsxs72 } from "react/jsx-runtime";
|
|
14719
14919
|
function githubKindIcon(kind) {
|
|
14720
14920
|
switch (kind) {
|
|
14721
14921
|
case "pull_request":
|
|
@@ -14814,6 +15014,14 @@ function hubspotStatusToVariant(status) {
|
|
|
14814
15014
|
if (s === "OPEN") return "warning";
|
|
14815
15015
|
return "grey";
|
|
14816
15016
|
}
|
|
15017
|
+
function validatedHttpsUrl(value) {
|
|
15018
|
+
if (typeof value !== "string") return null;
|
|
15019
|
+
try {
|
|
15020
|
+
return new URL(value).protocol === "https:" ? value : null;
|
|
15021
|
+
} catch {
|
|
15022
|
+
return null;
|
|
15023
|
+
}
|
|
15024
|
+
}
|
|
14817
15025
|
function decodeVideoMarkerId(id) {
|
|
14818
15026
|
const mux = id.match(/^mux-([A-Za-z0-9_-]+)$/);
|
|
14819
15027
|
if (mux) {
|
|
@@ -14826,8 +15034,8 @@ function decodeVideoMarkerId(id) {
|
|
|
14826
15034
|
try {
|
|
14827
15035
|
const b64 = mp4[1].replace(/-/g, "+").replace(/_/g, "/");
|
|
14828
15036
|
const url = atob(b64);
|
|
14829
|
-
|
|
14830
|
-
return { videoUrl:
|
|
15037
|
+
const safeUrl = validatedHttpsUrl(url);
|
|
15038
|
+
return safeUrl ? { videoUrl: safeUrl } : null;
|
|
14831
15039
|
} catch {
|
|
14832
15040
|
return null;
|
|
14833
15041
|
}
|
|
@@ -14835,6 +15043,26 @@ function decodeVideoMarkerId(id) {
|
|
|
14835
15043
|
if (/^[A-Za-z0-9_-]{11}$/.test(id)) return { youtubeUrl: id };
|
|
14836
15044
|
return null;
|
|
14837
15045
|
}
|
|
15046
|
+
function validatedVideoMetadata(chatRef) {
|
|
15047
|
+
const input = chatRef.metadata ?? {};
|
|
15048
|
+
const metadata = {};
|
|
15049
|
+
for (const key of ["videoUrl", "highlightVideoUrl", "videoPoster", "highlightVideoPoster"]) {
|
|
15050
|
+
const url = validatedHttpsUrl(input[key]);
|
|
15051
|
+
if (url) metadata[key] = url;
|
|
15052
|
+
}
|
|
15053
|
+
const youtubeUrl = input.youtubeUrl;
|
|
15054
|
+
if (typeof youtubeUrl === "string" && /^[A-Za-z0-9_-]{11}$/.test(youtubeUrl)) {
|
|
15055
|
+
metadata.youtubeUrl = youtubeUrl;
|
|
15056
|
+
}
|
|
15057
|
+
const safeUrl = validatedHttpsUrl(chatRef.url);
|
|
15058
|
+
if (safeUrl) {
|
|
15059
|
+
const youtubeId2 = extractYouTubeId(safeUrl);
|
|
15060
|
+
delete metadata.videoUrl;
|
|
15061
|
+
delete metadata.youtubeUrl;
|
|
15062
|
+
metadata[youtubeId2 ? "youtubeUrl" : "videoUrl"] = youtubeId2 ?? safeUrl;
|
|
15063
|
+
}
|
|
15064
|
+
return Object.keys(metadata).length > 0 ? metadata : null;
|
|
15065
|
+
}
|
|
14838
15066
|
function itemVideoMetadata(item) {
|
|
14839
15067
|
const pick = (...vals) => {
|
|
14840
15068
|
for (const v of vals) if (typeof v === "string" && v.length > 0) return v;
|
|
@@ -15318,7 +15546,7 @@ function RoadmapChatCard({
|
|
|
15318
15546
|
}
|
|
15319
15547
|
);
|
|
15320
15548
|
}
|
|
15321
|
-
function refHydratedEntry(docType, label, renderRef) {
|
|
15549
|
+
function refHydratedEntry(docType, label, renderRef, renderFromSourceMetadata = false) {
|
|
15322
15550
|
return {
|
|
15323
15551
|
label,
|
|
15324
15552
|
bareInline: true,
|
|
@@ -15326,7 +15554,19 @@ function refHydratedEntry(docType, label, renderRef) {
|
|
|
15326
15554
|
noComposedHref: true,
|
|
15327
15555
|
fallbackHref: (item) => item?.url ?? null,
|
|
15328
15556
|
skeleton: () => /* @__PURE__ */ jsx93(MingoInfoCardSkeleton, {}),
|
|
15329
|
-
render: (item, chatRef, opts) => renderRef(fetchedItemDisplayRef(item, chatRef), opts)
|
|
15557
|
+
render: (item, chatRef, opts) => renderRef(fetchedItemDisplayRef(item, chatRef), opts),
|
|
15558
|
+
renderFromSourceMetadata
|
|
15559
|
+
};
|
|
15560
|
+
}
|
|
15561
|
+
function sourceMetadataCardItem(chatRef) {
|
|
15562
|
+
return {
|
|
15563
|
+
type: chatRef.type,
|
|
15564
|
+
id: chatRef.id,
|
|
15565
|
+
title: chatRef.title,
|
|
15566
|
+
url: chatRef.url,
|
|
15567
|
+
targetPlatform: chatRef.targetPlatform,
|
|
15568
|
+
sourceRepo: chatRef.sourceRepo,
|
|
15569
|
+
metadata: chatRef.metadata
|
|
15330
15570
|
};
|
|
15331
15571
|
}
|
|
15332
15572
|
var FINANCIAL_CARD_CONFIGS = {
|
|
@@ -15478,8 +15718,18 @@ var CHAT_CARD_REGISTRY = {
|
|
|
15478
15718
|
// config's searchFilter is deliberately fail-closed there. Same
|
|
15479
15719
|
// ChatRef item shape (`buildHubspotTicketSelfRef` SSOT), same preset.
|
|
15480
15720
|
hubspot_ticket_self: refHydratedEntry("hubspot_ticket_self", "HubSpot ticket (self)", (displayRef, opts) => /* @__PURE__ */ jsx93(HubspotTicketChatCard, { chatRef: displayRef, isNewTab: opts.isNewTab, discuss: opts.discuss })),
|
|
15481
|
-
data_room_doc: refHydratedEntry(
|
|
15482
|
-
|
|
15721
|
+
data_room_doc: refHydratedEntry(
|
|
15722
|
+
"data_room_doc",
|
|
15723
|
+
"Data-room doc",
|
|
15724
|
+
(displayRef, opts) => /* @__PURE__ */ jsx93(DataRoomDocChatCard, { chatRef: displayRef, isNewTab: opts.isNewTab, discuss: opts.discuss }),
|
|
15725
|
+
true
|
|
15726
|
+
),
|
|
15727
|
+
markdown: refHydratedEntry(
|
|
15728
|
+
"markdown",
|
|
15729
|
+
"Doc page (markdown)",
|
|
15730
|
+
(displayRef, opts) => /* @__PURE__ */ jsx93(DataRoomDocChatCard, { chatRef: displayRef, isNewTab: opts.isNewTab, discuss: opts.discuss }),
|
|
15731
|
+
true
|
|
15732
|
+
),
|
|
15483
15733
|
// Body-synthesized video ids (`shortVideoId` content hashes / YouTube
|
|
15484
15734
|
// ids) have no backing table row to fetch — ref-only by nature.
|
|
15485
15735
|
video: {
|
|
@@ -15717,7 +15967,7 @@ function ChatCardLoader({
|
|
|
15717
15967
|
children
|
|
15718
15968
|
}
|
|
15719
15969
|
);
|
|
15720
|
-
const finish = (node) => entry.bareInline ? /* @__PURE__ */ jsx93(
|
|
15970
|
+
const finish = (node) => entry.bareInline ? /* @__PURE__ */ jsx93(Fragment33, { children: navWrap(node) }) : /* @__PURE__ */ jsx93(
|
|
15721
15971
|
ChatCardWithDiscuss,
|
|
15722
15972
|
{
|
|
15723
15973
|
chatRef: finalChatRef,
|
|
@@ -15730,8 +15980,12 @@ function ChatCardLoader({
|
|
|
15730
15980
|
if (!fetchEntry) {
|
|
15731
15981
|
return finish(entry.render(void 0, finalChatRef, renderOpts));
|
|
15732
15982
|
}
|
|
15733
|
-
if (isLoading) return /* @__PURE__ */ jsx93(
|
|
15983
|
+
if (isLoading) return /* @__PURE__ */ jsx93(Fragment33, { children: fetchEntry.skeleton?.() ?? null });
|
|
15734
15984
|
if (!item) {
|
|
15985
|
+
const hasSourceMetadata = fetchEntry.renderFromSourceMetadata && isSourceMetadataCardRef(chatRef) && typeof finalChatRef.metadata?.path === "string";
|
|
15986
|
+
if (hasSourceMetadata) {
|
|
15987
|
+
return finish(fetchEntry.render(sourceMetadataCardItem(finalChatRef), finalChatRef, renderOpts));
|
|
15988
|
+
}
|
|
15735
15989
|
if (isError) {
|
|
15736
15990
|
return /* @__PURE__ */ jsx93(CardLoadFailure, { label: entry.label, id: finalChatRef.id, detail: "Failed to load" });
|
|
15737
15991
|
}
|
|
@@ -15772,13 +16026,15 @@ function renderChatInlineEntityCard(chatRef, options = {}) {
|
|
|
15772
16026
|
}
|
|
15773
16027
|
);
|
|
15774
16028
|
if (chatRef.type === "video") {
|
|
16029
|
+
const enrichedMetadata = validatedVideoMetadata(chatRef);
|
|
15775
16030
|
const decoded = decodeVideoMarkerId(chatRef.id);
|
|
15776
|
-
|
|
16031
|
+
const playableMetadata = enrichedMetadata ?? decoded;
|
|
16032
|
+
if (playableMetadata) {
|
|
15777
16033
|
const displayRef = {
|
|
15778
16034
|
...chatRef,
|
|
15779
16035
|
title: chatRef.title && chatRef.title !== chatRef.id ? chatRef.title : "Video",
|
|
15780
|
-
url: chatRef.url ??
|
|
15781
|
-
metadata:
|
|
16036
|
+
url: chatRef.url ?? (typeof playableMetadata.videoUrl === "string" ? playableMetadata.videoUrl : null) ?? (typeof playableMetadata.youtubeUrl === "string" ? `https://www.youtube.com/watch?v=${playableMetadata.youtubeUrl}` : null),
|
|
16037
|
+
metadata: playableMetadata
|
|
15782
16038
|
};
|
|
15783
16039
|
return /* @__PURE__ */ jsx93(BlockCard, { inline: /* @__PURE__ */ jsx93(ChatInlineVideoPill, { chatRef: displayRef }), children: /* @__PURE__ */ jsx93(ChatVideoEntityCard, { chatRef: displayRef }) });
|
|
15784
16040
|
}
|
|
@@ -16777,14 +17033,17 @@ function buildNatsWsUrl(apiBaseUrl, options) {
|
|
|
16777
17033
|
// src/components/chat/hooks/use-slash-commands.ts
|
|
16778
17034
|
import { useQuery as useQuery2 } from "@tanstack/react-query";
|
|
16779
17035
|
import { useEffect as useEffect26, useState as useState32 } from "react";
|
|
17036
|
+
var COMMANDS_MAX_RESULTS = 10;
|
|
16780
17037
|
async function fetchSlashCommands(prefix, signal, commandsUrl) {
|
|
16781
17038
|
try {
|
|
16782
17039
|
const url = new URL(commandsUrl, window.location.origin);
|
|
16783
|
-
if (prefix) url.searchParams.set("q", prefix);
|
|
16784
17040
|
const res = await embedAuthedFetch(url.toString(), { signal, headers: {} });
|
|
16785
17041
|
if (!res.ok) return [];
|
|
16786
17042
|
const data = await res.json();
|
|
16787
|
-
|
|
17043
|
+
const commands = data.commands ?? [];
|
|
17044
|
+
const normalizedPrefix = prefix.trim().toLowerCase();
|
|
17045
|
+
if (!normalizedPrefix) return commands;
|
|
17046
|
+
return commands.filter(({ id }) => id.startsWith(normalizedPrefix)).slice(0, COMMANDS_MAX_RESULTS);
|
|
16788
17047
|
} catch (err) {
|
|
16789
17048
|
if (err?.name === "AbortError") throw err;
|
|
16790
17049
|
console.warn("[chat] slash-commands fetch failed, showing none:", err);
|
|
@@ -17877,6 +18136,23 @@ function approvalDisplaysInline(approvalType, displayApprovalTypes) {
|
|
|
17877
18136
|
return !displayApprovalTypes || displayApprovalTypes.includes(approvalType);
|
|
17878
18137
|
}
|
|
17879
18138
|
|
|
18139
|
+
// src/components/chat/utils/chat-source-metadata.ts
|
|
18140
|
+
function mergeChatSources(current, incoming) {
|
|
18141
|
+
const sourcesByIndex = new Map((current ?? []).map((source) => [source.index, source]));
|
|
18142
|
+
incoming.forEach((source) => {
|
|
18143
|
+
if (!sourcesByIndex.has(source.index)) sourcesByIndex.set(source.index, source);
|
|
18144
|
+
});
|
|
18145
|
+
return Array.from(sourcesByIndex.values());
|
|
18146
|
+
}
|
|
18147
|
+
function mergeChatRefs(current, incoming) {
|
|
18148
|
+
const refsByIdentity = new Map((current ?? []).map((ref) => [`${ref.type}:${ref.id}`, ref]));
|
|
18149
|
+
incoming.forEach((ref) => {
|
|
18150
|
+
const identity = `${ref.type}:${ref.id}`;
|
|
18151
|
+
if (!refsByIdentity.has(identity)) refsByIdentity.set(identity, ref);
|
|
18152
|
+
});
|
|
18153
|
+
return Array.from(refsByIdentity.values());
|
|
18154
|
+
}
|
|
18155
|
+
|
|
17880
18156
|
// src/components/chat/stream/message-mutations.ts
|
|
17881
18157
|
function nextId(role) {
|
|
17882
18158
|
return `${role}-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
|
|
@@ -18736,6 +19012,8 @@ function createChatStreamReducer(options = {}) {
|
|
|
18736
19012
|
const sourcesMap = /* @__PURE__ */ new Map();
|
|
18737
19013
|
let sendCount = 0;
|
|
18738
19014
|
let sseCurrentText = "";
|
|
19015
|
+
let pendingSources;
|
|
19016
|
+
let pendingRefs;
|
|
18739
19017
|
let stateCache = null;
|
|
18740
19018
|
function invalidate() {
|
|
18741
19019
|
stateCache = null;
|
|
@@ -18797,6 +19075,17 @@ function createChatStreamReducer(options = {}) {
|
|
|
18797
19075
|
}
|
|
18798
19076
|
setMessagesInternal(stampTrailingAssistantSeq(updateTrailingAssistant(messages, segments), seq));
|
|
18799
19077
|
}
|
|
19078
|
+
function attachPendingSourceMetadata() {
|
|
19079
|
+
if (!pendingSources && !pendingRefs) return;
|
|
19080
|
+
const last = messages[messages.length - 1];
|
|
19081
|
+
if (!last || last.role !== "assistant") return;
|
|
19082
|
+
const next = {
|
|
19083
|
+
...last,
|
|
19084
|
+
...pendingSources ? { sources: pendingSources } : {},
|
|
19085
|
+
...pendingRefs ? { refs: pendingRefs } : {}
|
|
19086
|
+
};
|
|
19087
|
+
setMessagesInternal([...messages.slice(0, -1), next]);
|
|
19088
|
+
}
|
|
18800
19089
|
function applyStreamStartToState() {
|
|
18801
19090
|
setPhaseInternal("streaming");
|
|
18802
19091
|
const adoptTail = adoptTrailingAssistant;
|
|
@@ -18915,6 +19204,8 @@ function createChatStreamReducer(options = {}) {
|
|
|
18915
19204
|
}
|
|
18916
19205
|
switch (event.type) {
|
|
18917
19206
|
case "turn-start": {
|
|
19207
|
+
pendingSources = void 0;
|
|
19208
|
+
pendingRefs = void 0;
|
|
18918
19209
|
isInStream = true;
|
|
18919
19210
|
hasEverStreamed = true;
|
|
18920
19211
|
turnStartedAt = Date.now();
|
|
@@ -18929,6 +19220,14 @@ function createChatStreamReducer(options = {}) {
|
|
|
18929
19220
|
emit("onStreamEnd");
|
|
18930
19221
|
setPhaseInternal("idle");
|
|
18931
19222
|
accumulator.resetSegments();
|
|
19223
|
+
pendingSources = void 0;
|
|
19224
|
+
pendingRefs = void 0;
|
|
19225
|
+
break;
|
|
19226
|
+
}
|
|
19227
|
+
case "sources": {
|
|
19228
|
+
pendingSources = mergeChatSources(pendingSources, event.sources);
|
|
19229
|
+
if (event.refs) pendingRefs = mergeChatRefs(pendingRefs, event.refs);
|
|
19230
|
+
attachPendingSourceMetadata();
|
|
18932
19231
|
break;
|
|
18933
19232
|
}
|
|
18934
19233
|
case "metadata": {
|
|
@@ -18957,10 +19256,12 @@ function createChatStreamReducer(options = {}) {
|
|
|
18957
19256
|
if (isInStream || !hasEverStreamed) {
|
|
18958
19257
|
emitSegments(segments);
|
|
18959
19258
|
applySegmentsToState(segments, withSeqMeta(void 0));
|
|
19259
|
+
attachPendingSourceMetadata();
|
|
18960
19260
|
} else {
|
|
18961
19261
|
const delta = [{ type: kind, text: event.text }];
|
|
18962
19262
|
emitSegments(delta, { append: true });
|
|
18963
19263
|
applySegmentsToState(delta, withSeqMeta({ append: true }));
|
|
19264
|
+
attachPendingSourceMetadata();
|
|
18964
19265
|
}
|
|
18965
19266
|
break;
|
|
18966
19267
|
}
|
|
@@ -20648,6 +20949,11 @@ function decodeNatsChunk(chunk) {
|
|
|
20648
20949
|
return { type: "thinking-delta", text: data.text, ...seq };
|
|
20649
20950
|
}
|
|
20650
20951
|
return null;
|
|
20952
|
+
case MESSAGE_TYPE.GUIDE:
|
|
20953
|
+
case MESSAGE_TYPE.SOURCES: {
|
|
20954
|
+
const event = sourceMetadataEvent(data.payload);
|
|
20955
|
+
return event ? { ...event, ...seq } : null;
|
|
20956
|
+
}
|
|
20651
20957
|
// An ask card is only an ask card with something to pick: a question and at
|
|
20652
20958
|
// least one option. Anything less is dropped rather than rendered as an
|
|
20653
20959
|
// empty card the user can't answer — the backend already falls back to a
|
|
@@ -20999,6 +21305,9 @@ function decodeHistoricalMessageData(data) {
|
|
|
20999
21305
|
return { type: "thinking-delta", text: data.text };
|
|
21000
21306
|
}
|
|
21001
21307
|
return null;
|
|
21308
|
+
case MESSAGE_TYPE.GUIDE:
|
|
21309
|
+
case MESSAGE_TYPE.SOURCES:
|
|
21310
|
+
return decodeNatsChunk({ type: data.type, payload: data.payload });
|
|
21002
21311
|
// Same completeness gate as the live decoder (`decodeNatsChunk`): a
|
|
21003
21312
|
// persisted row without a question or without options is not a card the
|
|
21004
21313
|
// user can answer, so it replays as nothing rather than as empty chrome.
|
|
@@ -21354,6 +21663,8 @@ function processHistoricalMessages(messages, options = {}) {
|
|
|
21354
21663
|
let currentAssistantTimestamp = null;
|
|
21355
21664
|
let lastAssistantId = null;
|
|
21356
21665
|
let currentAssistantStreamSeq;
|
|
21666
|
+
let currentAssistantSources;
|
|
21667
|
+
let currentAssistantRefs;
|
|
21357
21668
|
const flushAssistantMessage = () => {
|
|
21358
21669
|
const idToUse = lastAssistantId || currentAssistantId;
|
|
21359
21670
|
if (idToUse && accumulator.hasContent()) {
|
|
@@ -21366,6 +21677,8 @@ function processHistoricalMessages(messages, options = {}) {
|
|
|
21366
21677
|
authorType: assistantType,
|
|
21367
21678
|
timestamp: currentAssistantTimestamp || /* @__PURE__ */ new Date(),
|
|
21368
21679
|
avatar: assistantAvatar,
|
|
21680
|
+
...currentAssistantSources ? { sources: currentAssistantSources } : {},
|
|
21681
|
+
...currentAssistantRefs ? { refs: currentAssistantRefs } : {},
|
|
21369
21682
|
...currentAssistantStreamSeq !== void 0 ? { streamSeq: currentAssistantStreamSeq } : {}
|
|
21370
21683
|
});
|
|
21371
21684
|
accumulator.resetSegments();
|
|
@@ -21374,6 +21687,8 @@ function processHistoricalMessages(messages, options = {}) {
|
|
|
21374
21687
|
currentAssistantTimestamp = null;
|
|
21375
21688
|
lastAssistantId = null;
|
|
21376
21689
|
currentAssistantStreamSeq = void 0;
|
|
21690
|
+
currentAssistantSources = void 0;
|
|
21691
|
+
currentAssistantRefs = void 0;
|
|
21377
21692
|
};
|
|
21378
21693
|
messages.forEach((msg, index) => {
|
|
21379
21694
|
if (chatTypeFilter && msg.chatType !== chatTypeFilter) return;
|
|
@@ -21417,6 +21732,11 @@ function processHistoricalMessages(messages, options = {}) {
|
|
|
21417
21732
|
messageDataArray.forEach((data) => {
|
|
21418
21733
|
const event = decodeHistoricalMessageData(data);
|
|
21419
21734
|
if (!event) return;
|
|
21735
|
+
if (event.type === "sources") {
|
|
21736
|
+
currentAssistantSources = mergeChatSources(currentAssistantSources, event.sources);
|
|
21737
|
+
if (event.refs) currentAssistantRefs = mergeChatRefs(currentAssistantRefs, event.refs);
|
|
21738
|
+
return;
|
|
21739
|
+
}
|
|
21420
21740
|
applyHistoryEvent(
|
|
21421
21741
|
event,
|
|
21422
21742
|
accumulator,
|
|
@@ -21509,13 +21829,17 @@ function mapProcessedToUnified(processed) {
|
|
|
21509
21829
|
id: m.id,
|
|
21510
21830
|
role: m.role,
|
|
21511
21831
|
content: "",
|
|
21512
|
-
segments: m.content
|
|
21832
|
+
segments: m.content,
|
|
21833
|
+
...m.sources ? { sources: m.sources } : {},
|
|
21834
|
+
...m.refs ? { refs: m.refs } : {}
|
|
21513
21835
|
});
|
|
21514
21836
|
} else {
|
|
21515
21837
|
out.push({
|
|
21516
21838
|
id: m.id,
|
|
21517
21839
|
role: m.role,
|
|
21518
|
-
content: m.content
|
|
21840
|
+
content: m.content,
|
|
21841
|
+
...m.sources ? { sources: m.sources } : {},
|
|
21842
|
+
...m.refs ? { refs: m.refs } : {}
|
|
21519
21843
|
});
|
|
21520
21844
|
}
|
|
21521
21845
|
}
|
|
@@ -22799,7 +23123,7 @@ DrawerFooter.displayName = "DrawerFooter";
|
|
|
22799
23123
|
|
|
22800
23124
|
// src/components/ui/hover-dropdown.tsx
|
|
22801
23125
|
import { useState as useState43, useRef as useRef32, useCallback as useCallback24 } from "react";
|
|
22802
|
-
import { Fragment as
|
|
23126
|
+
import { Fragment as Fragment34, jsx as jsx96, jsxs as jsxs74 } from "react/jsx-runtime";
|
|
22803
23127
|
function DefaultAnchor({ href, className, children }) {
|
|
22804
23128
|
return /* @__PURE__ */ jsx96("a", { href, className, children });
|
|
22805
23129
|
}
|
|
@@ -22813,6 +23137,7 @@ function HoverDropdown({
|
|
|
22813
23137
|
}) {
|
|
22814
23138
|
const [open, setOpen] = useState43(false);
|
|
22815
23139
|
const timeoutRef = useRef32(void 0);
|
|
23140
|
+
const clickPinnedRef = useRef32(false);
|
|
22816
23141
|
const containerRef = useRef32(null);
|
|
22817
23142
|
const panelRef = useRef32(null);
|
|
22818
23143
|
useIsomorphicLayoutEffect(() => {
|
|
@@ -22847,14 +23172,17 @@ function HoverDropdown({
|
|
|
22847
23172
|
setOpen(true);
|
|
22848
23173
|
}, []);
|
|
22849
23174
|
const hide = useCallback24(() => {
|
|
23175
|
+
if (clickPinnedRef.current) return;
|
|
22850
23176
|
timeoutRef.current = setTimeout(() => setOpen(false), hideDelay);
|
|
22851
23177
|
}, [hideDelay]);
|
|
22852
23178
|
const toggle = useCallback24((e) => {
|
|
22853
23179
|
e.stopPropagation();
|
|
22854
23180
|
clearTimeout(timeoutRef.current);
|
|
22855
|
-
|
|
23181
|
+
const pinned = !clickPinnedRef.current;
|
|
23182
|
+
clickPinnedRef.current = pinned;
|
|
23183
|
+
setOpen(pinned);
|
|
22856
23184
|
}, []);
|
|
22857
|
-
if (items.length === 0) return /* @__PURE__ */ jsx96(
|
|
23185
|
+
if (items.length === 0) return /* @__PURE__ */ jsx96(Fragment34, { children });
|
|
22858
23186
|
const renderAnchorFn = renderAnchor ?? DefaultAnchor;
|
|
22859
23187
|
return /* @__PURE__ */ jsxs74("div", { ref: containerRef, className: "relative inline-flex", onMouseEnter: show, onMouseLeave: hide, onClick: toggle, children: [
|
|
22860
23188
|
children,
|
|
@@ -22864,7 +23192,7 @@ function HoverDropdown({
|
|
|
22864
23192
|
className: `fixed z-[9999] max-h-[420px] min-w-[220px] max-w-[340px] overflow-y-auto rounded-lg border border-ods-border bg-ods-card p-1 shadow-xl ${className || ""}`,
|
|
22865
23193
|
ref: panelRef,
|
|
22866
23194
|
children: items.map((item, i) => {
|
|
22867
|
-
const content = /* @__PURE__ */ jsxs74(
|
|
23195
|
+
const content = /* @__PURE__ */ jsxs74(Fragment34, { children: [
|
|
22868
23196
|
item.icon && /* @__PURE__ */ jsx96("span", { className: "flex-shrink-0 [&_svg]:size-3.5", children: item.icon }),
|
|
22869
23197
|
/* @__PURE__ */ jsx96("span", { className: "min-w-0 flex-1 truncate", children: item.label })
|
|
22870
23198
|
] });
|
|
@@ -23084,7 +23412,7 @@ function useChatDialogManager({
|
|
|
23084
23412
|
}
|
|
23085
23413
|
|
|
23086
23414
|
// src/components/chat/embeddable-chat.tsx
|
|
23087
|
-
import { Fragment as
|
|
23415
|
+
import { Fragment as Fragment35, jsx as jsx97, jsxs as jsxs75 } from "react/jsx-runtime";
|
|
23088
23416
|
var DRAWER_DEFAULT_WIDTH_RATIO = 0.5;
|
|
23089
23417
|
var DRAWER_WIDTH_KEY = "mingo-chat-width-v3";
|
|
23090
23418
|
var DRAWER_DEFAULT_WIDTH_PX = 750;
|
|
@@ -23258,7 +23586,7 @@ function SourceChip({
|
|
|
23258
23586
|
);
|
|
23259
23587
|
}
|
|
23260
23588
|
const displayName = src.name || formatRelativePath(src.path);
|
|
23261
|
-
const chipBody = (label) => /* @__PURE__ */ jsxs75(
|
|
23589
|
+
const chipBody = (label) => /* @__PURE__ */ jsxs75(Fragment35, { children: [
|
|
23262
23590
|
icon,
|
|
23263
23591
|
/* @__PURE__ */ jsxs75("span", { className: "max-w-[160px] truncate", children: [
|
|
23264
23592
|
"[",
|
|
@@ -23329,21 +23657,34 @@ function SourceChips({
|
|
|
23329
23657
|
}) {
|
|
23330
23658
|
const [expanded, setExpanded] = useState45(false);
|
|
23331
23659
|
if (cited.length === 0) {
|
|
23332
|
-
const
|
|
23333
|
-
|
|
23660
|
+
const visible = expanded ? uncited : uncited.slice(0, FALLBACK_TOP_RETRIEVED);
|
|
23661
|
+
const hiddenCount2 = Math.max(0, uncited.length - FALLBACK_TOP_RETRIEVED);
|
|
23662
|
+
if (visible.length === 0) return null;
|
|
23334
23663
|
return /* @__PURE__ */ jsxs75("div", { className: "mt-2 flex flex-col gap-1.5 border-t border-ods-border pt-2", children: [
|
|
23335
23664
|
/* @__PURE__ */ jsx97("span", { className: "uppercase text-ods-text-muted text-h6", children: "Top retrieved sources" }),
|
|
23336
|
-
/* @__PURE__ */
|
|
23337
|
-
|
|
23338
|
-
|
|
23339
|
-
|
|
23340
|
-
|
|
23341
|
-
|
|
23342
|
-
|
|
23343
|
-
|
|
23344
|
-
|
|
23345
|
-
|
|
23346
|
-
|
|
23665
|
+
/* @__PURE__ */ jsxs75("div", { className: `flex flex-wrap gap-1.5 ${expanded ? "max-h-[200px] overflow-y-auto overscroll-contain" : ""}`, children: [
|
|
23666
|
+
visible.map((src) => /* @__PURE__ */ jsx97(
|
|
23667
|
+
SourceChip,
|
|
23668
|
+
{
|
|
23669
|
+
src,
|
|
23670
|
+
baseRoute,
|
|
23671
|
+
chipBasePlatform,
|
|
23672
|
+
onClose,
|
|
23673
|
+
onDiscuss
|
|
23674
|
+
},
|
|
23675
|
+
src.index
|
|
23676
|
+
)),
|
|
23677
|
+
hiddenCount2 > 0 && /* @__PURE__ */ jsx97(
|
|
23678
|
+
"button",
|
|
23679
|
+
{
|
|
23680
|
+
onClick: () => setExpanded(!expanded),
|
|
23681
|
+
className: "inline-flex cursor-pointer items-center gap-1 rounded border border-ods-accent bg-ods-card px-2 py-0.5 text-ods-accent transition-colors text-h6 hover:bg-ods-accent/10",
|
|
23682
|
+
"aria-expanded": expanded,
|
|
23683
|
+
"aria-label": expanded ? "Show fewer sources" : `Show ${hiddenCount2} additional retrieved sources`,
|
|
23684
|
+
children: expanded ? "Show less" : `+${hiddenCount2} more retrieved ${hiddenCount2 === 1 ? "source" : "sources"}`
|
|
23685
|
+
}
|
|
23686
|
+
)
|
|
23687
|
+
] })
|
|
23347
23688
|
] });
|
|
23348
23689
|
}
|
|
23349
23690
|
const hiddenCount = uncited.length;
|
|
@@ -23770,6 +24111,10 @@ function EmbeddableChatInner({
|
|
|
23770
24111
|
// explicitly — see `Message.hidden` and `chat-message-list`'s skip.
|
|
23771
24112
|
...m.hidden ? { hidden: true } : {},
|
|
23772
24113
|
...m.scrollAnchor ? { scrollAnchor: m.scrollAnchor } : {},
|
|
24114
|
+
// Preserve same-turn rich metadata. Source chips and entity-card
|
|
24115
|
+
// renderers consume it after this raw-to-Message projection.
|
|
24116
|
+
...m.sources && m.sources.length > 0 ? { sources: m.sources } : {},
|
|
24117
|
+
...m.refs && m.refs.length > 0 ? { refs: m.refs } : {},
|
|
23773
24118
|
// Forward attached context items so the user bubble renders its chips.
|
|
23774
24119
|
...m.contextItems && m.contextItems.length > 0 ? { contextItems: m.contextItems } : {}
|
|
23775
24120
|
};
|
|
@@ -23921,21 +24266,32 @@ function EmbeddableChatInner({
|
|
|
23921
24266
|
});
|
|
23922
24267
|
return out;
|
|
23923
24268
|
}, [commandsById, enabledSet]);
|
|
23924
|
-
const
|
|
23925
|
-
|
|
23926
|
-
|
|
23927
|
-
|
|
23928
|
-
|
|
23929
|
-
|
|
23930
|
-
|
|
23931
|
-
|
|
23932
|
-
|
|
23933
|
-
|
|
23934
|
-
|
|
23935
|
-
|
|
23936
|
-
|
|
23937
|
-
|
|
23938
|
-
|
|
24269
|
+
const renderSourcesAfterMessage = useCallback26(
|
|
24270
|
+
(message, index) => {
|
|
24271
|
+
if (message.role !== "assistant" || !message.sources?.length) return null;
|
|
24272
|
+
if (chatLoading && index === messages.length - 1) return null;
|
|
24273
|
+
const content = typeof message.content === "string" ? message.content : message.content.filter((segment) => segment.type === "text").map((segment) => segment.text).join("\n");
|
|
24274
|
+
const citationOrder = [...content.matchAll(/\[(\d+)\]/g)].map((m) => parseInt(m[1], 10));
|
|
24275
|
+
const seenOrder = /* @__PURE__ */ new Map();
|
|
24276
|
+
citationOrder.forEach((idx) => {
|
|
24277
|
+
if (!seenOrder.has(idx)) seenOrder.set(idx, seenOrder.size);
|
|
24278
|
+
});
|
|
24279
|
+
const cited = message.sources.filter((s) => seenOrder.has(s.index)).sort((a, b) => (seenOrder.get(a.index) ?? 0) - (seenOrder.get(b.index) ?? 0));
|
|
24280
|
+
const uncited = message.sources.filter((s) => !seenOrder.has(s.index));
|
|
24281
|
+
return /* @__PURE__ */ jsx97("div", { className: "flex-shrink-0 pb-2", children: /* @__PURE__ */ jsx97(
|
|
24282
|
+
SourceChips,
|
|
24283
|
+
{
|
|
24284
|
+
cited,
|
|
24285
|
+
uncited,
|
|
24286
|
+
baseRoute: resolvedBaseRoute,
|
|
24287
|
+
chipBasePlatform,
|
|
24288
|
+
onClose: handleNavigationClose,
|
|
24289
|
+
onDiscuss: discussRef
|
|
24290
|
+
}
|
|
24291
|
+
) });
|
|
24292
|
+
},
|
|
24293
|
+
[chatLoading, messages.length, resolvedBaseRoute, chipBasePlatform, handleNavigationClose, discussRef]
|
|
24294
|
+
);
|
|
23939
24295
|
const [portalHost, setPortalHost] = useState45(null);
|
|
23940
24296
|
const [panelBoundary, setPanelBoundary] = useState45(null);
|
|
23941
24297
|
const [panelWidth, setPanelWidth] = useState45(0);
|
|
@@ -24091,7 +24447,7 @@ function EmbeddableChatInner({
|
|
|
24091
24447
|
// renders in the rail below); the chat block is untouched.
|
|
24092
24448
|
// Back is a full-height leading cell, matching the other
|
|
24093
24449
|
// header cells (not a small inline chevron).
|
|
24094
|
-
/* @__PURE__ */ jsxs75(
|
|
24450
|
+
/* @__PURE__ */ jsxs75(Fragment35, { children: [
|
|
24095
24451
|
/* @__PURE__ */ jsx97(ChatHeaderIconButton, { divider: "right", onClick: closeArchive, "aria-label": "Back to chats", children: /* @__PURE__ */ jsx97(Chevron02LeftIcon, { size: 24 }) }),
|
|
24096
24452
|
/* @__PURE__ */ jsx97("div", { className: "flex min-w-0 flex-1 items-center px-[var(--spacing-system-mf)]", children: /* @__PURE__ */ jsx97("span", { className: "min-w-0 flex-1 truncate text-ods-text-primary text-h3", children: "Chat Archive" }) })
|
|
24097
24453
|
] })
|
|
@@ -24100,7 +24456,7 @@ function EmbeddableChatInner({
|
|
|
24100
24456
|
// search + archive controls. When search is open the
|
|
24101
24457
|
// inline field takes over the title area in place
|
|
24102
24458
|
// (Figma 116:51217) and the magnifier toggle is hidden.
|
|
24103
|
-
/* @__PURE__ */ jsxs75(
|
|
24459
|
+
/* @__PURE__ */ jsxs75(Fragment35, { children: [
|
|
24104
24460
|
railSearchOpen && mingoCaps.onSearchChange ? /* @__PURE__ */ jsx97(
|
|
24105
24461
|
ChatHeaderSearchField,
|
|
24106
24462
|
{
|
|
@@ -24108,7 +24464,7 @@ function EmbeddableChatInner({
|
|
|
24108
24464
|
onSearchChange: mingoCaps.onSearchChange,
|
|
24109
24465
|
onCollapse: () => setRailSearchOpen(false)
|
|
24110
24466
|
}
|
|
24111
|
-
) : /* @__PURE__ */ jsxs75(
|
|
24467
|
+
) : /* @__PURE__ */ jsxs75(Fragment35, { children: [
|
|
24112
24468
|
/* @__PURE__ */ jsx97("div", { className: "flex min-w-0 flex-1 items-center px-[var(--spacing-system-mf)]", children: /* @__PURE__ */ jsx97("span", { className: "min-w-0 flex-1 truncate text-ods-text-primary text-h3", children: "Current Chats" }) }),
|
|
24113
24469
|
mingoCaps.onSearchChange && /* @__PURE__ */ jsx97(
|
|
24114
24470
|
ChatHeaderIconButton,
|
|
@@ -24247,61 +24603,49 @@ function EmbeddableChatInner({
|
|
|
24247
24603
|
onRetry: reloadDialogs
|
|
24248
24604
|
}
|
|
24249
24605
|
)
|
|
24250
|
-
) : /* @__PURE__ */ jsxs75(
|
|
24606
|
+
) : /* @__PURE__ */ jsxs75(Fragment35, { children: [
|
|
24251
24607
|
/* @__PURE__ */ jsx97("div", { ref: galleryPanelRef, className: "flex min-h-0 flex-1 flex-col p-[var(--spacing-system-m)]", children: /* @__PURE__ */ jsx97(
|
|
24252
24608
|
"div",
|
|
24253
24609
|
{
|
|
24254
24610
|
className: "flex min-h-0 flex-1 flex-col duration-200 animate-in fade-in-0",
|
|
24255
|
-
children: hasConversation ? /* @__PURE__ */
|
|
24256
|
-
|
|
24257
|
-
|
|
24258
|
-
|
|
24259
|
-
|
|
24260
|
-
|
|
24261
|
-
|
|
24262
|
-
|
|
24263
|
-
|
|
24264
|
-
|
|
24265
|
-
|
|
24266
|
-
|
|
24267
|
-
|
|
24268
|
-
|
|
24269
|
-
|
|
24270
|
-
|
|
24271
|
-
|
|
24272
|
-
|
|
24273
|
-
|
|
24274
|
-
|
|
24275
|
-
|
|
24276
|
-
|
|
24277
|
-
|
|
24278
|
-
|
|
24279
|
-
|
|
24280
|
-
|
|
24281
|
-
|
|
24282
|
-
|
|
24283
|
-
|
|
24284
|
-
|
|
24285
|
-
|
|
24286
|
-
|
|
24287
|
-
|
|
24288
|
-
|
|
24289
|
-
|
|
24290
|
-
|
|
24291
|
-
|
|
24292
|
-
|
|
24293
|
-
lastSources && (lastSources.cited.length > 0 || lastSources.uncited.length > 0) && !chatLoading && /* @__PURE__ */ jsx97("div", { className: "flex-shrink-0 pb-2", children: /* @__PURE__ */ jsx97(
|
|
24294
|
-
SourceChips,
|
|
24295
|
-
{
|
|
24296
|
-
cited: lastSources.cited,
|
|
24297
|
-
uncited: lastSources.uncited,
|
|
24298
|
-
baseRoute: resolvedBaseRoute,
|
|
24299
|
-
chipBasePlatform,
|
|
24300
|
-
onClose: handleNavigationClose,
|
|
24301
|
-
onDiscuss: discussRef
|
|
24302
|
-
}
|
|
24303
|
-
) })
|
|
24304
|
-
] }) : activeMode === "mingo" ? (
|
|
24611
|
+
children: hasConversation ? /* @__PURE__ */ jsx97("div", { className: "flex min-h-0 flex-1 flex-col", children: messagesInitialLoading ? (
|
|
24612
|
+
// Match the real list's `fullWidth` layout so swapping
|
|
24613
|
+
// skeleton → bubbles doesn't shift the column. The panel
|
|
24614
|
+
// wrapper above already pads (`p-[var(--spacing-system-m)]`),
|
|
24615
|
+
// so the skeleton sits flush (no inner px/pb).
|
|
24616
|
+
//
|
|
24617
|
+
// In `previewMode` the chat lives in a fixed-height host box
|
|
24618
|
+
// (e.g. the Mingo hero demo). The default bottom-anchored
|
|
24619
|
+
// skeleton overflows a short panel and grows its OWN
|
|
24620
|
+
// scrollbar — ugly. `fill` top-anchors + clips overflow so
|
|
24621
|
+
// it reads as "the whole panel is loading" and never scrolls.
|
|
24622
|
+
/* @__PURE__ */ jsx97(ChatMessageListSkeleton, { fullWidth: true, fill: previewMode, className: "flex-1" })
|
|
24623
|
+
) : /* @__PURE__ */ jsx97(
|
|
24624
|
+
ChatMessageList,
|
|
24625
|
+
{
|
|
24626
|
+
messages,
|
|
24627
|
+
isTyping: chatLoading,
|
|
24628
|
+
pendingApprovals,
|
|
24629
|
+
autoScroll: !previewMode,
|
|
24630
|
+
pinBottom: previewMode,
|
|
24631
|
+
overscrollContain: !previewMode,
|
|
24632
|
+
assistantType: "mingo",
|
|
24633
|
+
assistantIcon: mingoAssistantIcon,
|
|
24634
|
+
renderEntityCard,
|
|
24635
|
+
resolveContextIcon,
|
|
24636
|
+
renderContextItem,
|
|
24637
|
+
renderMention,
|
|
24638
|
+
renderAfterMessage: renderSourcesAfterMessage,
|
|
24639
|
+
onAskSelect: chatLoading || previewMode ? void 0 : handleAskSelect,
|
|
24640
|
+
NavLinkAnchor: NavLinkAnchorViaRuntime,
|
|
24641
|
+
className: previewMode ? "pointer-events-auto flex-1" : "flex-1 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
|
|
24642
|
+
contentClassName: "max-w-none pb-0",
|
|
24643
|
+
fullWidth: true,
|
|
24644
|
+
hasNextPage: hasMoreMessages,
|
|
24645
|
+
isFetchingNextPage: isMessagesLoading,
|
|
24646
|
+
onLoadMore: loadMoreMessages
|
|
24647
|
+
}
|
|
24648
|
+
) }) : activeMode === "mingo" ? (
|
|
24305
24649
|
/* Figma node 7532:222444 — default (Mingo-mode) empty state:
|
|
24306
24650
|
centred greeting + capability grid + Guide-chat promo +
|
|
24307
24651
|
quick-action chips. Guide mode keeps the slash-command
|
|
@@ -24474,7 +24818,7 @@ function EmbeddableChatInner({
|
|
|
24474
24818
|
]
|
|
24475
24819
|
}
|
|
24476
24820
|
) }) });
|
|
24477
|
-
return /* @__PURE__ */ jsxs75(
|
|
24821
|
+
return /* @__PURE__ */ jsxs75(Fragment35, { children: [
|
|
24478
24822
|
showInternalTrigger && !shellLess && /* @__PURE__ */ jsx97(
|
|
24479
24823
|
"div",
|
|
24480
24824
|
{
|
|
@@ -24863,4 +25207,4 @@ export {
|
|
|
24863
25207
|
buildStreamFrames,
|
|
24864
25208
|
EmbeddableChat
|
|
24865
25209
|
};
|
|
24866
|
-
//# sourceMappingURL=chunk-
|
|
25210
|
+
//# sourceMappingURL=chunk-4MVGFYRE.js.map
|