dsh-connect-trae 3.8.1 → 3.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +114 -0
- package/README.md +6 -2
- package/lib/client.js +1909 -126
- package/lib/index.d.ts +1243 -613
- package/lib/index.js +1891 -39
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,119 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 3.9.1 (2026-10-18)
|
|
4
|
+
|
|
5
|
+
> **3.9.0 从未发布到 npm**(发版时卡在 OTP 认证),本版本是同一套账号池功能加上 tag 之后
|
|
6
|
+
> 的十三处修正与重排。功能面见下面的 3.9.0 段;这里只列 3.9.0 tag 之后的改动。
|
|
7
|
+
|
|
8
|
+
### 新增
|
|
9
|
+
|
|
10
|
+
- **测试请求体积**(`regions.<面板>.pool.probeInputTokens`,默认 `0`):测速时向上游发多少
|
|
11
|
+
文本。`0` 是**一个词的最小探针**,其余选项 1 万 / 2 万 / 3 万 / 5 万 / 10 万 token。默认
|
|
12
|
+
保持最小而不是「像真实对话」——填多少就扣多少积分,插件没有证据说明 Trae 在小请求上会
|
|
13
|
+
误判,就不该让默认值替你花钱。老 Host 不认识这个字段时,卡片**不渲染这一行**(否则保存
|
|
14
|
+
必然读回失败)。
|
|
15
|
+
- **读余额前按需刷新 token**:单个账号的凭证过期后,读它的余额/签到/探针会先刷新一次
|
|
16
|
+
(同一账号并发只刷一次,失败时不重试而是返回旧凭证让上游如实 401)。此前只有「当前
|
|
17
|
+
绑定」的账号会被刷新,池里其他账号过期后余额永远是空的;现在读不到余额的行会明确标
|
|
18
|
+
「登录已失效」,而不是只显示一个 `—`。
|
|
19
|
+
|
|
20
|
+
### 修复
|
|
21
|
+
|
|
22
|
+
- **「本机今日已签到」是设备级事实,不是账号级**:Trae 的每日签到绑在 `x-device-id` 上,
|
|
23
|
+
同一台机器第二次签到必被 9095 拒。此前按账号记账,于是池表里第二个账号照样给一个「签到」
|
|
24
|
+
按钮——点了注定失败。现在任一账号当日已领即视为整台机器已用:其余行的按钮禁用、状态写
|
|
25
|
+
「本设备今日已用」,「一键签到所有账号」同样禁用并说明「一台设备一天一次」。
|
|
26
|
+
- **无签到面板的行列数错位**:表格换成四列时,行里仍渲染五个格子,动作按钮被挤到第二行。
|
|
27
|
+
- **绑定下拉里列出幽灵账号**:设置里存着、本机已无登录的账号没有凭证,选中后什么都不会
|
|
28
|
+
发生;现在从「手动选择计费账号」里剔除(仍留在成员表里可移除)。
|
|
29
|
+
- **刷新失败改为五分钟退避**:被吊销的账号每轮轮询都触发两次注定失败的上游刷新。
|
|
30
|
+
- **`tokenExpired` 只在真的读不到余额时上报**:不再出现「登录已失效」与有效余额并排。
|
|
31
|
+
- **药丸开关只作用于设置行**:它曾被写成全局 `.dsm-trae-switch input`,导致面板 tab 里的
|
|
32
|
+
开关也长成药丸;配色也改用能分清明暗的令牌(此前取到的 `brand-primary` 在浅色主题里近黑)。
|
|
33
|
+
|
|
34
|
+
### 变更(卡片外观)
|
|
35
|
+
|
|
36
|
+
- **池区块按参考卡片重排**:顶部只留动作行(一键签到 / 一键测试 / 重新检测),成员表自成
|
|
37
|
+
一张卡(卡头装「已选 N / M」+ 全选 / 清空),每格都是「主行 + 灰副行」,账号管理控件放进
|
|
38
|
+
虚线工具区,保存行移出设置盒并与「鼓励一下」同排。不再有第二张账号表重复同样的名字、
|
|
39
|
+
积分和签到状态。
|
|
40
|
+
- **一套尺度**:内边距 14 / 10,圆角 14(面)、10(面内的盒)、999(药丸),字阶 10–14,
|
|
41
|
+
区块用分隔线而不是再套一层框,同一行各格首行对齐。
|
|
42
|
+
- **成员状态写成字**:「已在池中」/「未入池」不再只靠勾选框表达;勾选框的 label 只包 input,
|
|
43
|
+
点账号名不会改计费对象。
|
|
44
|
+
|
|
45
|
+
### 测试
|
|
46
|
+
|
|
47
|
+
- 全仓 **841** 例通过(3.9.0 tag 时为 809)。新增:`tests/card-shot.spec.tsx`(用真实组件
|
|
48
|
+
渲染成静态页 + 几何审计 + Chrome headless 截图,`CARD_SHOT=1` 才跑,CI 零副作用)、
|
|
49
|
+
尺度守卫(间距变量、圆角白名单)、设备级签到的三条断言(含反向验证:改回按账号即失败)。
|
|
50
|
+
|
|
51
|
+
## 3.9.0 (2026-10-18)
|
|
52
|
+
|
|
53
|
+
> **账号池:多账号不再只是「列出来让你手点」。** 本机读完几个账号之后,可以打开一个
|
|
54
|
+
> **按规则自动选号、请求失败自动换号**的池(默认关闭)。此前多账号的全部能力止步于
|
|
55
|
+
> 「卡片把还有额度的账号列出来,你自己点一下切过去」——额度耗尽发生在一次对话中途时,
|
|
56
|
+
> 你只会看到一条失败,然后回去点按钮、再重发。这个版本把「谁付钱」变成一条可以委托给
|
|
57
|
+
> 插件的规则,同时**不偷偷替你换计费对象**:池默认关闭,打开它本身就是一次显式选择。
|
|
58
|
+
|
|
59
|
+
### 新增
|
|
60
|
+
|
|
61
|
+
- **账号池(逐面板,默认关闭)**:`enabled` / `targetModelId` / `memberAccountIds` 三个字段
|
|
62
|
+
落在 `regions.<面板>.pool`。名单是**显式 opt-in**(默认空,空名单意味着「谁都不服务」,
|
|
63
|
+
而不是「全员」)。
|
|
64
|
+
|
|
65
|
+
| 规则 | 为什么是这个顺序 |
|
|
66
|
+
| --- | --- |
|
|
67
|
+
| 先排除不可用 | `credential-rejected` / `plan-gated` / `not-found` 永久出池(这三种都不是「等一会儿就好」);`rate-limited` / `out-of-credit` / `unavailable` / `failed` 在重试时间后回池;`model-busy` 用 2 分钟短时钟 |
|
|
68
|
+
| 再优先快到期 | 同样是额度,先花掉 3 天内会过期的那部分,否则它过期后等于没拿到 |
|
|
69
|
+
| 然后比可用额度、token 新鲜度 | 额度高者先;同额度取 token 更新者 |
|
|
70
|
+
| 最后按账号 id 兜底 | 排序必须是**全序**,否则卡片与路由器会在两行之间来回抖 |
|
|
71
|
+
|
|
72
|
+
- **失败换号(真实请求路径)**:一次请求最多试 3 个账号。只有**账号级**失败才换号
|
|
73
|
+
(`authentication` / `hard_credit` / `soft_rate` / `server`);`not_found` / `client`
|
|
74
|
+
不换——模型 id 写错换号只会把同一个错误烧两遍,还会冤枉一个没机会服务的账号。换号
|
|
75
|
+
仍然失败时,错误消息尾部会带一句**为什么没有别的账号能接**(全部试过 / 剩余全被排除
|
|
76
|
+
+ 原因),而不是只留一个裸的上游错误。
|
|
77
|
+
- **实盘失败落盘**:换号过程中学到的结论以 `live-request` 探针写进
|
|
78
|
+
`$DSH_HOME/.trae-pool.<面板>.json`(0o600、原子写、永不抛错、**不存任何凭证**),
|
|
79
|
+
卡片能分辨「批量测出来的」与「真实流量告诉我的」。
|
|
80
|
+
- **卡片上的池区块**:成员表(草稿勾选框、状态点、当前计费徽标、在池标记、排除原因、
|
|
81
|
+
**通用积分**列并标注 Work 不可花、探针结论 + 相对时间 + 模型作用域、签到列只在支持的
|
|
82
|
+
面板出现、行内测速/移除)、幽灵成员(设置里存着但本机已无登录,仍渲染成可移除的行)、
|
|
83
|
+
「全部签到」与「全部测速」(NDJSON **逐行**返回,跑一个显示一个)、目标模型选择
|
|
84
|
+
(`''` = 自动挑免费模型;已下架的模型单独成一个选项并给「切回自动」按钮)、保存/放弃
|
|
85
|
+
草稿与未保存徽标、活动日志。
|
|
86
|
+
- **三条路由**:`POST /plugins/dsh-connect-trae/pool?action=checkin|test|remove`
|
|
87
|
+
(`test` 走 `application/x-ndjson`)。守卫:仅 POST(405)、仅环回来源(403)、池不可用
|
|
88
|
+
(503)、`action` 必须可解析(400)、`accountId` 必须是 24 位十六进制(400,且**在任何
|
|
89
|
+
写入或上游调用之前**校验——这个 id 会进文件名与凭证查找)、空池 409 区分 `no-members`
|
|
90
|
+
与 `no-live-members`、签到不支持的面板 409 `checkin-unsupported`(**在花掉一次只能失败
|
|
91
|
+
的请求之前**)。
|
|
92
|
+
|
|
93
|
+
### 修复
|
|
94
|
+
|
|
95
|
+
- **`checkinSupported` 按面板判定**:只有国内版有个人签到活动(国际版与企业版网关直接
|
|
96
|
+
404)。此前没有任何地方表达这件事,卡片只能靠「请求失败」来发现。
|
|
97
|
+
- **`toCredits` 补 `endpoint`**:Trae 的额度分 General(SOLO 聊天实际扣的)与 Work(够不到)
|
|
98
|
+
两个桶。池的排序与卡片显示统一用 **General**,此前只能拿到两桶之和——一个 Work 余额很
|
|
99
|
+
大、General 已空的账号会排在一个真能服务的账号前面。
|
|
100
|
+
|
|
101
|
+
### 测试
|
|
102
|
+
|
|
103
|
+
- 新增 **5 个文件 / 112 例**:`tests/account-pool.spec.ts`(56:排序全分支、出池规则、
|
|
104
|
+
冷却时钟、`billableMembers`、`resolveTargetModel` 的 stale 不给 id、批处理串行与流式、
|
|
105
|
+
9095 中止整批、落盘合并规则、`parseUpstreamResetAt` 无时区一律 undefined)、
|
|
106
|
+
`tests/account-pool-store.spec.ts`(20:往返/合并/按面板隔离/坏 JSON/版本不符/读时修补/
|
|
107
|
+
文件不含凭证/池文档组装与幽灵成员)、`tests/account-pool-route.spec.ts`(14:五种拒绝、
|
|
108
|
+
坏 id 时上游调用次数为 0、NDJSON 三行、409 两种空池、签到不支持时零次 claim)、
|
|
109
|
+
`tests/account-pool-failover.spec.ts`(12:轮转压倒绑定、清空恢复绑定、**refresh 落在被
|
|
110
|
+
轮转的账号上**、企业店拒绝个人轮转、shim 只在账号级失败换号、三次上限 + shortfall 文本、
|
|
111
|
+
池 hook 抛异常仍正常作答)、`tests/card-pool.spec.tsx`(10:草稿勾选→写 `regions`、
|
|
112
|
+
放弃还原、stale 目标、签到列按能力隐藏、NDJSON 增量渲染、幽灵成员可移除、**以及「区块里
|
|
113
|
+
每个 class 都真有样式规则」**——这条守卫此前只覆盖输入框读数,池区块曾在零 CSS 的情况下
|
|
114
|
+
通过全部行为断言)。
|
|
115
|
+
- 全仓 **823** 例通过(3.8.1 为 711)。
|
|
116
|
+
|
|
3
117
|
## 3.8.1 (2026-10-18)
|
|
4
118
|
|
|
5
119
|
> **signed-out 不再吞掉账号列表。** 2026-10-18 的现场报告是「本地突然刷不出账号了」:
|
package/README.md
CHANGED
|
@@ -36,12 +36,16 @@
|
|
|
36
36
|
- **企业版是独立计费通道,不是国内版的别名** —— 同一张 CN 凭据若属于 `tob_online` 租户,会被**两个**网关同时服务:消费池(扣个人积分)与租户池(扣企业额度)。同一模型、两种付费方,所以「谁付钱」由你显式选,插件不替你猜。`trae` 永不碰企业网关;`trae-enterprise` **不回落**,被拒绝就如实报错,不会悄悄改用个人额度重跑。企业版**默认关闭**——纯个人账号用不了企业池,默认放开等于塞一条一用就失败的 provider。
|
|
37
37
|
- **可单独关闭任一面板** —— 三个 tab 各带一个勾选(国内版与国际版默认勾选,企业版默认不勾):取消勾选即把该面板的供应商**整个从 DSH 模型选择器撤掉**(不是只藏起 tab),并且不再发起任何请求;重新勾选即恢复,账号、目录、勾选与上下文预算全部保留。用不到国际版就把国际版关掉即可。
|
|
38
38
|
- **插件卡片 tab 切换** —— 设置卡片顶部为「国内版 / 企业版 / 国际版」三个 tab,各含独立的账号选择、用量概览与模型管理;每个 tab 的账号、目录、勾选与未保存草稿完全隔离——在一个 tab 里切账号或刷新模型,不会触碰另一边的运行时目录与会话。国内版与企业版共用同一份 CN 凭据池,但**各有各的账号绑定与模型勾选**:两个池的名录并不相同(`DeepSeek-V4.1-Flash` 只有企业池列),所以勾选互不覆盖。
|
|
39
|
+
- **账号池:自动选号 + 失败换号(默认关闭)** —— 本机读完几个账号后,「该用谁的额度」可以交给插件按规则排序:**先排除不可用的**(凭据被拒、套餐不覆盖、账号已不存在、限流未到重试时间、额度耗尽),再在可用账号里**优先快到期的那点额度**(与其放着过期,不如先花掉),最后才比总额、token 新鲜度,并以账号 id 兜底成**全序**(同样的输入永远得到同样的顺序,不会在两行之间来回抖)。三个面板**各有各的池**:国内版与企业版共用同一份 CN 凭据,但企业版只挑租户账号、国内版不会漂到租户号上。开着池时,发请求前先按上面的顺序选中一个账号,并且**真实请求失败会换下一个账号重试(最多 3 个)**——只有账号级失败才换(`401` 凭据被拒、额度耗尽、限流、上游 5xx);模型 id 写错、请求本身不合法**不换号**,因为那不是账号的问题,换号只会把同一个错误烧两遍、还冤枉一个没机会服务的账号。换号失败的真相会写进池的探针记录,下一次排序直接把它排到后面,而每一次结论都能在卡片上看到:`可用` / `限流` / `额度耗尽` / `凭据被拒` / `套餐不覆盖` / `上游不提供` / `本次未测出`,以及「什么时候可以重试」。**关掉池就回到严格绑定**,不会有任何残留 override。卡片里的「全部测速」会把每个成员按目标模型各测一次,结果**边跑边显示**(一行一个答案,不等整批跑完),并落盘成下次排序的依据。
|
|
40
|
+
|
|
41
|
+
> 池是**显式选择**:默认关闭。它不会替你在没打开池的情况下换账号——「换账号等于换人计费」,所以这件事只能由你点头。池打开后卡片会明确写出**当前是谁在付费**(Host 报告的是「下一个真正发送请求的账号」,不是保存的那个绑定)。
|
|
42
|
+
|
|
39
43
|
- **倍率内嵌模型名** —— 模型名称按 Trae 自身菜单的格式显示积分倍率(如 `GLM-5.2 · x0.79`),倍率随目录刷新更新。
|
|
40
44
|
- **DSH 本地工具循环** —— 通过 Trae `llm_utils_chat` 获取待执行的结构化 `tool_calls`,交由 DSH 自带的本地工具执行,再将工具结果回传模型。
|
|
41
45
|
- **国内国际双区域自动识别** —— 自动发现 Trae CN / TRAE SOLO CN / Trae / TRAE SOLO 四个本地安装的登录账号;区域由凭证自带的 `userRegion` 声明自动判定(host 后缀与 edition 标签兜底),无需手动指定。
|
|
42
46
|
- **目录与勾选按面板隔离** —— 三个面板各一套模型目录、勾选、图片开关与上下文预算,各自读各自的槽位。名录从**该面板所钉的那条网关**读取——原本钉在企业池的客户端去读消费池名录,会永远发现不了自己池的独占模型。
|
|
43
47
|
- **识图能力跟随 Trae 自身的标注** —— Trae 把某个模型标为 `multimodal` 时,插件直接按多模态对外声明,无需你在卡片上逐一手勾(issue #16)。判据是「**你手动勾选的 ∪ Trae 标注多模态的**」:Trae 明确标 `false` 或未标注的模型保持纯文本,你可以照旧手动为它们打开图片输入。卡片上被自动开启的那一行显示为已勾选且只读,并说明原因。详见下方「图片输入(识图)」。
|
|
44
|
-
- **多账号切换** —— 支持重新读取 Token 列表并选择账号;Token 不写入 DSH
|
|
48
|
+
- **多账号切换** —— 支持重新读取 Token 列表并选择账号;Token 不写入 DSH 设置。**你的选择会被记住并长期生效**:插件不会因为某个账号额度用尽、或检测到另一个可用账号就自作主张替你切换(换账号意味着换人计费)——唯一的例外是你**亲自打开**的账号池(见下一条),那是一个显式选择,而不是插件的自作主张。所以当绑定的账号额度耗尽时,卡片会**明确告诉你**,并把本机其他还有额度的账号连同其可用积分数列出来,由你一键切换——而不是让面板一直空着、也不自动把你切走。「刷新账号与 Token」每次都会回报结果(找到几个账号、当前仍绑定谁),不会再「点了没反应」。下拉里显示的是产品名(`Trae` / `TRAE SOLO` / 国际版),便于分辨凭据来自哪个安装。
|
|
45
49
|
- **跟随 Trae 当前登录的账号** —— 你在 Trae 桌面端**退出并换登录**后,卡片会检测到「插件绑定的账号」与「Trae 现在登录的账号」不一致,并给出一行提示与**一键切换**(复用账号下拉的同一次写入,不引入第二条切换路径)。想让插件**自动跟随**,可打开设置卡片里的「跟随 Trae 当前登录的账号」开关:此后每次配置生效都会把 `accounts.<region>` 重绑到 App 当前登录的账号。**该开关默认关闭**——已有配置保持原来的严格绑定,自动换绑意味着换人计费,必须由你主动勾选;未勾选时上面那行提示就是你的手动通道。(issue #29)
|
|
46
50
|
- **账号导入 / 导出** —— 不用再为了用第二个账号而把凭据手工写进默认路径、顶掉上一个。在卡片账号区的「导入 / 导出账号」里:**导出**勾选若干账号下载一份 JSON;**导入**选择文件后先看**脱敏预览**(只显示账号标识与「是否有 Token」,不含凭据本身)再勾选导入。文件格式与同族 `dsh-connect-workbuddy` **互通**,两边导出的文件可以互相导入。导入按账号去重(同一账号再导入即覆盖更新),**认不出所属区域或因缺 Token 的记录会被跳过并计数**——国内版与国际版是两条并行计费通道,跨区导入会导致跨区计费,所以这里只认同能**正向识别**的区域(企业版共用 CN 凭据池,不构成第三条导入通道)。导出文件里是**有效 Token,请当作密码保管**。(issue #37)
|
|
47
51
|
- **只读用量与模型管理** —— 国内版查看 Work 积分与通用积分,国际版查看订阅/试用状态;刷新/启用 Trae 模型;只读查询不消耗额度。
|
|
@@ -49,7 +53,7 @@
|
|
|
49
53
|
- **一键测试启用模型** —— 给**已启用**的每个模型发一条最小消息(一句 `ping`、不带工具),逐个告诉你能不能真的应答:**可用** / **需要更高档位**(Trae `1005`,你的套餐不覆盖)/ **上游不提供**(`4001`,SOLO 通道没有这个模型)/ **被限流**(`4011`,Trae 限了这条通道)/ **登录凭据被拒** / **本次未测出**。最后一项是一等公民:超时、断连、代理、5xx **一律不算「不可用」**——只有上游明确的拒绝才算负面结论。**这是插件里唯一消耗额度的操作**(签到改变的是账号状态,不消耗),只在你点击时运行,结果只留在当前会话里不写入设置。
|
|
50
54
|
> `4011` 是**限流**不是「模型不可用」(issue #33 实测):它额度耗尽走的是另一个码 `4008`,所以「额度还有很多却报 4011」两句话可以同时成立。被限流的模型**等你一会儿再试**即可,不要删。
|
|
51
55
|
- **一键测试所有模型** —— 同一套探测,作用于当前 region 的**全部可见模型**(不限于已启用的)。想知道「没启用的那些到底还能不能用」时用它——比如套餐降级后,或 Trae 调整了模型阵容之后。
|
|
52
|
-
- **每日签到领取(逐账号)** —— 国内版**每个账号行各有一个签到按钮**,当日奖励直接写在按钮上(`签到 +150
|
|
56
|
+
- **每日签到领取(逐账号)** —— 国内版**每个账号行各有一个签到按钮**,当日奖励直接写在按钮上(`签到 +150`);该账号当天已领显示「已领取」并禁用,**本机今日名额已被别的账号用掉**时显示「本机已签」并禁用——如实区分「这个账号领了」和「这台设备领过了」,绝不把后者说成「已领取」。这是插件里**唯一会改变账号状态**的操作,由你主动点击触发;一次点击只针对该行账号、只发一次请求。Trae 的签到按「**每台设备每天一次**」计(换账号不会重置当天名额),所以逐账号签到始终是主路径。账号池里另有一个「全部签到」,它**不是**把同一件事盲目重复:一旦上游回 `9095`(本机今日已领),整批立刻停止并把剩余账号如实标成「本机已签」,产出的是真相而不是一排假失败。国际版没有签到活动,因此不显示该按钮。
|
|
53
57
|
- **输入框读数** —— 在输入框工具栏(「专家」与模型选择器之间)显示一块可点击读数,5 分钟自动刷新。**两个区域都显示,但显示的东西不同,这是数据决定的**:国内版是积分制,显示「Trae CN · <通用积分>」;国际版是订阅制,它的用量文档里根本没有积分字段,所以显示「Trae 国际版 · <套餐>」(如 `Pro` / `Free`)。**整块可点击**,弹出浮层显示一张**表格**:本区域**每个账号一行**,国内版列**通用积分**、国际版列**套餐**,**点行即可切换账号**(写入与卡片相同的 `accounts` 字段、合并时不丢掉另一个区域的选择),并把手动刷新按钮放在浮层里。**只在当前会话选中的模型属于本插件时出现**——选其它供应商的模型时整块不渲染。这样两个连接器插件不会争同一个位置(侧边栏底部是共享的根级行,输入框工具栏是按会话、按供应商的)。
|
|
54
58
|
|
|
55
59
|
<img src="docs/assets/dsh-connect-trae-composer-credits.png" width="536" alt="Trae credits panel: a table of accounts with their general balance, and the composer readout below" />
|