@paymanai/payman-ask-sdk 2.0.5 → 2.0.6

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.
@@ -2235,6 +2235,232 @@ var s6 = reactNative.StyleSheet.create({
2235
2235
  borderColor: "rgba(0,0,0,0.07)"
2236
2236
  }
2237
2237
  });
2238
+ var COMPACT_BREAKPOINT = 560;
2239
+ var PAYMAN_GREEN = "#0A3B44";
2240
+ function getCategoryGlyph(label) {
2241
+ const normalizedLabel = label.toLowerCase();
2242
+ if (normalizedLabel.includes("pay") || normalizedLabel.includes("transfer")) return "->";
2243
+ if (normalizedLabel.includes("account")) return "[]";
2244
+ if (normalizedLabel.includes("insight") || normalizedLabel.includes("analytics")) return "/_";
2245
+ if (normalizedLabel.includes("product")) return "o";
2246
+ return "+";
2247
+ }
2248
+ function formatSuggestionTitle(value) {
2249
+ return value.replace(
2250
+ /\b(Good (?:morning|afternoon|evening))[ \t]+(?=how can I help)/i,
2251
+ "$1 - "
2252
+ );
2253
+ }
2254
+ function PromptSuggestionsV2({
2255
+ title,
2256
+ categories,
2257
+ disabled = false,
2258
+ onPromptClick
2259
+ }) {
2260
+ const { width } = reactNative.useWindowDimensions();
2261
+ const isCompact = width < COMPACT_BREAKPOINT;
2262
+ const validCategories = React.useMemo(
2263
+ () => categories.filter((category) => category.prompts.length > 0),
2264
+ [categories]
2265
+ );
2266
+ const [activeCategoryIndex, setActiveCategoryIndex] = React.useState(null);
2267
+ React.useEffect(() => {
2268
+ if (activeCategoryIndex != null && (activeCategoryIndex < 0 || activeCategoryIndex >= validCategories.length)) {
2269
+ setActiveCategoryIndex(null);
2270
+ }
2271
+ }, [activeCategoryIndex, validCategories.length]);
2272
+ if (validCategories.length === 0) return null;
2273
+ const activeCategory = activeCategoryIndex == null ? null : validCategories[activeCategoryIndex] ?? null;
2274
+ const displayTitle = title ? formatSuggestionTitle(title) : void 0;
2275
+ const categoryButtons = validCategories.map((category, categoryIndex) => {
2276
+ const isActive = activeCategoryIndex === categoryIndex;
2277
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2278
+ reactNative.Pressable,
2279
+ {
2280
+ accessibilityRole: "button",
2281
+ accessibilityLabel: `${category.label} prompts`,
2282
+ accessibilityState: { expanded: isActive, selected: isActive },
2283
+ onPress: () => setActiveCategoryIndex(
2284
+ (currentIndex) => currentIndex === categoryIndex ? null : categoryIndex
2285
+ ),
2286
+ style: ({ pressed }) => [
2287
+ styles.categoryButton,
2288
+ isActive && styles.categoryButtonActive,
2289
+ pressed && styles.categoryButtonPressed
2290
+ ],
2291
+ children: [
2292
+ category.icon ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles.customIcon, children: category.icon }) : /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles.categoryIcon, isActive && styles.categoryIconActive], children: getCategoryGlyph(category.label) }),
2293
+ /* @__PURE__ */ jsxRuntime.jsx(
2294
+ reactNative.Text,
2295
+ {
2296
+ numberOfLines: 1,
2297
+ style: [styles.categoryText, isActive && styles.categoryTextActive],
2298
+ children: category.label
2299
+ }
2300
+ )
2301
+ ]
2302
+ },
2303
+ `${category.label}-${categoryIndex}`
2304
+ );
2305
+ });
2306
+ return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles.root, children: [
2307
+ displayTitle ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles.title, isCompact && styles.titleCompact], children: displayTitle }) : null,
2308
+ isCompact ? /* @__PURE__ */ jsxRuntime.jsx(
2309
+ reactNative.ScrollView,
2310
+ {
2311
+ horizontal: true,
2312
+ showsHorizontalScrollIndicator: false,
2313
+ contentContainerStyle: styles.categoryScrollContent,
2314
+ style: styles.categoryScroll,
2315
+ children: categoryButtons
2316
+ }
2317
+ ) : /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles.categoryWrap, children: categoryButtons }),
2318
+ activeCategory ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles.promptCard, isCompact && styles.promptCardCompact], children: activeCategory.prompts.map((prompt, promptIndex) => /* @__PURE__ */ jsxRuntime.jsxs(
2319
+ reactNative.Pressable,
2320
+ {
2321
+ accessibilityRole: "button",
2322
+ accessibilityLabel: `Use suggested prompt: ${prompt}`,
2323
+ disabled,
2324
+ onPress: () => onPromptClick(prompt),
2325
+ style: ({ pressed }) => [
2326
+ styles.promptButton,
2327
+ promptIndex > 0 && styles.promptButtonDivider,
2328
+ pressed && !disabled && styles.promptButtonPressed,
2329
+ disabled && styles.promptButtonDisabled
2330
+ ],
2331
+ children: [
2332
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles.promptText, children: prompt }),
2333
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles.promptArrow, children: "->" })
2334
+ ]
2335
+ },
2336
+ `${prompt}-${promptIndex}`
2337
+ )) }) : null
2338
+ ] });
2339
+ }
2340
+ var styles = reactNative.StyleSheet.create({
2341
+ root: {
2342
+ width: "100%",
2343
+ alignItems: "center"
2344
+ },
2345
+ title: {
2346
+ marginBottom: 8,
2347
+ color: "#18181b",
2348
+ fontSize: 16,
2349
+ fontWeight: "500",
2350
+ lineHeight: 24,
2351
+ textAlign: "center"
2352
+ },
2353
+ titleCompact: {
2354
+ maxWidth: 340,
2355
+ paddingHorizontal: 16,
2356
+ fontSize: 16,
2357
+ lineHeight: 24
2358
+ },
2359
+ categoryWrap: {
2360
+ width: "100%",
2361
+ flexDirection: "row",
2362
+ flexWrap: "wrap",
2363
+ justifyContent: "center",
2364
+ marginBottom: 12
2365
+ },
2366
+ categoryScroll: {
2367
+ width: "100%",
2368
+ marginBottom: 12
2369
+ },
2370
+ categoryScrollContent: {
2371
+ paddingHorizontal: 16,
2372
+ paddingVertical: 2
2373
+ },
2374
+ categoryButton: {
2375
+ minHeight: 30,
2376
+ flexDirection: "row",
2377
+ alignItems: "center",
2378
+ justifyContent: "center",
2379
+ marginHorizontal: 4,
2380
+ marginVertical: 4,
2381
+ paddingHorizontal: 12,
2382
+ paddingVertical: 6,
2383
+ borderWidth: 1,
2384
+ borderColor: "#e4e4e7",
2385
+ borderRadius: 999,
2386
+ backgroundColor: "#ffffff"
2387
+ },
2388
+ categoryButtonActive: {
2389
+ borderColor: PAYMAN_GREEN,
2390
+ backgroundColor: PAYMAN_GREEN
2391
+ },
2392
+ categoryButtonPressed: {
2393
+ opacity: 0.82
2394
+ },
2395
+ customIcon: {
2396
+ marginRight: 6
2397
+ },
2398
+ categoryIcon: {
2399
+ marginRight: 6,
2400
+ color: PAYMAN_GREEN,
2401
+ fontSize: 11,
2402
+ fontWeight: "700",
2403
+ lineHeight: 14
2404
+ },
2405
+ categoryIconActive: {
2406
+ color: "#ffffff"
2407
+ },
2408
+ categoryText: {
2409
+ maxWidth: 180,
2410
+ color: "#3f3f46",
2411
+ fontSize: 11,
2412
+ fontWeight: "600",
2413
+ lineHeight: 14
2414
+ },
2415
+ categoryTextActive: {
2416
+ color: "#ffffff"
2417
+ },
2418
+ promptCard: {
2419
+ width: "100%",
2420
+ maxWidth: 600,
2421
+ overflow: "hidden",
2422
+ borderWidth: 1,
2423
+ borderColor: "#e4e4e7",
2424
+ borderRadius: 16,
2425
+ backgroundColor: "#ffffff"
2426
+ },
2427
+ promptCardCompact: {
2428
+ width: "auto",
2429
+ alignSelf: "stretch",
2430
+ marginHorizontal: 16,
2431
+ borderRadius: 14
2432
+ },
2433
+ promptButton: {
2434
+ minHeight: 50,
2435
+ flexDirection: "row",
2436
+ alignItems: "center",
2437
+ justifyContent: "space-between",
2438
+ paddingHorizontal: 16,
2439
+ paddingVertical: 12
2440
+ },
2441
+ promptButtonDivider: {
2442
+ borderTopWidth: 1,
2443
+ borderTopColor: "#e4e4e7"
2444
+ },
2445
+ promptButtonPressed: {
2446
+ backgroundColor: "#eef7f7"
2447
+ },
2448
+ promptButtonDisabled: {
2449
+ opacity: 0.5
2450
+ },
2451
+ promptText: {
2452
+ flex: 1,
2453
+ paddingRight: 12,
2454
+ color: "#27272a",
2455
+ fontSize: 13,
2456
+ lineHeight: 18
2457
+ },
2458
+ promptArrow: {
2459
+ color: PAYMAN_GREEN,
2460
+ fontSize: 13,
2461
+ lineHeight: 16
2462
+ }
2463
+ });
2238
2464
  var WaveformBar = React.memo(
2239
2465
  ({
2240
2466
  delay,
@@ -2274,7 +2500,7 @@ var WaveformBar = React.memo(
2274
2500
  return /* @__PURE__ */ jsxRuntime.jsx(
2275
2501
  reactNative.Animated.View,
2276
2502
  {
2277
- style: [styles.waveformBar, { height, backgroundColor: color }]
2503
+ style: [styles2.waveformBar, { height, backgroundColor: color }]
2278
2504
  }
2279
2505
  );
2280
2506
  }
@@ -2351,7 +2577,7 @@ var RollingText = React.memo(({ text, color }) => {
2351
2577
  reactNative.Animated.Text,
2352
2578
  {
2353
2579
  style: [
2354
- styles.transcribedText,
2580
+ styles2.transcribedText,
2355
2581
  {
2356
2582
  color,
2357
2583
  opacity,
@@ -2413,20 +2639,20 @@ var VoiceOverlay = React.memo(
2413
2639
  }
2414
2640
  }, [visible, panelHeight, contentOpacity]);
2415
2641
  if (!mounted) return null;
2416
- return /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { onPress: onStopRecording, style: styles.panelWrapper, children: /* @__PURE__ */ jsxRuntime.jsx(
2642
+ return /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { onPress: onStopRecording, style: styles2.panelWrapper, children: /* @__PURE__ */ jsxRuntime.jsx(
2417
2643
  reactNative.Animated.View,
2418
2644
  {
2419
2645
  style: [
2420
- styles.panel,
2646
+ styles2.panel,
2421
2647
  {
2422
2648
  height: panelHeight,
2423
2649
  backgroundColor: bgColor
2424
2650
  }
2425
2651
  ],
2426
- children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.Animated.View, { style: [styles.content, { opacity: contentOpacity }], children: [
2427
- /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles.textContainer, children: transcribedText.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(RollingText, { text: transcribedText, color: textColor }) : /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles.placeholderText, { color: mutedColor }], children: "Listening..." }) }),
2428
- /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles.controlsContainer, children: [
2429
- /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles.waveformContainer, children: [0, 1, 2, 3, 4].map((index) => /* @__PURE__ */ jsxRuntime.jsx(
2652
+ children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.Animated.View, { style: [styles2.content, { opacity: contentOpacity }], children: [
2653
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles2.textContainer, children: transcribedText.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(RollingText, { text: transcribedText, color: textColor }) : /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles2.placeholderText, { color: mutedColor }], children: "Listening..." }) }),
2654
+ /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles2.controlsContainer, children: [
2655
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles2.waveformContainer, children: [0, 1, 2, 3, 4].map((index) => /* @__PURE__ */ jsxRuntime.jsx(
2430
2656
  WaveformBar,
2431
2657
  {
2432
2658
  delay: index * 20,
@@ -2435,7 +2661,7 @@ var VoiceOverlay = React.memo(
2435
2661
  },
2436
2662
  index
2437
2663
  )) }),
2438
- /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles.hintText, { color: mutedColor }], children: "Tap to stop" })
2664
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles2.hintText, { color: mutedColor }], children: "Tap to stop" })
2439
2665
  ] })
