@docyrus/ui-pro-ai-assistant 0.8.1 → 0.8.3

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.
@@ -9,14 +9,15 @@ interface AgentConsentDialogProps {
9
9
  onApproved: () => void;
10
10
  /** Called when the user declines — should close the assistant. */
11
11
  onDeclined: () => void;
12
+ /**
13
+ * Element to portal the gate into. When provided (and `position: relative`),
14
+ * the overlay is constrained to that container instead of the viewport, so
15
+ * the consent gate stays inside the assistant panel rather than covering the
16
+ * whole page. Falls back to a viewport-fixed overlay when omitted.
17
+ */
18
+ container?: HTMLElement | null;
12
19
  t: (key: string) => string;
13
20
  }
14
- /**
15
- * Gates the assistant behind an agent's "Terms & Agreement" consent.
16
- *
17
- * Shown (non-closable) the first time an agent is used (`agent.consent` is
18
- * falsy). Only `super_admin` users can approve; everyone else sees the terms
19
- * but the Approve button stays disabled — mirroring the Vue `KvAssistantView`.
20
- */
21
- export declare function AgentConsentDialog({ pending, onApproved, onDeclined, t }: AgentConsentDialogProps): import("react/jsx-runtime").JSX.Element;
21
+ /** Agent "Terms & Agreement" consent gate. Only `super_admin` can approve. */
22
+ export declare function AgentConsentDialog({ pending, onApproved, onDeclined, container, t }: AgentConsentDialogProps): import("react/jsx-runtime").JSX.Element;
22
23
  export {};
