@paymanai/payman-ask-sdk 1.0.0

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.
@@ -0,0 +1,1178 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+ var reactNative = require('react-native');
5
+ var paymanTypescriptAskSdk = require('@paymanai/payman-typescript-ask-sdk');
6
+ var lucideReactNative = require('lucide-react-native');
7
+ var jsxRuntime = require('react/jsx-runtime');
8
+ var Animated = require('react-native-reanimated');
9
+ var Markdown = require('react-native-markdown-display');
10
+ var clsx = require('clsx');
11
+ var tailwindMerge = require('tailwind-merge');
12
+
13
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
14
+
15
+ var React__default = /*#__PURE__*/_interopDefault(React);
16
+ var Animated__default = /*#__PURE__*/_interopDefault(Animated);
17
+ var Markdown__default = /*#__PURE__*/_interopDefault(Markdown);
18
+
19
+ // src/components/PaymanChat/index.native.tsx
20
+ var PaymanChatContext = React.createContext(void 0);
21
+ function usePaymanChat() {
22
+ const context = React.useContext(PaymanChatContext);
23
+ if (!context) {
24
+ throw new Error("usePaymanChat must be used within a PaymanChat component");
25
+ }
26
+ return context;
27
+ }
28
+ function ChatInput({
29
+ value,
30
+ onChange,
31
+ onSend,
32
+ onPause,
33
+ disabled = false,
34
+ placeholder = "Type your message...",
35
+ isWaitingForResponse = false,
36
+ hasSelectedSession = true,
37
+ isSessionParamsConfigured = true,
38
+ onClick,
39
+ inputStyle = "rounded",
40
+ layout = "full-width",
41
+ className
42
+ }) {
43
+ const isInputDisabled = disabled || isWaitingForResponse;
44
+ const showPauseButton = isWaitingForResponse && onPause;
45
+ const getPlaceholder = () => {
46
+ if (!hasSelectedSession) {
47
+ return "Select a version to start chatting";
48
+ }
49
+ if (!isSessionParamsConfigured) {
50
+ return "Configure User ID and User Label in Session Params";
51
+ }
52
+ return placeholder;
53
+ };
54
+ return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles.container, layout === "centered" && styles.containerCentered], children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles.wrapper, children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [styles.inputContainer, inputStyle === "rounded" && styles.inputRounded], children: [
55
+ /* @__PURE__ */ jsxRuntime.jsx(
56
+ reactNative.TextInput,
57
+ {
58
+ value,
59
+ onChangeText: onChange,
60
+ onPress: onClick,
61
+ editable: !isInputDisabled,
62
+ placeholder: getPlaceholder(),
63
+ placeholderTextColor: "#999",
64
+ multiline: true,
65
+ style: [
66
+ styles.input,
67
+ isInputDisabled && styles.inputDisabled
68
+ ],
69
+ returnKeyType: "default",
70
+ blurOnSubmit: false
71
+ }
72
+ ),
73
+ showPauseButton ? /* @__PURE__ */ jsxRuntime.jsx(
74
+ reactNative.Pressable,
75
+ {
76
+ onPress: onPause,
77
+ style: ({ pressed }) => [
78
+ styles.button,
79
+ pressed && styles.buttonPressed
80
+ ],
81
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReactNative.Pause, { size: 16, color: "#FFFFFF" })
82
+ }
83
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
84
+ reactNative.Pressable,
85
+ {
86
+ onPress: onSend,
87
+ disabled: isInputDisabled || !value.trim(),
88
+ style: ({ pressed }) => [
89
+ styles.button,
90
+ (isInputDisabled || !value.trim()) && styles.buttonDisabled,
91
+ pressed && styles.buttonPressed
92
+ ],
93
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReactNative.Send, { size: 16, color: "#FFFFFF" })
94
+ }
95
+ )
96
+ ] }) }) });
97
+ }
98
+ var styles = reactNative.StyleSheet.create({
99
+ container: {
100
+ padding: 16,
101
+ width: "100%"
102
+ },
103
+ containerCentered: {
104
+ alignItems: "center"
105
+ },
106
+ wrapper: {
107
+ position: "relative",
108
+ width: "100%",
109
+ maxWidth: 672
110
+ },
111
+ inputContainer: {
112
+ flexDirection: "row",
113
+ alignItems: "flex-end",
114
+ backgroundColor: "#F5F5F5",
115
+ borderWidth: 1,
116
+ borderColor: "#E5E5E5",
117
+ borderRadius: 12,
118
+ overflow: "hidden"
119
+ },
120
+ inputRounded: {
121
+ borderRadius: 24
122
+ },
123
+ input: {
124
+ flex: 1,
125
+ minHeight: 48,
126
+ maxHeight: 200,
127
+ paddingTop: 12,
128
+ paddingBottom: 12,
129
+ paddingLeft: 16,
130
+ paddingRight: 48,
131
+ fontSize: 14,
132
+ color: "#000",
133
+ lineHeight: 20
134
+ },
135
+ inputDisabled: {
136
+ opacity: 0.5
137
+ },
138
+ button: {
139
+ position: "absolute",
140
+ bottom: 8,
141
+ right: 8,
142
+ width: 32,
143
+ height: 32,
144
+ borderRadius: 16,
145
+ backgroundColor: "#007AFF",
146
+ justifyContent: "center",
147
+ alignItems: "center"
148
+ },
149
+ buttonDisabled: {
150
+ opacity: 0.5
151
+ },
152
+ buttonPressed: {
153
+ opacity: 0.8
154
+ }
155
+ });
156
+ function AnimatedLoader({ size = 16, color = "#007AFF" }) {
157
+ const rotation = Animated.useSharedValue(0);
158
+ React__default.default.useEffect(() => {
159
+ rotation.value = Animated.withRepeat(
160
+ Animated.withTiming(360, {
161
+ duration: 1e3,
162
+ easing: Animated.Easing.linear
163
+ }),
164
+ -1
165
+ );
166
+ }, [rotation]);
167
+ const animatedStyle = Animated.useAnimatedStyle(() => {
168
+ return {
169
+ transform: [{ rotate: `${rotation.value}deg` }]
170
+ };
171
+ });
172
+ return /* @__PURE__ */ jsxRuntime.jsx(Animated__default.default.View, { style: animatedStyle, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReactNative.Loader2, { size, color }) });
173
+ }
174
+ function AgentMessage({
175
+ message,
176
+ animated = false,
177
+ showAgentName = false,
178
+ agentName = "Assistant",
179
+ showAvatar = false,
180
+ layout = "full-width",
181
+ showTimestamp = false,
182
+ showExecutionSteps = false,
183
+ showStreamingDot = false,
184
+ streamingStepsText,
185
+ completedStepsText,
186
+ onExecutionTraceClick
187
+ }) {
188
+ const isStreaming = message.isStreaming ?? false;
189
+ const hasSteps = message.steps && message.steps.length > 0;
190
+ const hasTraceData = !!(message.tracingData || message.executionId) && !isStreaming;
191
+ const isError = message.isError ?? (message.streamProgress === "error" || !!message.errorDetails);
192
+ const isCancelled = message.isCancelled ?? false;
193
+ const currentExecutingStepId = message.currentExecutingStepId;
194
+ const [isStepsExpanded, setIsStepsExpanded] = React.useState(
195
+ isStreaming && hasSteps
196
+ );
197
+ React.useEffect(() => {
198
+ if (isStreaming && hasSteps) {
199
+ setIsStepsExpanded(true);
200
+ }
201
+ }, [isStreaming, hasSteps]);
202
+ const totalElapsedMs = hasSteps ? message.steps.reduce((sum, step) => sum + (step.elapsedMs || 0), 0) : 0;
203
+ const currentMessage = message.currentMessage;
204
+ const rawContent = message.streamingContent || message.content || "";
205
+ const content = rawContent.replace(/\\n/g, "\n");
206
+ const getStreamingStepsText = (expanded) => {
207
+ const defaultText = `${expanded ? "Hide" : "View"} progress ({count} ${message.steps.length === 1 ? "step" : "steps"})`;
208
+ const text = streamingStepsText || defaultText;
209
+ const prefix = expanded ? "Hide" : "View";
210
+ return text.replace("{count}", message.steps.length.toString()).replace(/^(View|Hide)/, prefix);
211
+ };
212
+ const getCompletedStepsText = (expanded) => {
213
+ if (completedStepsText) {
214
+ const result = completedStepsText.replace("{count}", message.steps.length.toString()).replace("{time}", (totalElapsedMs / 1e3).toFixed(1));
215
+ return result;
216
+ }
217
+ const prefix = expanded ? "Hide" : "View";
218
+ const stepWord = message.steps.length === 1 ? "step" : "steps";
219
+ return `${prefix} execution steps (${message.steps.length} ${stepWord})`;
220
+ };
221
+ const AnimatedView = animated ? Animated__default.default.View : reactNative.View;
222
+ const animatedProps = animated ? { entering: Animated.FadeInDown.duration(200), layout: Animated.Layout } : {};
223
+ const messageContent = /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles2.container, children: [
224
+ showAvatar && /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles2.avatarContainer, children: isStreaming && showStreamingDot ? (
225
+ // Animated dot indicator while streaming
226
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles2.dotContainer, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles2.dot, styles2.dotPulse] }) })
227
+ ) : (
228
+ // Avatar after completion
229
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles2.avatar, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReactNative.Bot, { size: 16, color: "#666" }) })
230
+ ) }),
231
+ /* @__PURE__ */ jsxRuntime.jsxs(
232
+ reactNative.View,
233
+ {
234
+ style: [
235
+ styles2.messageContainer,
236
+ layout === "centered" && styles2.messageContainerCentered
237
+ ],
238
+ children: [
239
+ /* @__PURE__ */ jsxRuntime.jsxs(
240
+ reactNative.View,
241
+ {
242
+ style: [
243
+ styles2.bubble,
244
+ layout === "centered" && styles2.bubbleCentered,
245
+ hasSteps && styles2.bubbleWithSteps,
246
+ isStreaming && styles2.bubbleStreaming,
247
+ isError && styles2.bubbleError
248
+ ],
249
+ children: [
250
+ showAgentName && /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles2.agentName, children: agentName }),
251
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles2.contentContainer, children: isStreaming && !content ? !showAvatar ? /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles2.thinkingContainer, children: [
252
+ /* @__PURE__ */ jsxRuntime.jsx(AnimatedLoader, { size: 16, color: "#007AFF" }),
253
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles2.thinkingText, children: currentMessage || "Thinking..." })
254
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles2.thinkingText, children: currentMessage || "Thinking..." }) : isCancelled && !content ? !showAvatar ? /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles2.thinkingContainer, children: [
255
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReactNative.X, { size: 16, color: "#666" }),
256
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles2.thinkingText, children: currentMessage || "The request was stopped." })
257
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles2.thinkingText, children: currentMessage || "The request was stopped." }) : /* @__PURE__ */ jsxRuntime.jsx(
258
+ Markdown__default.default,
259
+ {
260
+ style: isError ? markdownErrorStyles : markdownStyles,
261
+ children: content || (isStreaming ? "Thinking..." : isCancelled ? "The request was stopped." : isError ? "Oops, something went wrong. Please try again." : "")
262
+ }
263
+ ) })
264
+ ]
265
+ }
266
+ ),
267
+ showExecutionSteps && hasSteps && !isStreaming && !isError && /* @__PURE__ */ jsxRuntime.jsxs(
268
+ reactNative.View,
269
+ {
270
+ style: [
271
+ styles2.stepsContainer,
272
+ layout === "centered" && styles2.stepsContainerCentered
273
+ ],
274
+ children: [
275
+ /* @__PURE__ */ jsxRuntime.jsxs(
276
+ reactNative.Pressable,
277
+ {
278
+ onPress: () => setIsStepsExpanded(!isStepsExpanded),
279
+ style: styles2.stepsButton,
280
+ children: [
281
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles2.stepsButtonText, children: getCompletedStepsText(isStepsExpanded) }),
282
+ isStepsExpanded ? /* @__PURE__ */ jsxRuntime.jsx(lucideReactNative.ChevronUp, { size: 12, color: "#666" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReactNative.ChevronDown, { size: 12, color: "#666" })
283
+ ]
284
+ }
285
+ ),
286
+ isStepsExpanded && /* @__PURE__ */ jsxRuntime.jsx(
287
+ Animated__default.default.View,
288
+ {
289
+ entering: animated ? Animated.FadeIn.duration(200) : void 0,
290
+ exiting: animated ? Animated.FadeOut.duration(200) : void 0,
291
+ style: styles2.stepsList,
292
+ children: message.steps.map((step, index) => {
293
+ const isCurrentlyExecuting = step.id === currentExecutingStepId && step.status === "in_progress" && isStreaming && !isCancelled;
294
+ return /* @__PURE__ */ jsxRuntime.jsxs(
295
+ Animated__default.default.View,
296
+ {
297
+ entering: animated ? Animated.FadeInUp.duration(300).delay(index * 50) : void 0,
298
+ layout: animated ? Animated.Layout.springify() : void 0,
299
+ style: styles2.stepItem,
300
+ children: [
301
+ isCurrentlyExecuting && /* @__PURE__ */ jsxRuntime.jsx(AnimatedLoader, { size: 12, color: "#007AFF" }),
302
+ step.status === "pending" && isCancelled && /* @__PURE__ */ jsxRuntime.jsx(lucideReactNative.XCircle, { size: 12, color: "#666" }),
303
+ step.status === "pending" && !isCancelled && /* @__PURE__ */ jsxRuntime.jsx(AnimatedLoader, { size: 12, color: "#007AFF" }),
304
+ step.status === "in_progress" && !isCurrentlyExecuting && /* @__PURE__ */ jsxRuntime.jsx(AnimatedLoader, { size: 12, color: "#007AFF" }),
305
+ step.status === "completed" && /* @__PURE__ */ jsxRuntime.jsx(lucideReactNative.Check, { size: 12, color: "#007AFF" }),
306
+ step.status === "error" && /* @__PURE__ */ jsxRuntime.jsx(lucideReactNative.X, { size: 12, color: "#FF3B30" }),
307
+ /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles2.stepContent, children: [
308
+ /* @__PURE__ */ jsxRuntime.jsx(
309
+ reactNative.Text,
310
+ {
311
+ style: [
312
+ styles2.stepText,
313
+ step.status === "error" && styles2.stepTextError
314
+ ],
315
+ children: step.message
316
+ }
317
+ ),
318
+ step.elapsedMs && /* @__PURE__ */ jsxRuntime.jsxs(reactNative.Text, { style: styles2.stepTime, children: [
319
+ "(",
320
+ (step.elapsedMs / 1e3).toFixed(1),
321
+ "s)"
322
+ ] })
323
+ ] })
324
+ ]
325
+ },
326
+ step.id
327
+ );
328
+ })
329
+ }
330
+ )
331
+ ]
332
+ }
333
+ ),
334
+ hasSteps && isStreaming && /* @__PURE__ */ jsxRuntime.jsxs(
335
+ reactNative.View,
336
+ {
337
+ style: [
338
+ styles2.stepsContainer,
339
+ styles2.stepsContainerStreaming,
340
+ layout === "centered" && styles2.stepsContainerCentered
341
+ ],
342
+ children: [
343
+ /* @__PURE__ */ jsxRuntime.jsxs(
344
+ reactNative.Pressable,
345
+ {
346
+ onPress: () => setIsStepsExpanded(!isStepsExpanded),
347
+ style: styles2.stepsButton,
348
+ children: [
349
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles2.stepsButtonText, children: getStreamingStepsText(isStepsExpanded) }),
350
+ isStepsExpanded ? /* @__PURE__ */ jsxRuntime.jsx(lucideReactNative.ChevronUp, { size: 12, color: "#666" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReactNative.ChevronDown, { size: 12, color: "#666" })
351
+ ]
352
+ }
353
+ ),
354
+ isStepsExpanded && /* @__PURE__ */ jsxRuntime.jsx(
355
+ Animated__default.default.View,
356
+ {
357
+ entering: animated ? Animated.FadeIn.duration(200) : void 0,
358
+ exiting: animated ? Animated.FadeOut.duration(200) : void 0,
359
+ style: styles2.stepsList,
360
+ children: message.steps.map((step, index) => {
361
+ const isCurrentlyExecuting = step.id === currentExecutingStepId && step.status === "in_progress" && isStreaming && !isCancelled;
362
+ return /* @__PURE__ */ jsxRuntime.jsxs(
363
+ Animated__default.default.View,
364
+ {
365
+ entering: animated ? Animated.FadeInUp.duration(300).delay(index * 50) : void 0,
366
+ layout: animated ? Animated.Layout.springify() : void 0,
367
+ style: styles2.stepItem,
368
+ children: [
369
+ isCurrentlyExecuting && /* @__PURE__ */ jsxRuntime.jsx(AnimatedLoader, { size: 12, color: "#007AFF" }),
370
+ step.status === "pending" && isCancelled && /* @__PURE__ */ jsxRuntime.jsx(lucideReactNative.XCircle, { size: 12, color: "#666" }),
371
+ step.status === "pending" && !isCancelled && /* @__PURE__ */ jsxRuntime.jsx(AnimatedLoader, { size: 12, color: "#007AFF" }),
372
+ step.status === "in_progress" && !isCurrentlyExecuting && /* @__PURE__ */ jsxRuntime.jsx(AnimatedLoader, { size: 12, color: "#007AFF" }),
373
+ step.status === "completed" && /* @__PURE__ */ jsxRuntime.jsx(lucideReactNative.Check, { size: 12, color: "#007AFF" }),
374
+ step.status === "error" && /* @__PURE__ */ jsxRuntime.jsx(lucideReactNative.X, { size: 12, color: "#FF3B30" }),
375
+ /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles2.stepContent, children: [
376
+ /* @__PURE__ */ jsxRuntime.jsx(
377
+ reactNative.Text,
378
+ {
379
+ style: [
380
+ styles2.stepText,
381
+ step.status === "error" && styles2.stepTextError
382
+ ],
383
+ children: step.message
384
+ }
385
+ ),
386
+ step.elapsedMs && /* @__PURE__ */ jsxRuntime.jsxs(reactNative.Text, { style: styles2.stepTime, children: [
387
+ "(",
388
+ (step.elapsedMs / 1e3).toFixed(1),
389
+ "s)"
390
+ ] })
391
+ ] })
392
+ ]
393
+ },
394
+ step.id
395
+ );
396
+ })
397
+ }
398
+ )
399
+ ]
400
+ }
401
+ )
402
+ ]
403
+ }
404
+ ),
405
+ hasTraceData && onExecutionTraceClick && /* @__PURE__ */ jsxRuntime.jsx(
406
+ reactNative.Pressable,
407
+ {
408
+ onPress: () => onExecutionTraceClick({
409
+ message,
410
+ tracingData: message.tracingData,
411
+ executionId: message.executionId
412
+ }),
413
+ style: styles2.traceButton,
414
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReactNative.Binoculars, { size: 16, color: "#007AFF" })
415
+ }
416
+ )
417
+ ] });
418
+ return /* @__PURE__ */ jsxRuntime.jsx(AnimatedView, { ...animatedProps, children: messageContent });
419
+ }
420
+ var styles2 = reactNative.StyleSheet.create({
421
+ container: {
422
+ flexDirection: "row",
423
+ justifyContent: "flex-start",
424
+ alignItems: "flex-start",
425
+ width: "100%",
426
+ gap: 16
427
+ },
428
+ avatarContainer: {
429
+ width: 32,
430
+ height: 32,
431
+ marginTop: 2
432
+ },
433
+ dotContainer: {
434
+ width: 32,
435
+ height: 32,
436
+ justifyContent: "center",
437
+ alignItems: "center"
438
+ },
439
+ dot: {
440
+ width: 8,
441
+ height: 8,
442
+ borderRadius: 4,
443
+ backgroundColor: "#007AFF"
444
+ },
445
+ dotPulse: {
446
+ opacity: 0.75
447
+ },
448
+ avatar: {
449
+ width: 32,
450
+ height: 32,
451
+ borderRadius: 16,
452
+ backgroundColor: "#F5F5F5",
453
+ justifyContent: "center",
454
+ alignItems: "center"
455
+ },
456
+ messageContainer: {
457
+ minWidth: 0,
458
+ flex: 1,
459
+ maxWidth: "80%"
460
+ },
461
+ messageContainerCentered: {
462
+ maxWidth: "85%"
463
+ },
464
+ bubble: {
465
+ overflow: "hidden",
466
+ width: "100%",
467
+ padding: 12,
468
+ backgroundColor: "#F5F5F5",
469
+ borderRadius: 8
470
+ },
471
+ bubbleCentered: {
472
+ backgroundColor: "#FFFFFF",
473
+ borderWidth: 1,
474
+ borderColor: "#E5E5E5",
475
+ borderRadius: 16,
476
+ borderTopLeftRadius: 4
477
+ },
478
+ bubbleWithSteps: {
479
+ borderBottomLeftRadius: 0,
480
+ borderBottomRightRadius: 0
481
+ },
482
+ bubbleStreaming: {
483
+ borderColor: "#D1D5DB"
484
+ },
485
+ bubbleError: {
486
+ backgroundColor: "#FEE",
487
+ borderColor: "#FCC"
488
+ },
489
+ agentName: {
490
+ fontSize: 12,
491
+ fontWeight: "600",
492
+ opacity: 0.6,
493
+ marginBottom: 6
494
+ },
495
+ contentContainer: {
496
+ fontSize: 14,
497
+ lineHeight: 22
498
+ },
499
+ thinkingContainer: {
500
+ flexDirection: "row",
501
+ alignItems: "center",
502
+ gap: 12
503
+ },
504
+ thinkingText: {
505
+ fontSize: 14,
506
+ color: "#666"
507
+ },
508
+ stepsContainer: {
509
+ overflow: "hidden",
510
+ backgroundColor: "#F5F5F5",
511
+ borderTopWidth: 1,
512
+ borderTopColor: "rgba(0,0,0,0.1)",
513
+ borderBottomLeftRadius: 8,
514
+ borderBottomRightRadius: 8
515
+ },
516
+ stepsContainerCentered: {
517
+ backgroundColor: "#FFFFFF",
518
+ borderWidth: 1,
519
+ borderTopWidth: 0,
520
+ borderColor: "#E5E5E5",
521
+ borderBottomLeftRadius: 16,
522
+ borderBottomRightRadius: 16
523
+ },
524
+ stepsContainerStreaming: {
525
+ borderTopColor: "#D1D5DB"
526
+ },
527
+ stepsButton: {
528
+ width: "100%",
529
+ paddingHorizontal: 16,
530
+ paddingVertical: 8,
531
+ flexDirection: "row",
532
+ justifyContent: "space-between",
533
+ alignItems: "center"
534
+ },
535
+ stepsButtonText: {
536
+ fontSize: 12,
537
+ color: "#666"
538
+ },
539
+ stepsList: {
540
+ paddingHorizontal: 16,
541
+ paddingBottom: 12,
542
+ paddingTop: 8,
543
+ gap: 8,
544
+ backgroundColor: "rgba(0,0,0,0.02)"
545
+ },
546
+ stepItem: {
547
+ flexDirection: "row",
548
+ alignItems: "flex-start",
549
+ gap: 8
550
+ },
551
+ stepContent: {
552
+ flex: 1,
553
+ minWidth: 0
554
+ },
555
+ stepText: {
556
+ fontSize: 12,
557
+ color: "#666",
558
+ flexWrap: "wrap"
559
+ },
560
+ stepTextError: {
561
+ color: "#FF3B30"
562
+ },
563
+ stepTime: {
564
+ fontSize: 10,
565
+ opacity: 0.5,
566
+ marginLeft: 6
567
+ },
568
+ traceButton: {
569
+ marginTop: 2,
570
+ padding: 8,
571
+ backgroundColor: "rgba(255,255,255,0.05)",
572
+ borderWidth: 1,
573
+ borderColor: "rgba(255,255,255,0.2)",
574
+ borderRadius: 8
575
+ }
576
+ });
577
+ var markdownStyles = {
578
+ body: {
579
+ fontSize: 14,
580
+ lineHeight: 22,
581
+ color: "#000"
582
+ },
583
+ paragraph: {
584
+ marginBottom: 12,
585
+ fontSize: 14,
586
+ lineHeight: 22
587
+ },
588
+ strong: {
589
+ fontWeight: "600"
590
+ },
591
+ em: {
592
+ fontStyle: "italic"
593
+ },
594
+ code_inline: {
595
+ backgroundColor: "#F5F5F5",
596
+ paddingHorizontal: 6,
597
+ paddingVertical: 2,
598
+ borderRadius: 4,
599
+ fontSize: 12,
600
+ fontFamily: "monospace"
601
+ },
602
+ code_block: {
603
+ backgroundColor: "#F5F5F5",
604
+ padding: 12,
605
+ borderRadius: 8,
606
+ fontSize: 12,
607
+ fontFamily: "monospace",
608
+ marginVertical: 8
609
+ },
610
+ list_item: {
611
+ fontSize: 14,
612
+ lineHeight: 22
613
+ },
614
+ bullet_list: {
615
+ marginBottom: 12
616
+ },
617
+ ordered_list: {
618
+ marginBottom: 12
619
+ }
620
+ };
621
+ var markdownErrorStyles = {
622
+ ...markdownStyles,
623
+ body: {
624
+ ...markdownStyles.body,
625
+ color: "#FF3B30"
626
+ },
627
+ paragraph: {
628
+ ...markdownStyles.paragraph,
629
+ color: "#FF3B30"
630
+ }
631
+ };
632
+ function cn(...inputs) {
633
+ return tailwindMerge.twMerge(clsx.clsx(inputs));
634
+ }
635
+
636
+ // src/utils/formatDate.ts
637
+ function formatDate(timestamp) {
638
+ const date = typeof timestamp === "string" ? new Date(timestamp) : timestamp;
639
+ const now = /* @__PURE__ */ new Date();
640
+ const diffMs = now.getTime() - date.getTime();
641
+ const diffMins = Math.floor(diffMs / 6e4);
642
+ const diffHours = Math.floor(diffMs / 36e5);
643
+ const diffDays = Math.floor(diffMs / 864e5);
644
+ if (diffMins < 1) {
645
+ return "Just now";
646
+ }
647
+ if (diffMins < 60) {
648
+ return `${diffMins}m ago`;
649
+ }
650
+ if (diffHours < 24) {
651
+ return `${diffHours}h ago`;
652
+ }
653
+ if (diffDays < 7) {
654
+ return `${diffDays}d ago`;
655
+ }
656
+ return date.toLocaleDateString("en-US", {
657
+ month: "short",
658
+ day: "numeric",
659
+ year: date.getFullYear() !== now.getFullYear() ? "numeric" : void 0
660
+ });
661
+ }
662
+ function UserMessage({
663
+ message,
664
+ animated = false,
665
+ showAvatar = false
666
+ }) {
667
+ const AnimatedView = animated ? Animated__default.default.View : reactNative.View;
668
+ const animatedProps = animated ? { entering: Animated.FadeInDown.duration(300) } : {};
669
+ return /* @__PURE__ */ jsxRuntime.jsx(AnimatedView, { ...animatedProps, children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles3.container, children: [
670
+ /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles3.messageContainer, children: [
671
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles3.bubble, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles3.text, children: message.content }) }),
672
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles3.timestamp, children: formatDate(message.timestamp) })
673
+ ] }),
674
+ showAvatar && /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles3.avatarContainer, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles3.avatar, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReactNative.User, { size: 16, color: "#007AFF" }) }) })
675
+ ] }) });
676
+ }
677
+ var styles3 = reactNative.StyleSheet.create({
678
+ container: {
679
+ flexDirection: "row",
680
+ justifyContent: "flex-end",
681
+ width: "100%",
682
+ gap: 16
683
+ },
684
+ messageContainer: {
685
+ maxWidth: "85%",
686
+ minWidth: 0,
687
+ flexDirection: "column",
688
+ alignItems: "flex-end"
689
+ },
690
+ bubble: {
691
+ borderRadius: 8,
692
+ padding: 12,
693
+ backgroundColor: "#007AFF"
694
+ },
695
+ text: {
696
+ fontSize: 14,
697
+ color: "#FFFFFF",
698
+ lineHeight: 20
699
+ },
700
+ timestamp: {
701
+ fontSize: 10,
702
+ marginTop: 4,
703
+ color: "#666"
704
+ },
705
+ avatarContainer: {
706
+ width: 32,
707
+ height: 32,
708
+ marginTop: 2
709
+ },
710
+ avatar: {
711
+ width: 32,
712
+ height: 32,
713
+ borderRadius: 16,
714
+ backgroundColor: "rgba(0, 122, 255, 0.1)",
715
+ justifyContent: "center",
716
+ alignItems: "center"
717
+ }
718
+ });
719
+ function MessageRow({
720
+ message,
721
+ stage = "DEV",
722
+ animated = false,
723
+ showAgentName = false,
724
+ agentName = "Paygent",
725
+ showAvatars = false,
726
+ showUserAvatar,
727
+ showAssistantAvatar,
728
+ showExecutionSteps = false,
729
+ showStreamingDot = false,
730
+ streamingStepsText,
731
+ completedStepsText,
732
+ onExecutionTraceClick
733
+ }) {
734
+ const actualShowUserAvatar = showUserAvatar !== void 0 ? showUserAvatar : showAvatars;
735
+ const actualShowAssistantAvatar = showAssistantAvatar !== void 0 ? showAssistantAvatar : showAvatars;
736
+ if (message.role === "user") {
737
+ return /* @__PURE__ */ jsxRuntime.jsx(
738
+ UserMessage,
739
+ {
740
+ message,
741
+ animated,
742
+ showAvatar: actualShowUserAvatar
743
+ }
744
+ );
745
+ }
746
+ return /* @__PURE__ */ jsxRuntime.jsx(
747
+ AgentMessage,
748
+ {
749
+ message,
750
+ stage,
751
+ animated,
752
+ showAgentName,
753
+ agentName,
754
+ showAvatar: actualShowAssistantAvatar,
755
+ showExecutionSteps,
756
+ showStreamingDot,
757
+ streamingStepsText,
758
+ completedStepsText,
759
+ onExecutionTraceClick
760
+ }
761
+ );
762
+ }
763
+ function MessageRowSkeleton({
764
+ isRightAligned = false
765
+ }) {
766
+ const opacity = Animated.useSharedValue(0.3);
767
+ React.useEffect(() => {
768
+ opacity.value = Animated.withRepeat(
769
+ Animated.withTiming(1, { duration: 1e3 }),
770
+ -1,
771
+ true
772
+ );
773
+ }, []);
774
+ const animatedStyle = Animated.useAnimatedStyle(() => ({
775
+ opacity: opacity.value
776
+ }));
777
+ return /* @__PURE__ */ jsxRuntime.jsx(
778
+ reactNative.View,
779
+ {
780
+ style: [
781
+ styles4.container,
782
+ isRightAligned ? styles4.containerRight : styles4.containerLeft
783
+ ],
784
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
785
+ reactNative.View,
786
+ {
787
+ style: [
788
+ styles4.content,
789
+ isRightAligned ? styles4.contentRight : styles4.contentLeft
790
+ ],
791
+ children: [
792
+ /* @__PURE__ */ jsxRuntime.jsx(
793
+ reactNative.View,
794
+ {
795
+ style: [
796
+ styles4.bubble,
797
+ isRightAligned ? styles4.bubbleRight : styles4.bubbleLeft
798
+ ],
799
+ children: /* @__PURE__ */ jsxRuntime.jsx(Animated__default.default.View, { style: animatedStyle, children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles4.skeletonContainer, children: [
800
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles4.skeletonLine, { width: "75%" }] }),
801
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles4.skeletonLine, { width: "100%" }] }),
802
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles4.skeletonLine, { width: "85%" }] })
803
+ ] }) })
804
+ }
805
+ ),
806
+ /* @__PURE__ */ jsxRuntime.jsx(Animated__default.default.View, { style: [styles4.timestamp, animatedStyle] })
807
+ ]
808
+ }
809
+ )
810
+ }
811
+ );
812
+ }
813
+ var styles4 = reactNative.StyleSheet.create({
814
+ container: {
815
+ flexDirection: "row",
816
+ width: "100%"
817
+ },
818
+ containerLeft: {
819
+ justifyContent: "flex-start"
820
+ },
821
+ containerRight: {
822
+ justifyContent: "flex-end"
823
+ },
824
+ content: {
825
+ maxWidth: "80%",
826
+ width: "100%"
827
+ },
828
+ contentLeft: {
829
+ alignItems: "flex-start"
830
+ },
831
+ contentRight: {
832
+ alignItems: "flex-end"
833
+ },
834
+ bubble: {
835
+ borderRadius: 8,
836
+ padding: 12,
837
+ width: "100%"
838
+ },
839
+ bubbleLeft: {
840
+ backgroundColor: "#F5F5F5"
841
+ },
842
+ bubbleRight: {
843
+ backgroundColor: "rgba(0, 122, 255, 0.2)"
844
+ },
845
+ skeletonContainer: {
846
+ gap: 8
847
+ },
848
+ skeletonLine: {
849
+ height: 12,
850
+ backgroundColor: "rgba(0, 0, 0, 0.2)",
851
+ borderRadius: 4
852
+ },
853
+ timestamp: {
854
+ height: 8,
855
+ width: 64,
856
+ backgroundColor: "rgba(0, 0, 0, 0.2)",
857
+ borderRadius: 4,
858
+ marginTop: 4
859
+ }
860
+ });
861
+ function MessageList({
862
+ messages,
863
+ isLoading = false,
864
+ emptyStateText = "What can I help with?",
865
+ showEmptyStateIcon = true,
866
+ layout = "full-width",
867
+ showTimestamps = false,
868
+ stage = "DEV",
869
+ animated = false,
870
+ showAgentName = false,
871
+ agentName = "Paygent",
872
+ showAvatars = false,
873
+ showUserAvatar,
874
+ showAssistantAvatar,
875
+ showExecutionSteps = false,
876
+ showStreamingDot = false,
877
+ streamingStepsText,
878
+ completedStepsText,
879
+ onExecutionTraceClick,
880
+ className
881
+ }) {
882
+ const flatListRef = React.useRef(null);
883
+ React.useEffect(() => {
884
+ if (messages.length > 0) {
885
+ setTimeout(() => {
886
+ flatListRef.current?.scrollToEnd({ animated: true });
887
+ }, 100);
888
+ }
889
+ }, [messages.length]);
890
+ if (isLoading) {
891
+ return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles5.container, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles5.content, children: Array.from({ length: 6 }).map((_, index) => /* @__PURE__ */ jsxRuntime.jsx(
892
+ MessageRowSkeleton,
893
+ {
894
+ isRightAligned: index % 3 === 0
895
+ },
896
+ `skeleton-${index}`
897
+ )) }) });
898
+ }
899
+ if (messages.length === 0) {
900
+ return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles5.emptyContainer, children: /* @__PURE__ */ jsxRuntime.jsxs(
901
+ Animated__default.default.View,
902
+ {
903
+ entering: Animated.FadeIn.duration(500),
904
+ style: styles5.emptyContent,
905
+ children: [
906
+ showEmptyStateIcon && /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles5.iconContainer, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReactNative.Bot, { size: 24, color: "#999" }) }),
907
+ emptyStateText.split("\n").map((line, index) => /* @__PURE__ */ jsxRuntime.jsx(
908
+ reactNative.Text,
909
+ {
910
+ style: [
911
+ index === 0 ? layout === "centered" ? styles5.emptyTitle : styles5.emptyTitleDefault : styles5.emptySubtitle
912
+ ],
913
+ children: line
914
+ },
915
+ index
916
+ ))
917
+ ]
918
+ }
919
+ ) });
920
+ }
921
+ return /* @__PURE__ */ jsxRuntime.jsx(
922
+ reactNative.FlatList,
923
+ {
924
+ ref: flatListRef,
925
+ data: messages,
926
+ keyExtractor: (item) => item.id,
927
+ renderItem: ({ item }) => /* @__PURE__ */ jsxRuntime.jsx(
928
+ MessageRow,
929
+ {
930
+ message: item,
931
+ stage,
932
+ animated,
933
+ showAgentName,
934
+ agentName,
935
+ showAvatars,
936
+ showUserAvatar,
937
+ showAssistantAvatar,
938
+ showExecutionSteps,
939
+ showStreamingDot,
940
+ streamingStepsText,
941
+ completedStepsText,
942
+ onExecutionTraceClick
943
+ }
944
+ ),
945
+ contentContainerStyle: [
946
+ styles5.listContent,
947
+ layout === "centered" && styles5.listContentCentered
948
+ ],
949
+ showsVerticalScrollIndicator: true
950
+ }
951
+ );
952
+ }
953
+ var styles5 = reactNative.StyleSheet.create({
954
+ container: {
955
+ flex: 1
956
+ },
957
+ content: {
958
+ padding: 16,
959
+ gap: 16
960
+ },
961
+ emptyContainer: {
962
+ flex: 1,
963
+ justifyContent: "center",
964
+ alignItems: "center",
965
+ padding: 16
966
+ },
967
+ emptyContent: {
968
+ alignItems: "center",
969
+ gap: 16
970
+ },
971
+ iconContainer: {
972
+ width: 48,
973
+ height: 48,
974
+ justifyContent: "center",
975
+ alignItems: "center"
976
+ },
977
+ emptyTitle: {
978
+ fontSize: 24,
979
+ fontWeight: "600",
980
+ color: "#007AFF",
981
+ textAlign: "center"
982
+ },
983
+ emptyTitleDefault: {
984
+ fontSize: 24,
985
+ fontWeight: "600",
986
+ color: "#000",
987
+ textAlign: "center"
988
+ },
989
+ emptySubtitle: {
990
+ fontSize: 14,
991
+ color: "#999",
992
+ textAlign: "center"
993
+ },
994
+ listContent: {
995
+ padding: 16,
996
+ gap: 16
997
+ },
998
+ listContentCentered: {
999
+ maxWidth: 672,
1000
+ alignSelf: "center",
1001
+ width: "100%"
1002
+ }
1003
+ });
1004
+ function PaymanChat({
1005
+ config,
1006
+ callbacks = {},
1007
+ className,
1008
+ style,
1009
+ children
1010
+ }) {
1011
+ const [inputValue, setInputValue] = React.useState("");
1012
+ const {
1013
+ messages,
1014
+ sendMessage,
1015
+ isWaitingForResponse,
1016
+ resetSession,
1017
+ clearMessages,
1018
+ cancelStream,
1019
+ getSessionId,
1020
+ getMessages
1021
+ } = paymanTypescriptAskSdk.useChat(config, callbacks);
1022
+ const contextValue = React.useMemo(
1023
+ () => ({
1024
+ resetSession,
1025
+ clearMessages,
1026
+ cancelStream,
1027
+ getSessionId,
1028
+ getMessages,
1029
+ isWaitingForResponse
1030
+ }),
1031
+ [
1032
+ resetSession,
1033
+ clearMessages,
1034
+ cancelStream,
1035
+ getSessionId,
1036
+ getMessages,
1037
+ isWaitingForResponse
1038
+ ]
1039
+ );
1040
+ const { onExecutionTraceClick } = callbacks;
1041
+ const {
1042
+ placeholder = "Type your message...",
1043
+ emptyStateText = "What can I help with?",
1044
+ sessionParams,
1045
+ disableInput = false,
1046
+ hasAskPermission = true,
1047
+ streamingStepsText,
1048
+ completedStepsText,
1049
+ showAvatars = false,
1050
+ showUserAvatar,
1051
+ showAssistantAvatar,
1052
+ showAgentName = true,
1053
+ agentName = "Assistant",
1054
+ showExecutionSteps = true,
1055
+ showStreamingDot = true,
1056
+ layout = "full-width",
1057
+ showTimestamps = false,
1058
+ animated = true,
1059
+ isChatDisabled = false,
1060
+ disabledComponent,
1061
+ showEmptyStateIcon = true,
1062
+ inputStyle = "rounded"
1063
+ } = config;
1064
+ const isSessionParamsConfigured = React.useMemo(() => {
1065
+ if (!sessionParams) return false;
1066
+ return !!(sessionParams.id?.trim() && sessionParams.name?.trim());
1067
+ }, [sessionParams?.id, sessionParams?.name]);
1068
+ const handleSend = () => {
1069
+ if (inputValue.trim() && !disableInput && isSessionParamsConfigured) {
1070
+ sendMessage(inputValue.trim());
1071
+ setInputValue("");
1072
+ }
1073
+ };
1074
+ const isInputDisabled = isWaitingForResponse || !isSessionParamsConfigured || disableInput;
1075
+ if (isChatDisabled) {
1076
+ if (disabledComponent) {
1077
+ return /* @__PURE__ */ jsxRuntime.jsx(PaymanChatContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [styles6.container, style], children: [
1078
+ children,
1079
+ disabledComponent
1080
+ ] }) });
1081
+ }
1082
+ return /* @__PURE__ */ jsxRuntime.jsx(PaymanChatContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [styles6.container, style], children: [
1083
+ children,
1084
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles6.disabledContainer, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles6.disabledText, children: "Chat is currently disabled" }) })
1085
+ ] }) });
1086
+ }
1087
+ return /* @__PURE__ */ jsxRuntime.jsx(PaymanChatContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsxs(
1088
+ reactNative.KeyboardAvoidingView,
1089
+ {
1090
+ style: [styles6.container, style],
1091
+ behavior: reactNative.Platform.OS === "ios" ? "padding" : "height",
1092
+ keyboardVerticalOffset: reactNative.Platform.OS === "ios" ? 90 : 0,
1093
+ children: [
1094
+ children,
1095
+ /* @__PURE__ */ jsxRuntime.jsx(
1096
+ MessageList,
1097
+ {
1098
+ messages,
1099
+ isLoading: false,
1100
+ emptyStateText,
1101
+ showEmptyStateIcon,
1102
+ layout,
1103
+ showTimestamps,
1104
+ stage: config.stage || "DEV",
1105
+ animated,
1106
+ showAgentName,
1107
+ agentName,
1108
+ showAvatars,
1109
+ showUserAvatar,
1110
+ showAssistantAvatar,
1111
+ showExecutionSteps,
1112
+ showStreamingDot,
1113
+ streamingStepsText,
1114
+ completedStepsText,
1115
+ onExecutionTraceClick
1116
+ }
1117
+ ),
1118
+ hasAskPermission && /* @__PURE__ */ jsxRuntime.jsx(
1119
+ ChatInput,
1120
+ {
1121
+ value: inputValue,
1122
+ onChange: setInputValue,
1123
+ onSend: handleSend,
1124
+ onPause: cancelStream,
1125
+ disabled: isInputDisabled,
1126
+ placeholder,
1127
+ isWaitingForResponse,
1128
+ hasSelectedSession: true,
1129
+ isSessionParamsConfigured,
1130
+ inputStyle,
1131
+ layout
1132
+ }
1133
+ )
1134
+ ]
1135
+ }
1136
+ ) });
1137
+ }
1138
+ var styles6 = reactNative.StyleSheet.create({
1139
+ container: {
1140
+ flex: 1,
1141
+ backgroundColor: "#FFF",
1142
+ borderWidth: 1,
1143
+ borderColor: "#E5E5E5",
1144
+ borderRadius: 8,
1145
+ overflow: "hidden"
1146
+ },
1147
+ disabledContainer: {
1148
+ flex: 1,
1149
+ justifyContent: "center",
1150
+ alignItems: "center",
1151
+ padding: 16
1152
+ },
1153
+ disabledText: {
1154
+ fontSize: 14,
1155
+ color: "#999",
1156
+ textAlign: "center"
1157
+ }
1158
+ });
1159
+
1160
+ Object.defineProperty(exports, "generateId", {
1161
+ enumerable: true,
1162
+ get: function () { return paymanTypescriptAskSdk.generateId; }
1163
+ });
1164
+ Object.defineProperty(exports, "streamWorkflowEvents", {
1165
+ enumerable: true,
1166
+ get: function () { return paymanTypescriptAskSdk.streamWorkflowEvents; }
1167
+ });
1168
+ Object.defineProperty(exports, "useChat", {
1169
+ enumerable: true,
1170
+ get: function () { return paymanTypescriptAskSdk.useChat; }
1171
+ });
1172
+ exports.PaymanChat = PaymanChat;
1173
+ exports.PaymanChatContext = PaymanChatContext;
1174
+ exports.cn = cn;
1175
+ exports.formatDate = formatDate;
1176
+ exports.usePaymanChat = usePaymanChat;
1177
+ //# sourceMappingURL=index.native.js.map
1178
+ //# sourceMappingURL=index.native.js.map