dsh-llm-adapters 1.2.1 → 1.2.2
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/DEVELOPMENT.md +66 -15
- package/FAQ.md +39 -8
- package/README.md +11 -10
- package/client.js +1802 -1822
- package/lib/index.js +181 -205
- package/lib/types/account-store.d.ts +10 -3
- package/lib/types/auth.d.ts +7 -0
- package/lib/types/codearts-oauth.d.ts +19 -0
- package/lib/types/codearts.d.ts +1 -5
- package/lib/types/config.d.ts +0 -5
- package/lib/types/index.d.ts +1 -4
- package/lib/types/raccoon.d.ts +79 -6
- package/package.json +1 -1
- package/src/account-store.ts +11 -3
- package/src/auth.ts +15 -1
- package/src/codearts-oauth.ts +36 -5
- package/src/codearts.ts +24 -29
- package/src/config.ts +258 -264
- package/src/index.ts +1 -26
- package/src/raccoon.ts +163 -50
- package/lib/types/codearts-window.d.ts +0 -65
- package/src/codearts-window.ts +0 -136
package/DEVELOPMENT.md
CHANGED
|
@@ -27,7 +27,6 @@ src/
|
|
|
27
27
|
codearts-sign.ts 华为 SDK-HMAC-SHA256 请求签名
|
|
28
28
|
codearts-endpoints.ts 网关基址、窗口静态表、benefit 与 VL 清单
|
|
29
29
|
codearts.ts CodeArts 双目录合并 / 签名流式调用 / 额度 / 签到
|
|
30
|
-
codearts-window.ts CodeArts 会话预算:每 60 秒 3 次的排队窗口
|
|
31
30
|
catalog.ts 目录解析、模型缓存、能力来源合并
|
|
32
31
|
model-name.ts 公共名称规则:括号标签、倍率、连字符归一化、匹配 key
|
|
33
32
|
openrouter.ts OpenRouter 模型表:原子同步、磁盘缓存、通配匹配档位与模态
|
|
@@ -209,8 +208,47 @@ SHA-512 摘要 + JSON。插件从解密结果取 `Cloud-IDE-JWT`,从
|
|
|
209
208
|
没有独立的签到端点:积分由服务端在当天首次网页访问时发放,`setting_info` 的
|
|
210
209
|
`point_grant_popups` 只是通知,`/points/v2/bills` 里 `biz_type=daily_grant` 的记录才是可核对的
|
|
211
210
|
凭据。插件只把 `grant_at` 属于今天(北京时间)的记录算作今日签到,并把 `created_at` 作为到账时间
|
|
212
|
-
|
|
213
|
-
`
|
|
211
|
+
显示;这条路径是**只读**的:`checkinStatus()` 只读 `/points/v2/bills`,卡片上的按钮是「检测今日积分」,
|
|
212
|
+
不实现 `claimCheckin()`。
|
|
213
|
+
|
|
214
|
+
上游确实存在一条能主动触发发放的路径——`POST /office/v3/setting_info` 就是网页当日首次加载时发的那个
|
|
215
|
+
请求,重放它即可让服务端下发积分。插件**刻意不做**这件事,两个原因:一是那是在用户没要求的那一刻替账号
|
|
216
|
+
做状态变更;二是 harness 每轮重发上下文的场景下,把「顺带触发一次网页访问」藏进「看一眼到账没有」里,
|
|
217
|
+
等于让观察动作带副作用。领取交给官网,「打开网页签到」链接始终保留。
|
|
218
|
+
|
|
219
|
+
自动监测同样不做:按间隔定时跑一遍意味着每个间隔都花掉一次真实请求(无论积分是否迟到),并且会在用户
|
|
220
|
+
不知情时消耗账号额度。没有 `raccoonCheckinMinutes` 这个配置项,也没有定时器。
|
|
221
|
+
|
|
222
|
+
### 小浣熊的吞吐墙与会话 id(`raccoon.ts`)
|
|
223
|
+
|
|
224
|
+
上游的 `user_model_rate_limited`(「您的模型请求频率超限」)不是 RPM,而是**账号级 token 吞吐**。
|
|
225
|
+
社区在真实账号上的对照测量:1 秒间隔连发 ~320KB body,前 10 条 200、第 11 条 429;50 条小请求
|
|
226
|
+
连发不撞;直连与走代理同样 429(不是出口 IP);假 token 打同一地址回 401(链路正常,封的是额度);
|
|
227
|
+
连续 429 达 122 秒后小请求立刻 200、紧接着一条大请求又 429(桶在回血,速率只够小请求)。
|
|
228
|
+
官方客户端在同一账号上 26 分钟 125 次调用、97 次间隔 ≤10 秒,**0 次 429** —— 频率假说因此被证伪。
|
|
229
|
+
|
|
230
|
+
恢复时间上游不给:429 报文里没有 `Retry-After`,也没有任何 `x-ratelimit-*`,只有
|
|
231
|
+
`server-timing: inner; dur=20`。所以**没有任何依据去算退避**,插件对这类失败不重试(在已超限的桶上
|
|
232
|
+
重发会继续吃掉回血额度,公众号召实测里那种「8 次退避白等 38 秒」是负收益)。两条路径统一给出可读
|
|
233
|
+
错误:HTTP 429 由 `openAiStream` 抛出,流内错误帧则由 `onFrame` 钩子识别——后者原本一律标 502,
|
|
234
|
+
会把这个限制伪装成插件故障。判定只在 HTTP 路径看状态码,避免把流内已归类的 502 二次包装。
|
|
235
|
+
|
|
236
|
+
官方与第三方的差异有两处,插件只做了其一:
|
|
237
|
+
|
|
238
|
+
1. **会话 id 稳定**(已做)。官方日志显示 125 次调用全程一个 `sess-0-53927d74`;每个请求新建会话
|
|
239
|
+
等于告诉上游「同一账号几分钟内开了上百个会话」。插件按「账号 + 模型」派生
|
|
240
|
+
`sess-0-<8 hex>`,摘要源自 JWT 的 `sub`(`decodeJwtFacts` 新增 `subject`),**纯函数**而非随机值 ——
|
|
241
|
+
用进程内计数器会让重启后的同一会话变成新会话,正是这个 id 要避免的事。账号身份只以截断摘要
|
|
242
|
+
出现,不上线;只有 chat 路由带这个头,目录/额度/签到等业务路由保持原样。
|
|
243
|
+
2. **补官方 `X-Stainless-*` / `X-RACCOON-*` 身份并伪装 UA**(**未做**)。社区方案会把 UA 改成
|
|
244
|
+
`AsyncOpenAI/Python 2.8.0` 并补齐十余个官方头,其作者自己也标注「补头即解限属推断、未复验」。
|
|
245
|
+
更重要的是这与 DSH 的归因策略冲突:`@deepseek-ai/dsh-llm` 的 `attributionHeaders()` 明确规定
|
|
246
|
+
每个 provider 请求都必须带产品身份、且「nothing can suppress attribution entirely」,
|
|
247
|
+
身份如需变更要走 `AppIdentity` 而不是逐请求硬改 UA。插件因此保留 DSH 自身 UA 与
|
|
248
|
+
`x-client-*` 头,不冒充官方客户端。
|
|
249
|
+
|
|
250
|
+
真正可控的杠杆是单轮上下文大小:harness 每轮全量重发上下文,所以窗口从 1M 降到 200K 会让单轮
|
|
251
|
+
prompt 成本降到约 1/5,会话存活时间相应变长。这是纯本地设置,不依赖上游行为。
|
|
214
252
|
|
|
215
253
|
### CodeArts(`codearts-login.ts` + `codearts.ts`)
|
|
216
254
|
|
|
@@ -258,8 +296,8 @@ IDE 自身 provider 配置的 `limit.context`(`codearts-endpoints.ts` 的静
|
|
|
258
296
|
4. 转述结果按 `sha256(data URL)` 缓存到 `$DSH_HOME/llm-adapters/codearts-image-cache.json`(最多
|
|
259
297
|
64 条,`tmp → rename` 原子写)。同一张图在后续轮次、甚至重启后都直接复用,不再占会话额度。
|
|
260
298
|
|
|
261
|
-
每张**新**图是一次独立的 chat
|
|
262
|
-
|
|
299
|
+
每张**新**图是一次独立的 chat 请求,但它和主请求共用同一个会话(同一个 `x-ot-session-id`),所以
|
|
300
|
+
不再额外占一个名额;`describeImage` 只在 `TM.00001041` 时退避重试。`hasImageParts` 先做一次纯内存检查,
|
|
263
301
|
没有图片的请求完全不碰缓存文件。
|
|
264
302
|
|
|
265
303
|
思考只有两档:`off` / `on`。网关切的是**顶层** `thinking: { type: 'disabled' }`,不是
|
|
@@ -294,18 +332,31 @@ IDE 自身 provider 配置的 `limit.context`(`codearts-endpoints.ts` 的静
|
|
|
294
332
|
`wire.ts` 的 SSE 消费被拆成 `consumeOpenAiStream`:CodeArts 要自己签名 fetch,但帧处理与
|
|
295
333
|
`openAiStream` 完全相同;`onFrame` 钩子用来抓「HTTP 200 + SSE 内嵌 `error_code`」的排队/额度错误。
|
|
296
334
|
|
|
297
|
-
### CodeArts
|
|
335
|
+
### CodeArts 的会话计数键(`x-ot-session-id`)
|
|
298
336
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
113.2 + 60)。反过来说,`InferHub.4004.200`(缺 benefit 包)是**会**占额度的,所以那条路径靠
|
|
303
|
-
`noBenefit` 记住结论,而不是每次重猜。
|
|
337
|
+
体验版按账号限制的是**并发会话**,不是每分钟请求数:3 个名额,一个会话在请求结束后仍占位约 60 秒。
|
|
338
|
+
决定占哪个名额的是 `x-ot-session-id`,不是 `chat-id` / `session-id` / `prompt_cache_key`(后三者只管
|
|
339
|
+
前缀缓存亲和)。实网对照,同一账号、同一个 `glm-5.3-flash`、每条 `max_tokens: 16`,臂间排空 78 秒:
|
|
304
340
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
341
|
+
| 会话头 | 6 条串行 | 3 条并发 | 12 条串行 |
|
|
342
|
+
| --- | --- | --- | --- |
|
|
343
|
+
| 不发(每请求一个新会话) | 3 成功 + 3 × `TM.00001041` | — | — |
|
|
344
|
+
| 账号级稳定值 | 6/6,共 15.8 秒 | 3/3,1.5–1.7 秒 | 12/12,一条不排队 |
|
|
345
|
+
|
|
346
|
+
「复用 id 挡不住撞线」的旧结论测的是 `session-id`,与这里不冲突;早期那个 3 次/60 秒的排队窗口
|
|
347
|
+
(`codearts-window.ts`)也因此删掉了——留着它,插件自己就还在按分钟限自己。
|
|
348
|
+
|
|
349
|
+
这个值是**派生**的,不是随机生成的:对 refresh token 里的 `principal_id`(缺身份时退到
|
|
350
|
+
`account_name`)加固定前缀做 SHA-256,取 32 位 hex。好处是同一个账号在任何进程、任何一次续期之后
|
|
351
|
+
都是同一个值,老记录不用重新登录也能补上;解析出来的那份同时存进 `accounts.json`(`otSessionId`,
|
|
352
|
+
续期写回时保留)。令牌里解不出身份时退到本进程的 id——仍然是一个会话,不会退回每请求一个会话。
|
|
353
|
+
|
|
354
|
+
这不是绕过计费:稳定会话与逐请求新会话两条臂的计量完全一致(每条 944 token、0.12 积分,SSE 长度也
|
|
355
|
+
一样),上游的 token 计数器同步增长。这一点和「非流式请求返回 token 却不扣分」不同——后者是计费漏洞,
|
|
356
|
+
不采用。上游也没有释放会话的接口(`/api/v2/chat/stop`、`/session/close`、`/sessions` 实测全部 404),
|
|
357
|
+
所以被 `TM.00001041` 拒绝时只有退避重试(`QUEUE_ATTEMPTS` × `QUEUE_BACKOFF_MS`),用尽后给可读错误。
|
|
358
|
+
带 `maas_type: benefit` 的失败(`InferHub.4004.200`)在过去每请求一会话的口径下确实各占一个名额,
|
|
359
|
+
现在共用一个会话,但结论仍由 `noBenefit` 记住:没人该为一场注定失败的请求付一整轮时间。
|
|
309
360
|
|
|
310
361
|
### 公共的名称与能力规则
|
|
311
362
|
|
package/FAQ.md
CHANGED
|
@@ -78,6 +78,25 @@ Trae 共用这套规则。默认选**最强**的一档(强度顺序
|
|
|
78
78
|
插件不缓存 SSE,收到一块就转发一块。实测同一账号直连小浣熊的首字在 1–50 秒间波动,主要是
|
|
79
79
|
上游排队;关闭思考可以减少生成阶段的等待,但不能消除排队时间。
|
|
80
80
|
|
|
81
|
+
**小浣熊聊久了报 `user_model_rate_limited`(「您的模型请求频率超限」)?**
|
|
82
|
+
|
|
83
|
+
这条文案有误导:它说的不是每分钟请求数,而是**按账号的 token 吞吐**。社区实测可以佐证:
|
|
84
|
+
1 秒间隔连发大 body 的请求,前 10 条全 200、第 11 条被拒;而 50 条小请求连发不撞。同一账号在
|
|
85
|
+
官方客户端上 26 分钟跑了 125 次调用、其中 97 次间隔不超过 10 秒,一次都没被限流。所以
|
|
86
|
+
「频率」不是瓶颈,**单位时间灌进去的 token 量**才是。
|
|
87
|
+
|
|
88
|
+
撞上之后桶按吞吐缓慢回血,恢复是分钟级的;上游既不给 `Retry-After`,也不给任何
|
|
89
|
+
`x-ratelimit-*` 头,所以插件算不出「等多久」。插件也**不会**拿这事重试——在已经超限的桶上重发只会在
|
|
90
|
+
回血额度里继续加压、把恢复时间往后推。你看到的是一条说明了原因的错误,而不是裸的 429。
|
|
91
|
+
|
|
92
|
+
能自己动手的地方只有一个:**把该模型的上下文窗口调小**。一轮对话会把整段上下文全量重发,
|
|
93
|
+
窗口从 100 万降到 20 万,单轮成本降到约 1/5,同一会话的存活时间就相应变长。这是纯本地设置,
|
|
94
|
+
不依赖上游任何行为。
|
|
95
|
+
|
|
96
|
+
插件另外给每个「账号 + 模型」发一个稳定的会话 id(`x-raccoon-session-id`,形态对齐官方客户端的
|
|
97
|
+
`sess-0-xxxxxxxx`,由账号身份摘要而来、不含账号本身):官方客户端全程复用一个会话,而每请求新建
|
|
98
|
+
会话会被上游看成「同一账号在几分钟内开了上百个会话」。这一项有依据但尚未在本机实测到撞墙量级验证。
|
|
99
|
+
|
|
81
100
|
**额度读取失败会影响对话吗?**
|
|
82
101
|
不会。额度与模型目录是独立的读取;额度失败时卡片保留账号信息并显示原因,对话仍可用。
|
|
83
102
|
|
|
@@ -257,6 +276,17 @@ STS 令牌本来就只有两小时,插件在到期前 5 分钟用续期令牌
|
|
|
257
276
|
(可用 / 永久 / 每日)和小浣熊(剩余积分)只报剩余额度,画进度条就得凭空补一个分母,因此仍然
|
|
258
277
|
只显示数字。
|
|
259
278
|
|
|
279
|
+
**小浣熊的每日积分怎么领?**
|
|
280
|
+
|
|
281
|
+
插件**只检测、不领取**。上游没有独立的签到端点:积分由服务端在当天首次打开网页时发放,插件读
|
|
282
|
+
`/points/v2/bills` 里 `biz_type=daily_grant`、`grant_at` 属于今天的记录来判断到账没有,并在到账时
|
|
283
|
+
显示具体时间。卡片上的按钮因此是「检测今日积分」,不是「签到领积分」。
|
|
284
|
+
|
|
285
|
+
要领取就点「打开网页签到」到官网(该链接始终保留)。上游确实有一条能主动触发发放的路径——网页当日
|
|
286
|
+
首次加载发的 `setting_info`——但插件刻意不重放它:那是在你没要求的那一刻替账号做状态变更,而且会把
|
|
287
|
+
「看一眼到账没有」变成带副作用的动作。插件也**没有**自动监测:定时按间隔跑一遍意味着每个间隔都花掉
|
|
288
|
+
一次真实请求,无论积分是否迟到。
|
|
289
|
+
|
|
260
290
|
**CodeArts 有签到吗?**
|
|
261
291
|
|
|
262
292
|
有,但只对**积分计费账户**开放:插件先读账户类型,再查活动列表里的 `USER_LOGIN`,可领取时才
|
|
@@ -272,15 +302,16 @@ STS 令牌本来就只有两小时,插件在到期前 5 分钟用续期令牌
|
|
|
272
302
|
|
|
273
303
|
**CodeArts 报 `TM.00001041 并发会话数已达上限(3个)`?**
|
|
274
304
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
305
|
+
体验版按**账号**限制并发会话:3 个名额,一个会话在请求结束后还占位约 60 秒。网关是按
|
|
306
|
+
`x-ot-session-id` 这个头区分会话的,不是 `chat-id` / `session-id`,所以插件用一个从账号身份派生的
|
|
307
|
+
固定值——所有轮次共用一个会话,不会再被自己的历史请求挤掉名额。实网对照:同一个账号同一个模型,
|
|
308
|
+
不发这个头时串行第 4 条起全部被拒、约 60 秒后整批恢复;发稳定值后 6 连发、12 连发、6 条真并发
|
|
309
|
+
全部成功。计量不受影响(两条路径都是每条 944 token / 0.12 积分)。
|
|
278
310
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
在抢同一份额度),3 次重试后会给出可读的错误而不是原始错误码。
|
|
311
|
+
如果还在报这一条,说明 3 个名额被**别的东西**占着:同一账号的码道 IDE 或网页版、另一台设备,或另一个
|
|
312
|
+
用同一份凭据的插件。关掉其它会话,或等约一分钟让名额自己过期。插件会先退避重试 3 次,再给出这条
|
|
313
|
+
可读提示,而不是原始错误码。上游没有「关闭会话」的接口(`/api/v2/chat/stop`、`/session/close`、
|
|
314
|
+
`/sessions` 实测全部 404),所以没有主动释放名额这条路。
|
|
284
315
|
|
|
285
316
|
**Trae 模型列表为什么和客户端对不上?**
|
|
286
317
|
插件只列出 Trae 客户端当前聊天选择器的主通道模型(`solo_work_remote` / `solo_work_lite`),
|
package/README.md
CHANGED
|
@@ -80,11 +80,10 @@ CodeArts 走华为云 OAuth:浏览器里授权后,宿主拿到 AK/SK 与 STS
|
|
|
80
80
|
|
|
81
81
|
- **登录卡**:显示账号、到期时间、登录方式与额度;未登录时可发起登录,登录中可取消,也可退出登录。
|
|
82
82
|
Trae 的卡片顶部是区域切换(国内版 / 国际版),并提供网页登录与复用本机客户端两种方式;
|
|
83
|
-
Trae
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
插件页还可设置自动监测间隔(关闭 / 15 分钟 / 30 分钟 / 1 小时 / 2 小时),关闭后只保留手动入口。
|
|
83
|
+
Trae 国内版(仅客户端登录态)与 CodeArts 有「签到领积分」按钮;签到状态按
|
|
84
|
+
「今日已签到」(账号)与「本机今日已签到」(设备)分别显示。小浣熊**只检测、不领取**:插件读积分
|
|
85
|
+
流水里的 `daily_grant`(只认今天的记录),到账时显示具体到账时间,按钮是「检测今日积分」;积分由
|
|
86
|
+
服务端在当天首次打开网页时发放,领取请走「打开网页签到」(该链接无论是否到账都始终保留)。
|
|
88
87
|
- **Trae 本机客户端登录**:检测到本机安装了 Trae CN / 国际版客户端时,登录卡会显示客户端账号与
|
|
89
88
|
「复用客户端登录态」。插件只读 `User/globalStorage/storage.json` 里的加密登录态并在本机解密,
|
|
90
89
|
不修改客户端,也不把令牌返回给页面;网页登录与客户端登录可以随时切换,退出插件登录不会退出
|
|
@@ -111,16 +110,18 @@ CodeArts 走华为云 OAuth:浏览器里授权后,宿主拿到 AK/SK 与 STS
|
|
|
111
110
|
也可点「立即同步」。快照保存在本机,下载并解析完整成功后才原子替换;失败时继续使用上次成功
|
|
112
111
|
的数据,刷新模型列表不会清空它。一次网络抖动或上游 429/5xx 会自动重试一次,客户端标识也随
|
|
113
112
|
请求发送,避免被 CDN 当作匿名脚本限流。
|
|
114
|
-
-
|
|
115
|
-
|
|
116
|
-
|
|
113
|
+
- **小浣熊每日积分(只检测)**:卡片上的按钮是「检测今日积分」,只读今日流水并把到账时间显示出来。
|
|
114
|
+
插件不替你领取——积分由服务端在当天首次打开网页时发放,要领取请点「打开网页签到」。既没有自动
|
|
115
|
+
监测项(定时轮询每个间隔都要花一次真实请求),也不会把网页访问调用(`setting_info`)当成副作用发出去。
|
|
117
116
|
- **CodeArts 的模型清单**:合并两个端点(免费额度模型与常规模型),窗口表里没有的模型回退到
|
|
118
117
|
当前目录最小的真实窗口;签到只在积分计费账户上可用。所有模型都接收图片:`kimi-k2.6-vl` 与
|
|
119
118
|
`Qwen3-VL-235B` 直接读图,其余模型(含 DeepSeek、GLM、openpangu)先用 VL 模型转述成文字再回答;
|
|
120
119
|
转述结果按图片内容缓存,同一张图只在第一次多花一次对话。模型清单里的「读图」只标注这两个**原生**
|
|
121
120
|
多模态模型,转述能力写在列表下方的一句提示里。
|
|
122
|
-
- **CodeArts
|
|
123
|
-
|
|
121
|
+
- **CodeArts 的会话预算**:体验版按账号只允许 3 个**并发会话**,一个会话在请求结束后仍占位约 60 秒。
|
|
122
|
+
网关按 `x-ot-session-id` 这个头区分会话(不是 `chat-id` / `session-id`),插件因此用一个从账号身份
|
|
123
|
+
派生的固定值:所有轮次共用一个会话,连续对话不会被自己的历史请求挤掉名额。真被别处占满时(例如同时
|
|
124
|
+
开着码道 IDE),3 次退避重试后给出可读提示。
|
|
124
125
|
- **高级设置**:分组名称、强制识图 / 纯文本模型、模型别名、默认输出上限。
|
|
125
126
|
- **供应商开关**:在插件管理页关闭某个供应商后,它的设置页、模型分组与 provider 路由一起移除。
|
|
126
127
|
|