@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.js CHANGED
@@ -819,66 +819,6 @@ function processStreamEventV2(rawEvent, state) {
819
819
  }
820
820
  return state;
821
821
  }
822
- function buildFormattedThinking(steps, allThinkingText) {
823
- const parts = [];
824
- const safeSteps = steps ?? [];
825
- const cleanAll = allThinkingText.replace(/^\s+/, "");
826
- if (cleanAll) {
827
- const firstStepWithThinking = safeSteps.find(
828
- (s) => s.thinkingText && s.thinkingText.trim()
829
- );
830
- if (!firstStepWithThinking) {
831
- parts.push("**Preflight**");
832
- parts.push(cleanAll);
833
- } else {
834
- const stepText = firstStepWithThinking.thinkingText.trim();
835
- const idx = cleanAll.indexOf(stepText);
836
- if (idx > 0) {
837
- const orphaned = cleanAll.substring(0, idx).replace(/\s+$/, "");
838
- if (orphaned) {
839
- parts.push("**Preflight**");
840
- parts.push(orphaned);
841
- }
842
- }
843
- }
844
- }
845
- for (const step of safeSteps) {
846
- switch (step.eventType) {
847
- case "STAGE_STARTED": {
848
- if (step.message) parts.push(`**${step.message}**`);
849
- break;
850
- }
851
- case "ORCHESTRATOR_THINKING":
852
- parts.push("**Planning**");
853
- if (step.message) parts.push(step.message);
854
- break;
855
- case "INTENT_STARTED": {
856
- let label = step.message || "Processing";
857
- const started = label.match(/^(.+?)\s+started$/i);
858
- const progress = label.match(/^(.+?)\s+in progress$/i);
859
- if (started) label = started[1];
860
- else if (progress) label = progress[1];
861
- parts.push(`**${label}**`);
862
- if (step.thinkingText) parts.push(step.thinkingText);
863
- break;
864
- }
865
- case "INTENT_PROGRESS": {
866
- if (step.thinkingText) parts.push(step.thinkingText);
867
- else if (step.message) parts.push(step.message);
868
- break;
869
- }
870
- case "AGGREGATOR_THINKING":
871
- parts.push("**Finalizing**");
872
- if (step.message) parts.push(step.message);
873
- break;
874
- case "USER_ACTION_REQUIRED":
875
- parts.push("**Action required**");
876
- if (step.message) parts.push(step.message);
877
- break;
878
- }
879
- }
880
- return parts.length > 0 ? parts.join("\n") : allThinkingText;
881
- }
882
822
  function createCancelledMessageUpdate(steps, currentMessage) {
883
823
  const updatedSteps = steps.map((step) => {
884
824
  if (step.status === "in_progress") {
@@ -2055,9 +1995,6 @@ function buildContent(schema, values) {
2055
1995
  }
2056
1996
  return content;
2057
1997
  }
2058
- function migrateActiveStream(oldUserId, newUserId) {
2059
- activeStreamStore.rename(oldUserId, newUserId);
2060
- }
2061
1998
  var PaymanChatContext = react.createContext(void 0);
2062
1999
  function usePaymanChat() {
2063
2000
  const context = react.useContext(PaymanChatContext);
@@ -2563,46 +2500,6 @@ function createMarkdownComponents(options = {}) {
2563
2500
  td: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("td", { className: "p-3 align-middle text-sm whitespace-nowrap", children })
2564
2501
  };
2565
2502
  }
2566
- function ThinkingBlock({ text }) {
2567
- const [isOpen, setIsOpen] = react.useState(false);
2568
- const hasContent = typeof text === "string" && text.trim().length > 0;
2569
- if (!hasContent) return null;
2570
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-1.5 mb-1.5", children: [
2571
- /* @__PURE__ */ jsxRuntime.jsxs(
2572
- "button",
2573
- {
2574
- type: "button",
2575
- onClick: () => setIsOpen((prev) => !prev),
2576
- className: "inline-flex items-center gap-1 text-[10px] payman-agent-thinking-toggle transition-colors",
2577
- "aria-expanded": isOpen,
2578
- "aria-label": isOpen ? "Collapse thought process" : "Expand thought process",
2579
- children: [
2580
- /* @__PURE__ */ jsxRuntime.jsx(
2581
- framerMotion.motion.div,
2582
- {
2583
- animate: { rotate: isOpen ? 180 : 0 },
2584
- transition: { duration: 0.15 },
2585
- className: "shrink-0",
2586
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "h-3 w-3" })
2587
- }
2588
- ),
2589
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Thought process" })
2590
- ]
2591
- }
2592
- ),
2593
- /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { initial: false, children: isOpen && /* @__PURE__ */ jsxRuntime.jsx(
2594
- framerMotion.motion.div,
2595
- {
2596
- initial: { height: 0, opacity: 0 },
2597
- animate: { height: "auto", opacity: 1 },
2598
- exit: { height: 0, opacity: 0 },
2599
- transition: { duration: 0.2, ease: "easeInOut" },
2600
- className: "overflow-hidden",
2601
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 payman-agent-thinking-block rounded-md p-2 overflow-y-auto overflow-x-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "m-0 text-xs payman-agent-thinking-block-text whitespace-pre-wrap leading-relaxed", children: text }) })
2602
- }
2603
- ) })
2604
- ] });
2605
- }
2606
2503
  var FRIENDLY_ERROR_MESSAGE2 = "Oops, something went wrong. Please try again.";
