@paymanai/payman-ask-sdk 2.0.3 → 2.0.4

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.
@@ -60,9 +60,9 @@ var styles = reactNative.StyleSheet.create({
60
60
  function cn(...inputs) {
61
61
  return tailwindMerge.twMerge(clsx.clsx(inputs));
62
62
  }
63
- var DEFAULT_WIDTH = 280;
64
- var DEFAULT_MIN_WIDTH = 240;
65
- var DEFAULT_MAX_WIDTH = 480;
63
+ var DEFAULT_WIDTH = 260;
64
+ var DEFAULT_MIN_WIDTH = 220;
65
+ var DEFAULT_MAX_WIDTH = 440;
66
66
  var DEFAULT_PAGE_SIZE = 20;
67
67
  function getPersistKey(config, opts) {
68
68
  if (opts.persistKey) return opts.persistKey;
@@ -281,10 +281,11 @@ function SessionHistorySidebar({
281
281
  options,
282
282
  activeSessionId,
283
283
  loadingSessionId,
284
- streamingSessionIds,
285
284
  recentlyCompletedSessionIds,
286
285
  optimisticActivity,
287
286
  onSelectSession,
287
+ onNewSession,
288
+ newSessionDisabled = false,
288
289
  mobileOpen,
289
290
  onMobileOpenChange
290
291
  }) {
@@ -292,6 +293,7 @@ function SessionHistorySidebar({
292
293
  const mobileThemeSourceRef = react.useRef(null);
293
294
  const [mobilePortalThemeStyle, setMobilePortalThemeStyle] = react.useState({});
294
295
  const history = useSessionHistory(config, options, optimisticActivity);
296
+ const showNewSessionButton = options.showNewSessionButton === true;
295
297
  react.useEffect(() => {
296
298
  if (!isMobile) return;
297
299
  setMobilePortalThemeStyle(readPortalThemeStyle(mobileThemeSourceRef.current));
@@ -318,8 +320,10 @@ function SessionHistorySidebar({
318
320
  history,
319
321
  activeSessionId,
320
322
  loadingSessionId,
321
- streamingSessionIds,
322
323
  recentlyCompletedSessionIds,
324
+ showNewSessionButton,
325
+ onNewSession,
326
+ newSessionDisabled,
323
327
  onSelectSession: (s3) => {
324
328
  onSelectSession(s3);
325
329
  onMobileOpenChange(false);
@@ -334,8 +338,10 @@ function SessionHistorySidebar({
334
338
  history,
335
339
  activeSessionId,
336
340
  loadingSessionId,
337
- streamingSessionIds,
338
341
  recentlyCompletedSessionIds,
342
+ showNewSessionButton,
343
+ onNewSession,
344
+ newSessionDisabled,
339
345
  onSelectSession
340
346
  }
341
347
  );
@@ -344,11 +350,14 @@ function DesktopSidebar({
344
350
  history,
345
351
  activeSessionId,
346
352
  loadingSessionId,
347
- streamingSessionIds,
348
353
  recentlyCompletedSessionIds,
354
+ showNewSessionButton,
355
+ onNewSession,
356
+ newSessionDisabled,
349
357
  onSelectSession
350
358
  }) {
351
359
  const { width, setWidth, collapsed, setCollapsed, minWidth, maxWidth } = history;
360
+ const reduceMotion = framerMotion.useReducedMotion();
352
361
  const dragStateRef = react.useRef(null);
353
362
  const [isDragging, setIsDragging] = react.useState(false);
354
363
  const [handleHover, setHandleHover] = react.useState(false);
@@ -380,25 +389,42 @@ function DesktopSidebar({
380
389
  window.removeEventListener("pointercancel", onEnd);
381
390
  };
382
391
  }, [isDragging, setWidth]);
392
+ const handleActive = handleHover || isDragging;
393
+ const sidebarEnter = reduceMotion ? { duration: 0.1, ease: "easeOut" } : { duration: 0.16, ease: [0.25, 0.46, 0.45, 0.94] };
383
394
  if (collapsed) {
384
395
  return /* @__PURE__ */ jsxRuntime.jsx(
385
- CollapsedButton,
396
+ framerMotion.motion.div,
386
397
  {
387
- onExpand: () => setCollapsed(false),
388
- history,
389
- activeSessionId,
390
- loadingSessionId,
391
- streamingSessionIds,
392
- recentlyCompletedSessionIds,
393
- onSelectSession
394
- }
398
+ className: "payman-sidebar-collapsed-mount",
399
+ initial: reduceMotion ? false : { opacity: 0, scale: 0.96 },
400
+ animate: { opacity: 1, scale: 1 },
401
+ transition: sidebarEnter,
402
+ style: { alignSelf: "flex-start" },
403
+ children: /* @__PURE__ */ jsxRuntime.jsx(
404
+ CollapsedButton,
405
+ {
406
+ onExpand: () => setCollapsed(false),
407
+ history,
408
+ activeSessionId,
409
+ loadingSessionId,
410
+ recentlyCompletedSessionIds,
411
+ showNewSessionButton,
412
+ onNewSession,
413
+ newSessionDisabled,
414
+ onSelectSession
415
+ }
416
+ )
417
+ },
418
+ "payman-sidebar-desktop-collapsed"
395
419
  );
396
420
  }
397
- const handleActive = handleHover || isDragging;
398
421
  return /* @__PURE__ */ jsxRuntime.jsxs(
399
- "aside",
422
+ framerMotion.motion.aside,
400
423
  {
401
424
  className: "payman-sidebar payman-sidebar-desktop",
425
+ initial: reduceMotion ? false : { opacity: 0 },
426
+ animate: { opacity: 1 },
427
+ transition: sidebarEnter,
402
428
  style: {
403
429
  width,
404
430
  minWidth,
@@ -409,17 +435,24 @@ function DesktopSidebar({
409
435
  display: "flex",
410
436
  flexDirection: "column",
411
437
  overflow: "hidden",
412
- transition: isDragging ? "none" : "width 140ms ease"
438
+ transition: isDragging ? "none" : "width 100ms ease"
413
439
  },
414
440
  children: [
415
- /* @__PURE__ */ jsxRuntime.jsx(SidebarHeader, { onCollapse: () => setCollapsed(true) }),
441
+ /* @__PURE__ */ jsxRuntime.jsx(
442
+ SidebarTopBar,
443
+ {
444
+ onCollapse: () => setCollapsed(true),
445
+ showNewSessionButton,
446
+ onNewSession,
447
+ newSessionDisabled
448
+ }
449
+ ),
416
450
  /* @__PURE__ */ jsxRuntime.jsx(
417
451
  SessionList,
418
452
  {
419
453
  history,
420
454
  activeSessionId,
421
455
  loadingSessionId,
422
- streamingSessionIds,
423
456
  recentlyCompletedSessionIds,
424
457
  onSelectSession
425
458
  }
@@ -457,26 +490,30 @@ function DesktopSidebar({
457
490
  borderRadius: 999,
458
491
  background: handleActive ? "var(--payman-v2-text-3)" : "transparent",
459
492
  opacity: handleActive ? 1 : 0,
460
- transition: "opacity 140ms ease, background 140ms ease"
493
+ transition: "opacity 100ms ease, background 100ms ease"
461
494
  }
462
495
  }
463
496
  )
464
497
  }
465
498
  )
466
499
  ]
467
- }
500
+ },
501
+ "payman-sidebar-desktop-expanded"
468
502
  );
469
503
  }
470
- var POPOVER_LEAVE_DELAY_MS = 200;
504
+ var POPOVER_LEAVE_DELAY_MS = 220;
471
505
  function CollapsedButton({
472
506
  onExpand,
473
507
  history,
474
508
  activeSessionId,
475
509
  loadingSessionId,
476
- streamingSessionIds,
477
510
  recentlyCompletedSessionIds,
511
+ showNewSessionButton,
512
+ onNewSession,
513
+ newSessionDisabled,
478
514
  onSelectSession
479
515
  }) {
516
+ const reduceMotion = framerMotion.useReducedMotion();
480
517
  const [hoverOpen, setHoverOpen] = react.useState(false);
481
518
  const leaveTimerRef = react.useRef(null);
482
519
  const openPopover = () => {
@@ -505,22 +542,29 @@ function CollapsedButton({
505
542
  style: { position: "relative", alignSelf: "flex-start" },
506
543
  children: [
507
544
  /* @__PURE__ */ jsxRuntime.jsx(
508
- "button",
545
+ framerMotion.motion.button,
509
546
  {
510
547
  type: "button",
511
548
  "aria-label": "Expand sidebar",
512
549
  title: "Expand sidebar",
513
550
  onClick: onExpand,
514
551
  className: "payman-sidebar-collapsed-button",
552
+ whileHover: reduceMotion ? void 0 : { scale: 1.04 },
553
+ whileTap: reduceMotion ? void 0 : { scale: 0.97 },
554
+ transition: { type: "spring", stiffness: 620, damping: 32 },
515
555
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PanelLeftOpen, { size: 16 })
516
556
  }
517
557
  ),
518
- hoverOpen && /* @__PURE__ */ jsxRuntime.jsxs(
519
- "div",
558
+ /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: hoverOpen && /* @__PURE__ */ jsxRuntime.jsxs(
559
+ framerMotion.motion.div,
520
560
  {
521
561
  className: "payman-sidebar-popover",
522
562
  onMouseEnter: openPopover,
523
563
  onMouseLeave: schedulePopoverClose,
564
+ initial: reduceMotion ? { opacity: 0 } : { opacity: 0, x: -6, scale: 0.98 },
565
+ animate: reduceMotion ? { opacity: 1 } : { opacity: 1, x: 0, scale: 1 },
566
+ exit: reduceMotion ? { opacity: 0 } : { opacity: 0, x: -4, scale: 0.99 },
567
+ transition: reduceMotion ? { duration: 0.08 } : { duration: 0.14, ease: [0.25, 0.46, 0.45, 0.94] },
524
568
  style: {
525
569
  position: "absolute",
526
570
  left: "calc(100% + 6px)",
@@ -530,17 +574,24 @@ function CollapsedButton({
530
574
  zIndex: 50,
531
575
  display: "flex",
532
576
  flexDirection: "column",
533
- overflow: "hidden"
577
+ overflow: "hidden",
578
+ transformOrigin: "left center"
534
579
  },
535
580
  children: [
536
- /* @__PURE__ */ jsxRuntime.jsx(SidebarHeader, {}),
581
+ /* @__PURE__ */ jsxRuntime.jsx(
582
+ SidebarTopBar,
583
+ {
584
+ showNewSessionButton,
585
+ onNewSession,
586
+ newSessionDisabled
587
+ }
588
+ ),
537
589
  /* @__PURE__ */ jsxRuntime.jsx(
538
590
  SessionList,
539
591
  {
540
592
  history,
541
593
  activeSessionId,
542
594
  loadingSessionId,
543
- streamingSessionIds,
544
595
  recentlyCompletedSessionIds,
545
596
  onSelectSession: (s3) => {
546
597
  onSelectSession(s3);
@@ -549,8 +600,9 @@ function CollapsedButton({
549
600
  }
550
601
  )
551
602
  ]
552
- }
553
- )
603
+ },
604
+ "payman-sidebar-hover-popover"
605
+ ) })
554
606
  ]
555
607
  }
556
608
  );
@@ -562,10 +614,16 @@ function MobileDrawer({
562
614
  history,
563
615
  activeSessionId,
564
616
  loadingSessionId,
565
- streamingSessionIds,
566
617
  recentlyCompletedSessionIds,
618
+ showNewSessionButton,
619
+ onNewSession,
620
+ newSessionDisabled,
567
621
  onSelectSession
568
622
  }) {
623
+ const handleNewSession = onNewSession ? () => {
624
+ onOpenChange(false);
625
+ onNewSession();
626
+ } : void 0;
569
627
  if (!open || typeof document === "undefined") return null;
570
628
  return reactDom.createPortal(
571
629
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -596,14 +654,22 @@ function MobileDrawer({
596
654
  },
597
655
  children: [
598
656
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-sidebar-sheet-grabber", "aria-hidden": true }),
599
- /* @__PURE__ */ jsxRuntime.jsx(SidebarHeader, { onCollapse: () => onOpenChange(false), mobile: true }),
657
+ /* @__PURE__ */ jsxRuntime.jsx(
658
+ SidebarTopBar,
659
+ {
660
+ onCollapse: () => onOpenChange(false),
661
+ mobile: true,
662
+ showNewSessionButton,
663
+ onNewSession: handleNewSession,
664
+ newSessionDisabled
665
+ }
666
+ ),
600
667
  /* @__PURE__ */ jsxRuntime.jsx(
601
668
  SessionList,
602
669
  {
603
670
  history,
604
671
  activeSessionId,
605
672
  loadingSessionId,
606
- streamingSessionIds,
607
673
  recentlyCompletedSessionIds,
608
674
  onSelectSession
609
675
  }
@@ -616,12 +682,48 @@ function MobileDrawer({
616
682
  document.body
617
683
  );
618
684
  }
685
+ function SidebarTopBar({
686
+ onCollapse,
687
+ mobile = false,
688
+ showNewSessionButton = false,
689
+ onNewSession,
690
+ newSessionDisabled = false
691
+ }) {
692
+ const shouldShowNewSession = showNewSessionButton && onNewSession != null;
693
+ return /* @__PURE__ */ jsxRuntime.jsxs(
694
+ "div",
695
+ {
696
+ className: cn(
697
+ "payman-sidebar-topbar",
698
+ shouldShowNewSession && "has-new-session"
699
+ ),
700
+ children: [
701
+ /* @__PURE__ */ jsxRuntime.jsx(SidebarHeader, { onCollapse, mobile }),
702
+ shouldShowNewSession && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-sidebar-new-session-wrap", children: /* @__PURE__ */ jsxRuntime.jsxs(
703
+ "button",
704
+ {
705
+ type: "button",
706
+ className: "payman-sidebar-new-session-button",
707
+ onClick: onNewSession,
708
+ disabled: newSessionDisabled,
709
+ "aria-label": "New Session",
710
+ title: "New Session",
711
+ children: [
712
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { size: 13, strokeWidth: 2.4 }),
713
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "New Session" })
714
+ ]
715
+ }
716
+ ) })
717
+ ]
718
+ }
719
+ );
720
+ }
619
721
  function SidebarHeader({
620
722
  onCollapse,
621
723
  mobile = false
622
724
  }) {
623
725
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-sidebar-header", children: [
624
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Recent sessions" }),
726
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-sidebar-header-title", children: "Recent sessions" }),
625
727
  onCollapse && /* @__PURE__ */ jsxRuntime.jsx(
626
728
  "button",
627
729
  {
@@ -629,7 +731,8 @@ function SidebarHeader({
629
731
  "aria-label": mobile ? "Close recent sessions" : "Collapse sidebar",
630
732
  title: mobile ? "Close recent sessions" : "Collapse sidebar",
631
733
  onClick: onCollapse,
632
- children: mobile ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { size: 16 }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PanelLeftClose, { size: 14 })
734
+ className: "payman-sidebar-header-icon-button",
735
+ children: mobile ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { size: 15 }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PanelLeftClose, { size: 13 })
633
736
  }
634
737
  )
635
738
  ] });
@@ -638,7 +741,6 @@ function SessionList({
638
741
  history,
639
742
  activeSessionId,
640
743
  loadingSessionId,
641
- streamingSessionIds,
642
744
  recentlyCompletedSessionIds,
643
745
  onSelectSession
644
746
  }) {
@@ -675,7 +777,6 @@ function SessionList({
675
777
  session: s3,
676
778
  isActive: s3.sessionId === activeSessionId,
677
779
  isLoading: s3.sessionId === loadingSessionId,
678
- isStreaming: streamingSessionIds?.has(s3.sessionId) ?? false,
679
780
  isRecentlyCompleted: recentlyCompletedSessionIds?.has(s3.sessionId) ?? false,
680
781
  onSelect: onSelectSession
681
782
  },
@@ -708,26 +809,12 @@ function SessionRow({
708
809
  session,
709
810
  isActive,
710
811
  isLoading,
711
- isStreaming,
712
812
  isRecentlyCompleted,
713
813
  onSelect
714
814
  }) {
715
815
  let statusNode = null;
716
816
  let statusLabel;
717
- if (isStreaming) {
718
- statusNode = /* @__PURE__ */ jsxRuntime.jsxs(
719
- "span",
720
- {
721
- className: "payman-sidebar-row-status payman-sidebar-row-status-live",
722
- "aria-hidden": true,
723
- children: [
724
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-sidebar-row-live-dot" }),
725
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-sidebar-row-live-track" })
726
- ]
727
- }
728
- );
729
- statusLabel = "Running";
730
- } else if (isRecentlyCompleted) {
817
+ if (isRecentlyCompleted) {
731
818
  statusNode = /* @__PURE__ */ jsxRuntime.jsx(
732
819
  "span",
733
820
  {
@@ -748,7 +835,7 @@ function SessionRow({
748
835
  onClick: () => onSelect(session),
749
836
  className: cn("payman-sidebar-row", isActive && "is-active"),
750
837
  title: statusLabel ? `${session.sessionTitle || "Untitled session"} \u2014 ${statusLabel}` : session.sessionTitle,
751
- "aria-busy": isLoading || isStreaming || void 0,
838
+ "aria-busy": isLoading || void 0,
752
839
  children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "payman-sidebar-row-main", children: [
753
840
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-sidebar-row-title", children: session.sessionTitle || "Untitled session" }),
754
841
  statusNode
@@ -837,10 +924,17 @@ function groupSessionsByDate(sessions, now) {
837
924
  }
838
925
  return orderedGroups;
839
926
  }
927
+ function titleCaseDateHeading(label) {
928
+ return label.replace(/[\p{L}\p{M}]+/gu, (word) => {
929
+ const lower = word.toLocaleLowerCase(void 0);
930
+ const first = lower.charAt(0).toLocaleUpperCase(void 0);
931
+ return first + lower.slice(1);
932
+ });
933
+ }
840
934
  function getSessionDateBucket(iso, now) {
841
935
  const date = new Date(iso);
842
936
  if (Number.isNaN(date.getTime())) {
843
- return { key: "older", label: "Older" };
937
+ return { key: "older", label: titleCaseDateHeading("Older") };
844
938
  }
845
939
  const dayKey = [
846
940
  date.getFullYear(),
@@ -852,22 +946,26 @@ function getSessionDateBucket(iso, now) {
852
946
  const dayDiff = Math.round(
853
947
  (today.getTime() - sessionDay.getTime()) / 864e5
854
948
  );
855
- if (dayDiff <= 0) return { key: dayKey, label: "Today" };
856
- if (dayDiff === 1) return { key: dayKey, label: "Yesterday" };
949
+ if (dayDiff <= 0) return { key: dayKey, label: titleCaseDateHeading("Today") };
950
+ if (dayDiff === 1) return { key: dayKey, label: titleCaseDateHeading("Yesterday") };
857
951
  if (dayDiff < 7) {
858
952
  return {
859
953
  key: dayKey,
860
- label: date.toLocaleDateString(void 0, { weekday: "long" })
954
+ label: titleCaseDateHeading(
955
+ date.toLocaleDateString(void 0, { weekday: "long" })
956
+ )
861
957
  };
862
958
  }
863
959
  const sameYear = date.getFullYear() === now.getFullYear();
864
960
  return {
865
961
  key: dayKey,
866
- label: date.toLocaleDateString(void 0, {
867
- month: "short",
868
- day: "numeric",
869
- year: sameYear ? void 0 : "numeric"
870
- })
962
+ label: titleCaseDateHeading(
963
+ date.toLocaleDateString(void 0, {
964
+ month: "long",
965
+ day: "numeric",
966
+ year: sameYear ? void 0 : "numeric"
967
+ })
968
+ )
871
969
  };
872
970
  }
873
971
  function ChatHeader({