@athenaintel/react 0.9.12 → 0.9.14

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
@@ -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
@@ -63166,6 +63446,7 @@ function parsePythonResult(result) {
63166
63446
  const data = normalizeResult(result);
63167
63447
  if (!data)
63168
63448
  return {
63449
+ outputs: [],
63169
63450
  stdout: null,
63170
63451
  stderr: null,
63171
63452
  value: null,
@@ -63173,7 +63454,9 @@ function parsePythonResult(result) {
63173
63454
  exception: null,
63174
63455
  imagePng: null,
63175
63456
  plotlyJson: null,
63176
- createdAssets: []
63457
+ createdAssets: [],
63458
+ assetId: null,
63459
+ deckId: null
63177
63460
  };
63178
63461
  const inner = typeof data.result === "object" && data.result !== null ? data.result : data;
63179
63462
  const stdout = inner.stdout ?? null;
@@ -63191,13 +63474,18 @@ function parsePythonResult(result) {
63191
63474
  }
63192
63475
  let imagePng = null;
63193
63476
  let plotlyJson = null;
63477
+ const outputs = [];
63194
63478
  if (inner.data && typeof inner.data === "object") {
63195
63479
  imagePng = inner.data.png ?? null;
63196
63480
  }
63197
63481
  if (Array.isArray(data.outputs)) {
63198
63482
  for (const output of data.outputs) {
63199
63483
  if (output && typeof output === "object") {
63484
+ const outputRecord = output;
63200
63485
  const mimeBundle = output.mime_bundle;
63486
+ let outputImagePng = null;
63487
+ let outputPlotlyJson = null;
63488
+ let outputTextPlain = null;
63201
63489
  if (mimeBundle && typeof mimeBundle === "object") {
63202
63490
  const mb = mimeBundle;
63203
63491
  if (!plotlyJson && typeof mb["plotly+json"] === "string") {
@@ -63206,12 +63494,52 @@ function parsePythonResult(result) {
63206
63494
  if (!imagePng && typeof mb["image/png"] === "string") {
63207
63495
  imagePng = mb["image/png"];
63208
63496
  }
63209
- }
63497
+ outputPlotlyJson = typeof mb["plotly+json"] === "string" ? mb["plotly+json"] : null;
63498
+ outputImagePng = typeof mb["image/png"] === "string" ? mb["image/png"] : null;
63499
+ outputTextPlain = typeof mb["text/plain"] === "string" ? mb["text/plain"] : null;
63500
+ }
63501
+ outputs.push({
63502
+ objectId: typeof outputRecord.object_id === "string" ? outputRecord.object_id : null,
63503
+ title: typeof outputRecord.title === "string" ? outputRecord.title : null,
63504
+ textPlain: outputTextPlain,
63505
+ imagePng: outputImagePng,
63506
+ plotlyJson: outputPlotlyJson,
63507
+ assetId: typeof outputRecord.asset_id === "string" ? outputRecord.asset_id : null
63508
+ });
63210
63509
  }
63211
63510
  }
63212
63511
  }
63213
63512
  const createdAssets = Array.isArray(data.created_assets) ? data.created_assets : [];
63214
- return { stdout, stderr, value, error: error2, exception, imagePng, plotlyJson, createdAssets };
63513
+ const assetId = typeof data.asset_id === "string" ? data.asset_id : null;
63514
+ const deckId = typeof data.deck_id === "string" ? data.deck_id : null;
63515
+ return {
63516
+ outputs,
63517
+ stdout,
63518
+ stderr,
63519
+ value,
63520
+ error: error2,
63521
+ exception,
63522
+ imagePng,
63523
+ plotlyJson,
63524
+ createdAssets,
63525
+ assetId,
63526
+ deckId
63527
+ };
63528
+ }
63529
+ function getExecutionTextOutput(parsed) {
63530
+ const output = [
63531
+ parsed.value,
63532
+ parsed.stdout,
63533
+ parsed.stderr,
63534
+ ...parsed.outputs.map((entry) => {
63535
+ if (!entry.textPlain) {
63536
+ return null;
63537
+ }
63538
+ return entry.title ? `${entry.title}
63539
+ ${entry.textPlain}` : entry.textPlain;
63540
+ })
63541
+ ].filter((chunk) => Boolean(chunk && chunk.trim())).join("\n\n");
63542
+ return output || null;
63215
63543
  }
63216
63544
  function getPlotly() {
63217
63545
  return window.Plotly;
@@ -63496,7 +63824,8 @@ const RunPythonCodeToolUIImpl = ({
63496
63824
  [result, isComplete]
63497
63825
  );
63498
63826
  const openAsset = useAssetPanelStore((s) => s.openAsset);
63499
- const hasOutput = parsed && (parsed.stdout || parsed.stderr || parsed.value);
63827
+ const outputText = parsed ? getExecutionTextOutput(parsed) : null;
63828
+ const hasOutput = Boolean(outputText);
63500
63829
  const hasError = parsed && (parsed.error || parsed.exception);
63501
63830
  const hasImage = parsed == null ? void 0 : parsed.imagePng;
63502
63831
  const hasPlotly = parsed == null ? void 0 : parsed.plotlyJson;
@@ -63517,7 +63846,7 @@ const RunPythonCodeToolUIImpl = ({
63517
63846
  /* @__PURE__ */ jsxRuntime.jsx(Terminal, { className: "size-3 text-muted-foreground" }),
63518
63847
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[11px] font-medium text-muted-foreground", children: "Output" })
63519
63848
  ] }),
63520
- /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "max-h-48 overflow-auto whitespace-pre-wrap break-words rounded-md bg-muted/30 p-2 text-[11px] leading-relaxed font-mono text-foreground/80", children: [parsed.value, parsed.stdout, parsed.stderr].filter(Boolean).join("\n") })
63849
+ /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "max-h-48 overflow-auto whitespace-pre-wrap break-words rounded-md bg-muted/30 p-2 text-[11px] leading-relaxed font-mono text-foreground/80", children: outputText })
63521
63850
  ] }),
