@mobileai/react-native 0.9.10 → 0.9.12
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 +635 -39
- package/lib/module/components/AIAgent.js.map +1 -1
- package/lib/module/components/AgentChatBar.js +309 -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 +44 -15
- 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/services/telemetry/deviceMetadata.js +10 -0
- package/lib/module/services/telemetry/deviceMetadata.js.map +1 -0
- package/lib/module/support/EscalationEventSource.js +168 -0
- package/lib/module/support/EscalationEventSource.js.map +1 -0
- package/lib/module/support/EscalationSocket.js +46 -7
- package/lib/module/support/EscalationSocket.js.map +1 -1
- package/lib/module/support/SupportChatModal.js +544 -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 +45 -13
- package/lib/module/support/escalateTool.js.map +1 -1
- package/lib/module/support/index.js +2 -0
- 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 +2 -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/services/telemetry/deviceMetadata.d.ts +6 -0
- package/lib/typescript/src/services/telemetry/deviceMetadata.d.ts.map +1 -0
- package/lib/typescript/src/support/EscalationEventSource.d.ts +38 -0
- package/lib/typescript/src/support/EscalationEventSource.d.ts.map +1 -0
- 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 +21 -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 +16 -1
- package/lib/typescript/src/support/escalateTool.d.ts.map +1 -1
- package/lib/typescript/src/support/index.d.ts +2 -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 +622 -38
- package/src/components/AgentChatBar.tsx +348 -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 +46 -14
- package/src/services/telemetry/device.ts +88 -11
- package/src/services/telemetry/deviceMetadata.ts +13 -0
- package/src/support/EscalationEventSource.ts +190 -0
- package/src/support/EscalationSocket.ts +47 -8
- package/src/support/SupportChatModal.tsx +563 -0
- package/src/support/TicketStore.ts +100 -0
- package/src/support/escalateTool.ts +53 -13
- package/src/support/index.ts +2 -0
- package/src/support/types.ts +14 -0
|
@@ -12,14 +12,33 @@ import type { ToolDefinition } from '../core/types';
|
|
|
12
12
|
import type { EscalationConfig, EscalationContext } from './types';
|
|
13
13
|
import { EscalationSocket } from './EscalationSocket';
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
import { ENDPOINTS } from '../config/endpoints';
|
|
16
|
+
import { getDeviceId } from '../services/telemetry/device';
|
|
17
|
+
import { getDeviceMetadata } from '../services/telemetry/deviceMetadata';
|
|
18
|
+
import { logger } from '../utils/logger';
|
|
19
|
+
|
|
20
|
+
const MOBILEAI_HOST = ENDPOINTS.escalation;
|
|
16
21
|
|
|
17
22
|
export interface EscalationToolDeps {
|
|
18
23
|
config: EscalationConfig;
|
|
19
24
|
analyticsKey?: string;
|
|
20
25
|
getContext: () => Omit<EscalationContext, 'conversationSummary'>;
|
|
21
26
|
getHistory: () => Array<{ role: string; content: string }>;
|
|
22
|
-
|
|
27
|
+
getScreenFlow?: () => string[];
|
|
28
|
+
onHumanReply?: (reply: string, ticketId?: string) => void;
|
|
29
|
+
onEscalationStarted?: (ticketId: string, socket: EscalationSocket) => void;
|
|
30
|
+
onTypingChange?: (isTyping: boolean) => void;
|
|
31
|
+
onTicketClosed?: (ticketId?: string) => void;
|
|
32
|
+
userContext?: {
|
|
33
|
+
userId?: string;
|
|
34
|
+
name?: string;
|
|
35
|
+
email?: string;
|
|
36
|
+
phone?: string;
|
|
37
|
+
plan?: string;
|
|
38
|
+
custom?: Record<string, string | number | boolean>;
|
|
39
|
+
};
|
|
40
|
+
pushToken?: string;
|
|
41
|
+
pushTokenType?: 'fcm' | 'expo' | 'apns';
|
|
23
42
|
}
|
|
24
43
|
|
|
25
44
|
export function createEscalateTool(deps: EscalationToolDeps): ToolDefinition;
|
|
@@ -44,7 +63,7 @@ export function createEscalateTool(
|
|
|
44
63
|
deps = depsOrConfig as EscalationToolDeps;
|
|
45
64
|
}
|
|
46
65
|
|
|
47
|
-
const { config, analyticsKey, getContext, getHistory, onHumanReply } = deps;
|
|
66
|
+
const { config, analyticsKey, getContext, getHistory, onHumanReply, onEscalationStarted, onTypingChange, onTicketClosed, userContext, pushToken, pushTokenType, getScreenFlow } = deps;
|
|
48
67
|
|
|
49
68
|
// Determine effective provider
|
|
50
69
|
const provider = config.provider ?? (analyticsKey ? 'mobileai' : 'custom');
|
|
@@ -72,10 +91,11 @@ export function createEscalateTool(
|
|
|
72
91
|
|
|
73
92
|
if (provider === 'mobileai') {
|
|
74
93
|
if (!analyticsKey) {
|
|
75
|
-
|
|
94
|
+
logger.warn('Escalation', 'provider=mobileai but no analyticsKey — falling back to custom');
|
|
76
95
|
} else {
|
|
77
96
|
try {
|
|
78
97
|
const history = getHistory().slice(-20); // last 20 messages for context
|
|
98
|
+
logger.info('Escalation', '★★★ Creating ticket — reason:', reason, '| deviceId:', getDeviceId());
|
|
79
99
|
const res = await fetch(`${MOBILEAI_HOST}/api/v1/escalations`, {
|
|
80
100
|
method: 'POST',
|
|
81
101
|
headers: { 'Content-Type': 'application/json' },
|
|
@@ -85,32 +105,52 @@ export function createEscalateTool(
|
|
|
85
105
|
screen: context.currentScreen,
|
|
86
106
|
history,
|
|
87
107
|
stepsBeforeEscalation: context.stepsBeforeEscalation,
|
|
108
|
+
userContext: {
|
|
109
|
+
...userContext,
|
|
110
|
+
device: getDeviceMetadata(),
|
|
111
|
+
},
|
|
112
|
+
screenFlow: getScreenFlow?.() ?? [],
|
|
113
|
+
pushToken,
|
|
114
|
+
pushTokenType,
|
|
115
|
+
deviceId: getDeviceId(),
|
|
88
116
|
}),
|
|
89
117
|
});
|
|
90
118
|
|
|
91
119
|
if (res.ok) {
|
|
92
120
|
const { ticketId, wsUrl } = await res.json();
|
|
93
|
-
|
|
121
|
+
logger.info('Escalation', '★★★ Ticket created:', ticketId, '| wsUrl:', wsUrl);
|
|
94
122
|
|
|
95
123
|
// Connect WebSocket for real-time reply
|
|
96
124
|
socket?.disconnect();
|
|
97
125
|
socket = new EscalationSocket({
|
|
98
|
-
onReply: (reply) => {
|
|
99
|
-
|
|
100
|
-
onHumanReply?.(reply);
|
|
101
|
-
|
|
102
|
-
|
|
126
|
+
onReply: (reply, replyTicketId) => {
|
|
127
|
+
logger.info('Escalation', '★★★ Human reply for ticket', ticketId, ':', reply.substring(0, 80));
|
|
128
|
+
onHumanReply?.(reply, replyTicketId || ticketId);
|
|
129
|
+
},
|
|
130
|
+
onTypingChange: (v) => {
|
|
131
|
+
logger.info('Escalation', '★★★ Agent typing:', v);
|
|
132
|
+
onTypingChange?.(v);
|
|
133
|
+
},
|
|
134
|
+
onTicketClosed: (closedTicketId) => {
|
|
135
|
+
logger.info('Escalation', '★★★ Ticket closed:', ticketId);
|
|
136
|
+
onTicketClosed?.(closedTicketId || ticketId);
|
|
103
137
|
},
|
|
104
138
|
onError: (err) => {
|
|
105
|
-
|
|
139
|
+
logger.error('Escalation', '★★★ WebSocket error:', err);
|
|
106
140
|
},
|
|
107
141
|
});
|
|
108
142
|
socket.connect(wsUrl);
|
|
143
|
+
logger.info('Escalation', '★★★ WebSocket connecting...');
|
|
144
|
+
|
|
145
|
+
// Pass the socket to UI
|
|
146
|
+
logger.info('Escalation', '★★★ Calling onEscalationStarted for ticket:', ticketId);
|
|
147
|
+
onEscalationStarted?.(ticketId, socket);
|
|
148
|
+
logger.info('Escalation', '★★★ onEscalationStarted DONE');
|
|
109
149
|
} else {
|
|
110
|
-
|
|
150
|
+
logger.error('Escalation', 'Failed to create ticket:', res.status);
|
|
111
151
|
}
|
|
112
152
|
} catch (err) {
|
|
113
|
-
|
|
153
|
+
logger.error('Escalation', 'Network error:', (err as Error).message);
|
|
114
154
|
}
|
|
115
155
|
|
|
116
156
|
const message = config.escalationMessage ?? 'Connecting you to a human agent...';
|
package/src/support/index.ts
CHANGED
|
@@ -11,6 +11,7 @@ export type {
|
|
|
11
11
|
CSATConfig,
|
|
12
12
|
CSATRating,
|
|
13
13
|
BusinessHoursConfig,
|
|
14
|
+
SupportTicket,
|
|
14
15
|
} from './types';
|
|
15
16
|
|
|
16
17
|
// Prompt injection
|
|
@@ -20,6 +21,7 @@ export { buildSupportPrompt } from './supportPrompt';
|
|
|
20
21
|
export { createEscalateTool } from './escalateTool';
|
|
21
22
|
export { EscalationSocket } from './EscalationSocket';
|
|
22
23
|
export type { SocketReplyHandler } from './EscalationSocket';
|
|
24
|
+
export { EscalationEventSource } from './EscalationEventSource';
|
|
23
25
|
|
|
24
26
|
// UI Components
|
|
25
27
|
export { SupportGreeting } from './SupportGreeting';
|
package/src/support/types.ts
CHANGED
|
@@ -139,3 +139,17 @@ export interface BusinessHoursConfig {
|
|
|
139
139
|
/** Message shown outside business hours */
|
|
140
140
|
offlineMessage?: string;
|
|
141
141
|
}
|
|
142
|
+
|
|
143
|
+
// ─── Support Ticket ───────────────────────────────────────
|
|
144
|
+
|
|
145
|
+
export interface SupportTicket {
|
|
146
|
+
id: string;
|
|
147
|
+
reason: string;
|
|
148
|
+
screen: string;
|
|
149
|
+
status: string;
|
|
150
|
+
history: Array<{ role: string; content: string; timestamp?: string }>;
|
|
151
|
+
createdAt: string;
|
|
152
|
+
wsUrl: string;
|
|
153
|
+
/** Number of unread messages (computed by backend = history.length - readMessageCount) */
|
|
154
|
+
unreadCount?: number;
|
|
155
|
+
}
|