@athenaintel/react 0.9.5 → 0.9.6

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.d.ts CHANGED
@@ -80,8 +80,11 @@ export declare interface AthenaConfig {
80
80
  apiKey?: string;
81
81
  token?: string | null;
82
82
  backendUrl: string;
83
+ appUrl: string;
83
84
  }
84
85
 
86
+ export declare type AthenaEnvironment = 'production' | 'staging';
87
+
85
88
  /**
86
89
  * Layout that places the chat on the left and the asset panel on the right.
87
90
  * When no assets are open, the chat takes full width. Includes a draggable resize handle.
@@ -96,7 +99,7 @@ export declare interface AthenaLayoutProps {
96
99
  minPercent?: number;
97
100
  }
98
101
 
99
- export declare function AthenaProvider({ children, apiKey, token: tokenProp, agent, model, tools, frontendTools, apiUrl, backendUrl, workbench, knowledgeBase, systemPrompt, threadId: threadIdProp, enableThreadList, theme, }: AthenaProviderProps): JSX.Element | null;
102
+ export declare function AthenaProvider({ children, apiKey, token: tokenProp, agent, model, tools, frontendTools, apiUrl, backendUrl, appUrl, environment, workbench, knowledgeBase, systemPrompt, threadId: threadIdProp, enableThreadList, theme, }: AthenaProviderProps): JSX.Element | null;
100
103
 
101
104
  export declare interface AthenaProviderProps {
102
105
  children: ReactNode;
@@ -117,6 +120,10 @@ export declare interface AthenaProviderProps {
117
120
  apiUrl?: string;
118
121
  /** URL for the Agora backend API. Defaults to Athena production. */
119
122
  backendUrl?: string;
123
+ /** URL for the Athena frontend app origin. Defaults to the matching Athena environment. */
124
+ appUrl?: string;
125
+ /** Athena environment preset used when URLs are not explicitly provided. */
126
+ environment?: AthenaEnvironment;
120
127
  /** Asset IDs to include in the workbench. */
121
128
  workbench?: string[];
122
129
  /** Knowledge base IDs for RAG context. */
@@ -316,9 +323,11 @@ export declare const CreatePresentationToolUI: ToolCallMessagePartComponent;
316
323
 
317
324
  export declare const CreateSheetToolUI: ToolCallMessagePartComponent;
318
325
 
319
- export declare const DEFAULT_API_URL = "https://sync.athenaintel.com/api/chat";
326
+ export declare const DEFAULT_API_URL: string;
327
+
328
+ export declare const DEFAULT_APP_URL: string;
320
329
 
321
- export declare const DEFAULT_BACKEND_URL = "https://api.athenaintel.com/api/assistant-ui";
330
+ export declare const DEFAULT_BACKEND_URL: string;
322
331
 
323
332
  export declare const EmailSearchToolUI: ToolCallMessagePartComponent;
324
333
 
@@ -406,6 +415,8 @@ export declare interface ParentBridgeState {
406
415
  apiUrl: string | null;
407
416
  /** Agora backend URL provided by the Marathon wrapper. */
408
417
  backendUrl: string | null;
418
+ /** Athena frontend origin provided by the parent wrapper. */
419
+ appUrl: string | null;
409
420
  /** True once config has been received from the parent (or timeout fired). */
410
421
  ready: boolean;
411
422
  }
@@ -894,14 +905,14 @@ export declare function useParentAuth(): string | null;
894
905
  * via PostMessage.
895
906
  *
896
907
  * When the app runs inside a Marathon wrapper, the wrapper sends:
897
- * 1. { type: 'athena-config', apiUrl, backendUrl } — correct API URLs for the environment
908
+ * 1. { type: 'athena-config', apiUrl, backendUrl, appUrl } — correct URLs for the environment
898
909
  * 2. { type: 'athena-auth', token } — relayed from the Olympus token-bridge iframe
899
910
  *
900
911
  * When running inside an Olympus inline preview, only athena-auth is sent.
901
912
  * When running standalone (no parent), returns defaults immediately.
902
913
  *
903
914
  * Protocol:
904
- * Parent -> iframe: { type: 'athena-config', apiUrl: string, backendUrl: string }
915
+ * Parent -> iframe: { type: 'athena-config', apiUrl: string, backendUrl: string, appUrl?: string }
905
916
  * Parent -> iframe: { type: 'athena-auth', token: '<propel-access-token>' }
