@blank-utils/llm 0.3.5 → 0.3.6
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/KaTeX_AMS-Regular-CYEKBG2K.woff +0 -0
- package/dist/KaTeX_AMS-Regular-JKX5W2C4.ttf +0 -0
- package/dist/KaTeX_AMS-Regular-U6PRYMIZ.woff2 +0 -0
- package/dist/KaTeX_Caligraphic-Bold-5QL5CMTE.woff2 +0 -0
- package/dist/KaTeX_Caligraphic-Bold-WZ3QSGD3.woff +0 -0
- package/dist/KaTeX_Caligraphic-Bold-ZTS3R3HK.ttf +0 -0
- package/dist/KaTeX_Caligraphic-Regular-3LKEU76G.woff +0 -0
- package/dist/KaTeX_Caligraphic-Regular-A7XRTZ5Q.ttf +0 -0
- package/dist/KaTeX_Caligraphic-Regular-KX5MEWCF.woff2 +0 -0
- package/dist/KaTeX_Fraktur-Bold-2QVFK6NQ.woff2 +0 -0
- package/dist/KaTeX_Fraktur-Bold-T4SWXBMT.woff +0 -0
- package/dist/KaTeX_Fraktur-Bold-WGHVTYOR.ttf +0 -0
- package/dist/KaTeX_Fraktur-Regular-2PEIFJSJ.woff2 +0 -0
- package/dist/KaTeX_Fraktur-Regular-5U4OPH2X.ttf +0 -0
- package/dist/KaTeX_Fraktur-Regular-PQMHCIK6.woff +0 -0
- package/dist/KaTeX_Main-Bold-2GA4IZIN.woff +0 -0
- package/dist/KaTeX_Main-Bold-W5FBVCZM.ttf +0 -0
- package/dist/KaTeX_Main-Bold-YP5VVQRP.woff2 +0 -0
- package/dist/KaTeX_Main-BoldItalic-4P4C7HJH.woff +0 -0
- package/dist/KaTeX_Main-BoldItalic-N4V3DX7S.woff2 +0 -0
- package/dist/KaTeX_Main-BoldItalic-ODMLBJJQ.ttf +0 -0
- package/dist/KaTeX_Main-Italic-I43T2HSR.ttf +0 -0
- package/dist/KaTeX_Main-Italic-RELBIK7M.woff2 +0 -0
- package/dist/KaTeX_Main-Italic-SASNQFN2.woff +0 -0
- package/dist/KaTeX_Main-Regular-ARRPAO67.woff2 +0 -0
- package/dist/KaTeX_Main-Regular-P5I74A2A.woff +0 -0
- package/dist/KaTeX_Main-Regular-W74P5G27.ttf +0 -0
- package/dist/KaTeX_Math-BoldItalic-6EBV3DK5.woff +0 -0
- package/dist/KaTeX_Math-BoldItalic-K4WTGH3J.woff2 +0 -0
- package/dist/KaTeX_Math-BoldItalic-VB447A4D.ttf +0 -0
- package/dist/KaTeX_Math-Italic-6KGCHLFN.woff2 +0 -0
- package/dist/KaTeX_Math-Italic-KKK3USB2.woff +0 -0
- package/dist/KaTeX_Math-Italic-SON4MRCA.ttf +0 -0
- package/dist/KaTeX_SansSerif-Bold-RRNVJFFW.woff2 +0 -0
- package/dist/KaTeX_SansSerif-Bold-STQ6RXC7.ttf +0 -0
- package/dist/KaTeX_SansSerif-Bold-X5M5EMOD.woff +0 -0
- package/dist/KaTeX_SansSerif-Italic-HMPFTM52.woff2 +0 -0
- package/dist/KaTeX_SansSerif-Italic-PSN4QKYX.woff +0 -0
- package/dist/KaTeX_SansSerif-Italic-WTBAZBGY.ttf +0 -0
- package/dist/KaTeX_SansSerif-Regular-2TL3USAE.ttf +0 -0
- package/dist/KaTeX_SansSerif-Regular-OQCII6EP.woff +0 -0
- package/dist/KaTeX_SansSerif-Regular-XIQ62X4E.woff2 +0 -0
- package/dist/KaTeX_Script-Regular-72OLXYNA.ttf +0 -0
- package/dist/KaTeX_Script-Regular-A5IFOEBS.woff +0 -0
- package/dist/KaTeX_Script-Regular-APUWIHLP.woff2 +0 -0
- package/dist/KaTeX_Size1-Regular-4HRHTS65.woff +0 -0
- package/dist/KaTeX_Size1-Regular-5LRUTBFT.woff2 +0 -0
- package/dist/KaTeX_Size1-Regular-7K6AASVL.ttf +0 -0
- package/dist/KaTeX_Size2-Regular-222HN3GT.ttf +0 -0
- package/dist/KaTeX_Size2-Regular-K5ZHAIS6.woff +0 -0
- package/dist/KaTeX_Size2-Regular-LELKET5D.woff2 +0 -0
- package/dist/KaTeX_Size3-Regular-TLFPAHDE.woff +0 -0
- package/dist/KaTeX_Size3-Regular-UFCO6WCA.ttf +0 -0
- package/dist/KaTeX_Size3-Regular-WQRQ47UD.woff2 +0 -0
- package/dist/KaTeX_Size4-Regular-7PGNVPQK.ttf +0 -0
- package/dist/KaTeX_Size4-Regular-CDMV7U5C.woff2 +0 -0
- package/dist/KaTeX_Size4-Regular-PKMWZHNC.woff +0 -0
- package/dist/KaTeX_Typewriter-Regular-3F5K6SQ6.ttf +0 -0
- package/dist/KaTeX_Typewriter-Regular-MJMFSK64.woff +0 -0
- package/dist/KaTeX_Typewriter-Regular-VBYJ4NRC.woff2 +0 -0
- package/dist/{chunk-PA7F4CD6.js → chunk-NDXKOAAG.js} +148 -767
- package/dist/{index-BfDM8kLq.d.ts → index-fIqGfqTG.d.ts} +1 -77
- package/dist/index.css +1155 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/react/index.css +1155 -0
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.js +1 -1
- package/package.json +9 -3
|
@@ -894,227 +894,8 @@ import { useRef as useRef3, useEffect as useEffect3, useState as useState3, useM
|
|
|
894
894
|
// src/react/chat-input.tsx
|
|
895
895
|
import "react";
|
|
896
896
|
import { useRef as useRef2, useEffect as useEffect2, useCallback as useCallback2, useState as useState2 } from "react";
|
|
897
|
-
import {
|
|
898
|
-
|
|
899
|
-
return /* @__PURE__ */ jsxs2("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
900
|
-
/* @__PURE__ */ jsx2("line", { x1: "5", y1: "12", x2: "19", y2: "12" }),
|
|
901
|
-
/* @__PURE__ */ jsx2("polyline", { points: "12 5 19 12 12 19" })
|
|
902
|
-
] });
|
|
903
|
-
}
|
|
904
|
-
function StopIcon() {
|
|
905
|
-
return /* @__PURE__ */ jsx2("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx2("rect", { x: "6", y: "6", width: "12", height: "12" }) });
|
|
906
|
-
}
|
|
907
|
-
function ImageIcon() {
|
|
908
|
-
return /* @__PURE__ */ jsxs2("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
909
|
-
/* @__PURE__ */ jsx2("rect", { x: "3", y: "3", width: "18", height: "18", rx: "0", ry: "0" }),
|
|
910
|
-
/* @__PURE__ */ jsx2("circle", { cx: "8.5", cy: "8.5", r: "1.5" }),
|
|
911
|
-
/* @__PURE__ */ jsx2("polyline", { points: "21 15 16 10 5 21" })
|
|
912
|
-
] });
|
|
913
|
-
}
|
|
914
|
-
function XIcon() {
|
|
915
|
-
return /* @__PURE__ */ jsxs2("svg", { width: "10", height: "10", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
916
|
-
/* @__PURE__ */ jsx2("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
917
|
-
/* @__PURE__ */ jsx2("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
918
|
-
] });
|
|
919
|
-
}
|
|
920
|
-
var STYLE_ID = "__llm-chat-input-styles";
|
|
921
|
-
function injectStyles(theme) {
|
|
922
|
-
if (typeof document === "undefined") return;
|
|
923
|
-
const existing = document.getElementById(STYLE_ID);
|
|
924
|
-
if (existing) existing.remove();
|
|
925
|
-
const d = theme === "dark";
|
|
926
|
-
const border = d ? "rgba(255,255,255,0.12)" : "rgba(0,0,0,0.12)";
|
|
927
|
-
const borderFocus = d ? "rgba(255,255,255,0.35)" : "rgba(0,0,0,0.35)";
|
|
928
|
-
const bg = d ? "#000000" : "#ffffff";
|
|
929
|
-
const text = d ? "#ffffff" : "#000000";
|
|
930
|
-
const textMuted = d ? "rgba(255,255,255,0.3)" : "rgba(0,0,0,0.3)";
|
|
931
|
-
const textSecondary = d ? "rgba(255,255,255,0.5)" : "rgba(0,0,0,0.5)";
|
|
932
|
-
const monoFont = `ui-monospace, SFMono-Regular, "SF Mono", Menlo, Monaco, Consolas, monospace`;
|
|
933
|
-
const sansFont = `-apple-system, BlinkMacSystemFont, "Segoe UI", "Inter", Roboto, Helvetica, Arial, sans-serif`;
|
|
934
|
-
const css = `
|
|
935
|
-
.llm-ci {
|
|
936
|
-
display: flex;
|
|
937
|
-
flex-direction: column;
|
|
938
|
-
border: 1px solid ${border};
|
|
939
|
-
background: ${bg};
|
|
940
|
-
padding: 12px;
|
|
941
|
-
transition: border-color 0.15s;
|
|
942
|
-
position: relative;
|
|
943
|
-
}
|
|
944
|
-
.llm-ci:focus-within {
|
|
945
|
-
border-color: ${borderFocus};
|
|
946
|
-
}
|
|
947
|
-
|
|
948
|
-
/* Attached Images */
|
|
949
|
-
.llm-ci-images {
|
|
950
|
-
display: flex;
|
|
951
|
-
flex-wrap: wrap;
|
|
952
|
-
gap: 6px;
|
|
953
|
-
margin-bottom: 8px;
|
|
954
|
-
}
|
|
955
|
-
.llm-ci-image-preview {
|
|
956
|
-
position: relative;
|
|
957
|
-
width: 52px;
|
|
958
|
-
height: 52px;
|
|
959
|
-
overflow: hidden;
|
|
960
|
-
border: 1px solid ${border};
|
|
961
|
-
}
|
|
962
|
-
.llm-ci-image-preview img {
|
|
963
|
-
width: 100%;
|
|
964
|
-
height: 100%;
|
|
965
|
-
object-fit: cover;
|
|
966
|
-
}
|
|
967
|
-
.llm-ci-image-remove {
|
|
968
|
-
position: absolute;
|
|
969
|
-
top: 2px;
|
|
970
|
-
right: 2px;
|
|
971
|
-
width: 16px;
|
|
972
|
-
height: 16px;
|
|
973
|
-
background: ${d ? "rgba(0,0,0,0.7)" : "rgba(255,255,255,0.8)"};
|
|
974
|
-
color: ${text};
|
|
975
|
-
border: none;
|
|
976
|
-
display: flex;
|
|
977
|
-
align-items: center;
|
|
978
|
-
justify-content: center;
|
|
979
|
-
cursor: pointer;
|
|
980
|
-
opacity: 0;
|
|
981
|
-
transition: opacity 0.1s;
|
|
982
|
-
}
|
|
983
|
-
.llm-ci-image-preview:hover .llm-ci-image-remove {
|
|
984
|
-
opacity: 1;
|
|
985
|
-
}
|
|
986
|
-
|
|
987
|
-
/* Textarea */
|
|
988
|
-
.llm-ci textarea {
|
|
989
|
-
width: 100%;
|
|
990
|
-
min-height: 24px;
|
|
991
|
-
max-height: 200px;
|
|
992
|
-
resize: none;
|
|
993
|
-
border: none;
|
|
994
|
-
outline: none;
|
|
995
|
-
background: transparent;
|
|
996
|
-
color: ${text};
|
|
997
|
-
font-size: 14px;
|
|
998
|
-
line-height: 1.5;
|
|
999
|
-
padding: 0;
|
|
1000
|
-
margin: 0;
|
|
1001
|
-
font-family: ${sansFont};
|
|
1002
|
-
scrollbar-width: thin;
|
|
1003
|
-
}
|
|
1004
|
-
.llm-ci textarea::placeholder {
|
|
1005
|
-
color: ${textMuted};
|
|
1006
|
-
}
|
|
1007
|
-
|
|
1008
|
-
/* Toolbar */
|
|
1009
|
-
.llm-ci-toolbar {
|
|
1010
|
-
display: flex;
|
|
1011
|
-
align-items: center;
|
|
1012
|
-
justify-content: space-between;
|
|
1013
|
-
margin-top: 8px;
|
|
1014
|
-
min-height: 28px;
|
|
1015
|
-
}
|
|
1016
|
-
.llm-ci-left-actions {
|
|
1017
|
-
display: flex;
|
|
1018
|
-
align-items: center;
|
|
1019
|
-
gap: 2px;
|
|
1020
|
-
}
|
|
1021
|
-
.llm-ci-right-actions {
|
|
1022
|
-
display: flex;
|
|
1023
|
-
align-items: center;
|
|
1024
|
-
gap: 8px;
|
|
1025
|
-
}
|
|
1026
|
-
|
|
1027
|
-
/* Icon Buttons */
|
|
1028
|
-
.llm-ci-btn-icon {
|
|
1029
|
-
display: flex;
|
|
1030
|
-
align-items: center;
|
|
1031
|
-
justify-content: center;
|
|
1032
|
-
width: 28px;
|
|
1033
|
-
height: 28px;
|
|
1034
|
-
border: none;
|
|
1035
|
-
background: transparent;
|
|
1036
|
-
color: ${textSecondary};
|
|
1037
|
-
cursor: pointer;
|
|
1038
|
-
transition: color 0.1s;
|
|
1039
|
-
}
|
|
1040
|
-
.llm-ci-btn-icon:hover {
|
|
1041
|
-
color: ${text};
|
|
1042
|
-
}
|
|
1043
|
-
|
|
1044
|
-
/* Send / Stop \u2014 flat, monospace, uppercase */
|
|
1045
|
-
.llm-ci-send {
|
|
1046
|
-
display: flex;
|
|
1047
|
-
align-items: center;
|
|
1048
|
-
justify-content: center;
|
|
1049
|
-
height: 28px;
|
|
1050
|
-
padding: 0 12px;
|
|
1051
|
-
border: 1px solid ${border};
|
|
1052
|
-
font-size: 10px;
|
|
1053
|
-
font-weight: 400;
|
|
1054
|
-
font-family: ${monoFont};
|
|
1055
|
-
text-transform: uppercase;
|
|
1056
|
-
letter-spacing: 0.08em;
|
|
1057
|
-
cursor: pointer;
|
|
1058
|
-
transition: all 0.1s;
|
|
1059
|
-
gap: 6px;
|
|
1060
|
-
background: transparent;
|
|
1061
|
-
color: ${textSecondary};
|
|
1062
|
-
}
|
|
1063
|
-
.llm-ci-send--active {
|
|
1064
|
-
background: ${text};
|
|
1065
|
-
color: ${bg};
|
|
1066
|
-
border-color: ${text};
|
|
1067
|
-
}
|
|
1068
|
-
.llm-ci-send--active:hover {
|
|
1069
|
-
opacity: 0.8;
|
|
1070
|
-
}
|
|
1071
|
-
.llm-ci-send--disabled {
|
|
1072
|
-
color: ${textMuted};
|
|
1073
|
-
border-color: ${d ? "rgba(255,255,255,0.06)" : "rgba(0,0,0,0.06)"};
|
|
1074
|
-
cursor: not-allowed;
|
|
1075
|
-
}
|
|
1076
|
-
.llm-ci-send--stop {
|
|
1077
|
-
background: transparent;
|
|
1078
|
-
border-color: ${border};
|
|
1079
|
-
color: ${textSecondary};
|
|
1080
|
-
}
|
|
1081
|
-
.llm-ci-send--stop:hover {
|
|
1082
|
-
border-color: ${borderFocus};
|
|
1083
|
-
color: ${text};
|
|
1084
|
-
}
|
|
1085
|
-
|
|
1086
|
-
/* Model Selector Slot */
|
|
1087
|
-
.llm-ci-model-selector {
|
|
1088
|
-
margin-right: auto;
|
|
1089
|
-
}
|
|
1090
|
-
|
|
1091
|
-
/* Hidden file input */
|
|
1092
|
-
.llm-ci-file-input {
|
|
1093
|
-
display: none;
|
|
1094
|
-
}
|
|
1095
|
-
|
|
1096
|
-
/* Drag Overlay */
|
|
1097
|
-
.llm-ci-drag-overlay {
|
|
1098
|
-
position: absolute;
|
|
1099
|
-
inset: 0;
|
|
1100
|
-
background: ${d ? "rgba(0,0,0,0.9)" : "rgba(255,255,255,0.9)"};
|
|
1101
|
-
display: flex;
|
|
1102
|
-
align-items: center;
|
|
1103
|
-
justify-content: center;
|
|
1104
|
-
z-index: 10;
|
|
1105
|
-
border: 1px dashed ${textSecondary};
|
|
1106
|
-
color: ${textSecondary};
|
|
1107
|
-
font-size: 11px;
|
|
1108
|
-
font-family: ${monoFont};
|
|
1109
|
-
text-transform: uppercase;
|
|
1110
|
-
letter-spacing: 0.08em;
|
|
1111
|
-
}
|
|
1112
|
-
`;
|
|
1113
|
-
const style = document.createElement("style");
|
|
1114
|
-
style.id = STYLE_ID;
|
|
1115
|
-
style.textContent = css;
|
|
1116
|
-
document.head.appendChild(style);
|
|
1117
|
-
}
|
|
897
|
+
import { Send, Square, ImagePlus, X } from "lucide-react";
|
|
898
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1118
899
|
function ChatInput({
|
|
1119
900
|
value,
|
|
1120
901
|
onChange,
|
|
@@ -1122,11 +903,10 @@ function ChatInput({
|
|
|
1122
903
|
onStop,
|
|
1123
904
|
disabled = false,
|
|
1124
905
|
isGenerating = false,
|
|
1125
|
-
placeholder = "
|
|
906
|
+
placeholder = "Message...",
|
|
1126
907
|
maxRows = 8,
|
|
1127
908
|
actions,
|
|
1128
|
-
|
|
1129
|
-
className,
|
|
909
|
+
className = "",
|
|
1130
910
|
images = [],
|
|
1131
911
|
onImageAdd,
|
|
1132
912
|
onImageRemove,
|
|
@@ -1135,29 +915,22 @@ function ChatInput({
|
|
|
1135
915
|
const textareaRef = useRef2(null);
|
|
1136
916
|
const fileInputRef = useRef2(null);
|
|
1137
917
|
const [isDragging, setIsDragging] = useState2(false);
|
|
1138
|
-
useEffect2(() => {
|
|
1139
|
-
injectStyles(theme);
|
|
1140
|
-
}, [theme]);
|
|
1141
918
|
useEffect2(() => {
|
|
1142
919
|
const textarea = textareaRef.current;
|
|
1143
920
|
if (!textarea) return;
|
|
1144
921
|
textarea.style.height = "auto";
|
|
1145
|
-
const lineHeight =
|
|
922
|
+
const lineHeight = 24;
|
|
1146
923
|
const maxHeight = lineHeight * maxRows + 24;
|
|
1147
|
-
|
|
1148
|
-
textarea.style.height = `${newHeight}px`;
|
|
924
|
+
textarea.style.height = `${Math.min(textarea.scrollHeight, maxHeight)}px`;
|
|
1149
925
|
}, [value, maxRows]);
|
|
1150
|
-
const handleKeyDown = useCallback2(
|
|
1151
|
-
(e)
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
onSend();
|
|
1156
|
-
}
|
|
926
|
+
const handleKeyDown = useCallback2((e) => {
|
|
927
|
+
if (e.key === "Enter" && !e.shiftKey) {
|
|
928
|
+
e.preventDefault();
|
|
929
|
+
if (!disabled && (value.trim() || images.length > 0)) {
|
|
930
|
+
onSend();
|
|
1157
931
|
}
|
|
1158
|
-
}
|
|
1159
|
-
|
|
1160
|
-
);
|
|
932
|
+
}
|
|
933
|
+
}, [disabled, value, images.length, onSend]);
|
|
1161
934
|
const processFile = useCallback2((file) => {
|
|
1162
935
|
if (file.type === "application/pdf" || file.name.toLowerCase().endsWith(".pdf")) {
|
|
1163
936
|
const reader2 = new FileReader();
|
|
@@ -1195,12 +968,7 @@ ${newText}` : newText);
|
|
|
1195
968
|
reader.onload = (e) => {
|
|
1196
969
|
if (e.target?.result && typeof e.target.result === "string") {
|
|
1197
970
|
const id = Math.random().toString(36).substring(7);
|
|
1198
|
-
onImageAdd?.({
|
|
1199
|
-
id,
|
|
1200
|
-
dataUrl: e.target.result,
|
|
1201
|
-
file,
|
|
1202
|
-
name: file.name
|
|
1203
|
-
});
|
|
971
|
+
onImageAdd?.({ id, dataUrl: e.target.result, file, name: file.name });
|
|
1204
972
|
}
|
|
1205
973
|
};
|
|
1206
974
|
reader.readAsDataURL(file);
|
|
@@ -1235,18 +1003,10 @@ ${newText}` : newText);
|
|
|
1235
1003
|
}, [processFile]);
|
|
1236
1004
|
const hasValue = value.trim().length > 0 || images.length > 0;
|
|
1237
1005
|
const canSend = hasValue && !disabled && !isGenerating;
|
|
1238
|
-
let sendClass = "llm-ci-send";
|
|
1239
|
-
if (isGenerating) {
|
|
1240
|
-
sendClass += " llm-ci-send--stop";
|
|
1241
|
-
} else if (canSend) {
|
|
1242
|
-
sendClass += " llm-ci-send--active";
|
|
1243
|
-
} else {
|
|
1244
|
-
sendClass += " llm-ci-send--disabled";
|
|
1245
|
-
}
|
|
1246
1006
|
return /* @__PURE__ */ jsxs2(
|
|
1247
1007
|
"div",
|
|
1248
1008
|
{
|
|
1249
|
-
className: `
|
|
1009
|
+
className: `relative flex flex-col bg-zinc-50 dark:bg-zinc-900 border border-zinc-200 dark:border-zinc-800 rounded-2xl shadow-sm focus-within:ring-2 focus-within:ring-blue-500/20 focus-within:border-blue-500 transition-all p-3 ${className}`,
|
|
1250
1010
|
onDragOver: (e) => {
|
|
1251
1011
|
e.preventDefault();
|
|
1252
1012
|
setIsDragging(true);
|
|
@@ -1254,7 +1014,10 @@ ${newText}` : newText);
|
|
|
1254
1014
|
onDragLeave: () => setIsDragging(false),
|
|
1255
1015
|
onDrop: handleDrop,
|
|
1256
1016
|
children: [
|
|
1257
|
-
isDragging && /* @__PURE__ */
|
|
1017
|
+
isDragging && /* @__PURE__ */ jsxs2("div", { className: "absolute inset-0 bg-white/90 dark:bg-zinc-900/90 flex flex-col items-center justify-center z-20 border-2 border-dashed border-blue-500 rounded-2xl", children: [
|
|
1018
|
+
/* @__PURE__ */ jsx2(ImagePlus, { className: "w-8 h-8 text-blue-500 mb-2" }),
|
|
1019
|
+
/* @__PURE__ */ jsx2("span", { className: "text-blue-500 font-medium tracking-wide", children: "Drop file to attach" })
|
|
1020
|
+
] }),
|
|
1258
1021
|
/* @__PURE__ */ jsx2(
|
|
1259
1022
|
"input",
|
|
1260
1023
|
{
|
|
@@ -1262,19 +1025,19 @@ ${newText}` : newText);
|
|
|
1262
1025
|
type: "file",
|
|
1263
1026
|
accept: "image/*,.pdf",
|
|
1264
1027
|
multiple: true,
|
|
1265
|
-
className: "
|
|
1028
|
+
className: "hidden",
|
|
1266
1029
|
onChange: handleFileSelect
|
|
1267
1030
|
}
|
|
1268
1031
|
),
|
|
1269
|
-
images.length > 0 && /* @__PURE__ */ jsx2("div", { className: "
|
|
1270
|
-
/* @__PURE__ */ jsx2("img", { src: img.dataUrl, alt: "attachment" }),
|
|
1032
|
+
images.length > 0 && /* @__PURE__ */ jsx2("div", { className: "flex flex-wrap gap-2 mb-3 px-2", children: images.map((img) => /* @__PURE__ */ jsxs2("div", { className: "relative w-14 h-14 overflow-hidden border border-zinc-200 dark:border-zinc-700 rounded-xl group select-none", children: [
|
|
1033
|
+
/* @__PURE__ */ jsx2("img", { src: img.dataUrl, alt: "attachment", className: "w-full h-full object-cover transition-transform group-hover:scale-105" }),
|
|
1271
1034
|
/* @__PURE__ */ jsx2(
|
|
1272
1035
|
"button",
|
|
1273
1036
|
{
|
|
1274
1037
|
type: "button",
|
|
1275
|
-
className: "
|
|
1038
|
+
className: "absolute top-1 right-1 w-5 h-5 bg-black/50 hover:bg-black/80 text-white rounded-full flex items-center justify-center opacity-0 group-hover:opacity-100 transition-all backdrop-blur-sm",
|
|
1276
1039
|
onClick: () => onImageRemove?.(img.id),
|
|
1277
|
-
children: /* @__PURE__ */ jsx2(
|
|
1040
|
+
children: /* @__PURE__ */ jsx2(X, { className: "w-3 h-3" })
|
|
1278
1041
|
}
|
|
1279
1042
|
)
|
|
1280
1043
|
] }, img.id)) }),
|
|
@@ -1288,39 +1051,47 @@ ${newText}` : newText);
|
|
|
1288
1051
|
onPaste: handlePaste,
|
|
1289
1052
|
placeholder,
|
|
1290
1053
|
disabled: disabled && !isGenerating,
|
|
1291
|
-
rows: 1
|
|
1054
|
+
rows: 1,
|
|
1055
|
+
className: "w-full min-h-[24px] max-h-[200px] resize-none border-none outline-none bg-transparent text-zinc-900 dark:text-zinc-100 text-[15px] leading-relaxed px-2 m-0 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 scrollbar-thin scrollbar-thumb-zinc-300 dark:scrollbar-thumb-zinc-700"
|
|
1292
1056
|
}
|
|
1293
1057
|
),
|
|
1294
|
-
/* @__PURE__ */ jsxs2("div", { className: "
|
|
1295
|
-
/* @__PURE__ */ jsxs2("div", { className: "
|
|
1296
|
-
modelSelector && /* @__PURE__ */ jsx2("div", { className: "
|
|
1058
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex items-end justify-between mt-3 px-1", children: [
|
|
1059
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-1", children: [
|
|
1060
|
+
modelSelector && /* @__PURE__ */ jsx2("div", { className: "mr-2", children: modelSelector }),
|
|
1297
1061
|
/* @__PURE__ */ jsx2(
|
|
1298
1062
|
"button",
|
|
1299
1063
|
{
|
|
1300
1064
|
type: "button",
|
|
1301
|
-
className: "
|
|
1065
|
+
className: "flex items-center justify-center w-8 h-8 rounded-full text-zinc-500 dark:text-zinc-400 hover:text-zinc-900 dark:hover:text-zinc-100 hover:bg-zinc-200/50 dark:hover:bg-zinc-800 transition-colors",
|
|
1302
1066
|
onClick: () => fileInputRef.current?.click(),
|
|
1303
|
-
title: "Attach image
|
|
1304
|
-
children: /* @__PURE__ */ jsx2(
|
|
1067
|
+
title: "Attach image or PDF (Ctrl+V to paste)",
|
|
1068
|
+
children: /* @__PURE__ */ jsx2(ImagePlus, { className: "w-4 h-4" })
|
|
1305
1069
|
}
|
|
1306
1070
|
),
|
|
1307
1071
|
actions
|
|
1308
1072
|
] }),
|
|
1309
|
-
/* @__PURE__ */ jsx2("div", { className: "
|
|
1073
|
+
/* @__PURE__ */ jsx2("div", { className: "flex items-center gap-2", children: isGenerating ? /* @__PURE__ */ jsxs2(
|
|
1310
1074
|
"button",
|
|
1311
1075
|
{
|
|
1312
1076
|
type: "button",
|
|
1313
|
-
className:
|
|
1314
|
-
onClick:
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
children: isGenerating ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
1318
|
-
/* @__PURE__ */ jsx2(StopIcon, {}),
|
|
1077
|
+
className: "flex items-center justify-center h-8 px-4 rounded-full bg-zinc-200 dark:bg-zinc-800 text-zinc-700 dark:text-zinc-300 hover:bg-zinc-300 dark:hover:bg-zinc-700 text-xs font-semibold tracking-wide transition-colors gap-1.5 cursor-pointer shadow-sm",
|
|
1078
|
+
onClick: onStop,
|
|
1079
|
+
children: [
|
|
1080
|
+
/* @__PURE__ */ jsx2(Square, { className: "w-3 h-3 fill-current" }),
|
|
1319
1081
|
" Stop"
|
|
1320
|
-
]
|
|
1082
|
+
]
|
|
1083
|
+
}
|
|
1084
|
+
) : /* @__PURE__ */ jsxs2(
|
|
1085
|
+
"button",
|
|
1086
|
+
{
|
|
1087
|
+
type: "button",
|
|
1088
|
+
className: `flex items-center justify-center h-8 px-4 rounded-full text-xs font-semibold tracking-wide transition-all gap-1.5 ${canSend ? "bg-black dark:bg-white text-white dark:text-black shadow-md hover:scale-[1.02] active:scale-[0.98] cursor-pointer" : "bg-zinc-200 dark:bg-zinc-800 text-zinc-400 dark:text-zinc-600 cursor-not-allowed"}`,
|
|
1089
|
+
onClick: onSend,
|
|
1090
|
+
disabled: !canSend,
|
|
1091
|
+
children: [
|
|
1321
1092
|
"Send ",
|
|
1322
|
-
/* @__PURE__ */ jsx2(
|
|
1323
|
-
]
|
|
1093
|
+
/* @__PURE__ */ jsx2(Send, { className: "w-3.5 h-3.5" })
|
|
1094
|
+
]
|
|
1324
1095
|
}
|
|
1325
1096
|
) })
|
|
1326
1097
|
] })
|
|
@@ -1330,430 +1101,53 @@ ${newText}` : newText);
|
|
|
1330
1101
|
}
|
|
1331
1102
|
|
|
1332
1103
|
// src/react/components.tsx
|
|
1104
|
+
import { RotateCcw, ChevronDown } from "lucide-react";
|
|
1105
|
+
import { clsx } from "clsx";
|
|
1106
|
+
import { twMerge } from "tailwind-merge";
|
|
1333
1107
|
import { Streamdown } from "streamdown";
|
|
1334
1108
|
import { code } from "@streamdown/code";
|
|
1335
1109
|
import { mermaid } from "@streamdown/mermaid";
|
|
1336
|
-
import {
|
|
1110
|
+
import { math } from "@streamdown/math";
|
|
1111
|
+
import "streamdown/styles.css";
|
|
1112
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1113
|
+
function cn(...inputs) {
|
|
1114
|
+
return twMerge(clsx(inputs));
|
|
1115
|
+
}
|
|
1337
1116
|
var DEFAULT_SYSTEM_PROMPT = `You are a helpful AI assistant.
|
|
1338
1117
|
- You can use full Markdown (bold, italic, headers, lists).
|
|
1339
1118
|
- You can use Code Blocks with language syntax highlighting.
|
|
1340
1119
|
- You can use Mermaid diagrams (\`\`\`mermaid ... \`\`\`).
|
|
1341
1120
|
- You can use LaTeX math ($$ ... $$).`;
|
|
1342
1121
|
var ALL_MODELS = { ...WEBLLM_MODELS, ...TRANSFORMERS_MODELS };
|
|
1343
|
-
function RetryIcon() {
|
|
1344
|
-
return /* @__PURE__ */ jsxs3("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1345
|
-
/* @__PURE__ */ jsx3("polyline", { points: "23 4 23 10 17 10" }),
|
|
1346
|
-
/* @__PURE__ */ jsx3("path", { d: "M20.49 15a9 9 0 1 1-2.12-9.36L23 10" })
|
|
1347
|
-
] });
|
|
1348
|
-
}
|
|
1349
|
-
function ChevronDownIcon() {
|
|
1350
|
-
return /* @__PURE__ */ jsx3("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx3("polyline", { points: "6 9 12 15 18 9" }) });
|
|
1351
|
-
}
|
|
1352
|
-
var STYLE_ID2 = "__llm-chat-styles";
|
|
1353
|
-
function injectChatStyles(theme) {
|
|
1354
|
-
if (typeof document === "undefined") return;
|
|
1355
|
-
const existing = document.getElementById(STYLE_ID2);
|
|
1356
|
-
if (existing) existing.remove();
|
|
1357
|
-
const d = theme === "dark";
|
|
1358
|
-
const bg = d ? "#000000" : "#ffffff";
|
|
1359
|
-
const border = d ? "rgba(255,255,255,0.12)" : "rgba(0,0,0,0.12)";
|
|
1360
|
-
const borderSubtle = d ? "rgba(255,255,255,0.06)" : "rgba(0,0,0,0.06)";
|
|
1361
|
-
const text = d ? "#ffffff" : "#000000";
|
|
1362
|
-
const textSecondary = d ? "rgba(255,255,255,0.5)" : "rgba(0,0,0,0.5)";
|
|
1363
|
-
const textTertiary = d ? "rgba(255,255,255,0.3)" : "rgba(0,0,0,0.3)";
|
|
1364
|
-
const surfaceSubtle = d ? "rgba(255,255,255,0.04)" : "rgba(0,0,0,0.03)";
|
|
1365
|
-
const monoFont = `ui-monospace, SFMono-Regular, "SF Mono", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace`;
|
|
1366
|
-
const sansFont = `-apple-system, BlinkMacSystemFont, "Segoe UI", "Inter", Roboto, Helvetica, Arial, sans-serif`;
|
|
1367
|
-
const css = `
|
|
1368
|
-
.llm-chat {
|
|
1369
|
-
display: flex;
|
|
1370
|
-
flex-direction: column;
|
|
1371
|
-
border: 1px solid ${border};
|
|
1372
|
-
background: ${bg};
|
|
1373
|
-
overflow: hidden;
|
|
1374
|
-
font-family: ${sansFont};
|
|
1375
|
-
color: ${text};
|
|
1376
|
-
}
|
|
1377
|
-
|
|
1378
|
-
/* Header */
|
|
1379
|
-
.llm-chat-header {
|
|
1380
|
-
display: flex;
|
|
1381
|
-
align-items: center;
|
|
1382
|
-
justify-content: space-between;
|
|
1383
|
-
padding: 12px 16px;
|
|
1384
|
-
border-bottom: 1px solid ${borderSubtle};
|
|
1385
|
-
}
|
|
1386
|
-
|
|
1387
|
-
/* Model Selector */
|
|
1388
|
-
.llm-chat-model-select {
|
|
1389
|
-
position: relative;
|
|
1390
|
-
}
|
|
1391
|
-
.llm-chat-model-btn {
|
|
1392
|
-
display: flex;
|
|
1393
|
-
align-items: center;
|
|
1394
|
-
gap: 6px;
|
|
1395
|
-
background: transparent;
|
|
1396
|
-
border: none;
|
|
1397
|
-
color: ${text};
|
|
1398
|
-
font-weight: 400;
|
|
1399
|
-
font-size: 11px;
|
|
1400
|
-
font-family: ${monoFont};
|
|
1401
|
-
text-transform: uppercase;
|
|
1402
|
-
letter-spacing: 0.05em;
|
|
1403
|
-
padding: 4px 0;
|
|
1404
|
-
cursor: pointer;
|
|
1405
|
-
transition: opacity 0.1s;
|
|
1406
|
-
}
|
|
1407
|
-
.llm-chat-model-btn:hover {
|
|
1408
|
-
opacity: 0.6;
|
|
1409
|
-
}
|
|
1410
|
-
.llm-chat-model-menu {
|
|
1411
|
-
position: absolute;
|
|
1412
|
-
top: 100%;
|
|
1413
|
-
left: 0;
|
|
1414
|
-
margin-top: 4px;
|
|
1415
|
-
width: 280px;
|
|
1416
|
-
max-height: 300px;
|
|
1417
|
-
overflow-y: auto;
|
|
1418
|
-
background: ${d ? "#0a0a0a" : "#fafafa"};
|
|
1419
|
-
border: 1px solid ${border};
|
|
1420
|
-
z-index: 50;
|
|
1421
|
-
padding: 4px 0;
|
|
1422
|
-
scrollbar-width: thin;
|
|
1423
|
-
}
|
|
1424
|
-
.llm-chat-model-group {
|
|
1425
|
-
padding: 8px 12px 4px;
|
|
1426
|
-
font-size: 10px;
|
|
1427
|
-
font-weight: 400;
|
|
1428
|
-
color: ${textSecondary};
|
|
1429
|
-
text-transform: uppercase;
|
|
1430
|
-
letter-spacing: 0.08em;
|
|
1431
|
-
font-family: ${monoFont};
|
|
1432
|
-
}
|
|
1433
|
-
.llm-chat-model-item {
|
|
1434
|
-
display: block;
|
|
1435
|
-
width: 100%;
|
|
1436
|
-
text-align: left;
|
|
1437
|
-
padding: 6px 12px;
|
|
1438
|
-
font-size: 12px;
|
|
1439
|
-
font-family: ${monoFont};
|
|
1440
|
-
color: ${textSecondary};
|
|
1441
|
-
background: transparent;
|
|
1442
|
-
border: none;
|
|
1443
|
-
cursor: pointer;
|
|
1444
|
-
white-space: nowrap;
|
|
1445
|
-
overflow: hidden;
|
|
1446
|
-
text-overflow: ellipsis;
|
|
1447
|
-
transition: color 0.1s;
|
|
1448
|
-
}
|
|
1449
|
-
.llm-chat-model-item:hover {
|
|
1450
|
-
color: ${text};
|
|
1451
|
-
}
|
|
1452
|
-
.llm-chat-model-item--active {
|
|
1453
|
-
color: ${text};
|
|
1454
|
-
}
|
|
1455
|
-
|
|
1456
|
-
/* Status */
|
|
1457
|
-
.llm-chat-status {
|
|
1458
|
-
display: flex;
|
|
1459
|
-
align-items: center;
|
|
1460
|
-
gap: 8px;
|
|
1461
|
-
font-size: 10px;
|
|
1462
|
-
font-family: ${monoFont};
|
|
1463
|
-
text-transform: uppercase;
|
|
1464
|
-
letter-spacing: 0.08em;
|
|
1465
|
-
color: ${textSecondary};
|
|
1466
|
-
}
|
|
1467
|
-
.llm-chat-dot {
|
|
1468
|
-
width: 5px;
|
|
1469
|
-
height: 5px;
|
|
1470
|
-
border-radius: 50%;
|
|
1471
|
-
}
|
|
1472
|
-
.llm-chat-dot--loading {
|
|
1473
|
-
background: ${textSecondary};
|
|
1474
|
-
animation: llm-pulse 1.5s infinite;
|
|
1475
|
-
}
|
|
1476
|
-
.llm-chat-dot--ready {
|
|
1477
|
-
background: ${text};
|
|
1478
|
-
}
|
|
1479
|
-
.llm-chat-dot--error {
|
|
1480
|
-
background: #ff3333;
|
|
1481
|
-
}
|
|
1482
|
-
|
|
1483
|
-
/* Progress */
|
|
1484
|
-
.llm-chat-progress {
|
|
1485
|
-
padding: 0 16px 8px;
|
|
1486
|
-
}
|
|
1487
|
-
.llm-chat-progress-bar {
|
|
1488
|
-
height: 1px;
|
|
1489
|
-
background: ${borderSubtle};
|
|
1490
|
-
overflow: hidden;
|
|
1491
|
-
}
|
|
1492
|
-
.llm-chat-progress-fill {
|
|
1493
|
-
height: 100%;
|
|
1494
|
-
background: ${text};
|
|
1495
|
-
transition: width 0.3s ease;
|
|
1496
|
-
}
|
|
1497
|
-
.llm-chat-progress-text {
|
|
1498
|
-
font-size: 10px;
|
|
1499
|
-
font-family: ${monoFont};
|
|
1500
|
-
color: ${textTertiary};
|
|
1501
|
-
margin-top: 4px;
|
|
1502
|
-
text-align: right;
|
|
1503
|
-
text-transform: uppercase;
|
|
1504
|
-
letter-spacing: 0.05em;
|
|
1505
|
-
}
|
|
1506
|
-
|
|
1507
|
-
/* Messages */
|
|
1508
|
-
.llm-chat-messages {
|
|
1509
|
-
flex: 1;
|
|
1510
|
-
overflow-y: auto;
|
|
1511
|
-
padding: 20px 16px;
|
|
1512
|
-
display: flex;
|
|
1513
|
-
flex-direction: column;
|
|
1514
|
-
gap: 24px;
|
|
1515
|
-
scrollbar-width: thin;
|
|
1516
|
-
}
|
|
1517
|
-
|
|
1518
|
-
/* Welcome */
|
|
1519
|
-
.llm-chat-welcome {
|
|
1520
|
-
display: flex;
|
|
1521
|
-
flex-direction: column;
|
|
1522
|
-
align-items: flex-start;
|
|
1523
|
-
justify-content: center;
|
|
1524
|
-
flex: 1;
|
|
1525
|
-
color: ${textTertiary};
|
|
1526
|
-
padding: 40px 0;
|
|
1527
|
-
}
|
|
1528
|
-
.llm-chat-welcome h3 {
|
|
1529
|
-
font-size: 11px;
|
|
1530
|
-
font-weight: 400;
|
|
1531
|
-
font-family: ${monoFont};
|
|
1532
|
-
text-transform: uppercase;
|
|
1533
|
-
letter-spacing: 0.08em;
|
|
1534
|
-
color: ${textSecondary};
|
|
1535
|
-
margin: 0 0 8px;
|
|
1536
|
-
}
|
|
1537
|
-
.llm-chat-welcome p {
|
|
1538
|
-
font-size: 13px;
|
|
1539
|
-
margin: 0;
|
|
1540
|
-
max-width: 360px;
|
|
1541
|
-
line-height: 1.6;
|
|
1542
|
-
color: ${textTertiary};
|
|
1543
|
-
}
|
|
1544
|
-
|
|
1545
|
-
/* Bubble */
|
|
1546
|
-
.llm-chat-bubble {
|
|
1547
|
-
display: flex;
|
|
1548
|
-
flex-direction: column;
|
|
1549
|
-
max-width: 100%;
|
|
1550
|
-
}
|
|
1551
|
-
.llm-chat-bubble--user {
|
|
1552
|
-
align-self: flex-end;
|
|
1553
|
-
max-width: 80%;
|
|
1554
|
-
overflow-wrap: break-word;
|
|
1555
|
-
}
|
|
1556
|
-
.llm-chat-bubble--assistant {
|
|
1557
|
-
align-self: flex-start;
|
|
1558
|
-
width: 100%;
|
|
1559
|
-
min-width: 0; /* Prevents flex children from expanding past 100% */
|
|
1560
|
-
overflow-x: hidden;
|
|
1561
|
-
}
|
|
1562
|
-
|
|
1563
|
-
/* User message \u2014 flat, subtle bg, no radius */
|
|
1564
|
-
.llm-chat-user-content {
|
|
1565
|
-
padding: 10px 14px;
|
|
1566
|
-
font-size: 14px;
|
|
1567
|
-
line-height: 1.6;
|
|
1568
|
-
white-space: pre-wrap;
|
|
1569
|
-
background: ${surfaceSubtle};
|
|
1570
|
-
border: 1px solid ${borderSubtle};
|
|
1571
|
-
color: ${text};
|
|
1572
|
-
}
|
|
1573
|
-
|
|
1574
|
-
/* Streamdown Overrides / Markdown Styling */
|
|
1575
|
-
.llm-chat-assistant-content {
|
|
1576
|
-
font-size: 14px;
|
|
1577
|
-
line-height: 1.7;
|
|
1578
|
-
color: ${text};
|
|
1579
|
-
word-wrap: break-word;
|
|
1580
|
-
}
|
|
1581
|
-
.llm-chat-assistant-content > *:first-child { margin-top: 0; }
|
|
1582
|
-
.llm-chat-assistant-content > *:last-child { margin-bottom: 0; }
|
|
1583
|
-
|
|
1584
|
-
.llm-chat-assistant-content p {
|
|
1585
|
-
margin: 0 0 12px 0;
|
|
1586
|
-
}
|
|
1587
|
-
|
|
1588
|
-
.llm-chat-assistant-content h1,
|
|
1589
|
-
.llm-chat-assistant-content h2,
|
|
1590
|
-
.llm-chat-assistant-content h3,
|
|
1591
|
-
.llm-chat-assistant-content h4 {
|
|
1592
|
-
margin: 20px 0 10px 0;
|
|
1593
|
-
color: ${text};
|
|
1594
|
-
font-weight: 600;
|
|
1595
|
-
line-height: 1.3;
|
|
1596
|
-
}
|
|
1597
|
-
.llm-chat-assistant-content h1 { font-size: 1.5em; }
|
|
1598
|
-
.llm-chat-assistant-content h2 { font-size: 1.3em; }
|
|
1599
|
-
.llm-chat-assistant-content h3 { font-size: 1.1em; }
|
|
1600
|
-
|
|
1601
|
-
.llm-chat-assistant-content ul,
|
|
1602
|
-
.llm-chat-assistant-content ol {
|
|
1603
|
-
margin: 0 0 12px 0;
|
|
1604
|
-
padding-left: 24px;
|
|
1605
|
-
}
|
|
1606
|
-
.llm-chat-assistant-content li {
|
|
1607
|
-
margin-bottom: 4px;
|
|
1608
|
-
}
|
|
1609
|
-
|
|
1610
|
-
.llm-chat-assistant-content pre {
|
|
1611
|
-
background: ${surfaceSubtle} !important;
|
|
1612
|
-
border: 1px solid ${borderSubtle} !important;
|
|
1613
|
-
border-radius: 6px !important;
|
|
1614
|
-
padding: 12px !important;
|
|
1615
|
-
margin: 12px 0 !important;
|
|
1616
|
-
overflow-x: auto !important;
|
|
1617
|
-
white-space: pre !important;
|
|
1618
|
-
max-width: 100%;
|
|
1619
|
-
}
|
|
1620
|
-
.llm-chat-assistant-content code {
|
|
1621
|
-
font-family: ${monoFont} !important;
|
|
1622
|
-
font-size: 13px !important;
|
|
1623
|
-
white-space: inherit;
|
|
1624
|
-
}
|
|
1625
|
-
.llm-chat-assistant-content :not(pre) > code {
|
|
1626
|
-
background: ${surfaceSubtle};
|
|
1627
|
-
border: 1px solid ${borderSubtle};
|
|
1628
|
-
border-radius: 4px;
|
|
1629
|
-
padding: 2px 5px;
|
|
1630
|
-
font-size: 12.5px !important;
|
|
1631
|
-
white-space: pre-wrap !important;
|
|
1632
|
-
word-break: break-word;
|
|
1633
|
-
}
|
|
1634
|
-
|
|
1635
|
-
.llm-chat-assistant-content blockquote {
|
|
1636
|
-
border-left: 3px solid ${borderSubtle};
|
|
1637
|
-
margin: 0 0 12px 0;
|
|
1638
|
-
padding-left: 12px;
|
|
1639
|
-
color: ${textTertiary};
|
|
1640
|
-
}
|
|
1641
|
-
|
|
1642
|
-
.llm-chat-assistant-content a {
|
|
1643
|
-
color: #3b82f6;
|
|
1644
|
-
text-decoration: none;
|
|
1645
|
-
}
|
|
1646
|
-
.llm-chat-assistant-content a:hover {
|
|
1647
|
-
text-decoration: underline;
|
|
1648
|
-
}
|
|
1649
|
-
|
|
1650
|
-
.llm-chat-assistant-content table {
|
|
1651
|
-
border-collapse: collapse;
|
|
1652
|
-
width: 100%;
|
|
1653
|
-
margin: 12px 0;
|
|
1654
|
-
}
|
|
1655
|
-
.llm-chat-assistant-content th,
|
|
1656
|
-
.llm-chat-assistant-content td {
|
|
1657
|
-
border: 1px solid ${borderSubtle};
|
|
1658
|
-
padding: 6px 10px;
|
|
1659
|
-
text-align: left;
|
|
1660
|
-
}
|
|
1661
|
-
.llm-chat-assistant-content th {
|
|
1662
|
-
background: ${surfaceSubtle};
|
|
1663
|
-
font-weight: 600;
|
|
1664
|
-
}
|
|
1665
|
-
|
|
1666
|
-
/* Attachments in message */
|
|
1667
|
-
.llm-chat-msg-images {
|
|
1668
|
-
display: flex;
|
|
1669
|
-
flex-wrap: wrap;
|
|
1670
|
-
gap: 6px;
|
|
1671
|
-
margin-bottom: 8px;
|
|
1672
|
-
justify-content: flex-end;
|
|
1673
|
-
}
|
|
1674
|
-
.llm-chat-msg-img {
|
|
1675
|
-
width: 100px;
|
|
1676
|
-
height: 100px;
|
|
1677
|
-
object-fit: cover;
|
|
1678
|
-
border: 1px solid ${border};
|
|
1679
|
-
}
|
|
1680
|
-
|
|
1681
|
-
/* Error */
|
|
1682
|
-
.llm-chat-error {
|
|
1683
|
-
margin: 0 16px;
|
|
1684
|
-
padding: 10px 14px;
|
|
1685
|
-
border: 1px solid ${d ? "rgba(255,50,50,0.2)" : "rgba(200,0,0,0.15)"};
|
|
1686
|
-
display: flex;
|
|
1687
|
-
align-items: center;
|
|
1688
|
-
justify-content: space-between;
|
|
1689
|
-
gap: 12px;
|
|
1690
|
-
}
|
|
1691
|
-
.llm-chat-error-text {
|
|
1692
|
-
font-size: 12px;
|
|
1693
|
-
font-family: ${monoFont};
|
|
1694
|
-
color: ${d ? "#ff6666" : "#cc0000"};
|
|
1695
|
-
flex: 1;
|
|
1696
|
-
}
|
|
1697
|
-
.llm-chat-error-retry {
|
|
1698
|
-
display: flex;
|
|
1699
|
-
align-items: center;
|
|
1700
|
-
gap: 4px;
|
|
1701
|
-
padding: 4px 10px;
|
|
1702
|
-
border: 1px solid ${d ? "rgba(255,50,50,0.3)" : "rgba(200,0,0,0.2)"};
|
|
1703
|
-
background: transparent;
|
|
1704
|
-
color: ${d ? "#ff6666" : "#cc0000"};
|
|
1705
|
-
font-size: 11px;
|
|
1706
|
-
font-family: ${monoFont};
|
|
1707
|
-
text-transform: uppercase;
|
|
1708
|
-
letter-spacing: 0.05em;
|
|
1709
|
-
cursor: pointer;
|
|
1710
|
-
}
|
|
1711
|
-
.llm-chat-error-retry:hover {
|
|
1712
|
-
background: ${d ? "rgba(255,50,50,0.08)" : "rgba(200,0,0,0.04)"};
|
|
1713
|
-
}
|
|
1714
|
-
|
|
1715
|
-
.llm-chat-input-area {
|
|
1716
|
-
padding: 12px 16px 16px;
|
|
1717
|
-
border-top: 1px solid ${borderSubtle};
|
|
1718
|
-
}
|
|
1719
|
-
|
|
1720
|
-
/* Streamdown Animation CSS */
|
|
1721
|
-
@keyframes sd-fadeIn {
|
|
1722
|
-
from { opacity: 0; }
|
|
1723
|
-
to { opacity: 1; }
|
|
1724
|
-
}
|
|
1725
|
-
@keyframes sd-blurIn {
|
|
1726
|
-
from { opacity: 0; filter: blur(4px); }
|
|
1727
|
-
to { opacity: 1; filter: blur(0); }
|
|
1728
|
-
}
|
|
1729
|
-
@keyframes sd-slideUp {
|
|
1730
|
-
from { opacity: 0; transform: translateY(4px); }
|
|
1731
|
-
to { opacity: 1; transform: translateY(0); }
|
|
1732
|
-
}
|
|
1733
|
-
[data-sd-animate] {
|
|
1734
|
-
animation: var(--sd-animation, sd-fadeIn) var(--sd-duration, 150ms)
|
|
1735
|
-
var(--sd-easing, ease) both;
|
|
1736
|
-
}
|
|
1737
|
-
|
|
1738
|
-
@keyframes llm-pulse {
|
|
1739
|
-
0%, 100% { opacity: 1; }
|
|
1740
|
-
50% { opacity: 0.2; }
|
|
1741
|
-
}
|
|
1742
|
-
`;
|
|
1743
|
-
const style = document.createElement("style");
|
|
1744
|
-
style.id = STYLE_ID2;
|
|
1745
|
-
style.textContent = css;
|
|
1746
|
-
document.head.appendChild(style);
|
|
1747
|
-
}
|
|
1748
1122
|
function isVisionModel2(modelId) {
|
|
1749
1123
|
if (!modelId) return false;
|
|
1750
1124
|
const lower = modelId.toLowerCase();
|
|
1751
1125
|
return lower.includes("vl") || lower.includes("vision") || lower.includes("moondream");
|
|
1752
1126
|
}
|
|
1127
|
+
var markdownComponents = {
|
|
1128
|
+
h1: ({ children }) => /* @__PURE__ */ jsx3("h1", { className: "text-3xl font-bold tracking-tight mt-6 mb-4 text-zinc-900 dark:text-zinc-100", children }),
|
|
1129
|
+
h2: ({ children }) => /* @__PURE__ */ jsx3("h2", { className: "text-2xl font-semibold tracking-tight mt-6 mb-4 text-zinc-900 dark:text-zinc-100 border-b border-zinc-200 dark:border-zinc-800 pb-2", children }),
|
|
1130
|
+
h3: ({ children }) => /* @__PURE__ */ jsx3("h3", { className: "text-xl font-semibold tracking-tight mt-6 mb-3 text-zinc-900 dark:text-zinc-100", children }),
|
|
1131
|
+
h4: ({ children }) => /* @__PURE__ */ jsx3("h4", { className: "text-lg font-semibold tracking-tight mt-4 mb-2 text-zinc-900 dark:text-zinc-100", children }),
|
|
1132
|
+
p: ({ children }) => /* @__PURE__ */ jsx3("p", { className: "leading-7 [&:not(:first-child)]:mt-4 text-zinc-800 dark:text-zinc-300", children }),
|
|
1133
|
+
ul: ({ children }) => /* @__PURE__ */ jsx3("ul", { className: "my-4 ml-6 list-disc [&>li]:mt-2 text-zinc-800 dark:text-zinc-300", children }),
|
|
1134
|
+
ol: ({ children }) => /* @__PURE__ */ jsx3("ol", { className: "my-4 ml-6 list-decimal [&>li]:mt-2 text-zinc-800 dark:text-zinc-300", children }),
|
|
1135
|
+
li: ({ children }) => /* @__PURE__ */ jsx3("li", { children }),
|
|
1136
|
+
blockquote: ({ children }) => /* @__PURE__ */ jsx3("blockquote", { className: "mt-4 border-l-2 border-zinc-300 dark:border-zinc-700 pl-4 italic text-zinc-600 dark:text-zinc-400", children }),
|
|
1137
|
+
a: ({ href, children }) => /* @__PURE__ */ jsx3("a", { href, className: "font-medium text-blue-600 hover:underline dark:text-blue-400", target: "_blank", rel: "noopener noreferrer", children }),
|
|
1138
|
+
table: ({ children }) => /* @__PURE__ */ jsx3("div", { className: "my-4 w-full overflow-y-auto", children: /* @__PURE__ */ jsx3("table", { className: "w-full text-sm", children }) }),
|
|
1139
|
+
tr: ({ children }) => /* @__PURE__ */ jsx3("tr", { className: "m-0 border-t border-zinc-200 dark:border-zinc-800 p-0 even:bg-zinc-50 dark:even:bg-zinc-900/50", children }),
|
|
1140
|
+
th: ({ children }) => /* @__PURE__ */ jsx3("th", { className: "border border-zinc-200 dark:border-zinc-700 bg-zinc-50 dark:bg-zinc-900 px-4 py-2 font-semibold text-zinc-900 dark:text-zinc-100 text-left [&[align=center]]:text-center [&[align=right]]:text-right", children }),
|
|
1141
|
+
td: ({ children }) => /* @__PURE__ */ jsx3("td", { className: "border border-zinc-200 dark:border-zinc-700 px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right text-zinc-700 dark:text-zinc-300", children }),
|
|
1142
|
+
pre: ({ children }) => /* @__PURE__ */ jsx3("pre", { className: "mt-4 mb-4 overflow-x-auto rounded-xl border border-zinc-200 dark:border-zinc-800 bg-zinc-50 dark:bg-zinc-950 p-4 text-[13px] leading-relaxed font-mono shadow-sm", children }),
|
|
1143
|
+
code: ({ children, className }) => {
|
|
1144
|
+
const isInline = !className;
|
|
1145
|
+
return /* @__PURE__ */ jsx3("code", { className: cn("font-mono text-[13px]", isInline ? "bg-zinc-100 dark:bg-zinc-800/60 rounded-md px-1.5 py-0.5 border border-zinc-200 dark:border-zinc-700 text-zinc-800 dark:text-zinc-300" : ""), children });
|
|
1146
|
+
}
|
|
1147
|
+
};
|
|
1753
1148
|
function ModelSelector({
|
|
1754
1149
|
currentModel,
|
|
1755
|
-
onSelect
|
|
1756
|
-
theme
|
|
1150
|
+
onSelect
|
|
1757
1151
|
}) {
|
|
1758
1152
|
const [isOpen, setIsOpen] = useState3(false);
|
|
1759
1153
|
const ref = useRef3(null);
|
|
@@ -1775,27 +1169,28 @@ function ModelSelector({
|
|
|
1775
1169
|
}
|
|
1776
1170
|
return label;
|
|
1777
1171
|
}, [currentModel]);
|
|
1778
|
-
return /* @__PURE__ */ jsxs3("div", { className: "
|
|
1172
|
+
return /* @__PURE__ */ jsxs3("div", { className: "relative", ref, children: [
|
|
1779
1173
|
/* @__PURE__ */ jsxs3(
|
|
1780
1174
|
"button",
|
|
1781
1175
|
{
|
|
1782
1176
|
type: "button",
|
|
1783
|
-
className: "
|
|
1177
|
+
className: "flex items-center gap-1.5 px-3 py-1.5 bg-zinc-100 hover:bg-zinc-200 dark:bg-zinc-800 dark:hover:bg-zinc-700 text-zinc-700 dark:text-zinc-300 text-xs font-medium tracking-wide rounded-full transition-colors",
|
|
1784
1178
|
onClick: () => setIsOpen(!isOpen),
|
|
1785
1179
|
children: [
|
|
1786
|
-
"
|
|
1787
|
-
|
|
1788
|
-
"] ",
|
|
1789
|
-
/* @__PURE__ */ jsx3(ChevronDownIcon, {})
|
|
1180
|
+
/* @__PURE__ */ jsx3("span", { children: displayModel }),
|
|
1181
|
+
/* @__PURE__ */ jsx3(ChevronDown, { className: "w-3.5 h-3.5 opacity-70" })
|
|
1790
1182
|
]
|
|
1791
1183
|
}
|
|
1792
1184
|
),
|
|
1793
|
-
isOpen && /* @__PURE__ */ jsxs3("div", { className: "
|
|
1794
|
-
/* @__PURE__ */ jsx3("div", { className: "
|
|
1185
|
+
isOpen && /* @__PURE__ */ jsxs3("div", { className: "absolute top-[calc(100%+8px)] left-0 w-72 max-h-[300px] overflow-y-auto bg-white dark:bg-zinc-900 border border-zinc-200 dark:border-zinc-800 rounded-xl shadow-xl z-50 py-2 scrollbar-thin", children: [
|
|
1186
|
+
/* @__PURE__ */ jsx3("div", { className: "px-3 py-1.5 text-[10px] font-bold text-zinc-400 dark:text-zinc-500 uppercase tracking-wider", children: "WebLLM" }),
|
|
1795
1187
|
Object.entries(WEBLLM_MODELS).map(([key, value]) => /* @__PURE__ */ jsxs3(
|
|
1796
1188
|
"button",
|
|
1797
1189
|
{
|
|
1798
|
-
className:
|
|
1190
|
+
className: cn(
|
|
1191
|
+
"block w-full text-left px-3 py-2 text-xs font-medium truncate transition-colors",
|
|
1192
|
+
currentModel === value ? "bg-blue-50 text-blue-600 dark:bg-blue-900/20 dark:text-blue-400" : "text-zinc-600 dark:text-zinc-400 hover:bg-zinc-50 dark:hover:bg-zinc-800/50"
|
|
1193
|
+
),
|
|
1799
1194
|
onClick: () => {
|
|
1800
1195
|
onSelect(value);
|
|
1801
1196
|
setIsOpen(false);
|
|
@@ -1803,16 +1198,19 @@ function ModelSelector({
|
|
|
1803
1198
|
children: [
|
|
1804
1199
|
key,
|
|
1805
1200
|
" ",
|
|
1806
|
-
isVisionModel2(value)
|
|
1201
|
+
isVisionModel2(value) && /* @__PURE__ */ jsx3("span", { className: "ml-1 px-1.5 py-0.5 rounded text-[9px] bg-zinc-100 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700", children: "VISION" })
|
|
1807
1202
|
]
|
|
1808
1203
|
},
|
|
1809
1204
|
key
|
|
1810
1205
|
)),
|
|
1811
|
-
/* @__PURE__ */ jsx3("div", { className: "
|
|
1206
|
+
/* @__PURE__ */ jsx3("div", { className: "px-3 py-1.5 text-[10px] font-bold text-zinc-400 dark:text-zinc-500 uppercase tracking-wider mt-2 border-t border-zinc-100 dark:border-zinc-800 pt-3", children: "Transformers.js" }),
|
|
1812
1207
|
Object.entries(TRANSFORMERS_MODELS).map(([key, value]) => /* @__PURE__ */ jsxs3(
|
|
1813
1208
|
"button",
|
|
1814
1209
|
{
|
|
1815
|
-
className:
|
|
1210
|
+
className: cn(
|
|
1211
|
+
"block w-full text-left px-3 py-2 text-xs font-medium truncate transition-colors",
|
|
1212
|
+
currentModel === value ? "bg-blue-50 text-blue-600 dark:bg-blue-900/20 dark:text-blue-400" : "text-zinc-600 dark:text-zinc-400 hover:bg-zinc-50 dark:hover:bg-zinc-800/50"
|
|
1213
|
+
),
|
|
1816
1214
|
onClick: () => {
|
|
1817
1215
|
onSelect(value);
|
|
1818
1216
|
setIsOpen(false);
|
|
@@ -1820,7 +1218,7 @@ function ModelSelector({
|
|
|
1820
1218
|
children: [
|
|
1821
1219
|
key,
|
|
1822
1220
|
" ",
|
|
1823
|
-
isVisionModel2(value)
|
|
1221
|
+
isVisionModel2(value) && /* @__PURE__ */ jsx3("span", { className: "ml-1 px-1.5 py-0.5 rounded text-[9px] bg-zinc-100 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700", children: "VISION" })
|
|
1824
1222
|
]
|
|
1825
1223
|
},
|
|
1826
1224
|
key
|
|
@@ -1830,7 +1228,7 @@ function ModelSelector({
|
|
|
1830
1228
|
}
|
|
1831
1229
|
function Chat({
|
|
1832
1230
|
systemPrompt = DEFAULT_SYSTEM_PROMPT,
|
|
1833
|
-
placeholder = "
|
|
1231
|
+
placeholder = "Message...",
|
|
1834
1232
|
theme = "dark",
|
|
1835
1233
|
className,
|
|
1836
1234
|
maxHeight = "600px",
|
|
@@ -1840,7 +1238,7 @@ function Chat({
|
|
|
1840
1238
|
onError: onErrorProp,
|
|
1841
1239
|
showHeader = true,
|
|
1842
1240
|
showProgress = true,
|
|
1843
|
-
welcomeMessage = "
|
|
1241
|
+
welcomeMessage = "How can I help you today?",
|
|
1844
1242
|
onModelChange
|
|
1845
1243
|
}) {
|
|
1846
1244
|
const { llm, isLoading, isReady, loadProgress, error, modelId, reload } = useLLM();
|
|
@@ -1853,9 +1251,6 @@ function Chat({
|
|
|
1853
1251
|
const messagesEndRef = useRef3(null);
|
|
1854
1252
|
const abortRef = useRef3(false);
|
|
1855
1253
|
const isProcessingRef = useRef3(false);
|
|
1856
|
-
useEffect3(() => {
|
|
1857
|
-
injectChatStyles(theme);
|
|
1858
|
-
}, [theme]);
|
|
1859
1254
|
useEffect3(() => {
|
|
1860
1255
|
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
1861
1256
|
}, [messages, streamingText, isGenerating]);
|
|
@@ -1954,83 +1349,70 @@ function Chat({
|
|
|
1954
1349
|
setStreamingText("");
|
|
1955
1350
|
}
|
|
1956
1351
|
};
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
return /* @__PURE__ */ jsxs3("div", { className: `llm-chat${className ? ` ${className}` : ""}`, style: { maxHeight, height: "100%" }, children: [
|
|
1960
|
-
showHeader && /* @__PURE__ */ jsxs3("div", { className: "llm-chat-header", children: [
|
|
1352
|
+
return /* @__PURE__ */ jsxs3("div", { className: cn("flex flex-col bg-white dark:bg-[#09090b] border border-zinc-200 dark:border-zinc-800 rounded-3xl overflow-hidden shadow-sm", className), style: { maxHeight, height: "100%" }, children: [
|
|
1353
|
+
showHeader && /* @__PURE__ */ jsxs3("div", { className: "flex items-center justify-between px-5 py-4 border-b border-zinc-100 dark:border-zinc-800/60 bg-white/50 dark:bg-zinc-900/20 backdrop-blur-md", children: [
|
|
1961
1354
|
onModelChange ? /* @__PURE__ */ jsx3(
|
|
1962
1355
|
ModelSelector,
|
|
1963
1356
|
{
|
|
1964
1357
|
currentModel: modelId,
|
|
1965
|
-
onSelect: onModelChange
|
|
1966
|
-
theme
|
|
1358
|
+
onSelect: onModelChange
|
|
1967
1359
|
}
|
|
1968
|
-
) : /* @__PURE__ */
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
"
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
] }) }),
|
|
1979
|
-
/* @__PURE__ */ jsxs3("div", { className: "llm-chat-status", children: [
|
|
1980
|
-
/* @__PURE__ */ jsx3("span", { children: statusText }),
|
|
1981
|
-
/* @__PURE__ */ jsx3("div", { className: statusDotClass })
|
|
1360
|
+
) : /* @__PURE__ */ jsxs3("div", { className: "px-3 py-1 bg-zinc-100 dark:bg-zinc-800 rounded-full flex items-center gap-2", children: [
|
|
1361
|
+
/* @__PURE__ */ jsx3("span", { className: "text-xs font-semibold tracking-wide text-zinc-700 dark:text-zinc-300", children: modelId?.split("/").pop() }),
|
|
1362
|
+
modelId && isVisionModel2(modelId) && /* @__PURE__ */ jsx3("span", { className: "px-1.5 py-0.5 rounded text-[9px] font-bold bg-blue-100 text-blue-600 dark:bg-blue-900/30 dark:text-blue-400 border border-blue-200 dark:border-blue-800", children: "VISION" })
|
|
1363
|
+
] }),
|
|
1364
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2", children: [
|
|
1365
|
+
/* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-zinc-500 dark:text-zinc-400 capitalize", children: error ? "Error" : isReady ? "Ready" : isLoading ? "Loading" : "Idle" }),
|
|
1366
|
+
/* @__PURE__ */ jsx3("div", { className: cn(
|
|
1367
|
+
"w-2 h-2 rounded-full",
|
|
1368
|
+
error ? "bg-red-500" : isReady ? "bg-emerald-500 shadow-[0_0_8px_rgba(16,185,129,0.5)]" : "bg-zinc-300 dark:bg-zinc-700 animate-pulse"
|
|
1369
|
+
) })
|
|
1982
1370
|
] })
|
|
1983
1371
|
] }),
|
|
1984
|
-
showProgress && isLoading && loadProgress && /* @__PURE__ */ jsxs3("div", { className: "
|
|
1985
|
-
/* @__PURE__ */
|
|
1372
|
+
showProgress && isLoading && loadProgress && /* @__PURE__ */ jsxs3("div", { className: "px-5 py-3 border-b border-zinc-100 dark:border-zinc-800 bg-zinc-50/50 dark:bg-zinc-900/30", children: [
|
|
1373
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex justify-between items-center mb-1.5", children: [
|
|
1374
|
+
/* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-zinc-600 dark:text-zinc-400 truncate pr-4", children: loadProgress.status }),
|
|
1375
|
+
/* @__PURE__ */ jsxs3("span", { className: "text-xs font-bold text-zinc-900 dark:text-zinc-100", children: [
|
|
1376
|
+
Math.round(loadProgress.progress),
|
|
1377
|
+
"%"
|
|
1378
|
+
] })
|
|
1379
|
+
] }),
|
|
1380
|
+
/* @__PURE__ */ jsx3("div", { className: "h-1.5 w-full bg-zinc-200 dark:bg-zinc-800 rounded-full overflow-hidden", children: /* @__PURE__ */ jsx3(
|
|
1986
1381
|
"div",
|
|
1987
1382
|
{
|
|
1988
|
-
className: "
|
|
1383
|
+
className: "h-full bg-blue-500 dark:bg-blue-600 rounded-full transition-all duration-300 ease-out",
|
|
1989
1384
|
style: { width: `${Math.min(100, loadProgress.progress)}%` }
|
|
1990
1385
|
}
|
|
1991
|
-
) })
|
|
1992
|
-
/* @__PURE__ */ jsx3("div", { className: "llm-chat-progress-text", children: loadProgress.status })
|
|
1386
|
+
) })
|
|
1993
1387
|
] }),
|
|
1994
|
-
error && /* @__PURE__ */ jsxs3("div", { className: "
|
|
1995
|
-
/* @__PURE__ */ jsx3("span", { className: "
|
|
1996
|
-
/* @__PURE__ */ jsxs3(
|
|
1997
|
-
|
|
1998
|
-
" Retry"
|
|
1999
|
-
] })
|
|
2000
|
-
] }),
|
|
2001
|
-
/* @__PURE__ */ jsxs3("div", { className: "llm-chat-messages", children: [
|
|
2002
|
-
!isLoading && messages.length === 0 && !error && /* @__PURE__ */ jsxs3("div", { className: "llm-chat-welcome", children: [
|
|
2003
|
-
/* @__PURE__ */ jsxs3("h3", { children: [
|
|
2004
|
-
"[",
|
|
2005
|
-
welcomeMessage,
|
|
2006
|
-
"]"
|
|
2007
|
-
] }),
|
|
2008
|
-
/* @__PURE__ */ jsx3("p", { children: "Markdown, code blocks, Mermaid diagrams. Paste images with Ctrl+V." })
|
|
2009
|
-
] }),
|
|
2010
|
-
messages.map((msg, i) => /* @__PURE__ */ jsx3("div", { className: `llm-chat-bubble llm-chat-bubble--${msg.role}`, children: msg.role === "user" ? /* @__PURE__ */ jsxs3(Fragment3, { children: [
|
|
2011
|
-
msg.images && msg.images.length > 0 && /* @__PURE__ */ jsx3("div", { className: "llm-chat-msg-images", children: msg.images.map((img) => /* @__PURE__ */ jsx3("img", { src: img.dataUrl, className: "llm-chat-msg-img", alt: "attachment" }, img.id)) }),
|
|
2012
|
-
/* @__PURE__ */ jsx3("div", { className: "llm-chat-user-content", style: { padding: "0px" }, children: /* @__PURE__ */ jsx3("div", { className: "llm-chat-assistant-content", style: { padding: "10px 14px" }, children: /* @__PURE__ */ jsx3(Streamdown, { plugins: { code, mermaid }, children: msg.content }) }) })
|
|
2013
|
-
] }) : /* @__PURE__ */ jsx3("div", { className: "llm-chat-assistant-content", children: /* @__PURE__ */ jsx3(
|
|
2014
|
-
Streamdown,
|
|
2015
|
-
{
|
|
2016
|
-
plugins: { code, mermaid },
|
|
2017
|
-
animated: true,
|
|
2018
|
-
isAnimating: false,
|
|
2019
|
-
children: msg.content
|
|
2020
|
-
}
|
|
2021
|
-
) }) }, i)),
|
|
2022
|
-
streamingText && /* @__PURE__ */ jsx3("div", { className: "llm-chat-bubble llm-chat-bubble--assistant", children: /* @__PURE__ */ jsx3("div", { className: "llm-chat-assistant-content", children: /* @__PURE__ */ jsx3(
|
|
2023
|
-
Streamdown,
|
|
1388
|
+
error && /* @__PURE__ */ jsxs3("div", { className: "flex items-center justify-between mx-5 mt-4 p-3 bg-red-50 dark:bg-red-950/30 border border-red-200 dark:border-red-900/50 rounded-xl", children: [
|
|
1389
|
+
/* @__PURE__ */ jsx3("span", { className: "text-sm text-red-700 dark:text-red-400 font-medium", children: error.message }),
|
|
1390
|
+
/* @__PURE__ */ jsxs3(
|
|
1391
|
+
"button",
|
|
2024
1392
|
{
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
1393
|
+
className: "flex items-center gap-1.5 px-3 py-1.5 bg-white dark:bg-black border border-red-200 dark:border-red-900 shadow-sm rounded-lg text-xs font-semibold text-red-700 dark:text-red-400 hover:bg-red-50 dark:hover:bg-red-950/50 transition-colors",
|
|
1394
|
+
onClick: reload,
|
|
1395
|
+
children: [
|
|
1396
|
+
/* @__PURE__ */ jsx3(RotateCcw, { className: "w-3.5 h-3.5" }),
|
|
1397
|
+
" Retry"
|
|
1398
|
+
]
|
|
2029
1399
|
}
|
|
2030
|
-
)
|
|
2031
|
-
|
|
1400
|
+
)
|
|
1401
|
+
] }),
|
|
1402
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex-1 overflow-y-auto p-5 flex flex-col gap-6 scrollbar-thin scrollbar-thumb-zinc-200 dark:scrollbar-thumb-zinc-800", children: [
|
|
1403
|
+
!isLoading && messages.length === 0 && !error && /* @__PURE__ */ jsxs3("div", { className: "flex-1 flex flex-col items-center justify-center text-center opacity-80 mt-12 mb-8 transition-opacity hover:opacity-100", children: [
|
|
1404
|
+
/* @__PURE__ */ jsx3("div", { className: "w-16 h-16 bg-gradient-to-tr from-blue-500 to-cyan-400 rounded-2xl shadow-xl shadow-blue-500/20 mb-6 flex items-center justify-center transform rotate-3", children: /* @__PURE__ */ jsx3("svg", { width: "28", height: "28", viewBox: "0 0 24 24", fill: "none", stroke: "white", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx3("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" }) }) }),
|
|
1405
|
+
/* @__PURE__ */ jsx3("h3", { className: "text-2xl font-bold tracking-tight text-zinc-900 dark:text-zinc-100 mb-2", children: welcomeMessage }),
|
|
1406
|
+
/* @__PURE__ */ jsx3("p", { className: "text-zinc-500 dark:text-zinc-400 max-w-sm", children: "Use Markdown, paste images (Ctrl+V), create Mermaid diagrams, and write math equations safely." })
|
|
1407
|
+
] }),
|
|
1408
|
+
messages.map((msg, i) => /* @__PURE__ */ jsx3("div", { className: cn("flex flex-col max-w-[85%]", msg.role === "user" ? "self-end" : "self-start w-full"), children: msg.role === "user" ? /* @__PURE__ */ jsxs3("div", { className: "bg-zinc-100 dark:bg-zinc-800 text-zinc-900 dark:text-zinc-100 px-5 py-3.5 rounded-[24px] rounded-br-[8px] sm:px-6 shadow-sm border border-zinc-200 dark:border-zinc-700/50", children: [
|
|
1409
|
+
msg.images && msg.images.length > 0 && /* @__PURE__ */ jsx3("div", { className: "flex flex-wrap gap-2 mb-3 mt-1", children: msg.images.map((img) => /* @__PURE__ */ jsx3("img", { src: img.dataUrl, className: "w-24 h-24 object-cover rounded-xl border border-zinc-200 dark:border-zinc-700 shadow-sm", alt: "attachment" }, img.id)) }),
|
|
1410
|
+
/* @__PURE__ */ jsx3("div", { className: "prose prose-sm dark:prose-invert max-w-none", children: /* @__PURE__ */ jsx3(Streamdown, { plugins: { code, mermaid, math }, components: markdownComponents, animated: true, isAnimating: false, children: msg.content }) })
|
|
1411
|
+
] }) : /* @__PURE__ */ jsx3("div", { className: "prose prose-sm dark:prose-invert max-w-none px-2 w-full min-w-0", children: /* @__PURE__ */ jsx3(Streamdown, { plugins: { code, mermaid, math }, components: markdownComponents, animated: true, isAnimating: false, children: msg.content }) }) }, i)),
|
|
1412
|
+
streamingText && /* @__PURE__ */ jsx3("div", { className: "flex flex-col self-start w-full max-w-[85%]", children: /* @__PURE__ */ jsx3("div", { className: "prose prose-sm dark:prose-invert max-w-none px-2 w-full min-w-0", children: /* @__PURE__ */ jsx3(Streamdown, { plugins: { code, mermaid, math }, components: markdownComponents, animated: true, isAnimating: isGenerating, children: streamingText }) }) }),
|
|
1413
|
+
/* @__PURE__ */ jsx3("div", { ref: messagesEndRef, className: "h-4" })
|
|
2032
1414
|
] }),
|
|
2033
|
-
/* @__PURE__ */ jsx3("div", { className: "
|
|
1415
|
+
/* @__PURE__ */ jsx3("div", { className: "p-4 bg-white/80 dark:bg-zinc-950/80 backdrop-blur-xl border-t border-zinc-100 dark:border-zinc-800/80", children: /* @__PURE__ */ jsx3(
|
|
2034
1416
|
ChatInput,
|
|
2035
1417
|
{
|
|
2036
1418
|
value: input,
|
|
@@ -2040,7 +1422,6 @@ function Chat({
|
|
|
2040
1422
|
disabled: !isReady && !isLoading,
|
|
2041
1423
|
isGenerating,
|
|
2042
1424
|
placeholder: isLoading ? "Model is loading..." : placeholder,
|
|
2043
|
-
theme,
|
|
2044
1425
|
actions: inputActions,
|
|
2045
1426
|
images,
|
|
2046
1427
|
onImageAdd: (img) => setImages((prev) => [...prev, img]),
|