@firstlovecenter/ai-chat 0.2.0 → 0.2.2
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/CHANGELOG.md +86 -0
- package/dist/ui/index.cjs +55 -20
- package/dist/ui/index.cjs.map +1 -1
- package/dist/ui/index.js +55 -20
- package/dist/ui/index.js.map +1 -1
- package/package.json +3 -2
package/dist/ui/index.js
CHANGED
|
@@ -523,6 +523,14 @@ function AiLineChart({
|
|
|
523
523
|
))
|
|
524
524
|
] }) }) });
|
|
525
525
|
}
|
|
526
|
+
function formatDuration(ms) {
|
|
527
|
+
if (ms < 0) ms = 0;
|
|
528
|
+
const totalSec = Math.round(ms / 1e3);
|
|
529
|
+
if (totalSec < 60) return `${totalSec}s`;
|
|
530
|
+
const m = Math.floor(totalSec / 60);
|
|
531
|
+
const s = totalSec % 60;
|
|
532
|
+
return s === 0 ? `${m}m` : `${m}m ${s}s`;
|
|
533
|
+
}
|
|
526
534
|
var PROVIDER_LABELS = {
|
|
527
535
|
claude: "Claude",
|
|
528
536
|
grok: "Grok",
|
|
@@ -697,7 +705,7 @@ function AiChat({
|
|
|
697
705
|
}
|
|
698
706
|
setAnswers((prev) => [
|
|
699
707
|
...prev,
|
|
700
|
-
{ question: trimmed, blocks: [], done: false }
|
|
708
|
+
{ question: trimmed, blocks: [], done: false, startedAt: Date.now() }
|
|
701
709
|
]);
|
|
702
710
|
const ac = new AbortController();
|
|
703
711
|
abortRef.current = ac;
|
|
@@ -718,6 +726,7 @@ function AiChat({
|
|
|
718
726
|
(prev) => updateLast(prev, (a) => ({
|
|
719
727
|
...a,
|
|
720
728
|
done: true,
|
|
729
|
+
durationMs: a.startedAt != null ? Date.now() - a.startedAt : void 0,
|
|
721
730
|
error: { code: "NETWORK", message }
|
|
722
731
|
}))
|
|
723
732
|
);
|
|
@@ -729,6 +738,7 @@ function AiChat({
|
|
|
729
738
|
(prev) => updateLast(prev, (a) => ({
|
|
730
739
|
...a,
|
|
731
740
|
done: true,
|
|
741
|
+
durationMs: a.startedAt != null ? Date.now() - a.startedAt : void 0,
|
|
732
742
|
error: { code: "NO_BODY", message: "No response stream." }
|
|
733
743
|
}))
|
|
734
744
|
);
|
|
@@ -755,6 +765,7 @@ function AiChat({
|
|
|
755
765
|
(prev) => updateLast(prev, (a) => ({
|
|
756
766
|
...a,
|
|
757
767
|
done: true,
|
|
768
|
+
durationMs: a.startedAt != null ? Date.now() - a.startedAt : void 0,
|
|
758
769
|
error: { code: "STREAM", message }
|
|
759
770
|
}))
|
|
760
771
|
);
|
|
@@ -787,7 +798,7 @@ function AiChat({
|
|
|
787
798
|
/* @__PURE__ */ jsxs(
|
|
788
799
|
"aside",
|
|
789
800
|
{
|
|
790
|
-
|
|
801
|
+
inert: !sidebarOpen,
|
|
791
802
|
className: cn(
|
|
792
803
|
"absolute inset-y-0 left-0 z-20 flex w-72 max-w-[85vw] flex-col border-r border-border bg-sidebar text-sidebar-foreground shadow-lg transition-transform duration-200 ease-out",
|
|
793
804
|
sidebarOpen ? "translate-x-0" : "-translate-x-full"
|
|
@@ -919,22 +930,16 @@ function AiChat({
|
|
|
919
930
|
] }) : heroVisible ? /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col items-center justify-center text-center", children: [
|
|
920
931
|
/* @__PURE__ */ jsx("h1", { className: "text-2xl font-medium tracking-tight text-foreground sm:text-3xl", children: greeting }),
|
|
921
932
|
/* @__PURE__ */ jsx("p", { className: "mt-2 text-2xl font-light tracking-tight text-muted-foreground sm:text-3xl", children: "What's on your mind?" })
|
|
922
|
-
] }) : /* @__PURE__ */
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
)),
|
|
933
|
-
pending && /* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground", children: [
|
|
934
|
-
/* @__PURE__ */ jsx(Loader2, { className: "mr-1 inline size-3.5 animate-spin" }),
|
|
935
|
-
"Thinking\u2026"
|
|
936
|
-
] })
|
|
937
|
-
] })
|
|
933
|
+
] }) : /* @__PURE__ */ jsx("div", { className: "mx-auto flex w-full max-w-3xl flex-col gap-6", children: answers.map((a, idx) => /* @__PURE__ */ jsx(
|
|
934
|
+
AnswerView,
|
|
935
|
+
{
|
|
936
|
+
answer: a,
|
|
937
|
+
onRetry: () => void submit(a.question),
|
|
938
|
+
forwardRef: idx === answers.length - 1 ? lastAnswerRef : void 0,
|
|
939
|
+
isLast: idx === answers.length - 1
|
|
940
|
+
},
|
|
941
|
+
idx
|
|
942
|
+
)) })
|
|
938
943
|
}
|
|
939
944
|
),
|
|
940
945
|
/* @__PURE__ */ jsx("div", { className: "shrink-0 px-4 pb-4 pt-2", children: /* @__PURE__ */ jsxs(
|
|
@@ -1059,6 +1064,14 @@ function AnswerView({
|
|
|
1059
1064
|
}, [answer.blocks, answer.error]);
|
|
1060
1065
|
const showActions = answer.done && (answer.blocks.length > 0 || answer.error != null);
|
|
1061
1066
|
const isThinking = !answer.done && answer.blocks.length === 0 && !answer.error;
|
|
1067
|
+
const [, forceTick] = useState(0);
|
|
1068
|
+
useEffect(() => {
|
|
1069
|
+
if (answer.done || answer.startedAt == null) return;
|
|
1070
|
+
const id = window.setInterval(() => forceTick((n) => n + 1), 1e3);
|
|
1071
|
+
return () => window.clearInterval(id);
|
|
1072
|
+
}, [answer.done, answer.startedAt]);
|
|
1073
|
+
const liveElapsed = answer.startedAt != null ? Date.now() - answer.startedAt : null;
|
|
1074
|
+
const finalDuration = answer.durationMs;
|
|
1062
1075
|
return /* @__PURE__ */ jsxs(
|
|
1063
1076
|
"div",
|
|
1064
1077
|
{
|
|
@@ -1075,7 +1088,15 @@ function AnswerView({
|
|
|
1075
1088
|
/* @__PURE__ */ jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsx(UserChip, { text: answer.question }) }),
|
|
1076
1089
|
isThinking ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
1077
1090
|
/* @__PURE__ */ jsx("div", { className: "flex size-7 shrink-0 items-center justify-center rounded-full bg-primary/10 text-primary", children: /* @__PURE__ */ jsx(Sparkles, { className: "size-4" }) }),
|
|
1078
|
-
/* @__PURE__ */
|
|
1091
|
+
/* @__PURE__ */ jsxs("p", { className: "flex items-center text-sm text-muted-foreground", children: [
|
|
1092
|
+
/* @__PURE__ */ jsx(Loader2, { className: "mr-1 inline size-3.5 animate-spin" }),
|
|
1093
|
+
"Thinking\u2026",
|
|
1094
|
+
liveElapsed != null && liveElapsed >= 1e3 && /* @__PURE__ */ jsxs("span", { className: "ml-1 tabular-nums", children: [
|
|
1095
|
+
"(",
|
|
1096
|
+
formatDuration(liveElapsed),
|
|
1097
|
+
")"
|
|
1098
|
+
] })
|
|
1099
|
+
] })
|
|
1079
1100
|
] }) : /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3", children: [
|
|
1080
1101
|
/* @__PURE__ */ jsx("div", { className: "mt-0.5 flex size-7 shrink-0 items-center justify-center rounded-full bg-primary/10 text-primary", children: /* @__PURE__ */ jsx(Sparkles, { className: "size-4" }) }),
|
|
1081
1102
|
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-3", children: [
|
|
@@ -1107,6 +1128,14 @@ function AnswerView({
|
|
|
1107
1128
|
className: "inline-flex size-8 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground",
|
|
1108
1129
|
children: /* @__PURE__ */ jsx(RotateCcw, { className: "size-4" })
|
|
1109
1130
|
}
|
|
1131
|
+
),
|
|
1132
|
+
finalDuration != null && finalDuration >= 1e3 && /* @__PURE__ */ jsx(
|
|
1133
|
+
"span",
|
|
1134
|
+
{
|
|
1135
|
+
className: "ml-1 text-xs text-muted-foreground tabular-nums",
|
|
1136
|
+
title: "Time taken to generate this response",
|
|
1137
|
+
children: formatDuration(finalDuration)
|
|
1138
|
+
}
|
|
1110
1139
|
)
|
|
1111
1140
|
] })
|
|
1112
1141
|
] })
|
|
@@ -1312,7 +1341,13 @@ function handleEvent(raw, setAnswers) {
|
|
|
1312
1341
|
})
|
|
1313
1342
|
);
|
|
1314
1343
|
} else if (event === "done") {
|
|
1315
|
-
setAnswers(
|
|
1344
|
+
setAnswers(
|
|
1345
|
+
(prev) => updateLast(prev, (a) => ({
|
|
1346
|
+
...a,
|
|
1347
|
+
done: true,
|
|
1348
|
+
durationMs: a.startedAt != null ? Date.now() - a.startedAt : void 0
|
|
1349
|
+
}))
|
|
1350
|
+
);
|
|
1316
1351
|
} else if (event === "error") {
|
|
1317
1352
|
setAnswers(
|
|
1318
1353
|
(prev) => updateLast(prev, (a) => ({
|