@athenaintel/react 0.9.14 → 0.9.16

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
@@ -16501,7 +16501,7 @@ const createUrlWithFallback = (url, fallbackUrl) => {
16501
16501
  return new URL(`${normalizeBaseUrl(fallbackUrl)}/`);
16502
16502
  }
16503
16503
  };
16504
- const getHostname = (value) => {
16504
+ const getHostname$1 = (value) => {
16505
16505
  if (!value) return null;
16506
16506
  try {
16507
16507
  return new URL(value).hostname;
@@ -16542,7 +16542,7 @@ function deriveAthenaAppUrl({
16542
16542
  sourcePort: "8000"
16543
16543
  });
16544
16544
  if (workspaceAppUrl) return workspaceAppUrl;
16545
- const backendHostname = getHostname(backendUrl);
16545
+ const backendHostname = getHostname$1(backendUrl);
16546
16546
  if (backendHostname === "api.athenaintel.com") {
16547
16547
  return ATHENA_ENVIRONMENT_URLS.production.appUrl;
16548
16548
  }
@@ -16556,7 +16556,7 @@ function deriveAthenaAppUrl({
16556
16556
  sourcePort: "8787"
16557
16557
  });
16558
16558
  if (workspaceAppUrl) return workspaceAppUrl;
16559
- const apiHostname = getHostname(apiUrl);
16559
+ const apiHostname = getHostname$1(apiUrl);
16560
16560
  if (apiHostname === "sync.athenaintel.com") {
16561
16561
  return ATHENA_ENVIRONMENT_URLS.production.appUrl;
16562
16562
  }
@@ -58661,57 +58661,282 @@ const MentionExtension = Node3.create({
58661
58661
  };
58662
58662
  }
58663
58663
  });
58664
- const useAssetPanelStore = create((set2, get2) => ({
58665
- isOpen: false,
58666
- tabs: [],
58667
- activeTabId: null,
58668
- viewMode: "tabs",
58669
- isFullscreen: false,
58670
- assetPanelHostCount: 0,
58671
- autoOpenGeneration: 0,
58672
- autoOpenedAssets: /* @__PURE__ */ new Map(),
58673
- registerAssetPanelHost: () => set2((state) => ({ assetPanelHostCount: state.assetPanelHostCount + 1 })),
58674
- unregisterAssetPanelHost: () => set2((state) => ({ assetPanelHostCount: Math.max(0, state.assetPanelHostCount - 1) })),
58675
- openAsset: (assetId, meta) => set2((s) => {
58676
- const existing = s.tabs.find((t) => t.id === assetId);
58677
- if (existing) {
58678
- const tabs = meta ? s.tabs.map(
58679
- (t) => t.id === assetId ? { ...t, name: meta.name ?? t.name, type: meta.type ?? t.type } : t
58680
- ) : s.tabs;
58681
- return { isOpen: true, tabs, activeTabId: assetId };
58664
+ function createJSONStorage(getStorage, options) {
58665
+ let storage;
58666
+ try {
58667
+ storage = getStorage();
58668
+ } catch (e) {
58669
+ return;
58670
+ }
58671
+ const persistStorage = {
58672
+ getItem: (name) => {
58673
+ var _a2;
58674
+ const parse2 = (str2) => {
58675
+ if (str2 === null) {
58676
+ return null;
58677
+ }
58678
+ return JSON.parse(str2, void 0);
58679
+ };
58680
+ const str = (_a2 = storage.getItem(name)) != null ? _a2 : null;
58681
+ if (str instanceof Promise) {
58682
+ return str.then(parse2);
58683
+ }
58684
+ return parse2(str);
58685
+ },
58686
+ setItem: (name, newValue) => storage.setItem(name, JSON.stringify(newValue, void 0)),
58687
+ removeItem: (name) => storage.removeItem(name)
58688
+ };
58689
+ return persistStorage;
58690
+ }
58691
+ const toThenable = (fn) => (input) => {
58692
+ try {
58693
+ const result = fn(input);
58694
+ if (result instanceof Promise) {
58695
+ return result;
58682
58696
  }
58683
- const newTab = {
58684
- id: assetId,
58685
- name: (meta == null ? void 0 : meta.name) ?? null,
58686
- type: (meta == null ? void 0 : meta.type) ?? "unknown"
58697
+ return {
58698
+ then(onFulfilled) {
58699
+ return toThenable(onFulfilled)(result);
58700
+ },
58701
+ catch(_onRejected) {
58702
+ return this;
58703
+ }
58687
58704
  };
58688
- return { isOpen: true, tabs: [...s.tabs, newTab], activeTabId: assetId };
58689
- }),
58690
- closeTab: (assetId) => set2((s) => {
58691
- var _a2;
58692
- const tabs = s.tabs.filter((t) => t.id !== assetId);
58693
- if (tabs.length === 0) {
58694
- return { isOpen: false, tabs: [], activeTabId: null, isFullscreen: false };
58705
+ } catch (e) {
58706
+ return {
58707
+ then(_onFulfilled) {
58708
+ return this;
58709
+ },
58710
+ catch(onRejected) {
58711
+ return toThenable(onRejected)(e);
58712
+ }
58713
+ };
58714
+ }
58715
+ };
58716
+ const persistImpl = (config2, baseOptions) => (set2, get2, api) => {
58717
+ let options = {
58718
+ storage: createJSONStorage(() => window.localStorage),
58719
+ partialize: (state) => state,
58720
+ version: 0,
58721
+ merge: (persistedState, currentState) => ({
58722
+ ...currentState,
58723
+ ...persistedState
58724
+ }),
58725
+ ...baseOptions
58726
+ };
58727
+ let hasHydrated = false;
58728
+ let hydrationVersion = 0;
58729
+ const hydrationListeners = /* @__PURE__ */ new Set();
58730
+ const finishHydrationListeners = /* @__PURE__ */ new Set();
58731
+ let storage = options.storage;
58732
+ if (!storage) {
58733
+ return config2(
58734
+ (...args) => {
58735
+ console.warn(
58736
+ `[zustand persist middleware] Unable to update item '${options.name}', the given storage is currently unavailable.`
58737
+ );
58738
+ set2(...args);
58739
+ },
58740
+ get2,
58741
+ api
58742
+ );
58743
+ }
58744
+ const setItem = () => {
58745
+ const state = options.partialize({ ...get2() });
58746
+ return storage.setItem(options.name, {
58747
+ state,
58748
+ version: options.version
58749
+ });
58750
+ };
58751
+ const savedSetState = api.setState;
58752
+ api.setState = (state, replace2) => {
58753
+ savedSetState(state, replace2);
58754
+ return setItem();
58755
+ };
58756
+ const configResult = config2(
58757
+ (...args) => {
58758
+ set2(...args);
58759
+ return setItem();
58760
+ },
58761
+ get2,
58762
+ api
58763
+ );
58764
+ api.getInitialState = () => configResult;
58765
+ let stateFromStorage;
58766
+ const hydrate = () => {
58767
+ var _a2, _b;
58768
+ if (!storage) return;
58769
+ const currentVersion = ++hydrationVersion;
58770
+ hasHydrated = false;
58771
+ hydrationListeners.forEach((cb) => {
58772
+ var _a22;
58773
+ return cb((_a22 = get2()) != null ? _a22 : configResult);
58774
+ });
58775
+ const postRehydrationCallback = ((_b = options.onRehydrateStorage) == null ? void 0 : _b.call(options, (_a2 = get2()) != null ? _a2 : configResult)) || void 0;
58776
+ return toThenable(storage.getItem.bind(storage))(options.name).then((deserializedStorageValue) => {
58777
+ if (deserializedStorageValue) {
58778
+ if (typeof deserializedStorageValue.version === "number" && deserializedStorageValue.version !== options.version) {
58779
+ if (options.migrate) {
58780
+ const migration = options.migrate(
58781
+ deserializedStorageValue.state,
58782
+ deserializedStorageValue.version
58783
+ );
58784
+ if (migration instanceof Promise) {
58785
+ return migration.then((result) => [true, result]);
58786
+ }
58787
+ return [true, migration];
58788
+ }
58789
+ console.error(
58790
+ `State loaded from storage couldn't be migrated since no migrate function was provided`
58791
+ );
58792
+ } else {
58793
+ return [false, deserializedStorageValue.state];
58794
+ }
58795
+ }
58796
+ return [false, void 0];
58797
+ }).then((migrationResult) => {
58798
+ var _a22;
58799
+ if (currentVersion !== hydrationVersion) {
58800
+ return;
58801
+ }
58802
+ const [migrated, migratedState] = migrationResult;
58803
+ stateFromStorage = options.merge(
58804
+ migratedState,
58805
+ (_a22 = get2()) != null ? _a22 : configResult
58806
+ );
58807
+ set2(stateFromStorage, true);
58808
+ if (migrated) {
58809
+ return setItem();
58810
+ }
58811
+ }).then(() => {
58812
+ if (currentVersion !== hydrationVersion) {
58813
+ return;
58814
+ }
58815
+ postRehydrationCallback == null ? void 0 : postRehydrationCallback(stateFromStorage, void 0);
58816
+ stateFromStorage = get2();
58817
+ hasHydrated = true;
58818
+ finishHydrationListeners.forEach((cb) => cb(stateFromStorage));
58819
+ }).catch((e) => {
58820
+ if (currentVersion !== hydrationVersion) {
58821
+ return;
58822
+ }
58823
+ postRehydrationCallback == null ? void 0 : postRehydrationCallback(void 0, e);
58824
+ });
58825
+ };
58826
+ api.persist = {
58827
+ setOptions: (newOptions) => {
58828
+ options = {
58829
+ ...options,
58830
+ ...newOptions
58831
+ };
58832
+ if (newOptions.storage) {
58833
+ storage = newOptions.storage;
58834
+ }
58835
+ },
58836
+ clearStorage: () => {
58837
+ storage == null ? void 0 : storage.removeItem(options.name);
58838
+ },
58839
+ getOptions: () => options,
58840
+ rehydrate: () => hydrate(),
58841
+ hasHydrated: () => hasHydrated,
58842
+ onHydrate: (cb) => {
58843
+ hydrationListeners.add(cb);
58844
+ return () => {
58845
+ hydrationListeners.delete(cb);
58846
+ };
58847
+ },
58848
+ onFinishHydration: (cb) => {
58849
+ finishHydrationListeners.add(cb);
58850
+ return () => {
58851
+ finishHydrationListeners.delete(cb);
58852
+ };
58695
58853
  }
58696
- const activeTabId = s.activeTabId === assetId ? ((_a2 = tabs[Math.min(s.tabs.findIndex((t) => t.id === assetId), tabs.length - 1)]) == null ? void 0 : _a2.id) ?? null : s.activeTabId;
58697
- return { tabs, activeTabId };
58698
- }),
58699
- setActiveTab: (assetId) => set2({ activeTabId: assetId, viewMode: "tabs" }),
58700
- setViewMode: (mode) => set2({ viewMode: mode }),
58701
- closePanel: () => set2({ isOpen: false, tabs: [], activeTabId: null, viewMode: "tabs", isFullscreen: false }),
58702
- toggleFullscreen: () => set2((s) => ({ isFullscreen: !s.isFullscreen })),
58703
- resetAutoOpen: () => set2((s) => ({ autoOpenGeneration: s.autoOpenGeneration + 1 })),
58704
- markAutoOpened: (assetId) => {
58705
- const state = get2();
58706
- if (state.autoOpenedAssets.get(assetId) === state.autoOpenGeneration) {
58707
- return false;
58854
+ };
58855
+ if (!options.skipHydration) {
58856
+ hydrate();
58857
+ }
58858
+ return stateFromStorage || configResult;
58859
+ };
58860
+ const persist = persistImpl;
58861
+ const useAssetPanelStore = create()(
58862
+ persist(
58863
+ (set2, get2) => ({
58864
+ isOpen: false,
58865
+ tabs: [],
58866
+ activeTabId: null,
58867
+ viewMode: "tabs",
58868
+ isFullscreen: false,
58869
+ assetPanelHostCount: 0,
58870
+ autoOpenGeneration: 0,
58871
+ autoOpenedAssets: /* @__PURE__ */ new Map(),
58872
+ registerAssetPanelHost: () => set2((state) => ({ assetPanelHostCount: state.assetPanelHostCount + 1 })),
58873
+ unregisterAssetPanelHost: () => set2((state) => ({ assetPanelHostCount: Math.max(0, state.assetPanelHostCount - 1) })),
58874
+ openAsset: (assetId, meta) => set2((s) => {
58875
+ const existing = s.tabs.find((t) => t.id === assetId);
58876
+ if (existing) {
58877
+ const tabs = meta ? s.tabs.map(
58878
+ (t) => t.id === assetId ? {
58879
+ ...t,
58880
+ name: meta.name ?? t.name,
58881
+ type: meta.type ?? t.type,
58882
+ embedSearchParams: meta.embedSearchParams ?? t.embedSearchParams
58883
+ } : t
58884
+ ) : s.tabs;
58885
+ return { isOpen: true, tabs, activeTabId: assetId };
58886
+ }
58887
+ const newTab = {
58888
+ id: assetId,
58889
+ name: (meta == null ? void 0 : meta.name) ?? null,
58890
+ type: (meta == null ? void 0 : meta.type) ?? "unknown",
58891
+ embedSearchParams: (meta == null ? void 0 : meta.embedSearchParams) ?? null
58892
+ };
58893
+ return { isOpen: true, tabs: [...s.tabs, newTab], activeTabId: assetId };
58894
+ }),
58895
+ closeTab: (assetId) => set2((s) => {
58896
+ var _a2;
58897
+ const tabs = s.tabs.filter((t) => t.id !== assetId);
58898
+ if (tabs.length === 0) {
58899
+ return { isOpen: false, tabs: [], activeTabId: null, isFullscreen: false };
58900
+ }
58901
+ const activeTabId = s.activeTabId === assetId ? ((_a2 = tabs[Math.min(s.tabs.findIndex((t) => t.id === assetId), tabs.length - 1)]) == null ? void 0 : _a2.id) ?? null : s.activeTabId;
58902
+ return { tabs, activeTabId };
58903
+ }),
58904
+ setActiveTab: (assetId) => set2({ activeTabId: assetId, viewMode: "tabs" }),
58905
+ setViewMode: (mode) => set2({ viewMode: mode }),
58906
+ closePanel: () => set2({ isOpen: false, tabs: [], activeTabId: null, viewMode: "tabs", isFullscreen: false }),
58907
+ toggleFullscreen: () => set2((s) => ({ isFullscreen: !s.isFullscreen })),
58908
+ resetAutoOpen: () => set2((s) => ({ autoOpenGeneration: s.autoOpenGeneration + 1 })),
58909
+ markAutoOpened: (assetId) => {
58910
+ const state = get2();
58911
+ if (state.autoOpenedAssets.get(assetId) === state.autoOpenGeneration) {
58912
+ return false;
58913
+ }
58914
+ state.autoOpenedAssets.set(assetId, state.autoOpenGeneration);
58915
+ return true;
58916
+ }
58917
+ }),
58918
+ {
58919
+ name: "athena-react-asset-panel",
58920
+ partialize: ({
58921
+ isOpen,
58922
+ tabs,
58923
+ activeTabId,
58924
+ viewMode,
58925
+ isFullscreen
58926
+ }) => ({
58927
+ isOpen,
58928
+ tabs,
58929
+ activeTabId,
58930
+ viewMode,
58931
+ isFullscreen
58932
+ }),
58933
+ storage: createJSONStorage(() => sessionStorage)
58708
58934
  }
58709
- state.autoOpenedAssets.set(assetId, state.autoOpenGeneration);
58710
- return true;
58711
- }
58712
- }));
58935
+ )
58936
+ );
58713
58937
  const ATHENA_APP_HOSTNAMES = /* @__PURE__ */ new Set(["app.athenaintel.com", "staging-app.athenaintel.com"]);
58714
58938
  const ATHENA_PREVIEW_HOSTNAME_SUFFIX = ".previews.athenaintel.com";
58939
+ const ATHENA_WORKSPACE_HOSTNAME_SUFFIXES = [".app.athenaintel.com", ".staging-app.athenaintel.com"];
58715
58940
  const ASSET_TYPE_ALIASES = {
58716
58941
  document: "document",
58717
58942
  notebook: "notebook",
@@ -58724,13 +58949,43 @@ const ASSET_TYPE_ALIASES = {
58724
58949
  super_document: "document"
58725
58950
  };
58726
58951
  const isAthenaSpacesPath = (url) => url.pathname.replace(/\/+$/, "") === "/dashboard/spaces";
58727
- const normalizeAssetType = (value) => {
58952
+ const normalizeAssetType$1 = (value) => {
58728
58953
  if (!value) {
58729
58954
  return null;
58730
58955
  }
58731
58956
  const normalizedValue = value.trim().replace(/^athena\//, "").toLowerCase().replace(/-/g, "_");
58732
58957
  return ASSET_TYPE_ALIASES[normalizedValue] ?? null;
58733
58958
  };
58959
+ const isLikelyAssetId = (value) => !!value && /^(asset|thread|project|collection)_[a-z0-9-]+$/i.test(value.trim());
58960
+ const sanitizeDisplayName = (value) => {
58961
+ if (!value) {
58962
+ return null;
58963
+ }
58964
+ const trimmedValue = value.trim();
58965
+ if (!trimmedValue) {
58966
+ return null;
58967
+ }
58968
+ if (trimmedValue.startsWith('"') && trimmedValue.endsWith('"') || trimmedValue.startsWith("'") && trimmedValue.endsWith("'")) {
58969
+ return trimmedValue.slice(1, -1).trim() || null;
58970
+ }
58971
+ return trimmedValue;
58972
+ };
58973
+ const getCitationDisplayName = ({
58974
+ assetName,
58975
+ linkText
58976
+ }) => {
58977
+ const sanitizedAssetName = sanitizeDisplayName(assetName);
58978
+ const sanitizedLinkText = sanitizeDisplayName(linkText);
58979
+ const genericLinkTextPattern = /^(this|that|the)\s+asset$/i;
58980
+ if (sanitizedAssetName && !isLikelyAssetId(sanitizedAssetName)) {
58981
+ return sanitizedAssetName;
58982
+ }
58983
+ if (sanitizedLinkText && !genericLinkTextPattern.test(sanitizedLinkText)) {
58984
+ return sanitizedLinkText;
58985
+ }
58986
+ return sanitizedAssetName ?? sanitizedLinkText;
58987
+ };
58988
+ const getEmbedSearchParams = (url) => Object.fromEntries(url.searchParams.entries());
58734
58989
  const getOrigin = (value) => {
58735
58990
  if (!value) {
58736
58991
  return null;
@@ -58741,6 +58996,20 @@ const getOrigin = (value) => {
58741
58996
  return null;
58742
58997
  }
58743
58998
  };
58999
+ const getHostname = (value) => {
59000
+ if (!value) {
59001
+ return null;
59002
+ }
59003
+ try {
59004
+ return new URL(value).hostname.toLowerCase();
59005
+ } catch {
59006
+ return null;
59007
+ }
59008
+ };
59009
+ const matchesHostnameOrSubdomain = ({
59010
+ hostname,
59011
+ candidateHostname
59012
+ }) => hostname === candidateHostname || hostname.endsWith(`.${candidateHostname}`);
58744
59013
  const getCurrentOrigin = () => {
58745
59014
  if (typeof window === "undefined") {
58746
59015
  return null;
@@ -58763,7 +59032,11 @@ const isAthenaAppUrl = ({
58763
59032
  appUrl
58764
59033
  }) => {
58765
59034
  const hostname = url.hostname.toLowerCase();
58766
- if (ATHENA_APP_HOSTNAMES.has(hostname) || hostname.endsWith(ATHENA_PREVIEW_HOSTNAME_SUFFIX)) {
59035
+ if (ATHENA_APP_HOSTNAMES.has(hostname) || hostname.endsWith(ATHENA_PREVIEW_HOSTNAME_SUFFIX) || ATHENA_WORKSPACE_HOSTNAME_SUFFIXES.some((suffix) => hostname.endsWith(suffix))) {
59036
+ return true;
59037
+ }
59038
+ const configuredHostname = getHostname(appUrl);
59039
+ if (configuredHostname && matchesHostnameOrSubdomain({ hostname, candidateHostname: configuredHostname })) {
58767
59040
  return true;
58768
59041
  }
58769
59042
  const configuredOrigin = getOrigin(appUrl);
@@ -58794,7 +59067,11 @@ const parseAthenaCitationLink = ({
58794
59067
  url,
58795
59068
  assetId,
58796
59069
  assetIds,
58797
- assetType: normalizeAssetType(url.searchParams.get("asset_type") ?? url.searchParams.get("type"))
59070
+ assetType: normalizeAssetType$1(
59071
+ url.searchParams.get("asset_type") ?? url.searchParams.get("assetType") ?? url.searchParams.get("type")
59072
+ ),
59073
+ assetName: sanitizeDisplayName(url.searchParams.get("name")),
59074
+ embedSearchParams: getEmbedSearchParams(url)
58798
59075
  };
58799
59076
  };
58800
59077
  const isAthenaCitationUrl = ({
@@ -58842,12 +59119,19 @@ const useAthenaLinkClickHandler = () => {
58842
59119
  const citationMetadata = citationLink ? {
58843
59120
  assetId: citationLink.assetId,
58844
59121
  assetIds: citationLink.assetIds,
58845
- assetType: citationLink.assetType
59122
+ assetType: citationLink.assetType,
59123
+ assetName: citationLink.assetName,
59124
+ embedSearchParams: citationLink.embedSearchParams
58846
59125
  } : null;
58847
59126
  const openInAssetPanel = citationLink ? () => {
59127
+ const displayName = getCitationDisplayName({
59128
+ assetName: citationLink.assetName,
59129
+ linkText: trimmedLinkText
59130
+ });
58848
59131
  openAsset(citationLink.assetId, {
58849
- name: trimmedLinkText ?? void 0,
58850
- type: citationLink.assetType ?? void 0
59132
+ name: displayName ?? void 0,
59133
+ type: citationLink.assetType ?? void 0,
59134
+ embedSearchParams: citationLink.embedSearchParams
58851
59135
  });
58852
59136
  } : void 0;
58853
59137
  const context2 = {
@@ -63287,6 +63571,12 @@ function extractAssetId(result) {
63287
63571
  if (typeof id === "string" && id.startsWith("asset_")) return id;
63288
63572
  return null;
63289
63573
  }
63574
+ function extractAssetTitle(result) {
63575
+ const data = normalizeResult(result);
63576
+ if (!data) return null;
63577
+ const title = data.assetTitle ?? data.asset_title ?? data.title ?? data.name;
63578
+ return typeof title === "string" && title.trim().length > 0 ? title.trim() : null;
63579
+ }
63290
63580
  function resetAssetAutoOpen() {
63291
63581
  useAssetPanelStore.getState().resetAutoOpen();
63292
63582
  }
@@ -64006,6 +64296,7 @@ const OpenAssetToolUIImpl = ({
64006
64296
  const typedArgs = args;
64007
64297
  const argsAssetId = (typedArgs == null ? void 0 : typedArgs.asset_id) ?? (typedArgs == null ? void 0 : typedArgs.assetId) ?? "";
64008
64298
  const resultAssetId = extractAssetId(result);
64299
+ const resultAssetTitle = extractAssetTitle(result);
64009
64300
  const assetId = resultAssetId ?? (argsAssetId.startsWith("asset_") ? argsAssetId : null);
64010
64301
  const isRunning = (status == null ? void 0 : status.type) === "running";
64011
64302
  const isComplete = (status == null ? void 0 : status.type) === "complete" || !status;
@@ -64017,10 +64308,10 @@ const OpenAssetToolUIImpl = ({
64017
64308
  if (isComplete && !isCancelled && assetId && !wasCompleteAtMount.current) {
64018
64309
  const store = useAssetPanelStore.getState();
64019
64310
  if (store.markAutoOpened(assetId)) {
64020
- store.openAsset(assetId);
64311
+ store.openAsset(assetId, { name: resultAssetTitle ?? void 0 });
64021
64312
  }
64022
64313
  }
64023
- }, [isComplete, isCancelled, assetId]);
64314
+ }, [isComplete, isCancelled, assetId, resultAssetTitle]);
64024
64315
  return /* @__PURE__ */ jsxRuntime.jsx(
64025
64316
  ToolCard,
64026
64317
  {
@@ -64036,7 +64327,7 @@ const OpenAssetToolUIImpl = ({
64036
64327
  "button",
64037
64328
  {
64038
64329
  type: "button",
64039
- onClick: () => openAsset(assetId),
64330
+ onClick: () => openAsset(assetId, { name: resultAssetTitle ?? void 0 }),
64040
64331
  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",
64041
64332
  children: [
64042
64333
  /* @__PURE__ */ jsxRuntime.jsx(ExternalLink, { className: "size-3" }),
@@ -64961,14 +65252,58 @@ const AthenaUserMessage = ({
64961
65252
  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 } }) })
64962
65253
  }
64963
65254
  );
65255
+ const EMBED_ASSET_TYPE_ALIASES = {
65256
+ document: "document",
65257
+ image: "document",
65258
+ notebook: "notebook",
65259
+ pdf: "document",
65260
+ powerpoint_deck: "presentation",
65261
+ presentation: "presentation",
65262
+ puck_presentation: "presentation",
65263
+ sheet: "spreadsheet",
65264
+ spreadsheet: "spreadsheet",
65265
+ super_document: "document"
65266
+ };
64964
65267
  const embedCache = /* @__PURE__ */ new Map();
65268
+ const normalizeAssetType = (value) => {
65269
+ if (!value) {
65270
+ return null;
65271
+ }
65272
+ const normalizedValue = value.trim().replace(/^athena\//, "").toLowerCase().replace(/-/g, "_");
65273
+ return EMBED_ASSET_TYPE_ALIASES[normalizedValue] ?? null;
65274
+ };
65275
+ const appendEmbedSearchParams = ({
65276
+ embedUrl,
65277
+ embedSearchParams
65278
+ }) => {
65279
+ if (!embedSearchParams || Object.keys(embedSearchParams).length === 0) {
65280
+ return embedUrl;
65281
+ }
65282
+ const url = new URL(embedUrl);
65283
+ for (const [key, value] of Object.entries(embedSearchParams)) {
65284
+ if (!value) {
65285
+ continue;
65286
+ }
65287
+ url.searchParams.set(key, value);
65288
+ }
65289
+ return url.toString();
65290
+ };
64965
65291
  function useAssetEmbed(assetId, options = {
64966
65292
  backendUrl: ""
64967
65293
  }) {
64968
- const { readOnly = false, expiresInSeconds = 60 * 60 * 24 * 30, backendUrl, apiKey, token } = options;
65294
+ const {
65295
+ readOnly = false,
65296
+ expiresInSeconds = 60 * 60 * 24 * 30,
65297
+ backendUrl,
65298
+ apiKey,
65299
+ token,
65300
+ embedSearchParams
65301
+ } = options;
64969
65302
  const [embedUrl, setEmbedUrl] = React.useState(null);
64970
65303
  const [isLoading, setIsLoading] = React.useState(false);
64971
65304
  const [error2, setError] = React.useState(null);
65305
+ const [assetTitle, setAssetTitle] = React.useState(null);
65306
+ const [assetType, setAssetType] = React.useState(null);
64972
65307
  const abortRef = React.useRef(null);
64973
65308
  React.useEffect(() => {
64974
65309
  var _a2;
@@ -64976,14 +65311,18 @@ function useAssetEmbed(assetId, options = {
64976
65311
  setEmbedUrl(null);
64977
65312
  setIsLoading(false);
64978
65313
  setError(null);
65314
+ setAssetTitle(null);
65315
+ setAssetType(null);
64979
65316
  return;
64980
65317
  }
64981
- const cacheKey = `${assetId}:${readOnly}:${token ?? apiKey ?? "anon"}`;
65318
+ const cacheKey = `${assetId}:${readOnly}:${token ?? apiKey ?? "anon"}:${JSON.stringify(embedSearchParams ?? {})}`;
64982
65319
  const cached = embedCache.get(cacheKey);
64983
65320
  if (cached && cached.expiresAt > Date.now() / 1e3) {
64984
65321
  setEmbedUrl(cached.url);
64985
65322
  setIsLoading(false);
64986
65323
  setError(null);
65324
+ setAssetTitle(cached.assetTitle);
65325
+ setAssetType(cached.assetType);
64987
65326
  return;
64988
65327
  }
64989
65328
  const apiBaseUrl = backendUrl.replace(/\/api\/assistant-ui\/?$/, "");
@@ -64991,11 +65330,14 @@ function useAssetEmbed(assetId, options = {
64991
65330
  (_a2 = abortRef.current) == null ? void 0 : _a2.abort();
64992
65331
  const controller = new AbortController();
64993
65332
  abortRef.current = controller;
65333
+ setEmbedUrl(null);
64994
65334
  setIsLoading(true);
64995
65335
  setError(null);
65336
+ setAssetTitle(null);
65337
+ setAssetType(null);
64996
65338
  const headers = { "Content-Type": "application/json" };
64997
65339
  if (token) {
64998
- headers["Authorization"] = `Bearer ${token}`;
65340
+ headers.Authorization = `Bearer ${token}`;
64999
65341
  } else if (apiKey) {
65000
65342
  headers["X-API-KEY"] = apiKey;
65001
65343
  }
@@ -65015,17 +65357,31 @@ function useAssetEmbed(assetId, options = {
65015
65357
  }
65016
65358
  return res.json();
65017
65359
  }).then((data) => {
65018
- embedCache.set(`${assetId}:${readOnly}:${token ?? apiKey ?? "anon"}`, { url: data.embed_url, expiresAt: data.expires_at });
65019
- setEmbedUrl(data.embed_url);
65360
+ const resolvedAssetType = normalizeAssetType(data.athena_converted_type) ?? normalizeAssetType(data.athena_original_type);
65361
+ const resolvedEmbedUrl = appendEmbedSearchParams({
65362
+ embedUrl: data.embed_url,
65363
+ embedSearchParams
65364
+ });
65365
+ embedCache.set(cacheKey, {
65366
+ url: resolvedEmbedUrl,
65367
+ expiresAt: data.expires_at,
65368
+ assetTitle: data.title ?? null,
65369
+ assetType: resolvedAssetType
65370
+ });
65371
+ setEmbedUrl(resolvedEmbedUrl);
65372
+ setAssetTitle(data.title ?? null);
65373
+ setAssetType(resolvedAssetType);
65020
65374
  setIsLoading(false);
65021
65375
  }).catch((err) => {
65022
- if (err.name === "AbortError") return;
65376
+ if (err.name === "AbortError") {
65377
+ return;
65378
+ }
65023
65379
  setError(err.message);
65024
65380
  setIsLoading(false);
65025
65381
  });
65026
65382
  return () => controller.abort();
65027
- }, [assetId, readOnly, expiresInSeconds, backendUrl, apiKey, token]);
65028
- return { embedUrl, isLoading, error: error2 };
65383
+ }, [assetId, readOnly, expiresInSeconds, backendUrl, apiKey, token, embedSearchParams]);
65384
+ return { embedUrl, isLoading, error: error2, assetTitle, assetType };
65029
65385
  }
65030
65386
  const ASSET_TYPE_CONFIG = {
65031
65387
  presentation: { icon: Presentation, label: "Presentation" },
@@ -65035,13 +65391,28 @@ const ASSET_TYPE_CONFIG = {
65035
65391
  unknown: { icon: File$1, label: "Asset" }
65036
65392
  };
65037
65393
  const AssetIframe = React.memo(
65038
- ({ tabId, tabName }) => {
65394
+ ({ tabId, tabName, tabType, embedSearchParams }) => {
65039
65395
  const { backendUrl, apiKey, token } = useAthenaConfig();
65040
- const { embedUrl, isLoading, error: error2 } = useAssetEmbed(tabId, {
65396
+ const { embedUrl, isLoading, error: error2, assetTitle, assetType } = useAssetEmbed(tabId, {
65041
65397
  backendUrl,
65042
65398
  apiKey,
65043
- token
65399
+ token,
65400
+ embedSearchParams
65044
65401
  });
65402
+ React.useEffect(() => {
65403
+ if (!assetTitle && !assetType) {
65404
+ return;
65405
+ }
65406
+ const nextName = assetTitle ?? tabName;
65407
+ const nextType = assetType ?? tabType;
65408
+ if (nextName === tabName && nextType === tabType) {
65409
+ return;
65410
+ }
65411
+ useAssetPanelStore.getState().openAsset(tabId, {
65412
+ name: nextName ?? void 0,
65413
+ type: nextType
65414
+ });
65415
+ }, [assetTitle, assetType, tabId, tabName, tabType]);
65045
65416
  if (isLoading) {
65046
65417
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center", children: [
65047
65418
  /* @__PURE__ */ jsxRuntime.jsx(LoaderCircle, { className: "mx-auto size-6 animate-spin text-muted-foreground" }),
@@ -65126,7 +65497,15 @@ const PanelContent = ({
65126
65497
  }
65127
65498
  )
65128
65499
  ] }),
65129
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(AssetIframe, { tabId: tab.id, tabName: tab.name }) })
65500
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
65501
+ AssetIframe,
65502
+ {
65503
+ tabId: tab.id,
65504
+ tabName: tab.name,
65505
+ tabType: tab.type,
65506
+ embedSearchParams: tab.embedSearchParams
65507
+ }
65508
+ ) })
65130
65509
  ]
65131
65510
  },
65132
65511
  tab.id
@@ -65136,7 +65515,15 @@ const PanelContent = ({
65136
65515
  "div",
65137
65516
  {
65138
65517
  className: isActive2 ? "h-full w-full" : "hidden",
65139
- children: /* @__PURE__ */ jsxRuntime.jsx(AssetIframe, { tabId: tab.id, tabName: tab.name })
65518
+ children: /* @__PURE__ */ jsxRuntime.jsx(
65519
+ AssetIframe,
65520
+ {
65521
+ tabId: tab.id,
65522
+ tabName: tab.name,
65523
+ tabType: tab.type,
65524
+ embedSearchParams: tab.embedSearchParams
65525
+ }
65526
+ )
65140
65527
  },
65141
65528
  tab.id
65142
65529
  );