@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.js CHANGED
@@ -24723,6 +24723,34 @@ const resolveTokenOverride = ({
24723
24723
  }
24724
24724
  return token;
24725
24725
  };
24726
+ const useAthenaConfigValue = ({
24727
+ backendUrl,
24728
+ appUrl,
24729
+ apiKey,
24730
+ token,
24731
+ linkClicks,
24732
+ citationLinks
24733
+ }) => {
24734
+ const linkClicksRef = useRef(linkClicks);
24735
+ linkClicksRef.current = linkClicks;
24736
+ const citationLinksRef = useRef(citationLinks);
24737
+ citationLinksRef.current = citationLinks;
24738
+ return useMemo(
24739
+ () => ({
24740
+ backendUrl,
24741
+ appUrl,
24742
+ apiKey,
24743
+ token,
24744
+ get linkClicks() {
24745
+ return linkClicksRef.current;
24746
+ },
24747
+ get citationLinks() {
24748
+ return citationLinksRef.current;
24749
+ }
24750
+ }),
24751
+ [backendUrl, appUrl, apiKey, token]
24752
+ );
24753
+ };
24726
24754
  function AthenaStandalone({
24727
24755
  children,
24728
24756
  apiUrl,
@@ -24738,7 +24766,9 @@ function AthenaStandalone({
24738
24766
  workbench,
24739
24767
  knowledgeBase,
24740
24768
  systemPrompt,
24741
- threadId
24769
+ threadId,
24770
+ linkClicks,
24771
+ citationLinks
24742
24772
  }) {
24743
24773
  const auiTools = useMemo(() => Tools({ toolkit: frontendTools }), [frontendTools]);
24744
24774
  const aui = useAui({ tools: auiTools });
@@ -24756,10 +24786,14 @@ function AthenaStandalone({
24756
24786
  systemPrompt,
24757
24787
  threadId
24758
24788
  });
24759
- const athenaConfig = useMemo(
24760
- () => ({ backendUrl, appUrl, apiKey, token }),
24761
- [backendUrl, appUrl, apiKey, token]
24762
- );
24789
+ const athenaConfig = useAthenaConfigValue({
24790
+ backendUrl,
24791
+ appUrl,
24792
+ apiKey,
24793
+ token,
24794
+ linkClicks,
24795
+ citationLinks
24796
+ });
24763
24797
  return /* @__PURE__ */ jsx(AssistantRuntimeProvider, { aui, runtime, children: /* @__PURE__ */ jsx(AthenaContext.Provider, { value: athenaConfig, children: /* @__PURE__ */ jsx(TooltipProvider, { children }) }) });
24764
24798
  }
24765
24799
  function useAthenaRuntimeHook(config2) {
@@ -24793,7 +24827,9 @@ function AthenaWithThreadList({
24793
24827
  frontendTools,
24794
24828
  workbench,
24795
24829
  knowledgeBase,
24796
- systemPrompt
24830
+ systemPrompt,
24831
+ linkClicks,
24832
+ citationLinks
24797
24833
  }) {
24798
24834
  const adapter = useAthenaThreadListAdapter({
24799
24835
  backendUrl,
@@ -24854,10 +24890,14 @@ function AthenaWithThreadList({
24854
24890
  }, [authRefreshKey, handleRefresh]);
24855
24891
  const auiTools = useMemo(() => Tools({ toolkit: frontendTools }), [frontendTools]);
24856
24892
  const aui = useAui({ tools: auiTools });
24857
- const athenaConfig = useMemo(
24858
- () => ({ backendUrl, appUrl, apiKey, token }),
24859
- [backendUrl, appUrl, apiKey, token]
24860
- );
24893
+ const athenaConfig = useAthenaConfigValue({
24894
+ backendUrl,
24895
+ appUrl,
24896
+ apiKey,
24897
+ token,
24898
+ linkClicks,
24899
+ citationLinks
24900
+ });
24861
24901
  return /* @__PURE__ */ jsx(AssistantRuntimeProvider, { aui, runtime, children: /* @__PURE__ */ jsx(AthenaContext.Provider, { value: athenaConfig, children: /* @__PURE__ */ jsx(ThreadListRefreshContext.Provider, { value: handleRefresh, children: /* @__PURE__ */ jsx(TooltipProvider, { children }) }) }) });
24862
24902
  }
24863
24903
  function AthenaProvider({
@@ -24878,7 +24918,9 @@ function AthenaProvider({
24878
24918
  systemPrompt,
24879
24919
  threadId: threadIdProp,
24880
24920
  enableThreadList = false,
24881
- theme
24921
+ theme,
24922
+ linkClicks,
24923
+ citationLinks
24882
24924
  }) {
24883
24925
  const frontendToolNames = useMemo(() => Object.keys(frontendTools), [frontendTools]);
24884
24926
  const themeStyleVars = useMemo(() => theme ? themeToStyleVars(theme) : void 0, [theme]);
@@ -24918,6 +24960,8 @@ function AthenaProvider({
24918
24960
  workbench,
24919
24961
  knowledgeBase,
24920
24962
  systemPrompt,
24963
+ linkClicks,
24964
+ citationLinks,
24921
24965
  children
24922
24966
  }
24923
24967
  );
@@ -24939,6 +24983,8 @@ function AthenaProvider({
24939
24983
  knowledgeBase,
24940
24984
  systemPrompt,
24941
24985
  threadId: threadIdProp,
24986
+ linkClicks,
24987
+ citationLinks,
24942
24988
  children
24943
24989
  }
24944
24990
  );
@@ -58597,6 +58643,257 @@ const MentionExtension = Node3.create({
58597
58643
  };
58598
58644
  }
58599
58645
  });
58646
+ const useAssetPanelStore = create((set2, get2) => ({
58647
+ isOpen: false,
58648
+ tabs: [],
58649
+ activeTabId: null,
58650
+ viewMode: "tabs",
58651
+ isFullscreen: false,
58652
+ assetPanelHostCount: 0,
58653
+ autoOpenGeneration: 0,
58654
+ autoOpenedAssets: /* @__PURE__ */ new Map(),
58655
+ registerAssetPanelHost: () => set2((state) => ({ assetPanelHostCount: state.assetPanelHostCount + 1 })),
58656
+ unregisterAssetPanelHost: () => set2((state) => ({ assetPanelHostCount: Math.max(0, state.assetPanelHostCount - 1) })),
58657
+ openAsset: (assetId, meta) => set2((s) => {
58658
+ const existing = s.tabs.find((t) => t.id === assetId);
58659
+ if (existing) {
58660
+ const tabs = meta ? s.tabs.map(
58661
+ (t) => t.id === assetId ? { ...t, name: meta.name ?? t.name, type: meta.type ?? t.type } : t
58662
+ ) : s.tabs;
58663
+ return { isOpen: true, tabs, activeTabId: assetId };
58664
+ }
58665
+ const newTab = {
58666
+ id: assetId,
58667
+ name: (meta == null ? void 0 : meta.name) ?? null,
58668
+ type: (meta == null ? void 0 : meta.type) ?? "unknown"
58669
+ };
58670
+ return { isOpen: true, tabs: [...s.tabs, newTab], activeTabId: assetId };
58671
+ }),
58672
+ closeTab: (assetId) => set2((s) => {
58673
+ var _a2;
58674
+ const tabs = s.tabs.filter((t) => t.id !== assetId);
58675
+ if (tabs.length === 0) {
58676
+ return { isOpen: false, tabs: [], activeTabId: null, isFullscreen: false };
58677
+ }
58678
+ 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;
58679
+ return { tabs, activeTabId };
58680
+ }),
58681
+ setActiveTab: (assetId) => set2({ activeTabId: assetId, viewMode: "tabs" }),
58682
+ setViewMode: (mode) => set2({ viewMode: mode }),
58683
+ closePanel: () => set2({ isOpen: false, tabs: [], activeTabId: null, viewMode: "tabs", isFullscreen: false }),
58684
+ toggleFullscreen: () => set2((s) => ({ isFullscreen: !s.isFullscreen })),
58685
+ resetAutoOpen: () => set2((s) => ({ autoOpenGeneration: s.autoOpenGeneration + 1 })),
58686
+ markAutoOpened: (assetId) => {
58687
+ const state = get2();
58688
+ if (state.autoOpenedAssets.get(assetId) === state.autoOpenGeneration) {
58689
+ return false;
58690
+ }
58691
+ state.autoOpenedAssets.set(assetId, state.autoOpenGeneration);
58692
+ return true;
58693
+ }
58694
+ }));
58695
+ const ATHENA_APP_HOSTNAMES = /* @__PURE__ */ new Set(["app.athenaintel.com", "staging-app.athenaintel.com"]);
58696
+ const ATHENA_PREVIEW_HOSTNAME_SUFFIX = ".previews.athenaintel.com";
58697
+ const ASSET_TYPE_ALIASES = {
58698
+ document: "document",
58699
+ notebook: "notebook",
58700
+ pdf: "document",
58701
+ powerpoint: "presentation",
58702
+ presentation: "presentation",
58703
+ puck_presentation: "presentation",
58704
+ sheet: "spreadsheet",
58705
+ spreadsheet: "spreadsheet",
58706
+ super_document: "document"
58707
+ };
58708
+ const isAthenaSpacesPath = (url) => url.pathname.replace(/\/+$/, "") === "/dashboard/spaces";
58709
+ const normalizeAssetType = (value) => {
58710
+ if (!value) {
58711
+ return null;
58712
+ }
58713
+ const normalizedValue = value.trim().replace(/^athena\//, "").toLowerCase().replace(/-/g, "_");
58714
+ return ASSET_TYPE_ALIASES[normalizedValue] ?? null;
58715
+ };
58716
+ const getOrigin = (value) => {
58717
+ if (!value) {
58718
+ return null;
58719
+ }
58720
+ try {
58721
+ return new URL(value).origin;
58722
+ } catch {
58723
+ return null;
58724
+ }
58725
+ };
58726
+ const getCurrentOrigin = () => {
58727
+ if (typeof window === "undefined") {
58728
+ return null;
58729
+ }
58730
+ return window.location.origin;
58731
+ };
58732
+ const parseUrl = ({
58733
+ href,
58734
+ appUrl
58735
+ }) => {
58736
+ const fallbackBase = appUrl ?? getCurrentOrigin() ?? "https://app.athenaintel.com";
58737
+ try {
58738
+ return new URL(href, fallbackBase);
58739
+ } catch {
58740
+ return null;
58741
+ }
58742
+ };
58743
+ const isAthenaAppUrl = ({
58744
+ url,
58745
+ appUrl
58746
+ }) => {
58747
+ const hostname = url.hostname.toLowerCase();
58748
+ if (ATHENA_APP_HOSTNAMES.has(hostname) || hostname.endsWith(ATHENA_PREVIEW_HOSTNAME_SUFFIX)) {
58749
+ return true;
58750
+ }
58751
+ const configuredOrigin = getOrigin(appUrl);
58752
+ if (configuredOrigin && url.origin === configuredOrigin) {
58753
+ return true;
58754
+ }
58755
+ const currentOrigin = getCurrentOrigin();
58756
+ return !!currentOrigin && url.origin === currentOrigin;
58757
+ };
58758
+ const parseAthenaCitationLink = ({
58759
+ href,
58760
+ appUrl
58761
+ }) => {
58762
+ const url = parseUrl({ href, appUrl });
58763
+ if (!url || !isAthenaAppUrl({ url, appUrl }) || !isAthenaSpacesPath(url)) {
58764
+ return null;
58765
+ }
58766
+ const assetIdsParam = url.searchParams.get("asset_ids");
58767
+ if (!assetIdsParam) {
58768
+ return null;
58769
+ }
58770
+ const assetIds = assetIdsParam.split(",").map((value) => value.trim()).filter((value) => value.length > 0);
58771
+ const assetId = assetIds[0];
58772
+ if (!assetId) {
58773
+ return null;
58774
+ }
58775
+ return {
58776
+ url,
58777
+ assetId,
58778
+ assetIds,
58779
+ assetType: normalizeAssetType(url.searchParams.get("asset_type") ?? url.searchParams.get("type"))
58780
+ };
58781
+ };
58782
+ const isAthenaCitationUrl = ({
58783
+ href,
58784
+ appUrl
58785
+ }) => parseAthenaCitationLink({ href, appUrl }) !== null;
58786
+ const resolveAthenaLink = ({
58787
+ href,
58788
+ appUrl
58789
+ }) => {
58790
+ const url = parseUrl({ href, appUrl });
58791
+ if (!url) {
58792
+ return null;
58793
+ }
58794
+ const citation = parseAthenaCitationLink({ href, appUrl });
58795
+ if (citation) {
58796
+ return {
58797
+ url: citation.url,
58798
+ kind: "athena-citation",
58799
+ citation
58800
+ };
58801
+ }
58802
+ return {
58803
+ url,
58804
+ kind: isAthenaAppUrl({ url, appUrl }) ? "athena-app" : "external",
58805
+ citation: null
58806
+ };
58807
+ };
58808
+ const useAthenaLinkClickHandler = () => {
58809
+ const openAsset = useAssetPanelStore((state) => state.openAsset);
58810
+ const isAssetPanelAvailable = useAssetPanelStore((state) => state.assetPanelHostCount > 0);
58811
+ const athenaConfig = useContext(AthenaContext);
58812
+ const appUrl = athenaConfig == null ? void 0 : athenaConfig.appUrl;
58813
+ return useCallback(
58814
+ ({ href, linkText, target, nativeEvent }) => {
58815
+ var _a2, _b;
58816
+ const resolvedLink = resolveAthenaLink({ href, appUrl });
58817
+ if (!resolvedLink) {
58818
+ return false;
58819
+ }
58820
+ const linkClicks = athenaConfig == null ? void 0 : athenaConfig.linkClicks;
58821
+ const citationLinks = athenaConfig == null ? void 0 : athenaConfig.citationLinks;
58822
+ const trimmedLinkText = (linkText == null ? void 0 : linkText.trim()) || null;
58823
+ const citationLink = resolvedLink.citation;
58824
+ const citationMetadata = citationLink ? {
58825
+ assetId: citationLink.assetId,
58826
+ assetIds: citationLink.assetIds,
58827
+ assetType: citationLink.assetType
58828
+ } : null;
58829
+ const openInAssetPanel = citationLink ? () => {
58830
+ openAsset(citationLink.assetId, {
58831
+ name: trimmedLinkText ?? void 0,
58832
+ type: citationLink.assetType ?? void 0
58833
+ });
58834
+ } : void 0;
58835
+ const context2 = {
58836
+ href,
58837
+ url: resolvedLink.url,
58838
+ target: target ?? null,
58839
+ linkText: trimmedLinkText,
58840
+ isAssetPanelAvailable,
58841
+ kind: resolvedLink.kind,
58842
+ citation: citationMetadata,
58843
+ nativeEvent: nativeEvent ?? null,
58844
+ openInAssetPanel,
58845
+ openInBrowser: (nextTarget) => {
58846
+ var _a3;
58847
+ (_a3 = window.open(resolvedLink.url.toString(), nextTarget ?? target ?? "_blank")) == null ? void 0 : _a3.focus();
58848
+ }
58849
+ };
58850
+ if (((_a2 = linkClicks == null ? void 0 : linkClicks.onClick) == null ? void 0 : _a2.call(linkClicks, context2)) === true) {
58851
+ nativeEvent == null ? void 0 : nativeEvent.preventDefault();
58852
+ return true;
58853
+ }
58854
+ if (!citationLink || !openInAssetPanel || !citationMetadata) {
58855
+ return false;
58856
+ }
58857
+ const citationContext = {
58858
+ ...context2,
58859
+ kind: "athena-citation",
58860
+ citation: citationMetadata,
58861
+ assetId: citationMetadata.assetId,
58862
+ assetIds: citationMetadata.assetIds,
58863
+ assetType: citationMetadata.assetType,
58864
+ openInAssetPanel
58865
+ };
58866
+ if (((_b = citationLinks == null ? void 0 : citationLinks.onClick) == null ? void 0 : _b.call(citationLinks, citationContext)) === true) {
58867
+ nativeEvent == null ? void 0 : nativeEvent.preventDefault();
58868
+ return true;
58869
+ }
58870
+ if (((linkClicks == null ? void 0 : linkClicks.interceptAthenaCitations) ?? (citationLinks == null ? void 0 : citationLinks.interceptAthenaCitations)) === false) {
58871
+ return false;
58872
+ }
58873
+ if (!isAssetPanelAvailable) {
58874
+ return false;
58875
+ }
58876
+ citationContext.openInAssetPanel();
58877
+ nativeEvent == null ? void 0 : nativeEvent.preventDefault();
58878
+ return true;
58879
+ },
58880
+ [appUrl, athenaConfig, isAssetPanelAvailable, openAsset]
58881
+ );
58882
+ };
58883
+ const useAthenaCitationLinkHandler = () => {
58884
+ const athenaConfig = useContext(AthenaContext);
58885
+ const appUrl = athenaConfig == null ? void 0 : athenaConfig.appUrl;
58886
+ const handleLinkClick = useAthenaLinkClickHandler();
58887
+ return useCallback(
58888
+ (input) => {
58889
+ if (!parseAthenaCitationLink({ href: input.href, appUrl })) {
58890
+ return false;
58891
+ }
58892
+ return handleLinkClick(input);
58893
+ },
58894
+ [appUrl, handleLinkClick]
58895
+ );
58896
+ };
58600
58897
  const extensions = [
58601
58898
  index_default$2.configure({
58602
58899
  codeBlock: {
@@ -58606,7 +58903,7 @@ const extensions = [
58606
58903
  }
58607
58904
  }),
58608
58905
  index_default$3.configure({
58609
- openOnClick: true,
58906
+ openOnClick: false,
58610
58907
  autolink: true,
58611
58908
  HTMLAttributes: {
58612
58909
  class: "text-primary underline",
@@ -58634,6 +58931,9 @@ const extensions = [
58634
58931
  MentionExtension
58635
58932
  ];
58636
58933
  const TiptapText = ({ text: text2 }) => {
58934
+ const handleLinkClick = useAthenaLinkClickHandler();
58935
+ const handleLinkClickRef = useRef(handleLinkClick);
58936
+ handleLinkClickRef.current = handleLinkClick;
58637
58937
  const editor = useEditor({
58638
58938
  immediatelyRender: true,
58639
58939
  extensions,
@@ -58642,6 +58942,32 @@ const TiptapText = ({ text: text2 }) => {
58642
58942
  editorProps: {
58643
58943
  attributes: {
58644
58944
  class: "prose prose-sm dark:prose-invert max-w-none focus:outline-none"
58945
+ },
58946
+ handleClick: (_view, _pos, event) => {
58947
+ var _a2;
58948
+ if (event.button !== 0) {
58949
+ return false;
58950
+ }
58951
+ const target = event.target;
58952
+ const targetElement = target instanceof HTMLElement ? target : target instanceof Node ? target.parentElement : null;
58953
+ if (!targetElement) {
58954
+ return false;
58955
+ }
58956
+ const link2 = targetElement.closest("a[href]");
58957
+ if (!(link2 instanceof HTMLAnchorElement)) {
58958
+ return false;
58959
+ }
58960
+ if (handleLinkClickRef.current({
58961
+ href: link2.getAttribute("href") ?? link2.href,
58962
+ linkText: link2.textContent,
58963
+ target: link2.target,
58964
+ nativeEvent: event
58965
+ })) {
58966
+ return true;
58967
+ }
58968
+ event.preventDefault();
58969
+ (_a2 = window.open(link2.href, link2.target || "_blank")) == null ? void 0 : _a2.focus();
58970
+ return true;
58645
58971
  }
58646
58972
  }
58647
58973
  });
@@ -61740,52 +62066,6 @@ function CollapsibleTrigger({ ...props }) {
61740
62066
  function CollapsibleContent({ ...props }) {
61741
62067
  return /* @__PURE__ */ jsx(CollapsibleContent$1, { "data-slot": "collapsible-content", ...props });
61742
62068
  }
61743
- const useAssetPanelStore = create((set2, get2) => ({
61744
- isOpen: false,
61745
- tabs: [],
61746
- activeTabId: null,
61747
- viewMode: "tabs",
61748
- isFullscreen: false,
61749
- autoOpenGeneration: 0,
61750
- autoOpenedAssets: /* @__PURE__ */ new Map(),
61751
- openAsset: (assetId, meta) => set2((s) => {
61752
- const existing = s.tabs.find((t) => t.id === assetId);
61753
- if (existing) {
61754
- const tabs = meta ? s.tabs.map(
61755
- (t) => t.id === assetId ? { ...t, name: meta.name ?? t.name, type: meta.type ?? t.type } : t
61756
- ) : s.tabs;
61757
- return { isOpen: true, tabs, activeTabId: assetId };
61758
- }
61759
- const newTab = {
61760
- id: assetId,
61761
- name: (meta == null ? void 0 : meta.name) ?? null,
61762
- type: (meta == null ? void 0 : meta.type) ?? "unknown"
61763
- };
61764
- return { isOpen: true, tabs: [...s.tabs, newTab], activeTabId: assetId };
61765
- }),
61766
- closeTab: (assetId) => set2((s) => {
61767
- var _a2;
61768
- const tabs = s.tabs.filter((t) => t.id !== assetId);
61769
- if (tabs.length === 0) {
61770
- return { isOpen: false, tabs: [], activeTabId: null, isFullscreen: false };
61771
- }
61772
- 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;
61773
- return { tabs, activeTabId };
61774
- }),
61775
- setActiveTab: (assetId) => set2({ activeTabId: assetId, viewMode: "tabs" }),
61776
- setViewMode: (mode) => set2({ viewMode: mode }),
61777
- closePanel: () => set2({ isOpen: false, tabs: [], activeTabId: null, viewMode: "tabs", isFullscreen: false }),
61778
- toggleFullscreen: () => set2((s) => ({ isFullscreen: !s.isFullscreen })),
61779
- resetAutoOpen: () => set2((s) => ({ autoOpenGeneration: s.autoOpenGeneration + 1 })),
61780
- markAutoOpened: (assetId) => {
61781
- const state = get2();
61782
- if (state.autoOpenedAssets.get(assetId) === state.autoOpenGeneration) {
61783
- return false;
61784
- }
61785
- state.autoOpenedAssets.set(assetId, state.autoOpenGeneration);
61786
- return true;
61787
- }
61788
- }));
61789
62069
  const ANIMATION_DURATION = 200;
61790
62070
  const TOOL_META = {
61791
62071
  // Search & Browse
@@ -63148,6 +63428,7 @@ function parsePythonResult(result) {
63148
63428
  const data = normalizeResult(result);
63149
63429
  if (!data)
63150
63430
  return {
63431
+ outputs: [],
63151
63432
  stdout: null,
63152
63433
  stderr: null,
63153
63434
  value: null,
@@ -63155,7 +63436,9 @@ function parsePythonResult(result) {
63155
63436
  exception: null,
63156
63437
  imagePng: null,
63157
63438
  plotlyJson: null,
63158
- createdAssets: []
63439
+ createdAssets: [],
63440
+ assetId: null,
63441
+ deckId: null
63159
63442
  };
63160
63443
  const inner = typeof data.result === "object" && data.result !== null ? data.result : data;
63161
63444
  const stdout = inner.stdout ?? null;
@@ -63173,13 +63456,18 @@ function parsePythonResult(result) {
63173
63456
  }
63174
63457
  let imagePng = null;
63175
63458
  let plotlyJson = null;
63459
+ const outputs = [];
63176
63460
  if (inner.data && typeof inner.data === "object") {
63177
63461
  imagePng = inner.data.png ?? null;
63178
63462
  }
63179
63463
  if (Array.isArray(data.outputs)) {
63180
63464
  for (const output of data.outputs) {
63181
63465
  if (output && typeof output === "object") {
63466
+ const outputRecord = output;
63182
63467
  const mimeBundle = output.mime_bundle;
63468
+ let outputImagePng = null;
63469
+ let outputPlotlyJson = null;
63470
+ let outputTextPlain = null;
63183
63471
  if (mimeBundle && typeof mimeBundle === "object") {
63184
63472
  const mb = mimeBundle;
63185
63473
  if (!plotlyJson && typeof mb["plotly+json"] === "string") {
@@ -63188,12 +63476,52 @@ function parsePythonResult(result) {
63188
63476
  if (!imagePng && typeof mb["image/png"] === "string") {
63189
63477
  imagePng = mb["image/png"];
63190
63478
  }
63191
- }
63479
+ outputPlotlyJson = typeof mb["plotly+json"] === "string" ? mb["plotly+json"] : null;
63480
+ outputImagePng = typeof mb["image/png"] === "string" ? mb["image/png"] : null;
63481
+ outputTextPlain = typeof mb["text/plain"] === "string" ? mb["text/plain"] : null;
63482
+ }
63483
+ outputs.push({
63484
+ objectId: typeof outputRecord.object_id === "string" ? outputRecord.object_id : null,
63485
+ title: typeof outputRecord.title === "string" ? outputRecord.title : null,
63486
+ textPlain: outputTextPlain,
63487
+ imagePng: outputImagePng,
63488
+ plotlyJson: outputPlotlyJson,
63489
+ assetId: typeof outputRecord.asset_id === "string" ? outputRecord.asset_id : null
63490
+ });
63192
63491
  }
63193
63492
  }
63194
63493
  }
63195
63494
  const createdAssets = Array.isArray(data.created_assets) ? data.created_assets : [];
63196
- return { stdout, stderr, value, error: error2, exception, imagePng, plotlyJson, createdAssets };
63495
+ const assetId = typeof data.asset_id === "string" ? data.asset_id : null;
63496
+ const deckId = typeof data.deck_id === "string" ? data.deck_id : null;
63497
+ return {
63498
+ outputs,
63499
+ stdout,
63500
+ stderr,
63501
+ value,
63502
+ error: error2,
63503
+ exception,
63504
+ imagePng,
63505
+ plotlyJson,
63506
+ createdAssets,
63507
+ assetId,
63508
+ deckId
63509
+ };
63510
+ }
63511
+ function getExecutionTextOutput(parsed) {
63512
+ const output = [
63513
+ parsed.value,
63514
+ parsed.stdout,
63515
+ parsed.stderr,
63516
+ ...parsed.outputs.map((entry) => {
63517
+ if (!entry.textPlain) {
63518
+ return null;
63519
+ }
63520
+ return entry.title ? `${entry.title}
63521
+ ${entry.textPlain}` : entry.textPlain;
63522
+ })
63523
+ ].filter((chunk) => Boolean(chunk && chunk.trim())).join("\n\n");
63524
+ return output || null;
63197
63525
  }
63198
63526
  function getPlotly() {
63199
63527
  return window.Plotly;
@@ -63478,7 +63806,8 @@ const RunPythonCodeToolUIImpl = ({
63478
63806
  [result, isComplete]
63479
63807
  );
63480
63808
  const openAsset = useAssetPanelStore((s) => s.openAsset);
63481
- const hasOutput = parsed && (parsed.stdout || parsed.stderr || parsed.value);
63809
+ const outputText = parsed ? getExecutionTextOutput(parsed) : null;
63810
+ const hasOutput = Boolean(outputText);
63482
63811
  const hasError = parsed && (parsed.error || parsed.exception);
63483
63812
  const hasImage = parsed == null ? void 0 : parsed.imagePng;
63484
63813
  const hasPlotly = parsed == null ? void 0 : parsed.plotlyJson;
@@ -63499,7 +63828,7 @@ const RunPythonCodeToolUIImpl = ({
63499
63828
  /* @__PURE__ */ jsx(Terminal, { className: "size-3 text-muted-foreground" }),
63500
63829
  /* @__PURE__ */ jsx("span", { className: "text-[11px] font-medium text-muted-foreground", children: "Output" })
63501
63830
  ] }),
63502
- /* @__PURE__ */ 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") })
63831
+ /* @__PURE__ */ 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 })
63503
63832
  ] }),
63504
63833
  isComplete && hasError && /* @__PURE__ */ jsxs("div", { className: "border-t border-border/40 bg-destructive/10 px-4 py-2.5", children: [
63505
63834
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 mb-1", children: [
@@ -63547,6 +63876,109 @@ const RunPythonCodeToolUI = memo(
63547
63876
  RunPythonCodeToolUIImpl
63548
63877
  );
63549
63878
  RunPythonCodeToolUI.displayName = "RunPythonCodeToolUI";
63879
+ const ExecutePresentationCodeToolUIImpl = ({
63880
+ toolName,
63881
+ args,
63882
+ result,
63883
+ status
63884
+ }) => {
63885
+ var _a2;
63886
+ const typedArgs = args;
63887
+ const code2 = (typedArgs == null ? void 0 : typedArgs.code) ?? "";
63888
+ const summary = (typedArgs == null ? void 0 : typedArgs.summary) ?? null;
63889
+ const deckIdFromArgs = typeof (typedArgs == null ? void 0 : typedArgs.deck_id) === "string" ? typedArgs.deck_id : null;
63890
+ const isRunning = (status == null ? void 0 : status.type) === "running";
63891
+ const isComplete = (status == null ? void 0 : status.type) === "complete";
63892
+ const errorMsg = (status == null ? void 0 : status.type) === "incomplete" ? status.error : null;
63893
+ const parsed = useMemo(
63894
+ () => isComplete ? parsePythonResult(result) : null,
63895
+ [result, isComplete]
63896
+ );
63897
+ const outputText = parsed ? getExecutionTextOutput(parsed) : null;
63898
+ const assetId = (parsed == null ? void 0 : parsed.assetId) ?? null;
63899
+ const deckId = (parsed == null ? void 0 : parsed.deckId) ?? deckIdFromArgs;
63900
+ const hasError = parsed && (parsed.error || parsed.exception);
63901
+ const openAsset = useAssetPanelStore((s) => s.openAsset);
63902
+ const wasCompleteAtMount = useRef(isComplete);
63903
+ useEffect(() => {
63904
+ if (!isComplete || !assetId || wasCompleteAtMount.current) {
63905
+ return;
63906
+ }
63907
+ const store = useAssetPanelStore.getState();
63908
+ if (store.markAutoOpened(assetId)) {
63909
+ store.openAsset(assetId, { type: "presentation" });
63910
+ }
63911
+ }, [assetId, isComplete]);
63912
+ return /* @__PURE__ */ jsxs(
63913
+ ToolCard,
63914
+ {
63915
+ icon: Presentation,
63916
+ status: (status == null ? void 0 : status.type) ?? "complete",
63917
+ title: isRunning ? summary || "Executing presentation code..." : summary || "Presentation updated",
63918
+ subtitle: deckId ? `Deck ${truncate(deckId, 24)}` : assetId ? `Asset ${truncate(assetId, 24)}` : void 0,
63919
+ badge: "Deck",
63920
+ toolName,
63921
+ args: typedArgs,
63922
+ result,
63923
+ error: errorMsg,
63924
+ children: [
63925
+ assetId && isComplete && /* @__PURE__ */ jsx("div", { className: "border-t border-border/40 px-4 py-2.5", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3", children: [
63926
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
63927
+ /* @__PURE__ */ jsx("div", { className: "text-[11px] font-medium text-muted-foreground", children: "Open the updated deck in the asset panel" }),
63928
+ /* @__PURE__ */ jsx("div", { className: "truncate text-[11px] text-foreground/80", children: truncate(assetId, 32) })
63929
+ ] }),
63930
+ /* @__PURE__ */ jsxs(
63931
+ "button",
63932
+ {
63933
+ type: "button",
63934
+ onClick: () => openAsset(assetId, { type: "presentation" }),
63935
+ 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",
63936
+ children: [
63937
+ /* @__PURE__ */ jsx(ExternalLink, { className: "size-3" }),
63938
+ "Open deck"
63939
+ ]
63940
+ }
63941
+ )
63942
+ ] }) }),
63943
+ code2 && /* @__PURE__ */ jsx(ExpandableSection, { label: "Show code", children: /* @__PURE__ */ jsx(SyntaxHighlightedCode, { code: code2 }) }),
63944
+ isComplete && outputText && /* @__PURE__ */ jsxs("div", { className: "border-t border-border/40 px-4 py-2.5", children: [
63945
+ /* @__PURE__ */ jsxs("div", { className: "mb-1 flex items-center gap-1.5", children: [
63946
+ /* @__PURE__ */ jsx(Terminal, { className: "size-3 text-muted-foreground" }),
63947
+ /* @__PURE__ */ jsx("span", { className: "text-[11px] font-medium text-muted-foreground", children: "Execution log" })
63948
+ ] }),
63949
+ /* @__PURE__ */ 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 })
63950
+ ] }),
63951
+ isComplete && hasError && /* @__PURE__ */ jsxs("div", { className: "border-t border-border/40 bg-destructive/10 px-4 py-2.5", children: [
63952
+ /* @__PURE__ */ jsxs("div", { className: "mb-1 flex items-center gap-1.5", children: [
63953
+ /* @__PURE__ */ jsx(TriangleAlert, { className: "size-3 text-destructive" }),
63954
+ /* @__PURE__ */ jsx("span", { className: "text-[11px] font-medium text-destructive", children: parsed.exception ? `${parsed.exception.name}: ${parsed.exception.value}` : "Execution error" })
63955
+ ] }),
63956
+ /* @__PURE__ */ 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 })
63957
+ ] }),
63958
+ isComplete && parsed && parsed.createdAssets.length > 0 && /* @__PURE__ */ jsxs("div", { className: "border-t border-border/40 px-4 py-2", children: [
63959
+ /* @__PURE__ */ jsx("span", { className: "text-[11px] font-medium text-muted-foreground", children: "Created assets" }),
63960
+ /* @__PURE__ */ jsx("div", { className: "mt-1 flex flex-wrap gap-1.5", children: parsed.createdAssets.map((entry) => /* @__PURE__ */ jsxs(
63961
+ "button",
63962
+ {
63963
+ type: "button",
63964
+ onClick: () => openAsset(entry.asset_id),
63965
+ 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",
63966
+ children: [
63967
+ /* @__PURE__ */ jsx(ExternalLink, { className: "size-2.5" }),
63968
+ truncate(entry.asset_id, 20)
63969
+ ]
63970
+ },
63971
+ entry.asset_id
63972
+ )) })
63973
+ ] })
63974
+ ]
63975
+ }
63976
+ );
63977
+ };
63978
+ const ExecutePresentationCodeToolUI = memo(
63979
+ ExecutePresentationCodeToolUIImpl
63980
+ );
63981
+ ExecutePresentationCodeToolUI.displayName = "ExecutePresentationCodeToolUI";
63550
63982
  const OpenAssetToolUIImpl = ({
63551
63983
  toolName,
63552
63984
  args,
@@ -63628,6 +64060,7 @@ const TOOL_UI_REGISTRY = {
63628
64060
  create_new_sheet: CreateSheetToolUI,
63629
64061
  create_powerpoint_deck: CreatePresentationToolUI,
63630
64062
  create_new_notebook: CreateNotebookToolUI,
64063
+ execute_presentation_code: ExecutePresentationCodeToolUI,
63631
64064
  run_python_code: RunPythonCodeToolUI,
63632
64065
  open_asset_in_workspace: OpenAssetToolUI
63633
64066
  };
@@ -64340,7 +64773,7 @@ const MessageError = () => /* @__PURE__ */ jsx(MessagePrimitiveError, { children
64340
64773
  }
64341
64774
  ) })
64342
64775
  ] }) });
64343
- const AthenaAssistantMessageEmpty = () => /* @__PURE__ */ jsx("span", { className: "shimmer text-muted-foreground", children: "Thinking..." });
64776
+ const AthenaAssistantMessageEmpty = () => /* @__PURE__ */ jsx("span", { className: "shimmer text-[13px] text-muted-foreground", children: "Thinking..." });
64344
64777
  const AthenaReasoningPart = ({
64345
64778
  text: text2,
64346
64779
  status,
@@ -64390,7 +64823,7 @@ const AthenaReasoningPart = ({
64390
64823
  className: "flex w-full items-center justify-between gap-3 text-left",
64391
64824
  "aria-label": isRunning ? "Toggle reasoning while streaming" : "Toggle reasoning",
64392
64825
  children: [
64393
- /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-center gap-2 text-sm font-medium text-muted-foreground", children: [
64826
+ /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-center gap-2 text-[13px] font-medium text-muted-foreground", children: [
64394
64827
  /* @__PURE__ */ jsx(Brain, { className: "size-4 shrink-0" }),
64395
64828
  /* @__PURE__ */ jsx("span", { children: isRunning ? "Reasoning..." : "Reasoning" })
64396
64829
  ] }),
@@ -64411,7 +64844,7 @@ const AthenaReasoningPart = ({
64411
64844
  ]
64412
64845
  }
64413
64846
  ) }),
64414
- /* @__PURE__ */ jsx(CollapsibleContent, { className: "pt-3", children: isRunning && !hasText ? /* @__PURE__ */ jsx("span", { className: "shimmer text-sm text-muted-foreground", children: "Analyzing..." }) : isRunning ? /* @__PURE__ */ jsx("div", { className: "whitespace-pre-wrap break-words text-sm leading-relaxed text-foreground", children: text2 }) : /* @__PURE__ */ jsx("div", { className: "aui-assistant-reasoning-body text-sm", children: /* @__PURE__ */ jsx(EffectiveTextComponent, { ...reasoningTextProps }) }) })
64847
+ /* @__PURE__ */ jsx(CollapsibleContent, { className: "pt-3", children: isRunning && !hasText ? /* @__PURE__ */ jsx("span", { className: "shimmer text-[13px] text-muted-foreground", children: "Analyzing..." }) : isRunning ? /* @__PURE__ */ jsx("div", { className: "whitespace-pre-wrap break-words text-[13px] leading-relaxed text-foreground", children: text2 }) : /* @__PURE__ */ jsx("div", { className: "aui-assistant-reasoning-body text-[13px] leading-relaxed", children: /* @__PURE__ */ jsx(EffectiveTextComponent, { ...reasoningTextProps }) }) })
64415
64848
  ]
