@burtson-labs/bandit-engine 2.0.149 → 2.0.151

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.
Files changed (42) hide show
  1. package/dist/{aiProviderStore-FTD277QP.mjs → aiProviderStore-ZQ5VVVKQ.mjs} +2 -2
  2. package/dist/chat-3HV3GM5P.mjs +16 -0
  3. package/dist/chat-provider.js +5 -2
  4. package/dist/chat-provider.js.map +1 -1
  5. package/dist/chat-provider.mjs +5 -5
  6. package/dist/{chunk-P5IJLX6I.mjs → chunk-6STVJJSG.mjs} +4 -2
  7. package/dist/chunk-6STVJJSG.mjs.map +1 -0
  8. package/dist/{chunk-K2JGFKEB.mjs → chunk-CVFFNX7H.mjs} +2 -2
  9. package/dist/{chunk-JQSZNGII.mjs → chunk-DSYE5AHW.mjs} +9 -9
  10. package/dist/{chunk-43MLINPL.mjs → chunk-GWQRTUKF.mjs} +6 -3
  11. package/dist/chunk-GWQRTUKF.mjs.map +1 -0
  12. package/dist/{chunk-PU74BI6Y.mjs → chunk-QLATFSSO.mjs} +5 -5
  13. package/dist/{chunk-F7JXIW6T.mjs → chunk-RRCCSN3N.mjs} +2 -2
  14. package/dist/{chunk-F735W34E.mjs → chunk-TYRYAAP2.mjs} +38 -3
  15. package/dist/chunk-TYRYAAP2.mjs.map +1 -0
  16. package/dist/{chunk-K6IV4LYZ.mjs → chunk-U33KBX3Y.mjs} +4 -4
  17. package/dist/{chunk-NLBZZP3B.mjs → chunk-VLUXQE24.mjs} +3 -3
  18. package/dist/{chunk-ANX33XAO.mjs → chunk-ZRJYLJKZ.mjs} +65 -22
  19. package/dist/chunk-ZRJYLJKZ.mjs.map +1 -0
  20. package/dist/index.js +142 -52
  21. package/dist/index.js.map +1 -1
  22. package/dist/index.mjs +10 -10
  23. package/dist/management/management.js +136 -46
  24. package/dist/management/management.js.map +1 -1
  25. package/dist/management/management.mjs +8 -8
  26. package/dist/modals/chat-modal/chat-modal.js +40 -2
  27. package/dist/modals/chat-modal/chat-modal.js.map +1 -1
  28. package/dist/modals/chat-modal/chat-modal.mjs +4 -4
  29. package/package.json +1 -1
  30. package/dist/chat-Z4SQGSMN.mjs +0 -16
  31. package/dist/chunk-43MLINPL.mjs.map +0 -1
  32. package/dist/chunk-ANX33XAO.mjs.map +0 -1
  33. package/dist/chunk-F735W34E.mjs.map +0 -1
  34. package/dist/chunk-P5IJLX6I.mjs.map +0 -1
  35. /package/dist/{aiProviderStore-FTD277QP.mjs.map → aiProviderStore-ZQ5VVVKQ.mjs.map} +0 -0
  36. /package/dist/{chat-Z4SQGSMN.mjs.map → chat-3HV3GM5P.mjs.map} +0 -0
  37. /package/dist/{chunk-K2JGFKEB.mjs.map → chunk-CVFFNX7H.mjs.map} +0 -0
  38. /package/dist/{chunk-JQSZNGII.mjs.map → chunk-DSYE5AHW.mjs.map} +0 -0
  39. /package/dist/{chunk-PU74BI6Y.mjs.map → chunk-QLATFSSO.mjs.map} +0 -0
  40. /package/dist/{chunk-F7JXIW6T.mjs.map → chunk-RRCCSN3N.mjs.map} +0 -0
  41. /package/dist/{chunk-K6IV4LYZ.mjs.map → chunk-U33KBX3Y.mjs.map} +0 -0
  42. /package/dist/{chunk-NLBZZP3B.mjs.map → chunk-VLUXQE24.mjs.map} +0 -0
package/dist/index.mjs CHANGED
@@ -1,26 +1,26 @@
1
1
  import {
2
2
  chat_default
3
- } from "./chunk-ANX33XAO.mjs";
3
+ } from "./chunk-ZRJYLJKZ.mjs";
4
4
  import {
5
5
  chat_provider_default
6
- } from "./chunk-PU74BI6Y.mjs";
6
+ } from "./chunk-QLATFSSO.mjs";
7
7
  import "./chunk-ONQMRE2G.mjs";
