@mobileai/react-native 0.9.10 → 0.9.11
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 +11 -0
- package/lib/module/components/AIAgent.js +513 -36
- package/lib/module/components/AIAgent.js.map +1 -1
- package/lib/module/components/AgentChatBar.js +320 -13
- package/lib/module/components/AgentChatBar.js.map +1 -1
- package/lib/module/config/endpoints.js +22 -0
- package/lib/module/config/endpoints.js.map +1 -0
- package/lib/module/core/systemPrompt.js +126 -100
- package/lib/module/core/systemPrompt.js.map +1 -1
- package/lib/module/services/AudioInputService.js +9 -0
- package/lib/module/services/AudioInputService.js.map +1 -1
- package/lib/module/services/flags/FlagService.js +1 -1
- package/lib/module/services/flags/FlagService.js.map +1 -1
- package/lib/module/services/telemetry/TelemetryService.js +39 -13
- package/lib/module/services/telemetry/TelemetryService.js.map +1 -1
- package/lib/module/services/telemetry/device.js +80 -10
- package/lib/module/services/telemetry/device.js.map +1 -1
- package/lib/module/support/EscalationSocket.js +46 -7
- package/lib/module/support/EscalationSocket.js.map +1 -1
- package/lib/module/support/SupportChatModal.js +516 -0
- package/lib/module/support/SupportChatModal.js.map +1 -0
- package/lib/module/support/TicketStore.js +93 -0
- package/lib/module/support/TicketStore.js.map +1 -0
- package/lib/module/support/escalateTool.js +39 -13
- package/lib/module/support/escalateTool.js.map +1 -1
- package/lib/module/support/index.js.map +1 -1
- package/lib/typescript/src/components/AIAgent.d.ts +24 -1
- package/lib/typescript/src/components/AIAgent.d.ts.map +1 -1
- package/lib/typescript/src/components/AgentChatBar.d.ts +24 -2
- package/lib/typescript/src/components/AgentChatBar.d.ts.map +1 -1
- package/lib/typescript/src/config/endpoints.d.ts +18 -0
- package/lib/typescript/src/config/endpoints.d.ts.map +1 -0
- package/lib/typescript/src/core/systemPrompt.d.ts +4 -13
- package/lib/typescript/src/core/systemPrompt.d.ts.map +1 -1
- package/lib/typescript/src/core/types.d.ts +1 -1
- package/lib/typescript/src/core/types.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useAction.d.ts +2 -2
- package/lib/typescript/src/hooks/useAction.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/services/AudioInputService.d.ts.map +1 -1
- package/lib/typescript/src/services/telemetry/TelemetryService.d.ts.map +1 -1
- package/lib/typescript/src/services/telemetry/device.d.ts +15 -4
- package/lib/typescript/src/services/telemetry/device.d.ts.map +1 -1
- package/lib/typescript/src/support/EscalationSocket.d.ts +7 -1
- package/lib/typescript/src/support/EscalationSocket.d.ts.map +1 -1
- package/lib/typescript/src/support/SupportChatModal.d.ts +19 -0
- package/lib/typescript/src/support/SupportChatModal.d.ts.map +1 -0
- package/lib/typescript/src/support/TicketStore.d.ts +34 -0
- package/lib/typescript/src/support/TicketStore.d.ts.map +1 -0
- package/lib/typescript/src/support/escalateTool.d.ts +15 -1
- package/lib/typescript/src/support/escalateTool.d.ts.map +1 -1
- package/lib/typescript/src/support/index.d.ts +1 -1
- package/lib/typescript/src/support/index.d.ts.map +1 -1
- package/lib/typescript/src/support/types.d.ts +15 -0
- package/lib/typescript/src/support/types.d.ts.map +1 -1
- package/package.json +5 -1
- package/src/components/AIAgent.tsx +507 -36
- package/src/components/AgentChatBar.tsx +355 -9
- package/src/config/endpoints.ts +22 -0
- package/src/core/systemPrompt.ts +126 -100
- package/src/core/types.ts +1 -1
- package/src/hooks/useAction.ts +2 -2
- package/src/index.ts +1 -0
- package/src/services/AudioInputService.ts +9 -0
- package/src/services/flags/FlagService.ts +1 -1
- package/src/services/telemetry/TelemetryService.ts +40 -13
- package/src/services/telemetry/device.ts +88 -11
- package/src/support/EscalationSocket.ts +47 -8
- package/src/support/SupportChatModal.tsx +527 -0
- package/src/support/TicketStore.ts +100 -0
- package/src/support/escalateTool.ts +47 -13
- package/src/support/index.ts +1 -0
- package/src/support/types.ts +14 -0
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
Platform,
|
|
19
19
|
useWindowDimensions,
|
|
20
20
|
} from 'react-native';
|
|
21
|
-
import type { ExecutionResult, AgentMode, ChatBarTheme } from '../core/types';
|
|
21
|
+
import type { ExecutionResult, AgentMode, ChatBarTheme, AIMessage } from '../core/types';
|
|
22
22
|
import {
|
|
23
23
|
MicIcon,
|
|
24
24
|
SpeakerIcon,
|
|
@@ -28,6 +28,8 @@ import {
|
|
|
28
28
|
AIBadge,
|
|
29
29
|
CloseIcon,
|
|
30
30
|
} from './Icons';
|
|
31
|
+
import type { SupportTicket } from '../support/types';
|
|
32
|
+
import { logger } from '../utils/logger';
|
|
31
33
|
|
|
32
34
|
// ─── Props ─────────────────────────────────────────────────────
|
|
33
35
|
|
|
@@ -51,10 +53,31 @@ interface AgentChatBarProps {
|
|
|
51
53
|
isAISpeaking?: boolean;
|
|
52
54
|
/** Voice WebSocket is connected */
|
|
53
55
|
isVoiceConnected?: boolean;
|
|
56
|
+
/** Live human agent is typing */
|
|
57
|
+
/** Live human agent is typing */
|
|
58
|
+
isAgentTyping?: boolean; // used by SupportChatModal via AIAgent
|
|
54
59
|
/** Full session cleanup (stop mic, audio, WebSocket, live mode) */
|
|
55
60
|
onStopSession?: () => void;
|
|
56
61
|
/** Color theme overrides */
|
|
57
62
|
theme?: ChatBarTheme;
|
|
63
|
+
/** Active support tickets (for human mode) */
|
|
64
|
+
tickets?: SupportTicket[];
|
|
65
|
+
/** Currently selected ticket ID */
|
|
66
|
+
selectedTicketId?: string | null;
|
|
67
|
+
/** Callback when user selects a ticket */
|
|
68
|
+
onTicketSelect?: (ticketId: string) => void;
|
|
69
|
+
/** Callback when user goes back to ticket list */
|
|
70
|
+
onBackToTickets?: () => void;
|
|
71
|
+
/** Incremented to trigger auto-expand */
|
|
72
|
+
autoExpandTrigger?: number;
|
|
73
|
+
/** Chat messages for selected ticket */
|
|
74
|
+
chatMessages?: AIMessage[];
|
|
75
|
+
/** The user's original typed query — shown in the result bubble instead of agent reasoning */
|
|
76
|
+
lastUserMessage?: string | null;
|
|
77
|
+
/** Unread message counts per ticket (ticketId -> count) */
|
|
78
|
+
unreadCounts?: Record<string, number>;
|
|
79
|
+
/** Total unread messages across all tickets */
|
|
80
|
+
totalUnread?: number;
|
|
58
81
|
}
|
|
59
82
|
|
|
60
83
|
// ─── Mode Selector ─────────────────────────────────────────────
|
|
@@ -63,16 +86,27 @@ function ModeSelector({
|
|
|
63
86
|
modes,
|
|
64
87
|
activeMode,
|
|
65
88
|
onSelect,
|
|
89
|
+
isArabic = false,
|
|
90
|
+
totalUnread = 0,
|
|
66
91
|
}: {
|
|
67
92
|
modes: AgentMode[];
|
|
68
93
|
activeMode: AgentMode;
|
|
69
94
|
onSelect: (mode: AgentMode) => void;
|
|
95
|
+
isArabic?: boolean;
|
|
96
|
+
totalUnread?: number;
|
|
70
97
|
}) {
|
|
71
98
|
if (modes.length <= 1) return null;
|
|
72
99
|
|
|
73
100
|
const labels: Record<AgentMode, { label: string }> = {
|
|
74
|
-
text:
|
|
75
|
-
voice:
|
|
101
|
+
text: { label: isArabic ? 'نص' : 'Text' },
|
|
102
|
+
voice: { label: isArabic ? 'صوت' : 'Voice' },
|
|
103
|
+
human: { label: isArabic ? 'دعم' : 'Human' },
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const dotColor: Record<AgentMode, string> = {
|
|
107
|
+
text: '#7B68EE',
|
|
108
|
+
voice: '#34C759',
|
|
109
|
+
human: '#FF9500',
|
|
76
110
|
};
|
|
77
111
|
|
|
78
112
|
return (
|
|
@@ -93,7 +127,7 @@ function ModeSelector({
|
|
|
93
127
|
width: 6,
|
|
94
128
|
height: 6,
|
|
95
129
|
borderRadius: 3,
|
|
96
|
-
backgroundColor: mode
|
|
130
|
+
backgroundColor: dotColor[mode],
|
|
97
131
|
}} />
|
|
98
132
|
)}
|
|
99
133
|
<Text
|
|
@@ -104,6 +138,14 @@ function ModeSelector({
|
|
|
104
138
|
>
|
|
105
139
|
{labels[mode].label}
|
|
106
140
|
</Text>
|
|
141
|
+
{/* Unread indicator — inline after label */}
|
|
142
|
+
{mode === 'human' && totalUnread > 0 && (
|
|
143
|
+
<View style={styles.humanTabBadge}>
|
|
144
|
+
<Text style={styles.humanTabBadgeText}>
|
|
145
|
+
{totalUnread > 99 ? '99+' : totalUnread}
|
|
146
|
+
</Text>
|
|
147
|
+
</View>
|
|
148
|
+
)}
|
|
107
149
|
</Pressable>
|
|
108
150
|
))}
|
|
109
151
|
</View>
|
|
@@ -396,12 +438,24 @@ export function AgentChatBar({
|
|
|
396
438
|
isVoiceConnected,
|
|
397
439
|
onStopSession,
|
|
398
440
|
theme,
|
|
441
|
+
tickets = [],
|
|
442
|
+
selectedTicketId,
|
|
443
|
+
onTicketSelect,
|
|
444
|
+
autoExpandTrigger = 0,
|
|
445
|
+
lastUserMessage,
|
|
446
|
+
unreadCounts = {},
|
|
447
|
+
totalUnread = 0,
|
|
399
448
|
}: AgentChatBarProps) {
|
|
400
449
|
const [text, setText] = useState('');
|
|
401
450
|
const [isExpanded, setIsExpanded] = useState(false);
|
|
402
451
|
const { height } = useWindowDimensions();
|
|
403
452
|
const isArabic = language === 'ar';
|
|
404
453
|
|
|
454
|
+
// Auto-expand when triggered (e.g. on escalation)
|
|
455
|
+
useEffect(() => {
|
|
456
|
+
if (autoExpandTrigger > 0) setIsExpanded(true);
|
|
457
|
+
}, [autoExpandTrigger]);
|
|
458
|
+
|
|
405
459
|
const pan = useRef(new Animated.ValueXY({ x: 10, y: height - 200 })).current;
|
|
406
460
|
const keyboardOffset = useRef(new Animated.Value(0)).current;
|
|
407
461
|
|
|
@@ -459,6 +513,14 @@ export function AgentChatBar({
|
|
|
459
513
|
}
|
|
460
514
|
};
|
|
461
515
|
|
|
516
|
+
// ─── HEAVY DEBUG LOGGING ──────────────────────────────────────
|
|
517
|
+
logger.info('ChatBar', '★★★ RENDER — mode:', mode,
|
|
518
|
+
'| selectedTicketId:', selectedTicketId,
|
|
519
|
+
'| tickets:', tickets.length,
|
|
520
|
+
'| availableModes:', availableModes,
|
|
521
|
+
'| lastResult:', lastResult ? lastResult.message.substring(0, 60) : 'null',
|
|
522
|
+
'| isExpanded:', isExpanded);
|
|
523
|
+
|
|
462
524
|
// ─── FAB (Compressed) ──────────────────────────────────────
|
|
463
525
|
|
|
464
526
|
if (!isExpanded) {
|
|
@@ -470,10 +532,18 @@ export function AgentChatBar({
|
|
|
470
532
|
<Pressable
|
|
471
533
|
style={[styles.fab, theme?.primaryColor ? { backgroundColor: theme.primaryColor } : undefined]}
|
|
472
534
|
onPress={() => setIsExpanded(true)}
|
|
473
|
-
accessibilityLabel=
|
|
535
|
+
accessibilityLabel={totalUnread > 0 ? `Open AI Agent Chat - ${totalUnread} unread messages` : 'Open AI Agent Chat'}
|
|
474
536
|
>
|
|
475
537
|
{isThinking ? <LoadingDots size={28} color={theme?.textColor || '#fff'} /> : <AIBadge size={28} />}
|
|
476
538
|
</Pressable>
|
|
539
|
+
{/* Unread badge on collapsed FAB */}
|
|
540
|
+
{totalUnread > 0 && (
|
|
541
|
+
<View style={styles.fabUnreadBadge} pointerEvents="none">
|
|
542
|
+
<Text style={styles.fabUnreadBadgeText}>
|
|
543
|
+
{totalUnread > 99 ? '99+' : totalUnread}
|
|
544
|
+
</Text>
|
|
545
|
+
</View>
|
|
546
|
+
)}
|
|
477
547
|
</Animated.View>
|
|
478
548
|
);
|
|
479
549
|
}
|
|
@@ -500,10 +570,12 @@ export function AgentChatBar({
|
|
|
500
570
|
modes={availableModes}
|
|
501
571
|
activeMode={mode}
|
|
502
572
|
onSelect={(m) => onModeChange?.(m)}
|
|
573
|
+
isArabic={isArabic}
|
|
574
|
+
totalUnread={totalUnread}
|
|
503
575
|
/>
|
|
504
576
|
|
|
505
|
-
{/* Result Bubble */}
|
|
506
|
-
{lastResult && (() => {
|
|
577
|
+
{/* Result Bubble — only show in text/voice modes, NOT in human mode */}
|
|
578
|
+
{lastResult && mode !== 'human' && (() => {
|
|
507
579
|
const cleanMessage = lastResult.message.trim();
|
|
508
580
|
return (
|
|
509
581
|
<View style={[
|
|
@@ -512,8 +584,10 @@ export function AgentChatBar({
|
|
|
512
584
|
? [styles.resultSuccess, theme?.successColor ? { backgroundColor: theme.successColor } : undefined]
|
|
513
585
|
: [styles.resultError, theme?.errorColor ? { backgroundColor: theme.errorColor } : undefined],
|
|
514
586
|
]}>
|
|
515
|
-
|
|
516
|
-
<Text style={[styles.resultText, { textAlign: isArabic ? 'right' : 'left' }, theme?.textColor ? { color: theme.textColor } : undefined]}>
|
|
587
|
+
<ScrollView style={styles.resultScroll} nestedScrollEnabled>
|
|
588
|
+
<Text style={[styles.resultText, { textAlign: isArabic ? 'right' : 'left' }, theme?.textColor ? { color: theme.textColor } : undefined]}>
|
|
589
|
+
{lastUserMessage ?? cleanMessage}
|
|
590
|
+
</Text>
|
|
517
591
|
</ScrollView>
|
|
518
592
|
{onDismiss && (
|
|
519
593
|
<Pressable style={styles.dismissButton} onPress={onDismiss} hitSlop={12}>
|
|
@@ -536,6 +610,47 @@ export function AgentChatBar({
|
|
|
536
610
|
/>
|
|
537
611
|
)}
|
|
538
612
|
|
|
613
|
+
{/* Human mode: ticket list or chat */}
|
|
614
|
+
{mode === 'human' && !selectedTicketId && (
|
|
615
|
+
<ScrollView style={styles.ticketList} nestedScrollEnabled>
|
|
616
|
+
{tickets.length === 0 ? (
|
|
617
|
+
<Text style={styles.emptyText}>No active tickets</Text>
|
|
618
|
+
) : (
|
|
619
|
+
tickets.map(ticket => {
|
|
620
|
+
const unreadCount = unreadCounts[ticket.id] || 0;
|
|
621
|
+
return (
|
|
622
|
+
<Pressable
|
|
623
|
+
key={ticket.id}
|
|
624
|
+
style={styles.ticketCard}
|
|
625
|
+
onPress={() => onTicketSelect?.(ticket.id)}
|
|
626
|
+
>
|
|
627
|
+
<View style={styles.ticketTopRow}>
|
|
628
|
+
<Text style={styles.ticketReason} numberOfLines={2}>
|
|
629
|
+
{ticket.history.length > 0 ? (ticket.history[ticket.history.length - 1]?.content ?? ticket.reason) : ticket.reason}
|
|
630
|
+
</Text>
|
|
631
|
+
{unreadCount > 0 && (
|
|
632
|
+
<View style={styles.unreadBadge}>
|
|
633
|
+
<Text style={styles.unreadBadgeText}>
|
|
634
|
+
{unreadCount > 99 ? '99+' : unreadCount}
|
|
635
|
+
</Text>
|
|
636
|
+
</View>
|
|
637
|
+
)}
|
|
638
|
+
</View>
|
|
639
|
+
<View style={styles.ticketMeta}>
|
|
640
|
+
<Text style={styles.ticketScreen}>{ticket.screen}</Text>
|
|
641
|
+
<Text style={[styles.ticketStatus, ticket.status === 'open' && styles.statusOpen]}>
|
|
642
|
+
{ticket.status}
|
|
643
|
+
</Text>
|
|
644
|
+
</View>
|
|
645
|
+
</Pressable>
|
|
646
|
+
);
|
|
647
|
+
})
|
|
648
|
+
)}
|
|
649
|
+
</ScrollView>
|
|
650
|
+
)}
|
|
651
|
+
|
|
652
|
+
{mode === 'human' && selectedTicketId && null}
|
|
653
|
+
|
|
539
654
|
{mode === 'voice' && (
|
|
540
655
|
<VoiceControlsRow
|
|
541
656
|
isMicActive={isMicActive}
|
|
@@ -549,6 +664,7 @@ export function AgentChatBar({
|
|
|
549
664
|
/>
|
|
550
665
|
)}
|
|
551
666
|
|
|
667
|
+
{/* Voice controls removed since mode handles it */}
|
|
552
668
|
|
|
553
669
|
</Animated.View>
|
|
554
670
|
);
|
|
@@ -693,6 +809,148 @@ const styles = StyleSheet.create({
|
|
|
693
809
|
dictationButtonActive: {
|
|
694
810
|
backgroundColor: 'rgba(255, 59, 48, 0.3)',
|
|
695
811
|
},
|
|
812
|
+
ticketList: {
|
|
813
|
+
maxHeight: 260,
|
|
814
|
+
paddingHorizontal: 12,
|
|
815
|
+
},
|
|
816
|
+
ticketCard: {
|
|
817
|
+
backgroundColor: 'rgba(255, 255, 255, 0.08)',
|
|
818
|
+
borderRadius: 12,
|
|
819
|
+
padding: 14,
|
|
820
|
+
marginBottom: 8,
|
|
821
|
+
},
|
|
822
|
+
ticketTopRow: {
|
|
823
|
+
flexDirection: 'row',
|
|
824
|
+
alignItems: 'flex-start',
|
|
825
|
+
justifyContent: 'space-between',
|
|
826
|
+
gap: 8,
|
|
827
|
+
},
|
|
828
|
+
ticketReason: {
|
|
829
|
+
color: '#fff',
|
|
830
|
+
fontSize: 14,
|
|
831
|
+
fontWeight: '600',
|
|
832
|
+
flex: 1,
|
|
833
|
+
},
|
|
834
|
+
ticketMeta: {
|
|
835
|
+
flexDirection: 'row',
|
|
836
|
+
justifyContent: 'space-between',
|
|
837
|
+
alignItems: 'center',
|
|
838
|
+
marginTop: 6,
|
|
839
|
+
},
|
|
840
|
+
ticketScreen: {
|
|
841
|
+
color: 'rgba(255, 255, 255, 0.5)',
|
|
842
|
+
fontSize: 12,
|
|
843
|
+
},
|
|
844
|
+
ticketStatus: {
|
|
845
|
+
fontSize: 11,
|
|
846
|
+
fontWeight: '600',
|
|
847
|
+
color: 'rgba(255, 255, 255, 0.5)',
|
|
848
|
+
},
|
|
849
|
+
statusOpen: {
|
|
850
|
+
color: '#FF9500',
|
|
851
|
+
},
|
|
852
|
+
emptyText: {
|
|
853
|
+
color: 'rgba(255, 255, 255, 0.4)',
|
|
854
|
+
fontSize: 14,
|
|
855
|
+
textAlign: 'center',
|
|
856
|
+
paddingVertical: 30,
|
|
857
|
+
},
|
|
858
|
+
backBtn: {
|
|
859
|
+
paddingHorizontal: 16,
|
|
860
|
+
paddingVertical: 10,
|
|
861
|
+
},
|
|
862
|
+
backBtnText: {
|
|
863
|
+
color: '#7B68EE',
|
|
864
|
+
fontSize: 14,
|
|
865
|
+
fontWeight: '600',
|
|
866
|
+
},
|
|
867
|
+
chatMessages: {
|
|
868
|
+
maxHeight: 200,
|
|
869
|
+
paddingHorizontal: 12,
|
|
870
|
+
marginBottom: 8,
|
|
871
|
+
},
|
|
872
|
+
msgBubble: {
|
|
873
|
+
borderRadius: 12,
|
|
874
|
+
padding: 10,
|
|
875
|
+
marginBottom: 6,
|
|
876
|
+
maxWidth: '85%',
|
|
877
|
+
},
|
|
878
|
+
msgBubbleUser: {
|
|
879
|
+
backgroundColor: 'rgba(123, 104, 238, 0.3)',
|
|
880
|
+
alignSelf: 'flex-end',
|
|
881
|
+
},
|
|
882
|
+
msgBubbleAgent: {
|
|
883
|
+
backgroundColor: 'rgba(255, 255, 255, 0.1)',
|
|
884
|
+
alignSelf: 'flex-start',
|
|
885
|
+
},
|
|
886
|
+
msgText: {
|
|
887
|
+
color: '#fff',
|
|
888
|
+
fontSize: 13,
|
|
889
|
+
lineHeight: 18,
|
|
890
|
+
},
|
|
891
|
+
typingIndicator: {
|
|
892
|
+
paddingHorizontal: 16,
|
|
893
|
+
paddingBottom: 6,
|
|
894
|
+
},
|
|
895
|
+
typingText: {
|
|
896
|
+
fontSize: 12,
|
|
897
|
+
color: 'rgba(255, 255, 255, 0.4)',
|
|
898
|
+
fontStyle: 'italic',
|
|
899
|
+
},
|
|
900
|
+
unreadBadge: {
|
|
901
|
+
minWidth: 16,
|
|
902
|
+
height: 16,
|
|
903
|
+
borderRadius: 8,
|
|
904
|
+
backgroundColor: '#FF3B30',
|
|
905
|
+
justifyContent: 'center',
|
|
906
|
+
alignItems: 'center',
|
|
907
|
+
paddingHorizontal: 4,
|
|
908
|
+
},
|
|
909
|
+
unreadBadgeText: {
|
|
910
|
+
color: '#fff',
|
|
911
|
+
fontSize: 10,
|
|
912
|
+
fontWeight: '700',
|
|
913
|
+
lineHeight: 16,
|
|
914
|
+
textAlign: 'center',
|
|
915
|
+
},
|
|
916
|
+
humanTabBadge: {
|
|
917
|
+
minWidth: 14,
|
|
918
|
+
height: 14,
|
|
919
|
+
borderRadius: 7,
|
|
920
|
+
backgroundColor: '#FF3B30',
|
|
921
|
+
justifyContent: 'center',
|
|
922
|
+
alignItems: 'center',
|
|
923
|
+
paddingHorizontal: 3,
|
|
924
|
+
marginLeft: 3,
|
|
925
|
+
},
|
|
926
|
+
humanTabBadgeText: {
|
|
927
|
+
color: '#fff',
|
|
928
|
+
fontSize: 8,
|
|
929
|
+
fontWeight: '700',
|
|
930
|
+
lineHeight: 14,
|
|
931
|
+
textAlign: 'center',
|
|
932
|
+
},
|
|
933
|
+
fabUnreadBadge: {
|
|
934
|
+
position: 'absolute',
|
|
935
|
+
top: -2,
|
|
936
|
+
right: -2,
|
|
937
|
+
minWidth: 20,
|
|
938
|
+
height: 20,
|
|
939
|
+
borderRadius: 10,
|
|
940
|
+
backgroundColor: '#FF3B30',
|
|
941
|
+
justifyContent: 'center',
|
|
942
|
+
alignItems: 'center',
|
|
943
|
+
paddingHorizontal: 5,
|
|
944
|
+
borderWidth: 2,
|
|
945
|
+
borderColor: '#1a1a2e',
|
|
946
|
+
},
|
|
947
|
+
fabUnreadBadgeText: {
|
|
948
|
+
color: '#fff',
|
|
949
|
+
fontSize: 11,
|
|
950
|
+
fontWeight: '700',
|
|
951
|
+
lineHeight: 20,
|
|
952
|
+
textAlign: 'center',
|
|
953
|
+
},
|
|
696
954
|
});
|
|
697
955
|
|
|
698
956
|
const modeStyles = StyleSheet.create({
|
|
@@ -783,4 +1041,92 @@ const audioStyles = StyleSheet.create({
|
|
|
783
1041
|
statusDotConnecting: {
|
|
784
1042
|
backgroundColor: '#FFCC00',
|
|
785
1043
|
},
|
|
1044
|
+
humanStatusRow: {
|
|
1045
|
+
flexDirection: 'row',
|
|
1046
|
+
alignItems: 'center',
|
|
1047
|
+
justifyContent: 'center',
|
|
1048
|
+
paddingVertical: 10,
|
|
1049
|
+
gap: 8,
|
|
1050
|
+
},
|
|
1051
|
+
humanStatusDot: {
|
|
1052
|
+
width: 8,
|
|
1053
|
+
height: 8,
|
|
1054
|
+
borderRadius: 4,
|
|
1055
|
+
backgroundColor: '#FF9500',
|
|
1056
|
+
},
|
|
1057
|
+
humanStatusText: {
|
|
1058
|
+
color: '#FF9500',
|
|
1059
|
+
fontSize: 13,
|
|
1060
|
+
fontWeight: '600',
|
|
1061
|
+
},
|
|
1062
|
+
ticketList: {
|
|
1063
|
+
maxHeight: 260,
|
|
1064
|
+
paddingHorizontal: 12,
|
|
1065
|
+
},
|
|
1066
|
+
ticketCard: {
|
|
1067
|
+
backgroundColor: 'rgba(255, 255, 255, 0.08)',
|
|
1068
|
+
borderRadius: 12,
|
|
1069
|
+
padding: 14,
|
|
1070
|
+
marginBottom: 8,
|
|
1071
|
+
},
|
|
1072
|
+
ticketReason: {
|
|
1073
|
+
color: '#fff',
|
|
1074
|
+
fontSize: 14,
|
|
1075
|
+
fontWeight: '600',
|
|
1076
|
+
},
|
|
1077
|
+
ticketMeta: {
|
|
1078
|
+
flexDirection: 'row',
|
|
1079
|
+
justifyContent: 'space-between',
|
|
1080
|
+
alignItems: 'center',
|
|
1081
|
+
marginTop: 6,
|
|
1082
|
+
},
|
|
1083
|
+
ticketScreen: {
|
|
1084
|
+
color: 'rgba(255, 255, 255, 0.5)',
|
|
1085
|
+
fontSize: 12,
|
|
1086
|
+
},
|
|
1087
|
+
ticketStatus: {
|
|
1088
|
+
fontSize: 11,
|
|
1089
|
+
fontWeight: '600',
|
|
1090
|
+
color: 'rgba(255, 255, 255, 0.5)',
|
|
1091
|
+
},
|
|
1092
|
+
statusOpen: {
|
|
1093
|
+
color: '#FF9500',
|
|
1094
|
+
},
|
|
1095
|
+
emptyText: {
|
|
1096
|
+
color: 'rgba(255, 255, 255, 0.4)',
|
|
1097
|
+
fontSize: 14,
|
|
1098
|
+
textAlign: 'center',
|
|
1099
|
+
paddingVertical: 30,
|
|
1100
|
+
},
|
|
1101
|
+
backBtn: {
|
|
1102
|
+
paddingHorizontal: 16,
|
|
1103
|
+
paddingVertical: 10,
|
|
1104
|
+
},
|
|
1105
|
+
backBtnText: {
|
|
1106
|
+
color: '#7B68EE',
|
|
1107
|
+
fontSize: 14,
|
|
1108
|
+
fontWeight: '600',
|
|
1109
|
+
},
|
|
1110
|
+
backRow: {
|
|
1111
|
+
flexDirection: 'row',
|
|
1112
|
+
alignItems: 'center',
|
|
1113
|
+
paddingHorizontal: 12,
|
|
1114
|
+
paddingVertical: 8,
|
|
1115
|
+
borderBottomWidth: 1,
|
|
1116
|
+
borderBottomColor: 'rgba(255, 255, 255, 0.08)',
|
|
1117
|
+
},
|
|
1118
|
+
backText: {
|
|
1119
|
+
color: '#7B68EE',
|
|
1120
|
+
fontSize: 14,
|
|
1121
|
+
fontWeight: '600',
|
|
1122
|
+
},
|
|
1123
|
+
emptyTickets: {
|
|
1124
|
+
alignItems: 'center',
|
|
1125
|
+
justifyContent: 'center',
|
|
1126
|
+
paddingVertical: 40,
|
|
1127
|
+
},
|
|
1128
|
+
emptyTicketsText: {
|
|
1129
|
+
color: 'rgba(255, 255, 255, 0.4)',
|
|
1130
|
+
fontSize: 14,
|
|
1131
|
+
},
|
|
786
1132
|
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SDK Endpoint Configuration
|
|
3
|
+
*
|
|
4
|
+
* All MobileAI backend URLs live here.
|
|
5
|
+
* Change these to point to a self-hosted or staging server.
|
|
6
|
+
*
|
|
7
|
+
* Enterprise customers: use the `analyticsProxyUrl` prop on <AIAgent>
|
|
8
|
+
* to route telemetry through your own backend without touching this file.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const MOBILEAI_BASE = 'http://localhost:3001';
|
|
12
|
+
|
|
13
|
+
export const ENDPOINTS = {
|
|
14
|
+
/** Telemetry event ingest — receives batched SDK events */
|
|
15
|
+
telemetryIngest: `${MOBILEAI_BASE}/api/v1/events`,
|
|
16
|
+
|
|
17
|
+
/** Feature flag sync — fetches remote flags for this analyticsKey */
|
|
18
|
+
featureFlags: `${MOBILEAI_BASE}/api/v1/flags`,
|
|
19
|
+
|
|
20
|
+
/** Live agent escalation (support handoff) */
|
|
21
|
+
escalation: `${MOBILEAI_BASE}`,
|
|
22
|
+
} as const;
|