64416
64849
  }
64417
64850
  );
@@ -64620,9 +65053,27 @@ const AssetIframe = memo(
64620
65053
  }
64621
65054
  );
64622
65055
  AssetIframe.displayName = "AssetIframe";
64623
- const PanelContent = () => {
64624
- const { tabs, activeTabId, viewMode, closeTab } = useAssetPanelStore();
65056
+ const PanelContent = ({
65057
+ manageAssetPanelHostRegistration
65058
+ }) => {
65059
+ const {
65060
+ tabs,
65061
+ activeTabId,
65062
+ viewMode,
65063
+ closeTab,
65064
+ registerAssetPanelHost,
65065
+ unregisterAssetPanelHost
65066
+ } = useAssetPanelStore();
64625
65067
  const isTiled = viewMode === "tiled" && tabs.length >= 2;
65068
+ useEffect(() => {
65069
+ if (!manageAssetPanelHostRegistration) {
65070
+ return;
65071
+ }
65072
+ registerAssetPanelHost();
65073
+ return () => {
65074
+ unregisterAssetPanelHost();
65075
+ };
65076
+ }, [manageAssetPanelHostRegistration, registerAssetPanelHost, unregisterAssetPanelHost]);
64626
65077
  const gridClass = useMemo(() => {
64627
65078
  const n = tabs.length;
64628
65079
  if (n <= 1) return "";
@@ -64752,12 +65203,14 @@ const PanelHeader = ({ fullscreen }) => {
64752
65203
  )
64753
65204
  ] });
64754
65205
  };
