@athenaintel/react 0.9.18 → 0.9.20

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/index.cjs CHANGED
@@ -5,6 +5,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
5
5
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
6
6
  const jsxRuntime = require("react/jsx-runtime");
7
7
  const React = require("react");
8
+ const AthenaAuthContext = require("./AthenaAuthContext-B3AwLA5Z.cjs");
8
9
  const ReactDOM = require("react-dom");
9
10
  function _interopNamespaceDefault(e) {
10
11
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
@@ -16583,17 +16584,50 @@ function createAthenaSpacesUrl({
16583
16584
  }
16584
16585
  return url.toString();
16585
16586
  }
16586
- function isTrustedOrigin(origin) {
16587
+ function isTrustedOrigin({
16588
+ origin,
16589
+ trustedOrigins
16590
+ }) {
16587
16591
  try {
16588
- const { hostname } = new URL(origin);
16592
+ const normalizedOrigin = new URL(origin).origin;
16593
+ if (trustedOrigins.includes(normalizedOrigin)) {
16594
+ return true;
16595
+ }
16596
+ const { hostname } = new URL(normalizedOrigin);
16589
16597
  return hostname === "athenaintel.com" || hostname.endsWith(".athenaintel.com") || hostname === "localhost";
16590
16598
  } catch {
16591
16599
  return false;
16592
16600
  }
16593
16601
  }
16594
16602
  const BRIDGE_TIMEOUT_MS = 2e3;
16595
- function useParentBridge() {
16603
+ const normalizeOrigin = (value) => {
16604
+ try {
16605
+ return new URL(value).origin;
16606
+ } catch {
16607
+ return null;
16608
+ }
16609
+ };
16610
+ function useParentBridge({
16611
+ trustedOrigins = []
16612
+ } = {}) {
16596
16613
  const isInIframe = typeof window !== "undefined" && window.parent !== window;
16614
+ const runtimeTrustedOrigins = React.useMemo(() => {
16615
+ const origins = /* @__PURE__ */ new Set();
16616
+ if (typeof window !== "undefined") {
16617
+ origins.add(window.location.origin);
16618
+ const referrerOrigin = normalizeOrigin(document.referrer);
16619
+ if (referrerOrigin) {
16620
+ origins.add(referrerOrigin);
16621
+ }
16622
+ }
16623
+ for (const trustedOrigin of trustedOrigins) {
16624
+ const normalizedOrigin = normalizeOrigin(trustedOrigin);
16625
+ if (normalizedOrigin) {
16626
+ origins.add(normalizedOrigin);
16627
+ }
16628
+ }
16629
+ return [...origins];
16630
+ }, [trustedOrigins]);
16597
16631
  const [state, setState] = React.useState({
16598
16632
  token: null,
16599
16633
  apiUrl: null,
@@ -16607,7 +16641,9 @@ function useParentBridge() {
16607
16641
  React.useEffect(() => {
16608
16642
  if (!isInIframe) return;
16609
16643
  const handler = (event) => {
16610
- if (!isTrustedOrigin(event.origin)) return;
16644
+ if (!isTrustedOrigin({ origin: event.origin, trustedOrigins: runtimeTrustedOrigins })) {
16645
+ return;
16646
+ }
16611
16647
  if (!event.data || typeof event.data !== "object") return;
16612
16648
  if (event.data.type === "athena-config") {
16613
16649
  configReceived.current = true;
@@ -16642,7 +16678,7 @@ function useParentBridge() {
16642
16678
  window.removeEventListener("message", handler);
16643
16679
  clearTimeout(timer);
16644
16680
  };
16645
- }, [isInIframe]);
16681
+ }, [isInIframe, runtimeTrustedOrigins]);
16646
16682
  return state;
16647
16683
  }
16648
16684
  function useParentAuth() {
@@ -24317,6 +24353,22 @@ const useAthenaRuntime = (config2) => {
24317
24353
  tokenRef.current = token;
24318
24354
  const apiKeyRef = React.useRef(apiKey);
24319
24355
  apiKeyRef.current = apiKey;
24356
+ const runConfigRef = React.useRef({
24357
+ enabledTools,
24358
+ agent: agent2,
24359
+ model,
24360
+ workbench,
24361
+ knowledgeBase,
24362
+ systemPrompt
24363
+ });
24364
+ runConfigRef.current = {
24365
+ enabledTools,
24366
+ agent: agent2,
24367
+ model,
24368
+ workbench,
24369
+ knowledgeBase,
24370
+ systemPrompt
24371
+ };
24320
24372
  const isExistingThread = !!threadIdProp;
24321
24373
  const runtime = useAssistantTransportRuntime({
24322
24374
  initialState: { messages: [] },
@@ -24415,16 +24467,17 @@ const useAthenaRuntime = (config2) => {
24415
24467
  return true;
24416
24468
  },
24417
24469
  get runConfig() {
24470
+ const currentRunConfig = runConfigRef.current;
24418
24471
  return {
24419
24472
  custom: {
24420
- enabled_tools: enabledTools,
24421
- agent: agent2,
24422
- model,
24473
+ enabled_tools: currentRunConfig.enabledTools,
24474
+ agent: currentRunConfig.agent,
24475
+ model: currentRunConfig.model,
24423
24476
  effort_dial_duration: -1,
24424
24477
  plan_mode_enabled: false,
24425
- workbench,
24426
- knowledge_base: knowledgeBase,
24427
- ...systemPrompt ? { system_prompt: systemPrompt } : {}
24478
+ workbench: currentRunConfig.workbench,
24479
+ knowledge_base: currentRunConfig.knowledgeBase,
24480
+ ...currentRunConfig.systemPrompt ? { system_prompt: currentRunConfig.systemPrompt } : {}
24428
24481
  },
24429
24482
  persistToolInvocationLogs: true
24430
24483
  };
@@ -24973,8 +25026,13 @@ function AthenaProvider({
24973
25026
  const configuredApiUrl = (config2 == null ? void 0 : config2.apiUrl) ?? apiUrl;
24974
25027
  const configuredBackendUrl = (config2 == null ? void 0 : config2.backendUrl) ?? backendUrl;
24975
25028
  const configuredAppUrl = (config2 == null ? void 0 : config2.appUrl) ?? appUrl;
24976
- const bridge = useParentBridge();
24977
- const effectiveToken = configuredToken !== void 0 ? configuredToken : bridge.token;
25029
+ const configuredTrustedParentOrigins = config2 == null ? void 0 : config2.trustedParentOrigins;
25030
+ const bridge = useParentBridge({
25031
+ trustedOrigins: configuredTrustedParentOrigins
25032
+ });
25033
+ const authContext = React.useContext(AthenaAuthContext.AthenaAuthContext);
25034
+ const authProviderToken = (authContext == null ? void 0 : authContext.accessToken) ?? null;
25035
+ const effectiveToken = configuredToken !== void 0 ? configuredToken : authProviderToken ?? bridge.token;
24978
25036
  const effectiveApiUrl = configuredApiUrl ?? bridge.apiUrl ?? environmentUrls.apiUrl;
24979
25037
  const effectiveBackendUrl = configuredBackendUrl ?? bridge.backendUrl ?? environmentUrls.backendUrl;
24980
25038
  const effectiveAppUrl = configuredAppUrl ?? bridge.appUrl ?? deriveAthenaAppUrl({ apiUrl: effectiveApiUrl, backendUrl: effectiveBackendUrl }) ?? environmentUrls.appUrl;
@@ -58896,39 +58954,17 @@ const useAssetPanelStore = create()(
58896
58954
  const existing = s.tabs.find((t) => t.id === assetId);
58897
58955
  if (existing) {
58898
58956
  const tabs = meta ? s.tabs.map(
58899
- (t) => t.id === assetId ? {
58900
- ...t,
58901
- name: meta.name ?? t.name,
58902
- type: meta.type ?? t.type,
58903
- embedSearchParams: meta.embedSearchParams ?? t.embedSearchParams
58904
- } : t
58957
+ (t) => t.id === assetId ? { ...t, name: meta.name ?? t.name, type: meta.type ?? t.type } : t
58905
58958
  ) : s.tabs;
58906
58959
  return { isOpen: true, tabs, activeTabId: assetId };
58907
58960
  }
58908
58961
  const newTab = {
58909
58962
  id: assetId,
58910
58963
  name: (meta == null ? void 0 : meta.name) ?? null,
58911
- type: (meta == null ? void 0 : meta.type) ?? "unknown",
58912
- embedSearchParams: (meta == null ? void 0 : meta.embedSearchParams) ?? null
58964
+ type: (meta == null ? void 0 : meta.type) ?? "unknown"
58913
58965
  };
58914
58966
  return { isOpen: true, tabs: [...s.tabs, newTab], activeTabId: assetId };
58915
58967
  }),
58916
- updateTabMeta: (assetId, meta) => set2((s) => {
58917
- const existing = s.tabs.find((t) => t.id === assetId);
58918
- if (!existing) {
58919
- return {};
58920
- }
58921
- return {
58922
- tabs: s.tabs.map(
58923
- (t) => t.id === assetId ? {
58924
- ...t,
58925
- name: meta.name ?? t.name,
58926
- type: meta.type ?? t.type,
58927
- embedSearchParams: meta.embedSearchParams ?? t.embedSearchParams
58928
- } : t
58929
- )
58930
- };
58931
- }),
58932
58968
  closeTab: (assetId) => set2((s) => {
58933
58969
  var _a2;
58934
58970
  const tabs = s.tabs.filter((t) => t.id !== assetId);
@@ -58986,43 +59022,13 @@ const ASSET_TYPE_ALIASES = {
58986
59022
  super_document: "document"
58987
59023
  };
58988
59024
  const isAthenaSpacesPath = (url) => url.pathname.replace(/\/+$/, "") === "/dashboard/spaces";
58989
- const normalizeAssetType$1 = (value) => {
59025
+ const normalizeAssetType = (value) => {
58990
59026
  if (!value) {
58991
59027
  return null;
58992
59028
  }
58993
59029
  const normalizedValue = value.trim().replace(/^athena\//, "").toLowerCase().replace(/-/g, "_");
58994
59030
  return ASSET_TYPE_ALIASES[normalizedValue] ?? null;
58995
59031
  };
58996
- const isLikelyAssetId = (value) => !!value && /^(asset|thread|project|collection)_[a-z0-9-]+$/i.test(value.trim());
58997
- const sanitizeDisplayName = (value) => {
58998
- if (!value) {
58999
- return null;
59000
- }
59001
- const trimmedValue = value.trim();
59002
- if (!trimmedValue) {
59003
- return null;
59004
- }
59005
- if (trimmedValue.startsWith('"') && trimmedValue.endsWith('"') || trimmedValue.startsWith("'") && trimmedValue.endsWith("'")) {
59006
- return trimmedValue.slice(1, -1).trim() || null;
59007
- }
59008
- return trimmedValue;
59009
- };
59010
- const getCitationDisplayName = ({
59011
- assetName,
59012
- linkText
59013
- }) => {
59014
- const sanitizedAssetName = sanitizeDisplayName(assetName);
59015
- const sanitizedLinkText = sanitizeDisplayName(linkText);
59016
- const genericLinkTextPattern = /^(this|that|the)\s+asset$/i;
59017
- if (sanitizedAssetName && !isLikelyAssetId(sanitizedAssetName)) {
59018
- return sanitizedAssetName;
59019
- }
59020
- if (sanitizedLinkText && !genericLinkTextPattern.test(sanitizedLinkText)) {
59021
- return sanitizedLinkText;
59022
- }
59023
- return sanitizedAssetName ?? sanitizedLinkText;
59024
- };
59025
- const getEmbedSearchParams = (url) => Object.fromEntries(url.searchParams.entries());
59026
59032
  const getOrigin = (value) => {
59027
59033
  if (!value) {
59028
59034
  return null;
@@ -59104,11 +59110,7 @@ const parseAthenaCitationLink = ({
59104
59110
  url,
59105
59111
  assetId,
59106
59112
  assetIds,
59107
- assetType: normalizeAssetType$1(
59108
- url.searchParams.get("asset_type") ?? url.searchParams.get("assetType") ?? url.searchParams.get("type")
59109
- ),
59110
- assetName: sanitizeDisplayName(url.searchParams.get("name")),
59111
- embedSearchParams: getEmbedSearchParams(url)
59113
+ assetType: normalizeAssetType(url.searchParams.get("asset_type") ?? url.searchParams.get("type"))
59112
59114
  };
59113
59115
  };
59114
59116
  const isAthenaCitationUrl = ({
@@ -59156,19 +59158,12 @@ const useAthenaLinkClickHandler = () => {
59156
59158
  const citationMetadata = citationLink ? {
59157
59159
  assetId: citationLink.assetId,
59158
59160
  assetIds: citationLink.assetIds,
59159
- assetType: citationLink.assetType,
59160
- assetName: citationLink.assetName,
59161
- embedSearchParams: citationLink.embedSearchParams
59161
+ assetType: citationLink.assetType
59162
59162
  } : null;
59163
59163
  const openInAssetPanel = citationLink ? () => {
59164
- const displayName = getCitationDisplayName({
59165
- assetName: citationLink.assetName,
59166
- linkText: trimmedLinkText
59167
- });
59168
59164
  openAsset(citationLink.assetId, {
59169
- name: displayName ?? void 0,
59170
- type: citationLink.assetType ?? void 0,
59171
- embedSearchParams: citationLink.embedSearchParams
59165
+ name: trimmedLinkText ?? void 0,
59166
+ type: citationLink.assetType ?? void 0
59172
59167
  });
59173
59168
  } : void 0;
59174
59169
  const context2 = {
@@ -62420,7 +62415,9 @@ const TOOL_META = {
62420
62415
  create_email_draft: { displayName: "Drafting email", icon: Mail },
62421
62416
  unified_email_create_draft: { displayName: "Drafting email", icon: Mail },
62422
62417
  edit_email_draft: { displayName: "Editing email draft", icon: Mail },
62423
- unified_edit_email_draft: { displayName: "Editing email draft", icon: Mail },
62418
+ unified_email_edit_draft: { displayName: "Editing email draft", icon: Mail },
62419
+ unified_email_fetch_attachments: { displayName: "Fetching email attachments", icon: Mail },
62420
+ unified_email_forward: { displayName: "Forwarding email", icon: Mail },
62424
62421
  // Documents
62425
62422
  read_full_asset: { displayName: "Reading document", icon: BookOpen },
62426
62423
  create_new_document: { displayName: "Creating document", icon: FileText },
@@ -63608,12 +63605,6 @@ function extractAssetId(result) {
63608
63605
  if (typeof id === "string" && id.startsWith("asset_")) return id;
63609
63606
  return null;
63610
63607
  }
63611
- function extractAssetTitle(result) {
63612
- const data = normalizeResult(result);
63613
- if (!data) return null;
63614
- const title = data.assetTitle ?? data.asset_title ?? data.title ?? data.name;
63615
- return typeof title === "string" && title.trim().length > 0 ? title.trim() : null;
63616
- }
63617
63608
  function resetAssetAutoOpen() {
63618
63609
  useAssetPanelStore.getState().resetAutoOpen();
63619
63610
  }
@@ -64333,7 +64324,6 @@ const OpenAssetToolUIImpl = ({
64333
64324
  const typedArgs = args;
64334
64325
  const argsAssetId = (typedArgs == null ? void 0 : typedArgs.asset_id) ?? (typedArgs == null ? void 0 : typedArgs.assetId) ?? "";
64335
64326
  const resultAssetId = extractAssetId(result);
64336
- const resultAssetTitle = extractAssetTitle(result);
64337
64327
  const assetId = resultAssetId ?? (argsAssetId.startsWith("asset_") ? argsAssetId : null);
64338
64328
  const isRunning = (status == null ? void 0 : status.type) === "running";
64339
64329
  const isComplete = (status == null ? void 0 : status.type) === "complete" || !status;
@@ -64345,10 +64335,10 @@ const OpenAssetToolUIImpl = ({
64345
64335
  if (isComplete && !isCancelled && assetId && !wasCompleteAtMount.current) {
64346
64336
  const store = useAssetPanelStore.getState();
64347
64337
  if (store.markAutoOpened(assetId)) {
64348
- store.openAsset(assetId, { name: resultAssetTitle ?? void 0 });
64338
+ store.openAsset(assetId);
64349
64339
  }
64350
64340
  }
64351
- }, [isComplete, isCancelled, assetId, resultAssetTitle]);
64341
+ }, [isComplete, isCancelled, assetId]);
64352
64342
  return /* @__PURE__ */ jsxRuntime.jsx(
64353
64343
  ToolCard,
64354
64344
  {
@@ -64364,7 +64354,7 @@ const OpenAssetToolUIImpl = ({
64364
64354
  "button",
64365
64355
  {
64366
64356
  type: "button",
64367
- onClick: () => openAsset(assetId, { name: resultAssetTitle ?? void 0 }),
64357
+ onClick: () => openAsset(assetId),
64368
64358
  className: "flex items-center gap-1.5 rounded-md border border-border/60 px-3 py-1.5 text-xs font-medium text-muted-foreground transition-colors hover:bg-muted/50 hover:text-foreground",
64369
64359
  children: [
64370
64360
  /* @__PURE__ */ jsxRuntime.jsx(ExternalLink, { className: "size-3" }),
@@ -64975,7 +64965,9 @@ const AthenaChat = ({
64975
64965
  {
64976
64966
  turnAnchor: "top",
64977
64967
  className: "aui-thread-viewport relative flex flex-1 flex-col overflow-x-auto overflow-y-scroll scroll-smooth px-4 pt-4",
64968
+ "data-aui-thread-viewport": "",
64978
64969
  children: [
64970
+ /* @__PURE__ */ jsxRuntime.jsx(ThreadScrollToTop, {}),
64979
64971
  /* @__PURE__ */ jsxRuntime.jsx(AuiIf, { condition: (s) => s.thread.isEmpty, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aui-thread-welcome-root mx-auto my-auto flex w-full max-w-(--thread-max-width) grow flex-col", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aui-thread-welcome-center flex w-full grow flex-col items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "aui-thread-welcome-message flex size-full flex-col justify-center px-4", children: [
64980
64972
  /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "aui-thread-welcome-message-inner fade-in slide-in-from-bottom-1 animate-in fill-mode-both font-semibold text-2xl duration-200", children: welcomeMessage }),
64981
64973
  welcomeSubtext && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "aui-thread-welcome-message-inner fade-in slide-in-from-bottom-1 animate-in fill-mode-both text-muted-foreground text-lg delay-75 duration-200", children: welcomeSubtext }),
@@ -65021,6 +65013,50 @@ const ThreadLoadingOverlay = () => {
65021
65013
  if (!remoteId || timedOut) return null;
65022
65014
  return /* @__PURE__ */ jsxRuntime.jsx(AuiIf, { condition: (s) => s.thread.isEmpty, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 z-10 flex items-center justify-center bg-background/80", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "size-5 animate-spin rounded-full border-2 border-muted-foreground border-t-transparent" }) }) });
65023
65015
  };
65016
+ const THREAD_VIEWPORT_ATTR = "data-aui-thread-viewport";
65017
+ const useScrollToTop = () => {
65018
+ const [isAtTop, setIsAtTop] = React.useState(true);
65019
+ const [buttonEl, setButtonEl] = React.useState(null);
65020
+ const containerRef = React.useCallback((node) => {
65021
+ setButtonEl(node);
65022
+ }, []);
65023
+ const getViewport = React.useCallback(() => {
65024
+ if (!buttonEl) return null;
65025
+ return buttonEl.closest(`[${THREAD_VIEWPORT_ATTR}]`);
65026
+ }, [buttonEl]);
65027
+ React.useEffect(() => {
65028
+ const viewport = getViewport();
65029
+ if (!viewport) return;
65030
+ const handleScroll2 = () => {
65031
+ setIsAtTop(viewport.scrollTop <= 50);
65032
+ };
65033
+ handleScroll2();
65034
+ viewport.addEventListener("scroll", handleScroll2, { passive: true });
65035
+ return () => viewport.removeEventListener("scroll", handleScroll2);
65036
+ }, [getViewport]);
65037
+ const handleClick2 = React.useCallback(() => {
65038
+ const viewport = getViewport();
65039
+ if (!viewport) return;
65040
+ viewport.scrollTo({ top: 0, behavior: "smooth" });
65041
+ }, [getViewport]);
65042
+ return { isAtTop, containerRef, handleClick: handleClick2 };
65043
+ };
65044
+ const ThreadScrollToTop = () => {
65045
+ const { isAtTop, containerRef, handleClick: handleClick2 } = useScrollToTop();
65046
+ const isEmpty3 = useAuiState((s) => s.thread.isEmpty);
65047
+ if (isEmpty3) return null;
65048
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sticky top-0 z-10 mx-auto flex h-0 w-full max-w-(--thread-max-width) justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
65049
+ TooltipIconButton,
65050
+ {
65051
+ ref: containerRef,
65052
+ tooltip: "Scroll to top",
65053
+ variant: "outline",
65054
+ className: cn("aui-thread-scroll-to-top absolute top-2 rounded-full p-4 dark:bg-background dark:hover:bg-accent", isAtTop && "invisible"),
65055
+ onClick: handleClick2,
65056
+ children: /* @__PURE__ */ jsxRuntime.jsx(ArrowUp, {})
65057
+ }
65058
+ ) });
65059
+ };
65024
65060
  const ThreadScrollToBottom = () => /* @__PURE__ */ jsxRuntime.jsx(ThreadPrimitiveScrollToBottom, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
65025
65061
  TooltipIconButton,
65026
65062
  {
@@ -65289,67 +65325,14 @@ const AthenaUserMessage = ({
65289
65325
  children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aui-user-message-content wrap-break-word rounded-2xl bg-muted px-4 py-2.5 text-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(MessagePrimitiveParts, { components: { Text: TextComponent } }) })
65290
65326
  }
65291
65327
  );
65292
- const EMBED_ASSET_TYPE_ALIASES = {
65293
- document: "document",
65294
- image: "document",
65295
- notebook: "notebook",
65296
- pdf: "document",
65297
- powerpoint_deck: "presentation",
65298
- presentation: "presentation",
65299
- puck_presentation: "presentation",
65300
- sheet: "spreadsheet",
65301
- spreadsheet: "spreadsheet",
65302
- super_document: "document"
65303
- };
65304
65328
  const embedCache = /* @__PURE__ */ new Map();
65305
- const normalizeAssetType = (value) => {
65306
- if (!value) {
65307
- return null;
65308
- }
65309
- const normalizedValue = value.trim().replace(/^athena\//, "").toLowerCase().replace(/-/g, "_");
65310
- return EMBED_ASSET_TYPE_ALIASES[normalizedValue] ?? null;
65311
- };
65312
- const getEmbedSearchParamsCacheKey = (embedSearchParams) => {
65313
- if (!embedSearchParams || Object.keys(embedSearchParams).length === 0) {
65314
- return "{}";
65315
- }
65316
- const sortedEntries = Object.entries(embedSearchParams).sort(
65317
- ([left], [right]) => left.localeCompare(right)
65318
- );
65319
- return JSON.stringify(Object.fromEntries(sortedEntries));
65320
- };
65321
- const appendEmbedSearchParams = ({
65322
- embedUrl,
65323
- embedSearchParams
65324
- }) => {
65325
- if (!embedSearchParams || Object.keys(embedSearchParams).length === 0) {
65326
- return embedUrl;
65327
- }
65328
- const url = new URL(embedUrl);
65329
- for (const [key, value] of Object.entries(embedSearchParams)) {
65330
- if (!value) {
65331
- continue;
65332
- }
65333
- url.searchParams.set(key, value);
65334
- }
65335
- return url.toString();
65336
- };
65337
65329
  function useAssetEmbed(assetId, options = {
65338
65330
  backendUrl: ""
65339
65331
  }) {
65340
- const {
65341
- readOnly = false,
65342
- expiresInSeconds = 60 * 60 * 24 * 30,
65343
- backendUrl,
65344
- apiKey,
65345
- token,
65346
- embedSearchParams
65347
- } = options;
65332
+ const { readOnly = false, expiresInSeconds = 60 * 60 * 24 * 30, backendUrl, apiKey, token } = options;
65348
65333
  const [embedUrl, setEmbedUrl] = React.useState(null);
65349
65334
  const [isLoading, setIsLoading] = React.useState(false);
65350
65335
  const [error2, setError] = React.useState(null);
65351
- const [assetTitle, setAssetTitle] = React.useState(null);
65352
- const [assetType, setAssetType] = React.useState(null);
65353
65336
  const abortRef = React.useRef(null);
65354
65337
  React.useEffect(() => {
65355
65338
  var _a2;
@@ -65357,18 +65340,14 @@ function useAssetEmbed(assetId, options = {
65357
65340
  setEmbedUrl(null);
65358
65341
  setIsLoading(false);
65359
65342
  setError(null);
65360
- setAssetTitle(null);
65361
- setAssetType(null);
65362
65343
  return;
65363
65344
  }
65364
- const cacheKey = `${assetId}:${readOnly}:${token ?? apiKey ?? "anon"}:${getEmbedSearchParamsCacheKey(embedSearchParams)}`;
65345
+ const cacheKey = `${assetId}:${readOnly}:${token ?? apiKey ?? "anon"}`;
65365
65346
  const cached = embedCache.get(cacheKey);
65366
65347
  if (cached && cached.expiresAt > Date.now() / 1e3) {
65367
65348
  setEmbedUrl(cached.url);
65368
65349
  setIsLoading(false);
65369
65350
  setError(null);
65370
- setAssetTitle(cached.assetTitle);
65371
- setAssetType(cached.assetType);
65372
65351
  return;
65373
65352
  }
65374
65353
  const apiBaseUrl = backendUrl.replace(/\/api\/assistant-ui\/?$/, "");
@@ -65376,14 +65355,11 @@ function useAssetEmbed(assetId, options = {
65376
65355
  (_a2 = abortRef.current) == null ? void 0 : _a2.abort();
65377
65356
  const controller = new AbortController();
65378
65357
  abortRef.current = controller;
65379
- setEmbedUrl(null);
65380
65358
  setIsLoading(true);
65381
65359
  setError(null);
65382
- setAssetTitle(null);
65383
- setAssetType(null);
65384
65360
  const headers = { "Content-Type": "application/json" };
65385
65361
  if (token) {
65386
- headers.Authorization = `Bearer ${token}`;
65362
+ headers["Authorization"] = `Bearer ${token}`;
65387
65363
  } else if (apiKey) {
65388
65364
  headers["X-API-KEY"] = apiKey;
65389
65365
  }
@@ -65403,31 +65379,17 @@ function useAssetEmbed(assetId, options = {
65403
65379
  }
65404
65380
  return res.json();
65405
65381
  }).then((data) => {
65406
- const resolvedAssetType = normalizeAssetType(data.athena_converted_type) ?? normalizeAssetType(data.athena_original_type);
65407
- const resolvedEmbedUrl = appendEmbedSearchParams({
65408
- embedUrl: data.embed_url,
65409
- embedSearchParams
65410
- });
65411
- embedCache.set(cacheKey, {
65412
- url: resolvedEmbedUrl,
65413
- expiresAt: data.expires_at,
65414
- assetTitle: data.title ?? null,
65415
- assetType: resolvedAssetType
65416
- });
65417
- setEmbedUrl(resolvedEmbedUrl);
65418
- setAssetTitle(data.title ?? null);
65419
- setAssetType(resolvedAssetType);
65382
+ embedCache.set(`${assetId}:${readOnly}:${token ?? apiKey ?? "anon"}`, { url: data.embed_url, expiresAt: data.expires_at });
65383
+ setEmbedUrl(data.embed_url);
65420
65384
  setIsLoading(false);
65421
65385
  }).catch((err) => {
65422
- if (err.name === "AbortError") {
65423
- return;
65424
- }
65386
+ if (err.name === "AbortError") return;
65425
65387
  setError(err.message);
65426
65388
  setIsLoading(false);
65427
65389
  });
65428
65390
  return () => controller.abort();
65429
- }, [assetId, readOnly, expiresInSeconds, backendUrl, apiKey, token, embedSearchParams]);
65430
- return { embedUrl, isLoading, error: error2, assetTitle, assetType };
65391
+ }, [assetId, readOnly, expiresInSeconds, backendUrl, apiKey, token]);
65392
+ return { embedUrl, isLoading, error: error2 };
65431
65393
  }
65432
65394
  const ASSET_TYPE_CONFIG = {
65433
65395
  presentation: { icon: Presentation, label: "Presentation" },
@@ -65437,28 +65399,13 @@ const ASSET_TYPE_CONFIG = {
65437
65399
  unknown: { icon: File$1, label: "Asset" }
65438
65400
  };
65439
65401
  const AssetIframe = React.memo(
65440
- ({ tabId, tabName, tabType, embedSearchParams }) => {
65402
+ ({ tabId, tabName }) => {
65441
65403
  const { backendUrl, apiKey, token } = useAthenaConfig();
65442
- const { embedUrl, isLoading, error: error2, assetTitle, assetType } = useAssetEmbed(tabId, {
65404
+ const { embedUrl, isLoading, error: error2 } = useAssetEmbed(tabId, {
65443
65405
  backendUrl,
65444
65406
  apiKey,
65445
- token,
65446
- embedSearchParams
65407
+ token
65447
65408
  });
65448
- React.useEffect(() => {
65449
- if (!assetTitle && !assetType) {
65450
- return;
65451
- }
65452
- const nextName = assetTitle ?? tabName;
65453
- const nextType = assetType ?? tabType;
65454
- if (nextName === tabName && nextType === tabType) {
65455
- return;
65456
- }
65457
- useAssetPanelStore.getState().updateTabMeta(tabId, {
65458
- name: nextName ?? void 0,
65459
- type: nextType
65460
- });
65461
- }, [assetTitle, assetType, tabId, tabName, tabType]);
65462
65409
  if (isLoading) {
65463
65410
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center", children: [
65464
65411
  /* @__PURE__ */ jsxRuntime.jsx(LoaderCircle, { className: "mx-auto size-6 animate-spin text-muted-foreground" }),
@@ -65520,7 +65467,7 @@ const PanelContent = ({
65520
65467
  return /* @__PURE__ */ jsxRuntime.jsx(
65521
65468
  "div",
65522
65469
  {
65523
- className: cn("flex-1 overflow-hidden", isTiled && gridClass, isTiled && "gap-px bg-border/60"),
65470
+ className: `flex-1 overflow-hidden ${isTiled ? `${gridClass} gap-px bg-border/60` : ""}`,
65524
65471
  children: tabs.map((tab) => {
65525
65472
  const isActive2 = tab.id === activeTabId;
65526
65473
  const config2 = ASSET_TYPE_CONFIG[tab.type];
@@ -65543,15 +65490,7 @@ const PanelContent = ({
65543
65490
  }
65544
65491
  )
65545
65492
  ] }),
65546
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
65547
- AssetIframe,
65548
- {
65549
- tabId: tab.id,
65550
- tabName: tab.name,
65551
- tabType: tab.type,
65552
- embedSearchParams: tab.embedSearchParams
65553
- }
65554
- ) })
65493
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(AssetIframe, { tabId: tab.id, tabName: tab.name }) })
65555
65494
  ]
65556
65495
  },
65557
65496
  tab.id
@@ -65561,15 +65500,7 @@ const PanelContent = ({
65561
65500
  "div",
65562
65501
  {
65563
65502
  className: isActive2 ? "h-full w-full" : "hidden",
65564
- children: /* @__PURE__ */ jsxRuntime.jsx(
65565
- AssetIframe,
65566
- {
65567
- tabId: tab.id,
65568
- tabName: tab.name,
65569
- tabType: tab.type,
65570
- embedSearchParams: tab.embedSearchParams
65571
- }
65572
- )
65503
+ children: /* @__PURE__ */ jsxRuntime.jsx(AssetIframe, { tabId: tab.id, tabName: tab.name })
65573
65504
  },
65574
65505
  tab.id
65575
65506
  );
@@ -65587,10 +65518,7 @@ const TabBar = () => {
65587
65518
  return /* @__PURE__ */ jsxRuntime.jsxs(
65588
65519
  "div",
65589
65520
  {
65590
- className: cn(
65591
- "group flex max-w-[180px] shrink-0 cursor-pointer items-center gap-1.5 border-r border-border/40 px-3 py-1.5 text-xs",
65592
- isActive2 ? "border-b-2 border-b-primary bg-background text-foreground" : "text-muted-foreground hover:bg-background/50 hover:text-foreground"
65593
- ),
65521
+ className: `group flex max-w-[180px] shrink-0 cursor-pointer items-center gap-1.5 border-r border-border/40 px-3 py-1.5 text-xs ${isActive2 ? "border-b-2 border-b-primary bg-background text-foreground" : "text-muted-foreground hover:bg-background/50 hover:text-foreground"}`,
65594
65522
  onClick: () => setActiveTab(tab.id),
65595
65523
  children: [
65596
65524
  /* @__PURE__ */ jsxRuntime.jsx(TypeIcon, { className: "size-3 shrink-0" }),
@@ -65632,10 +65560,7 @@ const PanelHeader = ({ fullscreen }) => {
65632
65560
  "button",
65633
65561
  {
65634
65562
  onClick: () => setViewMode(isTiled ? "tabs" : "tiled"),
65635
- className: cn(
65636
- "flex size-7 items-center justify-center rounded-lg transition-colors",
65637
- isTiled ? "bg-primary/10 text-primary" : "text-muted-foreground hover:bg-accent hover:text-foreground"
65638
- ),
65563
+ className: `flex size-7 items-center justify-center rounded-lg transition-colors ${isTiled ? "bg-primary/10 text-primary" : "text-muted-foreground hover:bg-accent hover:text-foreground"}`,
65639
65564
  title: isTiled ? "Switch to tabs" : "Tile all assets",
65640
65565
  children: isTiled ? /* @__PURE__ */ jsxRuntime.jsx(Layers, { className: "size-3.5" }) : /* @__PURE__ */ jsxRuntime.jsx(LayoutGrid, { className: "size-3.5" })
65641
65566
  }