63522
63851
  isComplete && hasError && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-t border-border/40 bg-destructive/10 px-4 py-2.5", children: [
63523
63852
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 mb-1", children: [
@@ -63565,6 +63894,109 @@ const RunPythonCodeToolUI = React.memo(
63565
63894
  RunPythonCodeToolUIImpl
63566
63895
  );
63567
63896
  RunPythonCodeToolUI.displayName = "RunPythonCodeToolUI";
63897
+ const ExecutePresentationCodeToolUIImpl = ({
63898
+ toolName,
63899
+ args,
63900
+ result,
63901
+ status
63902
+ }) => {
63903
+ var _a2;
63904
+ const typedArgs = args;
63905
+ const code2 = (typedArgs == null ? void 0 : typedArgs.code) ?? "";
63906
+ const summary = (typedArgs == null ? void 0 : typedArgs.summary) ?? null;
63907
+ const deckIdFromArgs = typeof (typedArgs == null ? void 0 : typedArgs.deck_id) === "string" ? typedArgs.deck_id : null;
63908
+ const isRunning = (status == null ? void 0 : status.type) === "running";
63909
+ const isComplete = (status == null ? void 0 : status.type) === "complete";
63910
+ const errorMsg = (status == null ? void 0 : status.type) === "incomplete" ? status.error : null;
63911
+ const parsed = React.useMemo(
63912
+ () => isComplete ? parsePythonResult(result) : null,
63913
+ [result, isComplete]
63914
+ );
63915
+ const outputText = parsed ? getExecutionTextOutput(parsed) : null;
63916
+ const assetId = (parsed == null ? void 0 : parsed.assetId) ?? null;
63917
+ const deckId = (parsed == null ? void 0 : parsed.deckId) ?? deckIdFromArgs;
63918
+ const hasError = parsed && (parsed.error || parsed.exception);
63919
+ const openAsset = useAssetPanelStore((s) => s.openAsset);
63920
+ const wasCompleteAtMount = React.useRef(isComplete);
63921
+ React.useEffect(() => {
63922
+ if (!isComplete || !assetId || wasCompleteAtMount.current) {
63923
+ return;
63924
+ }
63925
+ const store = useAssetPanelStore.getState();
63926
+ if (store.markAutoOpened(assetId)) {
63927
+ store.openAsset(assetId, { type: "presentation" });
63928
+ }
63929
+ }, [assetId, isComplete]);
63930
+ return /* @__PURE__ */ jsxRuntime.jsxs(
63931
+ ToolCard,
63932
+ {
63933
+ icon: Presentation,
63934
+ status: (status == null ? void 0 : status.type) ?? "complete",
63935
+ title: isRunning ? summary || "Executing presentation code..." : summary || "Presentation updated",
63936
+ subtitle: deckId ? `Deck ${truncate(deckId, 24)}` : assetId ? `Asset ${truncate(assetId, 24)}` : void 0,
63937
+ badge: "Deck",
63938
+ toolName,
63939
+ args: typedArgs,
63940
+ result,
63941
+ error: errorMsg,
63942
+ children: [
63943
+ assetId && isComplete && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-border/40 px-4 py-2.5", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-3", children: [
63944
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
63945
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[11px] font-medium text-muted-foreground", children: "Open the updated deck in the asset panel" }),
63946
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate text-[11px] text-foreground/80", children: truncate(assetId, 32) })
63947
+ ] }),
63948
+ /* @__PURE__ */ jsxRuntime.jsxs(
63949
+ "button",
63950
+ {
63951
+ type: "button",
63952
+ onClick: () => openAsset(assetId, { type: "presentation" }),
63953
+ className: "flex shrink-0 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",
63954
+ children: [
63955
+ /* @__PURE__ */ jsxRuntime.jsx(ExternalLink, { className: "size-3" }),
63956
+ "Open deck"
63957
+ ]
63958
+ }
63959
+ )
63960
+ ] }) }),
63961
+ code2 && /* @__PURE__ */ jsxRuntime.jsx(ExpandableSection, { label: "Show code", children: /* @__PURE__ */ jsxRuntime.jsx(SyntaxHighlightedCode, { code: code2 }) }),
63962
+ isComplete && outputText && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-t border-border/40 px-4 py-2.5", children: [
63963
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-1 flex items-center gap-1.5", children: [
63964
+ /* @__PURE__ */ jsxRuntime.jsx(Terminal, { className: "size-3 text-muted-foreground" }),
63965
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[11px] font-medium text-muted-foreground", children: "Execution log" })
63966
+ ] }),
63967
+ /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "max-h-56 overflow-auto whitespace-pre-wrap break-words rounded-md bg-muted/30 p-2 text-[11px] leading-relaxed font-mono text-foreground/80", children: outputText })
63968
+ ] }),
63969
+ isComplete && hasError && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-t border-border/40 bg-destructive/10 px-4 py-2.5", children: [
63970
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-1 flex items-center gap-1.5", children: [
63971
+ /* @__PURE__ */ jsxRuntime.jsx(TriangleAlert, { className: "size-3 text-destructive" }),
63972
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[11px] font-medium text-destructive", children: parsed.exception ? `${parsed.exception.name}: ${parsed.exception.value}` : "Execution error" })
63973
+ ] }),
63974
+ /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "max-h-48 overflow-auto whitespace-pre-wrap break-words rounded-md bg-destructive/5 p-2 text-[11px] leading-relaxed font-mono text-destructive/80", children: ((_a2 = parsed.exception) == null ? void 0 : _a2.traceback) ?? parsed.error })
63975
+ ] }),
63976
+ isComplete && parsed && parsed.createdAssets.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-t border-border/40 px-4 py-2", children: [
63977
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[11px] font-medium text-muted-foreground", children: "Created assets" }),
63978
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 flex flex-wrap gap-1.5", children: parsed.createdAssets.map((entry) => /* @__PURE__ */ jsxRuntime.jsxs(
63979
+ "button",
63980
+ {
63981
+ type: "button",
63982
+ onClick: () => openAsset(entry.asset_id),
63983
+ className: "flex items-center gap-1 rounded-md border border-border/60 px-2 py-1 text-[11px] font-medium text-muted-foreground transition-colors hover:bg-muted/50 hover:text-foreground",
63984
+ children: [
63985
+ /* @__PURE__ */ jsxRuntime.jsx(ExternalLink, { className: "size-2.5" }),
63986
+ truncate(entry.asset_id, 20)
63987
+ ]
63988
+ },
63989
+ entry.asset_id
63990
+ )) })
63991
+ ] })
63992
+ ]
63993
+ }
63994
+ );
63995
+ };
63996
+ const ExecutePresentationCodeToolUI = React.memo(
63997
+ ExecutePresentationCodeToolUIImpl
63998
+ );
63999
+ ExecutePresentationCodeToolUI.displayName = "ExecutePresentationCodeToolUI";
63568
64000
  const OpenAssetToolUIImpl = ({
63569
64001
  toolName,
63570
64002
  args,
@@ -63646,6 +64078,7 @@ const TOOL_UI_REGISTRY = {
63646
64078
  create_new_sheet: CreateSheetToolUI,
63647
64079
  create_powerpoint_deck: CreatePresentationToolUI,
63648
64080
  create_new_notebook: CreateNotebookToolUI,
64081
+ execute_presentation_code: ExecutePresentationCodeToolUI,
63649
64082
  run_python_code: RunPythonCodeToolUI,
63650
64083
  open_asset_in_workspace: OpenAssetToolUI
63651
64084
  };
@@ -64358,7 +64791,7 @@ const MessageError = () => /* @__PURE__ */ jsxRuntime.jsx(MessagePrimitiveError,
64358
64791
  }
64359
64792
  ) })
