@athenaintel/react 0.9.12 → 0.9.13

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/README.md CHANGED
@@ -48,6 +48,44 @@ function App() {
48
48
 
49
49
  If `config.appUrl` is omitted, the provider resolves it from the parent bridge or from the matching Athena environment defaults. Known Athena staging and production `apiUrl` and `backendUrl` values automatically fall back to the corresponding frontend origin.
50
50
 
51
+ ## Citation Links
52
+
53
+ When you render chat inside `<AthenaLayout>`, Athena citation links (`app.athenaintel.com/dashboard/spaces?...`) now open the referenced asset in the SDK asset pane by default instead of navigating away.
54
+
55
+ If your host app wants different behavior, configure `linkClicks` on `<AthenaProvider>` or use `useAthenaLinkClickHandler()` inside a custom message renderer. The hook runs for every rendered link; only Athena citation links are intercepted by default.
56
+
57
+ ```tsx
58
+ import { useMemo } from 'react';
59
+ import { AthenaChat, AthenaLayout, AthenaProvider } from '@athenaintel/react';
60
+
61
+ function App() {
62
+ const linkClicks = useMemo(
63
+ () => ({
64
+ onClick: (link) => {
65
+ if (link.kind !== 'athena-citation' || !link.openInAssetPanel) {
66
+ return false;
67
+ }
68
+
69
+ console.log('Citation clicked:', link.citation?.assetId);
70
+ link.openInAssetPanel();
71
+ return true;
72
+ },
73
+ }),
74
+ [],
75
+ );
76
+
77
+ return (
78
+ <AthenaProvider linkClicks={linkClicks}>
79
+ <AthenaLayout>
80
+ <AthenaChat />
81
+ </AthenaLayout>
82
+ </AthenaProvider>
83
+ );
84
+ }
85
+ ```
86
+
87
+ Set `linkClicks={{ interceptAthenaCitations: false }}` to keep Athena citation links opening in the browser while still letting your app observe all link clicks.
88
+
51
89
  ## Theming
52
90
 
53
91
  ```tsx
package/dist/index.cjs CHANGED
@@ -24741,6 +24741,34 @@ const resolveTokenOverride = ({
24741
24741
  }
24742
24742
  return token;
24743
24743
  };
24744
+ const useAthenaConfigValue = ({
24745
+ backendUrl,
24746
+ appUrl,
24747
+ apiKey,
24748
+ token,
24749
+ linkClicks,
24750
+ citationLinks
24751
+ }) => {
24752
+ const linkClicksRef = React.useRef(linkClicks);
24753
+ linkClicksRef.current = linkClicks;
24754
+ const citationLinksRef = React.useRef(citationLinks);
24755
+ citationLinksRef.current = citationLinks;
24756
+ return React.useMemo(
24757
+ () => ({
24758
+ backendUrl,
24759
+ appUrl,
24760
+ apiKey,
24761
+ token,
24762
+ get linkClicks() {
24763
+ return linkClicksRef.current;
24764
+ },
24765
+ get citationLinks() {
24766
+ return citationLinksRef.current;
24767
+ }
24768
+ }),
24769
+ [backendUrl, appUrl, apiKey, token]
24770
+ );
24771
+ };
24744
24772
  function AthenaStandalone({
24745
24773
  children,
24746
24774
  apiUrl,
@@ -24756,7 +24784,9 @@ function AthenaStandalone({
24756
24784
  workbench,
24757
24785
  knowledgeBase,
24758
24786
  systemPrompt,
24759
- threadId
24787
+ threadId,
24788
+ linkClicks,
24789
+ citationLinks
24760
24790
  }) {
24761
24791
  const auiTools = React.useMemo(() => Tools({ toolkit: frontendTools }), [frontendTools]);
24762
24792
  const aui = useAui({ tools: auiTools });
@@ -24774,10 +24804,14 @@ function AthenaStandalone({
24774
24804
  systemPrompt,
24775
24805
  threadId
24776
24806
  });
24777
- const athenaConfig = React.useMemo(
24778
- () => ({ backendUrl, appUrl, apiKey, token }),
24779
- [backendUrl, appUrl, apiKey, token]
24780
- );
24807
+ const athenaConfig = useAthenaConfigValue({
24808
+ backendUrl,
24809
+ appUrl,
24810
+ apiKey,
24811
+ token,
24812
+ linkClicks,
24813
+ citationLinks
24814
+ });
24781
24815
  return /* @__PURE__ */ jsxRuntime.jsx(AssistantRuntimeProvider, { aui, runtime, children: /* @__PURE__ */ jsxRuntime.jsx(AthenaContext.Provider, { value: athenaConfig, children: /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { children }) }) });
24782
24816
  }
24783
24817
  function useAthenaRuntimeHook(config2) {
@@ -24811,7 +24845,9 @@ function AthenaWithThreadList({
24811
24845
  frontendTools,
24812
24846
  workbench,
24813
24847
  knowledgeBase,
24814
- systemPrompt
24848
+ systemPrompt,
24849
+ linkClicks,
24850
+ citationLinks
24815
24851
  }) {
24816
24852
  const adapter = useAthenaThreadListAdapter({
24817
24853
  backendUrl,
@@ -24872,10 +24908,14 @@ function AthenaWithThreadList({
24872
24908
  }, [authRefreshKey, handleRefresh]);
24873
24909
  const auiTools = React.useMemo(() => Tools({ toolkit: frontendTools }), [frontendTools]);
24874
24910
  const aui = useAui({ tools: auiTools });
24875
- const athenaConfig = React.useMemo(
24876
- () => ({ backendUrl, appUrl, apiKey, token }),
24877
- [backendUrl, appUrl, apiKey, token]
24878
- );
24911
+ const athenaConfig = useAthenaConfigValue({
24912
+ backendUrl,
24913
+ appUrl,
24914
+ apiKey,
24915
+ token,
24916
+ linkClicks,
24917
+ citationLinks
24918
+ });
24879
24919
  return /* @__PURE__ */ jsxRuntime.jsx(AssistantRuntimeProvider, { aui, runtime, children: /* @__PURE__ */ jsxRuntime.jsx(AthenaContext.Provider, { value: athenaConfig, children: /* @__PURE__ */ jsxRuntime.jsx(ThreadListRefreshContext.Provider, { value: handleRefresh, children: /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { children }) }) }) });
24880
24920
  }
24881
24921
  function AthenaProvider({
@@ -24896,7 +24936,9 @@ function AthenaProvider({
24896
24936
  systemPrompt,
24897
24937
  threadId: threadIdProp,
24898
24938
  enableThreadList = false,
24899
- theme
24939
+ theme,
24940
+ linkClicks,
24941
+ citationLinks
24900
24942
  }) {
24901
24943
  const frontendToolNames = React.useMemo(() => Object.keys(frontendTools), [frontendTools]);
24902
24944
  const themeStyleVars = React.useMemo(() => theme ? themeToStyleVars(theme) : void 0, [theme]);
@@ -24936,6 +24978,8 @@ function AthenaProvider({
24936
24978
  workbench,
24937
24979
  knowledgeBase,
24938
24980
  systemPrompt,
24981
+ linkClicks,
24982
+ citationLinks,
24939
24983
  children
24940
24984
  }
24941
24985
  );
@@ -24957,6 +25001,8 @@ function AthenaProvider({
24957
25001
  knowledgeBase,
24958
25002
  systemPrompt,
24959
25003
  threadId: threadIdProp,
25004
+ linkClicks,
25005
+ citationLinks,
24960
25006
  children
24961
25007
  }
24962
25008
  );
@@ -58615,6 +58661,257 @@ const MentionExtension = Node3.create({
58615
58661
  };
58616
58662
  }
58617
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 };
58682
+ }
58683
+ const newTab = {
58684
+ id: assetId,
58685
+ name: (meta == null ? void 0 : meta.name) ?? null,
58686
+ type: (meta == null ? void 0 : meta.type) ?? "unknown"
58687
+ };
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 };
58695
+ }
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;
58708
+ }
58709
+ state.autoOpenedAssets.set(assetId, state.autoOpenGeneration);
58710
+ return true;
58711
+ }
58712
+ }));
58713
+ const ATHENA_APP_HOSTNAMES = /* @__PURE__ */ new Set(["app.athenaintel.com", "staging-app.athenaintel.com"]);
58714
+ const ATHENA_PREVIEW_HOSTNAME_SUFFIX = ".previews.athenaintel.com";
58715
+ const ASSET_TYPE_ALIASES = {
58716
+ document: "document",
58717
+ notebook: "notebook",
58718
+ pdf: "document",
58719
+ powerpoint: "presentation",
58720
+ presentation: "presentation",
58721
+ puck_presentation: "presentation",
58722
+ sheet: "spreadsheet",
58723
+ spreadsheet: "spreadsheet",
58724
+ super_document: "document"
58725
+ };
58726
+ const isAthenaSpacesPath = (url) => url.pathname.replace(/\/+$/, "") === "/dashboard/spaces";
58727
+ const normalizeAssetType = (value) => {
58728
+ if (!value) {
58729
+ return null;
58730
+ }
58731
+ const normalizedValue = value.trim().replace(/^athena\//, "").toLowerCase().replace(/-/g, "_");
58732
+ return ASSET_TYPE_ALIASES[normalizedValue] ?? null;
58733
+ };
58734
+ const getOrigin = (value) => {
58735
+ if (!value) {
58736
+ return null;
58737
+ }
58738
+ try {
58739
+ return new URL(value).origin;
58740
+ } catch {
58741
+ return null;
58742
+ }
58743
+ };
58744
+ const getCurrentOrigin = () => {
58745
+ if (typeof window === "undefined") {
58746
+ return null;
58747
+ }
58748
+ return window.location.origin;
58749
+ };
58750
+ const parseUrl = ({
58751
+ href,
58752
+ appUrl
58753
+ }) => {
58754
+ const fallbackBase = appUrl ?? getCurrentOrigin() ?? "https://app.athenaintel.com";
58755
+ try {
58756
+ return new URL(href, fallbackBase);
58757
+ } catch {
58758
+ return null;
58759
+ }
58760
+ };
58761
+ const isAthenaAppUrl = ({
58762
+ url,
58763
+ appUrl
58764
+ }) => {
58765
+ const hostname = url.hostname.toLowerCase();
58766
+ if (ATHENA_APP_HOSTNAMES.has(hostname) || hostname.endsWith(ATHENA_PREVIEW_HOSTNAME_SUFFIX)) {
58767
+ return true;
58768
+ }
58769
+ const configuredOrigin = getOrigin(appUrl);
58770
+ if (configuredOrigin && url.origin === configuredOrigin) {
58771
+ return true;
58772
+ }
58773
+ const currentOrigin = getCurrentOrigin();
58774
+ return !!currentOrigin && url.origin === currentOrigin;
58775
+ };
58776
+ const parseAthenaCitationLink = ({
58777
+ href,
58778
+ appUrl
58779
+ }) => {
58780
+ const url = parseUrl({ href, appUrl });
58781
+ if (!url || !isAthenaAppUrl({ url, appUrl }) || !isAthenaSpacesPath(url)) {
58782
+ return null;
58783
+ }
58784
+ const assetIdsParam = url.searchParams.get("asset_ids");
58785
+ if (!assetIdsParam) {
58786
+ return null;
58787
+ }
58788
+ const assetIds = assetIdsParam.split(",").map((value) => value.trim()).filter((value) => value.length > 0);
58789
+ const assetId = assetIds[0];
58790
+ if (!assetId) {
58791
+ return null;
58792
+ }
58793
+ return {
58794
+ url,
58795
+ assetId,
58796
+ assetIds,
58797
+ assetType: normalizeAssetType(url.searchParams.get("asset_type") ?? url.searchParams.get("type"))
58798
+ };
58799
+ };
58800
+ const isAthenaCitationUrl = ({
58801
+ href,
58802
+ appUrl
58803
+ }) => parseAthenaCitationLink({ href, appUrl }) !== null;
58804
+ const resolveAthenaLink = ({
58805
+ href,
58806
+ appUrl
58807
+ }) => {
58808
+ const url = parseUrl({ href, appUrl });
58809
+ if (!url) {
58810
+ return null;
58811
+ }
58812
+ const citation = parseAthenaCitationLink({ href, appUrl });
58813
+ if (citation) {
58814
+ return {
58815
+ url: citation.url,
58816
+ kind: "athena-citation",
58817
+ citation
58818
+ };
58819
+ }
58820
+ return {
58821
+ url,
58822
+ kind: isAthenaAppUrl({ url, appUrl }) ? "athena-app" : "external",
58823
+ citation: null
58824
+ };
58825
+ };
58826
+ const useAthenaLinkClickHandler = () => {
58827
+ const openAsset = useAssetPanelStore((state) => state.openAsset);
58828
+ const isAssetPanelAvailable = useAssetPanelStore((state) => state.assetPanelHostCount > 0);
58829
+ const athenaConfig = React.useContext(AthenaContext);
58830
+ const appUrl = athenaConfig == null ? void 0 : athenaConfig.appUrl;
58831
+ return React.useCallback(
58832
+ ({ href, linkText, target, nativeEvent }) => {
58833
+ var _a2, _b;
58834
+ const resolvedLink = resolveAthenaLink({ href, appUrl });
58835
+ if (!resolvedLink) {
58836
+ return false;
58837
+ }
58838
+ const linkClicks = athenaConfig == null ? void 0 : athenaConfig.linkClicks;
58839
+ const citationLinks = athenaConfig == null ? void 0 : athenaConfig.citationLinks;
58840
+ const trimmedLinkText = (linkText == null ? void 0 : linkText.trim()) || null;
58841
+ const citationLink = resolvedLink.citation;
58842
+ const citationMetadata = citationLink ? {
58843
+ assetId: citationLink.assetId,
58844
+ assetIds: citationLink.assetIds,
58845
+ assetType: citationLink.assetType
58846
+ } : null;
58847
+ const openInAssetPanel = citationLink ? () => {
58848
+ openAsset(citationLink.assetId, {
58849
+ name: trimmedLinkText ?? void 0,
58850
+ type: citationLink.assetType ?? void 0
58851
+ });
58852
+ } : void 0;
58853
+ const context2 = {
58854
+ href,
58855
+ url: resolvedLink.url,
58856
+ target: target ?? null,
58857
+ linkText: trimmedLinkText,
58858
+ isAssetPanelAvailable,
58859
+ kind: resolvedLink.kind,
58860
+ citation: citationMetadata,
58861
+ nativeEvent: nativeEvent ?? null,
58862
+ openInAssetPanel,
58863
+ openInBrowser: (nextTarget) => {
58864
+ var _a3;
58865
+ (_a3 = window.open(resolvedLink.url.toString(), nextTarget ?? target ?? "_blank")) == null ? void 0 : _a3.focus();
58866
+ }
58867
+ };
58868
+ if (((_a2 = linkClicks == null ? void 0 : linkClicks.onClick) == null ? void 0 : _a2.call(linkClicks, context2)) === true) {
58869
+ nativeEvent == null ? void 0 : nativeEvent.preventDefault();
58870
+ return true;
58871
+ }
58872
+ if (!citationLink || !openInAssetPanel || !citationMetadata) {
58873
+ return false;
58874
+ }
58875
+ const citationContext = {
58876
+ ...context2,
58877
+ kind: "athena-citation",
58878
+ citation: citationMetadata,
58879
+ assetId: citationMetadata.assetId,
58880
+ assetIds: citationMetadata.assetIds,
58881
+ assetType: citationMetadata.assetType,
58882
+ openInAssetPanel
58883
+ };
58884
+ if (((_b = citationLinks == null ? void 0 : citationLinks.onClick) == null ? void 0 : _b.call(citationLinks, citationContext)) === true) {
58885
+ nativeEvent == null ? void 0 : nativeEvent.preventDefault();
58886
+ return true;
58887
+ }
58888
+ if (((linkClicks == null ? void 0 : linkClicks.interceptAthenaCitations) ?? (citationLinks == null ? void 0 : citationLinks.interceptAthenaCitations)) === false) {
58889
+ return false;
58890
+ }
58891
+ if (!isAssetPanelAvailable) {
58892
+ return false;
58893
+ }
58894
+ citationContext.openInAssetPanel();
58895
+ nativeEvent == null ? void 0 : nativeEvent.preventDefault();
58896
+ return true;
58897
+ },
58898
+ [appUrl, athenaConfig, isAssetPanelAvailable, openAsset]
58899
+ );
58900
+ };
58901
+ const useAthenaCitationLinkHandler = () => {
58902
+ const athenaConfig = React.useContext(AthenaContext);
58903
+ const appUrl = athenaConfig == null ? void 0 : athenaConfig.appUrl;
58904
+ const handleLinkClick = useAthenaLinkClickHandler();
58905
+ return React.useCallback(
58906
+ (input) => {
58907
+ if (!parseAthenaCitationLink({ href: input.href, appUrl })) {
58908
+ return false;
58909
+ }
58910
+ return handleLinkClick(input);
58911
+ },
58912
+ [appUrl, handleLinkClick]
58913
+ );
58914
+ };
58618
58915
  const extensions = [
58619
58916
  index_default$2.configure({
58620
58917
  codeBlock: {
@@ -58624,7 +58921,7 @@ const extensions = [
58624
58921
  }
58625
58922
  }),
58626
58923
  index_default$3.configure({
58627
- openOnClick: true,
58924
+ openOnClick: false,
58628
58925
  autolink: true,
58629
58926
  HTMLAttributes: {
58630
58927
  class: "text-primary underline",
@@ -58652,6 +58949,9 @@ const extensions = [
58652
58949
  MentionExtension
58653
58950
  ];
58654
58951
  const TiptapText = ({ text: text2 }) => {
58952
+ const handleLinkClick = useAthenaLinkClickHandler();
58953
+ const handleLinkClickRef = React.useRef(handleLinkClick);
58954
+ handleLinkClickRef.current = handleLinkClick;
58655
58955
  const editor = useEditor({
58656
58956
  immediatelyRender: true,
58657
58957
  extensions,
@@ -58660,6 +58960,32 @@ const TiptapText = ({ text: text2 }) => {
58660
58960
  editorProps: {
58661
58961
  attributes: {
58662
58962
  class: "prose prose-sm dark:prose-invert max-w-none focus:outline-none"
58963
+ },
58964
+ handleClick: (_view, _pos, event) => {
58965
+ var _a2;
58966
+ if (event.button !== 0) {
58967
+ return false;
58968
+ }
58969
+ const target = event.target;
58970
+ const targetElement = target instanceof HTMLElement ? target : target instanceof Node ? target.parentElement : null;
58971
+ if (!targetElement) {
58972
+ return false;
58973
+ }
58974
+ const link2 = targetElement.closest("a[href]");
58975
+ if (!(link2 instanceof HTMLAnchorElement)) {
58976
+ return false;
58977
+ }
58978
+ if (handleLinkClickRef.current({
58979
+ href: link2.getAttribute("href") ?? link2.href,
58980
+ linkText: link2.textContent,
58981
+ target: link2.target,
58982
+ nativeEvent: event
58983
+ })) {
58984
+ return true;
58985
+ }
58986
+ event.preventDefault();
58987
+ (_a2 = window.open(link2.href, link2.target || "_blank")) == null ? void 0 : _a2.focus();
58988
+ return true;
58663
58989
  }
58664
58990
  }
58665
58991
  });
@@ -61758,52 +62084,6 @@ function CollapsibleTrigger({ ...props }) {
61758
62084
  function CollapsibleContent({ ...props }) {
61759
62085
  return /* @__PURE__ */ jsxRuntime.jsx(CollapsibleContent$1, { "data-slot": "collapsible-content", ...props });
61760
62086
  }
61761
- const useAssetPanelStore = create((set2, get2) => ({
61762
- isOpen: false,
61763
- tabs: [],
61764
- activeTabId: null,
61765
- viewMode: "tabs",
61766
- isFullscreen: false,
61767
- autoOpenGeneration: 0,
61768
- autoOpenedAssets: /* @__PURE__ */ new Map(),
61769
- openAsset: (assetId, meta) => set2((s) => {
61770
- const existing = s.tabs.find((t) => t.id === assetId);
61771
- if (existing) {
61772
- const tabs = meta ? s.tabs.map(
61773
- (t) => t.id === assetId ? { ...t, name: meta.name ?? t.name, type: meta.type ?? t.type } : t
61774
- ) : s.tabs;
61775
- return { isOpen: true, tabs, activeTabId: assetId };
61776
- }
61777
- const newTab = {
61778
- id: assetId,
61779
- name: (meta == null ? void 0 : meta.name) ?? null,
61780
- type: (meta == null ? void 0 : meta.type) ?? "unknown"
61781
- };
61782
- return { isOpen: true, tabs: [...s.tabs, newTab], activeTabId: assetId };
61783
- }),
61784
- closeTab: (assetId) => set2((s) => {
61785
- var _a2;
61786
- const tabs = s.tabs.filter((t) => t.id !== assetId);
61787
- if (tabs.length === 0) {
61788
- return { isOpen: false, tabs: [], activeTabId: null, isFullscreen: false };
61789
- }
61790
- 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;
61791
- return { tabs, activeTabId };
61792
- }),
61793
- setActiveTab: (assetId) => set2({ activeTabId: assetId, viewMode: "tabs" }),
61794
- setViewMode: (mode) => set2({ viewMode: mode }),
61795
- closePanel: () => set2({ isOpen: false, tabs: [], activeTabId: null, viewMode: "tabs", isFullscreen: false }),
61796
- toggleFullscreen: () => set2((s) => ({ isFullscreen: !s.isFullscreen })),
61797
- resetAutoOpen: () => set2((s) => ({ autoOpenGeneration: s.autoOpenGeneration + 1 })),
61798
- markAutoOpened: (assetId) => {
61799
- const state = get2();
61800
- if (state.autoOpenedAssets.get(assetId) === state.autoOpenGeneration) {
61801
- return false;
61802
- }
61803
- state.autoOpenedAssets.set(assetId, state.autoOpenGeneration);
61804
- return true;
61805
- }
61806
- }));
61807
62087
  const ANIMATION_DURATION = 200;
61808
62088
  const TOOL_META = {
61809
62089
  // Search & Browse
@@ -64638,9 +64918,27 @@ const AssetIframe = React.memo(
64638
64918
  }
64639
64919
  );
64640
64920
  AssetIframe.displayName = "AssetIframe";
64641
- const PanelContent = () => {
64642
- const { tabs, activeTabId, viewMode, closeTab } = useAssetPanelStore();
64921
+ const PanelContent = ({
64922
+ manageAssetPanelHostRegistration
64923
+ }) => {
64924
+ const {
64925
+ tabs,
64926
+ activeTabId,
64927
+ viewMode,
64928
+ closeTab,
64929
+ registerAssetPanelHost,
64930
+ unregisterAssetPanelHost
64931
+ } = useAssetPanelStore();
64643
64932
  const isTiled = viewMode === "tiled" && tabs.length >= 2;
64933
+ React.useEffect(() => {
64934
+ if (!manageAssetPanelHostRegistration) {
64935
+ return;
64936
+ }
64937
+ registerAssetPanelHost();
64938
+ return () => {
64939
+ unregisterAssetPanelHost();
64940
+ };
64941
+ }, [manageAssetPanelHostRegistration, registerAssetPanelHost, unregisterAssetPanelHost]);
64644
64942
  const gridClass = React.useMemo(() => {
64645
64943
  const n = tabs.length;
64646
64944
  if (n <= 1) return "";
@@ -64770,12 +65068,14 @@ const PanelHeader = ({ fullscreen }) => {
64770
65068
  )
64771
65069
  ] });
64772
65070
  };
64773
- const AssetPanel = () => {
65071
+ const AssetPanel = ({
65072
+ manageAssetPanelHostRegistration = true
65073
+ }) => {
64774
65074
  const isFullscreen = useAssetPanelStore((s) => s.isFullscreen);
64775
65075
  const content = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
64776
65076
  /* @__PURE__ */ jsxRuntime.jsx(PanelHeader, { fullscreen: isFullscreen }),
64777
65077
  /* @__PURE__ */ jsxRuntime.jsx(TabBar, {}),
64778
- /* @__PURE__ */ jsxRuntime.jsx(PanelContent, {})
65078
+ /* @__PURE__ */ jsxRuntime.jsx(PanelContent, { manageAssetPanelHostRegistration })
64779
65079
  ] });
64780
65080
  if (isFullscreen) {
64781
65081
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed inset-0 z-50 flex flex-col bg-background", children: content });
@@ -64788,9 +65088,17 @@ const AthenaLayout = ({
64788
65088
  minPercent = 25
64789
65089
  }) => {
64790
65090
  const isOpen = useAssetPanelStore((s) => s.isOpen);
65091
+ const registerAssetPanelHost = useAssetPanelStore((s) => s.registerAssetPanelHost);
65092
+ const unregisterAssetPanelHost = useAssetPanelStore((s) => s.unregisterAssetPanelHost);
64791
65093
  const [chatPercent, setChatPercent] = React.useState(defaultChatPercent);
64792
65094
  const containerRef = React.useRef(null);
64793
65095
  const dragging = React.useRef(false);
65096
+ React.useEffect(() => {
65097
+ registerAssetPanelHost();
65098
+ return () => {
65099
+ unregisterAssetPanelHost();
65100
+ };
65101
+ }, [registerAssetPanelHost, unregisterAssetPanelHost]);
64794
65102
  const onPointerDown = React.useCallback(
64795
65103
  (e) => {
64796
65104
  e.preventDefault();
@@ -64832,7 +65140,7 @@ const AthenaLayout = ({
64832
65140
  onPointerUp
64833
65141
  }
64834
65142
  ),
64835
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(AssetPanel, {}) })
65143
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(AssetPanel, { manageAssetPanelHostRegistration: false }) })
64836
65144
  ] });
64837
65145
  };
64838
65146
  function ThreadList({ className }) {
@@ -65028,7 +65336,9 @@ exports.cn = cn;
65028
65336
  exports.createAssetToolUI = createAssetToolUI;
65029
65337
  exports.formatToolName = formatToolName;
65030
65338
  exports.getAssetInfo = getAssetInfo;
65339
+ exports.isAthenaCitationUrl = isAthenaCitationUrl;
65031
65340
  exports.normalizeResult = normalizeResult;
65341
+ exports.parseAthenaCitationLink = parseAthenaCitationLink;
65032
65342
  exports.resetAssetAutoOpen = resetAssetAutoOpen;
65033
65343
  exports.themeToStyleVars = themeToStyleVars;
65034
65344
  exports.themes = themes;
@@ -65037,7 +65347,9 @@ exports.tryParseJson = tryParseJson$1;
65037
65347
  exports.useAppendToComposer = useAppendToComposer;
65038
65348
  exports.useAssetEmbed = useAssetEmbed;
65039
65349
  exports.useAssetPanelStore = useAssetPanelStore;
65350
+ exports.useAthenaCitationLinkHandler = useAthenaCitationLinkHandler;
65040
65351
  exports.useAthenaConfig = useAthenaConfig;
65352
+ exports.useAthenaLinkClickHandler = useAthenaLinkClickHandler;
65041
65353
  exports.useAthenaRuntime = useAthenaRuntime;
65042
65354
  exports.useComposerAttachment = useComposerAttachment;
65043
65355
  exports.useFileUpload = useFileUpload;