2440
2666
  ] })
2441
2667
  }
@@ -2443,7 +2669,7 @@ var VoiceOverlay = React.memo(
2443
2669
  }
2444
2670
  );
2445
2671
  VoiceOverlay.displayName = "VoiceOverlay";
2446
- var styles = reactNative.StyleSheet.create({
2672
+ var styles2 = reactNative.StyleSheet.create({
2447
2673
  panelWrapper: {
2448
2674
  zIndex: 10,
2449
2675
  elevation: 10
@@ -2672,6 +2898,8 @@ var PaymanChat = React.forwardRef(
2672
2898
  const emptyStateEyebrow = ui.emptyState?.eyebrow;
2673
2899
  const showEmptyIcon = ui.emptyState?.icon ?? true;
2674
2900
  const emptyStateLogo = ui.emptyState?.logo;
2901
+ const suggestions = ui.emptyState?.suggestions;
2902
+ const showSuggestions = suggestions != null && suggestions.enabled !== false && suggestions.categories.some((category) => category.prompts.length > 0);
2675
2903
  const availability = config.availability;
2676
2904
  if (availability?.state === "disabled") {
2677
2905
  return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [s7.root, { backgroundColor: palette.background }], children: [
@@ -2724,7 +2952,15 @@ var PaymanChat = React.forwardRef(
2724
2952
  emptyStateLogo ? emptyStateLogo : showEmptyIcon ? /* @__PURE__ */ jsxRuntime.jsx(HeroMark, { palette }) : null,
2725
2953
  emptyStateEyebrow ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [s7.emptyEyebrow, { color: palette.textMuted }], children: emptyStateEyebrow }) : null,
2726
2954
  /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [s7.emptyStateText, { color: "#94a3b8" }], children: emptyStateText }),
2727
- !emptyStateLogo ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [s7.emptyStateSubtext, { color: palette.textSecondary }], children: "Ask anything about your accounts, payments, or transfers." }) : null
2955
+ !emptyStateLogo && !showSuggestions ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [s7.emptyStateSubtext, { color: palette.textSecondary }], children: "Ask anything about your accounts, payments, or transfers." }) : null,
2956
+ showSuggestions ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: s7.emptySuggestions, children: /* @__PURE__ */ jsxRuntime.jsx(
2957
+ PromptSuggestionsV2,
2958
+ {
2959
+ categories: suggestions.categories,
2960
+ disabled: isWaitingForResponse,
2961
+ onPromptClick: handleSend
2962
+ }
2963
+ ) }) : null
2728
2964
  ] }),
