@athenaintel/react 0.9.15 → 0.9.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -58875,14 +58875,20 @@ const useAssetPanelStore = create()(
58875
58875
  const existing = s.tabs.find((t) => t.id === assetId);
58876
58876
  if (existing) {
58877
58877
  const tabs = meta ? s.tabs.map(
58878
- (t) => t.id === assetId ? { ...t, name: meta.name ?? t.name, type: meta.type ?? t.type } : t
58878
+ (t) => t.id === assetId ? {
58879
+ ...t,
58880
+ name: meta.name ?? t.name,
58881
+ type: meta.type ?? t.type,
58882
+ embedSearchParams: meta.embedSearchParams ?? t.embedSearchParams
58883
+ } : t
58879
58884
  ) : s.tabs;
58880
58885
  return { isOpen: true, tabs, activeTabId: assetId };
58881
58886
  }
58882
58887
  const newTab = {
58883
58888
  id: assetId,
58884
58889
  name: (meta == null ? void 0 : meta.name) ?? null,
58885
- type: (meta == null ? void 0 : meta.type) ?? "unknown"
58890
+ type: (meta == null ? void 0 : meta.type) ?? "unknown",
58891
+ embedSearchParams: (meta == null ? void 0 : meta.embedSearchParams) ?? null
58886
58892
  };
58887
58893
  return { isOpen: true, tabs: [...s.tabs, newTab], activeTabId: assetId };
58888
58894
  }),
@@ -58943,13 +58949,43 @@ const ASSET_TYPE_ALIASES = {
58943
58949
  super_document: "document"
58944
58950
  };
58945
58951
  const isAthenaSpacesPath = (url) => url.pathname.replace(/\/+$/, "") === "/dashboard/spaces";