64360
64793
  ] }) });
64361
- const AthenaAssistantMessageEmpty = () => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shimmer text-muted-foreground", children: "Thinking..." });
64794
+ const AthenaAssistantMessageEmpty = () => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shimmer text-[13px] text-muted-foreground", children: "Thinking..." });
64362
64795
  const AthenaReasoningPart = ({
64363
64796
  text: text2,
64364
64797
  status,
@@ -64408,7 +64841,7 @@ const AthenaReasoningPart = ({
64408
64841
  className: "flex w-full items-center justify-between gap-3 text-left",
64409
64842
  "aria-label": isRunning ? "Toggle reasoning while streaming" : "Toggle reasoning",
64410
64843
  children: [
64411
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 items-center gap-2 text-sm font-medium text-muted-foreground", children: [
64844
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 items-center gap-2 text-[13px] font-medium text-muted-foreground", children: [
64412
64845
  /* @__PURE__ */ jsxRuntime.jsx(Brain, { className: "size-4 shrink-0" }),
64413
64846
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: isRunning ? "Reasoning..." : "Reasoning" })
64414
64847
  ] }),
@@ -64429,7 +64862,7 @@ const AthenaReasoningPart = ({
64429
64862
  ]
64430
64863
  }
64431
64864
  ) }),