2607
2504
  function looksLikeRawError(text) {
2608
2505
  if (!text || text.length < 10) return false;
@@ -2645,8 +2542,6 @@ function AgentMessage({
2645
2542
  const completedWithNoContent = !isStreaming && !isCancelled && content.length === 0 && (message.streamProgress === "completed" || message.streamProgress === "error");
2646
2543
  const conflictErrorMessage = getConflictErrorMessage(message.errorDetails);
2647
2544
  const isError = !!conflictErrorMessage || (isFriendlyWorkflowError(message.errorDetails) || looksLikeRawError(content)) && !hasMeaningfulContent || completedWithNoContent;
2648
- const activeThinkingText = message.activeThinkingText;
2649
- const allThinkingText = message.allThinkingText;
2650
2545
  const currentStep = react.useMemo(
2651
2546
  () => message.steps?.find(
2652
2547
  (s) => s.id === currentExecutingStepId && s.status === "in_progress"
@@ -2689,7 +2584,7 @@ function AgentMessage({
2689
2584
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: wrapper, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-3.5 w-3.5 payman-agent-step-icon--error" }) });
2690
2585
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: wrapper, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-1.5 w-1.5 rounded-full payman-agent-step-icon--pending-dim" }) });
2691
2586
  };
2692
- const stepsListContent = hasSteps && /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { initial: false, children: isStepsExpanded && /* @__PURE__ */ jsxRuntime.jsxs(
2587
+ const stepsListContent = hasSteps && /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { initial: false, children: isStepsExpanded && /* @__PURE__ */ jsxRuntime.jsx(
2693
2588
  framerMotion.motion.div,
2694
2589
  {
2695
2590
  initial: { height: 0, opacity: 0 },
@@ -2697,37 +2592,34 @@ function AgentMessage({
2697
2592
  exit: { height: 0, opacity: 0 },
2698
2593
  transition: { duration: 0.2, ease: "easeInOut" },
2699
2594
  className: "overflow-hidden",
2700
- children: [
2701
- !isStreaming && allThinkingText?.trim() && /* @__PURE__ */ jsxRuntime.jsx(ThinkingBlock, { text: allThinkingText }),
2702
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pt-1.5", children: message.steps.map((step) => {
2703
- const isCurrentlyExecuting = step.id === currentExecutingStepId && step.status === "in_progress" && isStreaming && !isCancelled;
2704
- const hasTime = step.elapsedMs != null && step.elapsedMs > 0;
2705
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-1.5", children: [
2706
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-1.5 items-start", children: [
2707
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-px", children: renderStepIcon(step, isCurrentlyExecuting) }),
2708
- /* @__PURE__ */ jsxRuntime.jsx(
2709
- "span",
2710
- {
2711
- className: cn(
2712
- "text-xs leading-relaxed min-w-0 break-words",
2713
- isCurrentlyExecuting && "shimmer-text font-medium",
2714
- !isCurrentlyExecuting && step.status === "error" && "payman-agent-step-text--error",
2715
- !isCurrentlyExecuting && step.eventType === "USER_ACTION_SUCCESS" && "payman-agent-step-text--success",
2716
- !isCurrentlyExecuting && step.status === "completed" && "payman-agent-step-text--completed",
2717
- !isCurrentlyExecuting && step.status === "pending" && "payman-agent-step-text--pending",
2718
- !isCurrentlyExecuting && step.status === "in_progress" && "payman-agent-step-text--in-progress"
2719
- ),
2720
- children: step.message
2721
- }
2722
- )
2723
- ] }),
2724
- hasTime && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pl-[22px] mt-1", children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1 px-1.5 py-0.5 rounded-md payman-agent-step-time leading-none", children: [
2725
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Clock, { className: "h-2.5 w-2.5 shrink-0 payman-agent-step-time-icon" }),
2726
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-mono payman-agent-step-time-text", children: formatElapsedTime(step.elapsedMs) })
2727
- ] }) })
2728
- ] }, step.id);
2729
- }) })
2730
- ]
2595
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pt-1.5", children: message.steps.map((step) => {
2596
+ const isCurrentlyExecuting = step.id === currentExecutingStepId && step.status === "in_progress" && isStreaming && !isCancelled;
2597
+ const hasTime = step.elapsedMs != null && step.elapsedMs > 0;
2598
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-1.5", children: [
2599
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-1.5 items-start", children: [
2600
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-px", children: renderStepIcon(step, isCurrentlyExecuting) }),
2601
+ /* @__PURE__ */ jsxRuntime.jsx(
2602
+ "span",
2603
+ {
2604
+ className: cn(
2605
+ "text-xs leading-relaxed min-w-0 break-words",
2606
+ isCurrentlyExecuting && "shimmer-text font-medium",
2607
+ !isCurrentlyExecuting && step.status === "error" && "payman-agent-step-text--error",
2608
+ !isCurrentlyExecuting && step.eventType === "USER_ACTION_SUCCESS" && "payman-agent-step-text--success",
2609
+ !isCurrentlyExecuting && step.status === "completed" && "payman-agent-step-text--completed",
2610
+ !isCurrentlyExecuting && step.status === "pending" && "payman-agent-step-text--pending",
2611
+ !isCurrentlyExecuting && step.status === "in_progress" && "payman-agent-step-text--in-progress"
2612
+ ),
2613
+ children: step.message
2614
+ }
2615
+ )
2616
+ ] }),
2617
+ hasTime && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pl-[22px] mt-1", children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1 px-1.5 py-0.5 rounded-md payman-agent-step-time leading-none", children: [
2618
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Clock, { className: "h-2.5 w-2.5 shrink-0 payman-agent-step-time-icon" }),
2619
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-mono payman-agent-step-time-text", children: formatElapsedTime(step.elapsedMs) })
2620
+ ] }) })
2621
+ ] }, step.id);
2622
+ }) })
2731
2623
  }
