@athenaintel/react 0.9.5 → 0.9.7

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
@@ -76,12 +76,13 @@ export declare interface AthenaChatProps {
76
76
  welcomeSuggestions?: WelcomeSuggestion[];
77
77
  }
78
78
 
79
- export declare interface AthenaConfig {
80
- apiKey?: string;
81
- token?: string | null;
79
+ export declare interface AthenaConfig extends Pick<AthenaProviderConfig, 'apiKey' | 'token'> {
82
80
  backendUrl: string;
81
+ appUrl: string;
83
82
  }
84
83
 
84
+ export declare type AthenaEnvironment = 'production' | 'staging';
85
+
85
86
  /**
86
87
  * Layout that places the chat on the left and the asset panel on the right.
87
88
  * When no assets are open, the chat takes full width. Includes a draggable resize handle.
@@ -96,15 +97,32 @@ export declare interface AthenaLayoutProps {
96
97
  minPercent?: number;
97
98
  }
98
99
 
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;
100
+ export declare function AthenaProvider({ children, config, apiKey, token: tokenProp, agent, model, tools, frontendTools, apiUrl, backendUrl, appUrl, environment, workbench, knowledgeBase, systemPrompt, threadId: threadIdProp, enableThreadList, theme, }: AthenaProviderProps): JSX.Element | null;
101
+
102
+ export declare interface AthenaProviderConfig {
103
+ /** API key for standalone authentication when no token is provided. */
104
+ apiKey?: string;
105
+ /** PropelAuth token. Takes priority over apiKey when provided. */
106
+ token?: string | null;
107
+ /** URL for the chat streaming endpoint. Defaults to the matching Athena environment. */
108
+ apiUrl?: string;
109
+ /** URL for the Athena backend API. Defaults to the matching Athena environment. */
110
+ backendUrl?: string;
111
+ /** URL for the Athena frontend app origin. Defaults to the matching Athena environment. */
112
+ appUrl?: string;
113
+ /** Athena environment preset used when URLs are not explicitly provided. */
114
+ environment?: AthenaEnvironment;
115
+ }
100
116
 
