@sagepilot-ai/react-native-sdk 0.3.0 → 0.3.1

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/README.md CHANGED
@@ -19,7 +19,7 @@ The SDK opens the Sagepilot-hosted chat experience inside a React Native WebView
19
19
  Use this install when your app wants Sagepilot chat without Sagepilot's Android CameraX implementation:
20
20
 
21
21
  ```bash
22
- npm install @sagepilot-ai/react-native-sdk react-native-webview
22
+ npm install @sagepilot-ai/react-native-sdk@latest react-native-webview
23
23
  ```
24
24
 
25
25
  This installs the base SDK only. It includes `SagepilotChat.configure`, hosted chat WebView, auth/session handling, the native bridge, attachment bridge protocol, `SagepilotFilePickerAdapter`, and custom picker support. It does not include CameraX or Android CameraX Gradle dependencies.
@@ -105,9 +105,11 @@ export function App() {
105
105
  Install this addon only when you want Sagepilot's Android in-app CameraX picker. Apps that skip this step keep the smaller base SDK install.
106
106
 
107
107
  ```bash
108
- npm install @sagepilot-ai/react-native-camera-addon
108
+ npm install @sagepilot-ai/react-native-camera-addon@latest
109
109
  ```
110
110
 
111
+ The addon declares `@sagepilot-ai/react-native-sdk` as a peer dependency. Keep the base SDK installed directly in your app; the addon should not be treated as a replacement SDK.
112
+
111
113
  After installing the addon, run a fresh native Android build. A Metro reload is not enough for React Native autolinking to register `NativeModules.SagepilotInAppCamera`.
112
114
 
113
115
  Then pass the addon picker into `SagepilotChat.configure`:
@@ -281,7 +283,7 @@ Configure `filePicker` so the attach button uses native pickers instead. Capture
281
283
  The base package does not include CameraX. Apps that want the smallest install can use only:
282
284
 
283
285
  ```bash
284
- npm install @sagepilot-ai/react-native-sdk react-native-webview
286
+ npm install @sagepilot-ai/react-native-sdk@latest react-native-webview
285
287
  ```
286
288
 
287
289
  ### Optional Android CameraX Addon
@@ -289,9 +291,11 @@ npm install @sagepilot-ai/react-native-sdk react-native-webview
289
291
  Install the CameraX addon only when you want Sagepilot's Android in-app camera implementation:
290
292
 
291
293
  ```bash
292
- npm install @sagepilot-ai/react-native-camera-addon
294
+ npm install @sagepilot-ai/react-native-camera-addon@latest
293
295
  ```
294
296
 
297
+ The addon declares `@sagepilot-ai/react-native-sdk` as a peer dependency. Keep the base SDK installed directly in your app; the addon should not be treated as a replacement SDK.
298
+
295
299
  Run a clean native Android rebuild after installing the addon. If you only Metro-reload, the native module is not linked yet and `createSagepilotCameraXFilePicker()` returns `undefined`, so the hosted widget falls back to the WebView file input.
296
300
 
297
301
  Then configure the addon adapter:
package/dist/index.js CHANGED
@@ -67,7 +67,7 @@ var SagepilotChatError = class extends Error {
67
67
 
68
68
  // src/core/config/constants.ts
69
69
  var SDK_NAME = "@sagepilot-ai/react-native-sdk";
70
- var SDK_VERSION = "0.3.0";
70
+ var SDK_VERSION = "0.3.1";
71
71
  var DEFAULT_HOST = "https://app.sagepilot.ai";
72
72
  var DEFAULT_WIDGET_HOST = "https://app.sagepilot.ai";
73
73
  var CUSTOMER_API_PREFIX = "/customer-api/v1";
@@ -1416,7 +1416,6 @@ var SAGEPILOT_DEFAULT_IMAGE_QUALITY = 0.8;
1416
1416
  var SAGEPILOT_DEFAULT_IMAGE_MAX_FILE_SIZE_BYTES = 15 * 1024 * 1024;
1417
1417
 
1418
1418
  // src/core/native/filePicker.ts
1419
- var DEBUG_PREFIX = "[SagepilotSDK][FilePicker]";
1420
1419
  var DEFAULT_IMAGE_MAX_DIMENSION = SAGEPILOT_DEFAULT_IMAGE_MAX_DIMENSION;
1421
1420
  var DEFAULT_IMAGE_QUALITY = SAGEPILOT_DEFAULT_IMAGE_QUALITY;
1422
1421
  var DEFAULT_IMAGE_MIME_TYPE = "image/jpeg";
@@ -1433,9 +1432,6 @@ function estimateBase64ByteSize(dataBase64) {
1433
1432
  function stripFileScheme(uri) {
1434
1433
  return uri.startsWith("file://") ? uri.replace("file://", "") : uri;
1435
1434
  }
1436
- function debugFilePicker(message, details) {
1437
- console.log(`${DEBUG_PREFIX} ${message}`, details ?? "");
1438
- }
1439
1435
  async function promptOpenSagepilotCameraSettings() {
1440
1436
  if (import_react_native2.Platform.OS !== "android") return;
1441
1437
  await new Promise((resolve) => {
@@ -1462,13 +1458,10 @@ async function ensureSagepilotAndroidCameraPermission() {
1462
1458
  if (import_react_native2.Platform.OS !== "android") return;
1463
1459
  let result;
1464
1460
  try {
1465
- debugFilePicker("requesting Android camera permission");
1466
1461
  result = await import_react_native2.PermissionsAndroid.request(import_react_native2.PermissionsAndroid.PERMISSIONS.CAMERA);
1467
1462
  } catch {
1468
- debugFilePicker("camera permission request threw; continuing to native launch");
1469
1463
  return;
1470
1464
  }
1471
- debugFilePicker("Android camera permission result", { result });
1472
1465
  if (result === import_react_native2.PermissionsAndroid.RESULTS.NEVER_ASK_AGAIN) {
1473
1466
  await promptOpenSagepilotCameraSettings();
1474
1467
  throw new SagepilotFilePickerError(
@@ -1565,13 +1558,6 @@ function createSagepilotFilePicker(options) {
1565
1558
  if (canUseCameraSource(imagePicker)) sources.push("camera");
1566
1559
  if (imagePicker) sources.push("library");
1567
1560
  if (documentsPicker) sources.push("documents");
1568
- debugFilePicker("adapter created", {
1569
- platform: import_react_native2.Platform.OS,
1570
- hasImagePicker: Boolean(imagePicker),
1571
- hasDocumentsPicker: Boolean(documentsPicker),
1572
- hasFileReader: Boolean(fileReader),
1573
- sources
1574
- });
1575
1561
  if (sources.length === 0) return void 0;
1576
1562
  const imageOptions = {
1577
1563
  mediaType: "photo",
@@ -1582,22 +1568,14 @@ function createSagepilotFilePicker(options) {
1582
1568
  saveToPhotos: false
1583
1569
  };
1584
1570
  async function pickFromCamera() {
1585
- debugFilePicker("camera pick requested", {
1586
- platform: import_react_native2.Platform.OS,
1587
- imageMaxDimension,
1588
- imageQuality,
1589
- imageMaxFileSizeBytes
1590
- });
1591
1571
  await ensureSagepilotAndroidCameraPermission();
1592
1572
  if (!imagePicker) {
1593
1573
  throw new SagepilotFilePickerError("camera_unavailable", "The camera picker is not available in this build.");
1594
1574
  }
1595
- debugFilePicker("launching image-picker camera", { platform: import_react_native2.Platform.OS });
1596
1575
  return imageAssetsToPickedFiles(await imagePicker.launchCamera(imageOptions), imageMaxFileSizeBytes);
1597
1576
  }
1598
1577
  async function pickFromLibrary(multiple) {
1599
1578
  if (!imagePicker) return [];
1600
- debugFilePicker("library pick requested", { multiple, imageSelectionLimit });
1601
1579
  return imageAssetsToPickedFiles(await imagePicker.launchImageLibrary({
1602
1580
  ...imageOptions,
1603
1581
  // Bounded multi-select: 0 (unlimited) lets a huge batch OOM the bridge.
@@ -1606,7 +1584,6 @@ function createSagepilotFilePicker(options) {
1606
1584
  }
1607
1585
  async function pickDocuments(multiple) {
1608
1586
  if (!documentsPicker) return [];
1609
- debugFilePicker("document pick requested", { multiple, documentMaxFileSizeBytes });
1610
1587
  let picked;
1611
1588
  try {
1612
1589
  picked = await documentsPicker.pick({ allowMultiSelection: multiple });
@@ -1656,7 +1633,6 @@ function createSagepilotFilePicker(options) {
1656
1633
  return {
1657
1634
  sources,
1658
1635
  async pickFiles(request) {
1659
- debugFilePicker("pickFiles request", request);
1660
1636
  if (request.source === "camera") return pickFromCamera();
1661
1637
  if (request.source === "library") return pickFromLibrary(request.multiple);
1662
1638
  return pickDocuments(request.multiple);
@@ -1877,7 +1853,6 @@ var FILE_PICKER_SOURCE_ICON_COLORS = {
1877
1853
  library: "#16a34a",
1878
1854
  documents: "#7c3aed"
1879
1855
  };
1880
- var DEBUG_PREFIX2 = "[SagepilotSDK][Provider]";
1881
1856
  var DELIVERY_RETRY_MS = 1500;
1882
1857
  var DELIVERY_LEGACY_FALLBACK_ATTEMPTS = 2;
1883
1858
  var DELIVERY_MAX_ATTEMPTS = 8;
@@ -1961,16 +1936,6 @@ function readFilePickerError(error) {
1961
1936
  }
1962
1937
  return { message: "Could not attach the selected file." };
1963
1938
  }
1964
- function debugProvider(message, details) {
1965
- console.log(`${DEBUG_PREFIX2} ${message}`, details ?? "");
1966
- }
1967
- function describeAttachmentTarget(target) {
1968
- return {
1969
- targetChatId: target?.chatId,
1970
- targetRouteChatId: target?.routeChatId,
1971
- targetScreen: target?.hostedChatView.screen
1972
- };
1973
- }
1974
1939
  function getHostedIdentityDispatchScript() {
1975
1940
  const message = internalSagepilotChat.getHostedIdentityMessage();
1976
1941
  if (!message) return "";
@@ -2120,10 +2085,6 @@ function SagepilotChatProvider({
2120
2085
  const batch = pendingBatchesRef.current[0];
2121
2086
  if (!batch) return;
2122
2087
  if (internalSagepilotChat.restoreHostedAttachmentTarget(batch.target)) {
2123
- debugProvider("restored hosted attachment target", {
2124
- batchId: batch.batchId,
2125
- ...describeAttachmentTarget(batch.target)
2126
- });
2127
2088
  widgetReadyRef.current = false;
2128
2089
  deliveryTimerRef.current = setTimeout(() => pumpDelivery(), DELIVERY_RETRY_MS);
2129
2090
  return;
@@ -2133,13 +2094,6 @@ function SagepilotChatProvider({
2133
2094
  const ref = nativeWebViewRef.current;
2134
2095
  const shouldDeliver = ref && (widgetReadyRef.current || attempts >= DELIVERY_LEGACY_FALLBACK_ATTEMPTS);
2135
2096
  if (shouldDeliver && ref) {
2136
- debugProvider("delivering native picked files", {
2137
- batchId: batch.batchId,
2138
- attempt: attempts,
2139
- widgetReady: widgetReadyRef.current,
2140
- count: batch.files.length,
2141
- ...describeAttachmentTarget(batch.target)
2142
- });
2143
2097
  ref.injectJavaScript(buildFilesPickedScript(batch));
2144
2098
  }
2145
2099
  if (attempts < DELIVERY_MAX_ATTEMPTS) {
@@ -2177,21 +2131,12 @@ function SagepilotChatProvider({
2177
2131
  storageKeys,
2178
2132
  target: internalSagepilotChat.getHostedAttachmentTarget()
2179
2133
  };
2180
- debugProvider("queued native picked files", {
2181
- batchId,
2182
- count: files.length,
2183
- totalBase64Bytes: totalBase64Bytes(files),
2184
- persistedToFileStore: hasFileStore,
2185
- ...describeAttachmentTarget(batch.target)
2186
- });
2187
2134
  pendingBatchesRef.current = [...pendingBatchesRef.current, batch];
2188
2135
  ensureDelivery();
2189
2136
  writeManifest();
2190
2137
  void writeBatchBytes(batch);
2191
2138
  }, [ensureDelivery, writeManifest, writeBatchBytes]);
2192
- const recoverNativeWebView = (0, import_react.useCallback)((reasonOrEvent) => {
2193
- const reason = typeof reasonOrEvent === "string" ? reasonOrEvent : "webview_render_process";
2194
- debugProvider("recovering native WebView", { reason });
2139
+ const recoverNativeWebView = (0, import_react.useCallback)((_reasonOrEvent) => {
2195
2140
  widgetReadyRef.current = false;
2196
2141
  setNativeWebViewKey((key) => key + 1);
2197
2142
  }, []);
@@ -2205,31 +2150,14 @@ function SagepilotChatProvider({
2205
2150
  const runNativeFilePicker = (0, import_react.useCallback)((source, multiple) => {
2206
2151
  const filePicker = internalSagepilotChat.getConfig()?.filePicker;
2207
2152
  if (!filePicker) {
2208
- debugProvider("native file picker requested but no adapter is configured", { source, multiple });
2209
2153
  return;
2210
2154
  }
2211
2155
  if (pickerInFlightRef.current) {
2212
- debugProvider("native file picker ignored because another picker is in flight", { source, multiple });
2213
2156
  return;
2214
2157
  }
2215
- debugProvider("native file picker starting", {
2216
- source,
2217
- multiple,
2218
- configuredSources: filePicker.sources
2219
- });
2220
2158
  pauseLivenessAfterPicker(6e4);
2221
2159
  pickerInFlightRef.current = true;
2222
2160
  filePicker.pickFiles({ source, multiple }).then((files) => {
2223
- debugProvider("native file picker resolved", {
2224
- source,
2225
- count: files.length,
2226
- files: files.map((file) => ({
2227
- fileName: file.file_name,
2228
- mimeType: file.mime_type,
2229
- size: file.size,
2230
- base64Length: file.data_base64.length
2231
- }))
2232
- });
2233
2161
  if (files.length === 0) {
2234
2162
  nativeWebViewRef.current?.injectJavaScript(buildFilePickerCancelledScript());
2235
2163
  return;
@@ -2237,7 +2165,6 @@ function SagepilotChatProvider({
2237
2165
  queuePickedFiles(files);
2238
2166
  }).catch((error) => {
2239
2167
  const { message, code } = readFilePickerError(error);
2240
- debugProvider("native file picker failed", { source, code, message });
2241
2168
  nativeWebViewRef.current?.injectJavaScript(buildFilePickerErrorScript(message, code));
2242
2169
  }).finally(() => {
2243
2170
  pickerInFlightRef.current = false;
@@ -2247,14 +2174,8 @@ function SagepilotChatProvider({
2247
2174
  const openNativeFilePicker = (0, import_react.useCallback)((multiple) => {
2248
2175
  const filePicker = internalSagepilotChat.getConfig()?.filePicker;
2249
2176
  if (!filePicker || filePicker.sources.length === 0) {
2250
- debugProvider("open native file picker ignored", {
2251
- multiple,
2252
- hasAdapter: Boolean(filePicker),
2253
- sources: filePicker?.sources ?? []
2254
- });
2255
2177
  return;
2256
2178
  }
2257
- debugProvider("open native file picker", { multiple, sources: filePicker.sources });
2258
2179
  const [onlySource] = filePicker.sources;
2259
2180
  if (filePicker.sources.length === 1 && onlySource && onlySource !== "camera") {
2260
2181
  runNativeFilePicker(onlySource, multiple);
@@ -2364,10 +2285,6 @@ function SagepilotChatProvider({
2364
2285
  const pauseRemainingMs = livenessPausedUntilRef.current - Date.now();
2365
2286
  if (pickerInFlightRef.current || pauseRemainingMs > 0) {
2366
2287
  const retryDelayMs = pickerInFlightRef.current ? 500 : Math.max(0, pauseRemainingMs);
2367
- debugProvider("liveness probe deferred after picker", {
2368
- pickerInFlight: pickerInFlightRef.current,
2369
- retryDelayMs
2370
- });
2371
2288
  clearDeferredLivenessProbe();
2372
2289
  livenessResumeTimerRef.current = setTimeout(() => {
2373
2290
  livenessResumeTimerRef.current = null;
@@ -2452,11 +2369,6 @@ function SagepilotChatProvider({
2452
2369
  const ackBatchId = message.batch_id;
2453
2370
  const head = pendingBatchesRef.current[0];
2454
2371
  if (head && (!ackBatchId || ackBatchId === head.batchId)) {
2455
- debugProvider("native picked files acknowledged", {
2456
- batchId: head.batchId,
2457
- ackBatchId,
2458
- count: message.count
2459
- });
2460
2372
  acknowledgeHeadBatch();
2461
2373
  }
2462
2374
  return;
@@ -2466,10 +2378,6 @@ function SagepilotChatProvider({
2466
2378
  if (pending && (!message.nonce || message.nonce === pending.nonce)) {
2467
2379
  if (message.alive === false) {
2468
2380
  clearPing();
2469
- debugProvider("liveness probe reported dead widget", {
2470
- supportsHeartbeat: message.supportsHeartbeat,
2471
- remountCount: livenessRemountCountRef.current
2472
- });
2473
2381
  if (livenessRemountCountRef.current < LIVENESS_MAX_REMOUNTS) {
2474
2382
  livenessRemountCountRef.current += 1;
2475
2383
  recoverNativeWebView("liveness_dead_pong");
@@ -2499,7 +2407,6 @@ function SagepilotChatProvider({
2499
2407
  nativeWebViewRef.current.injectJavaScript(getInjectedWebViewScript());
2500
2408
  };
2501
2409
  const handleNativeWebViewLoadEnd = () => {
2502
- debugProvider("native WebView load end");
2503
2410
  injectNativeBridgeToNativeWebView();
2504
2411
  postIdentityToNativeWebView();
2505
2412
  widgetReadyRef.current = false;
package/dist/index.mjs CHANGED
@@ -18,7 +18,7 @@ var SagepilotChatError = class extends Error {
18
18
 
19
19
  // src/core/config/constants.ts
20
20
  var SDK_NAME = "@sagepilot-ai/react-native-sdk";
21
- var SDK_VERSION = "0.3.0";
21
+ var SDK_VERSION = "0.3.1";
22
22
  var DEFAULT_HOST = "https://app.sagepilot.ai";
23
23
  var DEFAULT_WIDGET_HOST = "https://app.sagepilot.ai";
24
24
  var CUSTOMER_API_PREFIX = "/customer-api/v1";
@@ -1367,7 +1367,6 @@ var SAGEPILOT_DEFAULT_IMAGE_QUALITY = 0.8;
1367
1367
  var SAGEPILOT_DEFAULT_IMAGE_MAX_FILE_SIZE_BYTES = 15 * 1024 * 1024;
1368
1368
 
1369
1369
  // src/core/native/filePicker.ts
1370
- var DEBUG_PREFIX = "[SagepilotSDK][FilePicker]";
1371
1370
  var DEFAULT_IMAGE_MAX_DIMENSION = SAGEPILOT_DEFAULT_IMAGE_MAX_DIMENSION;
1372
1371
  var DEFAULT_IMAGE_QUALITY = SAGEPILOT_DEFAULT_IMAGE_QUALITY;
1373
1372
  var DEFAULT_IMAGE_MIME_TYPE = "image/jpeg";
@@ -1384,9 +1383,6 @@ function estimateBase64ByteSize(dataBase64) {
1384
1383
  function stripFileScheme(uri) {
1385
1384
  return uri.startsWith("file://") ? uri.replace("file://", "") : uri;
1386
1385
  }
1387
- function debugFilePicker(message, details) {
1388
- console.log(`${DEBUG_PREFIX} ${message}`, details ?? "");
1389
- }
1390
1386
  async function promptOpenSagepilotCameraSettings() {
1391
1387
  if (Platform2.OS !== "android") return;
1392
1388
  await new Promise((resolve) => {
@@ -1413,13 +1409,10 @@ async function ensureSagepilotAndroidCameraPermission() {
1413
1409
  if (Platform2.OS !== "android") return;
1414
1410
  let result;
1415
1411
  try {
1416
- debugFilePicker("requesting Android camera permission");
1417
1412
  result = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.CAMERA);
1418
1413
  } catch {
1419
- debugFilePicker("camera permission request threw; continuing to native launch");
1420
1414
  return;
1421
1415
  }
1422
- debugFilePicker("Android camera permission result", { result });
1423
1416
  if (result === PermissionsAndroid.RESULTS.NEVER_ASK_AGAIN) {
1424
1417
  await promptOpenSagepilotCameraSettings();
1425
1418
  throw new SagepilotFilePickerError(
@@ -1516,13 +1509,6 @@ function createSagepilotFilePicker(options) {
1516
1509
  if (canUseCameraSource(imagePicker)) sources.push("camera");
1517
1510
  if (imagePicker) sources.push("library");
1518
1511
  if (documentsPicker) sources.push("documents");
1519
- debugFilePicker("adapter created", {
1520
- platform: Platform2.OS,
1521
- hasImagePicker: Boolean(imagePicker),
1522
- hasDocumentsPicker: Boolean(documentsPicker),
1523
- hasFileReader: Boolean(fileReader),
1524
- sources
1525
- });
1526
1512
  if (sources.length === 0) return void 0;
1527
1513
  const imageOptions = {
1528
1514
  mediaType: "photo",
@@ -1533,22 +1519,14 @@ function createSagepilotFilePicker(options) {
1533
1519
  saveToPhotos: false
1534
1520
  };
1535
1521
  async function pickFromCamera() {
1536
- debugFilePicker("camera pick requested", {
1537
- platform: Platform2.OS,
1538
- imageMaxDimension,
1539
- imageQuality,
1540
- imageMaxFileSizeBytes
1541
- });
1542
1522
  await ensureSagepilotAndroidCameraPermission();
1543
1523
  if (!imagePicker) {
1544
1524
  throw new SagepilotFilePickerError("camera_unavailable", "The camera picker is not available in this build.");
1545
1525
  }
1546
- debugFilePicker("launching image-picker camera", { platform: Platform2.OS });
1547
1526
  return imageAssetsToPickedFiles(await imagePicker.launchCamera(imageOptions), imageMaxFileSizeBytes);
1548
1527
  }
1549
1528
  async function pickFromLibrary(multiple) {
1550
1529
  if (!imagePicker) return [];
1551
- debugFilePicker("library pick requested", { multiple, imageSelectionLimit });
1552
1530
  return imageAssetsToPickedFiles(await imagePicker.launchImageLibrary({
1553
1531
  ...imageOptions,
1554
1532
  // Bounded multi-select: 0 (unlimited) lets a huge batch OOM the bridge.
@@ -1557,7 +1535,6 @@ function createSagepilotFilePicker(options) {
1557
1535
  }
1558
1536
  async function pickDocuments(multiple) {
1559
1537
  if (!documentsPicker) return [];
1560
- debugFilePicker("document pick requested", { multiple, documentMaxFileSizeBytes });
1561
1538
  let picked;
1562
1539
  try {
1563
1540
  picked = await documentsPicker.pick({ allowMultiSelection: multiple });
@@ -1607,7 +1584,6 @@ function createSagepilotFilePicker(options) {
1607
1584
  return {
1608
1585
  sources,
1609
1586
  async pickFiles(request) {
1610
- debugFilePicker("pickFiles request", request);
1611
1587
  if (request.source === "camera") return pickFromCamera();
1612
1588
  if (request.source === "library") return pickFromLibrary(request.multiple);
1613
1589
  return pickDocuments(request.multiple);
@@ -1840,7 +1816,6 @@ var FILE_PICKER_SOURCE_ICON_COLORS = {
1840
1816
  library: "#16a34a",
1841
1817
  documents: "#7c3aed"
1842
1818
  };
1843
- var DEBUG_PREFIX2 = "[SagepilotSDK][Provider]";
1844
1819
  var DELIVERY_RETRY_MS = 1500;
1845
1820
  var DELIVERY_LEGACY_FALLBACK_ATTEMPTS = 2;
1846
1821
  var DELIVERY_MAX_ATTEMPTS = 8;
@@ -1924,16 +1899,6 @@ function readFilePickerError(error) {
1924
1899
  }
1925
1900
  return { message: "Could not attach the selected file." };
1926
1901
  }
1927
- function debugProvider(message, details) {
1928
- console.log(`${DEBUG_PREFIX2} ${message}`, details ?? "");
1929
- }
1930
- function describeAttachmentTarget(target) {
1931
- return {
1932
- targetChatId: target?.chatId,
1933
- targetRouteChatId: target?.routeChatId,
1934
- targetScreen: target?.hostedChatView.screen
1935
- };
1936
- }
1937
1902
  function getHostedIdentityDispatchScript() {
1938
1903
  const message = internalSagepilotChat.getHostedIdentityMessage();
1939
1904
  if (!message) return "";
@@ -2083,10 +2048,6 @@ function SagepilotChatProvider({
2083
2048
  const batch = pendingBatchesRef.current[0];
2084
2049
  if (!batch) return;
2085
2050
  if (internalSagepilotChat.restoreHostedAttachmentTarget(batch.target)) {
2086
- debugProvider("restored hosted attachment target", {
2087
- batchId: batch.batchId,
2088
- ...describeAttachmentTarget(batch.target)
2089
- });
2090
2051
  widgetReadyRef.current = false;
2091
2052
  deliveryTimerRef.current = setTimeout(() => pumpDelivery(), DELIVERY_RETRY_MS);
2092
2053
  return;
@@ -2096,13 +2057,6 @@ function SagepilotChatProvider({
2096
2057
  const ref = nativeWebViewRef.current;
2097
2058
  const shouldDeliver = ref && (widgetReadyRef.current || attempts >= DELIVERY_LEGACY_FALLBACK_ATTEMPTS);
2098
2059
  if (shouldDeliver && ref) {
2099
- debugProvider("delivering native picked files", {
2100
- batchId: batch.batchId,
2101
- attempt: attempts,
2102
- widgetReady: widgetReadyRef.current,
2103
- count: batch.files.length,
2104
- ...describeAttachmentTarget(batch.target)
2105
- });
2106
2060
  ref.injectJavaScript(buildFilesPickedScript(batch));
2107
2061
  }
2108
2062
  if (attempts < DELIVERY_MAX_ATTEMPTS) {
@@ -2140,21 +2094,12 @@ function SagepilotChatProvider({
2140
2094
  storageKeys,
2141
2095
  target: internalSagepilotChat.getHostedAttachmentTarget()
2142
2096
  };
2143
- debugProvider("queued native picked files", {
2144
- batchId,
2145
- count: files.length,
2146
- totalBase64Bytes: totalBase64Bytes(files),
2147
- persistedToFileStore: hasFileStore,
2148
- ...describeAttachmentTarget(batch.target)
2149
- });
2150
2097
  pendingBatchesRef.current = [...pendingBatchesRef.current, batch];
2151
2098
  ensureDelivery();
2152
2099
  writeManifest();
2153
2100
  void writeBatchBytes(batch);
2154
2101
  }, [ensureDelivery, writeManifest, writeBatchBytes]);
2155
- const recoverNativeWebView = useCallback((reasonOrEvent) => {
2156
- const reason = typeof reasonOrEvent === "string" ? reasonOrEvent : "webview_render_process";
2157
- debugProvider("recovering native WebView", { reason });
2102
+ const recoverNativeWebView = useCallback((_reasonOrEvent) => {
2158
2103
  widgetReadyRef.current = false;
2159
2104
  setNativeWebViewKey((key) => key + 1);
2160
2105
  }, []);
@@ -2168,31 +2113,14 @@ function SagepilotChatProvider({
2168
2113
  const runNativeFilePicker = useCallback((source, multiple) => {
2169
2114
  const filePicker = internalSagepilotChat.getConfig()?.filePicker;
2170
2115
  if (!filePicker) {
2171
- debugProvider("native file picker requested but no adapter is configured", { source, multiple });
2172
2116
  return;
2173
2117
  }
2174
2118
  if (pickerInFlightRef.current) {
2175
- debugProvider("native file picker ignored because another picker is in flight", { source, multiple });
2176
2119
  return;
2177
2120
  }
2178
- debugProvider("native file picker starting", {
2179
- source,
2180
- multiple,
2181
- configuredSources: filePicker.sources
2182
- });
2183
2121
  pauseLivenessAfterPicker(6e4);
2184
2122
  pickerInFlightRef.current = true;
2185
2123
  filePicker.pickFiles({ source, multiple }).then((files) => {
2186
- debugProvider("native file picker resolved", {
2187
- source,
2188
- count: files.length,
2189
- files: files.map((file) => ({
2190
- fileName: file.file_name,
2191
- mimeType: file.mime_type,
2192
- size: file.size,
2193
- base64Length: file.data_base64.length
2194
- }))
2195
- });
2196
2124
  if (files.length === 0) {
2197
2125
  nativeWebViewRef.current?.injectJavaScript(buildFilePickerCancelledScript());
2198
2126
  return;
@@ -2200,7 +2128,6 @@ function SagepilotChatProvider({
2200
2128
  queuePickedFiles(files);
2201
2129
  }).catch((error) => {
2202
2130
  const { message, code } = readFilePickerError(error);
2203
- debugProvider("native file picker failed", { source, code, message });
2204
2131
  nativeWebViewRef.current?.injectJavaScript(buildFilePickerErrorScript(message, code));
2205
2132
  }).finally(() => {
2206
2133
  pickerInFlightRef.current = false;
@@ -2210,14 +2137,8 @@ function SagepilotChatProvider({
2210
2137
  const openNativeFilePicker = useCallback((multiple) => {
2211
2138
  const filePicker = internalSagepilotChat.getConfig()?.filePicker;
2212
2139
  if (!filePicker || filePicker.sources.length === 0) {
2213
- debugProvider("open native file picker ignored", {
2214
- multiple,
2215
- hasAdapter: Boolean(filePicker),
2216
- sources: filePicker?.sources ?? []
2217
- });
2218
2140
  return;
2219
2141
  }
2220
- debugProvider("open native file picker", { multiple, sources: filePicker.sources });
2221
2142
  const [onlySource] = filePicker.sources;
2222
2143
  if (filePicker.sources.length === 1 && onlySource && onlySource !== "camera") {
2223
2144
  runNativeFilePicker(onlySource, multiple);
@@ -2327,10 +2248,6 @@ function SagepilotChatProvider({
2327
2248
  const pauseRemainingMs = livenessPausedUntilRef.current - Date.now();
2328
2249
  if (pickerInFlightRef.current || pauseRemainingMs > 0) {
2329
2250
  const retryDelayMs = pickerInFlightRef.current ? 500 : Math.max(0, pauseRemainingMs);
2330
- debugProvider("liveness probe deferred after picker", {
2331
- pickerInFlight: pickerInFlightRef.current,
2332
- retryDelayMs
2333
- });
2334
2251
  clearDeferredLivenessProbe();
2335
2252
  livenessResumeTimerRef.current = setTimeout(() => {
2336
2253
  livenessResumeTimerRef.current = null;
@@ -2415,11 +2332,6 @@ function SagepilotChatProvider({
2415
2332
  const ackBatchId = message.batch_id;
2416
2333
  const head = pendingBatchesRef.current[0];
2417
2334
  if (head && (!ackBatchId || ackBatchId === head.batchId)) {
2418
- debugProvider("native picked files acknowledged", {
2419
- batchId: head.batchId,
2420
- ackBatchId,
2421
- count: message.count
2422
- });
2423
2335
  acknowledgeHeadBatch();
2424
2336
  }
2425
2337
  return;
@@ -2429,10 +2341,6 @@ function SagepilotChatProvider({
2429
2341
  if (pending && (!message.nonce || message.nonce === pending.nonce)) {
2430
2342
  if (message.alive === false) {
2431
2343
  clearPing();
2432
- debugProvider("liveness probe reported dead widget", {
2433
- supportsHeartbeat: message.supportsHeartbeat,
2434
- remountCount: livenessRemountCountRef.current
2435
- });
2436
2344
  if (livenessRemountCountRef.current < LIVENESS_MAX_REMOUNTS) {
2437
2345
  livenessRemountCountRef.current += 1;
2438
2346
  recoverNativeWebView("liveness_dead_pong");
@@ -2462,7 +2370,6 @@ function SagepilotChatProvider({
2462
2370
  nativeWebViewRef.current.injectJavaScript(getInjectedWebViewScript());
2463
2371
  };
2464
2372
  const handleNativeWebViewLoadEnd = () => {
2465
- debugProvider("native WebView load end");
2466
2373
  injectNativeBridgeToNativeWebView();
2467
2374
  postIdentityToNativeWebView();
2468
2375
  widgetReadyRef.current = false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sagepilot-ai/react-native-sdk",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Sagepilot AI React Native chat SDK",
5
5
  "keywords": [
6
6
  "sagepilot",