58946
- const normalizeAssetType = (value) => {
58952
+ const normalizeAssetType$1 = (value) => {
58947
58953
  if (!value) {
58948
58954
  return null;
58949
58955
  }
58950
58956
  const normalizedValue = value.trim().replace(/^athena\//, "").toLowerCase().replace(/-/g, "_");
58951
58957
  return ASSET_TYPE_ALIASES[normalizedValue] ?? null;
58952
58958
  };
58959
+ const isLikelyAssetId = (value) => !!value && /^(asset|thread|project|collection)_[a-z0-9-]+$/i.test(value.trim());
58960
+ const sanitizeDisplayName = (value) => {
58961
+ if (!value) {
58962
+ return null;
58963
+ }
58964
+ const trimmedValue = value.trim();
58965
+ if (!trimmedValue) {
58966
+ return null;
58967
+ }
58968
+ if (trimmedValue.startsWith('"') && trimmedValue.endsWith('"') || trimmedValue.startsWith("'") && trimmedValue.endsWith("'")) {
58969
+ return trimmedValue.slice(1, -1).trim() || null;
58970
+ }
58971
+ return trimmedValue;
58972
+ };
58973
+ const getCitationDisplayName = ({
58974
+ assetName,
58975
+ linkText
58976
+ }) => {
58977
+ const sanitizedAssetName = sanitizeDisplayName(assetName);
58978
+ const sanitizedLinkText = sanitizeDisplayName(linkText);
58979
+ const genericLinkTextPattern = /^(this|that|the)\s+asset$/i;
58980
+ if (sanitizedAssetName && !isLikelyAssetId(sanitizedAssetName)) {
58981
+ return sanitizedAssetName;
58982
+ }
58983
+ if (sanitizedLinkText && !genericLinkTextPattern.test(sanitizedLinkText)) {
58984
+ return sanitizedLinkText;
58985
+ }
58986
+ return sanitizedAssetName ?? sanitizedLinkText;
58987
+ };
58988
+ const getEmbedSearchParams = (url) => Object.fromEntries(url.searchParams.entries());
58953
58989
  const getOrigin = (value) => {
58954
58990
  if (!value) {
58955
58991
  return null;
@@ -59031,7 +59067,11 @@ const parseAthenaCitationLink = ({
59031
59067
  url,
59032
59068
  assetId,
59033
59069
  assetIds,
59034
- assetType: normalizeAssetType(url.searchParams.get("asset_type") ?? url.searchParams.get("type"))
59070
+ assetType: normalizeAssetType$1(
59071
+ url.searchParams.get("asset_type") ?? url.searchParams.get("assetType") ?? url.searchParams.get("type")
59072
+ ),
59073
+ assetName: sanitizeDisplayName(url.searchParams.get("name")),
59074
+ embedSearchParams: getEmbedSearchParams(url)
59035
59075
  };
59036
59076
  };
59037
59077
  const isAthenaCitationUrl = ({
@@ -59079,12 +59119,19 @@ const useAthenaLinkClickHandler = () => {
59079
59119
  const citationMetadata = citationLink ? {
59080
59120
  assetId: citationLink.assetId,
59081
59121
  assetIds: citationLink.assetIds,
59082
- assetType: citationLink.assetType
59122
+ assetType: citationLink.assetType,
59123
+ assetName: citationLink.assetName,
59124
+ embedSearchParams: citationLink.embedSearchParams
59083
59125
  } : null;
59084
59126
  const openInAssetPanel = citationLink ? () => {
59127
+ const displayName = getCitationDisplayName({
59128
+ assetName: citationLink.assetName,
59129
+ linkText: trimmedLinkText
59130
+ });
59085
59131
  openAsset(citationLink.assetId, {
59086
- name: trimmedLinkText ?? void 0,
59087
- type: citationLink.assetType ?? void 0
59132
+ name: displayName ?? void 0,
59133
+ type: citationLink.assetType ?? void 0,
59134
+ embedSearchParams: citationLink.embedSearchParams
59088
59135
  });
59089
59136
  } : void 0;
59090
59137
  const context2 = {
@@ -63524,6 +63571,12 @@ function extractAssetId(result) {
63524
63571
  if (typeof id === "string" && id.startsWith("asset_")) return id;
63525
63572
  return null;
63526
63573
  }
63574
+ function extractAssetTitle(result) {
63575
+ const data = normalizeResult(result);
63576
+ if (!data) return null;
63577
+ const title = data.assetTitle ?? data.asset_title ?? data.title ?? data.name;
63578
+ return typeof title === "string" && title.trim().length > 0 ? title.trim() : null;
63579
+ }
63527
63580
  function resetAssetAutoOpen() {
63528
63581
  useAssetPanelStore.getState().resetAutoOpen();
63529
63582
  }
@@ -64243,6 +64296,7 @@ const OpenAssetToolUIImpl = ({
64243
64296
  const typedArgs = args;
64244
64297
  const argsAssetId = (typedArgs == null ? void 0 : typedArgs.asset_id) ?? (typedArgs == null ? void 0 : typedArgs.assetId) ?? "";
64245
64298
  const resultAssetId = extractAssetId(result);
64299
+ const resultAssetTitle = extractAssetTitle(result);
64246
64300
  const assetId = resultAssetId ?? (argsAssetId.startsWith("asset_") ? argsAssetId : null);
64247
64301
  const isRunning = (status == null ? void 0 : status.type) === "running";
64248
64302
  const isComplete = (status == null ? void 0 : status.type) === "complete" || !status;
@@ -64254,10 +64308,10 @@ const OpenAssetToolUIImpl = ({
64254
64308
  if (isComplete && !isCancelled && assetId && !wasCompleteAtMount.current) {
64255
64309
  const store = useAssetPanelStore.getState();
64256
64310
  if (store.markAutoOpened(assetId)) {
64257
- store.openAsset(assetId);
64311
+ store.openAsset(assetId, { name: resultAssetTitle ?? void 0 });
64258
64312
  }
64259
64313
  }
64260
- }, [isComplete, isCancelled, assetId]);
64314
+ }, [isComplete, isCancelled, assetId, resultAssetTitle]);
64261
64315
  return /* @__PURE__ */ jsxRuntime.jsx(
64262
64316
  ToolCard,
64263
64317
  {
@@ -64273,7 +64327,7 @@ const OpenAssetToolUIImpl = ({
64273
64327
  "button",
64274
64328
  {
64275
64329
  type: "button",
64276
- onClick: () => openAsset(assetId),
64330
+ onClick: () => openAsset(assetId, { name: resultAssetTitle ?? void 0 }),
64277
64331
  className: "flex items-center gap-1.5 rounded-md border border-border/60 px-3 py-1.5 text-xs font-medium text-muted-foreground transition-colors hover:bg-muted/50 hover:text-foreground",
64278
64332
  children: [
64279
64333
  /* @__PURE__ */ jsxRuntime.jsx(ExternalLink, { className: "size-3" }),
@@ -65198,14 +65252,58 @@ const AthenaUserMessage = ({
65198
65252
  children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aui-user-message-content wrap-break-word rounded-2xl bg-muted px-4 py-2.5 text-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(MessagePrimitiveParts, { components: { Text: TextComponent } }) })
65199
65253
  }
65200
65254
  );
65255
+ const EMBED_ASSET_TYPE_ALIASES = {
65256
+ document: "document",
65257
+ image: "document",
65258
+ notebook: "notebook",
65259
+ pdf: "document",
65260
+ powerpoint_deck: "presentation",
65261
+ presentation: "presentation",
65262
+ puck_presentation: "presentation",
65263
+ sheet: "spreadsheet",
65264
+ spreadsheet: "spreadsheet",
65265
+ super_document: "document"
65266
+ };
65201
65267
  const embedCache = /* @__PURE__ */ new Map();
65268
+ const normalizeAssetType = (value) => {
65269
+ if (!value) {
65270
+ return null;
65271
+ }
65272
+ const normalizedValue = value.trim().replace(/^athena\//, "").toLowerCase().replace(/-/g, "_");
65273
+ return EMBED_ASSET_TYPE_ALIASES[normalizedValue] ?? null;
65274
+ };
65275
+ const appendEmbedSearchParams = ({
65276
+ embedUrl,
65277
+ embedSearchParams
65278
+ }) => {
65279
+ if (!embedSearchParams || Object.keys(embedSearchParams).length === 0) {
65280
+ return embedUrl;
65281
+ }
65282
+ const url = new URL(embedUrl);
65283
+ for (const [key, value] of Object.entries(embedSearchParams)) {
65284
+ if (!value) {
65285
+ continue;
65286
+ }
65287
+ url.searchParams.set(key, value);
65288
+ }
65289
+ return url.toString();
65290
+ };
65202
65291
  function useAssetEmbed(assetId, options = {
65203
65292
  backendUrl: ""
65204
65293
  }) {
65205
- const { readOnly = false, expiresInSeconds = 60 * 60 * 24 * 30, backendUrl, apiKey, token } = options;
65294
+ const {
65295
+ readOnly = false,
65296
+ expiresInSeconds = 60 * 60 * 24 * 30,
65297
+ backendUrl,
65298
+ apiKey,
65299
+ token,
65300
+ embedSearchParams
65301
+ } = options;
65206
65302
  const [embedUrl, setEmbedUrl] = React.useState(null);
65207
65303
  const [isLoading, setIsLoading] = React.useState(false);
65208
65304
  const [error2, setError] = React.useState(null);
65305
+ const [assetTitle, setAssetTitle] = React.useState(null);
65306
+ const [assetType, setAssetType] = React.useState(null);
65209
65307
  const abortRef = React.useRef(null);
65210
65308
  React.useEffect(() => {
65211
65309
  var _a2;
@@ -65213,14 +65311,18 @@ function useAssetEmbed(assetId, options = {
65213
65311
  setEmbedUrl(null);
65214
65312
  setIsLoading(false);
65215
65313
  setError(null);
65314
+ setAssetTitle(null);
65315
+ setAssetType(null);
65216
65316
  return;
65217
65317
  }
65218
- const cacheKey = `${assetId}:${readOnly}:${token ?? apiKey ?? "anon"}`;
65318
+ const cacheKey = `${assetId}:${readOnly}:${token ?? apiKey ?? "anon"}:${JSON.stringify(embedSearchParams ?? {})}`;
65219
65319
  const cached = embedCache.get(cacheKey);
65220
65320
  if (cached && cached.expiresAt > Date.now() / 1e3) {
65221
65321
  setEmbedUrl(cached.url);
65222
65322
  setIsLoading(false);
65223
65323
  setError(null);
65324
+ setAssetTitle(cached.assetTitle);
65325
+ setAssetType(cached.assetType);
65224
65326
  return;
65225
65327
  }
65226
65328
  const apiBaseUrl = backendUrl.replace(/\/api\/assistant-ui\/?$/, "");
@@ -65228,11 +65330,14 @@ function useAssetEmbed(assetId, options = {
65228
65330
  (_a2 = abortRef.current) == null ? void 0 : _a2.abort();
65229
65331
  const controller = new AbortController();
65230
65332
  abortRef.current = controller;
65333
+ setEmbedUrl(null);
65231
65334
  setIsLoading(true);
65232
65335
  setError(null);
65336
+ setAssetTitle(null);
65337
+ setAssetType(null);
65233
65338
  const headers = { "Content-Type": "application/json" };
65234
65339
  if (token) {
65235
- headers["Authorization"] = `Bearer ${token}`;
65340
+ headers.Authorization = `Bearer ${token}`;
65236
65341
  } else if (apiKey) {
65237
65342
  headers["X-API-KEY"] = apiKey;
65238
65343
  }
@@ -65252,17 +65357,31 @@ function useAssetEmbed(assetId, options = {
65252
65357
  }
65253
65358
  return res.json();
65254
65359
  }).then((data) => {
65255
- embedCache.set(`${assetId}:${readOnly}:${token ?? apiKey ?? "anon"}`, { url: data.embed_url, expiresAt: data.expires_at });
65256
- setEmbedUrl(data.embed_url);
65360
+ const resolvedAssetType = normalizeAssetType(data.athena_converted_type) ?? normalizeAssetType(data.athena_original_type);
65361
+ const resolvedEmbedUrl = appendEmbedSearchParams({
65362
+ embedUrl: data.embed_url,
65363
+ embedSearchParams
65364
+ });
65365
+ embedCache.set(cacheKey, {
65366
+ url: resolvedEmbedUrl,
65367
+ expiresAt: data.expires_at,
65368
+ assetTitle: data.title ?? null,
65369
+ assetType: resolvedAssetType
65370
+ });
65371
+ setEmbedUrl(resolvedEmbedUrl);
65372
+ setAssetTitle(data.title ?? null);
65373
+ setAssetType(resolvedAssetType);
65257
65374
  setIsLoading(false);
65258
65375
  }).catch((err) => {
65259
- if (err.name === "AbortError") return;
65376
+ if (err.name === "AbortError") {
65377
+ return;
65378
+ }
65260
65379
  setError(err.message);
65261
65380
  setIsLoading(false);
65262
65381
  });
65263
65382
  return () => controller.abort();
65264
- }, [assetId, readOnly, expiresInSeconds, backendUrl, apiKey, token]);
65265
- return { embedUrl, isLoading, error: error2 };
65383
+ }, [assetId, readOnly, expiresInSeconds, backendUrl, apiKey, token, embedSearchParams]);
65384
+ return { embedUrl, isLoading, error: error2, assetTitle, assetType };
65266
65385
  }
65267
65386
  const ASSET_TYPE_CONFIG = {
65268
65387
  presentation: { icon: Presentation, label: "Presentation" },
@@ -65272,13 +65391,28 @@ const ASSET_TYPE_CONFIG = {
65272
65391
  unknown: { icon: File$1, label: "Asset" }
65273
65392
  };
65274
65393
  const AssetIframe = React.memo(
65275
- ({ tabId, tabName }) => {
65394
+ ({ tabId, tabName, tabType, embedSearchParams }) => {
65276
65395
  const { backendUrl, apiKey, token } = useAthenaConfig();
65277
- const { embedUrl, isLoading, error: error2 } = useAssetEmbed(tabId, {
65396
+ const { embedUrl, isLoading, error: error2, assetTitle, assetType } = useAssetEmbed(tabId, {
65278
65397
  backendUrl,
65279
65398
  apiKey,
65280
- token
65399
+ token,
65400
+ embedSearchParams
65281
65401
  });
65402
+ React.useEffect(() => {
65403
+ if (!assetTitle && !assetType) {
65404
+ return;
65405
+ }
65406
+ const nextName = assetTitle ?? tabName;
65407
+ const nextType = assetType ?? tabType;
65408
+ if (nextName === tabName && nextType === tabType) {
65409
+ return;
65410
+ }
65411
+ useAssetPanelStore.getState().openAsset(tabId, {
65412
+ name: nextName ?? void 0,
65413
+ type: nextType
65414
+ });
65415
+ }, [assetTitle, assetType, tabId, tabName, tabType]);
65282
65416
  if (isLoading) {
65283
65417
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center", children: [
65284
65418
  /* @__PURE__ */ jsxRuntime.jsx(LoaderCircle, { className: "mx-auto size-6 animate-spin text-muted-foreground" }),
@@ -65363,7 +65497,15 @@ const PanelContent = ({
65363
65497
  }
65364
65498
  )
65365
65499
  ] }),
65366
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(AssetIframe, { tabId: tab.id, tabName: tab.name }) })
65500
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
65501
+ AssetIframe,
65502
+ {
65503
+ tabId: tab.id,
65504
+ tabName: tab.name,
65505
+ tabType: tab.type,
65506
+ embedSearchParams: tab.embedSearchParams
65507
+ }
65508
+ ) })
65367
65509
  ]
65368
65510
  },
65369
65511
  tab.id
@@ -65373,7 +65515,15 @@ const PanelContent = ({
65373
65515
  "div",
65374
65516
  {
65375
65517
  className: isActive2 ? "h-full w-full" : "hidden",
65376
- children: /* @__PURE__ */ jsxRuntime.jsx(AssetIframe, { tabId: tab.id, tabName: tab.name })
65518
+ children: /* @__PURE__ */ jsxRuntime.jsx(
65519
+ AssetIframe,
65520
+ {
65521
+ tabId: tab.id,
65522
+ tabName: tab.name,
65523
+ tabType: tab.type,
65524
+ embedSearchParams: tab.embedSearchParams
65525
+ }
65526
+ )
65377
65527
  },
65378
65528
  tab.id
65379
65529
  );