@paymanai/payman-ask-sdk 1.2.19 → 1.2.20

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
@@ -8,6 +8,7 @@ import { Check, RotateCcw, Mic, ArrowUp, ArrowDown, X, Loader2, User, Clock, Spa
8
8
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
9
9
  import ReactMarkdown from 'react-markdown';
10
10
  import remarkGfm from 'remark-gfm';
11
+ import { createPortal } from 'react-dom';
11
12
 
12
13
  var PaymanChatContext = createContext(void 0);
13
14
  function usePaymanChat() {
@@ -315,6 +316,256 @@ function ChatInput({
315
316
  }
316
317
  );
317
318
  }
319
+ function ImageLightbox({
320
+ src,
321
+ alt = "",
322
+ onClose
323
+ }) {
324
+ const [isMounted, setIsMounted] = useState(false);
325
+ const [isImageLoaded, setIsImageLoaded] = useState(false);
326
+ const overlayStyle = {
327
+ position: "fixed",
328
+ inset: 0,
329
+ zIndex: 2147483647,
330
+ display: "flex",
331
+ alignItems: "center",
332
+ justifyContent: "center",
333
+ padding: 16,
334
+ background: "rgba(2, 6, 23, 0.92)",
335
+ isolation: "isolate"
336
+ };
337
+ const frameStyle = {
338
+ position: "relative",
339
+ width: "min(92vw, 1280px)",
340
+ height: "min(88vh, 920px)",
341
+ display: "flex",
342
+ alignItems: "center",
343
+ justifyContent: "center",
344
+ overflow: "hidden"
345
+ };
346
+ useEffect(() => {
347
+ setIsMounted(true);
348
+ return () => setIsMounted(false);
349
+ }, []);
350
+ useEffect(() => {
351
+ setIsImageLoaded(false);
352
+ }, [src]);
353
+ useEffect(() => {
354
+ if (typeof document === "undefined") return;
355
+ const previousOverflow = document.body.style.overflow;
356
+ document.body.style.overflow = "hidden";
357
+ return () => {
358
+ document.body.style.overflow = previousOverflow;
359
+ };
360
+ }, []);
361
+ useEffect(() => {
362
+ if (typeof document === "undefined") return;
363
+ const handleKeyDown = (event) => {
364
+ if (event.key === "Escape") {
365
+ onClose();
366
+ }
367
+ };
368
+ document.addEventListener("keydown", handleKeyDown);
369
+ return () => {
370
+ document.removeEventListener("keydown", handleKeyDown);
371
+ };
372
+ }, [onClose]);
373
+ if (!isMounted || typeof document === "undefined") {
374
+ return null;
375
+ }
376
+ return createPortal(
377
+ /* @__PURE__ */ jsx(AnimatePresence, { children: /* @__PURE__ */ jsxs(
378
+ motion.div,
379
+ {
380
+ style: overlayStyle,
381
+ initial: { opacity: 0 },
382
+ animate: { opacity: 1 },
383
+ exit: { opacity: 0 },
384
+ transition: { duration: 0.18 },
385
+ onClick: onClose,
386
+ children: [
387
+ /* @__PURE__ */ jsx(
388
+ "button",
389
+ {
390
+ type: "button",
391
+ onClick: onClose,
392
+ className: "absolute top-4 right-4 z-[1] flex h-9 w-9 items-center justify-center rounded-full bg-black/60 text-white/90 transition-colors hover:bg-black/75",
393
+ "aria-label": "Close",
394
+ children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
395
+ }
396
+ ),
397
+ /* @__PURE__ */ jsxs("div", { style: frameStyle, onClick: (event) => event.stopPropagation(), children: [
398
+ !isImageLoaded ? /* @__PURE__ */ jsxs("div", { className: "absolute inset-0 flex flex-col items-center justify-center gap-2", children: [
399
+ /* @__PURE__ */ jsx(Loader2, { className: "h-5 w-5 animate-spin text-white/80" }),
400
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-white/90", children: "Loading image" }),
401
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-white/60", children: "Reference image" })
402
+ ] }) : null,
403
+ /* @__PURE__ */ jsx("div", { className: "flex h-full w-full items-center justify-center p-3 sm:p-4", children: /* @__PURE__ */ jsx(
404
+ "img",
405
+ {
406
+ src,
407
+ alt,
408
+ draggable: false,
409
+ onLoad: () => setIsImageLoaded(true),
410
+ className: `block h-full w-full rounded-xl object-contain shadow-2xl transition-opacity duration-200 ${isImageLoaded ? "opacity-100" : "opacity-0"}`
411
+ }
412
+ ) })
413
+ ] })
414
+ ]
415
+ }
416
+ ) }),
417
+ document.body
418
+ );
419
+ }
420
+ var RAG_IMAGE_PATH_REGEX = /^(?:https?:\/\/[^/\s]+)?\/api\/rag\/chunks\/[^"'\s]+\/image(?:[?#][^"'\s]*)?$/;
421
+ function isUnresolvedRagImageSource(src) {
422
+ return RAG_IMAGE_PATH_REGEX.test(src);
423
+ }
424
+ function LoadingImageCard({
425
+ label,
426
+ description
427
+ }) {
428
+ return /* @__PURE__ */ jsxs("span", { className: "my-3 flex min-h-36 w-full flex-col items-center justify-center gap-2 px-4 py-5 text-center", children: [
429
+ /* @__PURE__ */ jsx(Loader2, { className: "h-5 w-5 animate-spin text-slate-500 dark:text-slate-300" }),
430
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-slate-600 dark:text-slate-200", children: label }),
431
+ /* @__PURE__ */ jsx("span", { className: "text-[11px] leading-relaxed text-slate-500/90 dark:text-slate-300/80", children: description })
432
+ ] });
433
+ }
434
+ function BrokenImageCard({ alt }) {
435
+ return /* @__PURE__ */ jsxs("span", { className: "my-3 flex min-h-44 w-full flex-col items-center justify-center gap-2 rounded-xl border border-dashed border-red-200 bg-red-50/60 px-4 py-5 text-center dark:border-red-900/40 dark:bg-red-950/20", children: [
436
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-red-600 dark:text-red-300", children: "Unable to load image" }),
437
+ alt ? /* @__PURE__ */ jsx("span", { className: "max-w-sm text-[11px] leading-relaxed text-red-500/80 dark:text-red-200/80", children: alt }) : null
438
+ ] });
439
+ }
440
+ function MarkdownImage({
441
+ src,
442
+ alt,
443
+ isResolving = false
444
+ }) {
445
+ const imageFrameStyle = {
446
+ width: "min(100%, 32rem)",
447
+ maxWidth: "100%"
448
+ };
449
+ const imageStyle = {
450
+ display: "block",
451
+ width: "100%",
452
+ height: "auto",
453
+ maxWidth: "100%",
454
+ maxHeight: "18rem",
455
+ objectFit: "contain"
456
+ };
457
+ const [isLoaded, setIsLoaded] = useState(false);
458
+ const [hasError, setHasError] = useState(false);
459
+ const [isLightboxOpen, setIsLightboxOpen] = useState(false);
460
+ const isUnresolvedRagImage = useMemo(
461
+ () => src ? isUnresolvedRagImageSource(src) : false,
462
+ [src]
463
+ );
464
+ const isResolvingRagImage = isResolving && isUnresolvedRagImage;
465
+ useEffect(() => {
466
+ setIsLoaded(false);
467
+ setHasError(false);
468
+ setIsLightboxOpen(false);
469
+ }, [src]);
470
+ if (!src) {
471
+ return null;
472
+ }
473
+ if (isResolvingRagImage) {
474
+ return /* @__PURE__ */ jsx(LoadingImageCard, { label: "Loading image", description: "Reference image" });
475
+ }
476
+ if (hasError) {
477
+ return /* @__PURE__ */ jsx(BrokenImageCard, { alt });
478
+ }
479
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
480
+ /* @__PURE__ */ jsx("span", { className: "my-3 block w-full", children: /* @__PURE__ */ jsx(
481
+ "button",
482
+ {
483
+ type: "button",
484
+ onClick: () => {
485
+ if (isLoaded) {
486
+ setIsLightboxOpen(true);
487
+ }
488
+ },
489
+ disabled: !isLoaded,
490
+ "aria-busy": !isLoaded,
491
+ className: "group relative mx-auto flex w-full items-center justify-center overflow-hidden rounded-xl bg-black/[0.03] px-3 py-3 text-left transition-colors hover:bg-black/[0.05] disabled:cursor-wait disabled:hover:bg-black/[0.03] dark:bg-white/[0.03] dark:hover:bg-white/[0.05] dark:disabled:hover:bg-white/[0.03]",
492
+ style: {
493
+ ...imageFrameStyle,
494
+ ...!isLoaded ? { minHeight: "9rem" } : {}
495
+ },
496
+ children: /* @__PURE__ */ jsx(
497
+ "img",
498
+ {
499
+ src,
500
+ alt: alt || "",
501
+ className: `relative z-[1] block h-auto max-h-[22rem] w-full max-w-full rounded-lg object-contain transition-opacity duration-200 ${isLoaded ? "opacity-100" : "opacity-0"}`,
502
+ style: imageStyle,
503
+ onLoad: () => {
504
+ setHasError(false);
505
+ setIsLoaded(true);
506
+ },
507
+ onError: () => {
508
+ setIsLoaded(false);
509
+ setHasError(true);
510
+ }
511
+ }
512
+ )
513
+ }
514
+ ) }),
515
+ isLightboxOpen && isLoaded ? /* @__PURE__ */ jsx(
516
+ ImageLightbox,
517
+ {
518
+ src,
519
+ alt,
520
+ onClose: () => setIsLightboxOpen(false)
521
+ }
522
+ ) : null
523
+ ] });
524
+ }
525
+ function createMarkdownComponents(options = {}) {
526
+ return {
527
+ p: ({ children }) => /* @__PURE__ */ jsx("p", { className: "mb-3 last:mb-0 text-sm leading-relaxed", children }),
528
+ code: ({ className: codeClassName, children }) => {
529
+ const isInline = !codeClassName;
530
+ return isInline ? /* @__PURE__ */ jsx("code", { className: "payman-agent-code-inline rounded-md px-1.5 py-0.5 font-mono text-xs break-all", children }) : /* @__PURE__ */ jsx("code", { className: "payman-agent-code-block my-2 block overflow-x-auto rounded-lg p-3 font-mono text-xs whitespace-pre", children });
531
+ },
532
+ pre: ({ children }) => /* @__PURE__ */ jsx("pre", { className: "my-2 max-w-full overflow-x-auto rounded-lg", children }),
533
+ ul: ({ children }) => /* @__PURE__ */ jsx("ul", { className: "mb-3 ml-4 list-disc space-y-1 text-sm", children }),
534
+ ol: ({ children }) => /* @__PURE__ */ jsx("ol", { className: "mb-3 ml-4 list-decimal space-y-1 text-sm", children }),
535
+ li: ({ children }) => /* @__PURE__ */ jsx("li", { className: "text-sm leading-relaxed", children }),
536
+ h1: ({ children }) => /* @__PURE__ */ jsx("h1", { className: "mt-4 mb-2 text-lg font-semibold first:mt-0", children }),
537
+ h2: ({ children }) => /* @__PURE__ */ jsx("h2", { className: "mt-3 mb-2 text-base font-semibold first:mt-0", children }),
538
+ h3: ({ children }) => /* @__PURE__ */ jsx("h3", { className: "mt-2 mb-1 text-sm font-semibold first:mt-0", children }),
539
+ strong: ({ children }) => /* @__PURE__ */ jsx("strong", { className: "font-semibold", children }),
540
+ em: ({ children }) => /* @__PURE__ */ jsx("em", { className: "italic", children }),
541
+ blockquote: ({ children }) => /* @__PURE__ */ jsx("blockquote", { className: "payman-agent-blockquote my-2 pl-4 italic", children }),
542
+ hr: () => /* @__PURE__ */ jsx("hr", { className: "payman-agent-hr my-4" }),
543
+ a: ({ href, children }) => /* @__PURE__ */ jsx(
544
+ "a",
545
+ {
546
+ href,
547
+ target: "_blank",
548
+ rel: "noopener noreferrer",
549
+ className: "payman-agent-link underline decoration-1 underline-offset-2",
550
+ children
551
+ }
552
+ ),
553
+ img: ({ src, alt }) => /* @__PURE__ */ jsx(
554
+ MarkdownImage,
555
+ {
556
+ src: typeof src === "string" ? src : void 0,
557
+ alt: typeof alt === "string" ? alt : void 0,
558
+ isResolving: options.isResolvingImages
559
+ }
560
+ ),
561
+ table: ({ children }) => /* @__PURE__ */ jsx("div", { className: "relative my-4 -mx-1 w-full overflow-x-auto", children: /* @__PURE__ */ jsx("table", { className: "payman-agent-table min-w-full caption-bottom overflow-hidden rounded-lg text-sm", children }) }),
562
+ thead: ({ children }) => /* @__PURE__ */ jsx("thead", { className: "payman-agent-thead [&_tr]:border-b", children }),
563
+ tbody: ({ children }) => /* @__PURE__ */ jsx("tbody", { className: "[&_tr:last-child]:border-0", children }),
564
+ tr: ({ children }) => /* @__PURE__ */ jsx("tr", { className: "payman-agent-tr border-b transition-colors", children }),
565
+ th: ({ children }) => /* @__PURE__ */ jsx("th", { className: "h-10 px-3 text-left align-middle text-xs font-medium whitespace-nowrap", children }),
566
+ td: ({ children }) => /* @__PURE__ */ jsx("td", { className: "p-3 align-middle text-sm whitespace-nowrap", children })
567
+ };
568
+ }
318
569
 