2732
2624
  ) });
2733
2625
  const stepsToggleRef = react.useRef(null);
@@ -2808,22 +2700,13 @@ function AgentMessage({
2808
2700
  "text-sm leading-relaxed min-w-0 w-full break-words overflow-wrap-anywhere",
2809
2701
  showAgentName && "mt-1"
2810
2702
  ),
2811
- children: isStreaming && !content ? (
2812
- // Streaming without content show thinking/step indicator
2813
- activeThinkingText ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2 items-start", children: [
2814
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "h-4 w-4 mt-0.5 payman-agent-thinking-spinner animate-spin shrink-0" }),
2815
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm leading-relaxed min-w-0 break-words payman-agent-thinking-text whitespace-pre-wrap flex-1", children: [
2816
- activeThinkingText,
2817
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-block w-0.5 h-3.5 payman-agent-thinking-cursor animate-pulse ml-0.5 align-text-bottom" })
2818
- ] })
2819
- ] }) : currentStep ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-1.5 items-start", children: [
2820
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-0.5 shrink-0", children: renderStepIcon(currentStep, true) }),
2821
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm leading-relaxed min-w-0 break-words shimmer-text font-medium flex-1", children: currentStep.message })
2822
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2.5 items-start", children: [
2823
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "w-4 h-4 mt-0.5 payman-agent-thinking-spinner animate-spin shrink-0" }),
2824
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm payman-agent-thinking-text flex-1", children: currentMessage || "Thinking..." })
2825
- ] })
2826
- ) : isCancelled && !content ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2.5 items-start", children: [
2703
+ children: isStreaming && !content ? currentStep ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-1.5 items-start", children: [
2704
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-0.5 shrink-0", children: renderStepIcon(currentStep, true) }),
2705
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm leading-relaxed min-w-0 break-words shimmer-text font-medium flex-1", children: currentStep.message })
2706
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2.5 items-start", children: [
2707
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "w-4 h-4 mt-0.5 payman-agent-thinking-spinner animate-spin shrink-0" }),
2708
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm payman-agent-thinking-text flex-1", children: currentMessage || "Thinking..." })
2709
+ ] }) : isCancelled && !content ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2.5 items-start", children: [
2827
2710
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-4 h-4 mt-0.5 payman-agent-cancelled-icon shrink-0" }),
2828
2711
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm payman-agent-cancelled-text italic flex-1", children: currentMessage || "Request was stopped." })
2829
2712
  ] }) : /* @__PURE__ */ jsxRuntime.jsx(
@@ -3692,7 +3575,62 @@ function MarkdownImageV2({
3692
3575
  }
3693
3576
  ) });