64432
- /* @__PURE__ */ jsxRuntime.jsx(CollapsibleContent, { className: "pt-3", children: isRunning && !hasText ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shimmer text-sm text-muted-foreground", children: "Analyzing..." }) : isRunning ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "whitespace-pre-wrap break-words text-sm leading-relaxed text-foreground", children: text2 }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aui-assistant-reasoning-body text-sm", children: /* @__PURE__ */ jsxRuntime.jsx(EffectiveTextComponent, { ...reasoningTextProps }) }) })
64865
+ /* @__PURE__ */ jsxRuntime.jsx(CollapsibleContent, { className: "pt-3", children: isRunning && !hasText ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shimmer text-[13px] text-muted-foreground", children: "Analyzing..." }) : isRunning ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "whitespace-pre-wrap break-words text-[13px] leading-relaxed text-foreground", children: text2 }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aui-assistant-reasoning-body text-[13px] leading-relaxed", children: /* @__PURE__ */ jsxRuntime.jsx(EffectiveTextComponent, { ...reasoningTextProps }) }) })
64433
64866
  ]
64434
64867
  }
64435
64868
  );
@@ -64638,9 +65071,27 @@ const AssetIframe = React.memo(
64638
65071
  }
64639
65072
  );
64640
65073
  AssetIframe.displayName = "AssetIframe";
64641
- const PanelContent = () => {
64642
- const { tabs, activeTabId, viewMode, closeTab } = useAssetPanelStore();
65074
+ const PanelContent = ({
65075
+ manageAssetPanelHostRegistration
65076
+ }) => {
65077
+ const {
65078
+ tabs,
65079
+ activeTabId,
65080
+ viewMode,
65081
+ closeTab,
65082
+ registerAssetPanelHost,
65083
+ unregisterAssetPanelHost
65084
+ } = useAssetPanelStore();
64643
65085
  const isTiled = viewMode === "tiled" && tabs.length >= 2;
65086
+ React.useEffect(() => {
65087
+ if (!manageAssetPanelHostRegistration) {
65088
+ return;
65089
+ }
65090
+ registerAssetPanelHost();
65091
+ return () => {
65092
+ unregisterAssetPanelHost();
65093
+ };
65094
+ }, [manageAssetPanelHostRegistration, registerAssetPanelHost, unregisterAssetPanelHost]);
64644
65095
  const gridClass = React.useMemo(() => {
64645
65096
  const n = tabs.length;
64646
65097
  if (n <= 1) return "";
@@ -64770,12 +65221,14 @@ const PanelHeader = ({ fullscreen }) => {
64770
65221
  )
64771
65222
  ] });
64772
65223
  };
