@blank-utils/llm 0.5.1 → 0.5.3

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.
@@ -1022,6 +1022,31 @@ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
1022
1022
  function cn(...inputs) {
1023
1023
  return twMerge(clsx(inputs));
1024
1024
  }
1025
+ async function resizeImageForWebLLM(dataUrl) {
1026
+ return new Promise((resolve, reject) => {
1027
+ const img = new Image();
1028
+ img.onload = () => {
1029
+ const TARGET_W = 1344;
1030
+ const TARGET_H = 1008;
1031
+ const canvas = document.createElement("canvas");
1032
+ canvas.width = TARGET_W;
1033
+ canvas.height = TARGET_H;
1034
+ const ctx = canvas.getContext("2d");
1035
+ if (!ctx) return resolve(dataUrl);
1036
+ ctx.fillStyle = "black";
1037
+ ctx.fillRect(0, 0, TARGET_W, TARGET_H);
1038
+ const scale = Math.min(TARGET_W / img.width, TARGET_H / img.height);
1039
+ const w = img.width * scale;
1040
+ const h = img.height * scale;
1041
+ const x = (TARGET_W - w) / 2;
1042
+ const y = (TARGET_H - h) / 2;
1043
+ ctx.drawImage(img, x, y, w, h);
1044
+ resolve(canvas.toDataURL("image/jpeg", 0.9));
1045
+ };
1046
+ img.onerror = () => resolve(dataUrl);
1047
+ img.src = dataUrl;
1048
+ });
1049
+ }
1025
1050
  function sanitizeMarkdownLanguageBlocks(markdown) {
1026
1051
  let cleanMarkdown = markdown;
1027
1052
  cleanMarkdown = cleanMarkdown.replace(/```([a-zA-Z0-9+#-]*)[_|█▋]+[ \t]*(?:\n|$)/gi, "```$1\n");
@@ -1067,7 +1092,8 @@ var DEFAULT_SYSTEM_PROMPT = `You are a helpful AI assistant.
1067
1092
  B -- Yes --> C[Continue]
1068
1093
  B -- No --> D[Error]
1069
1094
  \`\`\`
1070
- - You can use LaTeX math ($$ ... $$).`;
1095
+ - You can use LaTeX math ($$ ... $$).
1096
+ - IF you are provided an uploaded image, your primary task is strictly to analyze the contents of that specific image in natural language. Do not hallucinate that the user desires a Mermaid diagram unless they specifically ask for one.`;
1071
1097
  var ALL_MODELS = { ...WEBLLM_MODELS };
1072
1098
  function isVisionModel(modelId) {
1073
1099
  if (!modelId) return false;
@@ -1212,21 +1238,27 @@ Additional instructions:
1212
1238
  ${systemPrompt}` : systemPrompt;
1213
1239
  apiMessages.push({ role: "system", content: finalSystemPrompt });
1214
1240
  }
1215
- currentMessages.forEach((m) => {
1241
+ for (const m of currentMessages) {
1216
1242
  let content = m.content;
1217
1243
  if (m.role === "user" && m.images && m.images.length > 0 && isVisionModel(modelId || "")) {
1244
+ const processedImages = await Promise.all(
1245
+ m.images.map((img) => resizeImageForWebLLM(img.dataUrl))
1246
+ );
1218
1247
  content = [
1219
1248
  { type: "text", text: m.content },
1220
- ...m.images.map((img) => ({ type: "image_url", image_url: { url: img.dataUrl } }))
1249
+ ...processedImages.map((url) => ({ type: "image_url", image_url: { url } }))
1221
1250
  ];
1222
1251
  }
1223
1252
  apiMessages.push({ role: m.role, content });
1224
- });
1253
+ }
1225
1254
  let finalUserContent = userContent;
1226
1255
  if (attachedImages.length > 0 && isVisionModel(modelId || "")) {
1256
+ const processedImages = await Promise.all(
1257
+ attachedImages.map((img) => resizeImageForWebLLM(img.dataUrl))
1258
+ );
1227
1259
  finalUserContent = [
1228
1260
  { type: "text", text: userContent },
1229
- ...attachedImages.map((img) => ({ type: "image_url", image_url: { url: img.dataUrl } }))
1261
+ ...processedImages.map((url) => ({ type: "image_url", image_url: { url } }))
1230
1262
  ];
1231
1263
  }
1232
1264
  apiMessages.push({ role: "user", content: finalUserContent });
package/dist/index.css CHANGED
@@ -2290,6 +2290,9 @@ video {
2290
2290
  .table-row {
2291
2291
  display: table-row;
2292
2292
  }
2293
+ .contents {
2294
+ display: contents;
2295
+ }
2293
2296
  .list-item {
2294
2297
  display: list-item;
2295
2298
  }
package/dist/index.js CHANGED
@@ -22,7 +22,7 @@ import {
22
22
  useCompletion,
23
23
  useLLM,
24
24
  useStream
25
- } from "./chunk-S375B33F.js";
25
+ } from "./chunk-6EZY4F42.js";
26
26
  export {
27
27
  Chat,
28
28
  ChatInput,
@@ -2290,6 +2290,9 @@ video {
2290
2290
  .table-row {
2291
2291
  display: table-row;
2292
2292
  }
2293
+ .contents {
2294
+ display: contents;
2295
+ }
2293
2296
  .list-item {
2294
2297
  display: list-item;
2295
2298
  }
@@ -9,7 +9,7 @@ import {
9
9
  useCompletion,
10
10
  useLLM,
11
11
  useStream
12
- } from "../chunk-S375B33F.js";
12
+ } from "../chunk-6EZY4F42.js";
13
13
  export {
14
14
  Chat,
15
15
  ChatApp,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blank-utils/llm",
3
- "version": "0.5.1",
3
+ "version": "0.5.3",
4
4
  "description": "Run LLMs directly in your browser with WebGPU acceleration. Supports React hooks and eager background loading.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",