@copilotz/chat-ui 0.1.20 → 0.1.22

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.cjs CHANGED
@@ -630,6 +630,90 @@ var ThinkingIndicator = (0, import_react.memo)(function ThinkingIndicator2({ lab
630
630
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-sm text-muted-foreground animate-pulse", children: label })
631
631
  ] });
632
632
  });
633
+ var ThinkingBlock = (0, import_react.memo)(function ThinkingBlock2({ content, isStreaming = false, label = "Thinking", chunkSize = 12e3 }) {
634
+ const [open, setOpen] = (0, import_react.useState)(isStreaming);
635
+ const [thinkingActive, setThinkingActive] = (0, import_react.useState)(false);
636
+ const contentLenRef = (0, import_react.useRef)(0);
637
+ (0, import_react.useEffect)(() => {
638
+ if (!isStreaming) {
639
+ setThinkingActive(false);
640
+ contentLenRef.current = 0;
641
+ return;
642
+ }
643
+ if (content.length > contentLenRef.current) {
644
+ contentLenRef.current = content.length;
645
+ setThinkingActive(true);
646
+ }
647
+ }, [content.length, isStreaming]);
648
+ (0, import_react.useEffect)(() => {
649
+ if (!thinkingActive || !isStreaming) return;
650
+ const timer = setTimeout(() => setThinkingActive(false), 1e3);
651
+ return () => clearTimeout(timer);
652
+ }, [thinkingActive, isStreaming, content.length]);
653
+ (0, import_react.useEffect)(() => {
654
+ if (isStreaming && content.length > 0) setOpen(true);
655
+ }, [isStreaming, content.length]);
656
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mb-3 relative rounded-lg overflow-hidden", children: [
657
+ thinkingActive && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
658
+ "div",
659
+ {
660
+ className: "absolute inset-0 rounded-lg pointer-events-none",
661
+ style: {
662
+ padding: "1px",
663
+ background: "linear-gradient(135deg, hsl(var(--primary) / 0.4), hsl(var(--muted-foreground) / 0.2), hsl(var(--primary) / 0.4))",
664
+ backgroundSize: "200% 200%",
665
+ animation: "thinking-shimmer 2s ease-in-out infinite"
666
+ }
667
+ }
668
+ ),
669
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
670
+ "div",
671
+ {
672
+ className: `relative rounded-lg border bg-muted/30 ${thinkingActive ? "border-transparent" : "border-muted-foreground/20"}`,
673
+ style: thinkingActive ? { margin: "1px" } : void 0,
674
+ children: [
675
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
676
+ "button",
677
+ {
678
+ type: "button",
679
+ className: "flex w-full items-center gap-2 px-3 py-2 text-left text-xs font-medium text-muted-foreground hover:text-foreground/70 transition-colors",
680
+ onClick: () => setOpen((v) => !v),
681
+ children: [
682
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react.BrainCircuit, { className: `h-3.5 w-3.5 flex-shrink-0 ${thinkingActive ? "animate-pulse text-primary" : ""}` }),
683
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "flex-1", children: [
684
+ label,
685
+ thinkingActive && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "ml-1 inline-flex gap-0.5", children: [
686
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "inline-block w-1 h-1 bg-current rounded-full animate-bounce", style: { animationDelay: "0ms" } }),
687
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "inline-block w-1 h-1 bg-current rounded-full animate-bounce", style: { animationDelay: "150ms" } }),
688
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "inline-block w-1 h-1 bg-current rounded-full animate-bounce", style: { animationDelay: "300ms" } })
689
+ ] })
690
+ ] }),
691
+ open ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react.ChevronDown, { className: "h-3 w-3" }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react.ChevronRight, { className: "h-3 w-3" })
692
+ ]
693
+ }
694
+ ),
695
+ open && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "px-3 pb-3", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "border-l-2 border-muted-foreground/20 pl-3", children: [
696
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
697
+ PlainTextContent,
698
+ {
699
+ content,
700
+ className: "text-xs text-muted-foreground/80 leading-5",
701
+ chunkSize
702
+ }
703
+ ),
704
+ thinkingActive && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "inline-block w-1.5 h-3 bg-muted-foreground/40 animate-pulse ml-0.5" })
705
+ ] }) })
706
+ ]
707
+ }
708
+ ),
709
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("style", { children: `
710
+ @keyframes thinking-shimmer {
711
+ 0%, 100% { background-position: 0% 50%; }
712
+ 50% { background-position: 100% 50%; }
713
+ }
714
+ ` })
715
+ ] });
716
+ });
633
717
  var markdownComponents = {
634
718
  code: ({ node, className, children, ...props }) => {
635
719
  const inline = props.inline;
@@ -1020,6 +1104,15 @@ var Message = (0, import_react.memo)(({
1020
1104
  ] })
1021
1105
  ] })
1022
1106
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
1107
+ !messageIsUser && message.reasoning && message.reasoning.trim().length > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1108
+ ThinkingBlock,
1109
+ {
1110
+ content: message.reasoning,
1111
+ isStreaming: message.isStreaming,
1112
+ label: thinkingLabel,
1113
+ chunkSize: normalizedChunkChars
1114
+ }
1115
+ ),
1023
1116
  enableToolCallsDisplay && message.toolCalls && message.toolCalls.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "mb-3", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ToolCallsDisplay, { toolCalls: message.toolCalls, label: toolUsedLabel }) }),
1024
1117
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1025
1118
  StreamingText,