@sagepilot-ai/react-native-sdk 0.2.2 → 0.2.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.
package/dist/index.js CHANGED
@@ -1,3 +1,44 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ SagepilotChat: () => SagepilotChat,
34
+ SagepilotChatError: () => SagepilotChatError,
35
+ SagepilotChatProvider: () => SagepilotChatProvider,
36
+ createAsyncStorageCacheStorage: () => createAsyncStorageCacheStorage,
37
+ createKeychainTokenStorage: () => createKeychainTokenStorage,
38
+ useSagepilotChat: () => useSagepilotChat
39
+ });
40
+ module.exports = __toCommonJS(index_exports);
41
+
1
42
  // src/core/errors/SagepilotChatError.ts
2
43
  var SagepilotChatError = class extends Error {
3
44
  constructor(code, message, options = {}) {
@@ -15,7 +56,7 @@ var SagepilotChatError = class extends Error {
15
56
 
16
57
  // src/core/config/constants.ts
17
58
  var SDK_NAME = "@sagepilot-ai/react-native-sdk";
18
- var SDK_VERSION = "0.2.0";
59
+ var SDK_VERSION = "0.2.3";
19
60
  var DEFAULT_HOST = "https://app.sagepilot.ai";
20
61
  var DEFAULT_WIDGET_HOST = "https://app.sagepilot.ai";
21
62
  var CUSTOMER_API_PREFIX = "/customer-api/v1";
@@ -701,9 +742,9 @@ var SagepilotReactNativeChat = class {
701
742
  this.hostedChatView = { screen: "messages" };
702
743
  return this.showHostedChat();
703
744
  }
704
- presentMessageComposer(message) {
745
+ presentMessageComposer(message, options) {
705
746
  this.requireConfigured();
706
- this.hostedChatView = { screen: "composer", message };
747
+ this.hostedChatView = { screen: "composer", message, mode: options?.mode ?? "auto" };
707
748
  return this.showHostedChat();
708
749
  }
709
750
  dismiss() {
@@ -803,7 +844,9 @@ var SagepilotReactNativeChat = class {
803
844
  url.searchParams.set("jwt", this.legacyWidgetJwt);
804
845
  }
805
846
  if (this.hostedChatView.screen === "composer") {
806
- url.searchParams.set("new", "true");
847
+ if (this.hostedChatView.mode === "new") {
848
+ url.searchParams.set("new", "true");
849
+ }
807
850
  if (this.hostedChatView.message) {
808
851
  url.searchParams.set("topic", this.hostedChatView.message);
809
852
  }
@@ -1033,7 +1076,9 @@ var SagepilotChat = {
1033
1076
  stopUnreadPolling: () => internalSagepilotChat.stopUnreadPolling(),
1034
1077
  present: () => internalSagepilotChat.present(),
1035
1078
  presentMessages: () => internalSagepilotChat.presentMessages(),
1036
- presentMessageComposer: (message) => internalSagepilotChat.presentMessageComposer(message),
1079
+ presentMessageComposer: (message, options) => {
1080
+ return internalSagepilotChat.presentMessageComposer(message, options);
1081
+ },
1037
1082
  dismiss: () => internalSagepilotChat.dismiss(),
1038
1083
  hide: () => internalSagepilotChat.hide(),
1039
1084
  toggle: () => internalSagepilotChat.toggle(),
@@ -1059,18 +1104,9 @@ function createAsyncStorageCacheStorage(asyncStorage) {
1059
1104
  }
1060
1105
 
1061
1106
  // src/ui/SagepilotChatProvider.ts
1062
- import { createElement, useEffect, useRef, useState } from "react";
1063
- import {
1064
- ActivityIndicator,
1065
- Modal,
1066
- Platform,
1067
- Pressable,
1068
- SafeAreaView,
1069
- StyleSheet,
1070
- Text,
1071
- View
1072
- } from "react-native";
1073
- import { WebView } from "react-native-webview";
1107
+ var import_react = require("react");
1108
+ var import_react_native = require("react-native");
1109
+ var import_react_native_webview = require("react-native-webview");
1074
1110
 
1075
1111
  // src/core/webview/mobileBridge.ts
1076
1112
  function isHostedBridgeMessage(value) {
@@ -1151,6 +1187,28 @@ var mobileWebViewBridgeScript = `
1151
1187
  } catch (error) {}
1152
1188
  }, true);
1153
1189
 
1190
+ document.addEventListener("focusin", function (event) {
1191
+ try {
1192
+ var target = event.target && event.target.closest
1193
+ ? event.target
1194
+ : event.target && event.target.parentElement;
1195
+ if (target && target.closest && target.closest("input, textarea, [contenteditable='true']")) {
1196
+ sendToReactNative({ type: "sagepilot:keyboard_focus" });
1197
+ }
1198
+ } catch (error) {}
1199
+ }, true);
1200
+
1201
+ document.addEventListener("focusout", function (event) {
1202
+ try {
1203
+ var target = event.target && event.target.closest
1204
+ ? event.target
1205
+ : event.target && event.target.parentElement;
1206
+ if (target && target.closest && target.closest("input, textarea, [contenteditable='true']")) {
1207
+ sendToReactNative({ type: "sagepilot:keyboard_blur" });
1208
+ }
1209
+ } catch (error) {}
1210
+ }, true);
1211
+
1154
1212
  ensureViewport();
1155
1213
  injectMobileStyles();
1156
1214
  sendToReactNative({ type: "sagepilot:ready" });
@@ -1158,6 +1216,10 @@ var mobileWebViewBridgeScript = `
1158
1216
  })();
1159
1217
  `;
1160
1218
 
1219
+ // src/specs/SagepilotInsetsViewNativeComponent.ts
1220
+ var import_codegenNativeComponent = __toESM(require("react-native/Libraries/Utilities/codegenNativeComponent"));
1221
+ var SagepilotInsetsViewNativeComponent_default = (0, import_codegenNativeComponent.default)("SagepilotInsetsView");
1222
+
1161
1223
  // src/ui/SagepilotChatProvider.ts
1162
1224
  function readPresentationState() {
1163
1225
  return {
@@ -1200,30 +1262,62 @@ function readUrlOrigin(url) {
1200
1262
  var hostedChatWebViewProps = {
1201
1263
  allowFileAccess: true,
1202
1264
  allowFileAccessFromFileURLs: true,
1265
+ bounces: false,
1203
1266
  domStorageEnabled: true,
1204
1267
  javaScriptEnabled: true,
1268
+ overScrollMode: "never",
1269
+ scrollEnabled: import_react_native.Platform.OS !== "android",
1205
1270
  setSupportMultipleWindows: false,
1206
1271
  sharedCookiesEnabled: true,
1207
1272
  thirdPartyCookiesEnabled: true
1208
1273
  };
1274
+ var AndroidInsetsView = import_react_native.Platform.OS === "android" ? SagepilotInsetsViewNativeComponent_default : import_react_native.View;
1275
+ var emptyAndroidInsets = { top: 0, bottom: 0 };
1209
1276
  function SagepilotChatProvider({
1210
1277
  children,
1211
1278
  closeLabel = "Close",
1212
1279
  loadingLabel = "Loading chat"
1213
1280
  }) {
1214
- const [state, setState] = useState(readPresentationState);
1215
- const webFrameRef = useRef(null);
1216
- const nativeWebViewRef = useRef(null);
1217
- useEffect(() => {
1281
+ const [state, setState] = (0, import_react.useState)(readPresentationState);
1282
+ const [androidModalInsets, setAndroidModalInsets] = (0, import_react.useState)(emptyAndroidInsets);
1283
+ const webFrameRef = (0, import_react.useRef)(null);
1284
+ const nativeWebViewRef = (0, import_react.useRef)(null);
1285
+ (0, import_react.useEffect)(() => {
1218
1286
  return internalSagepilotChat.onStateChange(() => {
1219
1287
  setState(readPresentationState());
1220
1288
  });
1221
1289
  }, []);
1290
+ const handleAndroidInsetsChange = (0, import_react.useCallback)((event) => {
1291
+ const nextBottomInset = event.nativeEvent?.bottom;
1292
+ const nextTopInset = event.nativeEvent?.top;
1293
+ if (typeof nextBottomInset !== "number" || typeof nextTopInset !== "number" || !Number.isFinite(nextBottomInset) || !Number.isFinite(nextTopInset)) return;
1294
+ setAndroidModalInsets({
1295
+ top: Math.max(0, nextTopInset),
1296
+ bottom: Math.max(0, nextBottomInset)
1297
+ });
1298
+ }, []);
1222
1299
  const showCloseButton = state.presentation?.showCloseButton ?? false;
1223
1300
  const presentationStyle = state.presentation?.style ?? "sheet";
1224
1301
  const isFullScreenModal = presentationStyle === "fullScreen";
1225
1302
  const animationType = presentationStyle === "fullScreen" || presentationStyle === "push" ? "slide" : "fade";
1226
- const ModalContainer = Platform.OS === "ios" && isFullScreenModal ? SafeAreaView : View;
1303
+ const ModalContainer = import_react_native.Platform.OS === "ios" && isFullScreenModal ? import_react_native.SafeAreaView : import_react_native.View;
1304
+ const NativeModalContainer = import_react_native.Platform.OS === "android" ? AndroidInsetsView : ModalContainer;
1305
+ const ChatContentContainer = import_react_native.Platform.OS === "ios" ? import_react_native.KeyboardAvoidingView : import_react_native.View;
1306
+ const nativeModalContainerProps = import_react_native.Platform.OS === "android" ? { style: styles.container, onInsetsChange: handleAndroidInsetsChange } : { style: styles.container };
1307
+ const chatContentContainerProps = import_react_native.Platform.OS === "ios" ? {
1308
+ behavior: "padding",
1309
+ enabled: true,
1310
+ keyboardVerticalOffset: 0,
1311
+ style: styles.modalContent
1312
+ } : {
1313
+ style: [
1314
+ styles.modalContent,
1315
+ import_react_native.Platform.OS === "android" ? {
1316
+ paddingTop: androidModalInsets.top,
1317
+ paddingBottom: androidModalInsets.bottom
1318
+ } : null
1319
+ ].filter(Boolean)
1320
+ };
1227
1321
  const handleWebViewMessage = (event) => {
1228
1322
  internalSagepilotChat.handleHostedBridgeMessage(parseHostedBridgeMessage(event.nativeEvent?.data));
1229
1323
  };
@@ -1238,8 +1332,8 @@ function SagepilotChatProvider({
1238
1332
  if (!script || !nativeWebViewRef.current) return;
1239
1333
  nativeWebViewRef.current.injectJavaScript(script);
1240
1334
  };
1241
- useEffect(() => {
1242
- if (Platform.OS !== "web" || typeof window === "undefined") return;
1335
+ (0, import_react.useEffect)(() => {
1336
+ if (import_react_native.Platform.OS !== "web" || typeof window === "undefined") return;
1243
1337
  const trustedWidgetOrigin = readUrlOrigin(state.conversationUrl);
1244
1338
  if (!trustedWidgetOrigin) return;
1245
1339
  const handleWindowMessage = (event) => {
@@ -1249,41 +1343,41 @@ function SagepilotChatProvider({
1249
1343
  window.addEventListener("message", handleWindowMessage);
1250
1344
  return () => window.removeEventListener("message", handleWindowMessage);
1251
1345
  }, [state.conversationUrl]);
1252
- useEffect(() => {
1253
- if (Platform.OS !== "web" || !state.isPresented) return;
1346
+ (0, import_react.useEffect)(() => {
1347
+ if (import_react_native.Platform.OS !== "web" || !state.isPresented) return;
1254
1348
  postIdentityToWebFrame();
1255
1349
  }, [state.isPresented, state.conversationUrl, state.configured]);
1256
- useEffect(() => {
1257
- if (Platform.OS === "web" || !state.isPresented) return;
1350
+ (0, import_react.useEffect)(() => {
1351
+ if (import_react_native.Platform.OS === "web" || !state.isPresented) return;
1258
1352
  postIdentityToNativeWebView();
1259
1353
  }, [state.isPresented, state.conversationUrl, state.configured]);
1260
- if (Platform.OS === "web") {
1261
- return createElement(
1262
- View,
1354
+ if (import_react_native.Platform.OS === "web") {
1355
+ return (0, import_react.createElement)(
1356
+ import_react_native.View,
1263
1357
  { style: styles.root },
1264
1358
  children,
1265
- state.configured && !state.isPresented && state.shouldPreload && state.preloadUrl ? createElement("iframe", {
1359
+ state.configured && !state.isPresented && state.shouldPreload && state.preloadUrl ? (0, import_react.createElement)("iframe", {
1266
1360
  src: state.preloadUrl,
1267
1361
  style: styles.webPreloadFrame,
1268
1362
  title: "Sagepilot chat preload"
1269
1363
  }) : null,
1270
- state.configured && state.isPresented && state.conversationUrl ? createElement(
1271
- View,
1364
+ state.configured && state.isPresented && state.conversationUrl ? (0, import_react.createElement)(
1365
+ import_react_native.View,
1272
1366
  { style: styles.webOverlay },
1273
- createElement(
1274
- View,
1367
+ (0, import_react.createElement)(
1368
+ import_react_native.View,
1275
1369
  { style: styles.webPanel },
1276
- showCloseButton ? createElement(
1277
- Pressable,
1370
+ showCloseButton ? (0, import_react.createElement)(
1371
+ import_react_native.Pressable,
1278
1372
  {
1279
1373
  accessibilityRole: "button",
1280
1374
  accessibilityLabel: closeLabel,
1281
1375
  onPress: () => internalSagepilotChat.dismiss(),
1282
1376
  style: styles.webCloseButton
1283
1377
  },
1284
- createElement(Text, { style: styles.closeText }, closeLabel)
1378
+ (0, import_react.createElement)(import_react_native.Text, { style: styles.closeText }, closeLabel)
1285
1379
  ) : null,
1286
- createElement("iframe", {
1380
+ (0, import_react.createElement)("iframe", {
1287
1381
  ref: webFrameRef,
1288
1382
  src: state.conversationUrl,
1289
1383
  style: styles.webFrame,
@@ -1294,63 +1388,69 @@ function SagepilotChatProvider({
1294
1388
  ) : null
1295
1389
  );
1296
1390
  }
1297
- return createElement(
1298
- View,
1391
+ return (0, import_react.createElement)(
1392
+ import_react_native.View,
1299
1393
  { style: styles.root },
1300
1394
  children,
1301
- state.configured && !state.isPresented && state.shouldPreload && state.preloadUrl ? createElement(WebView, {
1395
+ state.configured && !state.isPresented && state.shouldPreload && state.preloadUrl ? (0, import_react.createElement)(import_react_native_webview.WebView, {
1302
1396
  ...hostedChatWebViewProps,
1303
1397
  source: { uri: state.preloadUrl },
1304
1398
  style: styles.preloadWebview,
1305
1399
  injectedJavaScriptBeforeContentLoaded: getInjectedWebViewScript(),
1306
1400
  onMessage: handleWebViewMessage
1307
1401
  }) : null,
1308
- createElement(
1309
- Modal,
1402
+ (0, import_react.createElement)(
1403
+ import_react_native.Modal,
1310
1404
  {
1311
1405
  visible: state.configured && state.isPresented,
1312
1406
  animationType,
1313
1407
  presentationStyle: isFullScreenModal ? "fullScreen" : "pageSheet",
1408
+ statusBarTranslucent: import_react_native.Platform.OS === "android",
1409
+ navigationBarTranslucent: import_react_native.Platform.OS === "android",
1314
1410
  onRequestClose: () => internalSagepilotChat.dismiss()
1315
1411
  },
1316
- createElement(
1317
- ModalContainer,
1318
- { style: styles.container },
1319
- showCloseButton ? createElement(
1320
- View,
1321
- { style: styles.header },
1322
- createElement(
1323
- Pressable,
1324
- {
1325
- accessibilityRole: "button",
1326
- accessibilityLabel: closeLabel,
1327
- onPress: () => internalSagepilotChat.dismiss(),
1328
- style: styles.closeButton
1329
- },
1330
- createElement(Text, { style: styles.closeText }, closeLabel)
1331
- )
1332
- ) : null,
1333
- state.conversationUrl ? createElement(WebView, {
1334
- ...hostedChatWebViewProps,
1335
- ref: nativeWebViewRef,
1336
- source: { uri: state.conversationUrl },
1337
- style: styles.webview,
1338
- startInLoadingState: true,
1339
- injectedJavaScriptBeforeContentLoaded: getInjectedWebViewScript(),
1340
- onMessage: handleWebViewMessage,
1341
- onLoadEnd: postIdentityToNativeWebView,
1342
- renderLoading: () => createElement(
1343
- View,
1344
- { style: styles.loading },
1345
- createElement(ActivityIndicator, null),
1346
- createElement(Text, { style: styles.loadingText }, loadingLabel)
1347
- )
1348
- }) : null
1412
+ (0, import_react.createElement)(
1413
+ NativeModalContainer,
1414
+ nativeModalContainerProps,
1415
+ (0, import_react.createElement)(
1416
+ ChatContentContainer,
1417
+ chatContentContainerProps,
1418
+ showCloseButton ? (0, import_react.createElement)(
1419
+ import_react_native.View,
1420
+ { style: styles.header },
1421
+ (0, import_react.createElement)(
1422
+ import_react_native.Pressable,
1423
+ {
1424
+ accessibilityRole: "button",
1425
+ accessibilityLabel: closeLabel,
1426
+ onPress: () => internalSagepilotChat.dismiss(),
1427
+ style: styles.closeButton
1428
+ },
1429
+ (0, import_react.createElement)(import_react_native.Text, { style: styles.closeText }, closeLabel)
1430
+ )
1431
+ ) : null,
1432
+ state.conversationUrl ? (0, import_react.createElement)(import_react_native_webview.WebView, {
1433
+ ...hostedChatWebViewProps,
1434
+ ref: nativeWebViewRef,
1435
+ source: { uri: state.conversationUrl },
1436
+ style: styles.webview,
1437
+ startInLoadingState: true,
1438
+ injectedJavaScriptBeforeContentLoaded: getInjectedWebViewScript(),
1439
+ onMessage: handleWebViewMessage,
1440
+ onLoadEnd: postIdentityToNativeWebView,
1441
+ renderLoading: () => (0, import_react.createElement)(
1442
+ import_react_native.View,
1443
+ { style: styles.loading },
1444
+ (0, import_react.createElement)(import_react_native.ActivityIndicator, null),
1445
+ (0, import_react.createElement)(import_react_native.Text, { style: styles.loadingText }, loadingLabel)
1446
+ )
1447
+ }) : null
1448
+ )
1349
1449
  )
1350
1450
  )
1351
1451
  );
1352
1452
  }
1353
- var styles = StyleSheet.create({
1453
+ var styles = import_react_native.StyleSheet.create({
1354
1454
  root: {
1355
1455
  flex: 1
1356
1456
  },
@@ -1358,6 +1458,11 @@ var styles = StyleSheet.create({
1358
1458
  flex: 1,
1359
1459
  backgroundColor: "#ffffff"
1360
1460
  },
1461
+ modalContent: {
1462
+ flex: 1,
1463
+ width: "100%",
1464
+ backgroundColor: "#ffffff"
1465
+ },
1361
1466
  header: {
1362
1467
  minHeight: 48,
1363
1468
  alignItems: "flex-end",
@@ -1431,7 +1536,7 @@ var styles = StyleSheet.create({
1431
1536
  borderStyle: "none"
1432
1537
  },
1433
1538
  loading: {
1434
- ...StyleSheet.absoluteFillObject,
1539
+ ...import_react_native.StyleSheet.absoluteFillObject,
1435
1540
  alignItems: "center",
1436
1541
  justifyContent: "center",
1437
1542
  backgroundColor: "#ffffff"
@@ -1444,7 +1549,7 @@ var styles = StyleSheet.create({
1444
1549
  });
1445
1550
 
1446
1551
  // src/hooks/useSagepilotChat.ts
1447
- import { useCallback, useEffect as useEffect2, useState as useState2 } from "react";
1552
+ var import_react2 = require("react");
1448
1553
  function readState() {
1449
1554
  const state = SagepilotChat.getState();
1450
1555
  return {
@@ -1456,23 +1561,25 @@ function readState() {
1456
1561
  };
1457
1562
  }
1458
1563
  function useSagepilotChat() {
1459
- const [state, setState] = useState2(readState);
1460
- useEffect2(() => {
1564
+ const [state, setState] = (0, import_react2.useState)(readState);
1565
+ (0, import_react2.useEffect)(() => {
1461
1566
  return SagepilotChat.onStateChange(() => {
1462
1567
  setState(readState());
1463
1568
  });
1464
1569
  }, []);
1465
- const present = useCallback(() => SagepilotChat.present(), []);
1466
- const presentMessages = useCallback(() => SagepilotChat.presentMessages(), []);
1467
- const presentMessageComposer = useCallback((message) => SagepilotChat.presentMessageComposer(message), []);
1468
- const dismiss = useCallback(() => SagepilotChat.dismiss(), []);
1469
- const hide = useCallback(() => SagepilotChat.hide(), []);
1470
- const toggle = useCallback(() => SagepilotChat.toggle(), []);
1471
- const identify = useCallback((identity) => {
1570
+ const present = (0, import_react2.useCallback)(() => SagepilotChat.present(), []);
1571
+ const presentMessages = (0, import_react2.useCallback)(() => SagepilotChat.presentMessages(), []);
1572
+ const presentMessageComposer = (0, import_react2.useCallback)((message, options) => {
1573
+ return SagepilotChat.presentMessageComposer(message, options);
1574
+ }, []);
1575
+ const dismiss = (0, import_react2.useCallback)(() => SagepilotChat.dismiss(), []);
1576
+ const hide = (0, import_react2.useCallback)(() => SagepilotChat.hide(), []);
1577
+ const toggle = (0, import_react2.useCallback)(() => SagepilotChat.toggle(), []);
1578
+ const identify = (0, import_react2.useCallback)((identity) => {
1472
1579
  return SagepilotChat.identify(identity);
1473
1580
  }, []);
1474
- const logout = useCallback(() => SagepilotChat.logout(), []);
1475
- const getUnreadCount = useCallback(() => SagepilotChat.getUnreadCount(), []);
1581
+ const logout = (0, import_react2.useCallback)(() => SagepilotChat.logout(), []);
1582
+ const getUnreadCount = (0, import_react2.useCallback)(() => SagepilotChat.getUnreadCount(), []);
1476
1583
  return {
1477
1584
  ...state,
1478
1585
  present,
@@ -1486,11 +1593,12 @@ function useSagepilotChat() {
1486
1593
  getUnreadCount
1487
1594
  };
1488
1595
  }
1489
- export {
1596
+ // Annotate the CommonJS export names for ESM import in node:
1597
+ 0 && (module.exports = {
1490
1598
  SagepilotChat,
1491
1599
  SagepilotChatError,
1492
1600
  SagepilotChatProvider,
1493
1601
  createAsyncStorageCacheStorage,
1494
1602
  createKeychainTokenStorage,
1495
1603
  useSagepilotChat
1496
- };
1604
+ });