64773
- const AssetPanel = () => {
65224
+ const AssetPanel = ({
65225
+ manageAssetPanelHostRegistration = true
65226
+ }) => {
64774
65227
  const isFullscreen = useAssetPanelStore((s) => s.isFullscreen);
64775
65228
  const content = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
64776
65229
  /* @__PURE__ */ jsxRuntime.jsx(PanelHeader, { fullscreen: isFullscreen }),
64777
65230
  /* @__PURE__ */ jsxRuntime.jsx(TabBar, {}),
64778
- /* @__PURE__ */ jsxRuntime.jsx(PanelContent, {})
65231
+ /* @__PURE__ */ jsxRuntime.jsx(PanelContent, { manageAssetPanelHostRegistration })
64779
65232
  ] });
64780
65233
  if (isFullscreen) {
64781
65234
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed inset-0 z-50 flex flex-col bg-background", children: content });
@@ -64788,9 +65241,17 @@ const AthenaLayout = ({
64788
65241
  minPercent = 25
64789
65242
  }) => {
64790
65243
  const isOpen = useAssetPanelStore((s) => s.isOpen);
65244
+ const registerAssetPanelHost = useAssetPanelStore((s) => s.registerAssetPanelHost);
65245
+ const unregisterAssetPanelHost = useAssetPanelStore((s) => s.unregisterAssetPanelHost);
64791
65246
  const [chatPercent, setChatPercent] = React.useState(defaultChatPercent);
64792
65247
  const containerRef = React.useRef(null);
64793
65248
  const dragging = React.useRef(false);
65249
+ React.useEffect(() => {
65250
+ registerAssetPanelHost();
65251
+ return () => {
65252
+ unregisterAssetPanelHost();
65253
+ };
65254
+ }, [registerAssetPanelHost, unregisterAssetPanelHost]);
64794
65255
  const onPointerDown = React.useCallback(
64795
65256
  (e) => {
64796
65257
  e.preventDefault();
@@ -64832,7 +65293,7 @@ const AthenaLayout = ({
64832
65293
  onPointerUp
64833
65294
  }
64834
65295
  ),
64835
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(AssetPanel, {}) })
65296
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(AssetPanel, { manageAssetPanelHostRegistration: false }) })
64836
65297
  ] });
64837
65298
  };
64838
65299
  function ThreadList({ className }) {
@@ -65028,7 +65489,9 @@ exports.cn = cn;
65028
65489
  exports.createAssetToolUI = createAssetToolUI;
65029
65490
  exports.formatToolName = formatToolName;
65030
65491
  exports.getAssetInfo = getAssetInfo;
65492
+ exports.isAthenaCitationUrl = isAthenaCitationUrl;
65031
65493
  exports.normalizeResult = normalizeResult;
65494
+ exports.parseAthenaCitationLink = parseAthenaCitationLink;
65032
65495
  exports.resetAssetAutoOpen = resetAssetAutoOpen;
65033
65496
  exports.themeToStyleVars = themeToStyleVars;
65034
65497
  exports.themes = themes;
@@ -65037,7 +65500,9 @@ exports.tryParseJson = tryParseJson$1;
65037
65500
  exports.useAppendToComposer = useAppendToComposer;
65038
65501
  exports.useAssetEmbed = useAssetEmbed;
65039
65502
  exports.useAssetPanelStore = useAssetPanelStore;
65503
+ exports.useAthenaCitationLinkHandler = useAthenaCitationLinkHandler;
65040
65504
  exports.useAthenaConfig = useAthenaConfig;
65505
+ exports.useAthenaLinkClickHandler = useAthenaLinkClickHandler;
65041
65506
  exports.useAthenaRuntime = useAthenaRuntime;
65042
65507
  exports.useComposerAttachment = useComposerAttachment;
65043
65508
  exports.useFileUpload = useFileUpload;