3694
3577
  }
3695
- function buildComponents(onImageClick, isResolvingRef) {
3578
+ function PdfBlockV2({ title, href, onOpen }) {
3579
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3580
+ "button",
3581
+ {
3582
+ type: "button",
3583
+ className: "payman-v2-pdf-block",
3584
+ onClick: (e) => {
3585
+ e.preventDefault();
3586
+ onOpen(href, title);
3587
+ },
3588
+ "aria-label": `Open PDF: ${title}`,
3589
+ children: [
3590
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-v2-pdf-block-icon-area", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileText, { size: 18, strokeWidth: 1.5 }) }),
3591
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-pdf-block-body", children: [
3592
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-v2-pdf-block-name", children: title }),
3593
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-v2-pdf-block-sub", children: "PDF \xB7 Click to preview" })
3594
+ ] })
3595
+ ]
3596
+ }
3597
+ );
3598
+ }
3599
+ function isPdfUrl(href) {
3600
+ if (!href) return false;
3601
+ try {
3602
+ const url = new URL(href);
3603
+ const filename = url.searchParams.get("filename");
3604
+ if (filename?.toLowerCase().endsWith(".pdf")) return true;
3605
+ return url.pathname.toLowerCase().endsWith(".pdf");
3606
+ } catch {
3607
+ return href.toLowerCase().endsWith(".pdf");
3608
+ }
3609
+ }
3610
+ function getPdfTitleFromUrl(href) {
3611
+ try {
3612
+ const url = new URL(href);
3613
+ const filename = url.searchParams.get("filename");
3614
+ if (filename) {
3615
+ return filename.replace(/\.pdf$/i, "").replace(/[-_]+/g, " ").trim();
3616
+ }
3617
+ const parts = url.pathname.split("/").filter(Boolean);
3618
+ const last = parts[parts.length - 1];
3619
+ if (last) return decodeURIComponent(last).replace(/\.pdf$/i, "").replace(/[-_]+/g, " ").trim();
3620
+ } catch {
3621
+ }
3622
+ return "Document";
3623
+ }
3624
+ function childrenToText(children) {
3625
+ if (typeof children === "string") return children;
3626
+ if (typeof children === "number") return String(children);
3627
+ if (Array.isArray(children)) return children.map(childrenToText).join("");
3628
+ if (children && typeof children === "object" && "props" in children) {
3629
+ return childrenToText(children.props.children);
3630
+ }
3631
+ return "";
3632
+ }
3633
+ function buildComponents(onImageClick, isResolvingRef, onPdfClick) {
3696
3634
  return {
3697
3635
  p: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("p", { children }),
3698
3636
  code: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("code", { children }),
@@ -3707,7 +3645,15 @@ function buildComponents(onImageClick, isResolvingRef) {
3707
3645
  em: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("em", { children }),
3708
3646
  blockquote: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("blockquote", { children }),
3709
3647
  hr: () => /* @__PURE__ */ jsxRuntime.jsx("hr", {}),
3710
- a: ({ href, children }) => /* @__PURE__ */ jsxRuntime.jsx("a", { href, target: "_blank", rel: "noopener noreferrer", children }),
3648
+ a: ({ href, children }) => {
3649
+ const url = href ?? "";
3650
+ if (onPdfClick && isPdfUrl(url)) {
3651
+ const linkText = childrenToText(children).trim();
3652
+ const title = linkText || getPdfTitleFromUrl(url);
3653
+ return /* @__PURE__ */ jsxRuntime.jsx(PdfBlockV2, { href: url, title, onOpen: onPdfClick });
3654
+ }
3655
+ return /* @__PURE__ */ jsxRuntime.jsx("a", { href, target: "_blank", rel: "noopener noreferrer", children });
3656
+ },
3711
3657
  img: ({ src, alt }) => /* @__PURE__ */ jsxRuntime.jsx(
3712
3658
  MarkdownImageV2,
3713
3659
  {
@@ -3728,13 +3674,14 @@ function MarkdownRendererV2({
3728
3674
  content,
3729
3675
  isStreaming,
3730
3676
  isResolvingImages,
3731
- onImageClick
3677
+ onImageClick,
3678
+ onPdfClick
3732
3679
  }) {
3733
3680
  const isResolvingRef = react.useRef(isResolvingImages);
3734
3681
  isResolvingRef.current = isResolvingImages;
3735
3682
  const components = react.useMemo(
3736
- () => buildComponents(onImageClick, isResolvingRef),
3737
- [onImageClick]
3683
+ () => buildComponents(onImageClick, isResolvingRef, onPdfClick),
3684
+ [onImageClick, onPdfClick]
3738
3685
  );
3739
3686
  return /* @__PURE__ */ jsxRuntime.jsx(
3740
3687
  "div",
@@ -3999,6 +3946,199 @@ function FeedbackReasonModal({
3999
3946
  }
4000
3947
  ) : null });
4001
3948
  }
3949
+ var MIN_WIDTH = 320;
3950
+ var MAX_WIDTH_RATIO = 0.92;
3951
+ var DEFAULT_WIDTH = 680;
3952
+ function PdfSheetV2({ src, title, onClose }) {
3953
+ const [isMounted, setIsMounted] = react.useState(false);
3954
+ const [isLoaded, setIsLoaded] = react.useState(false);
3955
+ const [width, setWidth] = react.useState(DEFAULT_WIDTH);
3956
+ const panelRef = react.useRef(null);
3957
+ const isDragging = react.useRef(false);
3958
+ const dragStartX = react.useRef(0);
3959
+ const dragStartWidth = react.useRef(0);
3960
+ react.useEffect(() => {
3961
+ setIsMounted(true);
3962
+ return () => setIsMounted(false);
3963
+ }, []);
3964
+ react.useEffect(() => {
3965
+ setIsLoaded(false);
3966
+ }, [src]);
3967
+ react.useEffect(() => {
3968
+ const onResize = () => {
3969
+ const max = Math.floor(window.innerWidth * MAX_WIDTH_RATIO);
3970
+ setWidth((w) => Math.min(w, max));
3971
+ };
3972
+ window.addEventListener("resize", onResize);
3973
+ return () => window.removeEventListener("resize", onResize);
3974
+ }, []);
3975
+ const handleKeyDown = react.useCallback(
3976
+ (e) => {
3977
+ if (e.key === "Escape") onClose();
3978
+ },
3979
+ [onClose]
3980
+ );
3981
+ react.useEffect(() => {
3982
+ if (!src || typeof document === "undefined") return;
3983
+ document.addEventListener("keydown", handleKeyDown);
3984
+ const previousOverflow = document.body.style.overflow;
3985
+ document.body.style.overflow = "hidden";
3986
+ return () => {
3987
+ document.removeEventListener("keydown", handleKeyDown);
3988
+ document.body.style.overflow = previousOverflow;
3989
+ };
3990
+ }, [src, handleKeyDown]);
3991
+ const handleDownload = () => {
3992
+ if (!src || typeof document === "undefined") return;
3993
+ const a = document.createElement("a");
3994
+ a.href = src;
3995
+ a.download = title ? `${title}.pdf` : "document.pdf";
3996
+ document.body.appendChild(a);
3997
+ a.click();
3998
+ a.remove();
3999
+ };
4000
+ const onResizeMouseDown = (e) => {
4001
+ e.preventDefault();
4002
+ isDragging.current = true;
4003
+ dragStartX.current = e.clientX;
4004
+ dragStartWidth.current = panelRef.current?.offsetWidth ?? width;
4005
+ document.body.style.cursor = "ew-resize";
4006
+ document.body.style.userSelect = "none";
4007
+ };
4008
+ react.useEffect(() => {
4009
+ const onMouseMove = (e) => {
4010
+ if (!isDragging.current || !panelRef.current) return;
4011
+ const delta = dragStartX.current - e.clientX;
4012
+ const maxW = Math.floor(window.innerWidth * MAX_WIDTH_RATIO);
4013
+ const newW = Math.max(MIN_WIDTH, Math.min(maxW, dragStartWidth.current + delta));
4014
+ panelRef.current.style.width = `${newW}px`;
4015
+ };
4016
+ const onMouseUp = () => {
4017
+ if (!isDragging.current) return;
4018
+ isDragging.current = false;
4019
+ document.body.style.cursor = "";
4020
+ document.body.style.userSelect = "";
4021
+ if (panelRef.current) {
4022
+ setWidth(panelRef.current.offsetWidth);
4023
+ }
4024
+ };
4025
+ document.addEventListener("mousemove", onMouseMove);
4026
+ document.addEventListener("mouseup", onMouseUp);
4027
+ return () => {
4028
+ document.removeEventListener("mousemove", onMouseMove);
4029
+ document.removeEventListener("mouseup", onMouseUp);
4030
+ };
4031
+ }, []);
4032
+ if (!isMounted || typeof document === "undefined") return null;
4033
+ return reactDom.createPortal(
4034
+ /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: src ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4035
+ /* @__PURE__ */ jsxRuntime.jsx(
4036
+ framerMotion.motion.div,
4037
+ {
4038
+ className: "payman-v2-pdf-sheet-overlay",
4039
+ initial: { opacity: 0 },
4040
+ animate: { opacity: 1 },
4041
+ exit: { opacity: 0 },
4042
+ transition: { duration: 0.22 },
4043
+ onClick: onClose,
4044
+ "aria-hidden": "true"
4045
+ },
4046
+ "pdf-sheet-backdrop"
4047
+ ),
4048
+ /* @__PURE__ */ jsxRuntime.jsxs(
4049
+ framerMotion.motion.div,
4050
+ {
4051
+ ref: panelRef,
4052
+ className: "payman-v2-pdf-sheet",
4053
+ style: { width },
4054
+ initial: { x: "100%" },
4055
+ animate: { x: 0 },
4056
+ exit: { x: "100%" },
4057
+ transition: {
4058
+ type: "spring",
4059
+ stiffness: 340,
4060
+ damping: 34,
4061
+ mass: 0.85
4062
+ },
4063
+ role: "dialog",
4064
+ "aria-modal": "true",
4065
+ "aria-label": title || "PDF Preview",
4066
+ children: [
4067
+ /* @__PURE__ */ jsxRuntime.jsx(
4068
+ "div",
4069
+ {
4070
+ className: "payman-v2-pdf-sheet-resize-handle",
4071
+ onMouseDown: onResizeMouseDown,
4072
+ "aria-hidden": "true",
4073
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-v2-pdf-sheet-resize-grip" })
4074
+ }
4075
+ ),
4076
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-pdf-sheet-header", children: [
4077
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-pdf-sheet-header-left", children: [
4078
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-v2-pdf-sheet-file-icon", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileText, { size: 14, strokeWidth: 1.75 }) }),
4079
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-v2-pdf-sheet-title", title, children: title || "Document" })
4080
+ ] }),
4081
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-pdf-sheet-header-actions", children: [
4082
+ /* @__PURE__ */ jsxRuntime.jsxs(
4083
+ "button",
4084
+ {
4085
+ type: "button",
4086
+ className: "payman-v2-pdf-sheet-download-btn",
4087
+ "aria-label": "Download PDF",
4088
+ onClick: handleDownload,
4089
+ children: [
4090
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Download, { size: 13, strokeWidth: 2 }),
4091
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Download" })
4092
+ ]
4093
+ }
4094
+ ),
4095
+ /* @__PURE__ */ jsxRuntime.jsx(
4096
+ "button",
4097
+ {
4098
+ type: "button",
4099
+ className: "payman-v2-pdf-sheet-close-btn",
4100
+ "aria-label": "Close preview",
4101
+ onClick: onClose,
4102
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { size: 15, strokeWidth: 2.25 })
4103
+ }
4104
+ )
4105
+ ] })
4106
+ ] }),
4107
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-pdf-sheet-body", children: [
4108
+ !isLoaded && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-pdf-sheet-loading", children: [
4109
+ /* @__PURE__ */ jsxRuntime.jsx(
4110
+ lucideReact.Loader2,
4111
+ {
4112
+ size: 20,
4113
+ strokeWidth: 2,
4114
+ style: {
4115
+ animation: "payman-v2-spin 0.65s linear infinite",
4116
+ color: "var(--payman-v2-text-3)"
4117
+ }
4118
+ }
4119
+ ),
4120
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "payman-v2-pdf-sheet-loading-text", children: "Loading PDF\u2026" })
4121
+ ] }),
4122
+ /* @__PURE__ */ jsxRuntime.jsx(
4123
+ "iframe",
4124
+ {
4125
+ src,
4126
+ title: title || "PDF Preview",
4127
+ className: "payman-v2-pdf-sheet-iframe",
4128
+ style: { opacity: isLoaded ? 1 : 0, transition: "opacity 0.3s ease" },
4129
+ onLoad: () => setIsLoaded(true)
4130
+ },
4131
+ src
4132
+ )
4133
+ ] })
4134
+ ]
4135
+ },
4136
+ "pdf-sheet-panel"
4137
+ )
4138
+ ] }) : null }),
4139
+ document.body
4140
+ );
4141
+ }
4002
4142
  var RESPONSE_SPEED = {
4003
4143
  normal: [2, 4],
4004
4144
  fast: 1,
@@ -4126,6 +4266,10 @@ function AssistantMessageV2({
4126
4266
  () => getFeedbackState(message)
4127
4267
  );
4128
4268
  const [reasonModalOpen, setReasonModalOpen] = react.useState(false);
4269
+ const [pdfSheet, setPdfSheet] = react.useState(null);
4270
+ const handlePdfClick = react.useCallback((href, title) => {
4271
+ setPdfSheet({ href, title });
4272
+ }, []);
4129
4273
  const canSubmitFeedback = !!onSubmitFeedback && !!message.executionId;
4130
4274
  const [toast, setToast] = react.useState(null);
4131
4275
  const copyResetTimerRef = react.useRef(null);
@@ -4323,7 +4467,8 @@ function AssistantMessageV2({
4323
4467
  content: displayContent,
4324
4468
  isStreaming: message.isStreaming && !isCancelled || isResponseTyping,
4325
4469
  isResolvingImages: message.isResolvingImages,
4326
- onImageClick
4470
+ onImageClick,
4471
+ onPdfClick: handlePdfClick
4327
4472
  }
4328
4473
  ) : !isThinkingStreaming ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-v2-assistant-msg-placeholder", children: "..." }) : null }),
4329
4474
  isCancelled && message.isStreaming && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-assistant-msg-paused", children: [
@@ -4421,6 +4566,14 @@ function AssistantMessageV2({
4421
4566
  showToast("Thank you for your feedback", "success");
4422
4567
  }
4423
4568
  }
4569
+ ),
4570
+ /* @__PURE__ */ jsxRuntime.jsx(
4571
+ PdfSheetV2,
4572
+ {
4573
+ src: pdfSheet?.href ?? null,
4574
+ title: pdfSheet?.title ?? "",
4575
+ onClose: () => setPdfSheet(null)
4576
+ }
4424
4577
  )
4425
4578
  ] });