2729
2965
  !isReadOnly ? /* @__PURE__ */ jsxRuntime.jsx(ChatInputV2, { ref: chatInputRef, ...inputProps }) : null
2730
2966
  ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
@@ -2897,6 +3133,10 @@ var s7 = reactNative.StyleSheet.create({
2897
3133
  letterSpacing: -0.15,
2898
3134
  maxWidth: 320
2899
3135
  },
3136
+ emptySuggestions: {
3137
+ width: "100%",
3138
+ marginTop: 16
3139
+ },
2900
3140
  disabledContainer: {
2901
3141
  flex: 1,
2902
3142
  alignItems: "center",
@@ -3864,21 +4104,21 @@ function ChatHeader({
3864
4104
  onCopySessionId(sessionId);
3865
4105
  }
3866
4106
  };
3867
- return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles2.container, children: [
3868
- /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles2.left, children: [
3869
- /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles2.title, children: "Chat" }),
3870
- sessionId && /* @__PURE__ */ jsxRuntime.jsxs(reactNative.Pressable, { onPress: handleCopySessionId, style: styles2.sessionChip, children: [
3871
- /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles2.sessionText, children: sessionId.length > 20 ? `${sessionId.substring(0, 8)}\u2026${sessionId.slice(-8)}` : sessionId }),
3872
- copiedSessionId ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles2.copyHint, children: "copied" }) : /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles2.copyHint, children: "copy" })
4107
+ return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles3.container, children: [
4108
+ /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles3.left, children: [
4109
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles3.title, children: "Chat" }),
4110
+ sessionId && /* @__PURE__ */ jsxRuntime.jsxs(reactNative.Pressable, { onPress: handleCopySessionId, style: styles3.sessionChip, children: [
4111
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles3.sessionText, children: sessionId.length > 20 ? `${sessionId.substring(0, 8)}\u2026${sessionId.slice(-8)}` : sessionId }),
4112
+ copiedSessionId ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles3.copyHint, children: "copied" }) : /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles3.copyHint, children: "copy" })
3873
4113
  ] })
3874
4114
  ] }),
3875
- /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles2.right, children: [
3876
- showResetSession && onNewSession && /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { onPress: onNewSession, style: styles2.btn, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles2.btnText, children: "Reset" }) }),
4115
+ /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles3.right, children: [
4116
+ showResetSession && onNewSession && /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { onPress: onNewSession, style: styles3.btn, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles3.btnText, children: "Reset" }) }),
3877
4117
  children
3878
4118
  ] })
3879
4119
  ] });
3880
4120
  }
3881
- var styles2 = reactNative.StyleSheet.create({
4121
+ var styles3 = reactNative.StyleSheet.create({
3882
4122
  container: {
3883
4123
  flexDirection: "row",
3884
4124
  alignItems: "center",