本版的主线是让"检查通过"意味着它所说的那件事:模型可用性探测此前从不发工具,于是一个只会聊天的中转站通过了验证、在第一条消息上失败,而设置面板仍标着"已验证";一个 2024 年才有的可选字段被无条件发给每个 OpenAI 兼容端点,让不认它的网关拒掉整场会话。界面一侧,一个中文词在两处字典里有两种英文,英文窗口上的"保存"按钮读作 Transcript;补全菜单的内置动词由内核按进程语言渲染,于是中文机器上的英文窗口配一份中文菜单。另一条主线是老外壳的退役:Wails 那套连同它的 CGO 与 GTK/WebKitGTK 构建要求一次性移除,Studio 从此只有一个外壳;内核与控制器随之做了一轮按主题的归位。自 2.16.0 起 39 个提交,净减两万六千行。
升级路径:无需人工步骤。三平台照旧自更新——Linux 走 .deb,Windows 运行下一个安装器,macOS 替换自身 bundle。已安装的 2.10 及更早的 Wails 版本仍由现有的接管路径升到本版,那条路径不是 Wails 代码,未被此次退役触及。
修复
检查通过,然后第一条消息就失败
- 模型可用性探测现在带一个工具。Reasonix 是代理,一个递不进工具的模型跑不了一回合。探测此前只发 messages 和 max_tokens,于是一个应答聊天、拒绝 tools 数组的中转站通过了验证,用户的第一条消息才失败——而那一行仍显示"已验证"。被拒时它再问一次、这次不带数组,只有当去掉数组正是让请求答上来的那件事时才报"tools":结论来自第二次尝试成功,不是拒绝里的某个词。凭据错误与限流不给重试——第二次会因第一次的同一个理由被拒——所以那条"只试一次"的规则对它们原样保留。连接按钮从未声称超出它所证明的(它只列模型,它自己的注释就这么写),但"已连接,OpenAI 兼容"读起来像"可以用了"。现在那一行说得出"端点应答聊天、拒绝工具调用",这一句话把人送去换网关,而不是送进一场注定失败的会话。
- 不再为一个 token 计数器赔上整场会话。
stream_options被无条件发给每个 OpenAI 兼容端点。它是 2024 年的新增项,比它更早的、或转发时较真的网关会拒掉带着它的请求,而它要的只是用量记录——一个 token 数,不是一回合需要的任何东西。于是一个别的代理都能驱动的中转站,在这里每一条消息都被拒。客户端现在对每个端点问一次:请求体被拒就去掉这个字段重试,若这样答上来了,此后不再发它。按端点问一次而不是每次被拒都问,所以一个因别的理由拒绝请求体的网关不会被永远反复试探;值得一问的状态码是点名的三个——400、413、422——而不是整个 4xx,因为 402 的意思是账户付不出钱,再发一次什么也不会变。实测于一个为此搭的网关:此前每一回合都失败,现在完成一回合,字段发了一次、再没发过。
一个中文词,一种英文读法
- 五个中文词条在两份字典里各有一份定义,而目录是十个模块展开进一个对象——同一个键写两遍,留下的是后展开的那一份,另一种读法从此不可达。其中三处渲染了错的词:
记录在指标那边是 "Save"、在运行图那边是 "Transcript",运行图赢了,于是那个记录模型上下文窗口的按钮读作 Transcript;还原在窗口控件是 "Restore"、在文件是 "Revert",文件赢了,于是最大化窗口的还原按钮自称 Revert;改动文件在权限规则里指 edit_file 这个工具,在顶栏指改动文件数,顶栏赢了。一个中文词承担两种意思,修法是两个中文词,不是更聪明的查表:记录值的按钮改称"保存",窗口控件改称"向下还原"(Windows 中文里它就叫这个)。另外两处(模型、取消)两种写法渲染相同,失去那份从未胜出的定义;十二个写了两遍但值相同的键失去它们的副本。 - 补全菜单说窗口的语言,不说进程的。内置动词由内核措辞、在窗口里被读,两者不必一致:一台 CLI 说中文的机器上可以开着英文窗口。端点此前读配置里的桌面语言,而在没有设置时——那是默认值,意思是"跟随机器"——落到本进程按自己的
$LANG装的那份目录。于是中文机器上的英文窗口,英文输入框下面挂着二十一条中文菜单。窗口才是"它正在画什么"的权威:配置里有值它早已采纳,没有值它跟随自己的区域设置,而那是内核读不到的。所以语言由请求携带,配置只回答那些什么都不说的客户端。
变更
Wails 外壳退役
- 一次事务,而不是逐件删除:
desktop/next与它的事件泵、remote_pump.go、/rx-replay、前端的WAILS_*常量与总线分支、apiPaths/apiPrefixes白名单、vendored 的 go-webview2 分支,以及 Wails 依赖连同它的 CGO 与 GTK/WebKitGTK 构建要求。先删任何一件留下的都是一个坏掉的外壳,而不是一棵更小的树。 - 允许它发生的是那个条件本身:不再有任何只有那个外壳才有的语义,加上此前记为"未验证"的那一条——发布线。studio-v2.11.0(2026-09-01)到 2.16.0 已经七次发出 Electron 包,而从已安装的 Wails 2.10 跨过来这件事由维护者确认过,不是在这里假定的。
- 两个后果值得说出来。desktop 模块现在不含 CGO,所以 CI 与贡献者都不再为构建它安装 GTK 或 WebKitGTK,
webkit2_41标签从每条命令里消失。而老外壳装下的东西原样不动:winuninstall、Electron 外壳的接管路径、studio_line的二进制名——已安装的 2.10 靠它们变成 2.11,它们都不是 Wails 代码。 - 迁移契约变成
docs/STUDIO_SHELL_BOUNDARIES.md:它立下的规则活得比迁移本身长,它记的那些账不必。契约里跟踪的展示层缺口原样转为已知缺口,并补上主机侧缺失的崩溃捕获。 - 内核随之失去只有那个外壳够得到的东西:
update.LocalApplication(一个自身即应用的进程,Electron 的不是)、update.Here、appidentity的 AppUserModelID 应用与快捷方式修复(Electron 自报 appId)、crashreport.CaptureStudioPanic。AppUserModelID 本身留下——Windows 的通知仍带着它。
内核按主题归位
四个各自占着一个包三分之一的文件,按它们服务的那个界面拆开,代码与规则一行未改:
controller.go3232 → 1430。七组方法回到它们的主题已经拥有的文件,回合入口(Send、RunTurn与它们驱动的循环)拿到自己的一个。留下的是构造函数与访问器——每个主题都要读的那份会话状态——这就是行为搬到状态旁边之后,控制器剩下的东西。审批桥拿到的不止一次搬家:决定一次工具调用跑不跑的gateApprover此前住在controller.go,在敏感路径之外;approval_bridge.go现在被声明为敏感,评审与覆盖率下限一并覆盖它。service.go(ACP)3047 → 1676,按协议自己命名的东西拆:会话动词、可在活动会话上切换的轴、以及记住会话的边车。gateway.go(bot)2973 → 1147:连接在做什么、聊天能发哪些命令、哪一条回复算哪种批准、一条消息属于哪个会话、以及发出去过什么。evidence.go2529 → 723,这一系列里第一个把自己的欠账清掉的文件:账本能被问什么、一条 shell 命令算不算验证(从解析出的形状读,不从措辞)、以及待办清单作为证据。- 一批判断收敛为一处:
fileutil.Under/AtOrUnder把三个包各自的pathWithin分成两个问题、各问一种(其中两个决定安全边界);internal/neterr把"这个 socket 失败值不值得再试"问一次,并点名每个平台真正报的身份——syscall.ECONNRESET在 Windows 上是个占位符,于是那边只剩一张英文子串表,而系统的句子是本地化的,非英文 Windows 上两条路都不通;extensioncontract让包解析器与内核读同一条 provider 引用语法,避免一个包通过校验却绑不上。 - 十七个只有测试够得到的导出函数、十三个只是填好一个参数的便利入口、四个再无人构造的类型退役。一个测试调用包装器不是在覆盖生产走的那条路,是在保着第二个入口的温。
- 五十七条带开发阶段编号的注释("stage 7"、"Phase 0")清零,其中三条不只是读不懂而且已经说错了——沙箱配置说读取不受限、而它文档的那个结构体带着
ForbidRead。
门禁与工具
- 两个走查回答了没人问它的问题。外壳的冒烟套件判的是工作台窗口,而一个没有配置模型的数据目录打开的是引导卡——那里根本没有那个窗口。拖拽区那条判据于是以 "no .chrome" 失败,读起来像标题栏有缺陷,实际是套件从没到达它的主题。它现在在外壳读取之前把目录带到判据所假定的状态,而一个已经带着配置的目录原样不动。
- 对比度走查报了一个禁用按钮。WCAG 豁免处于非活动状态的界面组件——一个控件变灰正是为了说它现在不能用——所以 4.5 的底线下那个 3.92 是没人能据以行动的数字,压在能行动的那些上面。两个走查都跳过禁用控件内部的元素,深色十二个区段回到零。
- 中文词条的重复由源文件判定,不由合成对象:展开之后失败的那一份已经不存在,类型系统与运行时都看不见跨两个对象字面量的重复。判据同时核对这次读取覆盖了整份目录——一个模式解析不出的条目,也就是它找不到第二份定义的条目——正是这一条抓出了 prettier 去掉引号的裸键(中文是合法标识符)。
macOS 已用 Developer ID 签名并公证,打开时不需要清除隔离属性。Windows 包未签名,SmartScreen 会告警:选「更多信息」,再选「仍要运行」。Linux 从 .deb 安装。
三个平台都能自更新:Linux 走自己的包,Windows 运行下一个安装器,macOS 替换自身 bundle。