906
917
  * iframe -> Parent: { type: 'athena-auth-ready' }
907
918
  */
package/dist/index.js CHANGED
@@ -16457,6 +16457,106 @@ const INTERNAL = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProp
16457
16457
  useSmoothStatus,
16458
16458
  useToolInvocations
16459
16459
  }, Symbol.toStringTag, { value: "Module" }));
16460
+ const ATHENA_ENVIRONMENT_URLS = {
16461
+ production: {
16462
+ apiUrl: "https://sync.athenaintel.com/api/chat",
16463
+ backendUrl: "https://api.athenaintel.com/api/assistant-ui",
16464
+ appUrl: "https://app.athenaintel.com"
16465
+ },
16466
+ staging: {
16467
+ apiUrl: "https://staging-sync.athenaintel.com/api/chat",
16468
+ backendUrl: "https://staging-api.athenaintel.com/api/assistant-ui",
16469
+ appUrl: "https://staging-app.athenaintel.com"
16470
+ }
16471
+ };
16472
+ const DEFAULT_ATHENA_ENVIRONMENT = "production";
16473
+ const DEFAULT_API_URL = ATHENA_ENVIRONMENT_URLS.production.apiUrl;
16474
+ const DEFAULT_BACKEND_URL = ATHENA_ENVIRONMENT_URLS.production.backendUrl;
16475
+ const DEFAULT_APP_URL = ATHENA_ENVIRONMENT_URLS.production.appUrl;
16476
+ const SPACES_PATHNAME = "/dashboard/spaces/";
16477
+ const normalizeBaseUrl = (url) => url.replace(/\/+$/, "");
16478
+ const getHostname = (value) => {
16479
+ if (!value) return null;
16480
+ try {
16481
+ return new URL(value).hostname;
16482
+ } catch {
16483
+ return null;
16484
+ }
16485
+ };
16486
+ const deriveWorkspaceAppUrl = ({
16487
+ sourceUrl,
16488
+ sourcePort
16489
+ }) => {
16490
+ var _a2;
16491
+ try {
16492
+ const parsedUrl = new URL(sourceUrl);
16493
+ const match2 = parsedUrl.hostname.match(
16494
+ new RegExp(`^(?<prefix>.+)--${sourcePort}\\.(?<domain>app\\.athenaintel\\.com|staging-app\\.athenaintel\\.com)$`)
16495
+ );
16496
+ if (!((_a2 = match2 == null ? void 0 : match2.groups) == null ? void 0 : _a2.prefix) || !match2.groups.domain) {
16497
+ return null;
16498
+ }
16499
+ return `${parsedUrl.protocol}//${match2.groups.prefix}--8082.${match2.groups.domain}`;
16500
+ } catch {
16501
+ return null;
16502
+ }
16503
+ };
16504
+ function getAthenaEnvironmentUrls({
16505
+ environment = DEFAULT_ATHENA_ENVIRONMENT
16506
+ } = {}) {
16507
+ return ATHENA_ENVIRONMENT_URLS[environment];
16508
+ }
16509
+ function deriveAthenaAppUrl({
16510
+ apiUrl,
16511
+ backendUrl
16512
+ }) {
16513
+ if (backendUrl) {
16514
+ const workspaceAppUrl = deriveWorkspaceAppUrl({
16515
+ sourceUrl: backendUrl,
16516
+ sourcePort: "8000"
16517
+ });
16518
+ if (workspaceAppUrl) return workspaceAppUrl;
16519
+ const backendHostname = getHostname(backendUrl);
16520
+ if (backendHostname === "api.athenaintel.com") {
16521
+ return ATHENA_ENVIRONMENT_URLS.production.appUrl;
16522
+ }
16523
+ if (backendHostname === "staging-api.athenaintel.com") {
16524
+ return ATHENA_ENVIRONMENT_URLS.staging.appUrl;
16525
+ }
16526
+ }
16527
+ if (apiUrl) {
16528
+ const workspaceAppUrl = deriveWorkspaceAppUrl({
16529
+ sourceUrl: apiUrl,
16530
+ sourcePort: "8787"
16531
+ });
16532
+ if (workspaceAppUrl) return workspaceAppUrl;
16533
+ const apiHostname = getHostname(apiUrl);
16534
+ if (apiHostname === "sync.athenaintel.com") {
16535
+ return ATHENA_ENVIRONMENT_URLS.production.appUrl;
16536
+ }
16537
+ if (apiHostname === "staging-sync.athenaintel.com") {
16538
+ return ATHENA_ENVIRONMENT_URLS.staging.appUrl;
16539
+ }
16540
+ }
16541
+ return null;
16542
+ }
16543
+ function createAthenaSpacesUrl({
16544
+ appUrl = DEFAULT_APP_URL,
16545
+ assetIds,
16546
+ sessionId
16547
+ }) {
16548
+ const url = new URL(SPACES_PATHNAME, `${normalizeBaseUrl(appUrl)}/`);
16549
+ if (assetIds) {
16550
+ const normalizedAssetIds = (Array.isArray(assetIds) ? assetIds : [assetIds]).map((assetId) => assetId.trim()).filter((assetId) => assetId.length > 0);
16551
+ if (normalizedAssetIds.length > 0) {
16552
+ url.searchParams.set("asset_ids", normalizedAssetIds.join(","));
16553
+ }
16554
+ }
16555
+ if (sessionId) {
16556
+ url.searchParams.set("session_id", sessionId);
16557
+ }
16558
+ return url.toString();
16559
+ }
16460
16560
  function isTrustedOrigin(origin) {
16461
16561
  try {
16462
16562
  const { hostname } = new URL(origin);
@@ -16472,6 +16572,7 @@ function useParentBridge() {
16472
16572
  token: null,
16473
16573
  apiUrl: null,
16474
16574
  backendUrl: null,
16575
+ appUrl: null,
16475
16576
  // If not in an iframe, we're ready immediately (standalone mode)
16476
16577
  ready: !isInIframe
16477
16578
  });
@@ -16487,7 +16588,8 @@ function useParentBridge() {
16487
16588
  setState((prev) => ({
16488
16589
  ...prev,
16489
16590
  apiUrl: typeof event.data.apiUrl === "string" ? event.data.apiUrl : prev.apiUrl,
16490
- backendUrl: typeof event.data.backendUrl === "string" ? event.data.backendUrl : prev.backendUrl
16591
+ backendUrl: typeof event.data.backendUrl === "string" ? event.data.backendUrl : prev.backendUrl,
16592
+ appUrl: typeof event.data.appUrl === "string" ? event.data.appUrl : prev.appUrl
16491
16593
  // Don't set ready here — wait for athena-auth (token) or the timeout.
16492
16594
  // Setting ready on config alone causes a race: the thread list fires
16493
16595
  // before the token arrives, falling back to X-API-KEY.
@@ -20719,8 +20821,6 @@ async function archiveThread(backendUrl, auth, threadId) {
20719
20821
  throw new Error(`[AthenaSDK] Failed to archive thread: ${res.status}`);
20720
20822
  }
20721
20823
  }
20722
- const DEFAULT_API_URL = "https://sync.athenaintel.com/api/chat";
20723
- const DEFAULT_BACKEND_URL = "https://api.athenaintel.com/api/assistant-ui";
20724
20824
  const DEFAULT_MODEL = "claude-opus-4-6-thinking-max-fast";
20725
20825
  const DEFAULT_AGENT = "athena_assist_agent";
20726
20826
  const ATHENA_TRACKING_ID_KEY = "_athena_tracking_id";
@@ -24529,6 +24629,7 @@ function AthenaStandalone({
24529
24629
  children,
24530
24630
  apiUrl,
24531
24631
  backendUrl,
24632
+ appUrl,
24532
24633
  apiKey,
24533
24634
  token,
24534
24635
  model,
@@ -24558,8 +24659,8 @@ function AthenaStandalone({
24558
24659
  threadId
24559
24660
  });
24560
24661
  const athenaConfig = useMemo(
24561
- () => ({ backendUrl, apiKey, token }),
24562
- [backendUrl, apiKey, token]
24662
+ () => ({ backendUrl, appUrl, apiKey, token }),
24663
+ [backendUrl, appUrl, apiKey, token]
24563
24664
  );
24564
24665
  return /* @__PURE__ */ jsx(AssistantRuntimeProvider, { aui, runtime, children: /* @__PURE__ */ jsx(AthenaContext.Provider, { value: athenaConfig, children: /* @__PURE__ */ jsx(TooltipProvider, { children }) }) });
24565
24666
  }
@@ -24584,6 +24685,7 @@ function AthenaWithThreadList({
24584
24685
  children,
24585
24686
  apiUrl,
24586
24687
  backendUrl,
24688
+ appUrl,
24587
24689
  apiKey,
24588
24690
  token,
24589
24691
  model,
@@ -24655,8 +24757,8 @@ function AthenaWithThreadList({
24655
24757
  const auiTools = useMemo(() => Tools({ toolkit: frontendTools }), [frontendTools]);
24656
24758
  const aui = useAui({ tools: auiTools });
24657
24759
  const athenaConfig = useMemo(
24658
- () => ({ backendUrl, apiKey, token }),
24659
- [backendUrl, apiKey, token]
24760
+ () => ({ backendUrl, appUrl, apiKey, token }),
24761
+ [backendUrl, appUrl, apiKey, token]
24660
24762
  );
24661
24763
  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 }) }) }) });
24662
24764
  }
