v0.32.0

arkohut/pensievev0.32.0May 7, 2026by github-actions[bot]

AI Summary

Migrates frontend from Svelte to React and introduces a structured VLM extraction plugin.

Key Highlights

  • Frontend rewritten from Svelte to React (Vite + TypeScript)
  • Structured VLM extraction plugin for per-screen metadata
  • Worklog v2 format with UTC timestamps

Breaking Changes

  • Frontend framework changed from Svelte to React

New Features

  • React + Vite + TypeScript stack migration
  • Opt-in structured VLM plugin with JSON storage
  • Thumbnail shortcut endpoint
  • Worklog v2 format with UTC timestamps
  • VLM max_tokens default raised to 4096

Full Release Notes

## Features

- Frontend rewritten from Svelte to React by @arkohut
  - Migrated the entire web UI to a Vite + React + TypeScript stack with TanStack Router/Query, Tailwind, and shadcn/ui primitives
  - Reached feature parity with the previous Svelte UI: URL-driven search, library/time/facet filters, entity detail with context navigation, config page, image grid with figure modal
  - Added theme toggle with full dark-mode adaptation, sticky compact header that fades on scroll, and bilingual (en/zh) i18n via react-i18next
  - Smaller bundles via vendor splitting (react / tanstack / ui)

- Structured VLM extraction plugin (Layer 1) by @arkohut
  - New opt-in `builtin_structured_vlm` plugin that asks a VLM to emit JSON-structured per-screen metadata (primary app, task identity, etc.) using a versioned prompt
  - Stores results under a versioned key `structured_vlm_<promptver>_<model>` so prompt or model changes write to a new key without overwriting old data
  - Categorized failure logs (image_load / http_4xx / http_5xx / network / empty / json_parse / schema) and automatic retry on transient (5xx + network) errors
  - Filters Claude Code system-message pollution from task-identity extraction so strings like "[Request interrupted by user]" don't leak into structured output

- Worklog v2 with UTC timestamps by @arkohut
  - New worklog format stores UTC timestamps; v1 reader retained for backwards compatibility

- Thumbnail shortcut endpoint by @arkohut
  - Adds a direct path for fetching an entity's thumbnail without going through the full entity API

## Bug Fixes

- Watch background processing no longer dies after a VLM failure by @arkohut
  - Fixed a death-loop where a single VLM error stopped the watch worker for the rest of the session, leaving newly captured screenshots unprocessed; also fixes the related case where overnight background processing would silently stop

- Search index refresh and result ordering by @Delon Saks
  - Index is correctly refreshed after entity updates, and search results return in the expected ranked order

- Datetime now displays in the user's current zone by @arkohut
  - Times in the UI follow the local zone instead of a fixed offset; DST transitions are handled by computing the offset at the timestamp rather than caching it

- `get_entity_by_filepath` is now scoped by `library_id` by @arkohut
  - Prevents cross-library collisions when two libraries contain files with the same path

- VLM `max_tokens` default raised 2048 → 4096 by @arkohut
  - 2048 was too tight for screens with long URLs (e.g. Google SERP `gs_lcrp` parameters) — repetitive token loops would truncate JSON output before completion

**Full Changelog**: https://github.com/arkohut/memos/compare/v0.31.0...v0.32.0

---

## 新特性

- 前端从 Svelte 迁移至 React by @arkohut
  - 完整重写 Web UI,技术栈切换为 Vite + React + TypeScript,路由/查询使用 TanStack Router/Query,UI 基于 Tailwind + shadcn/ui
  - 与原 Svelte 版本达到功能对等:URL 驱动的搜索、library/time/facet 过滤器、带上下文导航的 entity 详情页、config 页面、带 figure 弹窗的图片网格
  - 新增主题切换与完整暗色模式适配、滚动时折叠的紧凑 header、基于 react-i18next 的中英双语
  - 通过 vendor 拆分(react / tanstack / ui)减小 bundle 体积

- 结构化 VLM 抽取插件(Layer 1)by @arkohut
  - 新增 opt-in 的 `builtin_structured_vlm` 插件,调用 VLM 用版本化 prompt 对每张截图输出结构化 JSON 元数据(primary app、task identity 等)
  - 结果存储 key 为版本化的 `structured_vlm_<promptver>_<model>`,prompt 版本或模型变更会写入新 key,不覆盖旧数据
  - 失败日志按 image_load / http_4xx / http_5xx / network / empty / json_parse / schema 分类,对 transient 错误(5xx + 网络)自动重试
  - 过滤 task identity 抽取中 Claude Code 的系统消息污染,避免 "[Request interrupted by user]" 之类字符串进入结构化输出

- Worklog v2(UTC 时间戳)by @arkohut
  - Worklog 新格式使用 UTC 时间戳,保留 v1 读取器以向后兼容

- 缩略图快捷接口 by @arkohut
  - 新增直接获取 entity 缩略图的端点,无需走完整的 entity API

## Bug 修复

- 修复 watch 后台进程在 VLM 失败后停摆的问题 by @arkohut
  - 修复了单次 VLM 错误就让 watch worker 余下整个会话不再处理新截图的死循环;同时修复夜间后台处理会静默停止的相关问题

- 搜索索引刷新与结果排序 by @Delon Saks
  - entity 更新后索引正确刷新,搜索结果按期望的排名顺序返回

- 时间显示改为当前时区 by @arkohut
  - UI 中的时间按本地时区显示而非固定偏移;DST 切换通过基于时间戳计算偏移来正确处理

- `get_entity_by_filepath` 按 `library_id` 隔离 by @arkohut
  - 避免两个 library 中存在同名路径文件时的跨库冲突

- VLM `max_tokens` 默认值 2048 → 4096 by @arkohut
  - 2048 在含长 URL(如 Google SERP `gs_lcrp` 参数)的截图上过紧,会触发重复 token 循环把 JSON 输出截断在结束前

**完整更新日志**: https://github.com/arkohut/memos/compare/v0.31.0...v0.32.0