8
8
  import {
9
9
  management_default,
10
10
  useGatewayHealth,
11
11
  useGatewayMemory,
12
12
  useGatewayModels
13
- } from "./chunk-JQSZNGII.mjs";
14
- import "./chunk-P5IJLX6I.mjs";
15
- import "./chunk-F7JXIW6T.mjs";
16
- import "./chunk-K2JGFKEB.mjs";
13
+ } from "./chunk-DSYE5AHW.mjs";
14
+ import "./chunk-6STVJJSG.mjs";
15
+ import "./chunk-RRCCSN3N.mjs";
16
+ import "./chunk-CVFFNX7H.mjs";
17
17
  import {
18
18
  defineCustomElement
19
19
  } from "./chunk-IXIM7BNO.mjs";
20
20
  import {
21
21
  FeedbackButton,
22
22
  chat_modal_default
23
- } from "./chunk-K6IV4LYZ.mjs";
23
+ } from "./chunk-U33KBX3Y.mjs";
24
24
  import {
25
25
  FeedbackModal,
26
26
  StreamingTTSClient,
@@ -37,7 +37,7 @@ import {
37
37
  useTTS,
38
38
  useVoiceStore,
39
39
  voiceService
40
- } from "./chunk-F735W34E.mjs";
40
+ } from "./chunk-TYRYAAP2.mjs";
41
41
  import {
42
42
  DEFAULT_TIER_FEATURES,
43
43
  FeatureFlagContext,
@@ -56,7 +56,7 @@ import {
56
56
  useVectorStore,
57
57
  vectorDatabaseService,
58
58
  vectorMigrationService
59
- } from "./chunk-NLBZZP3B.mjs";
59
+ } from "./chunk-VLUXQE24.mjs";
60
60
  import {
61
61
  usePackageSettingsStore,
62
62
  usePreferencesStore
@@ -64,7 +64,7 @@ import {
64
64
  import {
65
65
  authenticationService,
66
66
  useAuthenticationStore
67
- } from "./chunk-43MLINPL.mjs";
67
+ } from "./chunk-GWQRTUKF.mjs";
68
68
  import {
69
69
  DebugLogger,
70
70
  debugLogger
@@ -1585,7 +1585,7 @@ function emitAuthTokenChanged(token) {
1585
1585
  detail: { token }
1586
1586
  }));
1587
1587
  }
1588
- var TOKEN_KEY2, AUTH_TOKEN_CHANGED_EVENT, AuthenticationService, authenticationService;
1588
+ var TOKEN_KEY2, AUTH_TOKEN_CHANGED_EVENT, AuthenticationService, authenticationService2;
1589
1589
  var init_authenticationService = __esm({
1590
1590
  "src/services/auth/authenticationService.ts"() {
1591
1591
  "use strict";
@@ -1638,7 +1638,7 @@ var init_authenticationService = __esm({
1638
1638
  }
1639
1639
  }
1640
1640
  };
1641
- authenticationService = new AuthenticationService();
1641
+ authenticationService2 = new AuthenticationService();
1642
1642
  }
1643
1643
  });
1644
1644
 
