@paymanai/payman-ask-sdk 4.0.12 → 4.0.13

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/dist/index.mjs CHANGED
@@ -3,7 +3,7 @@ import { AnimatePresence, motion } from 'framer-motion';
3
3
  import { clsx } from 'clsx';
4
4
  import { twMerge } from 'tailwind-merge';
5
5
  import * as Sentry from '@sentry/react';
6
- import { ArrowDown, Pencil, X, RotateCcw, Telescope, Zap, Plus, ImagePlus, Paperclip, Mic, ArrowUp, Check, AlertCircle, Copy, WifiOff, ThumbsUp, ThumbsDown, Binoculars, Info, Download, Loader2, ChevronDown, User, Clock, Sparkles, ImageOff, Eye, ChevronRight, ShieldCheck } from 'lucide-react';
6
+ import { ArrowDown, Pencil, X, RotateCcw, Telescope, Zap, Plus, ImagePlus, Paperclip, Mic, ArrowUp, Check, AlertCircle, Copy, WifiOff, ThumbsUp, ThumbsDown, Binoculars, Info, Download, Loader2, ChevronDown, FileText, User, Clock, Sparkles, ImageOff, Eye, ChevronRight, ShieldCheck } from 'lucide-react';
7
7
  import ReactMarkdown from 'react-markdown';
8
8
  import remarkGfm from 'remark-gfm';
9
9
  import { createPortal } from 'react-dom';
@@ -792,66 +792,6 @@ function processStreamEventV2(rawEvent, state) {
792
792
  }
793
793
  return state;
794
794
  }