319
570
  // src/utils/errorMessages.ts
320
571
  var WORKFLOW_FAILED = "WORKFLOW_FAILED";
@@ -447,6 +698,12 @@ function AgentMessage({
447
698
  ),
448
699
  [message.steps, currentExecutingStepId]
449
700
  );
701
+ const markdownRenderers = useMemo(
702
+ () => createMarkdownComponents({
703
+ isResolvingImages: message.isResolvingImages
704
+ }),
705
+ [message.isResolvingImages]
706
+ );
450
707
  const getStepsLabel = (streaming) => {
451
708
  const count = message.steps.length;
452
709
  const stepWord = count === 1 ? "step" : "steps";
@@ -634,7 +891,7 @@ function AgentMessage({
634
891
  ReactMarkdown,
635
892
  {
636
893
  remarkPlugins: [remarkGfm],
637
- components: markdownComponents(),
894
+ components: markdownRenderers,
638
895
  children: isError ? conflictErrorMessage ?? FRIENDLY_ERROR_MESSAGE : content || (isStreaming ? "Thinking..." : isCancelled ? "Request was stopped." : "")
639
896
  }
640
897
  )
@@ -685,42 +942,6 @@ function AgentMessage({
685
942
  }
686
943
  return messageContent;
687
944
  }
688
- function markdownComponents(_isError) {
689
- return {
690
- p: ({ children }) => /* @__PURE__ */ jsx("p", { className: "mb-3 last:mb-0 text-sm leading-relaxed", children }),
691
- code: ({ className: codeClassName, children }) => {
692
- const isInline = !codeClassName;
693
- return isInline ? /* @__PURE__ */ jsx("code", { className: "px-1.5 py-0.5 rounded-md text-xs font-mono break-all payman-agent-code-inline", children }) : /* @__PURE__ */ jsx("code", { className: "block p-3 rounded-lg text-xs font-mono overflow-x-auto my-2 whitespace-pre payman-agent-code-block", children });
694
- },
695
- pre: ({ children }) => /* @__PURE__ */ jsx("pre", { className: "my-2 overflow-x-auto max-w-full rounded-lg", children }),
696
- ul: ({ children }) => /* @__PURE__ */ jsx("ul", { className: "list-disc ml-4 mb-3 space-y-1 text-sm", children }),
697
- ol: ({ children }) => /* @__PURE__ */ jsx("ol", { className: "list-decimal ml-4 mb-3 space-y-1 text-sm", children }),
698
- li: ({ children }) => /* @__PURE__ */ jsx("li", { className: "text-sm leading-relaxed", children }),
699
- h1: ({ children }) => /* @__PURE__ */ jsx("h1", { className: "text-lg font-semibold mb-2 mt-4 first:mt-0", children }),
700
- h2: ({ children }) => /* @__PURE__ */ jsx("h2", { className: "text-base font-semibold mb-2 mt-3 first:mt-0", children }),
701
- h3: ({ children }) => /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold mb-1 mt-2 first:mt-0", children }),
702
- strong: ({ children }) => /* @__PURE__ */ jsx("strong", { className: "font-semibold", children }),
703
- em: ({ children }) => /* @__PURE__ */ jsx("em", { className: "italic", children }),
704
- blockquote: ({ children }) => /* @__PURE__ */ jsx("blockquote", { className: "pl-4 my-2 italic payman-agent-blockquote", children }),
705
- hr: () => /* @__PURE__ */ jsx("hr", { className: "my-4 payman-agent-hr" }),
706
- a: ({ href, children }) => /* @__PURE__ */ jsx(
707
- "a",
708
- {
709
- href,
710
- target: "_blank",
711
- rel: "noopener noreferrer",
712
- className: "underline underline-offset-2 decoration-1 payman-agent-link",
713
- children
714
- }
715
- ),
716
- table: ({ children }) => /* @__PURE__ */ jsx("div", { className: "relative w-full overflow-x-auto my-4 -mx-1", children: /* @__PURE__ */ jsx("table", { className: "min-w-full caption-bottom text-sm rounded-lg overflow-hidden payman-agent-table", children }) }),
717
- thead: ({ children }) => /* @__PURE__ */ jsx("thead", { className: "[&_tr]:border-b payman-agent-thead", children }),
718
- tbody: ({ children }) => /* @__PURE__ */ jsx("tbody", { className: "[&_tr:last-child]:border-0", children }),
719
- tr: ({ children }) => /* @__PURE__ */ jsx("tr", { className: "border-b transition-colors payman-agent-tr", children }),
720
- th: ({ children }) => /* @__PURE__ */ jsx("th", { className: "h-10 px-3 text-left align-middle font-medium whitespace-nowrap text-xs", children }),
721
- td: ({ children }) => /* @__PURE__ */ jsx("td", { className: "p-3 align-middle text-sm whitespace-nowrap", children })
722
- };
723
- }
724
945
  function UserMessage({
725
946
  message,
726
947
  animated = false,