Skip to content

Reasonix Studio v2.12.0

Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 04 Sep 00:47
· 869 commits to main-v2 since this release

本版的主线是远程工作区第一次真正可用:此前这条线没有发布过远端能装的内核,所以「在另一台机器上开工作区」在任何配置下都装不上东西,而失败会报成一个与真因无关的错误码。同期把项目自身状态移出跨项目共享的缓存前缀(首轮缓存命中率实测 4.2% → 54.7%),并把 Controller 按生命周期拆成协作者。自 2.11.0 起 56 个提交。

升级路径:无需人工步骤。三平台照旧自更新——Linux 走 .deb,Windows 运行下一个安装器,macOS 替换自身 bundle。

新增

远程工作区:这条线现在会发布远端要装的内核

  • 发布 CLI 归档。此前 studio 线只发桌面包,而远端安装的三条路里有两条要按版本名去取一个 release。它们取的地址不存在(tag 是 studio-v2.11.0,取的却是 /download/v2.11.0/),于是双双在发网络请求之前就被拒,只剩 npm 一条——而 npm 上那个包属于 1.x 线,装下来低于开工作区所需的内核版本。现在每次发布同时产出六个平台的 reasonix-<os>-<arch> 归档与 SHA256SUMSreleaseasset.Line 表达 tag 命名空间(它是 tag 前缀,不是 update.Line 那种安装布局——一个类型同时回答两件事,就会让 tag 前缀去决定 .deb 装到哪)。
  • 内核声明自己的版本。打包脚本此前不注入版本,于是发布出去的内核自称 dev,而按版本取 release 的两条路都拒绝一个非发布版本。顺带修好了一个从未生效的门:ParseVersion 读不了 studio-v2.11.0(它在第一个连字符处断开),版本因此为空,而「没说版本」按设计是放行的——所以内核版本下限对整条 studio 线从来没有真正生效过。注入的是 v2.12.0 这种 semver 而非完整 tag,门才成立。
  • 取过一次的发布不再取第二次。为一台够不到 release 的机器安装时,归档由本机取下、经 SFTP 推过去;每多一台同平台的机器就重付一次同样的下载。现在验证过的字节留在 <cache>/cli/<tag>/<goos>-<goarch>,第二台起不再下载,而安装包体积不变——把 CLI 塞进 Studio 是相反的取舍:给每次安装加约 30MB,只为省一次下载,且只对同平台的远端有效。缓存旁存摘要,那是本机磁盘的完整性检查而不是边界(能写二进制的也能写摘要),不匹配即当作未命中。
  • 内核可以托管 Studio 页面。新界面此前只有一条到达路径——经桌面外壳,隔着一道绑死 127.0.0.1 且不可放宽的 loopback 门。其它任何打开内核的方式拿到的都是内核内嵌的旧页面。现在页面挂载是 hub 的能力(--page,落在 /_studio/),两个宿主共用一份。它位于认证门之内:外壳把页面包在门外是安全的(loopback 门先答),但一个绑到网络地址的 serve 没有那道门,同样的写法等于把页面交给任何能连到端口的人。
  • 首次连接不再是一项配置任务,以及一条临时 -R 转发在重连后仍留在原端口上。

其它

  • 上下文窗口在「注意到它缺失的地方」直接声明:中继服务以自己的名义转发别人的模型,没有任何探测或目录能说出它的上限,此前只能把人指到连接页。
  • 折叠阈值成为设置项,并说明是哪一条边界触发的。
  • 工具调用会报告它花在命令之外的时间;宿主记录一个会话计费多少、冷启动花了多少。
  • 请求会说明它携带的正文是否与上次发出的相同。

修复

远端安装:探测说能用、启动必崩

一个内核能否被驱动,此前只靠在 serve --help 里找一个 port-file 来判断。但启动传的不止这一个——broker 那一对晚了一整条发布线才出现。于是一个只有前半组标志的旧内核通过了探测,带着 --provider-broker 被启动,在一个它从未定义过的标志上退出。到达使用者的是 20 秒后的「serve 从未报告端口」:一个超时、一台机器、一句「去看日志」——而那份日志已被失败清理删掉。真因(那台机器上的内核来自另一条线)没有出现在任何一处。

现在探测问的就是启动会传的那一组,并有测试断言两者相等。同一形状还有两处:失败清理与停止各自抄了一份「一次 serve 的记录由哪些文件组成」,broker 令牌加进来时两边都漏了,于是每次失败的启动都把本机的凭据留在远端;remote testremote connect 接的是不同的参数,前者因此把一条 connect 会走的路报成关闭、把一条注定被拒的路报成开着。

失败归因也补上了缺的那个身份:ErrNoReleaseForBuild 说「这个构建没有可安装的发布」,排在各条路自己的错误码之前——被指去装 curl 的人装完了仍然没有路。npm 那条路装完后版本不够时,现在报的是版本不够,而不是「装到 PATH 之外」。没有摘掉 npm 这条路:摘它需要硬编码「npm 上是 1.x」这个会过期的判断。

另外,一个由程序启动、凭据来自 broker 的内核不再在启动时查询余额——它按设计没有自己的凭据,那次查询必然失败,于是每份远端日志的开头都常驻一条与故障无关的错误,而那份日志只在排查故障时才会被打开。

编码与路径

  • 命令输出按它被写出时的代码页读取。
  • 大于预读窗口的 CJK 文件不再被判成 GB18030。
  • 以盘符根开头的 glob 走那个盘,而不是当前目录;在盘符根打开的项目不再显示为 \

其它

  • MCP:会话的 MCP 生命期不再等同于构建它的那次请求;连接一个待定服务器是一个决定并被记录;仓库声明的服务器会等待回答;读取 Claude Code 实际写入的 scope。
  • capability:目录是索引而不是每一条描述;批处理分发器在模型读得到的地方被命名;工具自己的名字解析到它自己。
  • agent:从未运行的调用不再判定一次修改失败;在参数中途被截断的调用即使终端看起来完整也会被丢弃;子代理的工具 id 只做一次命名空间;依赖屏障不再丢掉委派。
  • 被拒绝的完成会说明是哪一条主张没有成立、缺了什么。
  • 判断哪些文件是测试不再靠读工作区。
  • 界面要过而目录里没有的八个 i18n 键。
  • 最新的指令可以取代它之前的副本。
  • 长文件名不再覆盖它自己的 +N -N;前缀缓存说明文字不再成为那一行的溃缩区。

内部

  • Controller 按生命周期拆成协作者:会话的生命周期与持久化、审批编排及其守卫、MCP 服务器编排、把输入变成一个回合与运行一个回合、取消与善后,各自成文件;一次回合的投影从八处前置改为一处。
  • 项目自身的规则、记忆索引、技能目录与版本控制状态移出每个项目共享的缓存前缀,改由回合承担。
  • 安装脚本现在会被真正执行而不只是被写出来:下载、校验摘要、解包、定位、读回版本,全程真跑一次 shell。
  • macOS 按架构分别构建而不再产出单一 universal bundle;产物按其中的 bundle 命名;不再打包 bundle 里没有任何东西会读取的文件。

macOS 已用 Developer ID 签名并公证,打开时不需要清除隔离属性。Windows 的窗口、内核与安装器都经 SignPath 做了 Authenticode 签名。Linux.deb 安装。

三个平台都能自更新:Linux 走自己的包,Windows 运行下一个安装器,macOS 替换自身 bundle。