@blank-utils/llm 0.4.11 → 0.4.13
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.
|
@@ -915,6 +915,28 @@ function ChatInput({
|
|
|
915
915
|
const textareaRef = useRef2(null);
|
|
916
916
|
const fileInputRef = useRef2(null);
|
|
917
917
|
const [isDragging, setIsDragging] = useState2(false);
|
|
918
|
+
const captionerRef = useRef2(null);
|
|
919
|
+
useEffect2(() => {
|
|
920
|
+
let mounted = true;
|
|
921
|
+
const initCaptioner = async () => {
|
|
922
|
+
try {
|
|
923
|
+
const { pipeline: pipeline2, env } = await import("@huggingface/transformers");
|
|
924
|
+
env.allowLocalModels = false;
|
|
925
|
+
env.useBrowserCache = true;
|
|
926
|
+
const captioner = await pipeline2("image-to-text", "Xenova/vit-gpt2-image-captioning", {
|
|
927
|
+
device: "wasm",
|
|
928
|
+
dtype: "q4"
|
|
929
|
+
});
|
|
930
|
+
if (mounted) captionerRef.current = captioner;
|
|
931
|
+
} catch (err) {
|
|
932
|
+
console.warn("Failed to initialize background captioner:", err);
|
|
933
|
+
}
|
|
934
|
+
};
|
|
935
|
+
initCaptioner();
|
|
936
|
+
return () => {
|
|
937
|
+
mounted = false;
|
|
938
|
+
};
|
|
939
|
+
}, []);
|
|
918
940
|
useEffect2(() => {
|
|
919
941
|
const textarea = textareaRef.current;
|
|
920
942
|
if (!textarea) return;
|
|
@@ -1007,12 +1029,45 @@ ${newText}` : newText);
|
|
|
1007
1029
|
reader2.readAsArrayBuffer(file);
|
|
1008
1030
|
return;
|
|
1009
1031
|
}
|
|
1032
|
+
if (file.type === "image/svg+xml" || file.name.toLowerCase().endsWith(".svg")) {
|
|
1033
|
+
const reader2 = new FileReader();
|
|
1034
|
+
reader2.onload = (e) => {
|
|
1035
|
+
const text = e.target?.result;
|
|
1036
|
+
if (text) {
|
|
1037
|
+
const id = Math.random().toString(36).substring(7);
|
|
1038
|
+
const dataUrl = `data:image/svg+xml;utf8,${encodeURIComponent(text)}`;
|
|
1039
|
+
onImageAdd?.({
|
|
1040
|
+
id,
|
|
1041
|
+
dataUrl,
|
|
1042
|
+
file,
|
|
1043
|
+
name: file.name,
|
|
1044
|
+
extractedText: text
|
|
1045
|
+
});
|
|
1046
|
+
}
|
|
1047
|
+
};
|
|
1048
|
+
reader2.readAsText(file);
|
|
1049
|
+
return;
|
|
1050
|
+
}
|
|
1010
1051
|
if (!file.type.startsWith("image/")) return;
|
|
1011
1052
|
const reader = new FileReader();
|
|
1012
|
-
reader.onload = (e) => {
|
|
1053
|
+
reader.onload = async (e) => {
|
|
1013
1054
|
if (e.target?.result && typeof e.target.result === "string") {
|
|
1014
1055
|
const id = Math.random().toString(36).substring(7);
|
|
1015
|
-
|
|
1056
|
+
const dataUrl = e.target.result;
|
|
1057
|
+
let extractedText;
|
|
1058
|
+
if (captionerRef.current) {
|
|
1059
|
+
try {
|
|
1060
|
+
const out = await captionerRef.current(dataUrl);
|
|
1061
|
+
if (Array.isArray(out) && out[0] && out[0].generated_text) {
|
|
1062
|
+
extractedText = out[0].generated_text;
|
|
1063
|
+
} else if (!Array.isArray(out) && out.generated_text) {
|
|
1064
|
+
extractedText = out.generated_text;
|
|
1065
|
+
}
|
|
1066
|
+
} catch (err) {
|
|
1067
|
+
console.warn("Background captioning failed for image:", err);
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
onImageAdd?.({ id, dataUrl, file, name: file.name, extractedText });
|
|
1016
1071
|
}
|
|
1017
1072
|
};
|
|
1018
1073
|
reader.readAsDataURL(file);
|
|
@@ -1432,7 +1487,17 @@ ${systemPrompt}` : systemPrompt;
|
|
|
1432
1487
|
let finalText = text;
|
|
1433
1488
|
for (const img of currentImages) {
|
|
1434
1489
|
if (img.extractedText) {
|
|
1435
|
-
|
|
1490
|
+
let prefix = "";
|
|
1491
|
+
if (img.name.toLowerCase().endsWith(".svg")) {
|
|
1492
|
+
prefix = `\u{1F4C4} SVG Source Code (${img.name}):
|
|
1493
|
+
`;
|
|
1494
|
+
} else if (!isVisionModel2(modelId || "")) {
|
|
1495
|
+
prefix = `\u{1F5BC}\uFE0F Image Auto-Caption (${img.name}):
|
|
1496
|
+
`;
|
|
1497
|
+
}
|
|
1498
|
+
if (prefix || img.name.toLowerCase().endsWith(".pdf")) {
|
|
1499
|
+
finalText += (finalText ? "\n\n" : "") + `${prefix}${img.extractedText}`;
|
|
1500
|
+
}
|
|
1436
1501
|
}
|
|
1437
1502
|
}
|
|
1438
1503
|
setInput("");
|
|
@@ -1541,7 +1606,7 @@ ${systemPrompt}` : systemPrompt;
|
|
|
1541
1606
|
mermaid: mermaidOptions,
|
|
1542
1607
|
controls: streamdownControls,
|
|
1543
1608
|
parseMarkdownIntoBlocksFn: sanitizeMarkdownLanguageBlocks,
|
|
1544
|
-
children: msg.content
|
|
1609
|
+
children: msg.content.includes("\u{1F4C4} PDF:") ? (msg.content.split("\u{1F4C4} PDF:")[0] || "").trim() : msg.content
|
|
1545
1610
|
}
|
|
1546
1611
|
) })
|
|
1547
1612
|
] }) : /* @__PURE__ */ jsxs3("div", { className: "prose prose-base dark:prose-invert max-w-none py-2 w-full min-w-0 font-mono bg-transparent mt-2 !text-current", children: [
|
package/dist/index.js
CHANGED
package/dist/react/index.js
CHANGED
package/package.json
CHANGED