@@ -1721,12 +1721,15 @@ var init_gateway_service = __esm({
1721
1721
  return;
1722
1722
  }
1723
1723
  const data = error.response?.data;
1724
- const code = data?.code;
1725
- if (code !== "FORCE_RELOGIN" && code !== "ACCOUNT_LOCKED") {
1724
+ let code = data?.code;
1725
+ if (status === 401 && !code) {
1726
+ code = "TOKEN_EXPIRED";
1727
+ }
1728
+ if (code !== "FORCE_RELOGIN" && code !== "ACCOUNT_LOCKED" && code !== "TOKEN_EXPIRED") {
1726
1729
  return;
1727
1730
  }
1728
1731
  try {
1729
- authenticationService.clearToken();
1732
+ authenticationService2.clearToken();
1730
1733
  } catch {
1731
1734
  }
1732
1735
  if (typeof window !== "undefined" && typeof window.dispatchEvent === "function") {
@@ -8137,7 +8140,7 @@ function buildUrl(path) {
8137
8140
  }
8138
8141
  function buildHeaders() {
8139
8142
  const headers = { "Content-Type": "application/json" };
8140
- const token = authenticationService.getToken();
8143
+ const token = authenticationService2.getToken();
8141
8144
  if (token) {
8142
8145
  headers["Authorization"] = `Bearer ${token}`;
8143
8146
  }
@@ -8285,7 +8288,7 @@ function resolveAuthIdentity(token) {
8285
8288
  if (!token) {
8286
8289
  return null;
8287
8290
  }
8288
- const claims = authenticationService.parseJwtClaims(token);
8291
+ const claims = authenticationService2.parseJwtClaims(token);
8289
8292
  if (claims?.sub) {
8290
8293
  return claims.sub;
8291
8294
  }
@@ -8818,7 +8821,7 @@ var init_conversationSyncStore = __esm({
8818
8821
  async initialize() {
8819
8822
  ensureTrackersInitialized();
8820
8823
  const gatewayUrl = usePackageSettingsStore.getState().settings?.gatewayApiUrl;
8821
- const token = authenticationService.getToken();
8824
+ const token = authenticationService2.getToken();
8822
8825
  const tokenIdentity = resolveAuthIdentity(token);
8823
8826
  const current = get();
8824
8827
  const storedIdentity = getStoredSyncIdentity();
@@ -8944,10 +8947,10 @@ var init_conversationSyncStore = __esm({
8944
8947
  });
8945
8948
  set({
8946
8949
  hasLoadedPreference: true,
8947
- initializedForToken: authenticationService.getToken(),
8948
- initializedForIdentity: resolveAuthIdentity(authenticationService.getToken())
8950
+ initializedForToken: authenticationService2.getToken(),
8951
+ initializedForIdentity: resolveAuthIdentity(authenticationService2.getToken())
8949
8952
  });
8950
- setStoredSyncIdentity(resolveAuthIdentity(authenticationService.getToken()));
8953
+ setStoredSyncIdentity(resolveAuthIdentity(authenticationService2.getToken()));
8951
8954
  if (enabled) {
8952
8955
  set({ hasCompletedInitialUpload: false });
8953
8956
  }
@@ -8987,10 +8990,10 @@ var init_conversationSyncStore = __esm({
8987
8990
  });
8988
8991
  set({
8989
8992
  hasLoadedPreference: true,
8990
- initializedForToken: authenticationService.getToken(),
8991
- initializedForIdentity: resolveAuthIdentity(authenticationService.getToken())
8993
+ initializedForToken: authenticationService2.getToken(),
8994
+ initializedForIdentity: resolveAuthIdentity(authenticationService2.getToken())
8992
8995
  });
8993
- setStoredSyncIdentity(resolveAuthIdentity(authenticationService.getToken()));
8996
+ setStoredSyncIdentity(resolveAuthIdentity(authenticationService2.getToken()));
8994
8997
  if (preference.syncEnabled && preference.isAdvancedVectorFeaturesEnabled) {
8995
8998
  await get().runSync({ force: true });
8996
8999
  }
@@ -9030,7 +9033,7 @@ var init_conversationSyncStore = __esm({
9030
9033
  debugLogger.error("conversationSyncStore: runSync error - missing gateway URL");
9031
9034
  return;
9032
9035
  }
9033
- const token = authenticationService.getToken();
9036
+ const token = authenticationService2.getToken();
9034
9037
  if (!token) {
9035
9038
  set({ status: "error", lastError: "Authentication required to sync conversations." });
9036
9039
  debugLogger.error("conversationSyncStore: runSync error - missing auth token");
@@ -11834,6 +11837,46 @@ var init_knowledge_file_modal = __esm({
11834
11837
  }
11835
11838
  });
11836
11839
 
11840
+ // src/utils/openFileLink.ts
11841
+ var FILE_EXT_RE, isStandalonePwa, isFileLink, maybeHandleFileLinkClick;
11842
+ var init_openFileLink = __esm({
11843
+ "src/utils/openFileLink.ts"() {
11844
+ "use strict";
11845
+ init_debugLogger();
11846
+ FILE_EXT_RE = /\.(docx|pptx|xlsx|csv|json|md|txt|html|xml|ya?ml|pdf|zip)(?:[?#]|$)/i;
11847
+ isStandalonePwa = () => typeof window !== "undefined" && (window.matchMedia?.("(display-mode: standalone)").matches || window.navigator.standalone === true);
11848
+ isFileLink = (href) => Boolean(href && FILE_EXT_RE.test(href));
11849
+ maybeHandleFileLinkClick = (event, href) => {
11850
+ if (!href || !isStandalonePwa() || !isFileLink(href)) return;
11851
+ event.preventDefault();
11852
+ void (async () => {
11853
+ try {
11854
+ const res = await fetch(href);
11855
+ if (!res.ok) throw new Error(`fetch ${res.status}`);
11856
+ const blob = await res.blob();
11857
+ const rawName = new URL(href, window.location.href).pathname.split("/").pop() || "download";
11858
+ const name = decodeURIComponent(rawName);
11859
+ const file = new File([blob], name, {
11860
+ type: blob.type || "application/octet-stream"
11861
+ });
11862
+ const nav = navigator;
11863
+ if (nav.canShare?.({ files: [file] }) && nav.share) {
11864
+ await nav.share({ files: [file], title: name });
11865
+ return;
11866
+ }
11867
+ window.location.href = URL.createObjectURL(blob);
11868
+ } catch (error) {
11869
+ debugLogger.warn("openFileLink: share flow failed, falling back", {
11870
+ error: error instanceof Error ? error.message : String(error)
11871
+ });
11872
+ if (error?.name === "AbortError") return;
11873
+ window.open(href, "_blank", "noopener");
11874
+ }
11875
+ })();
11876
+ };
11877
+ }
11878
+ });
11879
+
11837
11880
  // src/services/tts/voiceService.ts
11838
11881
  var VoiceService, voiceService;
11839
11882
  var init_voiceService = __esm({
@@ -11879,7 +11922,7 @@ var init_voiceService = __esm({
11879
11922
  debugLogger.error("Gateway API URL not configured");
11880
11923
  throw new Error("Gateway API URL not configured");
11881
11924
  }
11882
- const token = authenticationService.getToken();
11925
+ const token = authenticationService2.getToken();
11883
11926
  if (!token) {
11884
11927
  debugLogger.warn("No JWT token available - skipping voice models fetch");
11885
11928
  const emptyModels = {
@@ -11889,7 +11932,7 @@ var init_voiceService = __esm({
11889
11932
  };
11890
11933
  return emptyModels;
11891
11934
  }
11892
- if (authenticationService.isTokenExpired(token)) {
11935
+ if (authenticationService2.isTokenExpired(token)) {
11893
11936
  debugLogger.warn("JWT token is expired - skipping voice models fetch");
11894
11937
  const emptyModels = {
11895
11938
  models: [],
@@ -11978,7 +12021,7 @@ var init_tts_client = __esm({
11978
12021
  init_packageSettingsStore();
11979
12022
  init_debugLogger();
11980
12023
  getOrAppendAuthHeader = (existing = {}) => {
11981
- const token = authenticationService.getToken();
12024
+ const token = authenticationService2.getToken();
11982
12025
  if (token) {
11983
12026
  existing["Authorization"] = `Bearer ${token}`;
11984
12027
  return existing;
@@ -12669,8 +12712,8 @@ var init_ai_response_action_bar = __esm({
12669
12712
  const { preferences } = usePreferencesStore();
12670
12713
  const { settings: packageSettings } = usePackageSettingsStore();
12671
12714
  (0, import_react13.useEffect)(() => {
12672
- const isAuthenticated = authenticationService.isAuthenticated();
12673
- const token = authenticationService.getToken();
12715
+ const isAuthenticated = authenticationService2.isAuthenticated();
12716
+ const token = authenticationService2.getToken();
12674
12717
  if (!initialized || availableVoices.length === 0) {
12675
12718
  if (token && isAuthenticated) {
12676
12719
  debugLogger.debug("AI Action Bar: Voices not initialized or unavailable, attempting to load from API");
@@ -12859,6 +12902,7 @@ var init_ai_response_text_field = __esm({
12859
12902
  init_lowlight();
12860
12903
  init_markdownRendering();
12861
12904
  init_lucide_icons();
12905
+ init_openFileLink();
12862
12906
  init_ai_response_action_bar();
12863
12907
  import_jsx_runtime9 = require("react/jsx-runtime");
12864
12908
  brainIcon = "https://cdn.burtson.ai/images/brain-icon.png";
@@ -13291,6 +13335,7 @@ ${sourcesMarkdownList.join("\n")}`;
13291
13335
  },
13292
13336
  target: "_blank",
13293
13337
  rel: "noopener noreferrer",
13338
+ onClick: (e) => maybeHandleFileLinkClick(e, href),
13294
13339
  children
13295
13340
  }
13296
13341
  );
@@ -15521,7 +15566,7 @@ var init_FeedbackModal = __esm({
15521
15566
  }
15522
15567
  const gatewayService = new GatewayService(
15523
15568
  gatewayUrl,
15524
- () => authenticationService.getToken(),
15569
+ () => authenticationService2.getToken(),
15525
15570
  feedbackEmail || settings?.feedbackEmail
15526
15571
  );
15527
15572
  const feedbackRequest = {
@@ -18968,6 +19013,7 @@ var init_StreamingMarkdown = __esm({
18968
19013
  init_lowlight();
18969
19014
  init_markdownRendering();
18970
19015
  init_lucide_icons();
19016
+ init_openFileLink();
18971
19017
  import_jsx_runtime24 = require("react/jsx-runtime");
18972
19018
  StreamingMarkdown = ({
18973
19019
  content,
@@ -19121,6 +19167,7 @@ ${listMarkdown}`;
19121
19167
  href,
19122
19168
  target: "_blank",
19123
19169
  rel: "noopener noreferrer",
19170
+ onClick: (e) => maybeHandleFileLinkClick(e, href),
19124
19171
  style: {
19125
19172
  color: theme.palette.info?.main ?? theme.palette.primary.main,
19126
19173
  textDecoration: "underline",
@@ -19463,7 +19510,7 @@ var init_mcpServersService = __esm({
19463
19510
  };
19464
19511
  authHeaders2 = () => {
19465
19512
  const headers = { "Content-Type": "application/json" };
19466
- const token = authenticationService.getToken();
19513
+ const token = authenticationService2.getToken();
19467
19514
  if (token) headers["Authorization"] = `Bearer ${token}`;
19468
19515
  return headers;
19469
19516
  };
@@ -20662,7 +20709,7 @@ var init_engineStore = __esm({
20662
20709
  }
20663
20710
  try {
20664
20711
  const headers = { "Content-Type": "application/json" };
20665
- const token = authenticationService.getToken();
20712
+ const token = authenticationService2.getToken();
20666
20713
  if (token) headers["Authorization"] = `Bearer ${token}`;
20667
20714
  const res = await fetch(`${base}/models`, { headers });
20668
20715
  const data = await res.json();
@@ -20980,7 +21027,7 @@ var init_stt_client = __esm({
20980
21027
  filename,
20981
21028
  url: `${gatewayUrl}/stt/transcribe`
20982
21029
  });
20983
- const token = authenticationService.getToken();
21030
+ const token = authenticationService2.getToken();
20984
21031
  const response = await fetch(`${gatewayUrl}/stt/transcribe`, {
20985
21032
  method: "POST",
20986
21033
  headers: {
@@ -22580,7 +22627,7 @@ function syncTelemetry() {
22580
22627
  const settings = usePackageSettingsStore.getState().settings;
22581
22628
  const cfg = resolveTelemetryConfig({
22582
22629
  telemetry: settings?.telemetry,
22583
- banditApiKey: authenticationService.getToken() ?? void 0
22630
+ banditApiKey: authenticationService2.getToken() ?? void 0
22584
22631
  });
22585
22632
  active = cfg ? new TelemetryExporter(cfg) : null;
22586
22633
  } catch {
@@ -23231,7 +23278,7 @@ var init_mcpService = __esm({
23231
23278
  }
23232
23279
  if (tool.mcpServerId) {
23233
23280
  const base2 = settings.gatewayApiUrl.replace(/\/$/, "");
23234
- const token2 = authenticationService.getToken();
23281
+ const token2 = authenticationService2.getToken();
23235
23282
  const controller2 = new AbortController();
23236
23283
  const timeoutId2 = setTimeout(() => controller2.abort(), 3e4);
23237
23284
  try {
@@ -23278,7 +23325,7 @@ var init_mcpService = __esm({
23278
23325
  "Content-Type": "application/json"
23279
23326
  }
23280
23327
  };
23281
- const token = authenticationService.getToken();
23328
+ const token = authenticationService2.getToken();
23282
23329
  if (token) {
23283
23330
  requestOptions.headers = {
23284
23331
  ...requestOptions.headers,
@@ -24276,6 +24323,29 @@ ${protocol}`;
24276
24323
  overrideComponentStatus("Idle");
24277
24324
  setIsSubmitting(false);
24278
24325
  setIsStreaming(false);
24326
+ if (/lifetime validation|token.*(expired|invalid)|unauthorized|\b401\b/i.test(err.message || "")) {
24327
+ const { replaceLastAnswer: replaceLastAnswer2 } = useConversationStore.getState();
24328
+ replaceLastAnswer2(
24329
+ "_Your session ended \u2014 sign back in to continue._",
24330
+ lastPartialRef.current.images,
24331
+ false,
24332
+ lastPartialRef.current.usedDocs,
24333
+ true
24334
+ );
24335
+ setResponse("");
24336
+ setStreamBuffer("");
24337
+ setIsThinking?.(false);
24338
+ setPendingMessage(null);
24339
+ try {
24340
+ authenticationService.clearToken();
24341
+ } catch {
24342
+ }
24343
+ window.dispatchEvent(
24344
+ new CustomEvent("auth:force-relogin", { detail: { code: "TOKEN_EXPIRED" } })
24345
+ );
24346
+ telemetryEndTurn({ error: "auth_expired" });
24347
+ return;
24348
+ }
24279
24349
  const rateLimit = parseRateLimitError(err);
24280
24350
  if (rateLimit) {
24281
24351
  debugLogger.info("Chat hit usage limit (429) \u2014 showing upgrade prompt", {
@@ -27558,7 +27628,7 @@ var init_conversation_drawer = __esm({
27558
27628
  title: "Sign out",
27559
27629
  onClick: (event) => {
27560
27630
  event.stopPropagation();
27561
- authenticationService.clearToken();
27631
+ authenticationService2.clearToken();
27562
27632
  window.location.href = "/login";
27563
27633
  },
27564
27634
  sx: {
@@ -28674,7 +28744,7 @@ var init_enhanced_mobile_conversations_modal = __esm({
28674
28744
  title: "Sign out",
28675
28745
  onClick: (event) => {
28676
28746
  event.stopPropagation();
28677
- authenticationService.clearToken();
28747
+ authenticationService2.clearToken();
28678
28748
  window.location.href = "/login";
28679
28749
  },
28680
28750
  sx: {
@@ -29554,7 +29624,7 @@ var init_UnderReview = __esm({
29554
29624
  const theme = (0, import_material51.useTheme)();
29555
29625
  const navigate = (0, import_react_router_dom4.useNavigate)();
29556
29626
  const handleResetSession = () => {
29557
- authenticationService.clearToken();
29627
+ authenticationService2.clearToken();
29558
29628
  navigate("/login");
29559
29629
  };
29560
29630
  return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
@@ -30233,8 +30303,8 @@ var init_chat2 = __esm({
30233
30303
  const notificationService2 = useNotificationService();
30234
30304
  const [selectedTheme, setSelectedTheme] = (0, import_react63.useState)(null);
30235
30305
  const [themeLoading, setThemeLoading] = (0, import_react63.useState)(true);
30236
- const token = authenticationService.getToken();
30237
- const claims = token ? authenticationService.parseJwtClaims(token) : null;
30306
+ const token = authenticationService2.getToken();
30307
+ const claims = token ? authenticationService2.parseJwtClaims(token) : null;
30238
30308
  const baseTheme = themeMap_default[selectedTheme ?? "bandit-dark"] || banditDarkTheme;
30239
30309
  const banditTheme = (0, import_react63.useMemo)(() => {
30240
30310
  return (0, import_styles34.createTheme)(baseTheme, {
@@ -30307,7 +30377,7 @@ var init_chat2 = __esm({
30307
30377
  } = useTTS();
30308
30378
  (0, import_react63.useEffect)(() => {
30309
30379
  const timer = setTimeout(() => {
30310
- const isAuthenticated = authenticationService.isAuthenticated();
30380
+ const isAuthenticated = authenticationService2.isAuthenticated();
30311
30381
  if (!initialized || availableVoices.length === 0) {
30312
30382
  if (token && isAuthenticated) {
30313
30383
  debugLogger.debug("Chat: Voices not initialized or unavailable, attempting to load from API");
@@ -30320,7 +30390,7 @@ var init_chat2 = __esm({
30320
30390
  return () => clearTimeout(timer);
30321
30391
  }, [initialized, availableVoices.length, loadVoicesFromAPI, token]);
30322
30392
  (0, import_react63.useEffect)(() => {
30323
- const isAuthenticated = authenticationService.isAuthenticated();
30393
+ const isAuthenticated = authenticationService2.isAuthenticated();
30324
30394
  if (packageSettings?.gatewayApiUrl && availableVoices.length === 0 && !initialized) {
30325
30395
  if (token && isAuthenticated) {
30326
30396
  debugLogger.debug("Chat: Gateway URL available and no voices loaded, attempting to load from API");
@@ -30342,6 +30412,7 @@ var init_chat2 = __esm({
30342
30412
  const [isMobile, setIsMobile] = (0, import_react63.useState)(false);
30343
30413
  const [drawerOpen, setDrawerOpen] = (0, import_react63.useState)(false);
30344
30414
  const [mobileConversationsOpen, setMobileConversationsOpen] = (0, import_react63.useState)(false);
30415
+ const cardSwipeStartXRef = (0, import_react63.useRef)(null);
30345
30416
  (0, import_react63.useEffect)(() => {
30346
30417
  if (typeof document === "undefined") return;
30347
30418
  const meta = document.querySelector('meta[name="theme-color"]');
@@ -31216,7 +31287,12 @@ var init_chat2 = __esm({
31216
31287
  // reads as full physical height with the rounded corner visible
31217
31288
  // where it overlaps the drawer.
31218
31289
  transform: isMobile && mobileConversationsOpen ? "translateX(calc(min(calc(100vw - 56px), 360px) - 12px))" : "none",
31219
- borderRadius: isMobile && mobileConversationsOpen ? "44px" : 0,
31290
+ // Square top-left + no top border: the card's edge runs unbroken
31291
+ // from the very top of the screen (all surfaces share one color),
31292
+ // which reads as true full height; a soft bottom-left corner keeps
31293
+ // the sheet feel.
31294
+ borderRadius: isMobile && mobileConversationsOpen ? "0 0 0 28px" : 0,
31295
+ borderTop: isMobile && mobileConversationsOpen ? "none" : void 0,
31220
31296
  zIndex: isMobile && mobileConversationsOpen ? theme.zIndex.modal + 1 : 0,
31221
31297
  // Hairline border so the rounded card reads even when the backdrop
31222
31298
  // is the same near-black as the shell.
@@ -31229,6 +31305,20 @@ var init_chat2 = __esm({
31229
31305
  setMobileConversationsOpen(false);
31230
31306
  }
31231
31307
  } : void 0,
31308
+ onTouchStart: isMobile && mobileConversationsOpen ? (e) => {
31309
+ if (e.currentTarget.contains(e.target)) {
31310
+ cardSwipeStartXRef.current = e.touches[0]?.clientX ?? null;
31311
+ }
31312
+ } : void 0,
31313
+ onTouchMove: isMobile && mobileConversationsOpen ? (e) => {
31314
+ const start = cardSwipeStartXRef.current;
31315
+ if (start === null) return;
31316
+ const dx = (e.touches[0]?.clientX ?? start) - start;
31317
+ if (Math.abs(dx) > 40) {
31318
+ cardSwipeStartXRef.current = null;
31319
+ setMobileConversationsOpen(false);
31320
+ }
31321
+ } : void 0,
31232
31322
  children: [
31233
31323
  /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
31234
31324
  chat_app_bar_default,
@@ -31526,12 +31616,12 @@ var init_chat2 = __esm({
31526
31616
  ossConfigured,
31527
31617
  isOSSMode: isOSSMode(),
31528
31618
  tier: featureFlag.getEvaluation()?.tier,
31529
- hasToken: authenticationService.isAuthenticated(),
31619
+ hasToken: authenticationService2.isAuthenticated(),
31530
31620
  playgroundBypassAuth,
31531
31621
  isPlaygroundRoute,
31532
31622
  bypassAuth
31533
31623
  });
31534
- if (!allowUnauthenticated && !bypassAuth && !authenticationService.isAuthenticated()) {
31624
+ if (!allowUnauthenticated && !bypassAuth && !authenticationService2.isAuthenticated()) {
31535
31625
  debugLogger.debug("User is not authenticated, redirecting to login");
31536
31626
  return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_react_router_dom5.Navigate, { to: "/login", replace: true });
31537
31627
  }
@@ -36351,7 +36441,7 @@ var useGatewayClient = () => {
36351
36441
  }
36352
36442
  return new GatewayService(
36353
36443
  gatewayUrl,
36354
- () => authenticationService.getToken(),
36444
+ () => authenticationService2.getToken(),
36355
36445
  feedbackEmail
36356
36446
  );
36357
36447
  }, [gatewayUrl, feedbackEmail]);
@@ -40200,7 +40290,7 @@ var buildHeaders2 = () => {
40200
40290
  const headers = {
40201
40291
  "Content-Type": "application/json"
40202
40292
  };
40203
- const token = authenticationService.getToken();
40293
+ const token = authenticationService2.getToken();
40204
40294
  if (token) {
40205
40295
  headers.Authorization = `Bearer ${token}`;
40206
40296
  }
@@ -42799,7 +42889,7 @@ var AIProviderInitService = class _AIProviderInitService {
42799
42889
  type: "ollama" /* OLLAMA */,
42800
42890
  baseUrl: settings.ollamaUrl,
42801
42891
  tokenFactory: () => {
42802
- let token = authenticationService.getToken();
42892
+ let token = authenticationService2.getToken();
42803
42893
  if (!token) {
42804
42894
  token = localStorage.getItem("authToken");
42805
42895
  }
@@ -42840,7 +42930,7 @@ var AIProviderInitService = class _AIProviderInitService {
42840
42930
  type: "ollama" /* OLLAMA */,
42841
42931
  baseUrl: settings.ollamaUrl || "http://localhost:11434",
42842
42932
  tokenFactory: () => {
42843
- let token = authenticationService.getToken();
42933
+ let token = authenticationService2.getToken();
42844
42934
  if (!token) {
42845
42935
  token = localStorage.getItem("authToken");
42846
42936
  }
@@ -42871,7 +42961,7 @@ var AIProviderInitService = class _AIProviderInitService {
42871
42961
  type: "ollama" /* OLLAMA */,
42872
42962
  baseUrl: "http://localhost:11434",
42873
42963
  tokenFactory: () => {
42874
- let token = authenticationService.getToken();
42964
+ let token = authenticationService2.getToken();
42875
42965
  if (!token) {
42876
42966
  token = localStorage.getItem("authToken");
42877
42967
  }
@@ -42961,7 +43051,7 @@ var AIProviderInitService = class _AIProviderInitService {
42961
43051
  return config;
42962
43052
  }
42963
43053
  config.tokenFactory = () => {
42964
- let token = authenticationService.getToken();
43054
+ let token = authenticationService2.getToken();
42965
43055
  if (!token && typeof localStorage !== "undefined") {
42966
43056
  try {
42967
43057
  token = localStorage.getItem("authToken");
@@ -43608,7 +43698,7 @@ function buildUrl3(path) {
43608
43698
  }
43609
43699
  function authHeaders() {
43610
43700
  const headers = { "Content-Type": "application/json" };
43611
- const token = authenticationService.getToken();
43701
+ const token = authenticationService2.getToken();
43612
43702
  if (token) headers["Authorization"] = `Bearer ${token}`;
43613
43703
  return headers;
43614
43704
  }
@@ -44953,7 +45043,7 @@ var Management = () => {
44953
45043
  let isActive = true;
44954
45044
  const loadCapabilities = async () => {
44955
45045
  try {
44956
- const token = authToken ?? authenticationService.getToken();
45046
+ const token = authToken ?? authenticationService2.getToken();
44957
45047
  const headers = {
44958
45048
  "Content-Type": "application/json"
44959
45049
  };
@@ -45089,7 +45179,7 @@ var Management = () => {
45089
45179
  "admin",
45090
45180
  "platform_admin"
45091
45181
  ]);
45092
- const userRoles = (authenticationService.parseJwtClaims(authenticationService.getToken() ?? "")?.roles ?? []).map((r) => r.toLowerCase());
45182
+ const userRoles = (authenticationService2.parseJwtClaims(authenticationService2.getToken() ?? "")?.roles ?? []).map((r) => r.toLowerCase());
45093
45183
  const isWorkspaceAdmin = userRoles.some(
45094
45184
  (r) => platformAdminRoles.has(r) || r.endsWith("-admin")
45095
45185
  );