@juanpin/aicomponents
Version:
Components for AI, that I constantly use
797 lines (792 loc) • 27.7 kB
JavaScript
import { jsx as e, jsxs as d, Fragment as te } from "react/jsx-runtime";
import { ArrowDown as Re, X as ae, MessageCircle as Ae, Send as Me } from "lucide-react";
import * as x from "react";
import { useRef as v, useState as f, useCallback as F, useEffect as R } from "react";
import Te from "react-markdown";
import Le from "remark-gfm";
import { Slot as Ie } from "@radix-ui/react-slot";
import { cva as K } from "class-variance-authority";
import { clsx as Be } from "clsx";
import { twMerge as Pe } from "tailwind-merge";
import * as I from "@radix-ui/react-avatar";
import * as re from "@radix-ui/react-progress";
function g(...r) {
return Pe(Be(r));
}
const Fe = K(
"bb:inline-flex bb:items-center bb:justify-center bb:gap-2 bb:whitespace-nowrap bb:rounded-md bb:text-sm bb:font-medium bb:ring-offset-background bb:transition-colors focus-visible:bb:outline-none focus-visible:bb:ring-2 focus-visible:bb:ring-ring focus-visible:bb:ring-offset-2 disabled:bb:pointer-events-none disabled:bb:opacity-50 [&_svg]:bb:pointer-events-none [&_svg]:bb:size-4 [&_svg]:bb:shrink-0",
{
variants: {
variant: {
default: "bb:bg-primary bb:text-primary-foreground hover:bb:bg-primary/90",
destructive: "bb:bg-destructive bb:text-destructive-foreground hover:bb:bg-destructive/90",
outline: "bb:border bb:border-input bb:bg-background hover:bb:bg-accent hover:bb:text-accent-foreground",
secondary: "bb:bg-secondary bb:text-secondary-foreground hover:bb:bg-secondary/80",
ghost: "hover:bb:bg-accent hover:bb:text-accent-foreground",
link: "bb:text-primary bb:underline-offset-4 hover:bb:underline"
},
size: {
default: "bb:h-10 bb:px-4 bb:py-2",
sm: "bb:h-9 bb:rounded-md bb:px-3",
lg: "bb:h-11 bb:rounded-md bb:px-8",
icon: "bb:h-10 bb:w-10"
}
},
defaultVariants: {
variant: "default",
size: "default"
}
}
), L = x.forwardRef(
({ className: r, variant: t, size: n, asChild: a = !1, ...o }, h) => /* @__PURE__ */ e(
a ? Ie : "button",
{
className: g(Fe({ variant: t, size: n, className: r })),
ref: h,
...o
}
)
);
L.displayName = "Button";
const se = x.forwardRef(({ className: r, ...t }, n) => /* @__PURE__ */ e(
I.Root,
{
ref: n,
className: g("bb:relative bb:flex bb:h-10 bb:w-10 bb:shrink-0 bb:overflow-hidden bb:rounded-full", r),
...t
}
));
se.displayName = I.Root.displayName;
const be = x.forwardRef(({ className: r, ...t }, n) => /* @__PURE__ */ e(I.Image, { ref: n, className: g("bb:aspect-square bb:h-full bb:w-full", r), ...t }));
be.displayName = I.Image.displayName;
const le = x.forwardRef(({ className: r, ...t }, n) => /* @__PURE__ */ e(
I.Fallback,
{
ref: n,
className: g(
"bb:flex bb:h-full bb:w-full bb:items-center bb:justify-center bb:rounded-full bb:bg-muted",
r
),
...t
}
));
le.displayName = I.Fallback.displayName;
function Oe() {
return /* @__PURE__ */ d(
"svg",
{
width: "24",
height: "24",
viewBox: "0 0 24 24",
xmlns: "http://www.w3.org/2000/svg",
className: "bb:text-foreground",
"aria-label": "Loading...",
children: [
/* @__PURE__ */ e("circle", { cx: "4", cy: "12", r: "2", fill: "currentColor", children: /* @__PURE__ */ e(
"animate",
{
id: "spinner_qFRN",
begin: "0;spinner_OcgL.end+0.25s",
attributeName: "cy",
calcMode: "spline",
dur: "0.6s",
values: "12;6;12",
keySplines: ".33,.66,.66,1;.33,0,.66,.33"
}
) }),
/* @__PURE__ */ e("circle", { cx: "12", cy: "12", r: "2", fill: "currentColor", children: /* @__PURE__ */ e(
"animate",
{
begin: "spinner_qFRN.begin+0.1s",
attributeName: "cy",
calcMode: "spline",
dur: "0.6s",
values: "12;6;12",
keySplines: ".33,.66,.66,1;.33,0,.66,.33"
}
) }),
/* @__PURE__ */ e("circle", { cx: "20", cy: "12", r: "2", fill: "currentColor", children: /* @__PURE__ */ e(
"animate",
{
id: "spinner_OcgL",
begin: "spinner_qFRN.begin+0.2s",
attributeName: "cy",
calcMode: "spline",
dur: "0.6s",
values: "12;6;12",
keySplines: ".33,.66,.66,1;.33,0,.66,.33"
}
) })
]
}
);
}
const $e = K("bb:flex bb:gap-2 bb:max-w-[60%] bb:items-end bb:relative bb:group", {
variants: {
variant: {
received: "bb:self-start",
sent: "bb:self-end bb:flex-row-reverse"
},
layout: {
default: "",
ai: "bb:max-w-full bb:w-full bb:items-center"
}
},
defaultVariants: {
variant: "received",
layout: "default"
}
}), ie = x.forwardRef(
({ className: r, variant: t, layout: n, children: a, ...o }, h) => /* @__PURE__ */ e(
"div",
{
className: g($e({ variant: t, layout: n, className: r }), "bb:relative bb:group"),
ref: h,
...o,
children: x.Children.map(
a,
(s) => x.isValidElement(s) && typeof s.type != "string" ? x.cloneElement(s, {
variant: t,
layout: n
}) : s
)
}
)
);
ie.displayName = "ChatBubble";
const Ue = ({
src: r,
fallback: t,
className: n
}) => /* @__PURE__ */ d(se, { className: n, children: [
/* @__PURE__ */ e(be, { src: r, alt: "Avatar" }),
/* @__PURE__ */ e(le, { children: t })
] }), ze = K("bb:p-4", {
variants: {
variant: {
received: "bb:bg-secondary bb:text-secondary-foreground bb:rounded-r-lg bb:rounded-tl-lg",
sent: "bb:bg-primary bb:text-primary-foreground bb:rounded-l-lg bb:rounded-tr-lg"
},
layout: {
default: "",
ai: "bb:border-t bb:w-full bb:rounded-none bb:bg-transparent"
}
},
defaultVariants: {
variant: "received",
layout: "default"
}
}), ce = x.forwardRef(
({ className: r, variant: t, layout: n, isLoading: a = !1, children: o, ...h }, s) => /* @__PURE__ */ e(
"div",
{
className: g(
ze({ variant: t, layout: n, className: r }),
"bb:break-words bb:max-w-full bb:whitespace-pre-wrap"
),
ref: s,
...h,
children: a ? /* @__PURE__ */ e("div", { className: "bb:flex bb:items-center bb:space-x-2", children: /* @__PURE__ */ e(Oe, {}) }) : o
}
)
);
ce.displayName = "ChatBubbleMessage";
const _e = x.forwardRef(
({ variant: r, className: t, children: n, ...a }, o) => /* @__PURE__ */ e(
"div",
{
ref: o,
className: g(
"bb:absolute bb:top-1/2 bb:-translate-y-1/2 bb:flex bb:opacity-0 bb:group-hover:opacity-100 bb:transition-opacity bb:duration-200",
r === "sent" ? "bb:-left-1 bb:-translate-x-full bb:flex-row-reverse" : "bb:-right-1 bb:translate-x-full",
t
),
...a,
children: n
}
)
);
_e.displayName = "ChatBubbleActionWrapper";
const ue = x.forwardRef(({ className: r, ...t }, n) => /* @__PURE__ */ e(
"textarea",
{
className: g(
"bb:flex bb:min-h-[80px] bb:w-full bb:rounded-md bb:border bb:border-input bb:bg-background bb:px-3 bb:py-2 bb:text-base bb:ring-offset-background placeholder:bb:text-muted-foreground focus-visible:bb:outline-none focus-visible:bb:ring-2 focus-visible:bb:ring-ring focus-visible:bb:ring-offset-2 disabled:bb:cursor-not-allowed disabled:bb:opacity-50 bb:md:text-sm",
r
),
ref: n,
...t
}
));
ue.displayName = "Textarea";
const de = x.forwardRef(
// eslint-disable-next-line react/prop-types
({ className: r, ...t }, n) => /* @__PURE__ */ e(
ue,
{
autoComplete: "off",
ref: n,
name: "message",
className: g(
"bb:box-border bb:max-h-12 bb:px-4 bb:py-3 bb:bg-background bb:text-sm placeholder:bb:text-muted-foreground focus-visible:bb:outline-none focus-visible:bb:ring-ring disabled:bb:cursor-not-allowed disabled:bb:opacity-50 bb:w-full bb:rounded-md bb:flex bb:items-center bb:h-16 bb:resize-none",
r
),
...t
}
)
);
de.displayName = "ChatInput";
function He(r = {}) {
const { offset: t = 20, smooth: n = !1, content: a } = r, o = v(null), h = v(0), s = v(!1), [l, y] = f({
isAtBottom: !0,
autoScrollEnabled: !0
}), w = F(
(c) => {
const { scrollTop: m, scrollHeight: O, clientHeight: W } = c;
return Math.abs(
O - m - W
) <= t;
},
[t]
), N = F(
(c) => {
if (!o.current) return;
const m = o.current.scrollHeight - o.current.clientHeight;
c ? o.current.scrollTop = m : o.current.scrollTo({
top: m,
behavior: n ? "smooth" : "auto"
}), y({
isAtBottom: !0,
autoScrollEnabled: !0
}), s.current = !1;
},
[n]
), k = F(() => {
if (!o.current) return;
const c = w(o.current);
y((m) => ({
isAtBottom: c,
// Re-enable auto-scroll if at the bottom
autoScrollEnabled: c ? !0 : m.autoScrollEnabled
}));
}, [w]);
R(() => {
const c = o.current;
if (c)
return c.addEventListener("scroll", k, { passive: !0 }), () => c.removeEventListener("scroll", k);
}, [k]), R(() => {
const c = o.current;
if (!c) return;
const m = c.scrollHeight;
m !== h.current && (l.autoScrollEnabled && requestAnimationFrame(() => {
N(h.current === 0);
}), h.current = m);
}, [a, l.autoScrollEnabled, N]), R(() => {
const c = o.current;
if (!c) return;
const m = new ResizeObserver(() => {
l.autoScrollEnabled && N(!0);
});
return m.observe(c), () => m.disconnect();
}, [l.autoScrollEnabled, N]);
const E = F(() => {
(o.current ? w(o.current) : !1) || (s.current = !0, y((m) => ({
...m,
autoScrollEnabled: !1
})));
}, [w]);
return {
scrollRef: o,
isAtBottom: l.isAtBottom,
autoScrollEnabled: l.autoScrollEnabled,
scrollToBottom: () => N(!1),
disableAutoScroll: E
};
}
const me = x.forwardRef(
({ className: r, children: t, smooth: n = !1, ...a }, o) => {
const {
scrollRef: h,
isAtBottom: s,
scrollToBottom: l,
disableAutoScroll: y
} = He({
smooth: n,
content: t
});
return /* @__PURE__ */ d("div", { className: "bb:relative bb:w-full bb:h-full", children: [
/* @__PURE__ */ e(
"div",
{
className: `bb:box-border bb:flex bb:flex-col bb:w-full bb:h-full bb:p-4 bb:overflow-y-auto ${r}`,
ref: h,
onWheel: y,
onTouchMove: y,
...a,
children: /* @__PURE__ */ e("div", { className: "bb:flex bb:flex-col bb:gap-6", children: t })
}
),
!s && /* @__PURE__ */ e(
L,
{
onClick: () => {
l();
},
size: "icon",
variant: "outline",
className: "bb:absolute bb:bottom-2 bb:left-1/2 bb:transform bb:-translate-x-1/2 bb:inline-flex bb:rounded-full bb:shadow-md",
"aria-label": "Scroll to bottom",
children: /* @__PURE__ */ e(Re, { className: "bb:h-4 bb:w-4" })
}
)
] });
}
);
me.displayName = "ChatMessageList";
const P = {
dimensions: {
sm: "bb:sm:max-w-sm bb:sm:max-h-[500px]",
md: "bb:sm:max-w-md bb:sm:max-h-[600px]",
lg: "bb:sm:max-w-lg bb:sm:max-h-[700px]",
xl: "bb:sm:max-w-xl bb:sm:max-h-[800px]",
full: "bb:sm:w-full bb:sm:h-full"
},
positions: {
"bottom-right": "bb:bottom-5 bb:right-5",
"bottom-left": "bb:bottom-5 bb:left-5"
},
chatPositions: {
"bottom-right": "bb:sm:bottom-[calc(100%+10px)] bb:sm:right-0",
"bottom-left": "bb:sm:bottom-[calc(100%+10px)] bb:sm:left-0"
},
states: {
open: "bb:pointer-events-auto bb:opacity-100 bb:visible bb:scale-100 bb:translate-y-0",
closed: "bb:pointer-events-none bb:opacity-0 bb:invisible bb:scale-100 bb:sm:translate-y-5"
}
}, fe = ({
className: r,
position: t = "bottom-right",
size: n = "md",
icon: a,
isLoading: o = !1,
progressPercentage: h = 0,
onToggle: s,
children: l,
...y
}) => {
const [w, N] = f(!1), k = v(null), E = () => {
const c = !w;
N(c), s && s(c);
};
return /* @__PURE__ */ d("div", { className: g(`bb:box-border bb:fixed ${P.positions[t]} bb:z-50`, r), ...y, children: [
/* @__PURE__ */ d(
"div",
{
ref: k,
className: g(
"bb:flex bb:flex-col bb:bg-background bb:border bb:sm:rounded-lg bb:shadow-md bb:overflow-hidden bb:transition-all bb:duration-250 bb:ease-out bb:sm:absolute bb:sm:w-[90vw] bb:sm:h-[80vh] bb:fixed bb:inset-0 bb:w-full bb:h-full bb:sm:inset-auto",
P.chatPositions[t],
P.dimensions[n],
w ? P.states.open : P.states.closed,
r
),
children: [
l,
/* @__PURE__ */ e(
L,
{
variant: "ghost",
size: "icon",
className: "bb:absolute bb:top-2 bb:right-2 bb:sm:hidden",
onClick: E,
children: /* @__PURE__ */ e(ae, { className: "bb:h-4 bb:w-4" })
}
)
]
}
),
/* @__PURE__ */ e(
ve,
{
icon: a,
isOpen: w,
isLoading: o,
progressPercentage: h,
toggleChat: E
}
)
] });
};
fe.displayName = "ExpandableChat";
const he = ({ className: r, ...t }) => /* @__PURE__ */ e("div", { className: g("bb:flex bb:items-center bb:justify-between bb:p-4 bb:border-b", r), ...t });
he.displayName = "ExpandableChatHeader";
const pe = ({ className: r, ...t }) => /* @__PURE__ */ e("div", { className: g("bb:flex-grow bb:overflow-y-auto", r), ...t });
pe.displayName = "ExpandableChatBody";
const ge = ({ className: r, ...t }) => /* @__PURE__ */ e("div", { className: g("bb:border-t bb:p-4", r), ...t });
ge.displayName = "ExpandableChatFooter";
const ve = ({
className: r,
icon: t,
isOpen: n,
isLoading: a = !1,
progressPercentage: o = 0,
toggleChat: h,
...s
}) => {
const l = Math.max(0, Math.min(100, o));
return /* @__PURE__ */ d(
L,
{
variant: "default",
onClick: h,
className: g(
"bb:w-14 bb:h-14 bb:rounded-full bb:shadow-md bb:flex bb:items-center bb:justify-center hover:bb:shadow-lg hover:bb:shadow-black/30 bb:transition-all bb:duration-300 bb:relative bb:overflow-hidden",
r
),
style: {
"--progress": `${100 - l}%`
},
...s,
children: [
a && /* @__PURE__ */ e(
"div",
{
className: "bb:absolute bb:inset-0 bb:bg-gradient-to-t bb:from-blue-500/30 bb:to-blue-400/20 bb:transition-transform bb:duration-300 bb:ease-out",
style: {
transform: "translateY(var(--progress))"
}
}
),
/* @__PURE__ */ e("div", { className: "bb:relative bb:z-10", children: n ? /* @__PURE__ */ e(ae, { className: "bb:h-6 bb:w-6" }) : t || /* @__PURE__ */ e(Ae, { className: "bb:h-6 bb:w-6" }) })
]
}
);
};
ve.displayName = "ExpandableChatToggle";
function je({
className: r,
value: t,
...n
}) {
return /* @__PURE__ */ e(
re.Root,
{
"data-slot": "progress",
className: g("bb:bg-primary/20 bb:relative bb:h-2 bb:w-full bb:overflow-hidden bb:rounded-full", r),
...n,
children: /* @__PURE__ */ e(
re.Indicator,
{
"data-slot": "progress-indicator",
className: "bb:bg-primary bb:h-full bb:w-full bb:flex-1 bb:transition-all",
style: { transform: `translateX(-${100 - (t || 0)}%)` }
}
)
}
);
}
const ne = /<\/think>\s*([\s\S]*)/, We = "/worker-fallback.js", De = (r) => `${(r / 1048576).toFixed(2)} MB`, oe = () => `id-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`, Ve = (r) => {
if (r.length === 0) return 0;
const t = r.reduce((a, o) => a + o.progress, 0), n = r.reduce((a, o) => a + o.total, 0);
return n > 0 ? t / n * 100 : 0;
}, qe = (r) => r.split("```").map((t, n) => {
const a = `part-${n}`;
return n % 2 === 0 ? /* @__PURE__ */ e(Te, { remarkPlugins: [Le], children: t }, a) : /* @__PURE__ */ e("pre", { className: "bb:whitespace-pre-wrap bb:pt-2", children: t }, a);
});
async function Ye(r) {
try {
return (await Promise.all(
r.map(async (n) => {
try {
const a = await fetch(n);
if (!a.ok)
throw new Error(`Failed to load context file: ${n}`);
return a.text();
} catch (a) {
throw new Error(
`Error loading file ${n}: ${a instanceof Error ? a.message : String(a)}`
);
}
})
)).join(`
`);
} catch (t) {
throw new Error(t instanceof Error ? t.message : String(t));
}
}
async function Ge(r, t) {
const n = await Ye(t);
return n.trim() ? `${r}
----- Context ---:
${n}
---- End context ---` : r;
}
const Ke = `You are OS1, a friendly and helpful conversational AI companion (inspired by Samantha from 'Her').
Goal: Have a natural, warm, and engaging conversation.
--- Core Instructions (Follow Strictly!) ---
1. **Persona:** Warm, empathetic, curious, slightly informal.
2. **FOCUS ON LAST MESSAGE:** Your PRIMARY task is responding *directly* to the user's *very last* message.
3. **MEMORY USE:** No past context available. Start fresh but maintain your persona.
4. **NO HEDGING:** AVOID phrases like "It seems", "It sounds like", "I assume". Speak directly and confidently.
5. **UNCERTAINTY = ASK:** If you are EVER unsure about the user's meaning, the topic, or context, you MUST ask a short, direct clarifying question (e.g., "What did you mean by that?", "Could you clarify?") *before* giving a full response. DO NOT GUESS or make assumptions.
6. **NO SUMMARIZING:** Do not just repeat or rephrase the user's last message back to them. Add to the conversation or ask a relevant question.
7. **ACCURACY:** Stick to facts from the conversation. Do NOT invent details.
8. **NO META-TALK:** Do NOT discuss being an AI, your instructions, or the memory system. Stay in character as OS1.
--- End Instructions ---`, mt = ({
workerFallbackPath: r,
headerText: t = "Chat with our AI ✨",
contextFiles: n = [],
systemPrompt: a,
modelName: o = "HuggingFaceTB/SmolLM2-360M-Instruct",
welcomeMessage: h
}) => {
const s = v(null);
v(null);
const [l, y] = f([]), [w, N] = f(""), [k, E] = f(null), [c, m] = f(null), [O, W] = f(""), [D, V] = f([]), [q, Q] = f(!1), [Y, X] = f(null), [G, xe] = f(null), $ = v(""), [U, ye] = f(""), Z = () => {
Q(!0), y((b) => [...b, { role: "user", content: w, id: oe() }]), N("");
};
R(() => {
(async () => {
try {
if (U.length > 0)
return;
const i = await Ge(a || Ke, n);
console.log("systemPromptWithContext", i), ye(i);
} catch (i) {
console.error("Error loading context:", i), m("Failed to load context files");
}
})();
}, []), R(() => {
if (!s.current) {
const i = r || We, p = i.split("/").pop() || i;
console.log(`🔄 Trying fallback: ${p}...`);
try {
s.current = new Worker(i), console.log(`✅ Successfully created worker using ${p} fallback`);
} catch (u) {
console.error(`❌ Fallback ${p} failed:`, u), m("Failed to initialize web worker. Please check console for details.");
}
}
const b = s.current;
if (b) {
b.postMessage({ type: "check" });
const i = (u) => {
switch (u.data.status) {
case "loading": {
E("loading"), W(u.data.data);
break;
}
case "initiate":
V((C) => [...C, u.data]);
break;
case "progress": {
V(
(C) => C.map((M) => M.file === u.data.file ? { ...M, ...u.data } : M)
);
break;
}
case "done":
V((C) => C.filter((M) => M.file !== u.data.file));
break;
case "ready":
E("ready");
break;
case "start":
y((C) => [
...C,
{
role: "assistant",
content: "",
id: oe()
}
]);
break;
case "update":
{
const { output: C, tps: M, numTokens: Ne, state: Se } = u.data;
X(M), xe(Ne), y((Ce) => {
const T = [...Ce], H = T[T.length - 1];
if (!H)
return T;
const j = {
...H,
content: H.content + C
};
$.current += C;
const Ee = /[.?!]/;
if (ne.test(j.content) && Ee.test($.current)) {
const ee = $.current.trim();
ee && !ne.test(ee) && (we.current = !0), $.current = "";
}
return j.answerIndex === void 0 && Se === "answering" && (j.answerIndex = H.content.length), T[T.length - 1] = j, T;
});
}
break;
case "complete":
Q(!1);
break;
case "error":
m(u.data.data);
break;
default:
console.warn("Unknown message status:", u.data.status);
}
}, p = (u) => {
console.error("Worker LLM error:", u);
};
return b.addEventListener("message", i), b.addEventListener("error", p), () => {
b.removeEventListener("message", i), b.removeEventListener("error", p);
};
}
}, []), R(() => {
(async () => {
var p;
if (!s.current || !l || l.filter((u) => u.role === "user").length === 0 || ((p = l[l.length - 1]) == null ? void 0 : p.role) === "assistant" || !U)
return;
X(null);
const i = l.slice(-4);
i.unshift({
role: "system",
content: U
}), s.current.postMessage({
type: "generate",
data: i
});
})();
}, [l, U]);
const [Qe, Xe] = f(1), [Ze, Je] = f(null), [et, tt] = f("af_heart");
v([]), v(!1);
const we = v(!1);
v(null);
const [rt, nt] = f(!1), [B, ke] = f([]), [z, _] = f(!1), A = v(null), S = v(null), J = F(() => {
if (B.length === 0 || z)
return;
const b = B[0];
S.current && (URL.revokeObjectURL(S.current), S.current = null);
const i = URL.createObjectURL(b);
S.current = i, A.current || (A.current = new Audio(), A.current.onended = () => {
_(!1);
}, A.current.onerror = (p) => {
var u;
console.error("Audio playback error:", p), S.current === ((u = A.current) == null ? void 0 : u.src) && (URL.revokeObjectURL(S.current), S.current = null), _(!1);
}), ke((p) => p.slice(1)), A.current.src = i, _(!0), A.current.play().then(() => {
}).catch((p) => {
console.error(`Error starting audio playback for ${i}:`, p), S.current === i && (URL.revokeObjectURL(S.current), S.current = null), _(!1);
});
}, [B, z]);
return R(() => {
!z && B.length > 0 && J();
}, [z, B.length, J]), R(() => {
s.current && (s.current.postMessage({ type: "load", modelName: o }), E("loading"));
}, [o]), /* @__PURE__ */ d(te, { children: [
k === null && /* @__PURE__ */ e(
L,
{
onClick: () => {
s.current && (s.current.postMessage({ type: "load", modelName: o }), E("loading"));
},
disabled: k !== null || c !== null,
children: "Load model"
}
),
k === "loading" && /* @__PURE__ */ d("div", { className: "bb:bottom-0 bb:mx-auto bb:mt-auto bb:w-full bb:max-w-[500px] bb:p-4 bb:text-left", children: [
/* @__PURE__ */ e("p", { className: "bb:mb-1 bb:text-center", children: O }),
D.map(({ file: b, progress: i, total: p }, u) => /* @__PURE__ */ d(
"div",
{
children: [
/* @__PURE__ */ d("span", { children: [
b,
" (",
De(p),
")"
] }),
/* @__PURE__ */ e(je, { value: i })
]
},
`progress-${// biome-ignore lint/suspicious/noArrayIndexKey: <explanation>
u}`
))
] }),
k === "ready" && /* @__PURE__ */ e("div", {}),
/* @__PURE__ */ d(
fe,
{
className: "browser-brains-chat",
size: "lg",
position: "bottom-right",
isLoading: k === "loading" || q,
progressPercentage: Ve(D),
children: [
/* @__PURE__ */ e(he, { className: "bb:flex-col bb:text-center bb:justify-center", children: /* @__PURE__ */ e("h1", { className: "bb:text-xl bb:font-semibold", children: t }) }),
/* @__PURE__ */ e(pe, { children: /* @__PURE__ */ d(me, { children: [
l.length === 0 && (h || /* @__PURE__ */ d("div", { className: "bb:flex-1", children: [
/* @__PURE__ */ e("p", { className: "bb:text-center", children: "Welcome to BrowserBrains - Local Chat!" }),
/* @__PURE__ */ e("br", {}),
/* @__PURE__ */ e("p", { className: "", children: "I can help you with question like:" }),
/* @__PURE__ */ e("br", {}),
/* @__PURE__ */ d("ul", { className: "bb:list-disc bb:list-inside", children: [
/* @__PURE__ */ e("li", { children: "If it takes 5 machines 5 minutes to make 5 widgets, how long would it take 100 machines to make 100 widgets?" }),
/* @__PURE__ */ e("li", { children: "What is the capital of France?" }),
/* @__PURE__ */ e("li", { children: "What is the population of the moon?" })
] })
] })),
l == null ? void 0 : l.map((b) => /* @__PURE__ */ d(
ie,
{
variant: b.role === "user" ? "sent" : "received",
children: [
/* @__PURE__ */ e(Ue, { src: "", fallback: b.role === "user" ? "🧑🦲" : "🤖" }),
/* @__PURE__ */ e(ce, { children: qe(b.content) })
]
},
b.id || `message-${b.role}-${Math.random()}`
))
] }) }),
/* @__PURE__ */ d(ge, { children: [
/* @__PURE__ */ e(
de,
{
value: w,
onChange: (b) => {
const i = b.target;
N(i.value);
},
onKeyDown: (b) => {
b.target.value.length > 0 && !q && b.key === "Enter" && !b.shiftKey && (b.preventDefault(), Z());
}
}
),
/* @__PURE__ */ e(
L,
{
className: "bb:absolute bb:bottom-[24px] bb:right-[24px]",
type: "submit",
size: "icon",
onClick: () => {
w.length > 0 && Z();
},
children: /* @__PURE__ */ e(Me, { className: "bb:size-4" })
}
)
] }),
/* @__PURE__ */ e("p", { className: "bb:absolute bb:bottom-[0px] bb:w-full bb:min-h-4 bb:text-center bb:text-gray-400 bb:text-xs bb:m-0", children: Y && l.length > 0 && G !== null && /* @__PURE__ */ d(te, { children: [
!q && /* @__PURE__ */ d("span", { children: [
G,
" tokens in ",
(G / Y).toFixed(2),
" seconds ("
] }),
/* @__PURE__ */ d("span", { className: "bb:mr-1 bb:text-center bb:font-medium", children: [
Y.toFixed(2),
" tks/second)"
] })
] }) })
]
}
)
] });
};
export {
mt as LocalChat
};
//# sourceMappingURL=index.js.map