@@ -24670,6 +24772,8 @@ function AthenaProvider({
24670
24772
  frontendTools = {},
24671
24773
  apiUrl,
24672
24774
  backendUrl,
24775
+ appUrl,
24776
+ environment,
24673
24777
  workbench,
24674
24778
  knowledgeBase,
24675
24779
  systemPrompt,
@@ -24679,10 +24783,15 @@ function AthenaProvider({
24679
24783
  }) {
24680
24784
  const frontendToolNames = useMemo(() => Object.keys(frontendTools), [frontendTools]);
24681
24785
  const themeStyleVars = useMemo(() => theme ? themeToStyleVars(theme) : void 0, [theme]);
24786
+ const environmentUrls = useMemo(
24787
+ () => getAthenaEnvironmentUrls({ environment }),
24788
+ [environment]
24789
+ );
24682
24790
  const bridge = useParentBridge();
24683
24791
  const effectiveToken = tokenProp ?? bridge.token;
24684
- const effectiveApiUrl = apiUrl ?? bridge.apiUrl ?? DEFAULT_API_URL;
24685
- const effectiveBackendUrl = backendUrl ?? bridge.backendUrl ?? DEFAULT_BACKEND_URL;
24792
+ const effectiveApiUrl = apiUrl ?? bridge.apiUrl ?? environmentUrls.apiUrl ?? DEFAULT_API_URL;
24793
+ const effectiveBackendUrl = backendUrl ?? bridge.backendUrl ?? environmentUrls.backendUrl ?? DEFAULT_BACKEND_URL;
24794
+ const effectiveAppUrl = appUrl ?? bridge.appUrl ?? deriveAthenaAppUrl({ apiUrl: effectiveApiUrl, backendUrl: effectiveBackendUrl }) ?? environmentUrls.appUrl ?? DEFAULT_APP_URL;
24686
24795
  if (!bridge.ready) {
24687
24796
  return null;
24688
24797
  }
@@ -24693,6 +24802,7 @@ function AthenaProvider({
24693
24802
  {
24694
24803
  apiUrl: effectiveApiUrl,
24695
24804
  backendUrl: effectiveBackendUrl,
24805
+ appUrl: effectiveAppUrl,
24696
24806
  apiKey,
24697
24807
  token: effectiveToken,
24698
24808
  model,
@@ -24712,6 +24822,7 @@ function AthenaProvider({
24712
24822
  {
24713
24823
  apiUrl: effectiveApiUrl,
24714
24824
  backendUrl: effectiveBackendUrl,
24825
+ appUrl: effectiveAppUrl,
24715
24826
  apiKey,
24716
24827
  token: effectiveToken,
24717
24828
  model,
@@ -60509,9 +60620,12 @@ function useAttachments() {
60509
60620
  }
60510
60621
  return ctx;
60511
60622
  }
60512
- function buildAttachmentMarkdown(attachments) {
60623
+ function buildAttachmentMarkdownWithAppUrl({
60624
+ attachments,
60625
+ appUrl = DEFAULT_APP_URL
60626
+ }) {
60513
60627
  if (attachments.length === 0) return "";
60514
- return attachments.map((a) => `[@${a.title}](https://app.athenaintel.com/dashboard/spaces?asset_id=${a.id})`).join("\n");
60628
+ return attachments.map((attachment) => `[@${attachment.title}](${createAthenaSpacesUrl({ appUrl, assetIds: attachment.id })})`).join("\n");
60515
60629
  }
60516
60630
  const QuoteCtx = createContext(null);
60517
60631
  function QuoteProvider({ children }) {
@@ -60577,7 +60691,10 @@ function buildComposedMessage(opts) {
60577
60691
  var _a2;
60578
60692
  const parts = [];
60579
60693
  if (opts.attachments && opts.attachments.length > 0) {
60580
- const attachmentMd = buildAttachmentMarkdown(opts.attachments);
60694
+ const attachmentMd = buildAttachmentMarkdownWithAppUrl({
60695
+ attachments: opts.attachments,
60696
+ appUrl: opts.appUrl
60697
+ });
60581
60698
  if (attachmentMd) parts.push(attachmentMd);
60582
60699
  }
60583
60700
  if (opts.quote) {
@@ -60598,6 +60715,7 @@ const TiptapComposer = ({ tools = [] }) => {
60598
60715
  const mentionStore = useMentionSuggestions(tools);
60599
60716
  const { attachments, clearAttachments, isUploading } = useAttachments();
60600
60717
  const { quote, clearQuote } = useQuote();
60718
+ const { appUrl } = useAthenaConfig();
60601
60719
  const attachmentsRef = useRef(attachments);
60602
60720
  attachmentsRef.current = attachments;
60603
60721
  const quoteRef = useRef(quote);
@@ -60618,7 +60736,8 @@ const TiptapComposer = ({ tools = [] }) => {
60618
60736
  const fullMessage = buildComposedMessage({
60619
60737
  attachments: currentAttachments,
60620
60738
  quote: currentQuote,
60621
- userText: markdown
60739
+ userText: markdown,
60740
+ appUrl
60622
60741
  });
60623
60742
  if (fullMessage) {
60624
60743
  aui.thread().append({
@@ -63968,6 +64087,7 @@ const ComposerAction = () => /* @__PURE__ */ jsxs("div", { className: "aui-compo
63968
64087
  ] });
63969
64088
  const ComposerSendWithQuote = () => {
63970
64089
  const aui = useAui();
64090
+ const { appUrl } = useAthenaConfig();
63971
64091
  const { quote, clearQuote } = useQuote();
63972
64092
  const { attachments, clearAttachments, isUploading } = useAttachments();
63973
64093
  const editorRef = useComposerEditorRef();
@@ -63981,7 +64101,8 @@ const ComposerSendWithQuote = () => {
63981
64101
  const fullMessage = buildComposedMessage({
63982
64102
  attachments,
63983
64103
  quote,
63984
- userText
64104
+ userText,
64105
+ appUrl
63985
64106
  });
63986
64107
  if (!fullMessage) return;
63987
64108
  aui.thread().append({
@@ -64065,6 +64186,7 @@ const AssistantMessage = ({ toolUIs }) => /* @__PURE__ */ jsxs(
64065
64186
  );
64066
64187
  const AssistantActionBar = () => {
64067
64188
  const threadId = useAthenaThreadId();
64189
+ const { appUrl } = useAthenaConfig();
64068
64190
  return /* @__PURE__ */ jsxs(
64069
64191
  ActionBarPrimitiveRoot,
64070
64192
  {
@@ -64094,10 +64216,7 @@ const AssistantActionBar = () => {
64094
64216
  {
64095
64217
  className: "aui-action-bar-more-item flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground",
64096
64218
  onClick: () => {
64097
- window.open(
64098
- `https://app.athenaintel.com/dashboard/spaces?session_id=${threadId}`,
64099
- "_blank"
64100
- );
64219
+ window.open(createAthenaSpacesUrl({ appUrl, sessionId: threadId }), "_blank");
64101
64220
  },
64102
64221
  children: [
64103
64222
  /* @__PURE__ */ jsx(ExternalLink, { className: "size-4" }),
@@ -64585,6 +64704,7 @@ export {
64585
64704
  CreatePresentationToolUI,
64586
64705
  CreateSheetToolUI,
64587
64706
  DEFAULT_API_URL,
64707
+ DEFAULT_APP_URL,
64588
64708
  DEFAULT_BACKEND_URL,
64589
64709
  EmailSearchToolUI,
64590
64710
  ExpandableSection,