@copilotz/chat-ui 0.6.3 → 0.6.5

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
@@ -501,6 +501,8 @@ var CollapsibleContent2 = CollapsiblePrimitive.CollapsibleContent;
501
501
  // src/components/chat/AssistantActivity.tsx
502
502
  import { Brain, ChevronDown, ChevronRight, LoaderCircle, Sparkles, Wrench } from "lucide-react";
503
503
  import { jsx as jsx7, jsxs as jsxs2 } from "react/jsx-runtime";
504
+ var ROOT_SPACING_CLASS = "mb-4 w-full max-w-full min-w-0";
505
+ var ACTION_SLOT_CLASS = "inline-flex h-9 min-w-[132px] items-center justify-end px-2 text-xs";
504
506
  var interpolate = (template, replacements) => Object.entries(replacements).reduce(
505
507
  (output, [key, value]) => output.replaceAll(`{{${key}}}`, String(value ?? "")),
506
508
  template
@@ -528,45 +530,65 @@ var resolveSummaryLabel = (activity, labels) => {
528
530
  }
529
531
  return labels?.activityThinking || "Thinking...";
530
532
  };
531
- var getStatusIcon = (toolCall) => {
533
+ var getStatusBadge = (toolCall) => {
532
534
  if (toolCall.status === "failed") {
533
535
  return /* @__PURE__ */ jsx7(Badge, { variant: "destructive", children: "failed" });
534
536
  }
535
537
  if (toolCall.status === "completed") {
536
- return /* @__PURE__ */ jsx7(Badge, { variant: "secondary", className: "bg-emerald-500/10 text-emerald-700 dark:text-emerald-300", children: "done" });
538
+ return /* @__PURE__ */ jsx7(
539
+ Badge,
540
+ {
541
+ variant: "secondary",
542
+ className: "bg-emerald-500/10 text-emerald-700 dark:text-emerald-300",
543
+ children: "done"
544
+ }
545
+ );
537
546
  }
538
547
  if (toolCall.status === "running") {
539
548
  return /* @__PURE__ */ jsx7(Badge, { variant: "secondary", className: "bg-primary/10 text-primary", children: "running" });
540
549
  }
541
550
  return /* @__PURE__ */ jsx7(Badge, { variant: "secondary", children: "pending" });
542
551
  };
543
- var AssistantActivitySkeleton = memo(function AssistantActivitySkeleton2() {
544
- return /* @__PURE__ */ jsxs2("div", { className: "mb-4 flex items-center gap-3 rounded-lg border border-border/50 bg-muted/20 px-3 py-2", children: [
545
- /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-1.5", children: [
546
- /* @__PURE__ */ jsx7("span", { className: "inline-block h-2 w-2 rounded-full bg-primary/80 animate-pulse" }),
547
- /* @__PURE__ */ jsx7("span", { className: "inline-block h-2 w-2 rounded-full bg-primary/60 animate-pulse [animation-delay:120ms]" }),
548
- /* @__PURE__ */ jsx7("span", { className: "inline-block h-2 w-2 rounded-full bg-primary/40 animate-pulse [animation-delay:240ms]" })
549
- ] }),
550
- /* @__PURE__ */ jsx7("div", { className: "h-3 w-28 rounded-full bg-muted animate-pulse" })
551
- ] });
552
- });
553
- var AssistantActivitySummary = memo(function AssistantActivitySummary2({
552
+ var ActivitySummaryCard = memo(function ActivitySummaryCard2({
554
553
  activity,
555
554
  labels
556
555
  }) {
557
- const summaryLabel = useMemo(() => resolveSummaryLabel(activity, labels), [activity, labels]);
556
+ const label = useMemo(() => resolveSummaryLabel(activity, labels), [activity, labels]);
558
557
  const isActive = activity.isActive;
559
558
  const icon = activity.summary.kind === "using_tools" ? /* @__PURE__ */ jsx7(Wrench, { className: cn("h-4 w-4 shrink-0", isActive ? "text-primary" : "text-muted-foreground") }) : activity.summary.kind === "preparing_answer" ? /* @__PURE__ */ jsx7(Sparkles, { className: cn("h-4 w-4 shrink-0", isActive ? "text-primary" : "text-muted-foreground") }) : /* @__PURE__ */ jsx7(Brain, { className: cn("h-4 w-4 shrink-0", isActive ? "text-primary" : "text-muted-foreground") });
560
- return /* @__PURE__ */ jsxs2("div", { className: cn(
561
- "flex w-full min-w-0 items-center gap-2 rounded-lg border px-3 py-2 text-sm transition-colors",
562
- isActive ? "border-primary/30 bg-primary/5 text-foreground" : "border-border/60 bg-muted/20 text-muted-foreground"
563
- ), children: [
564
- icon,
565
- /* @__PURE__ */ jsx7("span", { className: "min-w-0 flex-1 truncate", children: summaryLabel }),
566
- isActive && /* @__PURE__ */ jsx7(LoaderCircle, { className: "h-4 w-4 shrink-0 animate-spin text-primary" })
559
+ return /* @__PURE__ */ jsxs2(
560
+ "div",
561
+ {
562
+ className: cn(
563
+ "flex w-full min-w-0 items-center gap-2 rounded-lg border px-3 py-2 text-sm transition-colors",
564
+ isActive ? "border-primary/30 bg-primary/5 text-foreground" : "border-border/60 bg-muted/20 text-muted-foreground"
565
+ ),
566
+ children: [
567
+ icon,
568
+ /* @__PURE__ */ jsx7("span", { className: "min-w-0 flex-1 truncate", children: label }),
569
+ isActive && /* @__PURE__ */ jsx7(LoaderCircle, { className: "h-4 w-4 shrink-0 animate-spin text-primary" })
570
+ ]
571
+ }
572
+ );
573
+ });
574
+ var ActivitySummaryRow = memo(function ActivitySummaryRow2({
575
+ activity,
576
+ labels,
577
+ hasDetails,
578
+ open
579
+ }) {
580
+ return /* @__PURE__ */ jsxs2("div", { className: "grid w-full min-w-0 grid-cols-[minmax(0,1fr)_auto] items-center gap-2", children: [
581
+ /* @__PURE__ */ jsx7("div", { className: "min-w-0", children: /* @__PURE__ */ jsx7(ActivitySummaryCard, { activity, labels }) }),
582
+ hasDetails ? /* @__PURE__ */ jsx7(CollapsibleTrigger2, { asChild: true, children: /* @__PURE__ */ jsxs2(Button, { variant: "ghost", size: "sm", className: cn(ACTION_SLOT_CLASS, "shrink-0 text-muted-foreground"), children: [
583
+ open ? labels?.activityHideDetails || "Hide details" : labels?.activityShowDetails || "Show details",
584
+ open ? /* @__PURE__ */ jsx7(ChevronDown, { className: "ml-1 h-3.5 w-3.5" }) : /* @__PURE__ */ jsx7(ChevronRight, { className: "ml-1 h-3.5 w-3.5" })
585
+ ] }) }) : /* @__PURE__ */ jsxs2("div", { "aria-hidden": "true", className: cn(ACTION_SLOT_CLASS, "pointer-events-none invisible shrink-0"), children: [
586
+ labels?.activityShowDetails || "Show details",
587
+ /* @__PURE__ */ jsx7(ChevronRight, { className: "ml-1 h-3.5 w-3.5" })
588
+ ] })
567
589
  ] });
568
590
  });
569
- var AssistantActivityDetails = memo(function AssistantActivityDetails2({
591
+ var ActivityDetails = memo(function ActivityDetails2({
570
592
  activity
571
593
  }) {
572
594
  return /* @__PURE__ */ jsxs2("div", { className: "space-y-3 pt-3", children: [
@@ -579,7 +601,7 @@ var AssistantActivityDetails = memo(function AssistantActivityDetails2({
579
601
  activity.toolCalls.map((toolCall) => /* @__PURE__ */ jsx7(Card, { className: "border-border/60 bg-background/70", children: /* @__PURE__ */ jsxs2(CardContent, { className: "space-y-2 px-3 py-3", children: [
580
602
  /* @__PURE__ */ jsxs2("div", { className: "flex items-center justify-between gap-3", children: [
581
603
  /* @__PURE__ */ jsx7("div", { className: "min-w-0", children: /* @__PURE__ */ jsx7("div", { className: "truncate text-sm font-medium", children: toolCall.name }) }),
582
- getStatusIcon(toolCall)
604
+ getStatusBadge(toolCall)
583
605
  ] }),
584
606
  /* @__PURE__ */ jsxs2("div", { className: "space-y-2", children: [
585
607
  /* @__PURE__ */ jsxs2("div", { children: [
@@ -595,6 +617,16 @@ var AssistantActivityDetails = memo(function AssistantActivityDetails2({
595
617
  ] })
596
618
  ] });
597
619
  });
620
+ var ActivitySkeleton = memo(function ActivitySkeleton2() {
621
+ return /* @__PURE__ */ jsx7("div", { className: ROOT_SPACING_CLASS, children: /* @__PURE__ */ jsxs2("div", { className: "flex w-full min-w-0 items-center gap-3 rounded-lg border border-border/50 bg-muted/20 px-3 py-2", children: [
622
+ /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-1.5", children: [
623
+ /* @__PURE__ */ jsx7("span", { className: "inline-block h-2 w-2 rounded-full bg-primary/80 animate-pulse" }),
624
+ /* @__PURE__ */ jsx7("span", { className: "inline-block h-2 w-2 rounded-full bg-primary/60 animate-pulse [animation-delay:120ms]" }),
625
+ /* @__PURE__ */ jsx7("span", { className: "inline-block h-2 w-2 rounded-full bg-primary/40 animate-pulse [animation-delay:240ms]" })
626
+ ] }),
627
+ /* @__PURE__ */ jsx7("div", { className: "h-3 w-28 rounded-full bg-muted animate-pulse" })
628
+ ] }) });
629
+ });
598
630
  var AssistantActivity = memo(function AssistantActivity2({
599
631
  activity,
600
632
  displayMode,
@@ -602,30 +634,41 @@ var AssistantActivity = memo(function AssistantActivity2({
602
634
  }) {
603
635
  if (!activity) return null;
604
636
  if (displayMode === "hidden") {
605
- return activity.isActive ? /* @__PURE__ */ jsx7(AssistantActivitySkeleton, {}) : null;
637
+ return activity.isActive ? /* @__PURE__ */ jsx7(ActivitySkeleton, {}) : null;
606
638
  }
607
639
  if (displayMode === "summary") {
608
- if (!activity.isActive && activity.isComplete) return null;
609
- return /* @__PURE__ */ jsx7("div", { className: "mb-4 w-full", children: /* @__PURE__ */ jsx7(AssistantActivitySummary, { activity, labels }) });
640
+ if (!activity.isActive && activity.isComplete) {
641
+ return null;
642
+ }
643
+ return /* @__PURE__ */ jsx7("div", { className: ROOT_SPACING_CLASS, children: /* @__PURE__ */ jsx7(ActivitySummaryCard, { activity, labels }) });
610
644
  }
611
645
  const hasDetails = Boolean(activity.reasoning) || Boolean(activity.toolCalls?.length);
612
- const defaultOpen = activity.isActive && hasDetails;
613
- const [open, setOpen] = useState(defaultOpen);
646
+ const [open, setOpen] = useState(activity.isActive && hasDetails);
614
647
  useEffect(() => {
615
648
  if (activity.isActive && hasDetails) {
616
649
  setOpen(true);
617
650
  }
618
651
  }, [activity.isActive, hasDetails]);
619
- return /* @__PURE__ */ jsx7("div", { className: "mb-4 w-full", children: /* @__PURE__ */ jsx7(Collapsible, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsxs2("div", { className: "space-y-2", children: [
620
- /* @__PURE__ */ jsxs2("div", { className: "grid w-full grid-cols-[minmax(0,1fr)_auto] items-center gap-2", children: [
621
- /* @__PURE__ */ jsx7("div", { className: "min-w-0 w-full", children: /* @__PURE__ */ jsx7(AssistantActivitySummary, { activity, labels }) }),
622
- hasDetails && /* @__PURE__ */ jsx7(CollapsibleTrigger2, { asChild: true, children: /* @__PURE__ */ jsxs2(Button, { variant: "ghost", size: "sm", className: "h-9 shrink-0 px-2 text-xs text-muted-foreground", children: [
623
- open ? labels?.activityHideDetails || "Hide details" : labels?.activityShowDetails || "Show details",
624
- open ? /* @__PURE__ */ jsx7(ChevronDown, { className: "ml-1 h-3.5 w-3.5" }) : /* @__PURE__ */ jsx7(ChevronRight, { className: "ml-1 h-3.5 w-3.5" })
625
- ] }) })
626
- ] }),
627
- hasDetails && /* @__PURE__ */ jsx7(CollapsibleContent2, { className: "overflow-hidden rounded-lg border border-border/60 bg-muted/10 px-3", children: /* @__PURE__ */ jsx7(AssistantActivityDetails, { activity }) })
628
- ] }) }) });
652
+ return /* @__PURE__ */ jsx7(
653
+ Collapsible,
654
+ {
655
+ open: hasDetails ? open : false,
656
+ onOpenChange: hasDetails ? setOpen : void 0,
657
+ className: ROOT_SPACING_CLASS,
658
+ children: /* @__PURE__ */ jsxs2("div", { className: "space-y-2", children: [
659
+ /* @__PURE__ */ jsx7(
660
+ ActivitySummaryRow,
661
+ {
662
+ activity,
663
+ labels,
664
+ hasDetails,
665
+ open
666
+ }
667
+ ),
668
+ hasDetails && /* @__PURE__ */ jsx7(CollapsibleContent2, { className: "w-full overflow-hidden rounded-lg border border-border/60 bg-muted/10 px-3", children: /* @__PURE__ */ jsx7(ActivityDetails, { activity }) })
669
+ ] })
670
+ }
671
+ );
629
672
  });
630
673
 
631
674
  // src/components/chat/Message.tsx
@@ -5036,6 +5079,25 @@ function getMessageSpeakerKey(message) {
5036
5079
  }
5037
5080
  return message.role;
5038
5081
  }
5082
+ function getAssistantSpeakerTokens(message) {
5083
+ if (!message || message.role !== "assistant") return [];
5084
+ const rawTokens = [message.senderAgentId, message.senderName].filter((value) => typeof value === "string" && value.trim().length > 0).map((value) => value.trim().toLowerCase());
5085
+ if (rawTokens.length > 0) {
5086
+ return Array.from(new Set(rawTokens));
5087
+ }
5088
+ return ["assistant"];
5089
+ }
5090
+ function canGroupMessages(previous, next) {
5091
+ if (previous.role !== next.role) {
5092
+ return false;
5093
+ }
5094
+ if (previous.role !== "assistant") {
5095
+ return getMessageSpeakerKey(previous) === getMessageSpeakerKey(next);
5096
+ }
5097
+ const previousTokens = getAssistantSpeakerTokens(previous);
5098
+ const nextTokens = getAssistantSpeakerTokens(next);
5099
+ return previousTokens.some((token) => nextTokens.includes(token));
5100
+ }
5039
5101
  var mergeToolCalls = (activities) => {
5040
5102
  const merged = /* @__PURE__ */ new Map();
5041
5103
  for (const activity of activities) {
@@ -5101,7 +5163,7 @@ var groupMessagesForRender = (messages) => {
5101
5163
  for (let index = 1; index < messages.length; index++) {
5102
5164
  const previous = currentGroup[currentGroup.length - 1];
5103
5165
  const next = messages[index];
5104
- if (previous.role === next.role && getMessageSpeakerKey(previous) === getMessageSpeakerKey(next)) {
5166
+ if (canGroupMessages(previous, next)) {
5105
5167
  currentGroup.push(next);
5106
5168
  continue;
5107
5169
  }