Repository navigation
v5.3.13
v5.3.13 — 2026-10-21
主要改进
-
修复点「打开浏览器」闪退:浏览器标签栏在只剩一个标签时会补一份互补占位,它的权重在稳态下是
1f - 1f == 0f;而 Compose 的Modifier.weight对小于等于 0 的权重直接抛异常(这个检查发生在组合期,不是测量期),于是点开浏览器的瞬间标签栏首帧组合就抛异常、应用当场闪退,浏览器页面一个像素都画不出来。现在标签本体与互补占位的权重都夹进 (0, 1],两者之和仍为 1f,行尾「+」不跳位;并新增单元测试钉死「权重恒为正」这个不变量。 -
浏览器初始化失败不再拖垮应用:WebView / 渲染器初始化失败改由统一兜底捕获并展示失败页,而不是让异常逃出去崩掉应用;失败时同步归还「用户接管」所有权,避免
browser_use工具一直卡在USER_CONTROL_ACTIVE、用户再也打不开浏览器。 -
撤掉 WebView 的强制硬件层:该绕法属于已经下线的 ModalBottomSheet 独立二级窗口时代(用于绕开部分 OEM GPU 的空白渲染);浏览器改为主窗口全屏页后前提已消失,回到 Android 默认渲染路径。
-
媒体语义索引自动更新:新增「启动后自动更新」与「定时自动更新」两个独立开关,可只开其一或同时开启。自动更新固定走低耗后台档,不跟随用户手选的索引档位;模型未下载 / 索引进行中 / 防抖窗口内都静默跳过。定时走 AlarmManager 周期闹钟(非精确闹钟),闹钟重启后由启动流程重排兜底,开机广播再补一次。
-
媒体检索页批量操作与阈值:检索页补多选(全选 / 反选 / 退出多选)、批量移出索引与批量删除文件,并新增相似度阈值滑杆。
-
缩短发送到模型首包的本地等待:发送前持久化只重写当前会话内容,并与 overhead 估算并行;Runtime 历史解码移出主线程,补上停止与解码的竞态保护;首轮复用已构建的提示词与工具,工具 token 数按轮缓存;MCP 过期缓存不再阻塞本轮请求,首次发现并行执行;skill 索引复用共享缓存,纯文本历史跳过媒体 hydration。
-
新增 MCP 自配置与本地技能安装工具:
eta_configure_mcp让模型自行配置 MCP 服务器,skills_install_local支持从手机目录安装技能。 -
界面细节修正:回收站主列表补上水平内边距,与设置页保持一致。
-
文档:README 展示名改为 EtaExpressive,补致谢、分支变更记录与链接,移除 QQ 群与 Telegram 引用。
Improvements
-
fix: Tapping "Open Browser" no longer crashes the app. The browser tab bar adds a complementary spacer when only one tab is left, and its weight evaluated to
1f - 1f == 0fin the steady state; Compose rejects any weight <= 0 with an exception raised during composition rather than measurement, so the tab bar's very first frame killed the app before the browser page drew a pixel. Both the chip weight and the spacer weight are now clamped into (0, 1] while still summing to 1f, so the trailing "+" keeps its position, and a unit test pins the "weight is always positive" invariant. -
fix: Browser initialization failures are now caught and rendered as a failure page instead of killing the app, and a failed acquisition hands browser ownership back so the
browser_usetool no longer stays wedged onUSER_CONTROL_ACTIVEand the browser can be reopened. -
refactor: The forced hardware layer on the WebView was dropped. That workaround belonged to the retired ModalBottomSheet secondary window, where it dodged blank rendering on some OEM GPUs; with the browser now a full-screen page in the main window its premise is gone, so the default Android rendering path is used.
-
feat: Media semantic indexing gains automatic updates, with independent "update on launch" and "scheduled update" switches that can be enabled separately or together. Automatic updates always run at the low-power background level, ignore the manually selected index mode, and are skipped when the embedding model is missing, an index run is in flight, or the debounce window has not elapsed. Scheduling uses a non-exact AlarmManager alarm; a launch-time reschedule covers alarms lost across reboots, and the boot broadcast adds one more safety net.
-
feat: The media search page gains multi-select (select all / deselect all / exit), bulk removal from the index and bulk file deletion, plus a similarity-threshold slider.
-
perf: Shorter local wait before the first token reaches the model: persistence before sending rewrites only the current conversation and runs in parallel with overhead estimation; Runtime history decoding moves off the main thread with stop/decode race protection; the first turn reuses the already-built prompt and tools, with tool token counts cached per turn; expired MCP caches no longer block the request and first-time discovery runs in parallel; skill indexes reuse a shared cache and plain-text history skips media hydration.
-
feat: New
eta_configure_mcplets the model configure MCP servers itself, andskills_install_localinstalls skills from directories on the phone. -
style: The trash bin list gained horizontal padding to match the settings pages.
-
docs: The README display name is now EtaExpressive, with acknowledgements, a fork changelog and refreshed links; QQ group and Telegram references were removed.