feat: 识图提速(模型常驻/精简模板/磁盘缓存)+ WebUI 上传压缩 + 缓存清理脚本

- vision.ts: keep_alive:-1 常驻显存(治冷加载 7.7GB);转录缓存持久化
  data/agent/vision-cache.json(重启后历史图秒回);hook 转录用精简模板
- ChatInput/image-attachments: 上传 JPEG 长边>1600px 自动压缩 q0.85
- scripts/cleanup-cache.mjs: npm/opengrep 缓存、过期会话、旧图瘦身清理
- README 双语同步
This commit is contained in:
luckyyzh
2026-08-03 06:33:43 +08:00
parent e79485bf4c
commit ccb038988e
5 changed files with 425 additions and 23 deletions
+16 -14
View File
@@ -6,6 +6,7 @@ import { clearDraft, getDraft, setDraft, type ChatDraftImage } from "@/lib/draft
import {
MAX_ATTACHED_IMAGE_BYTES,
MAX_ATTACHED_IMAGES,
compressImageFile,
isBase64ImageWithinLimits,
} from "@/lib/image-attachments";
import {
@@ -390,20 +391,21 @@ export const ChatInput = forwardRef<ChatInputHandle, Props>(function ChatInput({
pendingImageCountRef.current += imageFiles.length;
try {
const newImages = await Promise.all(
imageFiles.map(
(file) =>
new Promise<AttachedImage>((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => {
const result = reader.result as string;
// result is "data:<mime>;base64,<data>"
const base64 = result.split(",")[1];
resolve({ data: base64, mimeType: file.type, previewUrl: URL.createObjectURL(file) });
};
reader.onerror = reject;
reader.readAsDataURL(file);
})
)
imageFiles.map(async (file) => {
// 大 JPEG 先压缩(长边 1600/q0.85),会话不再内嵌数 MB base64,加载/传输/转录都更快
const compressed = await compressImageFile(file);
const base64 = await new Promise<string>((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve((reader.result as string).split(",")[1]);
reader.onerror = reject;
reader.readAsDataURL(compressed);
});
return {
data: base64,
mimeType: compressed.type,
previewUrl: URL.createObjectURL(compressed),
};
})
);
setAttachedImages((prev) => {
const accepted = newImages.slice(0, Math.max(0, MAX_ATTACHED_IMAGES - prev.length));