987 Commits
Author SHA1 Message Date
fanlusky 799d6361e5 feat(server): 候选翻译目标语种新增泰语、越南语和意大利语 2026-10-08 17:20:58 +08:00
MSIME(MetaSequoia IME) 53020b2945 Merge pull request #657 from Hush-Jr/fix/ftb-cross-monitor-drag
fix(server): 悬浮工具栏跨屏拖动不再被拉回原显示器
2026-10-08 16:39:54 +08:00
fanlusky d830c75e59 fix(server): 悬浮工具栏跨屏拖动改用建议矩形并统一两后端的放置逻辑
- 拖动中的 WM_DPICHANGED 也采用 lParam 的建议矩形,避免固定左上角改尺寸
  导致 DPI 在分界线两侧来回翻转、窗口脱离光标
- 是否处于拖动改用 GetGUIThreadInfo(GUI_INMOVESIZE) 判定,去掉文件级标志,
  拖动中 HWND 被销毁也不会残留拖动状态
- WebView2 与 D2D 共用 PlaceResizedHost:D2D 的 ApplyAppearance 在拖动中
  也不再夹取;半屏尺寸上限按即将落到的显示器计算
- 尺寸变化的夹取恢复为整块显示器(允许压任务栏),拖动结束的兜底夹取仍用工作区
- WM_EXITSIZEMOVE 先执行挂起的 DPI 重测再夹取,避免松手后跳两次
2026-10-08 16:13:44 +08:00
fanlusky 06fb8f87ba fix(server): 关闭顶字且混输关闭时第五码仍走顶字,避免丢字与两端分叉
混输关闭时码表答得出的完整四码保留四码上限,关掉顶字后第五个字母会被 Server
裁掉,而 raw 预编辑样式的 TSF 已经显示了它,两边缓冲就此分叉。顶字开关改为只在
混输开启时生效(字母并入混输串),混输关闭时仍按顶字上屏首选。

同时修正第四键注释(两个开关作用在不同按键上)、设置页与配置模板的说明文字,
以及 settings_app.cpp 新增行的缩进。
2026-10-08 14:10:36 +08:00
Jia Sui 3d31a40a74 feat(server): 五笔四码自动上屏与顶字各加一个设置开关
「四码唯一时自动上屏」和「第五码将首选上屏」此前都是无条件行为,用户遇到
误上屏没有任何出口。四家主流五笔(搜狗/QQ/百度/微软)都提供这两个开关且
默认开启,这里补上并保持默认开,升级用户零行为变化。

- input.wubi_four_code_auto_commit(默认 true)门控四码唯一自动上屏
- input.wubi_fifth_code_top_commit(默认 true)门控真顶字
- 开关只落在 Server 判定层,引擎完全不知道:WubiInputOptions 不加字段,
  避免测试里大量聚合初始化静默取默认值
- 顶字关闭后第五个字母落回引擎既有四码上限(混输关=裁掉,混输开=并入混输
  串),与搜狗 PC 一致,不补新分支
- 顺带修正 input_key_policy.h 与 event_listener_keys.cpp 中把不存在的开关
  当既成事实引用的注释,以及两个把「无条件」写进名字的用例
2026-10-08 13:24:25 +08:00
Hush-Jr 61f40a6b66 fix(server): 悬浮工具栏跨屏拖动不再被拉回原显示器
不同缩放比例的双屏之间拖动悬浮工具栏时,Windows 会在指针越过屏幕
边界(窗口主体已进入新屏)时发送 WM_DPICHANGED,而捕获到的窗口此时仍
属于旧屏:

- LayoutFloatingToolbar/RelayoutHost 用 MonitorFromWindow + rcMonitor
  把窗口夹回当前显示器,于是刚跨过去就被拉回旧屏左/右缘,永远拖不过去。
- WM_EXITSIZEMOVE 的兜底夹取用 MonitorFromRect(最大交集)选屏,在副屏
  比主屏高的错位布局下也会把窗口拉回原屏。

改为:
- WM_DPICHANGED 期间若处于用户拖动(WM_ENTERSIZEMOVE..WM_EXITSIZEMOVE)
  的模态移动循环内,只改尺寸、绝不动位置;不在拖动中时应用系统 lParam
  建议位置。
