local-operator-ui 0.5.1 → 0.5.3

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.
@@ -1,4 +1,4 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./index-B87fKloA.js","./fonts-ChEL5asK.js","./fonts-B9KBGB-g.css","./index-CfuGYyUa.js","./pug-By0kVCfm.js","./javascript-C3MnDRiU.js"])))=>i.map(i=>d[i]);
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./index-PjN-o7b5.js","./fonts-ChEL5asK.js","./fonts-B9KBGB-g.css","./index-Bi6Xp3wq.js","./pug-By0kVCfm.js","./javascript-C3MnDRiU.js"])))=>i.map(i=>d[i]);
2
2
  import { c as createStyled, r as resolveProps, u as useTheme, a as reactExports, b as clsx, d as useForkRef, e as extendSxProp, j as jsxRuntimeExports, h as handleBreakpoints, f as resolveBreakpointValues, g as createUnarySpacing, i as deepmerge, m as mergeBreakpointsInOrder, k as composeClasses, l as generateUtilityClass, n as createTheme$1, o as getValue, R as React, p as getDefaultExportFromCjs, q as requireReactDom, s as React$1, t as generateUtilityClasses, v as useDefaultProps, w as styled$1, x as capitalize, y as memoTheme, _ as _inheritsLoose, z as _objectWithoutPropertiesLoose$i, T as TransitionGroupContext, A as duration, B as useTheme$1, C as useTimeout, D as useId, E as ButtonBase, F as alpha$1, G as createSimplePaletteValueFilter, H as CircularProgress, P as Paper, I as darken, J as lighten, K as useEventCallback, L as useEnhancedEffect, M as useRtl, N as globalCss, O as formatMuiErrorMessage, Q as rootShouldForwardProp, S as Typography, U as getPath$2, V as isFocusVisible, W as typographyClasses, X as slotShouldForwardProp, Y as css$1, Z as keyframes, $ as clamp, a0 as emphasize, a1 as Timeout, a2 as Button, a3 as Box, a4 as FontAwesomeIcon, a5 as faExclamationTriangle, a6 as faEllipsisVertical, a7 as faComment, a8 as faGear, a9 as faFileExport, aa as faBroom, ab as faTrash, ac as DEFAULT_THEME, ad as faChevronLeft, ae as faChevronRight, af as faRobot, ag as faCheck, ah as faTimes, ai as faEraser, aj as faPen, ak as faFileImport, al as faUpload, am as faPlus, an as faSearch, ao as requireReact, ap as LinearProgress, aq as faComments, ar as faInfoCircle, as as faServer, at as faStar, au as faTag, av as faIdCard, aw as faCalendarAlt, ax as faCodeBranch, ay as faShieldAlt, az as faArrowLeft, aA as faClock, aB as faHome, aC as faDownload, aD as faFileAlt, aE as faDesktop, aF as faImage, aG as faMusic, aH as faVideo, aI as faLaptop, aJ as faUsers, aK as faDatabase, aL as faBoxOpen, aM as faBook, aN as faHdd, aO as faBox, aP as faArchive, aQ as faNetworkWired, aR as faFolder, aS as faFolderOpen, aT as faFolderTree, aU as faChevronDown, aV as faTools, aW as _extends$u, aX as faSliders, aY as faArrowDown, aZ as faPaperclip, a_ as faStop, a$ as faPaperPlane, b0 as faChevronUp, b1 as faQuestion, b2 as faFile, b3 as faExclamationCircle, b4 as faLightbulb, b5 as faCode, b6 as faCommentDots, b7 as faEdit, b8 as faPencilAlt, b9 as faUser, ba as faCopy, bb as isDevelopmentMode, bc as faCommentSlash, bd as faArrowRight, be as faMagicWandSparkles, bf as faBrain, bg as faWandMagicSparkles, bh as faExternalLinkAlt, bi as faKey, bj as radientTheme, bk as faGlobe, bl as commonjsGlobal, bm as PropTypes, bn as faLock, bo as faSignOut, bp as faAdjust, bq as faSave, br as themes, bs as faMoon, bt as faSun, bu as faHexagonNodes, bv as faSkull, bw as faLeaf, bx as faMountain, by as faFire, bz as faIcicles, bA as faEnvelope, bB as faHistory, bC as faListAlt, bD as faCreditCard, bE as faPlusCircle, bF as faChartLine, bG as faShield, bH as library$1, bI as icons$1, bJ as CssBaseline, bK as ThemeProvider$1, bL as getTheme, bM as ReactDOM$1, bN as ErrorBoundary } from "./fonts-ChEL5asK.js";
3
3
  const styled = createStyled();
