@mobileai/react-native 0.9.18 → 0.9.20
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/LICENSE +28 -20
- package/MobileAIFloatingOverlay.podspec +25 -0
- package/android/build.gradle +61 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/java/com/mobileai/overlay/FloatingOverlayView.kt +151 -0
- package/android/src/main/java/com/mobileai/overlay/MobileAIOverlayPackage.kt +23 -0
- package/android/src/newarch/com/mobileai/overlay/FloatingOverlayViewManager.kt +45 -0
- package/android/src/oldarch/com/mobileai/overlay/FloatingOverlayViewManager.kt +29 -0
- package/ios/MobileAIFloatingOverlayComponentView.mm +73 -0
- package/lib/module/components/AIAgent.js +902 -136
- package/lib/module/components/AIConsentDialog.js +439 -0
- package/lib/module/components/AgentChatBar.js +828 -134
- package/lib/module/components/AgentOverlay.js +2 -1
- package/lib/module/components/DiscoveryTooltip.js +21 -9
- package/lib/module/components/FloatingOverlayWrapper.js +108 -0
- package/lib/module/components/Icons.js +123 -0
- package/lib/module/config/endpoints.js +12 -2
- package/lib/module/core/AgentRuntime.js +373 -27
- package/lib/module/core/FiberAdapter.js +56 -0
- package/lib/module/core/FiberTreeWalker.js +186 -80
- package/lib/module/core/IdleDetector.js +19 -0
- package/lib/module/core/NativeAlertInterceptor.js +191 -0
- package/lib/module/core/systemPrompt.js +203 -45
- package/lib/module/index.js +3 -0
- package/lib/module/providers/GeminiProvider.js +72 -56
- package/lib/module/providers/ProviderFactory.js +6 -2
- package/lib/module/services/AudioInputService.js +3 -12
- package/lib/module/services/AudioOutputService.js +1 -13
- package/lib/module/services/ConversationService.js +166 -0
- package/lib/module/services/MobileAIKnowledgeRetriever.js +41 -0
- package/lib/module/services/VoiceService.js +29 -8
- package/lib/module/services/telemetry/MobileAI.js +44 -0
- package/lib/module/services/telemetry/TelemetryService.js +13 -1
- package/lib/module/services/telemetry/TouchAutoCapture.js +44 -18
- package/lib/module/specs/FloatingOverlayNativeComponent.ts +19 -0
- package/lib/module/support/CSATSurvey.js +95 -12
- package/lib/module/support/EscalationSocket.js +70 -1
- package/lib/module/support/ReportedIssueEventSource.js +148 -0
- package/lib/module/support/escalateTool.js +4 -2
- package/lib/module/support/index.js +1 -0
- package/lib/module/support/reportIssueTool.js +127 -0
- package/lib/module/support/supportPrompt.js +77 -9
- package/lib/module/tools/guideTool.js +2 -1
- package/lib/module/tools/longPressTool.js +4 -3
- package/lib/module/tools/pickerTool.js +6 -4
- package/lib/module/tools/tapTool.js +12 -3
- package/lib/module/tools/typeTool.js +19 -10
- package/lib/module/utils/logger.js +175 -6
- package/lib/typescript/react-native.config.d.ts +11 -0
- package/lib/typescript/src/components/AIAgent.d.ts +28 -2
- package/lib/typescript/src/components/AIConsentDialog.d.ts +153 -0
- package/lib/typescript/src/components/AgentChatBar.d.ts +15 -2
- package/lib/typescript/src/components/DiscoveryTooltip.d.ts +3 -1
- package/lib/typescript/src/components/FloatingOverlayWrapper.d.ts +51 -0
- package/lib/typescript/src/components/Icons.d.ts +8 -0
- package/lib/typescript/src/config/endpoints.d.ts +5 -3
- package/lib/typescript/src/core/AgentRuntime.d.ts +4 -0
- package/lib/typescript/src/core/FiberAdapter.d.ts +25 -0
- package/lib/typescript/src/core/FiberTreeWalker.d.ts +2 -0
- package/lib/typescript/src/core/IdleDetector.d.ts +11 -0
- package/lib/typescript/src/core/NativeAlertInterceptor.d.ts +55 -0
- package/lib/typescript/src/core/types.d.ts +106 -1
- package/lib/typescript/src/index.d.ts +9 -4
- package/lib/typescript/src/providers/GeminiProvider.d.ts +6 -5
- package/lib/typescript/src/services/ConversationService.d.ts +55 -0
- package/lib/typescript/src/services/MobileAIKnowledgeRetriever.d.ts +9 -0
- package/lib/typescript/src/services/telemetry/MobileAI.d.ts +7 -0
- package/lib/typescript/src/services/telemetry/TelemetryService.d.ts +1 -1
- package/lib/typescript/src/services/telemetry/TouchAutoCapture.d.ts +9 -6
- package/lib/typescript/src/services/telemetry/types.d.ts +3 -1
- package/lib/typescript/src/specs/FloatingOverlayNativeComponent.d.ts +17 -0
- package/lib/typescript/src/support/EscalationSocket.d.ts +17 -0
- package/lib/typescript/src/support/ReportedIssueEventSource.d.ts +24 -0
- package/lib/typescript/src/support/escalateTool.d.ts +5 -0
- package/lib/typescript/src/support/index.d.ts +2 -1
- package/lib/typescript/src/support/reportIssueTool.d.ts +20 -0
- package/lib/typescript/src/support/types.d.ts +56 -1
- package/lib/typescript/src/utils/logger.d.ts +15 -0
- package/package.json +20 -5
- package/react-native.config.js +12 -0
- package/src/specs/FloatingOverlayNativeComponent.ts +19 -0
|
@@ -12,14 +12,16 @@ import { useEffect, useRef } from 'react';
|
|
|
12
12
|
import { View, Text, Pressable, StyleSheet, Animated } from 'react-native';
|
|
13
13
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
14
|
const LABELS = {
|
|
15
|
-
en: '
|
|
16
|
-
ar: '
|
|
15
|
+
en: 'Ask me to find items, answer questions, or complete tasks for you.',
|
|
16
|
+
ar: 'اطلب مني ألاقي العناصر، أجاوب على الأسئلة، أو أكمل المهام عنك.'
|
|
17
17
|
};
|
|
18
18
|
const AUTO_DISMISS_MS = 6000;
|
|
19
19
|
export function DiscoveryTooltip({
|
|
20
20
|
language,
|
|
21
21
|
primaryColor,
|
|
22
|
-
onDismiss
|
|
22
|
+
onDismiss,
|
|
23
|
+
side = 'left',
|
|
24
|
+
message
|
|
23
25
|
}) {
|
|
24
26
|
const scaleAnim = useRef(new Animated.Value(0)).current;
|
|
25
27
|
const opacityAnim = useRef(new Animated.Value(0)).current;
|
|
@@ -57,7 +59,7 @@ export function DiscoveryTooltip({
|
|
|
57
59
|
const isArabic = language === 'ar';
|
|
58
60
|
const bgColor = primaryColor || '#1a1a2e';
|
|
59
61
|
return /*#__PURE__*/_jsxs(Animated.View, {
|
|
60
|
-
style: [styles.container, {
|
|
62
|
+
style: [styles.container, side === 'right' ? styles.containerRight : styles.containerLeft, {
|
|
61
63
|
backgroundColor: bgColor,
|
|
62
64
|
transform: [{
|
|
63
65
|
scale: scaleAnim
|
|
@@ -69,10 +71,10 @@ export function DiscoveryTooltip({
|
|
|
69
71
|
style: styles.contentArea,
|
|
70
72
|
children: /*#__PURE__*/_jsx(Text, {
|
|
71
73
|
style: [styles.text, isArabic && styles.textRTL],
|
|
72
|
-
children: LABELS[language]
|
|
74
|
+
children: message || LABELS[language]
|
|
73
75
|
})
|
|
74
76
|
}), /*#__PURE__*/_jsx(View, {
|
|
75
|
-
style: [styles.pointer, {
|
|
77
|
+
style: [styles.pointer, side === 'right' ? styles.pointerRight : styles.pointerLeft, {
|
|
76
78
|
borderTopColor: bgColor
|
|
77
79
|
}]
|
|
78
80
|
})]
|
|
@@ -82,8 +84,7 @@ const styles = StyleSheet.create({
|
|
|
82
84
|
container: {
|
|
83
85
|
position: 'absolute',
|
|
84
86
|
bottom: 70,
|
|
85
|
-
|
|
86
|
-
minWidth: 200,
|
|
87
|
+
width: 220,
|
|
87
88
|
maxWidth: 260,
|
|
88
89
|
borderRadius: 16,
|
|
89
90
|
paddingHorizontal: 14,
|
|
@@ -97,6 +98,12 @@ const styles = StyleSheet.create({
|
|
|
97
98
|
shadowRadius: 8,
|
|
98
99
|
elevation: 6
|
|
99
100
|
},
|
|
101
|
+
containerLeft: {
|
|
102
|
+
right: -4
|
|
103
|
+
},
|
|
104
|
+
containerRight: {
|
|
105
|
+
left: -4
|
|
106
|
+
},
|
|
100
107
|
contentArea: {
|
|
101
108
|
flexDirection: 'row',
|
|
102
109
|
alignItems: 'center'
|
|
@@ -114,7 +121,6 @@ const styles = StyleSheet.create({
|
|
|
114
121
|
pointer: {
|
|
115
122
|
position: 'absolute',
|
|
116
123
|
bottom: -8,
|
|
117
|
-
right: 22,
|
|
118
124
|
width: 0,
|
|
119
125
|
height: 0,
|
|
120
126
|
borderLeftWidth: 8,
|
|
@@ -123,6 +129,12 @@ const styles = StyleSheet.create({
|
|
|
123
129
|
borderLeftColor: 'transparent',
|
|
124
130
|
borderRightColor: 'transparent',
|
|
125
131
|
borderTopColor: '#1a1a2e'
|
|
132
|
+
},
|
|
133
|
+
pointerLeft: {
|
|
134
|
+
right: 22
|
|
135
|
+
},
|
|
136
|
+
pointerRight: {
|
|
137
|
+
left: 22
|
|
126
138
|
}
|
|
127
139
|
});
|
|
128
140
|
//# sourceMappingURL=DiscoveryTooltip.js.map
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* FloatingOverlayWrapper — Cross-platform elevated overlay.
|
|
5
|
+
*
|
|
6
|
+
* Platform strategy (in priority order):
|
|
7
|
+
*
|
|
8
|
+
* iOS:
|
|
9
|
+
* 1. `FullWindowOverlay` from react-native-screens (optional peer dep).
|
|
10
|
+
* Creates a separate UIWindow at UIWindow.Level.alert+1.
|
|
11
|
+
* Renders ABOVE all native Modals, system alerts, and navigation chrome.
|
|
12
|
+
* 2. Falls back to plain View if react-native-screens is not installed.
|
|
13
|
+
*
|
|
14
|
+
* Android (both Old and New Architecture):
|
|
15
|
+
* 1. Native `MobileAIFloatingOverlay` ViewManager (bundled in this library).
|
|
16
|
+
* Creates a Dialog window with TYPE_APPLICATION_PANEL (z=1000),
|
|
17
|
+
* above normal app Dialog windows (TYPE_APPLICATION, z=2).
|
|
18
|
+
* No SYSTEM_ALERT_WINDOW permission needed — scoped to app's own window.
|
|
19
|
+
* 2. Falls back to plain View if the app hasn't been rebuilt after install
|
|
20
|
+
* (graceful degradation with DEV warning).
|
|
21
|
+
*
|
|
22
|
+
* Usage:
|
|
23
|
+
* <FloatingOverlayWrapper fallbackStyle={styles.floatingLayer}>
|
|
24
|
+
* <View pointerEvents="box-none" style={StyleSheet.absoluteFill}>
|
|
25
|
+
* {chatBar}
|
|
26
|
+
* {consentDialog} ← must be INSIDE the wrapper, AFTER the chat bar in JSX
|
|
27
|
+
* </View>
|
|
28
|
+
* </FloatingOverlayWrapper>
|
|
29
|
+
*
|
|
30
|
+
* Note: FullWindowOverlay on iOS does NOT officially accept style props in its TS definition,
|
|
31
|
+
* but passing StyleSheet.absoluteFill is often necessary to prevent dimensions collapsing conditionally.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
// imports consolidated above
|
|
35
|
+
|
|
36
|
+
// ─── iOS: FullWindowOverlay (react-native-screens optional peer dep) ──────────
|
|
37
|
+
|
|
38
|
+
let FullWindowOverlay = null;
|
|
39
|
+
if (Platform.OS === 'ios') {
|
|
40
|
+
try {
|
|
41
|
+
// Literal string required by Metro bundler — try/catch handles MODULE_NOT_FOUND
|
|
42
|
+
const screens = require('react-native-screens');
|
|
43
|
+
FullWindowOverlay = screens.FullWindowOverlay ?? null;
|
|
44
|
+
} catch {
|
|
45
|
+
// react-native-screens not installed — falls back to View
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// ─── Android: MobileAIFloatingOverlay (native module bundled in this library) ──
|
|
50
|
+
|
|
51
|
+
let NativeFloatingOverlay = null;
|
|
52
|
+
if (Platform.OS === 'android') {
|
|
53
|
+
try {
|
|
54
|
+
const {
|
|
55
|
+
requireNativeComponent
|
|
56
|
+
} = require('react-native');
|
|
57
|
+
// Throws if ViewManager is not registered (app hasn't been rebuilt after install)
|
|
58
|
+
NativeFloatingOverlay = requireNativeComponent('MobileAIFloatingOverlay');
|
|
59
|
+
} catch {
|
|
60
|
+
if (__DEV__) {
|
|
61
|
+
console.warn('[MobileAI] MobileAIFloatingOverlay native module not found on Android.\n' + 'The chat bar may appear behind native Modals.\n' + 'Fix: rebuild the app with `npx react-native run-android` or `npx expo run:android`.');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// ─── Export: whether a true elevated overlay is active ───────────────────────
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* True when a native elevated overlay is available on the current platform.
|
|
70
|
+
* Used by AIConsentDialog to decide whether to render as View vs Modal.
|
|
71
|
+
*
|
|
72
|
+
* iOS + react-native-screens installed → true
|
|
73
|
+
* Android + native rebuild done → true
|
|
74
|
+
* Everything else (fallback) → false
|
|
75
|
+
*/
|
|
76
|
+
export const isNativeOverlayActive = Platform.OS === 'ios' && !!FullWindowOverlay || Platform.OS === 'android' && !!NativeFloatingOverlay;
|
|
77
|
+
|
|
78
|
+
// ─── Component ────────────────────────────────────────────────────────────────
|
|
79
|
+
|
|
80
|
+
import { Platform, View, StyleSheet } from 'react-native';
|
|
81
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
82
|
+
export function FloatingOverlayWrapper({
|
|
83
|
+
children,
|
|
84
|
+
fallbackStyle
|
|
85
|
+
}) {
|
|
86
|
+
// iOS: FullWindowOverlay — separate UIWindow above everything
|
|
87
|
+
if (Platform.OS === 'ios' && FullWindowOverlay) {
|
|
88
|
+
// @ts-ignore - Some versions of react-native-screens don't type 'style'
|
|
89
|
+
return /*#__PURE__*/_jsx(FullWindowOverlay, {
|
|
90
|
+
style: StyleSheet.absoluteFill,
|
|
91
|
+
children: children
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Android: native elevated Dialog window (TYPE_APPLICATION_PANEL)
|
|
96
|
+
if (Platform.OS === 'android' && NativeFloatingOverlay) {
|
|
97
|
+
return /*#__PURE__*/_jsx(NativeFloatingOverlay, {
|
|
98
|
+
children: children
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Fallback: regular View — same behavior as before this overlay feature
|
|
103
|
+
return /*#__PURE__*/_jsx(View, {
|
|
104
|
+
style: fallbackStyle,
|
|
105
|
+
children: children
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=FloatingOverlayWrapper.js.map
|
|
@@ -334,4 +334,127 @@ export function AIBadge({
|
|
|
334
334
|
})]
|
|
335
335
|
});
|
|
336
336
|
}
|
|
337
|
+
// ─── History Icon (clock face: circle + hour + minute hands) ──
|
|
338
|
+
|
|
339
|
+
export function HistoryIcon({
|
|
340
|
+
size = 18,
|
|
341
|
+
color = '#fff'
|
|
342
|
+
}) {
|
|
343
|
+
const half = size / 2;
|
|
344
|
+
const stroke = Math.max(1.5, size * 0.09);
|
|
345
|
+
const ringSize = size * 0.9;
|
|
346
|
+
const minuteLen = half * 0.72; // from center to 12 o'clock
|
|
347
|
+
const hourLen = half * 0.52; // from center to 3 o'clock
|
|
348
|
+
|
|
349
|
+
return /*#__PURE__*/_jsxs(View, {
|
|
350
|
+
style: {
|
|
351
|
+
width: size,
|
|
352
|
+
height: size
|
|
353
|
+
},
|
|
354
|
+
children: [/*#__PURE__*/_jsx(View, {
|
|
355
|
+
style: {
|
|
356
|
+
position: 'absolute',
|
|
357
|
+
width: ringSize,
|
|
358
|
+
height: ringSize,
|
|
359
|
+
borderRadius: ringSize / 2,
|
|
360
|
+
borderWidth: stroke,
|
|
361
|
+
borderColor: color,
|
|
362
|
+
top: (size - ringSize) / 2,
|
|
363
|
+
left: (size - ringSize) / 2
|
|
364
|
+
}
|
|
365
|
+
}), /*#__PURE__*/_jsx(View, {
|
|
366
|
+
style: {
|
|
367
|
+
position: 'absolute',
|
|
368
|
+
width: stroke,
|
|
369
|
+
height: minuteLen,
|
|
370
|
+
backgroundColor: color,
|
|
371
|
+
borderRadius: stroke,
|
|
372
|
+
top: half - minuteLen,
|
|
373
|
+
left: half - stroke / 2
|
|
374
|
+
}
|
|
375
|
+
}), /*#__PURE__*/_jsx(View, {
|
|
376
|
+
style: {
|
|
377
|
+
position: 'absolute',
|
|
378
|
+
width: hourLen,
|
|
379
|
+
height: stroke,
|
|
380
|
+
backgroundColor: color,
|
|
381
|
+
borderRadius: stroke,
|
|
382
|
+
top: half - stroke / 2,
|
|
383
|
+
left: half
|
|
384
|
+
}
|
|
385
|
+
}), /*#__PURE__*/_jsx(View, {
|
|
386
|
+
style: {
|
|
387
|
+
position: 'absolute',
|
|
388
|
+
width: stroke * 2,
|
|
389
|
+
height: stroke * 2,
|
|
390
|
+
borderRadius: stroke,
|
|
391
|
+
backgroundColor: color,
|
|
392
|
+
top: half - stroke,
|
|
393
|
+
left: half - stroke
|
|
394
|
+
}
|
|
395
|
+
})]
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// ─── New Chat Icon (chat bubble + plus) ───────────────────────
|
|
400
|
+
|
|
401
|
+
export function NewChatIcon({
|
|
402
|
+
size = 18,
|
|
403
|
+
color = '#fff'
|
|
404
|
+
}) {
|
|
405
|
+
const stroke = size * 0.1;
|
|
406
|
+
const armLen = size * 0.35;
|
|
407
|
+
return /*#__PURE__*/_jsxs(View, {
|
|
408
|
+
style: {
|
|
409
|
+
width: size,
|
|
410
|
+
height: size,
|
|
411
|
+
alignItems: 'center',
|
|
412
|
+
justifyContent: 'center'
|
|
413
|
+
},
|
|
414
|
+
children: [/*#__PURE__*/_jsx(View, {
|
|
415
|
+
style: {
|
|
416
|
+
position: 'absolute',
|
|
417
|
+
top: 0,
|
|
418
|
+
left: 0,
|
|
419
|
+
width: size * 0.72,
|
|
420
|
+
height: size * 0.62,
|
|
421
|
+
borderRadius: size * 0.15,
|
|
422
|
+
borderWidth: stroke,
|
|
423
|
+
borderColor: color
|
|
424
|
+
}
|
|
425
|
+
}), /*#__PURE__*/_jsx(View, {
|
|
426
|
+
style: {
|
|
427
|
+
position: 'absolute',
|
|
428
|
+
bottom: size * 0.22,
|
|
429
|
+
left: size * 0.1,
|
|
430
|
+
width: 0,
|
|
431
|
+
height: 0,
|
|
432
|
+
borderTopWidth: size * 0.14,
|
|
433
|
+
borderTopColor: color,
|
|
434
|
+
borderRightWidth: size * 0.1,
|
|
435
|
+
borderRightColor: 'transparent'
|
|
436
|
+
}
|
|
437
|
+
}), /*#__PURE__*/_jsx(View, {
|
|
438
|
+
style: {
|
|
439
|
+
position: 'absolute',
|
|
440
|
+
top: size * 0.09,
|
|
441
|
+
right: 0,
|
|
442
|
+
width: armLen,
|
|
443
|
+
height: stroke,
|
|
444
|
+
backgroundColor: color,
|
|
445
|
+
borderRadius: stroke
|
|
446
|
+
}
|
|
447
|
+
}), /*#__PURE__*/_jsx(View, {
|
|
448
|
+
style: {
|
|
449
|
+
position: 'absolute',
|
|
450
|
+
top: size * 0.09 - armLen / 2 + stroke / 2,
|
|
451
|
+
right: armLen / 2 - stroke / 2,
|
|
452
|
+
width: stroke,
|
|
453
|
+
height: armLen,
|
|
454
|
+
backgroundColor: color,
|
|
455
|
+
borderRadius: stroke
|
|
456
|
+
}
|
|
457
|
+
})]
|
|
458
|
+
});
|
|
459
|
+
}
|
|
337
460
|
//# sourceMappingURL=Icons.js.map
|
|
@@ -10,13 +10,23 @@
|
|
|
10
10
|
* to route telemetry through your own backend without touching this file.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
import { Platform } from 'react-native';
|
|
14
|
+
const isDev = typeof __DEV__ !== 'undefined' ? __DEV__ : process.env.NODE_ENV === 'development';
|
|
15
|
+
const getDevLocalhost = () => {
|
|
16
|
+
if (Platform.OS === 'android') {
|
|
17
|
+
return 'http://10.0.2.2:3001';
|
|
18
|
+
}
|
|
19
|
+
return 'http://localhost:3001';
|
|
20
|
+
};
|
|
21
|
+
const MOBILEAI_BASE = process.env.EXPO_PUBLIC_MOBILEAI_BASE_URL || process.env.NEXT_PUBLIC_MOBILEAI_BASE_URL || (isDev ? getDevLocalhost() : 'https://api.mobileai.dev');
|
|
14
22
|
export const ENDPOINTS = {
|
|
15
23
|
/** Telemetry event ingest — receives batched SDK events */
|
|
16
24
|
telemetryIngest: `${MOBILEAI_BASE}/api/v1/events`,
|
|
17
25
|
/** Feature flag sync — fetches remote flags for this analyticsKey */
|
|
18
26
|
featureFlags: `${MOBILEAI_BASE}/api/v1/flags`,
|
|
19
27
|
/** Live agent escalation (support handoff) */
|
|
20
|
-
escalation: `${MOBILEAI_BASE}
|
|
28
|
+
escalation: `${MOBILEAI_BASE}`,
|
|
29
|
+
/** AI conversation history — save and retrieve per-user AI chat sessions */
|
|
30
|
+
conversations: `${MOBILEAI_BASE}/api/v1/conversations`
|
|
21
31
|
};
|
|
22
32
|
//# sourceMappingURL=endpoints.js.map
|