795
- function buildFormattedThinking(steps, allThinkingText) {
796
- const parts = [];
797
- const safeSteps = steps ?? [];
798
- const cleanAll = allThinkingText.replace(/^\s+/, "");
799
- if (cleanAll) {
800
- const firstStepWithThinking = safeSteps.find(
801
- (s) => s.thinkingText && s.thinkingText.trim()
802
- );
803
- if (!firstStepWithThinking) {
804
- parts.push("**Preflight**");
805
- parts.push(cleanAll);
806
- } else {
807
- const stepText = firstStepWithThinking.thinkingText.trim();
808
- const idx = cleanAll.indexOf(stepText);
809
- if (idx > 0) {
810
- const orphaned = cleanAll.substring(0, idx).replace(/\s+$/, "");
811
- if (orphaned) {
812
- parts.push("**Preflight**");
813
- parts.push(orphaned);
814
- }
815
- }
816
- }
817
- }
818
- for (const step of safeSteps) {
819
- switch (step.eventType) {
820
- case "STAGE_STARTED": {
821
- if (step.message) parts.push(`**${step.message}**`);
822
- break;
823
- }
824
- case "ORCHESTRATOR_THINKING":
825
- parts.push("**Planning**");
826
- if (step.message) parts.push(step.message);
827
- break;
828
- case "INTENT_STARTED": {
829
- let label = step.message || "Processing";
830
- const started = label.match(/^(.+?)\s+started$/i);
831
- const progress = label.match(/^(.+?)\s+in progress$/i);
832
- if (started) label = started[1];
833
- else if (progress) label = progress[1];
834
- parts.push(`**${label}**`);
835
- if (step.thinkingText) parts.push(step.thinkingText);
836
- break;
837
- }
838
- case "INTENT_PROGRESS": {
839
- if (step.thinkingText) parts.push(step.thinkingText);
840
- else if (step.message) parts.push(step.message);
841
- break;
842
- }
843
- case "AGGREGATOR_THINKING":
844
- parts.push("**Finalizing**");
845
- if (step.message) parts.push(step.message);
846
- break;
847
- case "USER_ACTION_REQUIRED":
848
- parts.push("**Action required**");
849
- if (step.message) parts.push(step.message);
850
- break;
851
- }
852
- }
853
- return parts.length > 0 ? parts.join("\n") : allThinkingText;
854
- }
855
795
  function createCancelledMessageUpdate(steps, currentMessage) {
856
796
  const updatedSteps = steps.map((step) => {
857
797
  if (step.status === "in_progress") {
@@ -2028,9 +1968,6 @@ function buildContent(schema, values) {
2028
1968
  }
2029
1969
  return content;
2030
1970
  }
2031
- function migrateActiveStream(oldUserId, newUserId) {
2032
- activeStreamStore.rename(oldUserId, newUserId);
2033
- }
2034
1971
  var PaymanChatContext = createContext(void 0);
2035
1972
  function usePaymanChat() {
2036
1973
  const context = useContext(PaymanChatContext);
@@ -2536,46 +2473,6 @@ function createMarkdownComponents(options = {}) {
2536
2473
  td: ({ children }) => /* @__PURE__ */ jsx("td", { className: "p-3 align-middle text-sm whitespace-nowrap", children })
2537
2474
  };
2538
2475
  }
2539
- function ThinkingBlock({ text }) {
2540
- const [isOpen, setIsOpen] = useState(false);
2541
- const hasContent = typeof text === "string" && text.trim().length > 0;
2542
- if (!hasContent) return null;
2543
- return /* @__PURE__ */ jsxs("div", { className: "mt-1.5 mb-1.5", children: [
2544
- /* @__PURE__ */ jsxs(
2545
- "button",
2546
- {
2547
- type: "button",
2548
- onClick: () => setIsOpen((prev) => !prev),
2549
- className: "inline-flex items-center gap-1 text-[10px] payman-agent-thinking-toggle transition-colors",
2550
- "aria-expanded": isOpen,
2551
- "aria-label": isOpen ? "Collapse thought process" : "Expand thought process",
2552
- children: [
2553
- /* @__PURE__ */ jsx(
2554
- motion.div,
2555
- {
2556
- animate: { rotate: isOpen ? 180 : 0 },
2557
- transition: { duration: 0.15 },
2558
- className: "shrink-0",
2559
- children: /* @__PURE__ */ jsx(ChevronDown, { className: "h-3 w-3" })
2560
- }
2561
- ),
2562
- /* @__PURE__ */ jsx("span", { children: "Thought process" })
2563
- ]
2564
- }
2565
- ),
2566
- /* @__PURE__ */ jsx(AnimatePresence, { initial: false, children: isOpen && /* @__PURE__ */ jsx(
2567
- motion.div,
2568
- {
2569
- initial: { height: 0, opacity: 0 },
2570
- animate: { height: "auto", opacity: 1 },
2571
- exit: { height: 0, opacity: 0 },
2572
- transition: { duration: 0.2, ease: "easeInOut" },
2573
- className: "overflow-hidden",
2574
- children: /* @__PURE__ */ jsx("div", { className: "mt-1 payman-agent-thinking-block rounded-md p-2 overflow-y-auto overflow-x-hidden", children: /* @__PURE__ */ jsx("p", { className: "m-0 text-xs payman-agent-thinking-block-text whitespace-pre-wrap leading-relaxed", children: text }) })
2575
- }
2576
- ) })
2577
- ] });
2578
- }
2579
2476
  var FRIENDLY_ERROR_MESSAGE2 = "Oops, something went wrong. Please try again.";
2580
2477
  function looksLikeRawError(text) {
2581
2478
  if (!text || text.length < 10) return false;
@@ -2618,8 +2515,6 @@ function AgentMessage({
2618
2515
  const completedWithNoContent = !isStreaming && !isCancelled && content.length === 0 && (message.streamProgress === "completed" || message.streamProgress === "error");
2619
2516
  const conflictErrorMessage = getConflictErrorMessage(message.errorDetails);
2620
2517
  const isError = !!conflictErrorMessage || (isFriendlyWorkflowError(message.errorDetails) || looksLikeRawError(content)) && !hasMeaningfulContent || completedWithNoContent;
2621
- const activeThinkingText = message.activeThinkingText;
2622
- const allThinkingText = message.allThinkingText;
2623
2518
  const currentStep = useMemo(
2624
2519
  () => message.steps?.find(
2625
2520
  (s) => s.id === currentExecutingStepId && s.status === "in_progress"
@@ -2662,7 +2557,7 @@ function AgentMessage({
2662
2557
  return /* @__PURE__ */ jsx("div", { className: wrapper, children: /* @__PURE__ */ jsx(X, { className: "h-3.5 w-3.5 payman-agent-step-icon--error" }) });
2663
2558
  return /* @__PURE__ */ jsx("div", { className: wrapper, children: /* @__PURE__ */ jsx("div", { className: "h-1.5 w-1.5 rounded-full payman-agent-step-icon--pending-dim" }) });
2664
2559
  };
2665
- const stepsListContent = hasSteps && /* @__PURE__ */ jsx(AnimatePresence, { initial: false, children: isStepsExpanded && /* @__PURE__ */ jsxs(
2560
+ const stepsListContent = hasSteps && /* @__PURE__ */ jsx(AnimatePresence, { initial: false, children: isStepsExpanded && /* @__PURE__ */ jsx(
2666
2561
  motion.div,
2667
2562
  {
2668
2563
  initial: { height: 0, opacity: 0 },
@@ -2670,37 +2565,34 @@ function AgentMessage({
2670
2565
  exit: { height: 0, opacity: 0 },
2671
2566
  transition: { duration: 0.2, ease: "easeInOut" },
2672
2567
  className: "overflow-hidden",
2673
- children: [
2674
- !isStreaming && allThinkingText?.trim() && /* @__PURE__ */ jsx(ThinkingBlock, { text: allThinkingText }),
2675
- /* @__PURE__ */ jsx("div", { className: "pt-1.5", children: message.steps.map((step) => {
2676
- const isCurrentlyExecuting = step.id === currentExecutingStepId && step.status === "in_progress" && isStreaming && !isCancelled;
2677
- const hasTime = step.elapsedMs != null && step.elapsedMs > 0;
2678
- return /* @__PURE__ */ jsxs("div", { className: "mb-1.5", children: [
2679
- /* @__PURE__ */ jsxs("div", { className: "flex gap-1.5 items-start", children: [
2680
- /* @__PURE__ */ jsx("div", { className: "mt-px", children: renderStepIcon(step, isCurrentlyExecuting) }),
2681
- /* @__PURE__ */ jsx(
2682
- "span",
2683
- {
2684
- className: cn(
2685
- "text-xs leading-relaxed min-w-0 break-words",
2686
- isCurrentlyExecuting && "shimmer-text font-medium",
2687
- !isCurrentlyExecuting && step.status === "error" && "payman-agent-step-text--error",
2688
- !isCurrentlyExecuting && step.eventType === "USER_ACTION_SUCCESS" && "payman-agent-step-text--success",
2689
- !isCurrentlyExecuting && step.status === "completed" && "payman-agent-step-text--completed",
2690
- !isCurrentlyExecuting && step.status === "pending" && "payman-agent-step-text--pending",
2691
- !isCurrentlyExecuting && step.status === "in_progress" && "payman-agent-step-text--in-progress"
2692
- ),
2693
- children: step.message
2694
- }
2695
- )
2696
- ] }),
2697
- hasTime && /* @__PURE__ */ jsx("div", { className: "pl-[22px] mt-1", children: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 px-1.5 py-0.5 rounded-md payman-agent-step-time leading-none", children: [
2698
- /* @__PURE__ */ jsx(Clock, { className: "h-2.5 w-2.5 shrink-0 payman-agent-step-time-icon" }),
2699
- /* @__PURE__ */ jsx("span", { className: "text-[10px] font-mono payman-agent-step-time-text", children: formatElapsedTime(step.elapsedMs) })
2700
- ] }) })
2701
- ] }, step.id);
2702
- }) })
2703
- ]
2568
+ children: /* @__PURE__ */ jsx("div", { className: "pt-1.5", children: message.steps.map((step) => {
2569
+ const isCurrentlyExecuting = step.id === currentExecutingStepId && step.status === "in_progress" && isStreaming && !isCancelled;
2570
+ const hasTime = step.elapsedMs != null && step.elapsedMs > 0;
2571
+ return /* @__PURE__ */ jsxs("div", { className: "mb-1.5", children: [
2572
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-1.5 items-start", children: [
2573
+ /* @__PURE__ */ jsx("div", { className: "mt-px", children: renderStepIcon(step, isCurrentlyExecuting) }),
2574
+ /* @__PURE__ */ jsx(
2575
+ "span",
2576
+ {
2577
+ className: cn(
2578
+ "text-xs leading-relaxed min-w-0 break-words",
2579
+ isCurrentlyExecuting && "shimmer-text font-medium",
2580
+ !isCurrentlyExecuting && step.status === "error" && "payman-agent-step-text--error",
2581
+ !isCurrentlyExecuting && step.eventType === "USER_ACTION_SUCCESS" && "payman-agent-step-text--success",
2582
+ !isCurrentlyExecuting && step.status === "completed" && "payman-agent-step-text--completed",
2583
+ !isCurrentlyExecuting && step.status === "pending" && "payman-agent-step-text--pending",
2584
+ !isCurrentlyExecuting && step.status === "in_progress" && "payman-agent-step-text--in-progress"
2585
+ ),
2586
+ children: step.message
2587
+ }
2588
+ )
2589
+ ] }),
2590
+ hasTime && /* @__PURE__ */ jsx("div", { className: "pl-[22px] mt-1", children: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 px-1.5 py-0.5 rounded-md payman-agent-step-time leading-none", children: [
2591
+ /* @__PURE__ */ jsx(Clock, { className: "h-2.5 w-2.5 shrink-0 payman-agent-step-time-icon" }),
2592
+ /* @__PURE__ */ jsx("span", { className: "text-[10px] font-mono payman-agent-step-time-text", children: formatElapsedTime(step.elapsedMs) })
2593
+ ] }) })
2594
+ ] }, step.id);
2595
+ }) })
2704
2596
  }
2705
2597
  ) });
2706
2598
  const stepsToggleRef = useRef(null);
@@ -2781,22 +2673,13 @@ function AgentMessage({
2781
2673
  "text-sm leading-relaxed min-w-0 w-full break-words overflow-wrap-anywhere",
2782
2674
  showAgentName && "mt-1"
2783
2675
  ),
2784
- children: isStreaming && !content ? (
2785
- // Streaming without content show thinking/step indicator
2786
- activeThinkingText ? /* @__PURE__ */ jsxs("div", { className: "flex gap-2 items-start", children: [
2787
- /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 mt-0.5 payman-agent-thinking-spinner animate-spin shrink-0" }),
2788
- /* @__PURE__ */ jsxs("span", { className: "text-sm leading-relaxed min-w-0 break-words payman-agent-thinking-text whitespace-pre-wrap flex-1", children: [
2789
- activeThinkingText,
2790
- /* @__PURE__ */ jsx("span", { className: "inline-block w-0.5 h-3.5 payman-agent-thinking-cursor animate-pulse ml-0.5 align-text-bottom" })
2791
- ] })
2792
- ] }) : currentStep ? /* @__PURE__ */ jsxs("div", { className: "flex gap-1.5 items-start", children: [
2793
- /* @__PURE__ */ jsx("div", { className: "mt-0.5 shrink-0", children: renderStepIcon(currentStep, true) }),
2794
- /* @__PURE__ */ jsx("span", { className: "text-sm leading-relaxed min-w-0 break-words shimmer-text font-medium flex-1", children: currentStep.message })
2795
- ] }) : /* @__PURE__ */ jsxs("div", { className: "flex gap-2.5 items-start", children: [
2796
- /* @__PURE__ */ jsx(Loader2, { className: "w-4 h-4 mt-0.5 payman-agent-thinking-spinner animate-spin shrink-0" }),
2797
- /* @__PURE__ */ jsx("span", { className: "text-sm payman-agent-thinking-text flex-1", children: currentMessage || "Thinking..." })
2798
- ] })
2799
- ) : isCancelled && !content ? /* @__PURE__ */ jsxs("div", { className: "flex gap-2.5 items-start", children: [
2676
+ children: isStreaming && !content ? currentStep ? /* @__PURE__ */ jsxs("div", { className: "flex gap-1.5 items-start", children: [
2677
+ /* @__PURE__ */ jsx("div", { className: "mt-0.5 shrink-0", children: renderStepIcon(currentStep, true) }),
2678
+ /* @__PURE__ */ jsx("span", { className: "text-sm leading-relaxed min-w-0 break-words shimmer-text font-medium flex-1", children: currentStep.message })
2679
+ ] }) : /* @__PURE__ */ jsxs("div", { className: "flex gap-2.5 items-start", children: [
2680
+ /* @__PURE__ */ jsx(Loader2, { className: "w-4 h-4 mt-0.5 payman-agent-thinking-spinner animate-spin shrink-0" }),
2681
+ /* @__PURE__ */ jsx("span", { className: "text-sm payman-agent-thinking-text flex-1", children: currentMessage || "Thinking..." })
2682
+ ] }) : isCancelled && !content ? /* @__PURE__ */ jsxs("div", { className: "flex gap-2.5 items-start", children: [
2800
2683
  /* @__PURE__ */ jsx(X, { className: "w-4 h-4 mt-0.5 payman-agent-cancelled-icon shrink-0" }),
2801
2684
  /* @__PURE__ */ jsx("span", { className: "text-sm payman-agent-cancelled-text italic flex-1", children: currentMessage || "Request was stopped." })
2802
2685
  ] }) : /* @__PURE__ */ jsx(
@@ -3665,7 +3548,62 @@ function MarkdownImageV2({
3665
3548
  }
3666
3549
  ) });
3667
3550
  }
3668
- function buildComponents(onImageClick, isResolvingRef) {
3551
+ function PdfBlockV2({ title, href, onOpen }) {
3552
+ return /* @__PURE__ */ jsxs(
3553
+ "button",
3554
+ {
3555
+ type: "button",
3556
+ className: "payman-v2-pdf-block",
3557
+ onClick: (e) => {
3558
+ e.preventDefault();
3559
+ onOpen(href, title);
3560
+ },
3561
+ "aria-label": `Open PDF: ${title}`,
3562
+ children: [
3563
+ /* @__PURE__ */ jsx("div", { className: "payman-v2-pdf-block-icon-area", children: /* @__PURE__ */ jsx(FileText, { size: 18, strokeWidth: 1.5 }) }),
3564
+ /* @__PURE__ */ jsxs("div", { className: "payman-v2-pdf-block-body", children: [
3565
+ /* @__PURE__ */ jsx("span", { className: "payman-v2-pdf-block-name", children: title }),
3566
+ /* @__PURE__ */ jsx("span", { className: "payman-v2-pdf-block-sub", children: "PDF \xB7 Click to preview" })
3567
+ ] })
3568
+ ]
3569
+ }
3570
+ );
3571
+ }
3572
+ function isPdfUrl(href) {
3573
+ if (!href) return false;
3574
+ try {
3575
+ const url = new URL(href);
3576
+ const filename = url.searchParams.get("filename");
3577
+ if (filename?.toLowerCase().endsWith(".pdf")) return true;
3578
+ return url.pathname.toLowerCase().endsWith(".pdf");
3579
+ } catch {
3580
+ return href.toLowerCase().endsWith(".pdf");
3581
+ }
3582
+ }
3583
+ function getPdfTitleFromUrl(href) {
3584
+ try {
3585
+ const url = new URL(href);
3586
+ const filename = url.searchParams.get("filename");
3587
+ if (filename) {
3588
+ return filename.replace(/\.pdf$/i, "").replace(/[-_]+/g, " ").trim();
3589
+ }
3590
+ const parts = url.pathname.split("/").filter(Boolean);
3591
+ const last = parts[parts.length - 1];
3592
+ if (last) return decodeURIComponent(last).replace(/\.pdf$/i, "").replace(/[-_]+/g, " ").trim();
3593
+ } catch {
3594
+ }
3595
+ return "Document";
3596
+ }
3597
+ function childrenToText(children) {
3598
+ if (typeof children === "string") return children;
3599
+ if (typeof children === "number") return String(children);
3600
+ if (Array.isArray(children)) return children.map(childrenToText).join("");
3601
+ if (children && typeof children === "object" && "props" in children) {
3602
+ return childrenToText(children.props.children);
3603
+ }
3604
+ return "";
3605
+ }
3606
+ function buildComponents(onImageClick, isResolvingRef, onPdfClick) {
3669
3607
  return {
3670
3608
  p: ({ children }) => /* @__PURE__ */ jsx("p", { children }),
3671
3609
  code: ({ children }) => /* @__PURE__ */ jsx("code", { children }),
@@ -3680,7 +3618,15 @@ function buildComponents(onImageClick, isResolvingRef) {
3680
3618
  em: ({ children }) => /* @__PURE__ */ jsx("em", { children }),
3681
3619
  blockquote: ({ children }) => /* @__PURE__ */ jsx("blockquote", { children }),
3682
3620
  hr: () => /* @__PURE__ */ jsx("hr", {}),
3683
- a: ({ href, children }) => /* @__PURE__ */ jsx("a", { href, target: "_blank", rel: "noopener noreferrer", children }),
3621
+ a: ({ href, children }) => {
3622
+ const url = href ?? "";
3623
+ if (onPdfClick && isPdfUrl(url)) {
3624
+ const linkText = childrenToText(children).trim();
3625
+ const title = linkText || getPdfTitleFromUrl(url);
3626
+ return /* @__PURE__ */ jsx(PdfBlockV2, { href: url, title, onOpen: onPdfClick });
3627
+ }
3628
+ return /* @__PURE__ */ jsx("a", { href, target: "_blank", rel: "noopener noreferrer", children });
3629
+ },
3684
3630
  img: ({ src, alt }) => /* @__PURE__ */ jsx(
3685
3631
  MarkdownImageV2,
3686
3632
  {
@@ -3701,13 +3647,14 @@ function MarkdownRendererV2({
3701
3647
  content,
3702
3648
  isStreaming,
3703
3649
  isResolvingImages,
3704
- onImageClick
3650
+ onImageClick,
3651
+ onPdfClick
3705
3652
  }) {
3706
3653
  const isResolvingRef = useRef(isResolvingImages);
3707
3654
  isResolvingRef.current = isResolvingImages;
3708
3655
  const components = useMemo(
3709
- () => buildComponents(onImageClick, isResolvingRef),
3710
- [onImageClick]
3656
+ () => buildComponents(onImageClick, isResolvingRef, onPdfClick),
3657
+ [onImageClick, onPdfClick]
3711
3658
  );
3712
3659
  return /* @__PURE__ */ jsx(
3713
3660
  "div",
@@ -3972,6 +3919,199 @@ function FeedbackReasonModal({
3972
3919
  }
3973
3920
  ) : null });
3974
3921
  }
3922
+ var MIN_WIDTH = 320;
3923
+ var MAX_WIDTH_RATIO = 0.92;
3924
+ var DEFAULT_WIDTH = 680;
3925
+ function PdfSheetV2({ src, title, onClose }) {
3926
+ const [isMounted, setIsMounted] = useState(false);
3927
+ const [isLoaded, setIsLoaded] = useState(false);
3928
+ const [width, setWidth] = useState(DEFAULT_WIDTH);
3929
+ const panelRef = useRef(null);
3930
+ const isDragging = useRef(false);
3931
+ const dragStartX = useRef(0);
3932
+ const dragStartWidth = useRef(0);
3933
+ useEffect(() => {
3934
+ setIsMounted(true);
3935
+ return () => setIsMounted(false);
3936
+ }, []);
3937
+ useEffect(() => {
3938
+ setIsLoaded(false);
3939
+ }, [src]);
3940
+ useEffect(() => {
3941
+ const onResize = () => {
3942
+ const max = Math.floor(window.innerWidth * MAX_WIDTH_RATIO);
3943
+ setWidth((w) => Math.min(w, max));
3944
+ };
3945
+ window.addEventListener("resize", onResize);
3946
+ return () => window.removeEventListener("resize", onResize);
3947
+ }, []);
3948
+ const handleKeyDown = useCallback(
3949
+ (e) => {
3950
+ if (e.key === "Escape") onClose();
3951
+ },
3952
+ [onClose]
3953
+ );
3954
+ useEffect(() => {
3955
+ if (!src || typeof document === "undefined") return;
3956
+ document.addEventListener("keydown", handleKeyDown);
3957
+ const previousOverflow = document.body.style.overflow;
3958
+ document.body.style.overflow = "hidden";
3959
+ return () => {
3960
+ document.removeEventListener("keydown", handleKeyDown);
3961
+ document.body.style.overflow = previousOverflow;
3962
+ };
3963
+ }, [src, handleKeyDown]);
3964
+ const handleDownload = () => {
3965
+ if (!src || typeof document === "undefined") return;
3966
+ const a = document.createElement("a");
3967
+ a.href = src;
3968
+ a.download = title ? `${title}.pdf` : "document.pdf";
3969
+ document.body.appendChild(a);
3970
+ a.click();
3971
+ a.remove();
3972
+ };
3973
+ const onResizeMouseDown = (e) => {
3974
+ e.preventDefault();
3975
+ isDragging.current = true;
3976
+ dragStartX.current = e.clientX;
3977
+ dragStartWidth.current = panelRef.current?.offsetWidth ?? width;
3978
+ document.body.style.cursor = "ew-resize";
3979
+ document.body.style.userSelect = "none";
3980
+ };
3981
+ useEffect(() => {
3982
+ const onMouseMove = (e) => {
3983
+ if (!isDragging.current || !panelRef.current) return;
3984
+ const delta = dragStartX.current - e.clientX;
3985
+ const maxW = Math.floor(window.innerWidth * MAX_WIDTH_RATIO);
3986
+ const newW = Math.max(MIN_WIDTH, Math.min(maxW, dragStartWidth.current + delta));
3987
+ panelRef.current.style.width = `${newW}px`;
3988
+ };
3989
+ const onMouseUp = () => {
3990
+ if (!isDragging.current) return;
3991
+ isDragging.current = false;
3992
+ document.body.style.cursor = "";
3993
+ document.body.style.userSelect = "";
3994
+ if (panelRef.current) {
3995
+ setWidth(panelRef.current.offsetWidth);
3996
+ }
3997
+ };
3998
+ document.addEventListener("mousemove", onMouseMove);
3999
+ document.addEventListener("mouseup", onMouseUp);
4000
+ return () => {
4001
+ document.removeEventListener("mousemove", onMouseMove);
4002
+ document.removeEventListener("mouseup", onMouseUp);
4003
+ };
4004
+ }, []);
4005
+ if (!isMounted || typeof document === "undefined") return null;
4006
+ return createPortal(
4007
+ /* @__PURE__ */ jsx(AnimatePresence, { children: src ? /* @__PURE__ */ jsxs(Fragment, { children: [
4008
+ /* @__PURE__ */ jsx(
4009
+ motion.div,
4010
+ {
4011
+ className: "payman-v2-pdf-sheet-overlay",
4012
+ initial: { opacity: 0 },
4013
+ animate: { opacity: 1 },
4014
+ exit: { opacity: 0 },
4015
+ transition: { duration: 0.22 },
4016
+ onClick: onClose,
4017
+ "aria-hidden": "true"
4018
+ },
4019
+ "pdf-sheet-backdrop"
4020
+ ),
4021
+ /* @__PURE__ */ jsxs(
4022
+ motion.div,
4023
+ {
4024
+ ref: panelRef,
4025
+ className: "payman-v2-pdf-sheet",
4026
+ style: { width },
4027
+ initial: { x: "100%" },
4028
+ animate: { x: 0 },
4029
+ exit: { x: "100%" },
4030
+ transition: {
4031
+ type: "spring",
4032
+ stiffness: 340,
4033
+ damping: 34,
4034
+ mass: 0.85
4035
+ },
4036
+ role: "dialog",
4037
+ "aria-modal": "true",
4038
+ "aria-label": title || "PDF Preview",
4039
+ children: [
4040
+ /* @__PURE__ */ jsx(
4041
+ "div",
4042
+ {
4043
+ className: "payman-v2-pdf-sheet-resize-handle",
4044
+ onMouseDown: onResizeMouseDown,
4045
+ "aria-hidden": "true",
4046
+ children: /* @__PURE__ */ jsx("div", { className: "payman-v2-pdf-sheet-resize-grip" })
4047
+ }
4048
+ ),
4049
+ /* @__PURE__ */ jsxs("div", { className: "payman-v2-pdf-sheet-header", children: [
4050
+ /* @__PURE__ */ jsxs("div", { className: "payman-v2-pdf-sheet-header-left", children: [
4051
+ /* @__PURE__ */ jsx("div", { className: "payman-v2-pdf-sheet-file-icon", children: /* @__PURE__ */ jsx(FileText, { size: 14, strokeWidth: 1.75 }) }),
4052
+ /* @__PURE__ */ jsx("span", { className: "payman-v2-pdf-sheet-title", title, children: title || "Document" })
4053
+ ] }),
4054
+ /* @__PURE__ */ jsxs("div", { className: "payman-v2-pdf-sheet-header-actions", children: [
4055
+ /* @__PURE__ */ jsxs(
4056
+ "button",
4057
+ {
4058
+ type: "button",
4059
+ className: "payman-v2-pdf-sheet-download-btn",
4060
+ "aria-label": "Download PDF",
4061
+ onClick: handleDownload,
4062
+ children: [
4063
+ /* @__PURE__ */ jsx(Download, { size: 13, strokeWidth: 2 }),
4064
+ /* @__PURE__ */ jsx("span", { children: "Download" })
4065
+ ]
4066
+ }
4067
+ ),
4068
+ /* @__PURE__ */ jsx(
4069
+ "button",
4070
+ {
4071
+ type: "button",
4072
+ className: "payman-v2-pdf-sheet-close-btn",
4073
+ "aria-label": "Close preview",
4074
+ onClick: onClose,
4075
+ children: /* @__PURE__ */ jsx(X, { size: 15, strokeWidth: 2.25 })
4076
+ }
4077
+ )
4078
+ ] })
4079
+ ] }),
4080
+ /* @__PURE__ */ jsxs("div", { className: "payman-v2-pdf-sheet-body", children: [
4081
+ !isLoaded && /* @__PURE__ */ jsxs("div", { className: "payman-v2-pdf-sheet-loading", children: [
4082
+ /* @__PURE__ */ jsx(
4083
+ Loader2,
4084
+ {
4085
+ size: 20,
4086
+ strokeWidth: 2,
4087
+ style: {
4088
+ animation: "payman-v2-spin 0.65s linear infinite",
4089
+ color: "var(--payman-v2-text-3)"
4090
+ }
4091
+ }
4092
+ ),
4093
+ /* @__PURE__ */ jsx("p", { className: "payman-v2-pdf-sheet-loading-text", children: "Loading PDF\u2026" })
4094
+ ] }),
4095
+ /* @__PURE__ */ jsx(
4096
+ "iframe",
4097
+ {
4098
+ src,
4099
+ title: title || "PDF Preview",
4100
+ className: "payman-v2-pdf-sheet-iframe",
4101
+ style: { opacity: isLoaded ? 1 : 0, transition: "opacity 0.3s ease" },
4102
+ onLoad: () => setIsLoaded(true)
4103
+ },
4104
+ src
4105
+ )
4106
+ ] })
4107
+ ]
4108
+ },
4109
+ "pdf-sheet-panel"
4110
+ )
4111
+ ] }) : null }),
4112
+ document.body
4113
+ );
4114
+ }
3975
4115
  var RESPONSE_SPEED = {
3976
4116
  normal: [2, 4],
3977
4117
  fast: 1,
@@ -4099,6 +4239,10 @@ function AssistantMessageV2({
4099
4239
  () => getFeedbackState(message)
4100
4240
  );
4101
4241
  const [reasonModalOpen, setReasonModalOpen] = useState(false);
4242
+ const [pdfSheet, setPdfSheet] = useState(null);
4243
+ const handlePdfClick = useCallback((href, title) => {
4244
+ setPdfSheet({ href, title });
4245
+ }, []);
4102
4246
  const canSubmitFeedback = !!onSubmitFeedback && !!message.executionId;
4103
4247
  const [toast, setToast] = useState(null);
4104
4248
  const copyResetTimerRef = useRef(null);
@@ -4296,7 +4440,8 @@ function AssistantMessageV2({
4296
4440
  content: displayContent,
4297
4441
  isStreaming: message.isStreaming && !isCancelled || isResponseTyping,
4298
4442
  isResolvingImages: message.isResolvingImages,
4299
- onImageClick
4443
+ onImageClick,
4444
+ onPdfClick: handlePdfClick
4300
4445
  }
4301
4446
  ) : !isThinkingStreaming ? /* @__PURE__ */ jsx("span", { className: "payman-v2-assistant-msg-placeholder", children: "..." }) : null }),
4302
4447
  isCancelled && message.isStreaming && /* @__PURE__ */ jsxs("div", { className: "payman-v2-assistant-msg-paused", children: [
@@ -4394,6 +4539,14 @@ function AssistantMessageV2({
4394
4539
  showToast("Thank you for your feedback", "success");
4395
4540
  }
4396
4541
  }
4542
+ ),
4543
+ /* @__PURE__ */ jsx(
4544
+ PdfSheetV2,
4545
+ {
4546
+ src: pdfSheet?.href ?? null,
4547
+ title: pdfSheet?.title ?? "",
4548
+ onClose: () => setPdfSheet(null)
4549
+ }
4397
4550
  )
4398
4551
  ] });
4399
4552
  }
@@ -6565,7 +6718,7 @@ var PaymanChatInner = forwardRef(function PaymanChatInner2({
6565
6718
  style,
6566
6719
  children: [
6567
6720
  children,
6568
- isChatDisabled ? disabledComponent || /* @__PURE__ */ jsx("div", { style: { flex: 1, display: "flex", alignItems: "center", justifyContent: "center", padding: "1rem" }, children: /* @__PURE__ */ jsx("div", { style: { textAlign: "center", color: "var(--payman-v2-text-3)", fontSize: "0.875rem" }, children: "Chat is currently disabled" }) }) : /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", children: isEmpty && !hasEverSentMessage ? /* @__PURE__ */ jsx(
6721
+ /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", children: isEmpty && !hasEverSentMessage ? /* @__PURE__ */ jsx(
6569
6722
  motion.div,
6570
6723
  {
6571
6724
  initial: { opacity: 1 },
@@ -6752,6 +6905,6 @@ var PaymanChat = forwardRef(
6752
6905
  }
6753
6906
  );
6754
6907
 
6755
- export { PaymanChat, PaymanChatContext, UserActionStaleError, buildContent, buildFormattedThinking, cancelUserAction, captureSentryError, classifyField, classifyUserActionKind, cn, coerceValue, createInitialV2State, defaultValueFor, formatDate, generateId, getOptions, isNestedOrUnsupported, isRequired, migrateActiveStream, processStreamEventV2, renderableFields, resendUserAction, streamWorkflowEvents, submitUserAction, useChatV2, usePaymanChat, useVoice, validateField, validateForm };
6908
+ export { PaymanChat, PaymanChatContext, UserActionStaleError, cancelUserAction, captureSentryError, cn, formatDate, resendUserAction, submitUserAction, useChatV2, usePaymanChat, useVoice };
6756
6909
  //# sourceMappingURL=index.mjs.map
6757
6910
  //# sourceMappingURL=index.mjs.map