4
4
  function getThemeProps(params) {
@@ -27066,15 +27066,23 @@ const AgentsApi = {
27066
27066
  * @param page - Page number (default: 1)
27067
27067
  * @param perPage - Number of agents per page (default: 10)
27068
27068
  * @param name - Optional name query to search agents by name
27069
+ * @param sort - Optional field to sort by (e.g., 'name', 'created_date', 'last_message_datetime')
27070
+ * @param direction - Optional sort direction ('asc' or 'desc')
27069
27071
  * @returns Promise resolving to the agents list response
27070
27072
  */
27071
- async listAgents(baseUrl, page = 1, perPage = 10, name2) {
27073
+ async listAgents(baseUrl, page = 1, perPage = 10, name2, sort, direction) {
27072
27074
  const url = new URL(`${baseUrl}/v1/agents`);
27073
27075
  url.searchParams.append("page", page.toString());
27074
27076
  url.searchParams.append("per_page", perPage.toString());
27075
27077
  if (name2) {
27076
27078
  url.searchParams.append("name", name2);
27077
27079
  }
27080
+ if (sort) {
27081
+ url.searchParams.append("sort", sort);
27082
+ }
27083
+ if (direction) {
27084
+ url.searchParams.append("direction", direction);
27085
+ }
27078
27086
  const response = await fetch(url.toString(), {
27079
27087
  method: "GET",
27080
27088
  headers: {
@@ -33132,7 +33140,7 @@ const useConnectivityGate = () => {
33132
33140
  };
33133
33141
  };
33134
33142
  const agentsQueryKey = ["agents"];
33135
- const useAgents = (page = 1, perPage = 50, refetchInterval = 0, name2) => {
33143
+ const useAgents = (page = 1, perPage = 50, refetchInterval = 0, name2, sort, direction) => {
33136
33144
  const { shouldEnableQuery, getConnectivityError } = useConnectivityGate();
33137
33145
  const connectivityError = getConnectivityError();
33138
33146
  reactExports.useEffect(() => {
@@ -33143,15 +33151,21 @@ const useAgents = (page = 1, perPage = 50, refetchInterval = 0, name2) => {
33143
33151
  return useQuery({
33144
33152
  // Only enable the query if server is online (bypass internet check)
33145
33153
  enabled: shouldEnableQuery({ bypassInternetCheck: true }),
33146
- queryKey: [...agentsQueryKey, page, perPage, name2],
33154
+ queryKey: [...agentsQueryKey, page, perPage, name2, sort, direction],
33147
33155
  queryFn: async () => {
33148
33156
  try {
33149
33157
  const client = createLocalOperatorClient(apiConfig.baseUrl);
33150
- const response = await client.agents.listAgents(page, perPage, name2);
33151
- if (response.status >= 400) {
33158
+ const response = await client.agents.listAgents(
33159
+ page,
33160
+ perPage,
33161
+ name2,
33162
+ sort,
33163
+ direction
33164
+ );
33165
+ if (response.status >= 400 || !response.result) {
33152
33166
  throw new Error(response.message || "Failed to fetch agents");
33153
33167
  }
33154
- return response.result?.agents || [];
33168
+ return response.result;
33155
33169
  } catch (error) {
33156
33170
  const errorMessage = error instanceof Error ? error.message : "An unknown error occurred while fetching agents";
33157
33171
  showErrorToast(errorMessage);
@@ -34065,7 +34079,9 @@ const DividerFlexItem = styled$1(Box)({
34065
34079
  flexShrink: 0,
34066
34080
  zIndex: 10
34067
34081
  });
34068
- const DividerHoverArea = styled$1(Box)(({ $active, $side }) => ({
34082
+ const DividerHoverArea = styled$1(Box, {
34083
+ shouldForwardProp: (prop) => prop !== "$active" && prop !== "$side"
34084
+ })(({ $active, $side }) => ({
34069
34085
  position: "absolute",
34070
34086
  top: 0,
34071
34087
  [$side]: 0,
@@ -34078,7 +34094,9 @@ const DividerHoverArea = styled$1(Box)(({ $active, $side }) => ({
34078
34094
  zIndex: 11,
34079
34095
  transition: "width 0.2s cubic-bezier(0.4,0,0.2,1)"
34080
34096
  }));
34081
- const DividerLine = styled$1(Box)(
34097
+ const DividerLine = styled$1(Box, {
34098
+ shouldForwardProp: (prop) => prop !== "$active" && prop !== "$side"
34099
+ })(
34082
34100
  ({ theme: theme2, $side, $active }) => ({
34083
34101
  position: "absolute",
34084
34102
  top: 0,
@@ -34093,7 +34111,9 @@ const DividerLine = styled$1(Box)(
34093
34111
  transition: "width 0.2s cubic-bezier(0.4,0,0.2,1), background 0.2s, opacity 0.2s"
34094
34112
  })
34095
34113
  );
34096
- const DragHandle = styled$1(Box)(({ theme: theme2, $active }) => ({
34114
+ const DragHandle = styled$1(Box, {
34115
+ shouldForwardProp: (prop) => prop !== "$active"
34116
+ })(({ theme: theme2, $active }) => ({
34097
34117
  position: "absolute",
34098
34118
  left: "50%",
34099
34119
  top: "50%",
@@ -34265,37 +34285,80 @@ const useDeferredUpdatesStore = create$1()(
34265
34285
  const CheckForUpdatesButton = () => {
34266
34286
  const [checking, setChecking] = reactExports.useState(false);
34267
34287
  const [snackbarOpen, setSnackbarOpen] = reactExports.useState(false);
34288
+ const [snackbarMessage, setSnackbarMessage] = reactExports.useState(null);
34289
+ const [snackbarSeverity, setSnackbarSeverity] = reactExports.useState("info");
34268
34290
  const [manualUpdateInfo, setManualUpdateInfo] = reactExports.useState(null);
34291
+ const manualCheckRef = reactExports.useRef(false);
34269
34292
  const { clearDeferredUpdate } = useDeferredUpdatesStore();
34270
34293
  reactExports.useEffect(() => {
34271
- const removeManualUpdateListener = window.api.updater.onUpdateError(
34294
+ const removeUpdateErrorListener = window.api.updater.onUpdateError(
34272
34295
  (message2) => {
34296
+ if (!manualCheckRef.current) return;
34297
+ const suppressedPatterns = [
34298
+ "ENOENT: no such file or directory, open",
34299
+ // e.g. missing update yml
34300
+ "Could not get code signature for running application",
34301
+ // macOS spurious
34302
+ "Cannot find latest.yml"
34303
+ // electron-updater
34304
+ ];
34305
+ const isSuppressed = suppressedPatterns.some(
34306
+ (pat) => message2.includes(pat)
34307
+ );
34273
34308
  if (message2.includes("manually")) {
34274
34309
  setManualUpdateInfo({
34275
34310
  message: "Please update the local-operator package manually using pip.",
34276
34311
  command: "pip install --upgrade local-operator"
34277
34312
  });
34313
+ setSnackbarSeverity("warning");
34314
+ setSnackbarOpen(true);
34315
+ } else if (!isSuppressed) {
34316
+ setSnackbarMessage(message2);
34317
+ setSnackbarSeverity("error");
34278
34318
  setSnackbarOpen(true);
34279
34319
  }
34280
34320
  }
34281
34321
  );
34322
+ const removeUpdateNotAvailableListener = window.api.updater.onUpdateNotAvailable(() => {
34323
+ if (!manualCheckRef.current) return;
34324
+ setSnackbarMessage("No updates available. You are up to date!");
34325
+ setSnackbarSeverity("success");
34326
+ setSnackbarOpen(true);
34327
+ });
34328
+ const removeBackendUpdateNotAvailableListener = window.api.updater.onBackendUpdateNotAvailable(() => {
34329
+ if (!manualCheckRef.current) return;
34330
+ setSnackbarMessage("No server updates available. You are up to date!");
34331
+ setSnackbarSeverity("success");
34332
+ setSnackbarOpen(true);
34333
+ });
34282
34334
  return () => {
34283
- removeManualUpdateListener();
34335
+ removeUpdateErrorListener();
34336
+ removeUpdateNotAvailableListener();
34337
+ removeBackendUpdateNotAvailableListener();
34284
34338
  };
34285
34339
  }, []);
34286
34340
  const checkForUpdates = async () => {
34287
34341
  try {
34288
34342
  setChecking(true);
34343
+ manualCheckRef.current = true;
34289
34344
  clearDeferredUpdate();
34290
34345
  await window.api.updater.checkForAllUpdates();
34291
34346
  } catch (error) {
34292
- console.error("Error checking for updates:", error);
34347
+ setSnackbarMessage(
34348
+ `Error checking for updates: ${error instanceof Error ? error.message : String(error)}`
34349
+ );
34350
+ setSnackbarSeverity("error");
34351
+ setSnackbarOpen(true);
34293
34352
  } finally {
34294
34353
  setChecking(false);
34354
+ setTimeout(() => {
34355
+ manualCheckRef.current = false;
34356
+ }, 2e3);
34295
34357
  }
34296
34358
  };
34297
34359
  const handleSnackbarClose = () => {
34298
34360
  setSnackbarOpen(false);
34361
+ setSnackbarMessage(null);
34299
34362
  };
34300
34363
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
34301
34364
  /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -34341,6 +34404,24 @@ const CheckForUpdatesButton = () => {
34341
34404
  }
34342
34405
  )
34343
34406
  }
34407
+ ),
34408
+ snackbarMessage && /* @__PURE__ */ jsxRuntimeExports.jsx(
34409
+ Snackbar,
34410
+ {
34411
+ open: snackbarOpen,
34412
+ autoHideDuration: 6e3,
34413
+ onClose: handleSnackbarClose,
34414
+ anchorOrigin: { vertical: "bottom", horizontal: "right" },
34415
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
34416
+ Alert,
34417
+ {
34418
+ onClose: handleSnackbarClose,
34419
+ severity: snackbarSeverity,
34420
+ sx: { width: "100%" },
34421
+ children: snackbarMessage
34422
+ }
34423
+ )
34424
+ }
34344
34425
  )
34345
34426
  ] });
34346
34427
  };
@@ -35339,7 +35420,7 @@ const useModels = ({ autoFetch = true } = {}) => {
35339
35420
  fetchModels(baseUrl);
35340
35421
  }
35341
35422
  }, [hasConnectivityIssue, autoFetch, isInitialized, baseUrl, fetchModels]);
35342
- const refreshModels = async () => {
35423
+ const refreshModels = reactExports.useCallback(async () => {
35343
35424
  if (shouldEnableQuery({ bypassInternetCheck: true })) {
35344
35425
  await fetchModels(baseUrl, true);
35345
35426
  } else {
@@ -35348,7 +35429,7 @@ const useModels = ({ autoFetch = true } = {}) => {
35348
35429
  throw error2;
35349
35430
  }
35350
35431
  }
35351
- };
35432
+ }, [baseUrl, fetchModels, shouldEnableQuery, getConnectivityError]);
35352
35433
  const getModelById = (modelId) => {
35353
35434
  return models.find((model) => model.id === modelId);
35354
35435
  };
@@ -35684,7 +35765,9 @@ const useMessageInput = ({
35684
35765
  setHistoryIndex(null);
35685
35766
  draftMessageRef.current = "";
35686
35767
  if (scrollToBottom) {
35687
- scrollToBottom();
35768
+ setTimeout(() => {
35769
+ scrollToBottom();
35770
+ }, 150);
35688
35771
  }
35689
35772
  }, [inputValue, onSubmit, scrollToBottom]);
35690
35773
  const getCursorPosition = reactExports.useCallback(() => {
@@ -35832,14 +35915,14 @@ function jwtDecode(token2, options) {
35832
35915
  throw new InvalidTokenError(`Invalid token specified: invalid json for part #${pos + 1} (${e3.message})`);
35833
35916
  }
35834
35917
  }
35835
- function joinUrl(baseUrl, path2) {
35918
+ function joinUrl$1(baseUrl, path2) {
35836
35919
  const normalizedBaseUrl = baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`;
35837
35920
  const normalizedPath = path2.startsWith("/") ? path2.slice(1) : path2;
35838
35921
  return normalizedBaseUrl + normalizedPath;
35839
35922
  }
35840
35923
  async function exchangeToken(baseUrl, provider, tokens2, clientId) {
35841
35924
  const endpoint = provider === "google" ? "/v1/auth/google" : "/v1/auth/microsoft";
35842
- const url = joinUrl(baseUrl, endpoint);
35925
+ const url = joinUrl$1(baseUrl, endpoint);
35843
35926
  const body2 = {
35844
35927
  id_token: tokens2.idToken,
35845
35928
  access_token: tokens2.accessToken,
@@ -35860,7 +35943,7 @@ async function exchangeToken(baseUrl, provider, tokens2, clientId) {
35860
35943
  return response.json();
35861
35944
  }
35862
35945
  async function createApplication(baseUrl, tenantId, accessToken, applicationData) {
35863
- const url = joinUrl(baseUrl, `/v1/tenants/${tenantId}/applications`);
35946
+ const url = joinUrl$1(baseUrl, `/v1/tenants/${tenantId}/applications`);
35864
35947
  const response = await fetch(url, {
35865
35948
  method: "POST",
35866
35949
  headers: {
@@ -35883,7 +35966,7 @@ async function exchangeMicrosoftToken(baseUrl, tokens2, clientId) {
35883
35966
  return exchangeToken(baseUrl, "microsoft", tokens2, clientId);
35884
35967
  }
35885
35968
  async function getUserInfo(baseUrl, accessToken) {
35886
- const url = joinUrl(baseUrl, "/v1/me");
35969
+ const url = joinUrl$1(baseUrl, "/v1/me");
35887
35970
  const response = await fetch(url, {
35888
35971
  method: "GET",
35889
35972
  headers: {
@@ -35898,7 +35981,7 @@ async function getUserInfo(baseUrl, accessToken) {
35898
35981
  return response.json();
35899
35982
  }
35900
35983
  async function provisionAccount(baseUrl, accessToken) {
35901
- const url = joinUrl(baseUrl, "/v1/provision");
35984
+ const url = joinUrl$1(baseUrl, "/v1/provision");
35902
35985
  const response = await fetch(url, {
35903
35986
  method: "POST",
35904
35987
  headers: {
@@ -35915,7 +35998,7 @@ async function provisionAccount(baseUrl, accessToken) {
35915
35998
  return response.json();
35916
35999
  }
35917
36000
  async function refreshToken(baseUrl, refreshToken2, clientId) {
35918
- const url = joinUrl(baseUrl, "/v1/auth/token");
36001
+ const url = joinUrl$1(baseUrl, "/v1/auth/token");
35919
36002
  const body2 = {
35920
36003
  refresh_token: refreshToken2,
35921
36004
  grant_type: "refresh_token",
@@ -35936,7 +36019,7 @@ async function refreshToken(baseUrl, refreshToken2, clientId) {
35936
36019
  return response.json();
35937
36020
  }
35938
36021
  async function revokeToken(baseUrl, token2, tokenType) {
35939
- const url = joinUrl(baseUrl, "/v1/auth/revoke");
36022
+ const url = joinUrl$1(baseUrl, "/v1/auth/revoke");
35940
36023
  const response = await fetch(url, {
35941
36024
  method: "POST",
35942
36025
  headers: {
@@ -35993,6 +36076,46 @@ const BillingApiImpl = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defi
35993
36076
  __proto__: null,
35994
36077
  getCreditBalance
35995
36078
  }, Symbol.toStringTag, { value: "Module" }));
36079
+ function joinUrl(baseUrl, path2) {
36080
+ const normalizedBaseUrl = baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`;
36081
+ const normalizedPath = path2.startsWith("/") ? path2.slice(1) : path2;
36082
+ return normalizedBaseUrl + normalizedPath;
36083
+ }
36084
+ const fetchPrices = async (baseUrl) => {
36085
+ const url = joinUrl(baseUrl, "/v1/prices");
36086
+ try {
36087
+ const response = await fetch(url, {
36088
+ method: "GET",
36089
+ headers: {
36090
+ // No Authorization needed for this public endpoint
36091
+ "Content-Type": "application/json"
36092
+ },
36093
+ credentials: "same-origin"
36094
+ // Match credentials policy from auth-api
36095
+ });
36096
+ if (!response.ok) {
36097
+ const errorText = await response.text();
36098
+ console.error(
36099
+ `Error fetching Radient prices: ${response.status} ${errorText}`
36100
+ );
36101
+ throw new Error(
36102
+ errorText || `Failed to fetch Radient prices: ${response.status}`
36103
+ );
36104
+ }
36105
+ const apiResponse = await response.json();
36106
+ return apiResponse.result;
36107
+ } catch (error) {
36108
+ console.error("Error during fetchPrices execution:", error);
36109
+ if (error instanceof Error) {
36110
+ throw error;
36111
+ }
36112
+ throw new Error("An unknown error occurred while fetching prices");
36113
+ }
36114
+ };
36115
+ const PricesApiImpl = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
36116
+ __proto__: null,
36117
+ fetchPrices
36118
+ }, Symbol.toStringTag, { value: "Module" }));
35996
36119
  const getUsageRollup = async (baseUrl, tenantId, accessToken, params) => {
35997
36120
  const endpointUrl = `${baseUrl}/v1/tenants/${tenantId}/usage/rollup`;
35998
36121
  const queryParams = new URLSearchParams();
@@ -36060,6 +36183,12 @@ class RadientClient {
36060
36183
  get usage() {
36061
36184
  return this.bindBaseUrlToApi(UsageApiImpl);
36062
36185
  }
36186
+ /**
36187
+ * Get the Prices API client with methods bound to the base URL
36188
+ */
36189
+ get prices() {
36190
+ return this.bindBaseUrlToApi(PricesApiImpl);
36191
+ }
36063
36192
  /**
36064
36193
  * Bind the base URL to all methods of an API module
36065
36194
  *
@@ -36197,34 +36326,57 @@ async function updateAccessToken(accessToken, expiresIn, newRefreshToken) {
36197
36326
  const expiry = Date.now() + expiresIn * 1e3;
36198
36327
  await window.api.session.storeSession(accessToken, expiry, refreshToken2);
36199
36328
  }
36200
- const queryClient = new QueryClient({
36201
- defaultOptions: {
36202
- queries: {
36203
- // Default stale time of 5 minutes
36204
- staleTime: 5 * 60 * 1e3,
36205
- // Default cache time of 10 minutes
36206
- gcTime: 10 * 60 * 1e3,
36207
- // Default retry configuration
36208
- retry: 1,
36209
- // Default refetch configuration
36210
- refetchOnWindowFocus: true,
36211
- refetchOnMount: true,
36212
- // Don't wait for reconnect to refetch - we handle offline status separately
36213
- refetchOnReconnect: false,
36214
- // Continue to run queries even when offline
36215
- networkMode: "always"
36216
- },
36217
- mutations: {
36218
- // Retry mutations once by default
36219
- retry: 1,
36220
- // Continue to run mutations even when offline
36221
- networkMode: "always"
36222
- }
36223
- }
36224
- });
36225
- const resetQueryCache = () => {
36226
- queryClient.clear();
36329
+ const DEFAULT_PROFILE = {
36330
+ name: "User",
36331
+ email: "user@example.com"
36227
36332
  };
36333
+ const useUserStore = create$1()(
36334
+ persist(
36335
+ (set) => ({
36336
+ profile: DEFAULT_PROFILE,
36337
+ isSigningOut: false,
36338
+ // Default value
36339
+ updateName: (name2) => {
36340
+ set((state) => ({
36341
+ profile: {
36342
+ ...state.profile,
36343
+ name: name2
36344
+ }
36345
+ }));
36346
+ },
36347
+ updateEmail: (email2) => {
36348
+ set((state) => ({
36349
+ profile: {
36350
+ ...state.profile,
36351
+ email: email2
36352
+ }
36353
+ }));
36354
+ },
36355
+ updateProfile: (profile) => {
36356
+ set((state) => ({
36357
+ profile: {
36358
+ ...state.profile,
36359
+ ...profile
36360
+ }
36361
+ }));
36362
+ },
36363
+ setIsSigningOut: (status) => {
36364
+ set({ isSigningOut: status });
36365
+ },
36366
+ clearProfile: () => {
36367
+ set({
36368
+ profile: {
36369
+ name: "",
36370
+ email: ""
36371
+ }
36372
+ });
36373
+ }
36374
+ }),
36375
+ {
36376
+ name: "user-profile-storage"
36377
+ }
36378
+ )
36379
+ );
36228
36380
  const radientUserKeys = {
36229
36381
  all: ["radient-user"],
36230
36382
  user: () => [...radientUserKeys.all, "user"],
@@ -36233,6 +36385,7 @@ const radientUserKeys = {
36233
36385
  };
36234
36386
  const useRadientUserQuery = () => {
36235
36387
  const queryClient2 = useQueryClient();
36388
+ const { setIsSigningOut } = useUserStore();
36236
36389
  const radientClient2 = createRadientClient(
36237
36390
  apiConfig.radientBaseUrl,
36238
36391
  apiConfig.radientClientId
@@ -36353,6 +36506,9 @@ const useRadientUserQuery = () => {
36353
36506
  const hasLocalSession = !!sessionQuery.data && !sessionQuery.isLoading;
36354
36507
  const isAuthenticated = !!userQuery.data && !userQuery.isLoading;
36355
36508
  const signOutMutation = useMutation({
36509
+ onMutate: () => {
36510
+ setIsSigningOut(true);
36511
+ },
36356
36512
  mutationFn: async () => {
36357
36513
  const session = sessionQuery.data;
36358
36514
  if (session?.refreshToken) {
@@ -36365,16 +36521,20 @@ const useRadientUserQuery = () => {
36365
36521
  console.error("Failed to revoke refresh token:", error);
36366
36522
  }
36367
36523
  }
36368
- clearSession();
36524
+ await clearSession();
36369
36525
  return true;
36370
36526
  },
36371
- onSuccess: () => {
36372
- resetQueryCache();
36527
+ onSuccess: async () => {
36528
+ await clearSession();
36529
+ queryClient2.removeQueries({ queryKey: radientUserKeys.all });
36530
+ refreshTokenMutation.reset();
36373
36531
  showSuccessToast("Successfully signed out");
36532
+ setIsSigningOut(false);
36374
36533
  },
36375
36534
  onError: (error) => {
36376
36535
  const errorMessage = error instanceof Error ? error.message : String(error);
36377
36536
  showErrorToast(`Failed to sign out: ${errorMessage}`);
36537
+ setIsSigningOut(false);
36378
36538
  }
36379
36539
  });
36380
36540
  const refreshUserMutation = useMutation({
@@ -36455,7 +36615,7 @@ const radientClient = createRadientClient(
36455
36615
  apiConfig.radientClientId
36456
36616
  );
36457
36617
  const useOidcAuth = (options) => {
36458
- const { onSuccess } = options || {};
36618
+ const { onSuccess, onAfterCredentialUpdate } = options || {};
36459
36619
  const [loading, setLoading] = reactExports.useState(true);
36460
36620
  const [error, setError] = reactExports.useState(null);
36461
36621
  const [status, setStatus] = reactExports.useState({
@@ -36522,6 +36682,13 @@ const useOidcAuth = (options) => {
36522
36682
  key: "RADIENT_API_KEY",
36523
36683
  value: appResponse.result.api_key
36524
36684
  });
36685
+ if (onAfterCredentialUpdate) {
36686
+ try {
36687
+ onAfterCredentialUpdate();
36688
+ } catch (err) {
36689
+ console.error("Error in onAfterCredentialUpdate callback:", err);
36690
+ }
36691
+ }
36525
36692
  try {
36526
36693
  await updateConfig({
36527
36694
  hosting: "radient",
@@ -36550,9 +36717,59 @@ const useOidcAuth = (options) => {
36550
36717
  showErrorToast(msg || "Authentication failed");
36551
36718
  }
36552
36719
  },
36553
- [queryClient2, updateConfig, onSuccess]
36554
- // Added onSuccess dependency
36720
+ [queryClient2, updateConfig, onSuccess, onAfterCredentialUpdate]
36555
36721
  );
36722
+ const signInWithGoogle = reactExports.useCallback(async () => {
36723
+ setLoading(true);
36724
+ setError(null);
36725
+ try {
36726
+ const result = await window.api.oauth.login("google");
36727
+ if (!result.success) {
36728
+ throw new Error(result.error || "Failed to initiate Google login");
36729
+ }
36730
+ } catch (err) {
36731
+ const msg = err instanceof Error ? err.message : String(err);
36732
+ console.error("Error initiating Google sign-in:", msg);
36733
+ setError(msg);
36734
+ showErrorToast(msg);
36735
+ setLoading(false);
36736
+ }
36737
+ }, []);
36738
+ const signInWithMicrosoft = reactExports.useCallback(async () => {
36739
+ setLoading(true);
36740
+ setError(null);
36741
+ try {
36742
+ const result = await window.api.oauth.login("microsoft");
36743
+ if (!result.success) {
36744
+ throw new Error(result.error || "Failed to initiate Microsoft login");
36745
+ }
36746
+ } catch (err) {
36747
+ const msg = err instanceof Error ? err.message : String(err);
36748
+ console.error("Error initiating Microsoft sign-in:", msg);
36749
+ setError(msg);
36750
+ showErrorToast(msg);
36751
+ setLoading(false);
36752
+ }
36753
+ }, []);
36754
+ const logout = reactExports.useCallback(async () => {
36755
+ setLoading(true);
36756
+ setError(null);
36757
+ try {
36758
+ const result = await window.api.oauth.logout();
36759
+ if (!result.success) {
36760
+ throw new Error(result.error || "Logout failed");
36761
+ }
36762
+ await window.api.session.clearSession();
36763
+ queryClient2.invalidateQueries({ queryKey: radientUserKeys.all });
36764
+ showSuccessToast("Successfully signed out.");
36765
+ } catch (err) {
36766
+ const msg = err instanceof Error ? err.message : String(err);
36767
+ console.error("Error during logout:", msg);
36768
+ setError(msg);
36769
+ showErrorToast(msg);
36770
+ setLoading(false);
36771
+ }
36772
+ }, [queryClient2]);
36556
36773
  reactExports.useEffect(() => {
36557
36774
  const cleanup = window.api.oauth.onStatusUpdate((newStatus) => {
36558
36775
  setStatus(newStatus);
@@ -36611,57 +36828,6 @@ const useOidcAuth = (options) => {
36611
36828
  };
36612
36829
  checkInitialStatus();
36613
36830
  }, []);
36614
- const signInWithGoogle = reactExports.useCallback(async () => {
36615
- setLoading(true);
36616
- setError(null);
36617
- try {
36618
- const result = await window.api.oauth.login("google");
36619
- if (!result.success) {
36620
- throw new Error(result.error || "Failed to initiate Google login");
36621
- }
36622
- } catch (err) {
36623
- const msg = err instanceof Error ? err.message : String(err);
36624
- console.error("Error initiating Google sign-in:", msg);
36625
- setError(msg);
36626
- showErrorToast(msg);
36627
- setLoading(false);
36628
- }
36629
- }, []);
36630
- const signInWithMicrosoft = reactExports.useCallback(async () => {
36631
- setLoading(true);
36632
- setError(null);
36633
- try {
36634
- const result = await window.api.oauth.login("microsoft");
36635
- if (!result.success) {
36636
- throw new Error(result.error || "Failed to initiate Microsoft login");
36637
- }
36638
- } catch (err) {
36639
- const msg = err instanceof Error ? err.message : String(err);
36640
- console.error("Error initiating Microsoft sign-in:", msg);
36641
- setError(msg);
36642
- showErrorToast(msg);
36643
- setLoading(false);
36644
- }
36645
- }, []);
36646
- const logout = reactExports.useCallback(async () => {
36647
- setLoading(true);
36648
- setError(null);
36649
- try {
36650
- const result = await window.api.oauth.logout();
36651
- if (!result.success) {
36652
- throw new Error(result.error || "Logout failed");
36653
- }
36654
- await window.api.session.clearSession();
36655
- queryClient2.invalidateQueries({ queryKey: radientUserKeys.all });
36656
- showSuccessToast("Successfully signed out.");
36657
- } catch (err) {
36658
- const msg = err instanceof Error ? err.message : String(err);
36659
- console.error("Error during logout:", msg);
36660
- setError(msg);
36661
- showErrorToast(msg);
36662
- setLoading(false);
36663
- }
36664
- }, [queryClient2]);
36665
36831
  return {
36666
36832
  signInWithGoogle,
36667
36833
  signInWithMicrosoft,
@@ -36694,56 +36860,15 @@ const usePaginationParams = () => {
36694
36860
  isView: (view) => location2.pathname.startsWith(`/${view}`)
36695
36861
  };
36696
36862
  };
36697
- const DEFAULT_PROFILE = {
36698
- name: "User",
36699
- email: "user@example.com"
36700
- };
36701
- const useUserStore = create$1()(
36702
- persist(
36703
- (set) => ({
36704
- profile: DEFAULT_PROFILE,
36705
- updateName: (name2) => {
36706
- set((state) => ({
36707
- profile: {
36708
- ...state.profile,
36709
- name: name2
36710
- }
36711
- }));
36712
- },
36713
- updateEmail: (email2) => {
36714
- set((state) => ({
36715
- profile: {
36716
- ...state.profile,
36717
- email: email2
36718
- }
36719
- }));
36720
- },
36721
- updateProfile: (profile) => {
36722
- set((state) => ({
36723
- profile: {
36724
- ...state.profile,
36725
- ...profile
36726
- }
36727
- }));
36728
- }
36729
- }),
36730
- {
36731
- name: "user-profile-storage"
36732
- }
36733
- )
36734
- );
36735
36863
  const useRadientAuth = () => {
36736
36864
  const userStore = useUserStore();
36737
36865
  const {
36738
36866
  user: radientUser,
36739
36867
  session,
36740
36868
  isLoading,
36741
- // Combined loading state from useRadientUserQuery
36742
36869
  error,
36743
36870
  isAuthenticated,
36744
- // Backend validated flag from useRadientUserQuery
36745
36871
  hasLocalSession,
36746
- // Local token exists flag from useRadientUserQuery
36747
36872
  signOut,
36748
36873
  refreshUser,
36749
36874
  refreshToken: refreshToken2
@@ -36757,7 +36882,7 @@ const useRadientAuth = () => {
36757
36882
  authStatus = "unauthenticated";
36758
36883
  }
36759
36884
  reactExports.useEffect(() => {
36760
- if (!radientUser?.account) {
36885
+ if (!isAuthenticated || !radientUser?.account) {
36761
36886
  return;
36762
36887
  }
36763
36888
  const { account } = radientUser;
@@ -36771,31 +36896,23 @@ const useRadientAuth = () => {
36771
36896
  email: account.email || currentEmail
36772
36897
  });
36773
36898
  }
36774
- }, [radientUser, userStore]);
36899
+ }, [isAuthenticated, radientUser, userStore]);
36775
36900
  return {
36776
36901
  // Authentication state
36777
36902
  authStatus,
36778
- // Use the new combined status
36779
36903
  isAuthenticated,
36780
- // Keep backend-validated flag for detailed checks if needed
36781
36904
  hasLocalSession,
36782
- // Expose this flag
36783
36905
  isLoading,
36784
- // Keep the combined loading flag
36785
36906
  error,
36786
- // User information (from Radient or fallback to user store)
36787
- user: {
36788
- name: radientUser?.account?.name || userStore.profile.name,
36789
- email: radientUser?.account?.email || userStore.profile.email,
36790
- // Include the full Radient user object if available
36907
+ // User information: only return if authenticated, otherwise null
36908
+ user: isAuthenticated && radientUser?.account ? {
36909
+ name: radientUser.account.name,
36910
+ email: radientUser.account.email,
36791
36911
  radientUser
36792
- // Added type assertion for clarity
36793
- },
36912
+ } : null,
36794
36913
  // Session token for API calls
36795
36914
  sessionToken: session?.accessToken,
36796
- // Expose the full session for advanced use cases
36797
36915
  session,
36798
- // Token refresh function
36799
36916
  refreshToken: refreshToken2,
36800
36917
  // Actions
36801
36918
  refreshUser,
@@ -37354,7 +37471,7 @@ const useStreamingMessage = ({
37354
37471
  };
37355
37472
  doRefetch();
37356
37473
  }
37357
- }, 100);
37474
+ }, 500);
37358
37475
  }
37359
37476
  } else {
37360
37477
  updateStreamingMessage(messageId, messageData);
@@ -37583,24 +37700,12 @@ const useStreamingMessage = ({
37583
37700
  if (onComplete) {
37584
37701
  onComplete(message2);
37585
37702
  }
37586
- if (refetchOnComplete) {
37587
- const timer = setTimeout(() => {
37588
- if (mountedRef.current) {
37589
- refetchMessage().catch((error2) => {
37590
- const errorMessage = error2 instanceof Error ? error2.message : String(error2);
37591
- console.error(`Error auto-refetching message: ${errorMessage}`);
37592
- });
37593
- }
37594
- }, 500);
37595
- return () => clearTimeout(timer);
37596
- }
37597
37703
  if (!keepAlive) {
37598
37704
  safeDisconnect();
37599
37705
  }
37600
37706
  } else if (!isComplete) {
37601
37707
  isCompletePrevRef.current = false;
37602
37708
  }
37603
- return void 0;
37604
37709
  }, [
37605
37710
  isComplete,
37606
37711
  message2,
@@ -37608,9 +37713,7 @@ const useStreamingMessage = ({
37608
37713
  keepAlive,
37609
37714
  safeDisconnect,
37610
37715
  messageId,
37611
- completeStreamingMessage,
37612
- refetchMessage,
37613
- refetchOnComplete
37716
+ completeStreamingMessage
37614
37717
  ]);
37615
37718
  return {
37616
37719
  message: message2,
@@ -37948,20 +38051,18 @@ const FieldContainer$3 = styled$1(Box)({
37948
38051
  marginBottom: 16
37949
38052
  // Reduced margin
37950
38053
  });
37951
- const FieldLabel$4 = styled$1(Typography)(({ theme: theme2 }) => ({
37952
- marginBottom: 6,
37953
- // Reduced margin
38054
+ const FieldLabel$4 = styled$1("label")(({ theme: theme2 }) => ({
37954
38055
  display: "flex",
37955
38056
  alignItems: "center",
38057
+ marginBottom: 6,
37956
38058
  color: theme2.palette.text.secondary,
37957
38059
  fontWeight: 500,
37958
- // Slightly less bold
37959
- fontSize: "0.875rem"
37960
- // Small text size
38060
+ fontSize: "0.875rem",
38061
+ fontFamily: theme2.typography.fontFamily,
38062
+ lineHeight: theme2.typography.body2.lineHeight
37961
38063
  }));
37962
38064
  const LabelIcon$4 = styled$1(Box)({
37963
38065
  marginRight: 8,
37964
- // Reduced margin
37965
38066
  opacity: 0.9,
37966
38067
  display: "flex",
37967
38068
  alignItems: "center"
@@ -37970,233 +38071,156 @@ const StyledTextField$4 = styled$1(TextField)(
37970
38071
  ({ theme: theme2, multiline }) => ({
37971
38072
  "& .MuiOutlinedInput-root": {
37972
38073
  borderRadius: 6,
37973
- // Slightly less rounded
37974
38074
  backgroundColor: theme2.palette.background.paper,
37975
- // Use paper background
37976
38075
  border: `1px solid ${theme2.palette.divider}`,
37977
- // Use divider color for border
37978
38076
  padding: 0,
37979
- // Remove root padding
37980
38077
  minHeight: multiline ? "auto" : "36px",
37981
- // Target height
37982
38078
  height: multiline ? "auto" : "36px",
37983
- // Explicit height
37984
38079
  alignItems: multiline ? "flex-start" : "center",
37985
38080
  transition: "border-color 0.2s ease, box-shadow 0.2s ease",
37986
38081
  "&:hover": {
37987
38082
  borderColor: theme2.palette.text.secondary,
37988
- // Darker border on hover
37989
38083
  backgroundColor: theme2.palette.background.paper
37990
- // Keep background consistent
37991
38084
  },
37992
38085
  "&.Mui-focused": {
37993
38086
  backgroundColor: theme2.palette.background.paper,
37994
- // Keep background consistent
37995
38087
  borderColor: theme2.palette.primary.main,
37996
- // Primary border color on focus
37997
38088
  boxShadow: `0 0 0 2px ${theme2.palette.primary.main}33`
37998
- // Subtle focus ring like shadcn
37999
38089
  },
38000
- // Remove default outline
38001
38090
  "& .MuiOutlinedInput-notchedOutline": {
38002
38091
  border: "none"
38003
38092
  }
38004
38093
  },
38005
38094
  "& .MuiInputBase-input": {
38006
38095
  padding: multiline ? "8px 12px" : "4px 12px",
38007
- // Target inner padding (vertical 4px)
38008
38096
  fontSize: "0.875rem",
38009
- // Small text size
38010
38097
  lineHeight: 1.5,
38011
- // Adjusted line height
38012
38098
  fontFamily: "inherit",
38013
38099
  height: multiline ? "auto" : "calc(36px - 8px)",
38014
- // Adjust height based on padding
38015
- // Ensure text doesn't overflow container
38016
38100
  overflow: "hidden",
38017
38101
  textOverflow: "ellipsis",
38018
38102
  whiteSpace: multiline ? "pre-wrap" : "nowrap",
38019
38103
  wordBreak: "break-word",
38020
- // Keep break-word for multiline
38021
38104
  alignSelf: multiline ? "flex-start" : "center"
38022
- // Center single line text vertically
38023
38105
  },
38024
- // Style placeholder
38025
38106
  "& .MuiInputBase-input::placeholder": {
38026
38107
  color: theme2.palette.text.disabled,
38027
38108
  opacity: 1
38028
- // Ensure placeholder is visible
38029
38109
  }
38030
38110
  })
38031
38111
  );
38032
38112
  const ActionButtonsContainer = styled$1(Box)({
38033
38113
  position: "absolute",
38034
38114
  top: "50%",
38035
- // Center vertically
38036
38115
  transform: "translateY(-50%)",
38037
- // Adjust vertical centering
38038
38116
  right: 6,
38039
- // Position from right
38040
38117
  display: "flex",
38041
38118
  alignItems: "center",
38042
- // Align items vertically
38043
38119
  gap: 4,
38044
38120
  zIndex: 10
38045
38121
  });
38046
38122
  const ActionIconButton = styled$1(IconButton)(({ theme: theme2 }) => ({
38047
38123
  padding: 4,
38048
- // Smaller padding
38049
38124
  borderRadius: 4,
38050
- // Slightly rounded corners
38051
38125
  height: 24,
38052
- // Smaller height
38053
38126
  width: 24,
38054
- // Smaller width
38055
38127
  color: theme2.palette.text.secondary,
38056
- // Default color
38057
38128
  "&:hover": {
38058
38129
  backgroundColor: theme2.palette.action.hover,
38059
- // Subtle hover background
38060
38130
  color: theme2.palette.text.primary
38061
38131
  }
38062
38132
  }));
38063
38133
  const SaveButton = styled$1(ActionIconButton)(({ theme: theme2 }) => ({
38064
38134
  color: theme2.palette.success.main,
38065
- // Green color for save
38066
38135
  "&:hover": {
38067
38136
  backgroundColor: `${theme2.palette.success.main}1A`,
38068
- // Lighter green background on hover
38069
38137
  color: theme2.palette.success.dark
38070
38138
  }
38071
38139
  }));
38072
38140
  const CancelButton = styled$1(ActionIconButton)(({ theme: theme2 }) => ({
38073
38141
  color: theme2.palette.error.main,
38074
- // Red color for cancel/close
38075
38142
  "&:hover": {
38076
38143
  backgroundColor: `${theme2.palette.error.main}1A`,
38077
- // Lighter red background on hover
38078
38144
  color: theme2.palette.error.dark
38079
38145
  }
38080
38146
  }));
38081
38147
  const ClearButton = styled$1(Button)(({ theme: theme2 }) => ({
38082
38148
  backgroundColor: theme2.palette.action.selected,
38083
- // Use a subtle background
38084
38149
  color: theme2.palette.error.main,
38085
- // Destructive text color
38086
38150
  minWidth: "auto",
38087
38151
  height: 24,
38088
- // Match icon button height
38089
38152
  padding: "0 8px",
38090
- // Horizontal padding
38091
38153
  fontSize: "0.75rem",
38092
- // Smaller text
38093
38154
  borderRadius: 4,
38094
38155
  textTransform: "none",
38095
- // No uppercase
38096
38156
  boxShadow: "none",
38097
38157
  border: `1px solid ${theme2.palette.action.disabledBackground}`,
38098
- // Subtle border
38099
38158
  marginLeft: 4,
38100
- // Add some space from icons
38101
38159
  marginRight: 16,
38102
38160
  "&:hover": {
38103
38161
  backgroundColor: theme2.palette.action.hover,
38104
- // Consistent hover
38105
38162
  borderColor: theme2.palette.error.light,
38106
38163
  boxShadow: "none"
38107
38164
  },
38108
- // Adjust icon size and margin
38109
38165
  "& .MuiButton-startIcon": {
38110
38166
  marginRight: 4,
38111
38167
  marginLeft: -2,
38112
38168
  "& > *:nth-of-type(1)": {
38113
- // Target the FontAwesomeIcon
38114
38169
  fontSize: "0.8rem"
38115
38170
  }
38116
38171
  }
38117
38172
  }));
38118
- const DisplayContainer = styled$1(Button, {
38173
+ const DisplayContainer = styled$1("button", {
38119
38174
  shouldForwardProp: (prop) => prop !== "multiline"
38120
- // Explicitly type the props passed to the styled Button
38121
38175
  })(({ theme: theme2, multiline }) => ({
38122
38176
  padding: multiline ? "8px 12px" : "4px 12px",
38123
- // Match input padding
38124
38177
  borderRadius: 6,
38125
- // Match input border radius
38126
38178
  backgroundColor: theme2.palette.background.paper,
38127
- // Match input background
38128
38179
  border: `1px solid ${theme2.palette.divider}`,
38129
- // Match input border
38130
38180
  position: "relative",
38131
38181
  minHeight: multiline ? "auto" : "36px",
38132
- // Match input height
38133
38182
  height: multiline ? "auto" : "36px",
38134
- // Explicit height
38135
38183
  display: "flex",
38136
38184
  alignItems: multiline ? "flex-start" : "center",
38137
- // Align text
38138
38185
  transition: "border-color 0.2s ease, background-color 0.2s ease",
38139
38186
  cursor: "pointer",
38140
38187
  boxSizing: "border-box",
38141
- // Ensure padding/border are included in height
38142
- // Button specific resets/styles
38143
38188
  width: "100%",
38144
- // Ensure it takes full width like the input
38145
38189
  textAlign: "left",
38146
- // Align text to the left
38147
38190
  textTransform: "none",
38148
- // Reset button text transform
38149
38191
  justifyContent: "flex-start",
38150
- // Align content (icon, text) to the start
38151
38192
  color: theme2.palette.text.primary,
38152
- // Ensure text color matches input text
38153
38193
  fontWeight: "normal",
38154
- // Reset button font weight
38155
38194
  fontFamily: "inherit",
38156
- // Use default font
38157
- "&:hover": {
38195
+ outline: "none",
38196
+ "&:hover, &:focus": {
38158
38197
  borderColor: theme2.palette.text.secondary,
38159
- // Match input hover border
38160
- backgroundColor: theme2.palette.action.hover,
38161
- // Subtle background change on hover
38162
- "& .edit-button": {
38163
- opacity: 1
38164
- // Show edit button on hover
38165
- }
38198
+ backgroundColor: theme2.palette.action.hover
38199
+ },
38200
+ "&:focus-visible": {
38201
+ outline: `2px solid ${theme2.palette.primary.main}`
38166
38202
  }
38167
38203
  }));
38168
38204
  const DisplayText = styled$1(Typography, {
38169
38205
  shouldForwardProp: (prop) => prop !== "multiline"
38170
38206
  })(({ multiline }) => ({
38171
38207
  fontSize: "0.875rem",
38172
- // Match input text size
38173
38208
  lineHeight: 1.5,
38174
- // Match input line height
38175
38209
  fontFamily: "inherit",
38176
- // Use standard font
38177
38210
  whiteSpace: multiline ? "pre-wrap" : "nowrap",
38178
38211
  wordBreak: "break-word",
38179
38212
  paddingRight: 30,
38180
- // Space for the edit button
38181
38213
  overflow: "hidden",
38182
- // Prevent overflow
38183
38214
  textOverflow: "ellipsis",
38184
- // Add ellipsis if text is too long
38185
38215
  flexGrow: 1,
38186
- // Allow text to take available space
38187
38216
  alignSelf: multiline ? "flex-start" : "center"
38188
- // Center single line text vertically
38189
38217
  }));
38190
38218
  const PlaceholderText = styled$1(Typography)(({ theme: theme2 }) => ({
38191
38219
  color: theme2.palette.text.disabled,
38192
38220
  fontStyle: "normal",
38193
- // Remove italic
38194
38221
  fontSize: "0.875rem",
38195
- // Match input text size
38196
38222
  lineHeight: 1.5,
38197
- // Match input line height
38198
38223
  paddingRight: 30,
38199
- // Space for the edit button
38200
38224
  overflow: "hidden",
38201
38225
  textOverflow: "ellipsis",
38202
38226
  whiteSpace: "nowrap",
@@ -38205,28 +38229,18 @@ const PlaceholderText = styled$1(Typography)(({ theme: theme2 }) => ({
38205
38229
  const EditButton = styled$1(IconButton)(({ theme: theme2 }) => ({
38206
38230
  position: "absolute",
38207
38231
  top: "50%",
38208
- // Center vertically
38209
38232
  transform: "translateY(-50%)",
38210
- // Adjust vertical centering
38211
38233
  right: 6,
38212
- // Position from right
38213
38234
  color: theme2.palette.text.secondary,
38214
- // Use secondary text color
38215
38235
  opacity: 0,
38216
- // Hidden by default
38217
38236
  transition: "opacity 0.2s ease, background-color 0.2s ease, color 0.2s ease",
38218
38237
  padding: 4,
38219
- // Match other icon buttons
38220
38238
  borderRadius: 4,
38221
- // Match other icon buttons
38222
38239
  height: 24,
38223
- // Match other icon buttons
38224
38240
  width: 24,
38225
- // Match other icon buttons
38226
38241
  marginLeft: 4,
38227
38242
  "&:hover": {
38228
38243
  backgroundColor: theme2.palette.action.hover,
38229
- // Subtle hover background
38230
38244
  color: theme2.palette.text.primary
38231
38245
  }
38232
38246
  }));
@@ -38409,62 +38423,64 @@ const EditableField = ({
38409
38423
  }
38410
38424
  )
38411
38425
  ] }) })
38412
- ] }) : (
38413
- // Using Box with role="button" is acceptable for MUI, but ensure accessibility attributes are correct
38414
- /* @__PURE__ */ jsxRuntimeExports.jsxs(
38426
+ ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(Box, { sx: { position: "relative", width: "100%" }, children: [
38427
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
38415
38428
  DisplayContainer,
38416
38429
  {
38430
+ type: "button",
38417
38431
  onClick: handleEdit,
38418
38432
  multiline,
38419
38433
  "aria-label": `Current value: ${displayValue || placeholder2}. Click to edit.`,
38420
- tabIndex: 0,
38421
38434
  onKeyDown: handleDisplayContainerKeyDown,
38422
- children: [
38423
- displayValue ? /* @__PURE__ */ jsxRuntimeExports.jsx(DisplayText, { multiline, children: displayValue }) : /* @__PURE__ */ jsxRuntimeExports.jsx(PlaceholderText, { children: placeholder2 }),
38424
- /* @__PURE__ */ jsxRuntimeExports.jsx(
38425
- EditButton,
38426
- {
38427
- className: "edit-button",
38428
- size: "small",
38429
- onClick: (e3) => {
38430
- e3.stopPropagation();
38431
- handleEdit();
38432
- },
38433
- title: "Edit",
38434
- "aria-label": `Edit ${label}`,
38435
- tabIndex: -1,
38436
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(FontAwesomeIcon, { icon: faPen, size: "xs" })
38437
- }
38438
- ),
38439
- showClearButton && /* @__PURE__ */ jsxRuntimeExports.jsx(
38440
- ClearButton,
38441
- {
38442
- className: "edit-button",
38443
- sx: {
38444
- position: "absolute",
38445
- top: "50%",
38446
- transform: "translateY(-50%)",
38447
- // Position next to edit icon, adjust based on icon size/padding
38448
- right: 30,
38449
- opacity: 0,
38450
- // Hidden by default
38451
- transition: "opacity 0.2s ease",
38452
- pointerEvents: "auto"
38453
- // Ensure it's clickable when visible
38454
- },
38455
- size: "small",
38456
- onClick: clearField,
38457
- title: "Clear field",
38458
- "aria-label": `Clear ${label}`,
38459
- startIcon: /* @__PURE__ */ jsxRuntimeExports.jsx(FontAwesomeIcon, { icon: faEraser }),
38460
- tabIndex: -1,
38461
- children: "Clear"
38462
- }
38463
- )
38464
- ]
38435
+ children: displayValue ? /* @__PURE__ */ jsxRuntimeExports.jsx(DisplayText, { multiline, children: displayValue }) : /* @__PURE__ */ jsxRuntimeExports.jsx(PlaceholderText, { children: placeholder2 })
38436
+ }
38437
+ ),
38438
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
38439
+ EditButton,
38440
+ {
38441
+ className: "edit-button",
38442
+ size: "small",
38443
+ sx: {
38444
+ position: "absolute",
38445
+ top: "50%",
38446
+ right: 6,
38447
+ transform: "translateY(-50%)",
38448
+ opacity: 0,
38449
+ transition: "opacity 0.2s ease",
38450
+ pointerEvents: "auto",
38451
+ "&:hover, &:focus, button:focus + &": { opacity: 1 }
38452
+ },
38453
+ onClick: handleEdit,
38454
+ title: "Edit",
38455
+ "aria-label": `Edit ${label}`,
38456
+ tabIndex: -1,
38457
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(FontAwesomeIcon, { icon: faPen, size: "xs" })
38458
+ }
38459
+ ),
38460
+ showClearButton && /* @__PURE__ */ jsxRuntimeExports.jsx(
38461
+ ClearButton,
38462
+ {
38463
+ className: "edit-button",
38464
+ sx: {
38465
+ position: "absolute",
38466
+ top: "50%",
38467
+ right: 36,
38468
+ transform: "translateY(-50%)",
38469
+ opacity: 0,
38470
+ transition: "opacity 0.2s ease",
38471
+ pointerEvents: "auto",
38472
+ "&:hover, &:focus, button:focus + &": { opacity: 1 }
38473
+ },
38474
+ size: "small",
38475
+ onClick: clearField,
38476
+ title: "Clear field",
38477
+ "aria-label": `Clear ${label}`,
38478
+ startIcon: /* @__PURE__ */ jsxRuntimeExports.jsx(FontAwesomeIcon, { icon: faEraser }),
38479
+ tabIndex: -1,
38480
+ children: "Clear"
38465
38481
  }
38466
38482
  )
38467
- )
38483
+ ] })
38468
38484
  ] });
38469
38485
  };
38470
38486
  const StyledIcon$1 = styled$1(FontAwesomeIcon)(({ theme: theme2 }) => ({
@@ -46309,10 +46325,13 @@ const HostingSelect = ({
46309
46325
  },
46310
46326
  getOptionLabel: (option2) => option2.name,
46311
46327
  isOptionEqualToValue: (option2, value2) => option2.id === value2.id,
46312
- renderOption: (props2, option2) => /* @__PURE__ */ jsxRuntimeExports.jsx("li", { ...props2, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(OptionContainer$1, { children: [
46313
- /* @__PURE__ */ jsxRuntimeExports.jsx(OptionLabel$1, { children: option2.name }),
46314
- option2.description && /* @__PURE__ */ jsxRuntimeExports.jsx(OptionDescription$1, { children: option2.description })
46315
- ] }) }),
46328
+ renderOption: (props2, option2) => {
46329
+ const { key, ...rest } = props2;
46330
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("li", { ...rest, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(OptionContainer$1, { children: [
46331
+ /* @__PURE__ */ jsxRuntimeExports.jsx(OptionLabel$1, { children: option2.name }),
46332
+ option2.description && /* @__PURE__ */ jsxRuntimeExports.jsx(OptionDescription$1, { children: option2.description })
46333
+ ] }) }, key);
46334
+ },
46316
46335
  freeSolo: allowCustom,
46317
46336
  renderInput: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx(
46318
46337
  TextField,
@@ -55913,16 +55932,15 @@ const ModelSelect = ({
55913
55932
  return void 0;
55914
55933
  }, [hostingId, refreshModels, isModelsLoading]);
55915
55934
  const modelOptions = reactExports.useMemo(() => {
55916
- const options = [
55917
- {
55918
- id: "",
55919
- name: "Default",
55920
- description: "Clear model selection",
55921
- model: void 0
55922
- }
55923
- ];
55935
+ const optionsMap = /* @__PURE__ */ new Map();
55936
+ optionsMap.set("", {
55937
+ id: "",
55938
+ name: "Default",
55939
+ description: "Clear model selection",
55940
+ model: void 0
55941
+ });
55924
55942
  for (const model of availableModels) {
55925
- options.push({
55943
+ optionsMap.set(model.id, {
55926
55944
  id: model.id,
55927
55945
  name: model.name,
55928
55946
  description: model.description,
@@ -55930,30 +55948,15 @@ const ModelSelect = ({
55930
55948
  recommended: model.recommended
55931
55949
  });
55932
55950
  }
55933
- const modelExists = availableModels.some((model) => {
55934
- if (model.id === value) {
55935
- return true;
55936
- }
55937
- if (value?.includes("/")) {
55938
- return model.id?.endsWith(value.split("/")[1]);
55939
- }
55940
- if (value && !value.includes("/")) {
55941
- if (model.id.includes("/")) {
55942
- return model.id.endsWith(`/${value}`);
55943
- }
55944
- return model.id === value;
55945
- }
55946
- return false;
55947
- });
55948
- if (value && value.trim() !== "" && !modelExists) {
55949
- options.push({
55951
+ if (value && value.trim() !== "" && !optionsMap.has(value)) {
55952
+ optionsMap.set(value, {
55950
55953
  id: value,
55951
55954
  name: value,
55952
55955
  description: "Custom model",
55953
55956
  model: void 0
55954
55957
  });
55955
55958
  }
55956
- return options;
55959
+ return Array.from(optionsMap.values());
55957
55960
  }, [availableModels, value]);
55958
55961
  const helperText = reactExports.useMemo(() => {
55959
55962
  if (availableModels.length === 0 && hostingId) {
@@ -56079,7 +56082,13 @@ const ModelSelect = ({
56079
56082
  },
56080
56083
  getOptionLabel: (option2) => option2.name,
56081
56084
  isOptionEqualToValue: (option2, value2) => option2.id === value2.id,
56082
- groupBy: (option2) => getProviderFromId(option2.id),
56085
+ groupBy: (option2) => {
56086
+ const modelOption = option2;
56087
+ if (hostingId === "radient" && modelOption.id === "auto") {
56088
+ return "radient";
56089
+ }
56090
+ return getProviderFromId(modelOption.id);
56091
+ },
56083
56092
  renderOption: (props2, option2) => {
56084
56093
  const { key, ...rest } = props2;
56085
56094
  return /* @__PURE__ */ jsxRuntimeExports.jsx("li", { ...rest, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(OptionContainer, { children: [
@@ -56150,19 +56159,19 @@ const ModelSelect = ({
56150
56159
  ] });
56151
56160
  };
56152
56161
  const FieldContainer = styled$1(Box)({
56153
- marginBottom: 24,
56154
56162
  position: "relative"
56155
56163
  });
56156
- const FieldLabel$1 = styled$1(Typography)(({ theme: theme2 }) => ({
56164
+ const FieldLabel$1 = styled$1("div")(({ theme: theme2 }) => ({
56165
+ fontFamily: theme2.typography.fontFamily,
56166
+ fontSize: "0.875rem",
56167
+ // Small text size
56168
+ fontWeight: 500,
56169
+ // Slightly less bold
56170
+ color: theme2.palette.text.secondary,
56157
56171
  marginBottom: 6,
56158
56172
  // Reduced margin
56159
56173
  display: "flex",
56160
- alignItems: "center",
56161
- color: theme2.palette.text.secondary,
56162
- fontWeight: 500,
56163
- // Slightly less bold
56164
- fontSize: "0.875rem"
56165
- // Small text size
56174
+ alignItems: "center"
56166
56175
  }));
56167
56176
  const LabelIcon$1 = styled$1(Box)({
56168
56177
  marginRight: 8,
@@ -56194,42 +56203,57 @@ const TitleIcon$2 = styled$1(FontAwesomeIcon)(({ theme: theme2 }) => ({
56194
56203
  }));
56195
56204
  const InfoCard = styled$1(Box)(({ theme: theme2 }) => ({
56196
56205
  display: "flex",
56197
- // Keep flex for vertical alignment if needed
56198
56206
  alignItems: "center",
56199
- // Align text vertically
56200
56207
  height: "36px",
56201
- // Match input height
56202
56208
  padding: theme2.spacing(0.5, 1.5),
56203
- // Match input padding (4px 12px)
56204
56209
  borderRadius: 4,
56205
- // Less rounded corners
56206
56210
  backgroundColor: theme2.palette.background.paper,
56207
- // Use paper background
56208
56211
  border: `1px solid ${theme2.palette.divider}`,
56209
- // Use divider color for border
56210
56212
  boxSizing: "border-box",
56211
56213
  width: "100%",
56212
- // Take full width of the grid item
56213
56214
  overflow: "hidden"
56214
- // Prevent text overflow
56215
56215
  }));
56216
56216
  const ValueText = styled$1(Typography)(({ theme: theme2 }) => ({
56217
- // Keep as Typography for consistency
56218
56217
  fontWeight: 400,
56219
- // Normal weight for value text inside the box
56220
56218
  fontSize: "0.875rem",
56221
56219
  color: theme2.palette.text.primary,
56222
56220
  whiteSpace: "nowrap",
56223
- // Prevent wrapping
56224
56221
  overflow: "hidden",
56225
- // Hide overflow
56226
56222
  textOverflow: "ellipsis"
56227
- // Add ellipsis
56228
56223
  }));
56229
56224
  const MonospaceValueText = styled$1(ValueText)(({ theme: theme2 }) => ({
56230
56225
  fontFamily: "monospace",
56231
56226
  color: theme2.palette.mode === "light" ? theme2.palette.grey[900] : theme2.palette.text.primary
56232
56227
  }));
56228
+ const ModelPlaceholderContainer = styled$1("div")(({ theme: theme2 }) => ({
56229
+ padding: "4px 12px",
56230
+ borderRadius: 6,
56231
+ backgroundColor: theme2.palette.background.paper,
56232
+ border: `1px solid ${theme2.palette.divider}`,
56233
+ position: "relative",
56234
+ minHeight: "36px",
56235
+ height: "36px",
56236
+ display: "flex",
56237
+ alignItems: "center",
56238
+ boxSizing: "border-box",
56239
+ width: "100%",
56240
+ textAlign: "left",
56241
+ justifyContent: "flex-start",
56242
+ color: theme2.palette.text.primary,
56243
+ fontWeight: "normal",
56244
+ fontFamily: "inherit"
56245
+ }));
56246
+ const ModelPlaceholderText = styled$1("div")(({ theme: theme2 }) => ({
56247
+ color: theme2.palette.text.disabled,
56248
+ fontStyle: "normal",
56249
+ fontSize: "0.875rem",
56250
+ lineHeight: 1.5,
56251
+ paddingRight: 30,
56252
+ overflow: "hidden",
56253
+ textOverflow: "ellipsis",
56254
+ whiteSpace: "nowrap",
56255
+ flexGrow: 1
56256
+ }));
56233
56257
  const GeneralSettings = ({
56234
56258
  selectedAgent,
56235
56259
  savingField,
@@ -56273,7 +56297,8 @@ const GeneralSettings = ({
56273
56297
  }
56274
56298
  }
56275
56299
  ) }),
56276
- /* @__PURE__ */ jsxRuntimeExports.jsxs(Grid, { container: true, spacing: 2, children: [
56300
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Grid, { container: true, spacing: 2, alignItems: "center", children: [
56301
+ " ",
56277
56302
  /* @__PURE__ */ jsxRuntimeExports.jsx(Grid, { item: true, xs: 12, md: 6, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
56278
56303
  HostingSelect,
56279
56304
  {
@@ -56330,29 +56355,11 @@ const GeneralSettings = ({
56330
56355
  },
56331
56356
  `model-select-${currentHosting}`
56332
56357
  ) : /* @__PURE__ */ jsxRuntimeExports.jsxs(FieldContainer, { children: [
56333
- /* @__PURE__ */ jsxRuntimeExports.jsxs(FieldLabel$1, { variant: "subtitle2", children: [
56358
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(FieldLabel$1, { children: [
56334
56359
  /* @__PURE__ */ jsxRuntimeExports.jsx(LabelIcon$1, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(FontAwesomeIcon, { icon: faRobot }) }),
56335
56360
  "Model"
56336
56361
  ] }),
56337
- /* @__PURE__ */ jsxRuntimeExports.jsx(
56338
- TextField,
56339
- {
56340
- placeholder: "Select a hosting provider first...",
56341
- variant: "outlined",
56342
- size: "small",
56343
- disabled: true,
56344
- fullWidth: true,
56345
- InputProps: {
56346
- sx: {
56347
- fontSize: "0.875rem",
56348
- lineHeight: 1.6,
56349
- backgroundColor: (theme2) => theme2.palette.inputField.background,
56350
- borderRadius: 2,
56351
- padding: "16px"
56352
- }
56353
- }
56354
- }
56355
- )
56362
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ModelPlaceholderContainer, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(ModelPlaceholderText, { children: "Select a hosting provider first..." }) })
56356
56363
  ] }) })
56357
56364
  ] })
56358
56365
  ] }),
@@ -56747,32 +56754,21 @@ const AgentsList$1 = styled$1(List$1)(({ theme: theme2 }) => ({
56747
56754
  }));
56748
56755
  const AgentListItemButton$1 = styled$1(ListItemButton)(({ theme: theme2 }) => ({
56749
56756
  margin: "0 8px 8px",
56750
- // Match chat sidebar margin
56751
56757
  borderRadius: 8,
56752
- // marginBottom: 4, // Removed, handled by margin bottom
56753
- // marginBottom: 4, // Removed, handled by margin bottom
56754
56758
  paddingRight: 12,
56755
- // Match chat sidebar padding (now that secondaryAction is removed)
56756
56759
  paddingTop: 6,
56757
- // Match chat sidebar padding
56758
56760
  paddingBottom: 6,
56759
- // Match chat sidebar padding
56760
56761
  paddingLeft: 12,
56761
- // Match chat sidebar padding
56762
56762
  position: "relative",
56763
- // Add relative positioning like chat sidebar
56764
56763
  "&.Mui-selected": {
56765
56764
  backgroundColor: alpha$1(theme2.palette.sidebar.itemActive, 0.1),
56766
- // Match chat sidebar alpha
56767
56765
  color: theme2.palette.sidebar.itemActiveText,
56768
56766
  "&:hover": {
56769
56767
  backgroundColor: alpha$1(theme2.palette.sidebar.itemActiveHover, 0.15)
56770
- // Match chat sidebar alpha
56771
56768
  }
56772
56769
  },
56773
56770
  "&:hover": {
56774
56771
  backgroundColor: alpha$1(theme2.palette.sidebar.itemHover, 0.1)
56775
- // Match chat sidebar alpha
56776
56772
  }
56777
56773
  }));
56778
56774
  const AgentAvatar$2 = styled$1(Avatar, {
@@ -56782,15 +56778,11 @@ const AgentAvatar$2 = styled$1(Avatar, {
56782
56778
  color: selected ? theme2.palette.sidebar.itemActiveText : theme2.palette.icon.text,
56783
56779
  boxShadow: `0 2px 4px ${alpha$1(theme2.palette.common.black, 0.15)}`,
56784
56780
  width: 42,
56785
- // Match chat sidebar avatar size
56786
56781
  height: 42
56787
- // Match chat sidebar avatar size
56788
56782
  }));
56789
56783
  const AgentName$1 = styled$1(Typography)(() => ({
56790
56784
  fontWeight: 600,
56791
- // Match chat sidebar
56792
56785
  fontSize: "0.9rem",
56793
- // Match chat sidebar
56794
56786
  whiteSpace: "nowrap",
56795
56787
  overflow: "hidden",
56796
56788
  textOverflow: "ellipsis",
@@ -56798,50 +56790,37 @@ const AgentName$1 = styled$1(Typography)(() => ({
56798
56790
  }));
56799
56791
  const DescriptionText = styled$1("div")(({ theme: theme2 }) => ({
56800
56792
  fontSize: "0.8rem",
56801
- // Match chat sidebar message preview
56802
56793
  color: theme2.palette.mode === "dark" ? "rgba(255, 255, 255, 0.7)" : "rgba(0, 0, 0, 0.6)",
56803
- // Match chat sidebar message preview
56804
56794
  whiteSpace: "nowrap",
56805
56795
  overflow: "hidden",
56806
56796
  textOverflow: "ellipsis",
56807
56797
  width: "100%",
56808
56798
  minHeight: "18px"
56809
- // Match chat sidebar message preview
56810
56799
  }));
56811
56800
  const CreationDateText = styled$1("div")(({ theme: theme2 }) => ({
56812
56801
  display: "flex",
56813
56802
  alignItems: "center",
56814
56803
  fontSize: "0.7rem",
56815
- // Match chat sidebar timestamp
56816
56804
  color: theme2.palette.mode === "dark" ? "rgba(255, 255, 255, 0.5)" : "rgba(0, 0, 0, 0.5)",
56817
- // Match chat sidebar timestamp
56818
56805
  marginTop: 2,
56819
- // Add small margin like chat sidebar name/preview spacing
56820
56806
  gap: 4
56821
56807
  }));
56822
56808
  const OptionsButtonContainer$1 = styled$1(Box)({
56823
56809
  position: "absolute",
56824
56810
  right: -8,
56825
- // Position relative to the container it will be placed in
56826
56811
  top: "50%",
56827
- // Center vertically
56828
56812
  transform: "translateY(-50%) translateX(100%)",
56829
- // Center vertically and position off-screen horizontally
56830
56813
  opacity: 0,
56831
56814
  transition: "opacity 0.2s ease, transform 0.2s ease",
56832
- // Target hover on the parent ListItemButton to trigger the effect
56833
56815
  ".MuiListItemButton-root:hover &": {
56834
56816
  opacity: 1,
56835
56817
  transform: "translateY(-50%) translateX(0)",
56836
- // Center vertically and slide in horizontally on hover
56837
56818
  visibility: "visible"
56838
56819
  },
56839
56820
  zIndex: 2,
56840
56821
  pointerEvents: "none",
56841
- // Container doesn't block clicks
56842
56822
  "& > *": {
56843
56823
  pointerEvents: "auto"
56844
- // Button inside is clickable
56845
56824
  }
56846
56825
  });
56847
56826
  const formatDate = (dateString) => {
@@ -56864,22 +56843,28 @@ const AgentsSidebar = ({
56864
56843
  const perPage = 50;
56865
56844
  const exportAgentMutation = useExportAgent();
56866
56845
  const { page, setPage } = usePaginationParams();
56867
- const [stableAgents, setStableAgents] = reactExports.useState([]);
56868
- const prevFetchingRef = reactExports.useRef(false);
56869
56846
  const {
56870
- data: agents = [],
56847
+ data: agentListResult,
56871
56848
  isLoading,
56872
56849
  isError,
56873
- refetch,
56874
- isFetching
56875
- } = useAgents(page, perPage, 0, searchQuery);
56876
- reactExports.useEffect(() => {
56877
- if (agents.length > 0 && (!isFetching || prevFetchingRef.current && !isFetching)) {
56878
- setStableAgents(agents);
56850
+ refetch
56851
+ } = useAgents(page, perPage, 0, searchQuery, "created_date", "desc");
56852
+ const agents = agentListResult?.agents || [];
56853
+ const totalAgents = agentListResult?.total || 0;
56854
+ const { data: selectedAgentDetails } = useAgent(
56855
+ // Only fetch if selectedAgentId exists and is not found in the current agents list
56856
+ selectedAgentId && !agents.find((a2) => a2.id === selectedAgentId) ? selectedAgentId : void 0
56857
+ );
56858
+ const combinedAgents = reactExports.useMemo(() => {
56859
+ const combined = [...agents];
56860
+ if (selectedAgentDetails && !combined.find((a2) => a2.id === selectedAgentDetails.id)) {
56861
+ combined.push(selectedAgentDetails);
56879
56862
  }
56880
- prevFetchingRef.current = isFetching;
56881
- }, [agents, isFetching]);
56882
- const displayAgents = isFetching && stableAgents.length > 0 ? stableAgents : agents;
56863
+ combined.sort((a2, b2) => {
56864
+ return new Date(b2.created_date).getTime() - new Date(a2.created_date).getTime();
56865
+ });
56866
+ return combined;
56867
+ }, [agents, selectedAgentDetails]);
56883
56868
  const handlePageChange = reactExports.useCallback(
56884
56869
  (_event, value) => {
56885
56870
  setPage(value);
@@ -56908,7 +56893,7 @@ const AgentsSidebar = ({
56908
56893
  async (agentId) => {
56909
56894
  try {
56910
56895
  const blob = await exportAgentMutation.mutateAsync(agentId);
56911
- const agent = agents.find((a22) => a22.id === agentId);
56896
+ const agent = combinedAgents.find((a22) => a22.id === agentId);
56912
56897
  const agentName = agent ? agent.name.replace(/\s+/g, "-").toLowerCase() : agentId;
56913
56898
  const url = URL.createObjectURL(blob);
56914
56899
  const a2 = document.createElement("a");
@@ -56922,41 +56907,48 @@ const AgentsSidebar = ({
56922
56907
  console.error("Failed to export agent:", error);
56923
56908
  }
56924
56909
  },
56925
- [agents, exportAgentMutation]
56910
+ [combinedAgents, exportAgentMutation]
56911
+ // Use combinedAgents
56926
56912
  );
56927
56913
  const handleAgentCreated = reactExports.useCallback(
56928
56914
  (agentId) => {
56929
56915
  const fetchAndSelectAgent = async () => {
56930
56916
  try {
56931
56917
  const result = await refetch();
56932
- const updatedAgents = result.data || [];
56933
- const createdAgent = updatedAgents.find(
56918
+ const updatedAgentList = result.data?.agents || [];
56919
+ const createdAgent = updatedAgentList.find(
56934
56920
  (agent) => agent.id === agentId
56935
56921
  );
56936
- if (createdAgent && onSelectAgent) {
56922
+ if (createdAgent) {
56937
56923
  onSelectAgent(createdAgent);
56938
56924
  } else {
56939
- await queryClient.prefetchQuery({
56940
- queryKey: ["agents", agentId],
56941
- queryFn: async () => {
56942
- const client = createLocalOperatorClient(apiConfig.baseUrl);
56943
- const response = await client.agents.getAgent(agentId);
56944
- return response.result;
56925
+ try {
56926
+ const { data: newAgentDetails } = await refetch();
56927
+ const foundAgent = (newAgentDetails?.agents || []).find(
56928
+ (a2) => a2.id === agentId
56929
+ );
56930
+ if (foundAgent) {
56931
+ onSelectAgent(foundAgent);
56932
+ } else {
56933
+ console.warn(
56934
+ "Newly created agent not found immediately after refetch."
56935
+ );
56945
56936
  }
56946
- });
56947
- const agentDetails = queryClient.getQueryData(["agents", agentId]);
56948
- if (agentDetails && onSelectAgent) {
56949
- onSelectAgent(agentDetails);
56937
+ } catch (fetchError) {
56938
+ console.error(
56939
+ "Error fetching newly created agent details:",
56940
+ fetchError
56941
+ );
56950
56942
  }
56951
56943
  }
56952
56944
  } catch (error) {
56953
- console.error("Error fetching agent details:", error);
56954
- refetch();
56945
+ console.error("Error refetching agents list:", error);
56955
56946
  }
56956
56947
  };
56957
56948
  fetchAndSelectAgent();
56958
56949
  },
56959
56950
  [onSelectAgent, refetch]
56951
+ // Keep dependencies
56960
56952
  );
56961
56953
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(SidebarContainer$4, { elevation: 0, children: [
56962
56954
  /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -56986,101 +56978,96 @@ const AgentsSidebar = ({
56986
56978
  ),
56987
56979
  children: "Failed to load agents. Please try again."
56988
56980
  }
56989
- ) : displayAgents.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx(EmptyStateContainer$3, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(Typography, { variant: "body2", color: "text.secondary", children: "No agents found" }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx(AgentsList$1, { children: displayAgents.map((agent) => /* @__PURE__ */ jsxRuntimeExports.jsx(ListItem, { disablePadding: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
56981
+ ) : combinedAgents.length === 0 && !isLoading ? (
56982
+ // Check combinedAgents and isLoading
56983
+ /* @__PURE__ */ jsxRuntimeExports.jsx(EmptyStateContainer$3, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(Typography, { variant: "body2", color: "text.secondary", children: searchQuery ? "No agents match your search" : "No agents found" }) })
56984
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsx(AgentsList$1, { children: combinedAgents.map((agent) => /* @__PURE__ */ jsxRuntimeExports.jsx(ListItem, { disablePadding: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
56990
56985
  AgentListItemButton$1,
56991
56986
  {
56992
- selected: selectedAgentId === agent.id,
56987
+ selected: selectedAgentId === agent.id || selectedAgentDetails?.id === agent.id,
56993
56988
  onClick: () => handleSelectAgent(agent),
56994
56989
  children: [
56995
56990
  /* @__PURE__ */ jsxRuntimeExports.jsx(ListItemAvatar, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(AgentAvatar$2, { selected: selectedAgentId === agent.id, children: /* @__PURE__ */ jsxRuntimeExports.jsx(FontAwesomeIcon, { icon: faRobot }) }) }),
56996
- /* @__PURE__ */ jsxRuntimeExports.jsx(
56997
- ListItemText,
56991
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ListItemText, { disableTypography: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
56992
+ Box,
56998
56993
  {
56999
- disableTypography: true,
57000
- children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
57001
- Box,
57002
- {
57003
- sx: {
57004
- position: "relative",
57005
- width: "100%",
57006
- overflow: "hidden"
57007
- },
57008
- children: [
57009
- /* @__PURE__ */ jsxRuntimeExports.jsx(
57010
- Tooltip$1,
57011
- {
57012
- enterDelay: 1200,
57013
- enterNextDelay: 1200,
57014
- title: agent.name,
57015
- arrow: true,
57016
- placement: "top-start",
57017
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(AgentName$1, { children: agent.name })
57018
- }
57019
- ),
57020
- /* @__PURE__ */ jsxRuntimeExports.jsx(
57021
- Tooltip$1,
57022
- {
57023
- title: agent.description || "No description",
57024
- arrow: true,
57025
- placement: "bottom-start",
57026
- enterDelay: 1200,
57027
- enterNextDelay: 1200,
57028
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(DescriptionText, { children: agent.description || "No description" })
57029
- }
57030
- ),
57031
- /* @__PURE__ */ jsxRuntimeExports.jsx(
57032
- Tooltip$1,
57033
- {
57034
- title: `Created: ${formatDate(agent.created_date)}`,
57035
- arrow: true,
57036
- placement: "bottom-start",
57037
- enterDelay: 1200,
57038
- enterNextDelay: 1200,
57039
- children: /* @__PURE__ */ jsxRuntimeExports.jsxs(CreationDateText, { children: [
57040
- /* @__PURE__ */ jsxRuntimeExports.jsx(FontAwesomeIcon, { icon: faClock, size: "xs" }),
57041
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: formatDate(agent.created_date) })
57042
- ] })
57043
- }
57044
- ),
57045
- /* @__PURE__ */ jsxRuntimeExports.jsx(OptionsButtonContainer$1, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
57046
- Tooltip$1,
56994
+ sx: {
56995
+ position: "relative",
56996
+ width: "100%",
56997
+ overflow: "hidden"
56998
+ },
56999
+ children: [
57000
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
57001
+ Tooltip$1,
57002
+ {
57003
+ enterDelay: 1200,
57004
+ enterNextDelay: 1200,
57005
+ title: agent.name,
57006
+ arrow: true,
57007
+ placement: "top-start",
57008
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(AgentName$1, { children: agent.name })
57009
+ }
57010
+ ),
57011
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
57012
+ Tooltip$1,
57013
+ {
57014
+ title: agent.description || "No description",
57015
+ arrow: true,
57016
+ placement: "bottom-start",
57017
+ enterDelay: 1200,
57018
+ enterNextDelay: 1200,
57019
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(DescriptionText, { children: agent.description || "No description" })
57020
+ }
57021
+ ),
57022
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
57023
+ Tooltip$1,
57024
+ {
57025
+ title: `Created: ${formatDate(agent.created_date)}`,
57026
+ arrow: true,
57027
+ placement: "bottom-start",
57028
+ enterDelay: 1200,
57029
+ enterNextDelay: 1200,
57030
+ children: /* @__PURE__ */ jsxRuntimeExports.jsxs(CreationDateText, { children: [
57031
+ /* @__PURE__ */ jsxRuntimeExports.jsx(FontAwesomeIcon, { icon: faClock, size: "xs" }),
57032
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: formatDate(agent.created_date) })
57033
+ ] })
57034
+ }
57035
+ ),
57036
+ /* @__PURE__ */ jsxRuntimeExports.jsx(OptionsButtonContainer$1, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
57037
+ Tooltip$1,
57038
+ {
57039
+ enterDelay: 1200,
57040
+ enterNextDelay: 1200,
57041
+ title: "Agent Options",
57042
+ arrow: true,
57043
+ placement: "top",
57044
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
57045
+ AgentOptionsMenu,
57047
57046
  {
57048
- enterDelay: 1200,
57049
- enterNextDelay: 1200,
57050
- title: "Agent Options",
57051
- arrow: true,
57052
- placement: "top",
57053
- children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
57054
- AgentOptionsMenu,
57055
- {
57056
- agentId: agent.id,
57057
- agentName: agent.name,
57058
- isAgentsPage: true,
57059
- onAgentDeleted: (deletedAgentId) => {
57060
- refetch();
57061
- },
57062
- onChatWithAgent: () => navigate(`/chat/${agent.id}`),
57063
- onExportAgent: () => handleExportAgent(agent.id),
57064
- buttonSx: {
57065
- // Match chat sidebar options button style
57066
- width: 24,
57067
- height: 24,
57068
- borderRadius: "4px",
57069
- display: "flex",
57070
- justifyContent: "center",
57071
- alignItems: "center",
57072
- opacity: 1
57073
- // Opacity controlled by container
57074
- }
57075
- }
57076
- ) })
57047
+ agentId: agent.id,
57048
+ agentName: agent.name,
57049
+ isAgentsPage: true,
57050
+ onAgentDeleted: (deletedAgentId) => {
57051
+ refetch();
57052
+ },
57053
+ onChatWithAgent: () => navigate(`/chat/${agent.id}`),
57054
+ onExportAgent: () => handleExportAgent(agent.id),
57055
+ buttonSx: {
57056
+ width: 24,
57057
+ height: 24,
57058
+ borderRadius: "4px",
57059
+ display: "flex",
57060
+ justifyContent: "center",
57061
+ alignItems: "center",
57062
+ opacity: 1
57063
+ }
57077
57064
  }
57078
57065
  ) })
57079
- ]
57080
- }
57081
- )
57066
+ }
57067
+ ) })
57068
+ ]
57082
57069
  }
57083
- )
57070
+ ) })
57084
57071
  ]
57085
57072
  }
57086
57073
  ) }, agent.id)) }),
@@ -57100,11 +57087,11 @@ const AgentsSidebar = ({
57100
57087
  onAgentImported: handleAgentCreated
57101
57088
  }
57102
57089
  ),
57103
- /* @__PURE__ */ jsxRuntimeExports.jsx(
57090
+ totalAgents > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
57104
57091
  CompactPagination,
57105
57092
  {
57106
57093
  page,
57107
- count: Math.max(1, Math.ceil(displayAgents.length / perPage)),
57094
+ count: Math.max(1, Math.ceil(totalAgents / perPage)),
57108
57095
  onChange: (newPage) => handlePageChange({}, newPage)
57109
57096
  }
57110
57097
  )
@@ -57151,7 +57138,8 @@ const AgentsPage = () => {
57151
57138
  const prevAgentIdRef = reactExports.useRef(agentId);
57152
57139
  const exportAgentMutation = useExportAgent();
57153
57140
  const { setLastAgentsPageAgentId, getLastAgentId, clearLastAgentId } = useAgentSelectionStore();
57154
- const { data: agents = [] } = useAgents();
57141
+ const { data: agentListResult } = useAgents();
57142
+ const agents = agentListResult?.agents || [];
57155
57143
  const effectiveAgentId = agentId || getLastAgentId("agents");
57156
57144
  const [selectedAgent, setSelectedAgent] = reactExports.useState(null);
57157
57145
  const { data: initialAgent, refetch: refetchAgent } = useAgent(
@@ -57168,7 +57156,7 @@ const AgentsPage = () => {
57168
57156
  }, 0);
57169
57157
  }
57170
57158
  }
57171
- }, [effectiveAgentId, agents]);
57159
+ }, [effectiveAgentId, agents, clearLastAgentId, clearAgentId]);
57172
57160
  reactExports.useEffect(() => {
57173
57161
  if (agentId) {
57174
57162
  setLastAgentsPageAgentId(agentId);
@@ -57855,11 +57843,14 @@ const DirectoryIndicator = ({
57855
57843
  )
57856
57844
  ] }) });
57857
57845
  };
57858
- const UtilitiesContainer = styled$1(Box)(({ theme: theme2 }) => ({
57846
+ const UtilitiesContainer = styled$1(Box, {
57847
+ shouldForwardProp: (prop) => prop !== "$expanded"
57848
+ })(({ theme: theme2, $expanded }) => ({
57859
57849
  padding: theme2.spacing(1, 3),
57860
57850
  backgroundColor: alpha$1(theme2.palette.background.paper, 0.4),
57861
57851
  borderTop: `1px solid ${alpha$1(theme2.palette.divider, 0.1)}`,
57862
- minHeight: 52
57852
+ // Apply minHeight only when collapsed to allow expansion
57853
+ minHeight: $expanded ? "auto" : 52
57863
57854
  }));
57864
57855
  const UtilitiesHeader = styled$1(Box)(({ theme: theme2 }) => ({
57865
57856
  display: "flex",
@@ -57888,7 +57879,7 @@ const ChatUtilities = ({
57888
57879
  setExpanded(!expanded);
57889
57880
  };
57890
57881
  if (!agentId) return null;
57891
- return /* @__PURE__ */ jsxRuntimeExports.jsxs(UtilitiesContainer, { children: [
57882
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(UtilitiesContainer, { $expanded: expanded, children: [
57892
57883
  /* @__PURE__ */ jsxRuntimeExports.jsxs(UtilitiesHeader, { onClick: toggleExpanded, children: [
57893
57884
  /* @__PURE__ */ jsxRuntimeExports.jsx(
57894
57885
  IconButton,
@@ -76428,7 +76419,7 @@ const languages = [
76428
76419
  name: "Go",
76429
76420
  extensions: ["go"],
76430
76421
  load() {
76431
- return __vitePreload(() => import("./index-B87fKloA.js"), true ? __vite__mapDeps([0,1,2]) : void 0, import.meta.url).then((m2) => m2.go());
76422
+ return __vitePreload(() => import("./index-PjN-o7b5.js"), true ? __vite__mapDeps([0,1,2]) : void 0, import.meta.url).then((m2) => m2.go());
76432
76423
  }
76433
76424
  }),
76434
76425
  /* @__PURE__ */ LanguageDescription.of({
@@ -76605,7 +76596,7 @@ const languages = [
76605
76596
  alias: ["yml"],
76606
76597
  extensions: ["yaml", "yml"],
76607
76598
  load() {
76608
- return __vitePreload(() => import("./index-CfuGYyUa.js"), true ? __vite__mapDeps([3,1,2]) : void 0, import.meta.url).then((m2) => m2.yaml());
76599
+ return __vitePreload(() => import("./index-Bi6Xp3wq.js"), true ? __vite__mapDeps([3,1,2]) : void 0, import.meta.url).then((m2) => m2.yaml());
76609
76600
  }
76610
76601
  }),
76611
76602
  // Legacy modes ported from CodeMirror 5
@@ -136137,10 +136128,10 @@ const AttachmentsPreview = ({
136137
136128
  ) })
136138
136129
  ] }, `${index2}-${attachment}`)) });
136139
136130
  };
136140
- const ButtonContainer$1 = styled$1(Box)(
136141
- ({
136142
- isChatUtilitiesExpanded
136143
- }) => ({
136131
+ const ButtonContainer$1 = styled$1(Box, {
136132
+ shouldForwardProp: (prop) => prop !== "isChatUtilitiesExpanded"
136133
+ })(
136134
+ ({ isChatUtilitiesExpanded }) => ({
136144
136135
  position: "absolute",
136145
136136
  bottom: isChatUtilitiesExpanded ? 260 : 200,
136146
136137
  zIndex: 1e3,
@@ -136462,7 +136453,7 @@ const MessageInput = ({
136462
136453
  const newAttachments = Array.from(e3.target.files).map((file) => {
136463
136454
  const filePath = file.path;
136464
136455
  if (filePath) {
136465
- return filePath;
136456
+ return normalizePath(filePath);
136466
136457
  }
136467
136458
  return URL.createObjectURL(file);
136468
136459
  });
@@ -178232,7 +178223,6 @@ const AgentListItemButton = styled$1(ListItemButton)(({ theme: theme2 }) => ({
178232
178223
  paddingBottom: 6,
178233
178224
  paddingLeft: 12,
178234
178225
  position: "relative",
178235
- // Ensure proper positioning context
178236
178226
  "&.Mui-selected": {
178237
178227
  backgroundColor: alpha$1(theme2.palette.sidebar.itemActive, 0.1),
178238
178228
  color: theme2.palette.sidebar.itemActiveText,
@@ -178259,9 +178249,7 @@ const MessageBubble = styled$1("div")({
178259
178249
  width: "100%",
178260
178250
  overflow: "hidden",
178261
178251
  position: "relative",
178262
- // Ensure the message bubble maintains its layout
178263
178252
  isolation: "isolate"
178264
- // Create a new stacking context
178265
178253
  });
178266
178254
  const AgentNameContainer = styled$1(Box)({
178267
178255
  display: "flex",
@@ -178269,7 +178257,6 @@ const AgentNameContainer = styled$1(Box)({
178269
178257
  alignItems: "center",
178270
178258
  width: "100%",
178271
178259
  position: "relative",
178272
- // Ensure the container maintains its position
178273
178260
  overflow: "hidden"
178274
178261
  });
178275
178262
  const AgentName = styled$1(Typography)(() => ({
@@ -178320,11 +178307,9 @@ const OptionsButtonContainer = styled$1(Box)({
178320
178307
  visibility: "visible"
178321
178308
  },
178322
178309
  zIndex: 2,
178323
- // Ensure the container doesn't affect layout when clicked
178324
178310
  pointerEvents: "none",
178325
178311
  "& > *": {
178326
178312
  pointerEvents: "auto"
178327
- // Allow clicks on children (the button itself)
178328
178313
  }
178329
178314
  });
178330
178315
  const NoMessagesContainer = styled$1("div")(({ theme: theme2 }) => ({
@@ -178350,11 +178335,32 @@ const ChatSidebar = ({
178350
178335
  const clearConversationMutation = useClearAgentConversation();
178351
178336
  const { page, setPage } = usePaginationParams();
178352
178337
  const {
178353
- data: agents = [],
178338
+ data: agentListResult,
178339
+ // Rename data to agentListResult
178354
178340
  isLoading,
178355
178341
  isError,
178356
178342
  refetch
178357
- } = useAgents(page, perPage, 5e3, searchQuery);
178343
+ } = useAgents(
178344
+ page,
178345
+ perPage,
178346
+ 5e3,
178347
+ searchQuery,
178348
+ "last_message_datetime",
178349
+ "desc"
178350
+ );
178351
+ const agents = agentListResult?.agents || [];
178352
+ const totalAgents = agentListResult?.total || 0;
178353
+ const { data: selectedAgentDetails } = useAgent(
178354
+ // Only fetch if selectedConversation exists and is not found in the current agents list
178355
+ selectedConversation && !agents.find((a2) => a2.id === selectedConversation) ? selectedConversation : void 0
178356
+ );
178357
+ const combinedAgents = reactExports.useMemo(() => {
178358
+ const combined = [...agents];
178359
+ if (selectedAgentDetails && !combined.find((a2) => a2.id === selectedAgentDetails.id)) {
178360
+ combined.push(selectedAgentDetails);
178361
+ }
178362
+ return combined;
178363
+ }, [agents, selectedAgentDetails]);
178358
178364
  const handlePageChange = reactExports.useCallback(
178359
178365
  (_event, value) => {
178360
178366
  setPage(value);
@@ -178383,7 +178389,7 @@ const ChatSidebar = ({
178383
178389
  async (agentId) => {
178384
178390
  try {
178385
178391
  const blob = await exportAgentMutation.mutateAsync(agentId);
178386
- const agent = agents.find((a22) => a22.id === agentId);
178392
+ const agent = combinedAgents.find((a22) => a22.id === agentId);
178387
178393
  const agentName = agent ? agent.name.replace(/\s+/g, "-").toLowerCase() : agentId;
178388
178394
  const url = URL.createObjectURL(blob);
178389
178395
  const a2 = document.createElement("a");
@@ -178397,15 +178403,16 @@ const ChatSidebar = ({
178397
178403
  console.error("Failed to export agent:", error);
178398
178404
  }
178399
178405
  },
178400
- [agents, exportAgentMutation]
178406
+ [combinedAgents, exportAgentMutation]
178407
+ // Use combinedAgents
178401
178408
  );
178402
178409
  const handleAgentCreated = reactExports.useCallback(
178403
178410
  (agentId) => {
178404
178411
  const fetchAndSelectAgent = async () => {
178405
178412
  try {
178406
178413
  const result = await refetch();
178407
- const updatedAgents = result.data || [];
178408
- const createdAgent = updatedAgents.find(
178414
+ const updatedAgentList = result.data?.agents || [];
178415
+ const createdAgent = updatedAgentList.find(
178409
178416
  (agent) => agent.id === agentId
178410
178417
  );
178411
178418
  if (createdAgent) {
@@ -178426,14 +178433,6 @@ const ChatSidebar = ({
178426
178433
  if (!message2) return "";
178427
178434
  return message2.length > maxLength ? `${message2.substring(0, maxLength)}...` : message2;
178428
178435
  };
178429
- const sortedAgents = [...agents].sort((a2, b2) => {
178430
- if (a2.last_message_datetime && b2.last_message_datetime) {
178431
- return new Date(b2.last_message_datetime).getTime() - new Date(a2.last_message_datetime).getTime();
178432
- }
178433
- if (a2.last_message_datetime) return -1;
178434
- if (b2.last_message_datetime) return 1;
178435
- return 0;
178436
- });
178437
178436
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(SidebarContainer$2, { elevation: 0, children: [
178438
178437
  /* @__PURE__ */ jsxRuntimeExports.jsx(
178439
178438
  SidebarHeader$2,
@@ -178462,10 +178461,13 @@ const ChatSidebar = ({
178462
178461
  ),
178463
178462
  children: "Failed to load agents. Please try again."
178464
178463
  }
178465
- ) : sortedAgents.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx(EmptyStateContainer$1, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(Typography, { variant: "body2", color: "text.secondary", children: "No agents found" }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx(AgentsList, { children: sortedAgents.map((agent) => /* @__PURE__ */ jsxRuntimeExports.jsx(ListItem, { disablePadding: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
178464
+ ) : combinedAgents.length === 0 && !isLoading ? (
178465
+ // Check combinedAgents and isLoading
178466
+ /* @__PURE__ */ jsxRuntimeExports.jsx(EmptyStateContainer$1, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(Typography, { variant: "body2", color: "text.secondary", children: searchQuery ? "No agents match your search" : "No agents found" }) })
178467
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsx(AgentsList, { children: combinedAgents.map((agent) => /* @__PURE__ */ jsxRuntimeExports.jsx(ListItem, { disablePadding: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
178466
178468
  AgentListItemButton,
178467
178469
  {
178468
- selected: selectedConversation === agent.id,
178470
+ selected: selectedConversation === agent.id || selectedAgentDetails?.id === agent.id,
178469
178471
  onClick: () => handleSelectConversation(agent.id),
178470
178472
  children: [
178471
178473
  /* @__PURE__ */ jsxRuntimeExports.jsx(ListItemAvatar, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(AgentAvatar, { selected: selectedConversation === agent.id, children: /* @__PURE__ */ jsxRuntimeExports.jsx(FontAwesomeIcon, { icon: faRobot }) }) }),
@@ -178571,11 +178573,11 @@ const ChatSidebar = ({
178571
178573
  onAgentImported: handleAgentCreated
178572
178574
  }
178573
178575
  ),
178574
- /* @__PURE__ */ jsxRuntimeExports.jsx(
178576
+ totalAgents > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
178575
178577
  CompactPagination,
178576
178578
  {
178577
178579
  page,
178578
- count: Math.max(1, Math.ceil(sortedAgents.length / perPage)),
178580
+ count: Math.max(1, Math.ceil(totalAgents / perPage)),
178579
178581
  onChange: (newPage) => handlePageChange({}, newPage)
178580
178582
  }
178581
178583
  )
@@ -178700,8 +178702,10 @@ const ChatPage = () => {
178700
178702
  );
178701
178703
  const messagesEndRef = reactExports.useRef(null);
178702
178704
  reactExports.useEffect(() => {
178703
- if (effectiveAgentId && agents.length > 0) {
178704
- const agentExists = agents.some((agent) => agent.id === effectiveAgentId);
178705
+ if (effectiveAgentId && agents && "agents" in agents && agents.agents.length > 0) {
178706
+ const agentExists = agents.agents.some(
178707
+ (agent) => agent.id === effectiveAgentId
178708
+ );
178705
178709
  if (!agentExists) {
178706
178710
  setTimeout(() => {
178707
178711
  clearLastAgentId("chat");
@@ -179513,10 +179517,17 @@ const CreateAgentStep = () => {
179513
179517
  severity: "success",
179514
179518
  icon: /* @__PURE__ */ jsxRuntimeExports.jsx(FontAwesomeIcon, { icon: faCheck }),
179515
179519
  sx: successAlertSx,
179516
- children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
179517
- /* @__PURE__ */ jsxRuntimeExports.jsx(EmojiContainer, { sx: { mb: 0 }, children: "🎉" }),
179518
- " AI assistant created successfully!"
179519
- ] })
179520
+ children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
179521
+ Box,
179522
+ {
179523
+ component: "span",
179524
+ sx: { display: "flex", alignItems: "center", gap: 1 },
179525
+ children: [
179526
+ /* @__PURE__ */ jsxRuntimeExports.jsx(EmojiContainer, { sx: { mb: 0 }, children: "🎉" }),
179527
+ " AI assistant created successfully!"
179528
+ ]
179529
+ }
179530
+ )
179520
179531
  }
179521
179532
  ),
179522
179533
  /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -180421,39 +180432,23 @@ const SignInButton = styled$1(Button)(({ theme: theme2 }) => ({
180421
180432
  display: "flex",
180422
180433
  alignItems: "center",
180423
180434
  justifyContent: "center",
180424
- // Center content
180425
180435
  padding: theme2.spacing(0.75, 2),
180426
- // Consistent padding
180427
180436
  borderRadius: theme2.shape.borderRadius * 0.75,
180428
- // Consistent radius
180429
180437
  fontSize: "0.875rem",
180430
- // Standard font size
180431
180438
  fontWeight: 500,
180432
- // Standard weight
180433
180439
  textTransform: "none",
180434
180440
  marginBottom: theme2.spacing(1.5),
180435
- // Reduced margin between buttons
180436
180441
  width: "100%",
180437
180442
  maxWidth: 320,
180438
- // Keep max width for centering effect
180439
180443
  border: `1px solid ${theme2.palette.divider}`,
180440
- // Standard border
180441
180444
  backgroundColor: theme2.palette.background.paper,
180442
- // Standard background
180443
180445
  color: theme2.palette.text.primary,
180444
- // Standard text color
180445
180446
  boxShadow: "none",
180446
- // Remove shadow
180447
180447
  transition: "background-color 0.2s ease-in-out, border-color 0.2s ease-in-out",
180448
- // Standard transition
180449
180448
  "&:hover": {
180450
180449
  backgroundColor: theme2.palette.action.hover,
180451
- // Standard hover
180452
180450
  borderColor: theme2.palette.divider,
180453
- // Keep border consistent on hover
180454
180451
  boxShadow: "none"
180455
- // Ensure no shadow on hover
180456
- // transform: "none", // Ensure no transform
180457
180452
  },
180458
180453
  "&:disabled": {
180459
180454
  borderColor: theme2.palette.divider,
@@ -180468,11 +180463,8 @@ const IconContainer = styled$1(Box)(({ theme: theme2 }) => ({
180468
180463
  alignItems: "center",
180469
180464
  justifyContent: "center",
180470
180465
  marginRight: theme2.spacing(1),
180471
- // Reduced margin
180472
180466
  fontSize: "1rem",
180473
- // Slightly smaller icon to fit button style
180474
180467
  width: 20,
180475
- // Explicit width/height for alignment
180476
180468
  height: 20
180477
180469
  }));
180478
180470
  const ButtonsContainer = styled$1(Box)(() => ({
@@ -180483,12 +180475,14 @@ const ButtonsContainer = styled$1(Box)(() => ({
180483
180475
  }));
180484
180476
  const RadientAuthButtons = ({
180485
180477
  onSignInSuccess,
180478
+ onAfterCredentialUpdate,
180486
180479
  titleText: titleText2 = "Sign in to Radient",
180487
180480
  descriptionText = "Choose your preferred sign-in method to access Radient services."
180488
180481
  }) => {
180489
180482
  const theme2 = useTheme$1();
180490
180483
  const { signInWithGoogle, signInWithMicrosoft, loading, error } = useOidcAuth(
180491
180484
  {
180485
+ onAfterCredentialUpdate,
180492
180486
  onSuccess: onSignInSuccess
180493
180487
  }
180494
180488
  );
@@ -180505,13 +180499,10 @@ const RadientAuthButtons = ({
180505
180499
  {
180506
180500
  sx: {
180507
180501
  fontSize: "1.125rem",
180508
- // ~18px
180509
180502
  fontWeight: 500,
180510
180503
  marginBottom: theme2.spacing(1),
180511
- // Reduced margin
180512
180504
  color: theme2.palette.text.primary,
180513
180505
  textAlign: "center"
180514
- // Center title
180515
180506
  },
180516
180507
  children: titleText2
180517
180508
  }
@@ -180521,13 +180512,10 @@ const RadientAuthButtons = ({
180521
180512
  {
180522
180513
  sx: {
180523
180514
  fontSize: "0.875rem",
180524
- // ~14px
180525
180515
  color: theme2.palette.text.secondary,
180526
180516
  marginBottom: theme2.spacing(3),
180527
- // Consistent margin
180528
180517
  lineHeight: 1.5,
180529
180518
  textAlign: "center"
180530
- // Center description
180531
180519
  },
180532
180520
  children: descriptionText
180533
180521
  }
@@ -180558,13 +180546,61 @@ const RadientAuthButtons = ({
180558
180546
  ] })
180559
180547
  ] });
180560
180548
  };
180549
+ const radientPricesKeys = {
180550
+ all: ["radient-prices"],
180551
+ prices: () => [...radientPricesKeys.all, "prices"]
180552
+ };
180553
+ const useRadientPricesQuery = () => {
180554
+ const radientClient2 = createRadientClient(
180555
+ apiConfig.radientBaseUrl,
180556
+ apiConfig.radientClientId
180557
+ // Not used by fetchPrices, but required by constructor
180558
+ );
180559
+ const pricesQuery = useQuery({
180560
+ // Use the defined query key
180561
+ queryKey: radientPricesKeys.prices(),
180562
+ // The query function calls the fetchPrices method from the client
180563
+ queryFn: async () => {
180564
+ try {
180565
+ const prices = await radientClient2.prices.fetchPrices();
180566
+ return prices;
180567
+ } catch (error) {
180568
+ console.error("Failed to fetch Radient prices:", error);
180569
+ throw error;
180570
+ }
180571
+ },
180572
+ // This data is fairly static, so we can set a longer stale time
180573
+ staleTime: 1e3 * 60 * 60,
180574
+ // 1 hour
180575
+ // Refetch only on mount or if stale, not on window focus or interval
180576
+ refetchOnWindowFocus: false,
180577
+ refetchOnMount: true,
180578
+ refetchInterval: false,
180579
+ // Retry on failure a few times
180580
+ retry: 3
180581
+ });
180582
+ return {
180583
+ // Prices data (default_new_credits, default_registration_credits)
180584
+ prices: pricesQuery.data,
180585
+ // Loading and error states from react-query
180586
+ isLoading: pricesQuery.isLoading,
180587
+ isFetching: pricesQuery.isFetching,
180588
+ error: pricesQuery.error,
180589
+ // Raw query object for advanced usage if needed
180590
+ pricesQuery
180591
+ };
180592
+ };
180561
180593
  const RadientSignInStep = ({
180562
180594
  onSignInSuccess
180563
- // This prop comes from OnboardingModal
180564
180595
  }) => {
180565
180596
  const theme2 = useTheme$1();
180597
+ const { prices, isLoading, error } = useRadientPricesQuery();
180598
+ const formatCurrency = (amount) => {
180599
+ if (typeof amount !== "number") return "$...";
180600
+ return `$${amount.toFixed(2)} USD`;
180601
+ };
180566
180602
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(SectionContainer, { children: [
180567
- /* @__PURE__ */ jsxRuntimeExports.jsx(SectionDescription$1, { sx: { mb: 3 }, children: "Sign in with your preferred method to get started with Radient Pass. This gives you access to web search, image generation, site crawling, and more." }),
180603
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SectionDescription$1, { sx: { mb: 3 }, children: "Sign in with your preferred method to get started with Radient Pass in a couple clicks. This gives you access to hundreds of models updated in real time, cost-saving with Radient Auto, web search, image generation, site crawling, and more all in Local Operator." }),
180568
180604
  /* @__PURE__ */ jsxRuntimeExports.jsxs(SectionDescription$1, { sx: { mb: 3 }, children: [
180569
180605
  "Start with",
180570
180606
  " ",
@@ -180575,7 +180611,7 @@ const RadientSignInStep = ({
180575
180611
  fontWeight: "medium",
180576
180612
  color: theme2.palette.primary.main,
180577
180613
  sx: { fontSize: "inherit" },
180578
- children: "$1 USD"
180614
+ children: isLoading ? /* @__PURE__ */ jsxRuntimeExports.jsx(CircularProgress, { size: 16, sx: { mr: 0.5 } }) : formatCurrency(prices?.default_new_credits)
180579
180615
  }
180580
180616
  ),
180581
180617
  " ",
@@ -180588,11 +180624,12 @@ const RadientSignInStep = ({
180588
180624
  fontWeight: "medium",
180589
180625
  color: theme2.palette.primary.main,
180590
180626
  sx: { fontSize: "inherit" },
180591
- children: "$5 USD"
180627
+ children: isLoading ? /* @__PURE__ */ jsxRuntimeExports.jsx(CircularProgress, { size: 16, sx: { mr: 0.5 } }) : formatCurrency(prices?.default_registration_credits)
180592
180628
  }
180593
180629
  ),
180594
180630
  " ",
180595
- "more with your first payment."
180631
+ "more with your first payment.",
180632
+ error && /* @__PURE__ */ jsxRuntimeExports.jsx(Typography, { color: "error", variant: "caption", display: "block", mt: 1, children: "Could not load credit information." })
180596
180633
  ] }),
180597
180634
  /* @__PURE__ */ jsxRuntimeExports.jsx(
180598
180635
  Box,
@@ -181051,7 +181088,7 @@ const UserProfileStep = () => {
181051
181088
  };
181052
181089
  const stepTitles = {
181053
181090
  [OnboardingStep.RADIENT_CHOICE]: "Choose Your Setup Option",
181054
- [OnboardingStep.RADIENT_SIGNIN]: "Sign in with a Radient Pass",
181091
+ [OnboardingStep.RADIENT_SIGNIN]: "Set Up With Radient Pass",
181055
181092
  [OnboardingStep.USER_PROFILE]: "Set Up Your Profile",
181056
181093
  [OnboardingStep.MODEL_CREDENTIAL]: "Add Model Provider Credentials",
181057
181094
  [OnboardingStep.SEARCH_API]: "Enable Web Search (Recommended)",
@@ -205316,8 +205353,11 @@ const LoadingContainer$2 = styled$1(Box)({
205316
205353
  alignItems: "center",
205317
205354
  minHeight: 150
205318
205355
  });
205319
- const RadientAccountSection = () => {
205356
+ const RadientAccountSection = ({
205357
+ onAfterCredentialUpdate
205358
+ }) => {
205320
205359
  const { isAuthenticated, user, isLoading, error, signOut } = useRadientAuth();
205360
+ const isSigningOut = useUserStore((state) => state.isSigningOut);
205321
205361
  const handleSignOut = reactExports.useCallback(async () => {
205322
205362
  try {
205323
205363
  await signOut();
@@ -205326,7 +205366,7 @@ const RadientAccountSection = () => {
205326
205366
  }
205327
205367
  }, [signOut]);
205328
205368
  const accountInfoSection = reactExports.useMemo(() => {
205329
- if (!isAuthenticated || !user.radientUser) return null;
205369
+ if (!isAuthenticated || !user?.radientUser) return null;
205330
205370
  const { account, identity: identity3 } = user.radientUser;
205331
205371
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
205332
205372
  /* @__PURE__ */ jsxRuntimeExports.jsxs(InfoContainer, { children: [
@@ -205384,9 +205424,9 @@ const RadientAccountSection = () => {
205384
205424
  )
205385
205425
  ] })
205386
205426
  ] });
205387
- }, [isAuthenticated, user.radientUser, handleSignOut]);
205427
+ }, [isAuthenticated, user?.radientUser, handleSignOut]);
205388
205428
  const signInSection = reactExports.useMemo(() => {
205389
- if (isAuthenticated) return null;
205429
+ if (isAuthenticated && user) return null;
205390
205430
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(Box, { sx: { mt: 1 }, children: [
205391
205431
  " ",
205392
205432
  /* @__PURE__ */ jsxRuntimeExports.jsx(Typography, { variant: "body2", color: "text.secondary", mb: 2.5, children: "You are not currently signed in to Radient. Sign in to access your account details or sign up to get free credits and unified access to models, tools, and more with Radient Pass." }),
@@ -205394,22 +205434,30 @@ const RadientAccountSection = () => {
205394
205434
  RadientAuthButtons,
205395
205435
  {
205396
205436
  titleText: "",
205437
+ onAfterCredentialUpdate,
205397
205438
  descriptionText: "",
205398
205439
  onSignInSuccess: () => {
205399
205440
  }
205400
205441
  }
205401
205442
  )
205402
205443
  ] });
205403
- }, [isAuthenticated]);
205444
+ }, [isAuthenticated, user, onAfterCredentialUpdate]);
205404
205445
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(Box, { children: [
205405
205446
  " ",
205406
- isLoading ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoadingContainer$2, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(CircularProgress, {}) }) : error ? /* @__PURE__ */ jsxRuntimeExports.jsxs(Typography, { color: "error", variant: "body2", children: [
205407
- "Error loading account information:",
205408
- " ",
205409
- error instanceof Error ? error.message : String(error)
205410
- ] }) : (
205411
- // Render either the account info or the sign-in prompt
205412
- accountInfoSection || signInSection
205447
+ isLoading || isSigningOut ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoadingContainer$2, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(CircularProgress, {}) }) : isAuthenticated && user?.radientUser ? (
205448
+ // If authenticated and user data exists, show account info
205449
+ accountInfoSection
205450
+ ) : (
205451
+ // If not loading and not authenticated (or user data missing), show sign-in section.
205452
+ // Display error above if it exists.
205453
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
205454
+ error && /* @__PURE__ */ jsxRuntimeExports.jsxs(Typography, { color: "error", variant: "body2", sx: { mb: 2 }, children: [
205455
+ "Error checking account status:",
205456
+ " ",
205457
+ error instanceof Error ? error.message : String(error)
205458
+ ] }),
205459
+ signInSection
205460
+ ] })
205413
205461
  )
205414
205462
  ] });
205415
205463
  };
@@ -206724,6 +206772,29 @@ const SettingsPage = () => {
206724
206772
  const [activeSection, setActiveSection] = reactExports.useState("general");
206725
206773
  const [isScrolling, setIsScrolling] = reactExports.useState(false);
206726
206774
  const scrollTimeoutRef = reactExports.useRef(null);
206775
+ const { data: credentialsData, refetch: refetchCredentials } = useCredentials();
206776
+ const { refreshModels } = useModels();
206777
+ const credentialKeys = reactExports.useMemo(
206778
+ () => credentialsData?.keys ? [...credentialsData.keys].sort() : [],
206779
+ [credentialsData?.keys]
206780
+ );
206781
+ const lastRefreshRef = reactExports.useRef({
206782
+ keys: "",
206783
+ hosting: void 0
206784
+ });
206785
+ reactExports.useEffect(() => {
206786
+ const keysString = credentialKeys.join(",");
206787
+ const hosting = config2?.values?.hosting;
206788
+ if (lastRefreshRef.current.keys !== keysString || lastRefreshRef.current.hosting !== hosting) {
206789
+ lastRefreshRef.current = { keys: keysString, hosting };
206790
+ refreshModels().catch((err) => {
206791
+ console.error(
206792
+ "Failed to refresh models after credentials or hosting change:",
206793
+ err
206794
+ );
206795
+ });
206796
+ }
206797
+ }, [credentialKeys, config2?.values?.hosting, refreshModels]);
206727
206798
  const sectionRefs = reactExports.useRef({
206728
206799
  general: reactExports.useRef(null),
206729
206800
  radient: reactExports.useRef(null),
@@ -207001,7 +207072,15 @@ const SettingsPage = () => {
207001
207072
  description: "Manage your Radient account, Radient Pass details, and credits.",
207002
207073
  cardRef: sectionRefs.radient,
207003
207074
  children: [
207004
- /* @__PURE__ */ jsxRuntimeExports.jsx(RadientAccountSection, {}),
207075
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
207076
+ RadientAccountSection,
207077
+ {
207078
+ onAfterCredentialUpdate: () => {
207079
+ refreshModels();
207080
+ refetchCredentials();
207081
+ }
207082
+ }
207083
+ ),
207005
207084
  isAuthenticated && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
207006
207085
  /* @__PURE__ */ jsxRuntimeExports.jsx(Divider, { sx: { my: 3 } }),
207007
207086
  /* @__PURE__ */ jsxRuntimeExports.jsx(BillingInfo, {}),
@@ -207237,8 +207316,8 @@ const UserProfileSidebar = React.memo(
207237
207316
  const [anchorEl, setAnchorEl] = reactExports.useState(null);
207238
207317
  const open2 = Boolean(anchorEl);
207239
207318
  const { user, isAuthenticated, signOut } = useRadientAuth();
207240
- const userName = user.name;
207241
- const userEmail = user.email;
207319
+ const userName = user?.name ?? "User";
207320
+ const userEmail = user?.email ?? "";
207242
207321
  const handleClick = reactExports.useCallback(
207243
207322
  (event) => {
207244
207323
  if (useAuth) {
@@ -207562,6 +207641,109 @@ const App = () => {
207562
207641
  ] }) })
207563
207642
  ] });
207564
207643
  };
207644
+ const queryClient = new QueryClient({
207645
+ defaultOptions: {
207646
+ queries: {
207647
+ // Default stale time of 5 minutes
207648
+ staleTime: 5 * 60 * 1e3,
207649
+ // Default cache time of 10 minutes
207650
+ gcTime: 10 * 60 * 1e3,
207651
+ // Default retry configuration
207652
+ retry: 1,
207653
+ // Default refetch configuration
207654
+ refetchOnWindowFocus: true,
207655
+ refetchOnMount: true,
207656
+ // Don't wait for reconnect to refetch - we handle offline status separately
207657
+ refetchOnReconnect: false,
207658
+ // Continue to run queries even when offline
207659
+ networkMode: "always"
207660
+ },
207661
+ mutations: {
207662
+ // Retry mutations once by default
207663
+ retry: 1,
207664
+ // Continue to run mutations even when offline
207665
+ networkMode: "always"
207666
+ }
207667
+ }
207668
+ });
207669
+ const useRadientTokenRefresher = () => {
207670
+ const { authStatus, hasLocalSession } = useRadientAuth();
207671
+ const queryClient2 = useQueryClient();
207672
+ const refreshTimeout = reactExports.useRef(null);
207673
+ const radientClient2 = reactExports.useMemo(
207674
+ () => createRadientClient(apiConfig.radientBaseUrl, apiConfig.radientClientId),
207675
+ []
207676
+ );
207677
+ const clearRefreshTimeout = reactExports.useCallback(() => {
207678
+ if (refreshTimeout.current) {
207679
+ clearTimeout(refreshTimeout.current);
207680
+ refreshTimeout.current = null;
207681
+ }
207682
+ }, []);
207683
+ const refreshAccessToken = reactExports.useCallback(async () => {
207684
+ const session = await getSession();
207685
+ if (!session || !session.refreshToken) {
207686
+ return;
207687
+ }
207688
+ const currentAccessToken = session.accessToken;
207689
+ try {
207690
+ const response = await radientClient2.refreshToken(session.refreshToken);
207691
+ const newAccessToken = response.result.access_token;
207692
+ const newRefreshToken = response.result.refresh_token || session.refreshToken;
207693
+ await updateAccessToken(
207694
+ newAccessToken,
207695
+ response.result.expires_in,
207696
+ newRefreshToken
207697
+ );
207698
+ if (newAccessToken !== currentAccessToken) {
207699
+ queryClient2.invalidateQueries({ queryKey: radientUserKeys.session() });
207700
+ }
207701
+ } catch (err) {
207702
+ const errorMessage = err instanceof Error ? err.message : String(err);
207703
+ if (errorMessage.toLowerCase().includes("invalid_grant") || errorMessage.toLowerCase().includes("refresh token expired") || errorMessage.toLowerCase().includes("invalid refresh token")) {
207704
+ await clearSession();
207705
+ queryClient2.invalidateQueries({ queryKey: radientUserKeys.all });
207706
+ showErrorToast("Session expired. Please sign in again.");
207707
+ }
207708
+ }
207709
+ }, [queryClient2, radientClient2]);
207710
+ const schedulePeriodicRefresh = reactExports.useCallback(() => {
207711
+ clearRefreshTimeout();
207712
+ refreshTimeout.current = setTimeout(
207713
+ async () => {
207714
+ await refreshAccessToken();
207715
+ schedulePeriodicRefresh();
207716
+ },
207717
+ 5 * 60 * 1e3
207718
+ );
207719
+ }, [refreshAccessToken, clearRefreshTimeout]);
207720
+ reactExports.useEffect(() => {
207721
+ if (authStatus === "authenticated" || hasLocalSession) {
207722
+ refreshAccessToken();
207723
+ schedulePeriodicRefresh();
207724
+ const handleFocus = () => {
207725
+ refreshAccessToken();
207726
+ };
207727
+ window.addEventListener("focus", handleFocus);
207728
+ return () => {
207729
+ clearRefreshTimeout();
207730
+ window.removeEventListener("focus", handleFocus);
207731
+ };
207732
+ }
207733
+ clearRefreshTimeout();
207734
+ return void 0;
207735
+ }, [
207736
+ authStatus,
207737
+ hasLocalSession,
207738
+ refreshAccessToken,
207739
+ schedulePeriodicRefresh,
207740
+ clearRefreshTimeout
207741
+ ]);
207742
+ };
207743
+ const RadientTokenRefresherRunner = () => {
207744
+ useRadientTokenRefresher();
207745
+ return null;
207746
+ };
207565
207747
  const RadientAuthProvider = ({
207566
207748
  children
207567
207749
  }) => {
@@ -207631,7 +207813,10 @@ document.addEventListener("DOMContentLoaded", () => {
207631
207813
  options: posthogOptions,
207632
207814
  children: /* @__PURE__ */ jsxRuntimeExports.jsx(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsxRuntimeExports.jsx(FeatureFlagProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(AuthProviders, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(ThemeProvider, { children: [
207633
207815
  /* @__PURE__ */ jsxRuntimeExports.jsx(CssBaseline, {}),
207634
- /* @__PURE__ */ jsxRuntimeExports.jsx(ErrorBoundary, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(HashRouter, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(App, {}) }) }),
207816
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ErrorBoundary, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(HashRouter, { children: [
207817
+ /* @__PURE__ */ jsxRuntimeExports.jsx(App, {}),
207818
+ /* @__PURE__ */ jsxRuntimeExports.jsx(RadientTokenRefresherRunner, {})
207819
+ ] }) }),
207635
207820
  /* @__PURE__ */ jsxRuntimeExports.jsx(ThemedToastContainer, {}),
207636
207821
  isDevelopmentMode()
207637
207822
  ] }) }) }) })