64755
- const AssetPanel = () => {
65206
+ const AssetPanel = ({
65207
+ manageAssetPanelHostRegistration = true
65208
+ }) => {
64756
65209
  const isFullscreen = useAssetPanelStore((s) => s.isFullscreen);
64757
65210
  const content = /* @__PURE__ */ jsxs(Fragment$2, { children: [
64758
65211
  /* @__PURE__ */ jsx(PanelHeader, { fullscreen: isFullscreen }),
64759
65212
  /* @__PURE__ */ jsx(TabBar, {}),
64760
- /* @__PURE__ */ jsx(PanelContent, {})
65213
+ /* @__PURE__ */ jsx(PanelContent, { manageAssetPanelHostRegistration })
64761
65214
  ] });
64762
65215
  if (isFullscreen) {
64763
65216
  return /* @__PURE__ */ jsx("div", { className: "fixed inset-0 z-50 flex flex-col bg-background", children: content });
@@ -64770,9 +65223,17 @@ const AthenaLayout = ({
64770
65223
  minPercent = 25
64771
65224
  }) => {
64772
65225
  const isOpen = useAssetPanelStore((s) => s.isOpen);
65226
+ const registerAssetPanelHost = useAssetPanelStore((s) => s.registerAssetPanelHost);
65227
+ const unregisterAssetPanelHost = useAssetPanelStore((s) => s.unregisterAssetPanelHost);
64773
65228
  const [chatPercent, setChatPercent] = useState(defaultChatPercent);
64774
65229
  const containerRef = useRef(null);
64775
65230
  const dragging = useRef(false);
65231
+ useEffect(() => {
65232
+ registerAssetPanelHost();
65233
+ return () => {
65234
+ unregisterAssetPanelHost();
65235
+ };
65236
+ }, [registerAssetPanelHost, unregisterAssetPanelHost]);
64776
65237
  const onPointerDown = useCallback(
64777
65238
  (e) => {
64778
65239
  e.preventDefault();
@@ -64814,7 +65275,7 @@ const AthenaLayout = ({
64814
65275
  onPointerUp
64815
65276
  }
64816
65277
  ),
64817
- /* @__PURE__ */ jsx("div", { className: "flex h-full flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsx(AssetPanel, {}) })
65278
+ /* @__PURE__ */ jsx("div", { className: "flex h-full flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsx(AssetPanel, { manageAssetPanelHostRegistration: false }) })
64818
65279
  ] });
64819
65280
  };
64820
65281
  function ThreadList({ className }) {
@@ -65011,7 +65472,9 @@ export {
65011
65472
  createAssetToolUI,
65012
65473
  formatToolName,
65013
65474
  getAssetInfo,
65475
+ isAthenaCitationUrl,
65014
65476
  normalizeResult,
65477
+ parseAthenaCitationLink,
65015
65478
  resetAssetAutoOpen,
65016
65479
  themeToStyleVars,
65017
65480
  themes,
@@ -65020,7 +65483,9 @@ export {
65020
65483
  useAppendToComposer,
65021
65484
  useAssetEmbed,
65022
65485
  useAssetPanelStore,
65486
+ useAthenaCitationLinkHandler,
65023
65487
  useAthenaConfig,
65488
+ useAthenaLinkClickHandler,
65024
65489
  useAthenaRuntime,
65025
65490
  useComposerAttachment,
65026
65491
  useFileUpload,