@@ -33,16 +33,11 @@ interface UseAssistantApiReturn {
33
33
  * an in-flight tool call (e.g. switch to AdaptiveCard rendering).
34
34
  */
35
35
  agentTools: Array<Record<string, any>>;
36
- /**
37
- * Set when the active agent requires consent that has not been given yet
38
- * (`agent.consent` is falsy). `null` once consent is satisfied. Drives the
39
- * "Terms & Agreement" gate. Mirrors the Vue `KvAssistantView` consent flow.
40
- */
36
+ /** Set when the active agent needs consent (not yet given); `null` once satisfied. */
41
37
  consentRequiredFor: {
42
38
  agentId: string;
43
39
  deploymentId?: string;
44
40
  } | null;
45
- /** Clears the pending consent (call after approve, or to dismiss the gate). */
46
41
  setConsentRequiredFor: (value: {
47
42
  agentId: string;
48
43
  deploymentId?: string;
package/dist/index.js CHANGED
@@ -11,6 +11,7 @@ import { Tabs as Tabs$1, TabsList as TabsList$1, TabsTrigger as TabsTrigger$1, T
11
11
  import { cn } from '@docyrus/ui-pro-shared/lib/utils';
12
12
  import { DefaultChatTransport, lastAssistantMessageIsCompleteWithToolCalls } from 'ai';
13
13
  import { Pencil, PilcrowIcon, Heading1Icon, Heading2Icon, Heading3Icon, SquareIcon, ListIcon, ListOrderedIcon, ChevronDownIcon, Code2Icon, QuoteIcon, LightbulbIcon, Columns3Icon, GripVertical, FileUpIcon, TableIcon, ImageIcon, FilmIcon, AudioLinesIcon, TableOfContentsIcon, RadicalIcon, RectangleVerticalIcon, CalendarIcon, PlusIcon, FileCodeIcon, MinusIcon, ChevronRightIcon, ListTree, PenToolIcon, Link2Icon, Check, X, Copy, FilesIcon, Link, Text, ExternalLink, Unlink, Bold, Italic, Underline, Strikethrough, Code2, MoreHorizontal, ArrowLeftIcon, ArrowRightIcon, Minus, Plus, CircleArrowDown, Minimize2, Trash2, FileUp, CheckCircle2, FileText, Loader2, Wrench, CornerDownLeftIcon, PencilLineIcon, MessageSquareTextIcon, MessagesSquareIcon, ArrowUpIcon, CheckIcon, CaptionsIcon, ZoomInIcon, CircleArrowDownIcon, MoveUpRightIcon, MoreHorizontalIcon, Eye, PlusCircle, HelpCircle, Maximize2, Download, FileSpreadsheet, ChevronDown, ChevronLeft, ChevronRight, CheckCircle, XCircle, Search, Globe, User, ArrowRight, MapPin, CalendarClock, List, RefreshCw, FilePlus, XIcon, CornerUpLeftIcon, AlbumIcon, FeatherIcon, ListMinusIcon, ListPlusIcon, ListEnd, Wand, LanguagesIcon, BadgeHelpIcon, PenLineIcon, SearchIcon, MusicIcon, CompassIcon, SmileIcon, LeafIcon, ClockIcon, AppleIcon, FlagIcon, StarIcon, DeleteIcon, AlignLeft, AlignCenter, AlignRight, RotateCcw, AlertTriangle, AlertCircle, ArrowUpDown, ArrowDownToLine, PenLine, PencilIcon, TrashIcon, FileIcon, Star, ChevronsUpDown, FolderIcon, MessageSquare, Hash, Table, CheckSquare, Calendar as Calendar$1, Clock, Phone, Mail, Send, RefreshCcw, Undo2, ChevronsUpDownIcon, ChevronsRight, ChevronsLeft, CalendarDays, RefreshCwIcon, PaintRoller, MessageSquareText, ArrowLeft, Boxes, Users, Bot, Brain, Lightbulb, BookOpen, PenTool, SlidersHorizontal, Wand2, Mic, Code, Trash, Edit, Share, FolderInput, Archive, Building2, ShieldCheck, PanelLeft, NotebookText, CirclePlus, MoreVertical, FileSearch, Microscope, Ruler, AudioLines, BrainCircuit, Circle, Zap, Upload, ThumbsUp, ThumbsDown, Sun, Shield, Settings, Play, Pause, Moon, Menu, Lock, Info, Image, Home, Heart, Folder, Filter, File as File$1, CreditCard, Cog, Cloud, ChevronUp, Bookmark, Bell, Plug, Inbox, LayoutGrid, FolderOpen, LayoutDashboard, Table2, WandSparklesIcon, ArrowUpToLineIcon, BoldIcon, ItalicIcon, UnderlineIcon, StrikethroughIcon, HighlighterIcon, Undo2Icon, Redo2Icon, ArrowDownToLineIcon, AlignLeftIcon, AlignCenterIcon, AlignRightIcon, AlignJustifyIcon, ListOrdered, ListTodoIcon, ListCollapseIcon, Grid3x3Icon, Combine, Ungroup, ArrowUp, ArrowDown, Trash2Icon, LinkIcon, WrapText, OutdentIcon, IndentIcon, EyeIcon, PenIcon } from 'lucide-react';
14
+ import { Tooltip, Slot, DropdownMenu, Dialog, AlertDialog as AlertDialog$1, Popover, Separator, Toolbar as Toolbar$1 } from 'radix-ui';
14
15
  import { Message, AIMessageAvatar, MessageContent, MessageActions, MessageAction, AIConversation, AIConversationContent, MessageResponse, AIConversationScrollButton, Tool, ToolHeader, ToolContent, ToolInput, ToolOutput, CodeBlock, CodeBlockCopyButton, resolveToolIcon, PromptInputButton, PromptInput, PromptInputTextarea, PromptInputFooter, PromptInputTools, PromptInputSubmit, usePromptInputAttachments } from '@docyrus/ui-pro-shared/ai';
15
16
  import { AsyncTokenManager, RestApiClient } from '@docyrus/api-client';
16
17
  import { TooltipProvider as TooltipProvider$1, Tooltip as Tooltip$2, TooltipTrigger as TooltipTrigger$1, TooltipContent as TooltipContent$1 } from '@docyrus/ui-pro-shared/components/tooltip';
@@ -63,7 +64,6 @@ import { ResponsiveContainer, BarChart, CartesianGrid, XAxis, YAxis, Tooltip as
63
64
  import Markdown from 'react-markdown';
64
65
  import remarkGfm from 'remark-gfm';
65
66
  import { Progress } from '@docyrus/ui-pro-shared/components/progress';
66
- import { Tooltip, Slot, DropdownMenu, Dialog, AlertDialog as AlertDialog$1, Popover, Separator, Toolbar as Toolbar$1 } from 'radix-ui';
67
67
  import { Label as Label$1 } from '@docyrus/ui-pro-shared/components/label';
68
68
  import { Popover as Popover$2, PopoverTrigger as PopoverTrigger$1, PopoverContent as PopoverContent$1 } from '@docyrus/ui-pro-shared/components/popover';
69
69
  import { RadioGroup as RadioGroup$1, RadioGroupItem } from '@docyrus/ui-pro-shared/components/radio-group';
@@ -2756,6 +2756,7 @@ function AgentConsentDialog({
2756
2756
  pending,
2757
2757
  onApproved,
2758
2758
  onDeclined,
2759
+ container,
2759
2760
  t
2760
2761
  }) {
2761
2762
  const apiClient = useApiClient();
@@ -2795,38 +2796,52 @@ function AgentConsentDialog({
2795
2796
  });
2796
2797
  onDeclined();
2797
2798
  };
2798
- return /* @__PURE__ */ jsx(Dialog$1, { open: !!pending, children: /* @__PURE__ */ jsxs(
2799
- DialogContent,
2800
- {
2801
- showCloseButton: false,
2802
- onInteractOutside: (e) => e.preventDefault(),
2803
- onEscapeKeyDown: (e) => e.preventDefault(),
2804
- className: "z-[200] sm:max-w-lg",
2805
- children: [
2806
- /* @__PURE__ */ jsx(DialogHeader, { children: /* @__PURE__ */ jsx(DialogTitle, { children: t("agentConsent.title") }) }),
2807
- /* @__PURE__ */ jsx("div", { className: "max-h-[55vh] overflow-y-auto pr-1 text-sm", children: /* @__PURE__ */ jsx(MessageResponse, { children: t("agentConsent.body") }) }),
2808
- /* @__PURE__ */ jsxs(DialogFooter, { children: [
2809
- /* @__PURE__ */ jsx(
2810
- Button,
2811
- {
2812
- variant: "outline",
2813
- onClick: declineConsent,
2814
- disabled: loading,
2815
- children: t("agentConsent.decline")
2816
- }
2817
- ),
2818
- /* @__PURE__ */ jsx(
2819
- Button,
2820
- {
2821
- onClick: acceptConsent,
2822
- disabled: !canApprove || loading,
2823
- children: t("agentConsent.approve")
2824
- }
2825
- )
2826
- ] })
2827
- ]
2828
- }
2829
- ) });
2799
+ const scoped = !!container;
2800
+ return /* @__PURE__ */ jsx(Dialog.Root, { open: !!pending, children: /* @__PURE__ */ jsxs(Dialog.Portal, { container: container ?? void 0, children: [
2801
+ /* @__PURE__ */ jsx(
2802
+ Dialog.Overlay,
2803
+ {
2804
+ className: cn(
2805
+ "data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs isolate z-[200] inset-0",
2806
+ scoped ? "absolute" : "fixed"
2807
+ )
2808
+ }
2809
+ ),
2810
+ /* @__PURE__ */ jsxs(
2811
+ Dialog.Content,
2812
+ {
2813
+ onInteractOutside: (e) => e.preventDefault(),
2814
+ onEscapeKeyDown: (e) => e.preventDefault(),
2815
+ className: cn(
2816
+ "bg-background data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 ring-foreground/10 grid w-full max-w-[calc(100%-2rem)] gap-6 rounded-xl p-6 text-sm ring-1 duration-100 sm:max-w-lg top-1/2 inset-s-1/2 z-[200] -translate-x-1/2 rtl:translate-x-1/2 -translate-y-1/2 outline-none",
2817
+ scoped ? "absolute" : "fixed"
2818
+ ),
2819
+ children: [
2820
+ /* @__PURE__ */ jsx(DialogHeader, { children: /* @__PURE__ */ jsx(DialogTitle, { children: t("agentConsent.title") }) }),
2821
+ /* @__PURE__ */ jsx("div", { className: "max-h-[55vh] overflow-y-auto pr-1 text-sm", children: /* @__PURE__ */ jsx(MessageResponse, { children: t("agentConsent.body") }) }),
2822
+ /* @__PURE__ */ jsxs(DialogFooter, { children: [
2823
+ /* @__PURE__ */ jsx(
2824
+ Button,
2825
+ {
2826
+ variant: "outline",
2827
+ onClick: declineConsent,
2828
+ disabled: loading,
2829
+ children: t("agentConsent.decline")
2830
+ }
2831
+ ),
2832
+ /* @__PURE__ */ jsx(
2833
+ Button,
2834
+ {
2835
+ onClick: acceptConsent,
2836
+ disabled: !canApprove || loading,
2837
+ children: t("agentConsent.approve")
2838
+ }
2839
+ )
2840
+ ] })
2841
+ ]
2842
+ }
2843
+ )
2844
+ ] }) });
2830
2845
  }
2831
2846
  var pickAvatar = (raw) => {
2832
2847
  const candidate = raw?.agentAvatar ?? raw?.avatar;
@@ -36642,6 +36657,17 @@ var DocyAssistant = ({
36642
36657
  });
36643
36658
  const activeAgentMatchesDetails = agentDetailsForId === activeAgentId;
36644
36659
  const liveAgentDetails = activeAgentMatchesDetails ? agentDetails : null;
36660
+ const consentStatusUnknown = !!activeAgentId && !activeAgentMatchesDetails;
36661
+ const consentGated = !!consentRequiredFor || consentStatusUnknown;
36662
+ const [declinedConsentAgentId, setDeclinedConsentAgentId] = useState(null);
36663
+ const consentTabRef = useRef(activeTabId);
36664
+ if (consentTabRef.current !== activeTabId) {
36665
+ consentTabRef.current = activeTabId;
36666
+ if (declinedConsentAgentId !== null) setDeclinedConsentAgentId(null);
36667
+ }
36668
+ const consentDeclined = !!consentRequiredFor && declinedConsentAgentId === consentRequiredFor.agentId;
36669
+ const consentDialogPending = uiState.activeTab === 0 && !consentDeclined ? consentRequiredFor : null;
36670
+ const [consentScope, setConsentScope] = useState(null);
36645
36671
  useEffect(() => {
36646
36672
  if (!agentDetailsForId || !agentDetails) return;
36647
36673
  setTabs((prev) => {
@@ -37238,7 +37264,7 @@ var DocyAssistant = ({
37238
37264
  onClearAppContext: clearAppContext,
37239
37265
  chatError,
37240
37266
  onDismissChatError: () => setChatError(null),
37241
- consentRequired: !!consentRequiredFor,
37267
+ consentRequired: consentGated,
37242
37268
  initialModelId,
37243
37269
  initialFeatures,
37244
37270
  enableMicrophone,
@@ -37632,29 +37658,36 @@ var DocyAssistant = ({
37632
37658
  dataSourceId: BASE_DATA_SOURCE_ID.thread,
37633
37659
  recordId: sessionState.selectedSessionId
37634
37660
  }
37635
- ),
37636
- /* @__PURE__ */ jsx(
37637
- AgentConsentDialog,
37638
- {
37639
- pending: consentRequiredFor,
37640
- onApproved: () => setConsentRequiredFor(null),
37641
- onDeclined: () => {
37642
- onClose?.();
37643
- },
37644
- t
37645
- }
37646
37661
  )
37647
37662
  ] });
37663
+ const renderConsentDialog = (container) => /* @__PURE__ */ jsx(
37664
+ AgentConsentDialog,
37665
+ {
37666
+ pending: consentDialogPending,
37667
+ container,
37668
+ onApproved: () => {
37669
+ setConsentRequiredFor(null);
37670
+ setDeclinedConsentAgentId(null);
37671
+ },
37672
+ onDeclined: () => {
37673
+ setDeclinedConsentAgentId(consentRequiredFor?.agentId ?? null);
37674
+ },
37675
+ t
37676
+ }
37677
+ );
37648
37678
  if (isInlineMode) {
37649
37679
  return /* @__PURE__ */ jsxs(ClientToolsProvider, { tools: clientToolMap, children: [
37650
- renderInlineViewContent({
37651
- isFullscreen: isInlineFullscreen,
37652
- enableSidebar: isInlineFullscreen ? true : enableSidebar,
37653
- className,
37654
- onExpand: hideExpand ? void 0 : handleExpand,
37655
- isOpen,
37656
- viewRef: ref
37657
- }),
37680
+ /* @__PURE__ */ jsxs("div", { ref: setConsentScope, className: "relative flex h-full min-h-0 w-full flex-col", children: [
37681
+ renderInlineViewContent({
37682
+ isFullscreen: isInlineFullscreen,
37683
+ enableSidebar: isInlineFullscreen ? true : enableSidebar,
37684
+ className,
37685
+ onExpand: hideExpand ? void 0 : handleExpand,
37686
+ isOpen,
37687
+ viewRef: ref
37688
+ }),
37689
+ renderConsentDialog(consentScope)
37690
+ ] }),
37658
37691
  assistantDialogs
37659
37692
  ] });
37660
37693
  }
@@ -37703,13 +37736,16 @@ var DocyAssistant = ({
37703
37736
  },
37704
37737
  ...props,
37705
37738
  ref,
37706
- children: renderInlineViewContent({
37707
- isFullscreen: false,
37708
- enableSidebar,
37709
- className: cn("h-full w-full border-0 shadow-none", uiState.isExpanded || uiState.isDocked ? "rounded-none" : "rounded-xl"),
37710
- onExpand: handleExpand,
37711
- isOpen: true
37712
- })
37739
+ children: /* @__PURE__ */ jsxs("div", { ref: setConsentScope, className: "relative flex h-full min-h-0 w-full flex-col", children: [
37740
+ renderInlineViewContent({
37741
+ isFullscreen: false,
37742
+ enableSidebar,
37743
+ className: cn("h-full w-full border-0 shadow-none", uiState.isExpanded || uiState.isDocked ? "rounded-none" : "rounded-xl"),
37744
+ onExpand: handleExpand,
37745
+ isOpen: true
37746
+ }),
37747
+ renderConsentDialog(consentScope)
37748
+ ] })
37713
37749
  }
37714
37750
  )
37715
37751
  ] }),