4426
4579
  }
@@ -6592,7 +6745,7 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
6592
6745
  style,
6593
6746
  children: [
6594
6747
  children,
6595
- isChatDisabled ? disabledComponent || /* @__PURE__ */ jsxRuntime.jsx("div", { style: { flex: 1, display: "flex", alignItems: "center", justifyContent: "center", padding: "1rem" }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { textAlign: "center", color: "var(--payman-v2-text-3)", fontSize: "0.875rem" }, children: "Chat is currently disabled" }) }) : /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { mode: "wait", children: isEmpty && !hasEverSentMessage ? /* @__PURE__ */ jsxRuntime.jsx(
6748
+ /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { mode: "wait", children: isEmpty && !hasEverSentMessage ? /* @__PURE__ */ jsxRuntime.jsx(
6596
6749
  framerMotion.motion.div,
6597
6750
  {
6598
6751
  initial: { opacity: 1 },
@@ -6782,31 +6935,14 @@ var PaymanChat = react.forwardRef(
6782
6935
  exports.PaymanChat = PaymanChat;
6783
6936
  exports.PaymanChatContext = PaymanChatContext;
6784
6937
  exports.UserActionStaleError = UserActionStaleError;
6785
- exports.buildContent = buildContent;
6786
- exports.buildFormattedThinking = buildFormattedThinking;
6787
6938
  exports.cancelUserAction = cancelUserAction;
6788
6939
  exports.captureSentryError = captureSentryError;
6789
- exports.classifyField = classifyField;
6790
- exports.classifyUserActionKind = classifyUserActionKind;
6791
6940
  exports.cn = cn;
6792
- exports.coerceValue = coerceValue;
6793
- exports.createInitialV2State = createInitialV2State;
6794
- exports.defaultValueFor = defaultValueFor;
6795
6941
  exports.formatDate = formatDate;
6796
- exports.generateId = generateId;
6797
- exports.getOptions = getOptions;
6798
- exports.isNestedOrUnsupported = isNestedOrUnsupported;
6799
- exports.isRequired = isRequired;
6800
- exports.migrateActiveStream = migrateActiveStream;
6801
- exports.processStreamEventV2 = processStreamEventV2;
6802
- exports.renderableFields = renderableFields;
6803
6942
  exports.resendUserAction = resendUserAction;
6804
- exports.streamWorkflowEvents = streamWorkflowEvents;
6805
6943
  exports.submitUserAction = submitUserAction;
6806
6944
  exports.useChatV2 = useChatV2;
6807
6945
  exports.usePaymanChat = usePaymanChat;
6808
6946
  exports.useVoice = useVoice;
6809
- exports.validateField = validateField;
6810
- exports.validateForm = validateForm;
6811
6947
  //# sourceMappingURL=index.js.map
6812
6948
  //# sourceMappingURL=index.js.map