101
117
  export declare interface AthenaProviderProps {
102
118
  children: ReactNode;
103
- /** API key for authentication. Used when running standalone (not in Olympus iframe). */
119
+ /** Preferred structured config for auth and Athena endpoint settings. */
120
+ config?: AthenaProviderConfig;
121
+ /** @deprecated Prefer `config.apiKey`. API key for authentication in standalone mode. */
104
122
  apiKey?: string;
105
- /** PropelAuth token. If provided, takes priority over apiKey. If omitted, the SDK
123
+ /** @deprecated Prefer `config.token`. PropelAuth token. If provided, takes priority over apiKey. If omitted, the SDK
106
124
  * will automatically listen for a token from the parent window via PostMessage. */
107
- token?: string;
125
+ token?: string | null;
108
126
  /** Agent name to use. Defaults to 'athena_assist_agent'. */
109
127
  agent?: string;
110
128
  /** LLM model identifier. Defaults to 'claude-opus-4-6-thinking-max-fast'. */
@@ -113,10 +131,14 @@ export declare interface AthenaProviderProps {
113
131
  tools?: string[];
114
132
  /** Frontend tools that execute in the browser. The agent can invoke these. */
115
133
  frontendTools?: Toolkit;
116
- /** URL for the chat streaming endpoint. Defaults to Athena production. */
134
+ /** @deprecated Prefer `config.apiUrl`. URL for the chat streaming endpoint. */
117
135
  apiUrl?: string;
118
- /** URL for the Agora backend API. Defaults to Athena production. */
136
+ /** @deprecated Prefer `config.backendUrl`. URL for the Athena backend API. */
119
137
  backendUrl?: string;
138
+ /** @deprecated Prefer `config.appUrl`. URL for the Athena frontend app origin. */
139
+ appUrl?: string;
140
+ /** @deprecated Prefer `config.environment`. Athena environment preset used when URLs are not explicitly provided. */
141
+ environment?: AthenaEnvironment;
120
142
  /** Asset IDs to include in the workbench. */
121
143
  workbench?: string[];
122
144
  /** Knowledge base IDs for RAG context. */
@@ -148,7 +170,7 @@ export declare interface AthenaRuntimeConfig {
148
170
  apiUrl?: string;
149
171
  /** URL for the sync server resume endpoint. Derived from apiUrl if not provided. */
150
172
  resumeApiUrl?: string;
151
- /** URL for the Agora backend API. Defaults to Athena production API. */
173
+ /** URL for the Athena backend API. Defaults to Athena production API. */
152
174
  backendUrl?: string;
153
175
  /** API key for authentication. Used when no auth token is provided. */
154
176
  apiKey?: string;
@@ -316,9 +338,11 @@ export declare const CreatePresentationToolUI: ToolCallMessagePartComponent;
316
338
 
317
339
  export declare const CreateSheetToolUI: ToolCallMessagePartComponent;
318
340
 
319
- export declare const DEFAULT_API_URL = "https://sync.athenaintel.com/api/chat";
341
+ export declare const DEFAULT_API_URL: string;
342
+
343
+ export declare const DEFAULT_APP_URL: string;
320
344
 
321
- export declare const DEFAULT_BACKEND_URL = "https://api.athenaintel.com/api/assistant-ui";
345
+ export declare const DEFAULT_BACKEND_URL: string;
322
346
 
323
347
  export declare const EmailSearchToolUI: ToolCallMessagePartComponent;
324
348
 
@@ -406,6 +430,8 @@ export declare interface ParentBridgeState {
406
430
  apiUrl: string | null;
407
431
  /** Agora backend URL provided by the Marathon wrapper. */
408
432
  backendUrl: string | null;
433
+ /** Athena frontend origin provided by the parent wrapper. */
434
+ appUrl: string | null;
409
435
  /** True once config has been received from the parent (or timeout fired). */
410
436
  ready: boolean;
411
437
  }
@@ -605,7 +631,7 @@ export declare interface ThreadListProps {
605
631
  }
606
632
 
607
633
  /**
608
- * Agora thread API client.
634
+ * Athena thread API client.
609
635
  * Calls existing REST endpoints for thread CRUD.
610
636
  */
611
637
  export declare interface ThreadSummary {
@@ -818,7 +844,7 @@ export declare function useAppendToComposer(): (text: string, opts?: {
818
844
 
819
845
  /**
820
846
  * Hook to generate an embed URL for rendering an asset in an iframe.
821
- * Calls the Agora `/api/embed/generate-token` endpoint.
847
+ * Calls the Athena embed token endpoint.
822
848
  */
823
849
  export declare function useAssetEmbed(assetId: string | null, options?: UseAssetEmbedOptions & {
824
850
  backendUrl: string;
@@ -859,7 +885,7 @@ export declare function useComposerAttachment(): {
859
885
  };
860
886
 
861
887
  /**
862
- * Hook for uploading files to the Athena platform via Agora's `/api/upload/` endpoint.
888
+ * Hook for uploading files to the Athena platform via the Athena upload endpoint.
863
889
  * Files become Athena assets (documents, spreadsheets, PDFs, images, etc.).
864
890
  *
865
891
  * Usage:
@@ -894,14 +920,14 @@ export declare function useParentAuth(): string | null;
894
920
  * via PostMessage.
895
921
  *
896
922
  * When the app runs inside a Marathon wrapper, the wrapper sends:
897
- * 1. { type: 'athena-config', apiUrl, backendUrl } — correct API URLs for the environment
923
+ * 1. { type: 'athena-config', apiUrl, backendUrl, appUrl } — correct URLs for the environment
898
924
  * 2. { type: 'athena-auth', token } — relayed from the Olympus token-bridge iframe
899
925
  *
900
926
  * When running inside an Olympus inline preview, only athena-auth is sent.
901
927
  * When running standalone (no parent), returns defaults immediately.
902
928
  *
903
929
  * Protocol:
904
- * Parent -> iframe: { type: 'athena-config', apiUrl: string, backendUrl: string }
930
+ * Parent -> iframe: { type: 'athena-config', apiUrl: string, backendUrl: string, appUrl?: string }
905
931
  * Parent -> iframe: { type: 'athena-auth', token: '<propel-access-token>' }
906
932
  * iframe -> Parent: { type: 'athena-auth-ready' }
907
933
  */
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.
@@ -20657,7 +20759,7 @@ function getAuthHeaders(auth) {
20657
20759
  }
20658
20760
  return {};
20659
20761
  }
20660
- function getAgoraBaseUrl(backendUrl) {
20762
+ function getAthenaApiBaseUrl(backendUrl) {
20661
20763
  const stripped = backendUrl.replace(/\/api\/assistant-ui\/?$/, "");
20662
20764
  if (stripped === backendUrl) {
20663
20765
  return backendUrl.replace(/\/$/, "");
@@ -20665,7 +20767,7 @@ function getAgoraBaseUrl(backendUrl) {
20665
20767
  return stripped;
20666
20768
  }
20667
20769
  async function listThreads(backendUrl, auth, opts = {}) {
20668
- const base2 = getAgoraBaseUrl(backendUrl);
20770
+ const base2 = getAthenaApiBaseUrl(backendUrl);
20669
20771
  const res = await fetch(`${base2}/api/conversations/threads/list`, {
20670
20772
  method: "POST",
20671
20773
  headers: { "Content-Type": "application/json", ...getAuthHeaders(auth) },
@@ -20694,7 +20796,7 @@ function deserializeMessage(msg) {
20694
20796
  return msg;
20695
20797
  }
20696
20798
  async function getThreadState(backendUrl, auth, threadId) {
20697
- const base2 = getAgoraBaseUrl(backendUrl);
20799
+ const base2 = getAthenaApiBaseUrl(backendUrl);
20698
20800
  const res = await fetch(`${base2}/api/unstable/threads/${threadId}`, {
20699
20801
  method: "GET",
20700
20802
  headers: { ...getAuthHeaders(auth) }
@@ -20709,7 +20811,7 @@ async function getThreadState(backendUrl, auth, threadId) {
20709
20811
  return data;
20710
20812
  }
20711
20813
  async function archiveThread(backendUrl, auth, threadId) {
20712
- const base2 = getAgoraBaseUrl(backendUrl);
20814
+ const base2 = getAthenaApiBaseUrl(backendUrl);
20713
20815
  const res = await fetch(`${base2}/api/conversations/threads/archive`, {
20714
20816
  method: "POST",
20715
20817
  headers: { "Content-Type": "application/json", ...getAuthHeaders(auth) },
@@ -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";
@@ -24525,10 +24625,20 @@ const themes = {
24525
24625
  radius: "0.625rem"
24526
24626
  }
24527
24627
  };
24628
+ const resolveTokenOverride = ({
24629
+ config: config2,
24630
+ token
24631
+ }) => {
24632
+ if ((config2 == null ? void 0 : config2.token) !== void 0) {
24633
+ return config2.token;
24634
+ }
24635
+ return token;
24636
+ };
24528
24637
  function AthenaStandalone({
24529
24638
  children,
24530
24639
  apiUrl,
24531
24640
  backendUrl,
24641
+ appUrl,
24532
24642
  apiKey,
24533
24643
  token,
24534
24644
  model,
@@ -24558,8 +24668,8 @@ function AthenaStandalone({
24558
24668
  threadId
24559
24669
  });
24560
24670
  const athenaConfig = useMemo(
24561
- () => ({ backendUrl, apiKey, token }),
24562
- [backendUrl, apiKey, token]
24671
+ () => ({ backendUrl, appUrl, apiKey, token }),
24672
+ [backendUrl, appUrl, apiKey, token]
24563
24673
  );
24564
24674
  return /* @__PURE__ */ jsx(AssistantRuntimeProvider, { aui, runtime, children: /* @__PURE__ */ jsx(AthenaContext.Provider, { value: athenaConfig, children: /* @__PURE__ */ jsx(TooltipProvider, { children }) }) });
24565
24675
  }
@@ -24584,6 +24694,7 @@ function AthenaWithThreadList({
24584
24694
  children,
24585
24695
  apiUrl,
24586
24696
  backendUrl,
24697
+ appUrl,
24587
24698
  apiKey,
24588
24699
  token,
24589
24700
  model,
@@ -24655,13 +24766,14 @@ function AthenaWithThreadList({
24655
24766
  const auiTools = useMemo(() => Tools({ toolkit: frontendTools }), [frontendTools]);
24656
24767
  const aui = useAui({ tools: auiTools });
24657
24768
  const athenaConfig = useMemo(
24658
- () => ({ backendUrl, apiKey, token }),
24659
- [backendUrl, apiKey, token]
24769
+ () => ({ backendUrl, appUrl, apiKey, token }),
24770
+ [backendUrl, appUrl, apiKey, token]
24660
24771
  );
24661
24772
  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
24773
  }
24663
24774
  function AthenaProvider({
24664
24775
  children,
24776
+ config: config2,
24665
24777
  apiKey,
24666
24778
  token: tokenProp,
24667
24779
  agent: agent2,
@@ -24670,6 +24782,8 @@ function AthenaProvider({
24670
24782
  frontendTools = {},
24671
24783
  apiUrl,
24672
24784
  backendUrl,
24785
+ appUrl,
24786
+ environment,
24673
24787
  workbench,
24674
24788
  knowledgeBase,
24675
24789
  systemPrompt,
@@ -24679,10 +24793,21 @@ function AthenaProvider({
24679
24793
  }) {
24680
24794
  const frontendToolNames = useMemo(() => Object.keys(frontendTools), [frontendTools]);
24681
24795
  const themeStyleVars = useMemo(() => theme ? themeToStyleVars(theme) : void 0, [theme]);
24796
+ const configuredEnvironment = (config2 == null ? void 0 : config2.environment) ?? environment;
24797
+ const environmentUrls = useMemo(
24798
+ () => getAthenaEnvironmentUrls({ environment: configuredEnvironment }),
24799
+ [configuredEnvironment]
24800
+ );
24801
+ const configuredApiKey = (config2 == null ? void 0 : config2.apiKey) ?? apiKey;
24802
+ const configuredToken = resolveTokenOverride({ config: config2, token: tokenProp });
24803
+ const configuredApiUrl = (config2 == null ? void 0 : config2.apiUrl) ?? apiUrl;
24804
+ const configuredBackendUrl = (config2 == null ? void 0 : config2.backendUrl) ?? backendUrl;
24805
+ const configuredAppUrl = (config2 == null ? void 0 : config2.appUrl) ?? appUrl;
24682
24806
  const bridge = useParentBridge();
24683
- const effectiveToken = tokenProp ?? bridge.token;
24684
- const effectiveApiUrl = apiUrl ?? bridge.apiUrl ?? DEFAULT_API_URL;
24685
- const effectiveBackendUrl = backendUrl ?? bridge.backendUrl ?? DEFAULT_BACKEND_URL;
24807
+ const effectiveToken = configuredToken !== void 0 ? configuredToken : bridge.token;
24808
+ const effectiveApiUrl = configuredApiUrl ?? bridge.apiUrl ?? environmentUrls.apiUrl ?? DEFAULT_API_URL;
24809
+ const effectiveBackendUrl = configuredBackendUrl ?? bridge.backendUrl ?? environmentUrls.backendUrl ?? DEFAULT_BACKEND_URL;
24810
+ const effectiveAppUrl = configuredAppUrl ?? bridge.appUrl ?? deriveAthenaAppUrl({ apiUrl: effectiveApiUrl, backendUrl: effectiveBackendUrl }) ?? environmentUrls.appUrl ?? DEFAULT_APP_URL;
24686
24811
  if (!bridge.ready) {
24687
24812
  return null;
24688
24813
  }
@@ -24693,7 +24818,8 @@ function AthenaProvider({
24693
24818
  {
24694
24819
  apiUrl: effectiveApiUrl,
24695
24820
  backendUrl: effectiveBackendUrl,
24696
- apiKey,
24821
+ appUrl: effectiveAppUrl,
24822
+ apiKey: configuredApiKey,
24697
24823
  token: effectiveToken,
24698
24824
  model,
24699
24825
  agent: agent2,
@@ -24712,7 +24838,8 @@ function AthenaProvider({
24712
24838
  {
24713
24839
  apiUrl: effectiveApiUrl,
24714
24840
  backendUrl: effectiveBackendUrl,
24715
- apiKey,
24841
+ appUrl: effectiveAppUrl,
24842
+ apiKey: configuredApiKey,
24716
24843
  token: effectiveToken,
24717
24844
  model,
24718
24845
  agent: agent2,
@@ -60509,9 +60636,12 @@ function useAttachments() {
60509
60636
  }
60510
60637
  return ctx;
60511
60638
  }
60512
- function buildAttachmentMarkdown(attachments) {
60639
+ function buildAttachmentMarkdownWithAppUrl({
60640
+ attachments,
60641
+ appUrl = DEFAULT_APP_URL
60642
+ }) {
60513
60643
  if (attachments.length === 0) return "";
60514
- return attachments.map((a) => `[@${a.title}](https://app.athenaintel.com/dashboard/spaces?asset_id=${a.id})`).join("\n");
60644
+ return attachments.map((attachment) => `[@${attachment.title}](${createAthenaSpacesUrl({ appUrl, assetIds: attachment.id })})`).join("\n");
60515
60645
  }
60516
60646
  const QuoteCtx = createContext(null);
60517
60647
  function QuoteProvider({ children }) {
@@ -60577,7 +60707,10 @@ function buildComposedMessage(opts) {
60577
60707
  var _a2;
60578
60708
  const parts = [];
60579
60709
  if (opts.attachments && opts.attachments.length > 0) {
60580
- const attachmentMd = buildAttachmentMarkdown(opts.attachments);
60710
+ const attachmentMd = buildAttachmentMarkdownWithAppUrl({
60711
+ attachments: opts.attachments,
60712
+ appUrl: opts.appUrl
60713
+ });
60581
60714
  if (attachmentMd) parts.push(attachmentMd);
60582
60715
  }
60583
60716
  if (opts.quote) {
@@ -60598,6 +60731,7 @@ const TiptapComposer = ({ tools = [] }) => {
60598
60731
  const mentionStore = useMentionSuggestions(tools);
60599
60732
  const { attachments, clearAttachments, isUploading } = useAttachments();
60600
60733
  const { quote, clearQuote } = useQuote();
60734
+ const { appUrl } = useAthenaConfig();
60601
60735
  const attachmentsRef = useRef(attachments);
60602
60736
  attachmentsRef.current = attachments;
60603
60737
  const quoteRef = useRef(quote);
@@ -60618,7 +60752,8 @@ const TiptapComposer = ({ tools = [] }) => {
60618
60752
  const fullMessage = buildComposedMessage({
60619
60753
  attachments: currentAttachments,
60620
60754
  quote: currentQuote,
60621
- userText: markdown
60755
+ userText: markdown,
60756
+ appUrl
60622
60757
  });
60623
60758
  if (fullMessage) {
60624
60759
  aui.thread().append({
@@ -63543,9 +63678,6 @@ function useFileUpload() {
63543
63678
  formData.append("files", file, file.name);
63544
63679
  }
63545
63680
  const baseUrl = backendUrl.replace(/\/api\/assistant-ui\/?$/, "");
63546
- if (baseUrl === backendUrl) {
63547
- console.warn("[AthenaSDK] useFileUpload: backendUrl does not end with /api/assistant-ui — upload URL may be incorrect:", `${baseUrl}/api/upload/`);
63548
- }
63549
63681
  const uploadUrl = `${baseUrl}/api/upload/`;
63550
63682
  const headers = {};
63551
63683
  if (token) {
@@ -63968,6 +64100,7 @@ const ComposerAction = () => /* @__PURE__ */ jsxs("div", { className: "aui-compo
63968
64100
  ] });
63969
64101
  const ComposerSendWithQuote = () => {
63970
64102
  const aui = useAui();
64103
+ const { appUrl } = useAthenaConfig();
63971
64104
  const { quote, clearQuote } = useQuote();
63972
64105
  const { attachments, clearAttachments, isUploading } = useAttachments();
63973
64106
  const editorRef = useComposerEditorRef();
@@ -63981,7 +64114,8 @@ const ComposerSendWithQuote = () => {
63981
64114
  const fullMessage = buildComposedMessage({
63982
64115
  attachments,
63983
64116
  quote,
63984
- userText
64117
+ userText,
64118
+ appUrl
63985
64119
  });
63986
64120
  if (!fullMessage) return;
63987
64121
  aui.thread().append({
@@ -64065,6 +64199,7 @@ const AssistantMessage = ({ toolUIs }) => /* @__PURE__ */ jsxs(
64065
64199
  );
64066
64200
  const AssistantActionBar = () => {
64067
64201
  const threadId = useAthenaThreadId();
64202
+ const { appUrl } = useAthenaConfig();
64068
64203
  return /* @__PURE__ */ jsxs(
64069
64204
  ActionBarPrimitiveRoot,
64070
64205
  {
@@ -64094,10 +64229,7 @@ const AssistantActionBar = () => {
64094
64229
  {
64095
64230
  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
64231
  onClick: () => {
64097
- window.open(
64098
- `https://app.athenaintel.com/dashboard/spaces?session_id=${threadId}`,
64099
- "_blank"
64100
- );
64232
+ window.open(createAthenaSpacesUrl({ appUrl, sessionId: threadId }), "_blank");
64101
64233
  },
64102
64234
  children: [
64103
64235
  /* @__PURE__ */ jsx(ExternalLink, { className: "size-4" }),
@@ -64146,8 +64278,8 @@ function useAssetEmbed(assetId, options = {
64146
64278
  setError(null);
64147
64279
  return;
64148
64280
  }
64149
- const agoraBase = backendUrl.replace(/\/api\/assistant-ui\/?$/, "");
64150
- const endpoint = `${agoraBase}/api/embed/generate-token`;
64281
+ const apiBaseUrl = backendUrl.replace(/\/api\/assistant-ui\/?$/, "");
64282
+ const endpoint = `${apiBaseUrl}/api/embed/generate-token`;
64151
64283
  (_a2 = abortRef.current) == null ? void 0 : _a2.abort();
64152
64284
  const controller = new AbortController();
64153
64285
  abortRef.current = controller;
@@ -64585,6 +64717,7 @@ export {
64585
64717
  CreatePresentationToolUI,
64586
64718
  CreateSheetToolUI,
64587
64719
  DEFAULT_API_URL,
64720
+ DEFAULT_APP_URL,
64588
64721
  DEFAULT_BACKEND_URL,
64589
64722
  EmailSearchToolUI,
64590
64723
  ExpandableSection,