Skip to content

Releases: dingminhua/dsh-connect-trae

v4.5.2 · 思考档位不再被吞,也不再被谎报

Choose a tag to compare

@dingminhua dingminhua released this 25 Oct 04:11

这一版做了什么

思考档位不再被吞,也不再被谎报。 插件原先只认识 low / high / xhigh 三档,任何不认识的档位一律按 high 发出去——用户选 Max、实际收到 high,无报错也无日志。这一版把词表与 Trae 客户端对齐,并把「不认识的档位」从谎报改成丢弃(#60)。

三处吞掉档位的地方

Trae 客户端自己认识五档——它的 bundle 里带着 reasoning_effort.{low,medium,high,extra_high,max} 这套 i18n key,并按 agent model 灰度下发(AI.agent.model.reasoning_effort_level_by_agent_model_v2)。插件在三处把它缩水了:

  1. 解析侧:EFFORT_MAP 与 TRAE_REASONING_EFFORTS 没有 medium / max,上游发来就在解析阶段被 filter 掉。
  2. thinkingLevelMap:minimal / medium / max 硬编码成 null,即使解析到了也不可选。
  3. 反向映射(最坏的一处):写成 effort === 'low' ? 'light' : effort === 'xhigh' ? 'extra_high' : 'high'——任何未预期档位都被映射成 high 发给上游。

第三处比前两处严重得多:前两处是「不给选择」,第三处是给出一个便宜了、但用户没要的答案,而且没有任何迹象。静默降档比不给选择器更坏。

改法

反向映射抽成 WIRE_EFFORT_MAP 查表 + wireEffortsOf(),三处调用点统一走它——报告人点到两处,第三处在 wire 行提升的分支里,不改的话同一份目录经不同来源进来会有两种行为。查不到即丢弃,让上游用它自己的默认值。

词表变宽,声称没变:能选哪些档位仍然只取决于上游为该模型实际下发的 options。今天只发三档的模型不会凭空多出 Max——测试里专门有一条断言这个,防止以后把「扩词表」误当成「放宽声称」。

实测(2026-10-25,本机 CN 凭据,98 行目录):当前 options 只有 ["light","high"]、["high","extra_high"]、["light","high","extra_high"] 三种,max 尚未下发。所以这是「今天就备好、明天才用上」,不是伪造档位。

顺带说清一件事

卡片每行显示的是 Trae 自己公布的最大窗口,而下面的预算单选只写 DSH 的本地预算——请求体里既没有窗口字段、也没有 max_mode,所以把预算提到 1M 并不会让上游按 1M 服务。原先的标签读起来像「已经放开到 1M」,现在模型栏加了一条常驻说明讲清这一点。

上游是否接受 v2_max_mode_enabled 这类字段尚未取证,所以这次没有动请求体(乱加字段可能让每次请求 400)。取证之后再决定要不要透传。

验证

  • 1125 例测试 / 87 文件全绿(本版新增 11 例)
  • 双 tsconfig 类型检查通过;tsdown 构建通过
  • 三处均做变异验证:恢复旧三元链 → 5 例红;恢复硬编码 null → 1 例红;去掉解析侧新键 → 1 例红
  • verify:release 20 项全部一致;registry shasum f24f6f79eade645a4c48dd10505fa4fca8776110 与 npm publish 日志一致

贡献者:@ahian-lee——诊断、根因、补丁、断言四样齐全,还主动标了「不要求伪造档位」,这是最难得的克制。

完整变更:v4.5.1...v4.5.2

v4.5.1 · 模型目录并入租户池,只在租户侧上架的模型不再隐形

Choose a tag to compare

@dingminhua dingminhua released this 24 Oct 17:35

这一版做了什么

只在租户池上架的模型不再隐形。 插件的模型目录原先只问了 solo.trae.cn 一处,而它并不发布租户池的完整名单——DeepSeek-V4.1-Flash-1017 就在其中(#46)。这一版把 console.enterprise.trae.cn 的目录并入主目录,两个池的模型都保留。

成因不是丢在合并层,而是读错了 host

目录基址循环在第一个答非空的 host 就 return,而主目录总会答——所以只在租户池上架的模型,即便拿着租户凭据也永远看不到。用未改动的 4.4.7 可以稳定复现,4.5.0 表现一致,所以升级修不了。

实测(2026-10-24,真实 CN 租户凭据):

目录 host 模型数 DeepSeek-V4.1-Flash-1017
solo.trae.cn/api/remote/v1 36 没有
console.enterprise.trae.cn/api/remote/v1 24 有

它不是显示别名。 用插件自己的 bridge 驱动真实网关,两个 id 被派往不同后端:DeepSeek-V4.1-Flash-1017 → deepseek-v4.1-flash-economic-ark,DeepSeek-V4.1-Flash → deepseek-v4.1-flash-ark。

为什么是「并集」而不是换 host 或兜底候选

  • 并集而非替换:两侧没有一方包含另一方——主目录的 36 个里有 19 个不在租户应答中,其中就包括 deepseek-v4.1-flash。换 host 等于用 1 个模型换掉 19 个。
  • 不能做成兜底候选:候选恰恰在主目录应答时被跳过,而那正是唯一会出错的情形。
  • 冲突保留主目录的拼写,按不区分大小写比较。这里不能用 preferStrongerRow 打擂台:deriveCatalog 用 enabled.has(model.id) 精确匹配,改名会让用户已存进 enabledModelIds 的那一项静默失配、模型从选择里消失。
  • 逐 host 尽力而为:传输失败、非 2xx、响应体读不出、应答为空,都记日志后跳过,绝不抛出。某个额外 host 坏掉,损失的是它的模型,而不是整份目录。

门控与代价

  • 按凭据、不按面板:只登录租户账号的机器,在 Trae(消费端)面板下 store.resolve() 依然会返回租户凭据(offered() 是「藏光了就回退」),所以按面板判会漏掉这类用户。现在判「解析出的凭据 tenantId 非空」,个人凭据在发出请求前就跳过。
  • unionRegion 挡住跨区域请求:DSH_TRAE_TENANT_IN_CONSUMER 是环境变量、不分区域,原先国际版面板也会挂上 CN 租户 host。现在区域不符即跳过。
  • 额外 host 有负缓存:discoverModels() 不传 signal、超时回落到 30 秒,原先企业 host 不可达时每次刷新都要多等。失败后与主 host 同款冷却 5 分钟。

验证

  • 1114 例测试 / 87 文件全绿(本版新增 8 例,覆盖并集、大小写冲突、额外 host 不可达/被拒/空应答、个人凭据跳过、跨区域跳过、冷却、已是主 host 时不重复请求、未配置时行为不变)
  • 双 tsconfig 类型检查通过;tsdown 构建通过
  • verify:release 20 项全部一致;registry shasum e3eff0e0471365fd6312b8981cc5dd0c8eb46a03 与本地 npm pack 一致

贡献者:@yuantao313(PR #59)

完整变更:v4.5.0...v4.5.1

v4.5.0 · 宽窗模型多一个 500K 上下文中间档

Choose a tag to compare

@dingminhua dingminhua released this 24 Oct 09:31

这一版做了什么

Trae 每个模型公布两个上下文窗口:默认(dev)档与 Max 档。dev 实测是 200K / 256K / 272K,Max 实测 1M(MiMo 为 981504)。从默认直接跳到 Max 是 5 倍,而 1M 的计费并不是每个会话都用得上——所以这一版在两者之间加了一个 500K 的半步。国内版与国际版都生效。

为什么 500K 是有门槛的

500K 不是上游公布的窗口,是本地的选择。所以:

  • 出现的条件:该模型的 maxContextWindow >= 500000,且 500K 严格宽于它的 dev 窗、又严格窄于它的 Max。dev 本身已是 500K、或 Max 正好 500K 时不会出现重复选项。
  • 生效的条件:applyContextBudgets 用同一条规则(contextBudgetOptions)校验落盘值。旧配置里留下的 500K,在某模型 Max 被上游调小之后会安静失效、退回 dev 档,而不是把模型撑到它没有的窗口。

两处共用一条规则,是为了避免那个最隐蔽的失败:卡片上能点,落盘后不生效。

卡片上的变化

  • 每行的上下文单选从固定两个变成 1 / 2 / 3 个:无 Max 的行仍是一个只读选项。
  • 新增整区按钮 「整区切到 500K」,只作用于 Max ≥ 500K 的行,写入值与逐行单选完全一致(与「整区切到 Max」「全部恢复默认上下文」并列)。

顺带修掉的一次崩溃

scripts/verify-release.mjs 的确定性重建比对原本在工作树里跑 npm run build。开发者常态是把 bundle 以软链装进 profile,于是这等于当着活着的宿主改写它正在服务的客户端 bundle——2026-10-24 14:40 桌面版渲染进程连崩三次(EXC_BREAKPOINT/SIGTRAP),应用白屏要人工重启。现在重建改到临时 worktree 里做,工作树的 lib/ 一个字节都不动;pnpm run build 之前也会提醒当前有没有宿主正在服务这些字节。细节见 DEVELOPMENT.md「危险动作:不要在宿主运行时重建 lib/」。

验证

  • 1106 例测试 / 87 文件全绿(本版新增 12 例)
  • 双 tsconfig 类型检查通过
  • 变异验证:去掉 500K 档 → 5 例红;放宽接受规则 → 3 例红
  • verify:release 20 项全部一致;registry shasum 0d328d2672cf113618daed555ef72c19e9cbd294 与本地 npm pack 一致

v4.4.7

Choose a tag to compare

@dingminhua dingminhua released this 24 Oct 06:37

被隔离的账号副本现在会被点名:账号消失不必再去 ~/.dsh 里翻文件

4.4.6 修掉了一处会静默丢数据的路径:读不出来(半截写入、手改、格式不认识)的账号副本文件,被改名留存在原地(.corrupt-<时间戳>,字节完整),而不是被下一次刷新合并覆盖、抹掉其余全部账号。

但那件事是静默的:宿主侧一行日志都不打,卡片的「诊断」栏也看不到。用户唯一能发现它的方式,是自己去 ~/.dsh 里翻文件名带 .corrupt- 的文件——这是只有开发者才想得到的动作。对「账号凭空消失」这类报告,排查因此要多绕好几轮。

4.4.7 只补可见性,不改任何账号、刷新、镜像的行为。

新增

  • 诊断栏新增一行「损坏副本留存」:点名那份留存文件(原来的路径、现在的路径、字节数,以及能读成 JSON 时的账号数)。
  • 未登录那一屏也显示同一条通知。这一点是刻意的:账号消失之后,用户落地的正是「未登录」那一屏,而那一屏根本不渲染分栏——诊断栏根本看不到。只把通知放进诊断栏,等于没做。
  • 通知是「扫描」出来的,不是另记一本账:证据就是磁盘上那个文件。用户把留存文件删掉(说明已经取回),提示随之消失,没有第二处状态需要清理,也不会留下永远消不掉的旧提示。
  • 读不出账号数就不猜:被撕裂的文件没有可数的行,显示「账号数无法读取」,而不是印一个会读成「没有账号丢失」的 0。
  • 健康的机器上什么都不显示:没有通知,也没有空盒子。

关于 #56

如果你正卡在 issue #56(Trae CN 依次登录两个账号,被顶掉的那个过一阵子消失),这一版让排查少绕一圈:

  • 升级到 4.4.7 后打开设置页,卡片会直接告诉你有没有出现过隔离,不必再自己去 ~/.dsh 找 .corrupt-* 文件;
  • 如果出现了通知,那份文件里就是被顶掉账号的最后一份完整副本(字节未损);
  • 4.4.6 的修复解决的是「不再抹掉」,4.4.7 解决的是「不再没人知道」。

测试

  • 85 文件 / 1093 例全绿(4.4.6 基线 1084 + 新增 9)。新增用例覆盖:宿主报告隔离文件、用户删除后通知随之消失、signed-out 与 signed-in 两种状态文档都带上通知、诊断栏点名、未登录屏可见、账号数可读/不可读、健机器保持沉默。

v4.4.6...v4.4.7

v4.4.6

Choose a tag to compare

@dingminhua dingminhua released this 24 Oct 06:08

对齐宿主 DSH 0.2.1-rc.3(插件代码零改动),并修掉账号链路上三处会静默丢数据的问题

宿主桌面版推进到 0.2.1-rc.3。这一版上游只落地 5 个提交:三个是「导航项自定义」(面板固定/取消固定、More 菜单、埋点),一个是 DeepSeek API-key 通道改走官方 /models 目录,一个是版本号——均与本插件不相干。

插件消费的 13 个宿主包里只有 dsh-client-ui-primitives 有代码变化,且全是新增(TooltipSide 增加 'left' 并改用实测边框盒换边放置、MenuItemButton 增加 current、Menu 增加 minWidthFromAnchor、新增 IconAppsAddOutline*)。本插件对它只有类型层引用,运行时不消费这些组件,因此不需要任何适配。cordis / schemastery / pi-ai 均未变(宿主实测随包的 pi-ai 仍是 1.1.0)。

真正的风险在插件自己身上——下面的三条修复才是这一版值得更新的原因。

修复

  • 副本文件损坏不再清掉全部账号(PR #58)。
    parseOwn 此前把「读不懂的副本文件」(半截写入、手改损坏、未知版本)一律当成「一个账号都没有」,而镜像 / 刷新 / 导入三条合并写路径又以它为合并基底——一次损坏读 + 一次刷新 = 其余全部账号的副本被无声抹掉,账号行随下一个轮询消失,且异常全被吞掉,日志里什么都看不到。
    • parseOwn 改为三态(合法 / 合法空 / 无法解析),读不懂的文件先隔离为 .corrupt-<时间戳>(字节保留、可找回),再从干净文件开始。
    • 隔离失败则宁可不写,绝不覆盖读不懂的字节。
    • deleteAccount 对不可解析文件拒绝而非当空。
    • 这可能是 #56(被顶掉的账号若干时间后消失)的一种成因——遇到这个现象请检查 $DSH_HOME/.trae-auth.cn.json 及同目录的 .corrupt-* 隔离文件。
  • 墓碑读-改-写收进一把锁(PR #58)。墓碑文件被两个并发流读改写:镜像(清失效墓碑)与删除(加墓碑),此前都是锁外读、锁内写,两个方向都会丢更新——丢一个墓碑=已删账号在下一轮镜像复活;丢一次清理=墓碑永久残留,该账号之后永远无法再被镜像。
  • 池测量的删除不再丢并发写入(PR #58)。dropTraePoolProbe 的读取挪进锁内(对齐同文件 writeTraePoolProbes 的范式):此前锁外读的快照会把并发批次刚写入的测量覆盖掉。

兼容性

  • peer 范围无需改动:0.2.1-rc.3 对 >=0.1.7-rc.1 <0.3.0-0 已判通过(实测)。
  • 本插件注册的 5 个槽位(plugins.bundle.config、plugins.row.config、conversation.input.left、conversation.composer.dock、conversation.input.model.label)在 rc.3 上仍然存在且契约未变;宿主新增的槽位与本插件无交集。
  • rc.3 宿主上实测:宿主侧配置条目在册,客户端三处槽位注册均 active。

测试

  • 84 文件 / 1084 条全绿(4.4.5 基线 1080 + 新增 4)。新增用例覆盖:损坏副本文件被隔离且字节保留、合法文件中坏一行只丢该行、隔离失败时放弃写入且原字节不动、墓碑并发删除/写入序列化、池测量的 drop 与 write 不互相覆盖。
  • 补上 tests/dsh-peer-range.spec.ts 的「必须放行的版本」清单里此前缺失的当前宿主版本 0.2.1-rc.3——范围若被误收窄到当前宿主之外,这条守卫现在会变红。

升级提醒

  • 无需改配置、无需重新登录账号;直接升级即可。
  • 首次启动若发现 $DSH_HOME 下出现 .trae-auth.*.json.corrupt-* 文件,说明旧版本已经把一次损坏读当成了空列表——里面的账号仍在,请按 PR #58 的说明取回。

v4.4.5...v4.4.6

v4.4.5

Choose a tag to compare

@dingminhua dingminhua released this 23 Oct 08:26

模型列表不再倒出官方已下架的历史配置:46 → 34 行,按通道分组、默认只看常用通道

合并自 #55,修 #52。报告人问「为啥 trae 的模型数量这么爆炸」并提醒「拿 code 的模型请求 solo 的潜在风险」——查下来是同一个洞:插件列的是 12 个目录 function 的并集(46 行),而 Trae 客户端一次只渲染一个 function(14–24 行);#46 的提升通道只问「能不能调」,不问「官方还展不展示」。

修复

  • 按 IDE 名册三档判决(接入第三条上游信号 batch_get_detail_param 的 is_invisible_to_user)。它是逐 (config, function) 的模式名册,不是生命周期标记(实测:DeepSeek-V4-Pro 在 solo_work_remote 隐藏、在 solo_coder/chat_v3 可见),所以判定分三种:
    • 退役(12 行):所有对话 function 都隐藏 → 移出目录。正是截图里尾部整屏的老模型。
    • 改钉(6 行):自己通道隐藏、别的对话通道展示 → wireFunction 换成官方展示它的那个,按通道优先级选(两次刷新一致)。这正面回答了「拿 code 的模型请求 solo」——错的是我们猜的并集首个 function,换成官方自己的答案。
    • 保留:名册沉默(没提到 / 只当工具配置 / 无对话通道能判)→ 一行不动。沉默不是判决。
    • fail-open:名册读不到就返回 undefined,一行不动,永不把刷新搞失败;成功失败各缓存 10 分钟。
  • 顺序改为纯函数:通道优先级 → 显示名(大小写不敏感、版本号按数字比较,GLM-5.10 在 GLM-5.9 后)→ id 兜底。同一账号两次刷新不再排出两个样子;发现流程与卡片各排一次,升级前保存的旧目录也被扶正。

卡片

  • 按通道分组(原生 <details>,默认全开),组头写明模式与行数——34 行变成 6 组,「为什么这么多」一眼有答案。
  • 搜索匹配显示名、id 与 config_name(排查 4001 的人手上拿的是上游名);搜索只是视图,「测试所有」与批量操作仍作用全量目录。
  • 默认只看常用通道(solo_work_remote + solo_work_lite + 未标注 = 24 行,与客户端单模式 14–24 同量级),「全部」34 行;被藏起来的已启用行有固定提示 + 一键切换。

测试

  • 84 文件 / 1080 条全绿(4.4.4 基线 1019 + 新增 61)。新增三个 spec:official-roster(23 条,含走真实 mergeTraeModelSources 的端到端与 fail-open/缓存窗口)、model-order(26 条)、card-model-groups(12 条,含「搜索时测试范围不缩小」)。审阅时补做了变异验证:把 config_switch 混入判决,恰好只有专用测试变红。

已知边界

  • repin 未做真实对话调用(花额度),只证明到「官方在别的通道展示它」。
  • config_switch 只记录不判决(语义未实测)。
  • 视图选择不跨会话记忆,默认回到「常用通道」。
  • 体积:client +25.75 kB / index +18.81 kB(新模块 + 分组 UI,预期增长)。

v4.4.4...v4.4.5

v4.4.4

Choose a tag to compare

@dingminhua dingminhua released this 23 Oct 07:54

同价的会员分支不再被读成第二重折扣;闲时徽标补上时段

合并自 #53。真机截图比对时发现:同一个 deepseek-v4.1-flash,插件胶囊写「闲时 5 折」、官方客户端写「会员 5 折」、详情栏又并排列出两段一模一样的 5 折——查下来不是渲染错,是旧实现把同一个折后价的两条资格路径讲成了两层折扣。

修复

  • 同价的会员分支不再当第二重折扣。off_peak_member_discount_18_9 这类活动里 member 与 off_peak 指向同一个 0.06(实测 2026-10-23:两者都是 0.12 → 0.06, discount 50;会员全天可享,非会员只在闲时窗口内可享)。旧悬停写「会员价另有 5 折」,读起来就是 0.06 再打五折 = 0.03,上游从来没有这个价。现在比较两条分支的折后价,只有 member.rate < 现价 才带会员价,文案改成给绝对数(会员价 0.06 积分/百万 token(5 折));等值时整句不出现。
  • 闲时徽标补上时段。current 判定出的 offPeak 徽标,若本地时钟确认某窗口正开着,现在会把该窗口(起止 + 时区)挂上去——以前有「写着闲时 5 折、悬停却说不出时段」的形状。时钟与上游不一致时不补,宁可少说。

文档

  • 新增 docs/PROMO_CLIENT_RENDER.md:官方客户端渲染链路取证(featureOrder + Jexl + tag/tooltip.sections,服务端下发渲染配置而非客户端判折扣;免费用户也看到「会员 5 折」是因为那是 campaign 的招牌 tag)。实测与推断逐段标注;docs/PROMO_BADGE.md §3/§4 同步补注。

测试

  • 81 文件 / 1019 条全绿(4.4.3 基线 1014 + 新增 5)。同价不引用在三层都有断言:promo.spec(badge 级)、card-promo.spec.tsx(卡片悬停)、model-label-slot.spec.tsx(选择器悬停);另有「上游闲时判定补时段」「时钟不认时不补」两条。

已知边界

  • 不跟官方 campaign headline 改叫「会员 5 折」:官方那枚 tag 描述的是活动招牌价(非会员也可见),我们按本地判定给当下成立的价——粒度差异,不是错误。
  • 官方渲染配置体是加密的(AES-CTR + gzip,密钥主进程注入),tooltip.sections 装配顺序系从日志与本地 i18n 表反推,文档已标注。

v4.4.3...v4.4.4

v4.4.3

Choose a tag to compare

@dingminhua dingminhua released this 23 Oct 05:42

模型选择器里也看得见活动优惠;账号池信息架构重排;两个真 bug 修复

合并自 #51(#50 的落实)。结论移植自姊妹插件 dsh-connect-workbuddy,代码按 Trae 结构重写——两边促销协议不同,共通的只有「怎么判、什么时候判、显示几个数字」。

新增

  • 模型选择器里也画活动优惠胶囊(宿主 conversation.input.model.label 插槽)。挑模型时就能看见折扣——徽标画在设置卡片里时你已经选完了。守住三条:倍率只出现一个(名字里已有的目录倍率被按形状拆出,有折扣时换成折后价,杜绝 workbuddy #120 的 · x0.55 · x0.55 回归);渲染时刻判定(共享分钟定时器,夜间折扣不会第二天早上还挂着);取数走 detail=fast(打开选择器不触发上游读,缓存 60s;企业版读自己的名册,别人的 provider 一个徽标都不画、连请求都不发)。

修复

  • regionsMapOf 不再跳到过期的同名区域:旧规则「有 regions 键就往下跳」会读到同一 panel 的另一份更旧拷贝,表现为已保存的开关/手动排序读回空值、看着像没保存。新规则按形状判定(外层含 panel id 即 map)。
  • 三处被基础类覆盖的样式(真机截图比对时发现):模式条的描边渐变、池外计费警示的橙色、账号下拉的 max-width,都因修饰类规则写在基础类之前而被抹平。改用双类选择器(.a.b),与规则顺序解耦。

重构

  • 账号池信息架构重排:总开关上提到标题下方(读运行态而非草稿)、手动选号并进标题行、「派单中」不再与「未入池」同框(正交事实分开说,冲突时一句话解释)、批量按钮移进成员区、保存条 sticky、测试模型只说一遍(表头改「状态」,行尾仅在实测模型 ≠ 池模型时点名)、三段说明收进 <details> 折叠。
  • promo-shot 工具修复:4.3.0 分栏后失效(等一个看不见的区),改为 view: 'page' + 按 tab id 点模型栏。三个截图工具现在全过。

测试

  • 81 文件 / 1014 条全绿,本批净增 17 条。变异验证三处:regionsMapOf 回旧行为 → 1 红;倍率优先级改「名字优先」→ 2 红(报错正是真实症状 Doubao-Seed-2.1-Turbo · x0.4050% off);modelDiffers 回无条件 → 2 红。

v4.4.2...v4.4.3

v4.4.2

Choose a tag to compare

@dingminhua dingminhua released this 23 Oct 03:58

带工具的对话在 deepseek-v4.1-flash 上整轮 400/4027 拒绝——已在两个工具出口归一化为 draft-4

接 #48 的后续证据(#49):上游校验分后端。同一凭证、同一 SOLO 出口、同一工具 schema,glm-5.2(智谱后端)放行属性内的 required: true,而 deepseek-v4.1-flash 按 JSON Schema draft-4+ 严校验,直接回 4027 … tools.N.function.parameters/properties/X/required: invalid JSON Schema——且 tools.N 是按批校验,一个不合格即全挂,所以「带工具必 400」。之前判「上游已放行」是因为只在宽松的智谱后端上试过。

修复

  • 工具 schema 出口统一归一化为 draft-4。DSH schemastery 生成的工具参数是 draft-3 风格——required: true 写在属性内部;draft-4 起已改为父级字符串数组 { "required": ["tool"] }。新增 normalizeTraeToolSchema / normalizeTraeToolSchemas 递归提升(覆盖 items/anyOf/oneOf/allOf 任意嵌套,与既有 required 数组去重合并),幂等——已是 draft-4 的 schema 原样返回,不改变合法载荷。
  • 两个工具出口都套上归一化:prepareSoloBody(SOLO llm_utils_chat 主路径)与 buildTraeRawChatDraft(raw chat 路径)。纯本地、不碰凭据、不改调用方入参。

测试

  • 989 例测试全绿,新增 7 例回归:draft-3 提升、嵌套递归、数组合并、draft-4 幂等、非 properties 处的 boolean 不误伤、入参不被原地修改、SOLO wire 载荷为 draft-4。

已知边界

  • 归一化只处理 draft-3 boolean required 这一种已实测命中的非法形态。
  • 修复侧验证为单测 + 构造载荷核验;上游行为依据报告人 #49 的三步对照实验(D1 无工具 200 / D2 draft-3 4027 / D3 draft-4 200)。

v4.4.1...v4.4.2

v4.4.1

Choose a tag to compare

@dingminhua dingminhua released this 22 Oct 15:17

这是一个自我纠正的版本。4.4.0 发布后作者对提升的模型做了真实调用实测,实测把 4.4.0 自己的一个缺陷挖了出来。

4.4.0 藏掉了一个能用的模型

4.4.0 为了防止重名孪生行,加了「显示名已被占用就跳过」的规则。但这一条把 kimi-k2-0905 也丢掉了 —— 它和 kimi-k2 同名,却是另一个真模型:

id 上下文 输出上限 function 实测
已有 kimi-k2 28000 16000 chat_v3 AVAILABLE
被藏 kimi-k2-0905 168000 32000 solo_coder AVAILABLE

也就是说:报告人在 issue #46 里抱怨的「带日期的快照 ID 拿不到」,在 kimi-k2-0905 上依然成立 —— 成因从「合并只遍历骨架」换成了「去重按名字判断」,症状没变。修一个「被丢弃」类缺陷时,新加的过滤条件可能产生同一个症状,这次就是。

改法:重名是能力测试,不是名字测试

claimedNames 记录每个显示名下最大的上下文窗口。一个重名行只有在严格更大时才提升,并追加 id 以便区分 —— 两行都渲染成 Kimi-K2-0905 的 picker 是在撒谎。

实测数据检验这条规则:

情形 判定 理由
kimi-k2 28000 → kimi-k2-0905 168000 提升 能力差 6 倍
minimax-m2 100000 → -auto 168000 提升 上下文更大
glm-4.7 vs glm-4.7-auto 跳过 元数据完全相同,真重复
glm-5.2_advisor_default 168000 < glm-5.2 200000 跳过 内部改道,比已有更小

比较基准是最强的占用者,所以与名单顺序无关。

结果:目录 42 → 46 行,提升行 7 → 11。 新增 kimi-k2-0905、minimax-m2-auto、minimax-m2.1-auto、glm-4.6-auto(均为 168K / solo_coder),显示名形如 MiniMax-M2 (minimax-m2-auto)。

顺带把 4.4.0 缺的实测补上了

4.4.0 的说明里写着「新提升的 7 个模型未实测可调用性」。现在测了,全部通过 —— 真调用,走插件自己的 bridge,每个一次最小 ping:

模型 function 结果
seed-code-pro-0430 / glm-5-turbo solo_work_remote AVAILABLE
glm-4.7 / glm-4.6 / minimax-m2 / minimax-m2.1 / qwen3-coder chat_v3 AVAILABLE
kimi-k2 inline_chat · chat_v3 · solo_work_remote 三个 function 全通
4.4.1 新增的 4 行 solo_coder 全部 AVAILABLE

11/11 提升行全部可调用。 合计 21 次真实调用,约 11 额度。4.4.0 里「kimi-k2 归属 inline_chat、可调用性未取证」这条边界也一并关闭。

一条诚实的负面发现

4.4.0 的「多问几个 function」带出了 doubao_1_8(Doubao-Seed-1.8),但它实测 4001 拒绝 —— 它没有 wireFunction,也没有上下文与输出元数据,是条残缺的骨架行。按 issue #19「全部呈现 + 如实报错」的策略这是合规行为(选中会得到明确的上游原文错误),但它确实是一条新增的、调不通的行。记在这里,不假装它可用。

测试

982 例测试全绿,新增 4 例:重名但更强者被提升且名字带 id、重名且相等/更弱者仍被排除、-auto 孪生按能力取舍、比较基准取最强占用者。

一个教训:46 个单测全绿也看不出少了一行模型。单测只能验证「规则按我写的执行」,验证不了「这个规则对不对」—— 后者只能靠对真实上游动手。

完整诊断见 docs/ISSUE46_DIAGNOSIS.md 第 9 节。

安装

npm install dsh-connect-trae@4.4.1

v4.4.0...v4.4.1 比较: v4.4.0...v4.4.1