- 所有保持位置的夹取(含 D2D presenter)只要求窗口落在各屏工作区的
  并集内,仅在完全离开所有屏幕时才按窗口中心就近收回。
- 夹取目标显示器改用窗口中心判定,避免跨缝窗口被判定为旧屏。
2026-10-08 04:37:11 +08:00
Ehtasham Yasin 6bd2452dc4 Merge branch 'develop' into feat/shuangpin-shift-enter 2026-10-07 08:53:14 +02:00
Jia Sui 9e46ccb427 feat(server): HandleImeKey 分段计时埋点,定位提交超时类吞字卡顿
诊断日志新增 handle-read-packet / handle-engine / handle-selection /
handle-worker-push / handle-async-query / handle-candidates 六类分段
(>=8ms 才输出),用于定位 server 按键处理偶发数百毫秒卡顿——昨晚
request=628 卡 344ms 导致空格排队超 TSF 300ms 提交预算、整会话重置
吞掉 "juede"。纯观测改动,零行为变化;.gitignore 忽略本地测试暂存
目录 .tmp-test/。
2026-10-07 09:00:47 +08:00
Ehtasham-Yasin 0fe601e259 feat(server): submit converted shuangpin with Shift+Enter 2026-10-06 15:09:29 +02:00
Lu Fan(SonnyCalcr) 5d6eaa5bd1 feat(server): 全拼纠错候选的 * 标记可在设置中关闭 (#631)
新增 quanpin.autocorrect_marker 开关,默认开启(显示 *),关闭后纠错得到的候选
不再在末尾附加 * 标记。只影响候选窗显示,不影响上屏文字和词频。

同步出厂模板、工作配置、两个设置宿主的读写映射和设置页「输入」分区的开关,
并在配置持久化测试里覆盖默认值、落盘重读和缺键回退。
2026-10-05 22:04:06 +08:00
Lu Fan(SonnyCalcr) 53ee180ec3 feat(engine): 直接辅助码句中四码可用第二位辅码大写结束 (#630)
直接辅助码的四码在句中原来只能补 / 结束(uiab/),现在也可以把第二位辅码敲成大写(uiaB)。
设置页「直接辅助码句中四码标记」两个勾选框可多选、至少留一个,默认只勾 /。

- 引擎:拼写图新增 Aux2Upper(非缩写)。开着大写标记时大写字母只能当第二位辅码,
  走不通再退回不分大小写的旧规则,第一位辅码敲大写(uiAuiQ)照常可用。/ 的收键受勾选控制。
- 协议:DirectHelpcodeChanged 载荷改为 "0"/"1"/"2"(2 = 开着但 / 不是编码键),
  TSF 据此决定吃不吃 /。
- 配置:新增 helpcode.shuangpin_direct_helpcode_slash / _uppercase,同步写入出厂模板、
  工作配置和两个设置宿主的读写映射。
2026-10-05 20:43:02 +08:00
Lu Fan(SonnyCalcr) 3c79876205 Merge pull request #629 from fanlusky/feat/v-mode
feat: 新增 V 模式,数字转中文与算式计算
2026-10-05 17:51:21 +08:00
fanlusky b986c3496f refactor(server): D2D 候选组页时只读一次翻译开关 2026-10-05 13:02:46 +08:00
fanlusky 70d76ce52a perf(server): 神经重排完成时队列里最多排一个重查任务
每批重排完成都排一个 ApplyRescoredOrder,每个都清整句缓存并重查一遍词格,
两个模型同开时更多,且都排在按键前面。重查本身会读所有模型已算完的结果,
所以排队期间再完成的批次不必各排一个;出队即放行,之后完成的批次还能再排。
2026-10-05 13:02:46 +08:00
Lu Fan(SonnyCalcr) 1da1c1bcd6 fix(engine): 辅助码串上的 Ctrl+方向与 Ctrl+Backspace 按单元编辑 (#627)
双拼串里带句中辅助码(反引号段 / 大写段)或开着直接辅助码时,segment_raw_boundaries
直接返回空,Server 只能退回逐字符移动和删除。

现在按请求带着的辅助码段布局切单元:每个音节和挂在它后面的辅码段各算一个单元,
Ctrl+Backspace 可以只删辅码,Ctrl+方向也能停在音节与辅码之间。布局对不上原串时仍
不给边界、退回逐字符。直接辅助码没解析出辅码时请求原样放行,沿用普通双拼切分。

光标前缀重算与按段编辑共用同一套边界,带辅助码的串也随之按光标前缀出候选。
2026-10-05 04:19:23 +08:00
Lu Fan(SonnyCalcr) b391fd616b feat: T 模式支持输入指定的日期和时间 (#626)
Shift+T 后面除了 rq / sj / xq 唤醒词,还可以直接写数字:

- YYYYMMDD、YYYY/M/D、M/D(年份取今年)出那一天的日期格式,星期按那一天算
- YYYY/M 出年月格式(新增 date:ym_* 五种)
- h:mm、h:mm:ss 出时间格式,写了秒才给带秒的格式
- YYYYMMDDhh[:mm[:ss]] 出日期加时间的格式

指定的日期时间沿用唤醒词的格式 ID,学到的顺序、置顶、固定位置跟着走。

输入形状放在 engine/contracts/date_time_input.h,TSF、Server、引擎共用:
数字、/ 和 : 只在还能接成某种形状时才进输入串,接不上的数字仍是选词键,
/ 和 : 仍是标点,Shift+数字始终选词。小键盘数字同样可以输入。

Refs #531
2026-10-05 03:42:12 +08:00
Lu Fan(SonnyCalcr) ae353d142c feat(server): 语言栏右键菜单新增输入方案二级菜单 (#625)
在托盘语言栏菜单第二项加入「输入方案」,悬停展开全拼/双拼/五笔二级菜单,
当前方案打勾,点击即切换(与设置页走同一条 SetConfiguredInputScheme 路径)。

- D2D:TrayMenuPresenter 用 Popup 实现子菜单,展开时宿主窗口向有空间的一侧加宽,收起时还原
- WebView2:页面通过 inputSchemeSubmenu 请求宿主加宽窗口,再由 PlaceInputSchemeSubmenu 摆放;
  changeInputScheme 切换方案
- 契约:messages.json 新增 changeInputScheme / inputSchemeSubmenu,并重新生成 ui-html/webview2/shared
2026-10-05 02:44:59 +08:00
Lu Fan(SonnyCalcr) 1b74617eed feat(server): make direct and mid-sentence helpcode mutually exclusive (#621)
Turning either one on now turns the other off, in the config setters both
settings hosts go through, so the snapshot pushed back to the settings page
shows the change; the page also flips the other toggle immediately. Turning
one off leaves the other alone. Configs saved before this with both on load
with mid-sentence helpcode treated as off in memory, matching the behaviour
direct helpcode already had, without rewriting the user's file.
2026-10-04 22:04:32 +08:00
Lu Fan(SonnyCalcr) 5208753ce8 feat: 句中辅助码新增大写字母触发方式 (#620)
* feat(engine): add uppercase trigger for shuangpin mid-sentence helpcode

With the uppercase trigger on, an uppercase letter right after a complete
two-key syllable opens a mid-sentence helpcode block by itself, as if the
backtick had been typed before it: ulpbXihfa is ulpb`xihfa, and a following
uppercase letter is still the second code (ulpbXYih is ulpb`xYih). The raw
input keeps the typed letters; the block rules live in
contracts/mid_sentence_helpcode.h so TSF, Server and engine parse alike,
including the semicolon final, which no longer counts uppercase blocks.

The scheme now hands the parsed layout (source index and decorations) to the
request, so selection advance and preedit no longer re-parse the raw input.
Adds the MidSentenceHelpcodeUppercaseChanged worker opcode (31).

* feat(windows): count uppercase helpcode blocks before backtick and semicolon

With MidSentenceHelpcodeUppercaseChanged on, TSF uses the shared block rules
when deciding whether '`' opens a block and whether ';' is the ing final, in
both the synchronous and the deferred key classification.

* feat(server): wire the mid-sentence helpcode uppercase trigger

New helpcode.shuangpin_mid_sentence_helpcode_uppercase (default off) in both
config templates, both settings hosts and the settings page as a third
trigger checkbox. It takes effect only with mid-sentence helpcode on and
direct helpcode off; the Server applies it to the semicolon final rule and
broadcasts MidSentenceHelpcodeUppercaseChanged to TSF.
2026-10-04 21:00:41 +08:00
Lu Fan(SonnyCalcr) 22fb1e2569 Merge pull request #619 from fanlusky/feat/shuangpin-direct-helpcode
feat: 双拼直接辅助码(万象式,无需引导键)
2026-10-04 19:32:10 +08:00
Lu Fan(SonnyCalcr) e46029fe91 Merge pull request #592 from metasequoiaime/feat/quanpin-autocorrect-context-ranking
feat(engine,server): 让输入法靠上下文猜错字
2026-10-04 15:48:38 +08:00
Jia Sui 6b4f8e5398 fix(server): 速度分母加下限避免零散输入日算出离谱速率 (#614)
活跃时间只累加相邻两次上屏之间的间隔,首键之前与末键之后的时间不在其中。零散输入的日子分母可能只剩几秒,按它外推会得到没人打过的速率:本机 20261004 记录 81 个可读字符 / 1.9 秒活跃,页面显示 2503 字/分。

CharsPerMinute 在 active_ms > 0 时改用 max(active_ms, kMinSpeedActiveMs) 作分母。active_ms <= 0 仍返回 0——那是没有测量,不是测量小,不该被下限救活。

kMinSpeedActiveMs 与 kFastestSpeedMinActiveMs 保持为两个常量、两个理由:下限管数值,排名门槛管资格。没有门槛的话,被下限压到「每分钟字数」量级的爆发日仍会拿下最快日。

前端 speedOf 是同一公式的手写副本,一并改,并把运算顺序对齐 C++ 的 chars / (ms / 60000),否则两侧会差一个 ulp。落库口径不变,无需迁移历史数据。
2026-10-04 14:24:53 +08:00
Jia Sui 0952333f94 test(server): 更正三处与生成式空间不符的用例名 2026-10-04 08:16:18 +08:00
Jia Sui 7e1ae10da2 docs(engine): 更正生成式空间可达性论断,删除对用户不可见的错误结论 2026-10-04 05:21:45 +08:00
Jia Sui 3a0d95e143 test(engine,server): 对齐生成式纠错空间的类型位可达性断言 2026-10-04 04:25:25 +08:00
Lu Fan(SonnyCalcr) 1b462a9e2a fix(server): keep default AI endpoint and model out of provider slots (#610) 2026-10-04 00:02:50 +08:00
HowGeGe 5e77dffabf fix(server): preserve endpoint and model per provider (#605) 2026-10-03 23:18:41 +08:00
HowGeGe d9b8d82b8c fix(installer): preserve TSF diagnostics across template upgrades (#606) 2026-10-03 23:14:16 +08:00
fanlusky af34e23d07 feat(server): 语法模型支持浏览器下载与本地导入,新增网络代理设置
应用内下载 octagram 模型较慢时,设置页每个模型行提供「浏览器下载」直链,
下载后用「导入」选中 .gram 文件:后台复制进模型目录,与应用内下载走同一套
格式校验与原子落位,原文件不动。导入与下载共用单槽。

帮助页新增网络代理(跟随系统 / 直连 / 自定义 HTTP 代理),新增 [network]
配置段。云输入、模型下载、AI 联想、翻译、语音识别与润色、凭证测试统一经
NetworkProxy 选择代理,改动即时生效。WinHTTP 的「跟随系统」由 DEFAULT_PROXY
改为 AUTOMATIC_PROXY,真正读取用户的系统代理与 PAC。

契约新增 collocationModelImport 消息;旧设置宿主补上 openExternalUrl。
2026-10-03 22:49:07 +08:00
fanlusky 05d202ce5b feat(server): 日期时间候选支持调频、置顶、固定位置,并加「📅日期」格式入口
日期时间候选(Shift+T 模式与 rq / sj / xq 混输)按格式 ID 调频:日期文本每天都变,
所以给每种格式一个稳定 ID,学到的顺序记在用户库新表 date_time_format_order,固定位置
借用 fixed_candidate_positions。T 模式与混输共用一份顺序,混输取排第一的格式。右键
置顶、固定位置、取消固定对日期候选生效。

混输时在第三位放一个「📅日期」入口(时间为「🕒时间」),选中后不上屏,候选框整页换成
全部格式,与 Ctrl+Enter 译文页同一套子页机制。新增开关 utility.date_time_menu,默认
打开,出厂模板、工作配置、两个设置宿主与设置页同步更新。UILess 宿主不显示入口。
2026-10-03 20:44:22 +08:00
Lu Fan(SonnyCalcr) f4490bc8f2 Merge pull request #597 from fanlusky/revert/pr-576
revert(server): 撤回 #576 的 skin.toml 统一规则
2026-10-03 18:38:08 +08:00
fanlusky bc62de0c60 fix(server): WebView2 不可用提示按失败原因和实际受影响的窗口区分
重试预算在任一宿主建出 controller 后清零,因此其余宿主已正常时,单个宿主连续失败
也会耗尽预算,原提示却说三个窗口都不会出现、并要求重装 Runtime。现在只列出仍没有
controller 的窗口;environment 创建失败才提示安装或修复 Runtime,controller 失败
(如 uiAccess 下的 E_INVALIDARG)改为提示右键托盘图标重试。一次性提示在取得进展后
重新武装,同一会话恢复后再失败仍会提示。
2026-10-03 18:24:55 +08:00
fanlusky 1ae1f1eddb revert(server): 撤回 #576 的 skin.toml 统一规则
This reverts commit c5b0c24c48.

#576 未经评审即被合入 develop,先撤回,待评审意见处理后重新提交。
2026-10-03 18:11:23 +08:00
Zzz210s 9d0dec0368 fix(server): WebView2 启动失败时记下原因并提示用户
三个小窗启动即 DWM cloaked,只有 WebView2 控制器画完首帧才揭开,所以初始化
一直失败时用户看到的是"引擎没反应":没有候选窗、没有报错。原先 12 次退避重试
用完直接 return,失败 HRESULT 也一条都不写(本文件的 DIAG_LOGF 被编译成空),
现有的 MessageBox 又挂在 parked 到屏幕外的 cloak 宿主上。现在失败会写进统一
诊断日志,重试耗尽时弹一次无属主的可见提示。
2026-10-03 18:03:05 +08:00
小莫 c5b0c24c48 feat(server): read skin.toml with the rules every platform shares (#576)
* feat(server): 外部皮肤接受跨平台客户端的 base 与装饰规则,社区皮肤可在 Windows 加载

社区皮肤库按跨平台客户端(msime 的 client-core)的规则校验,base 写的是全局主题 system / shuishan / light / paper / night / ink,而 Windows 只认六个内置皮肤 ID,所以社区里绝大多数皮肤在 Windows 上整包加载失败。

- base 为 system 时按 fluent 加载,配色原样保留。
- base 为五个内置全局主题时按 fluent 加载,并照 theme::resolve 换算配色:主题固定明暗,只取包里那一种明暗的配色,深浅两种模式都画它;读不懂的颜色当作没写,没写的按主题补齐,右键菜单和悬浮工具栏一并补上。包没声明那一种明暗时不生效,与客户端一致。
- 装饰规则与客户端对齐:空表或两个尺寸都为 0 表示无装饰;有尺寸而无 image 时用图片类型的 preview,都没有就不画。
- 复制 msime-cloud 的 client_dialect.json 作测试夹具,新测试要求客户端接受的每个包在 Windows 上都能加载;scripts/sync-client-dialect.py 负责同步,每周的 Skin client dialect 工作流比对上游。

* feat(server): 皮肤清单与跨平台客户端统一为同一套规则

同一个皮肤包现在在每个平台上要么都能加载,要么都被拒绝。规则以 msime client-core 的 load() 为准,共享用例表 client_dialect.json 改为从 msime 同步,测试要求每一条用例的接受与否都与客户端一致。

- 保留 ID 加上全局主题 ID(system、shuishan、light、paper、night、ink、custom)。
- 收紧到客户端的规则:skin.toml 最大 64 KiB;schema_version 必须是整数 1;author、description 写了不能为空;preview 写了必须指向包内已有的文件;toolbar_stylesheet 写了必须是包根目录里已有的 .css 文件;[license] 的各键有长度限制;[candidate] 与其中的 dark、light 必须是表;装饰图与背景图须是图片扩展名。
- 仓库自带的 7 个皮肤、示例皮肤和 msime-skins 里的 4 个皮肤在新规则下都能加载。
2026-10-03 17:39:49 +09:00
Jia Sui 2557ee4a63 docs: 修正 AGENTS.md 与注释中与代码不符的五处描述
spec 校对时逐条核对「文件:行号」锚点发现,五处文档描述与代码现状不符:

- windows/AGENTS.md:格式化遵循的是本目录 .clang-format,仓库没有根目录 .clang-format
- 根 AGENTS.md:engine/... 前缀 include 只对 server/ 成立,windows/ 无仓库根,走相对路径
- scripts/format.sh:注释声称 CI 会跑 generate.py --check,实际没有任何 CI 作业调用
- server/AGENTS.md:测试源文件数与三处行号锚点过期
- server/CMakeLists.txt:注释里的 "eleven add_test()" 实际是 24 个,删去具体数字

纯文档与注释改动,无行为变化。
2026-10-03 08:29:50 +08:00
luojiyin b0b672ccf1 fix(ai): 限制建议缓存大小 2026-10-03 00:56:30 +08:00
Lu Fan(SonnyCalcr) f7a78183ee Merge pull request #584 from luojiyin1987/fix/ai-suggestion-cache-key
fix(ai): include semantic request inputs in suggestion cache key
2026-10-03 00:41:49 +08:00
fanlusky 5e100de92f fix(server): 建议缓存键容忍非法 UTF-8,避免工作线程抛出终止进程 2026-10-03 00:29:19 +08:00
fanlusky 233ac9ef33 feat(engine,server,windows,ui-html,installer): 句中辅助码触发键可多选,新增分号
设置页「句中辅助码触发键」可勾选反引号和分号,至少保留一个。

- 分号只在 AcceptsMarkerAt 成立(这一节是偶数键)时才当触发键;微软/搜狗/紫光双拼的
  ing 韵母只跟在奇数键之后,两者不抢同一个位置,判断时分号先让给 ing 韵母
- 无论按哪个键,TSF 按键缓冲、Server raw 与引擎输入串里都记成反引号,引擎解析不变
- 新配置项 helpcode.shuangpin_mid_sentence_helpcode_backtick / _semicolon 同步写入出厂
  模板、工作配置与两个设置宿主
- opcode 28 保持「反引号是否触发」、载荷单个 "0"/"1"(TSF 会丢弃更长的帧);分号走新增
  的 opcode 29,旧 DLL 忽略它
2026-10-02 23:55:46 +08:00
Jia Sui f73a988cd5 fix(server): 按配置段拆分设置宿主分发链,修复 C1061 构建失败
configUpdate 的分发是一条 109 分支的 else-if 链,MSVC 以 error C1061
(编译器限制:块嵌套太深)拒绝编译,MetasequoiaImeServer Release 构建失败。
嵌套上限约 127 层,develop 上原本 105 个分支已贴近上限,本分支 69092b9d
新增 association.sentence_collocation_additive / _rerank 两个键后就顶穿了。

按 config.toml 的段名拆成 10 个 Apply<段名>Subkey,沿用文件内既有的
ApplySmartPunctuationSubkey 模式;各段名互不重叠,调用点依次调用全部函数,
至多一个命中。拆后每段最长 27 个分支。

拆链不是纯文本搬运:段内谓词重叠的分支会双跑。两处已恢复 else-if 并就地注明原因——
general 的 4 个 floating_toolbar_* 键与 custom_translation.enabled 各自都被同段末的
rfind 前缀分支覆盖,拆成并列 if 后会先正确写入一次、再被前缀分支用 value_to<bool>
读同一个值错误写入一次。tencent_tmt 的 target_language 判断在 rfind 分支体内部,不受影响。

验证:clang-format 18.1.8 零违规;Release 构建产出 Server 与 Settings 两个 exe;
按 else-if 链编号复验跨链重叠为 0、109 个分支不变;ctest 在同一隔离环境下与改动前
基线一致(2 个既有失败,均本地复现、CI 为绿,与本改动无关)。
2026-10-02 23:05:51 +08:00
luojiyin add578fdeb fix(ai): 修正建议缓存键语义输入 2026-10-02 21:30:30 +08:00
Jia Sui 18d6b4754a fix(server,ui-html,installer): octagram 来源徽章按模型包声明,白霜显示〔墨奇〕 2026-10-02 21:13:31 +08:00
Jia Sui 426bd960a6 fix(server): octagram 落位失败清理 .part 残留,订正重新下载的注释 2026-10-02 20:15:41 +08:00
Jia Sui 01c45c8d90 fix(server,ui-html,engine): octagram 激活中的模型包也可删除,引擎映射支持动态释放 2026-10-02 20:15:41 +08:00
Jia Sui c2e7fd0c9b fix(server,ui-html,installer): octagram 模型取消默认/回退语义,删除守卫只保护显式激活包 2026-10-02 20:15:41 +08:00
Jia Sui 03c0a4246d feat(server,ui-html,engine,installer): 接入社区多 octagram 模型,分模型下载与单选激活 2026-10-02 20:15:40 +08:00
Jia Sui 8f22f68d4c refactor(server,ui-html): 万象模型撤下未评测说明与hash检查
有效性判定收敛为单一标准:能被引擎读取端打开(格式锁)即已下载——
「未经评测」的前提随上游更新不再成立,摘要比对、旁挂 .sha256 与
reviewed 字段不再有任何用途,全链路移除:

- collocation_model:删 kReviewedSha256、Sha256Hex(含 bcrypt 依赖)、
  DigestSidecar/ReadRecordedDigest;NOTICE.md 保留 CC-BY-4.0 署名四要素
  (来源/许可/文件名/字节数),删 SHA256 行与重训备注
- 双宿主快照序列化对称删 reviewed;设置页 ready 文案固定「模型已就绪」,
  删「上游已更新,未经评测」分支
- 顺删本文件从未使用的 <sstream>/<atomic>

行为变化:老用户数据目录里的 .sha256 旁挂文件不再被读取,按整个 models
目录的保留逻辑留到卸载才消失,无害。

验证:clang-format 18.1.8 --Werror、Server 双宿主 Release 构建、
pnpm test 91 例、tsc/vite build、全仓 grep 无残留。
2026-10-02 20:15:40 +08:00
Jia Sui 4541b8c4c8 refactor(server): 语法模型与万象品牌解耦,徽章按模型包派生 2026-10-02 20:15:40 +08:00
Jia Sui 98f7d61284 refactor(server): 万象合并为单个总开关
sentence_collocation_additive + sentence_collocation_rerank 两个键、两个 UI 开关合并为
sentence_collocation_enabled + 一个「万象语法整句」。上游 RIME-LMDG 只有单开关形态
(__include: octagram + grammar/language),它公布的句子正确率 +15%(61.71% → 76.86%)
对应的正是解码期接入,没有「只开重排」的评测;两个开关对同一份模型是可分性的过度承诺。

顺带清掉一个死开关:引擎的 SentenceAssociationOptions 里根本没有 additive 字段,
加成分由 collocation_model 非空隐含开启。GetConfiguredAssocSentenceCollocationAdditive
的唯一消费者是设置页回显,写入的值没有任何读取方——这是「开关开了没反应」的第二处
断点,与模型 id 那处叠加。现在契约对齐:开关关则连路径都不解析,模型缺席则重排一并关闭。

保留 sentence_collocation_model(手动换模型包的逃生口)与两个权重(高级调参,本就
不进设置页)。

行为变化:MergeConfigIntoTemplate 以模板为骨架重建用户配置,模板里没有的键会被丢弃,
因此旧的两个键消失、新的 sentence_collocation_enabled 取模板默认 false,等于已开启的
用户被重置为关闭。可接受——该特性此前因模型 id 从未被写入而根本无法生效,不存在可被
重置掉的行为。

改动面 14 个文件:配置层四处、会话接线一处、双宿主序列化与 configUpdate 分发各两处、
两份 config 模板、设置页四处加测试。

验证:全仓旧键零残留,clang-format 18.1.8 --Werror 通过,Server/Settings 构建 exit 0,
pnpm test 91 例通过,tsc 通过。
2026-10-02 20:15:40 +08:00