dsh-connect-doubao 0.6.0 → 0.6.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 +78 -0
- package/README.en.md +13 -6
- package/README.md +47 -35
- package/lib/cli-doctor.d.ts +1 -1
- package/lib/cli-doctor.js +2 -2
- package/lib/cli-probe.js +1 -1
- package/lib/client.js +58 -12
- package/lib/{doubao-quota-CAdK_fAm.js → doubao-quota-oVRIAATg.js} +65 -7
- package/lib/{doubao-status-gcSuFOQg.js → doubao-status-Dm-JiTV6.js} +407 -245
- package/lib/{doubao-upstream-CAg0AS4T.d.ts → doubao-upstream-DvtS4CgR.d.ts} +54 -4
- package/lib/index.d.ts +30 -2
- package/lib/index.js +3 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,84 @@
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
## 0.6.1 — 2026-11-12
|
|
8
|
+
|
|
9
|
+
> 这一版把「模型清单」从一张硬编码表,改成照抄豆包客户端菜单:有什么模型、各自多少倍率、
|
|
10
|
+
> 各自支持哪几档思考强度,全部实时读出来。三处缺陷叠在一起,任何一处单修都看不出效果。
|
|
11
|
+
|
|
12
|
+
### 修复
|
|
13
|
+
|
|
14
|
+
- **清单读错了缓存目录** —— `CACHE_DB_DIRS` 只列了 `chrome_doubao-launcher_0`,该库最后
|
|
15
|
+
一次写入是 2026-09-17,插件于是永远只看到 `0/3/4/5/9` 五条,而客户端菜单早已列出十二条。
|
|
16
|
+
现在优先读 `Default/Preferences` 里的 `saman.local_storage_for_web['frontend-request-cache']`
|
|
17
|
+
(应用每次刷新菜单都会重写,是唯一还保持最新的源),IndexedDB 退为兜底,并补上
|
|
18
|
+
`chrome_doubao-chat_0`。
|
|
19
|
+
- **键名校验卡掉了新模型** —— `looksLikeModelKey` 原为 `/^[\w-]{1,24}$/`,而第三方模型键长
|
|
20
|
+
27–37(`person-kimi-k3-1-pro-highspeed-261111` 是 37 字符),于是 Kimi 高速 / GLM Flash /
|
|
21
|
+
DeepSeek V4 系列被逐条丢弃。改为按形状校验、长度上限 64。
|
|
22
|
+
- **刷新按钮其实不刷新** —— 卡片的「刷新」发的是 GET,而清 memo 的分支挂在 POST 上,于是它把
|
|
23
|
+
十分钟前的 memo 原样又画了一遍。改为 POST(带 `x-dsh-doubao-write` 头),现在点一次就真重读。
|
|
24
|
+
- **极高 / 最高 根本发不出去** —— shim 的 `toDoubaoLevel` 只认 low/mid/high,序号 6 和 7 被静默
|
|
25
|
+
夹到「高」,DeepSeek / Kimi / 2.1 Max 的上半档等于不存在。现在 6/7 直通。
|
|
26
|
+
- **档位顺序被排序打乱** —— 「自动」声明的是 低(3) / 中(8) / 高(5),按数值排序会把「高」排成
|
|
27
|
+
中间档、8 排成最强档。改为保留菜单顺序。
|
|
28
|
+
- **非标准档位被吞掉** —— `findReasoningLevel` 以前只认三个名字,序号 8 会退回「高」;现在未知
|
|
29
|
+
序号原样透传成一个临时档位,不会把用户选的那个换掉。
|
|
30
|
+
|
|
31
|
+
### 新增
|
|
32
|
+
|
|
33
|
+
- **倍率 / 优惠标签** —— 读客户端菜单的 `tag_list` 原样显示:`0.65x`、`0.46x` 这类是倍率,
|
|
34
|
+
`限时优惠 0.01x`、`小额免费` 这类是活动标签(描边样式区分,避免活动价被当成常价)。
|
|
35
|
+
卡片同时注明「倍率来自客户端菜单,本插件不参与计费,也无法核对实际扣费」。
|
|
36
|
+
- **每个模型自己的思考档位** —— 菜单的 `reasoning_effort_config.option_list` 是逐模型的,而且
|
|
37
|
+
不统一:GLM 只有 低/高/最高(3/5/7),2.1 Lite 是 低/中/高(3/4/5)。以前统一用目录里那三档,
|
|
38
|
+
等于对 GLM 承诺了一个它没开的「中」。现在按模型自己的阶梯渲染,`thinkingLevelMap` 也据此生成。
|
|
39
|
+
- **档位验证标记** —— 实测过的档位(3/4/5)实线;只在菜单里声明、还没在真实请求中验证的
|
|
40
|
+
(6 极高 / 7 最高)虚线,tooltip 里写明。
|
|
41
|
+
|
|
42
|
+
### 其它
|
|
43
|
+
|
|
44
|
+
- 新模型按 `default_mode` 归入对应模式:`mode_id: "3"` 的第三方模型走「工作任务」
|
|
45
|
+
(`agent_mode 1` / `conversation_mode 2` / `need_deep_think 10001`),不会被当成普通对话。
|
|
46
|
+
- `findDoubaoModel` 对未见过的键改为原样透传,新增 `isKnownModelId` 区分「没有显示名」与
|
|
47
|
+
「不存在」——否则新模型会被静默换成豆包快速。
|
|
48
|
+
- `toPiModel` 的 `thinkingLevelMap` 按模型阶梯生成:`xhigh` / `max` 只在模型真有这两档时给出
|
|
49
|
+
映射,否则为 `null`(pi-ai 把 `null` 读成「不提供」,而不是夹到相邻档)。
|
|
50
|
+
- 卡片里的 `requested_model` 优先显示客户端原名。
|
|
51
|
+
- 新增回归测试:长 `person-*` 键必须能解析、超长与含空格的键必须被拒、6/7 档位、未知序号透传、
|
|
52
|
+
逐模型阶梯、倍率原样保留。
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## 0.6.0 — 2026-11-11
|
|
57
|
+
|
|
58
|
+
> 模型清单从「只认五个老模型」修成「客户端菜单有什么就显示什么」。三处缺陷叠在一起,
|
|
59
|
+
> 任何一处单修都看不出效果。
|
|
60
|
+
|
|
61
|
+
### 修复
|
|
62
|
+
|
|
63
|
+
- **清单读错了缓存目录**:`CACHE_DB_DIRS` 只列了 `chrome_doubao-launcher_0`,该库最后一次
|
|
64
|
+
写入是 2026-09-17,插件于是永远只看到 `0/3/4/5/9` 五条,而客户端菜单早已列出十二条。
|
|
65
|
+
现在优先读 `Default/Preferences` 里的 `saman.local_storage_for_web['frontend-request-cache']`
|
|
66
|
+
(应用每次刷新菜单都会重写,是唯一还保持最新的源),IndexedDB 退为兜底,并补上
|
|
67
|
+
`chrome_doubao-chat_0`。
|
|
68
|
+
- **键名校验卡掉了新模型**:`looksLikeModelKey` 原为 `/^[\w-]{1,24}$/`,而第三方模型键长
|
|
69
|
+
27–37(`person-kimi-k3-1-pro-highspeed-261111` 37 字符),于是 Kimi 高速 / GLM Flash /
|
|
70
|
+
DeepSeek V4 系列被逐条丢弃。改为按形状校验、长度上限 64。
|
|
71
|
+
- **刷新按钮其实不刷新**:卡片的「刷新」发的是 GET,而清 memo 的分支挂在 POST 上,
|
|
72
|
+
于是它把十年前的 memo 原样又画了一遍。改为 POST(带 `x-dsh-doubao-write`),
|
|
73
|
+
现在点一次就真重读缓存。
|
|
74
|
+
|
|
75
|
+
### 其它
|
|
76
|
+
|
|
77
|
+
- 新模型按 `default_mode` 归入对应模式:`mode_id: "3"` 的第三方模型走「工作任务」
|
|
78
|
+
(`agent_mode 1` / `conversation_mode 2` / `need_deep_think 10001`),不会被当成普通对话。
|
|
79
|
+
- `findDoubaoModel` 对未见过的键改为原样透传 + `isKnownModelId` 区分「没名字」与「不存在」,
|
|
80
|
+
否则新模型会被静默换成豆包快速。
|
|
81
|
+
- 卡片里的 `requested_model` 优先显示客户端原名。
|
|
82
|
+
- 新增回归测试:长 `person-*` 键必须能解析、超长与含空格的键必须被拒。
|
|
83
|
+
|
|
84
|
+
---
|
|
7
85
|
## 0.6.0 — 2026-11-11
|
|
8
86
|
|
|
9
87
|
> 生图这条路从「能出图」修到「在对话框里直接看到对的图」。三处都是实测出来的,不是推断。
|
package/README.en.md
CHANGED
|
@@ -39,12 +39,19 @@ With no session the plugin fails loudly ("还没有浏览器登录态…") rathe
|
|
|
39
39
|
|
|
40
40
|
## Features
|
|
41
41
|
|
|
42
|
-
- **
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
- **
|
|
47
|
-
`
|
|
42
|
+
- **The model list is the client's own menu, not a hardcoded table** — the plugin reads
|
|
43
|
+
`Default/Preferences` → `saman.local_storage_for_web['frontend-request-cache']`, so new
|
|
44
|
+
models, new prices and new level ladders appear without a plugin release. Measured
|
|
45
|
+
2026-11-12: 12 models (2 对话-mode, 9 「工作任务」-mode, 1 alias) plus the image alias.
|
|
46
|
+
- **Billing multipliers, verbatim** — the menu's `tag_list` is shown unchanged: `0.65x`,
|
|
47
|
+
`0.46x` etc. as plain multipliers, `限时优惠 0.01x` / `小额免费` as campaign tags (outlined
|
|
48
|
+
so a promo cannot read as the standing price). Display only: the plugin does not bill
|
|
49
|
+
and cannot verify the actual charge.
|
|
50
|
+
- **Per-model thinking ladders** — `reasoning_effort_config.option_list` is per model and
|
|
51
|
+
not uniform: GLM publishes 低/高/最高 (3/5/7), 2.1 Lite 低/中/高 (3/4/5), and Auto even puts
|
|
52
|
+
「中」 on ordinal **8**. The picker and `thinkingLevelMap` are built from that ladder, so
|
|
53
|
+
no level is offered that a model has no answer for. Solid chip = measured on a real
|
|
54
|
+
request (3/4/5); dotted = declared by the menu only (6 极高 / 7 最高).
|
|
48
55
|
- **Deep thinking on by default** — no extra switch: non-task models send
|
|
49
56
|
`need_deep_think: 3` on every turn, task models keep the captured `10001`. Set
|
|
50
57
|
`DSH_DOUBAO_DEEP_THINK=0` to turn it back off.
|
package/README.md
CHANGED
|
@@ -93,58 +93,70 @@
|
|
|
93
93
|
|
|
94
94
|
## 模型目录
|
|
95
95
|
|
|
96
|
-
|
|
96
|
+
**清单不是硬编码的,是照抄豆包客户端菜单。** 客户端每次刷新菜单都会把它写进
|
|
97
|
+
`Default/Preferences` 的 `saman.local_storage_for_web['frontend-request-cache']`
|
|
98
|
+
(`_DesktopActionBarBriefListRequestCacheDataV1.data.modeSelectData`),插件读这里,
|
|
99
|
+
所以豆包上新模型、调价、改档位都会自动出现,不需要等插件发版。IndexedDB 只在 Preferences
|
|
100
|
+
尚未写入时兜底。
|
|
97
101
|
|
|
98
|
-
|
|
99
|
-
| --- | --- |
|
|
100
|
-
| 对话 | 豆包 快速(`0`)、豆包 2.1 Turbo「专家」(`3`) |
|
|
101
|
-
| 工作任务 | 自动(`9`)、2.1 Lite(`seed-lite-7b`)、2.1 Pro(`5`)、Turbo(`3`) |
|
|
102
|
-
|
|
103
|
-
**本插件提供这两组里的五条**(外加生图别名):
|
|
102
|
+
豆包把模型按**模式**分组(`default_mode`:`1` = 对话,`3` = 工作任务)。当前这台机器读到的:
|
|
104
103
|
|
|
105
|
-
|
|
|
104
|
+
| 名称 | `model_item_key` | 模式 | 倍率标签 | 思考档位 |
|
|
106
105
|
| --- | --- | --- | --- | --- |
|
|
107
|
-
| `0` |
|
|
108
|
-
|
|
|
109
|
-
|
|
|
110
|
-
| `
|
|
111
|
-
| `
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
`
|
|
116
|
-
|
|
106
|
+
| 豆包 快速 | `0` | 对话 | — | 不可推理 |
|
|
107
|
+
| 豆包 2.1 Turbo | `3` | 对话 | — | 低 / 中 / 高 |
|
|
108
|
+
| 豆包 2.1 Pro | `5` | 工作任务 | 0.65x | 低 / 中 / 高 |
|
|
109
|
+
| 自动 | `9` | 工作任务 | 小额免费 | 低 / 中(8) / 高 |
|
|
110
|
+
| 豆包 2.1 Lite | `seed-lite-7b` | 工作任务 | 限时优惠 0.01x | 低 / 中 / 高 |
|
|
111
|
+
| DeepSeek V4 Pro | `person-deepseek-v4-pro-ga-260813` | 工作任务 | 0.46x | 低 / 中 / 高 / 极高 / 最高 |
|
|
112
|
+
| DeepSeek V4.1 Flash | `person-deepseek-v4-1-flash-261017` | 工作任务 | 限时优惠 0.01x | 低 / 中 / 高 / 极高 / 最高 |
|
|
113
|
+
| Kimi K3 | `person-kimi-k3-261111` | 工作任务 | 1.48x | 低 / 中 / 高 / 极高 / 最高 |
|
|
114
|
+
| Kimi K3.1 Pro | `person-kimi-k3-1-pro-261111` | 工作任务 | 0.95x | 低 / 中 / 高 / 极高 / 最高 |
|
|
115
|
+
| Kimi K3.1 Pro 高速 | `person-kimi-k3-1-pro-highspeed-261111` | 工作任务 | 1.44x | 低 / 中 / 高 / 极高 / 最高 |
|
|
116
|
+
| GLM 5.3 | `person-glm-5-3-261111` | 工作任务 | 0.80x | 低 / 高 / 最高 |
|
|
117
|
+
| GLM 5.3 Flash | `person-glm-5-3-flash-261111` | 工作任务 | 0.08x | 低 / 高 / 最高 |
|
|
118
|
+
| 豆包 生图(Seedream 5.5) | `image-gen` | 别名 | — | 低 / 中 / 高 |
|
|
119
|
+
|
|
120
|
+
> **倍率是客户端菜单的原始文本,只作展示。** 本插件不参与计费,也无法核对实际扣费;
|
|
121
|
+
> `限时优惠 0.01x` / `小额免费` 是活动标签,卡片上用描边样式与常价区分。
|
|
122
|
+
> 这份表会随客户端菜单变化,以上是 2026-11-12 实测结果。
|
|
123
|
+
|
|
124
|
+
**思考档位是逐模型的,不是统一三档。** 菜单的 `reasoning_effort_config.option_list` 每个模型
|
|
125
|
+
各写一份:GLM 只有 低/高/最高(3/5/7),2.1 Lite 是 低/中/高(3/4/5),「自动」甚至把「中」写在
|
|
126
|
+
序号 8 上(所以档位顺序按菜单原序保留,不能按数值排序)。插件按模型自己的阶梯渲染并生成
|
|
127
|
+
`thinkingLevelMap`;**实线 = 已在真实请求中验证(3/4/5),虚线 = 仅菜单声明(6 极高 / 7 最高)**。
|
|
128
|
+
|
|
129
|
+
**「工作任务」模型为什么能用。** 执行侧本来是豆包客户端进程内的 CUA 运行时(`tasks-mode-resource`
|
|
130
|
+
+ `sbox`),外部客户端注册不进去,每一轮必然 `710010702`。但 CUA 进程并非必需——服务端真正等的只是
|
|
131
|
+
三条 HTTP 应答:
|
|
117
132
|
|
|
118
133
|
```
|
|
119
|
-
POST /alice/office/tool_local/msg/ack
|
|
120
|
-
POST /alice/office/tool_local/upload_command_result
|
|
121
|
-
POST /alice/office/tool_local/msg/complete
|
|
134
|
+
POST /alice/office/tool_local/msg/ack # 轮询本地指令
|
|
135
|
+
POST /alice/office/tool_local/upload_command_result # 回传执行结果
|
|
136
|
+
POST /alice/office/tool_local/msg/complete # 标记该指令完成
|
|
122
137
|
```
|
|
123
138
|
|
|
124
|
-
服务端按 `${unique_key}:${device_id}:${aid}:message:${seq}`
|
|
125
|
-
`command: 6003`(`cmd_call
|
|
126
|
-
`
|
|
127
|
-
把这些走完,于是任务回合不再落到 `710010702`。**实测 2026-11-05 跑通,Lite 与 Pro
|
|
128
|
-
各一次纯文本回合。**
|
|
139
|
+
服务端按 `${unique_key}:${device_id}:${aid}:message:${seq}` 顺序下发(`seq = 0,1,2,…`):
|
|
140
|
+
`command: 6003`(`cmd_call`)需回传结果,`command: 6004`(`agent_finished`)表示本轮结束。
|
|
141
|
+
插件在流式生成期间并发跑应答器把这些走完,于是任务回合不再落到 `710010702`。**实测 2026-11-05 通过。**
|
|
129
142
|
|
|
130
143
|
> ⚠️ **`msg/ack` 必须单条查询。** `{ msg_ids: [0,1,2,3,4,5,6] }` 会整体失败并返回
|
|
131
|
-
> `{"code":710010702,"msg":"系统错误"}
|
|
132
|
-
>
|
|
133
|
-
|
|
134
|
-
**推理强度**:低 = `3`、中 = `4`、高 = `5`(由客户端切换档位时重新序列化的配置 diff 读出,
|
|
135
|
-
并由配置里的 `reasoning_effort_config` 独立确认)。
|
|
144
|
+
> `{"code":710010702,"msg":"系统错误"}`——批里只要含一个服务端尚未生成的 `seq`,整批就废。
|
|
145
|
+
> 这是逆向时最容易踩的坑,`tests/` 里没有钉它(需要真实上游才能复现)。
|
|
136
146
|
|
|
137
|
-
**深度思考开关默认打开**(2026-11-07
|
|
147
|
+
**深度思考开关默认打开**(2026-11-07 起):非「工作任务」模型每轮发 `need_deep_think: 3` 与
|
|
138
148
|
`ext.use_deep_think: "3"`;「工作任务」模型(2.1 Lite / Pro / 自动)沿用官方客户端抓到的真实
|
|
139
|
-
形态 `10001`。设 `DSH_DOUBAO_DEEP_THINK=0`
|
|
140
|
-
`reasoning_effort`
|
|
149
|
+
形态 `10001`。设 `DSH_DOUBAO_DEEP_THINK=0` 可恢复成不思考的普通回合。**档位始终只由
|
|
150
|
+
`reasoning_effort` 携带,与开关是两个独立的轴。**
|
|
141
151
|
|
|
142
152
|
「豆包 快速」**不参与思考**:深度思考全开、档位拉到高,它的回复仍是 `thinking: false`,流里也没有
|
|
143
153
|
`10040` 思考容器。所以它被标记为不可推理,模型选择器不再给它显示低/中/高。
|
|
144
154
|
|
|
145
|
-
>
|
|
155
|
+
> **思考过程为什么看不见**:开关打开后服务端确实在思考(响应里有 `10040` 思考容器和 `10091`
|
|
146
156
|
> 计时块),但**推理正文不下发**。2026-11-07 用官方客户端抓包对照确认:思考容器的子块只有一个
|
|
147
157
|
> `summary: "正在思考"`,正文块里只有正式答案。这是接口限制,不是插件丢内容。
|
|
158
|
+
> 插件的 `collectBlocks` 仍按 `parent_id` 把思考子块与答案分开,shim 也仍以
|
|
159
|
+
> `reasoning_content` 转发——服务端哪天真的开始下发,客户端不需要改动就能看到。
|
|
148
160
|
|
|
149
161
|
---
|
|
150
162
|
|
package/lib/cli-doctor.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { O as classifyDoubaoFailure, f as DoubaoUpstreamError } from "./doubao-upstream-
|
|
1
|
+
import { O as classifyDoubaoFailure, f as DoubaoUpstreamError } from "./doubao-upstream-DvtS4CgR.js";
|
|
2
2
|
//#region src/cli-doctor.d.ts
|
|
3
3
|
type CheckStatus = 'ok' | 'fail' | 'skip';
|
|
4
4
|
interface DoctorCheck {
|
package/lib/cli-doctor.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { B as REQUIRED_COOKIE_NAMES, D as classifyDoubaoFailure, K as loadDoubaoCredentials, P as probeAccount, Q as listDoubaoProfiles, Y as describeProfileLocation, ft as DOUBAO_MODELS, i as formatDuration, m as DoubaoUpstreamError, mt as DOUBAO_PROVIDER_DISPLAY_NAME, n as fetchQuota, o as millisUntilReset, pt as DOUBAO_PROVIDER, r as findWindow, wt as discoverDoubaoModels } from "./doubao-quota-
|
|
3
|
-
import { _ as createDoubaoAdapter, a as doubaoQuotaView,
|
|
2
|
+
import { B as REQUIRED_COOKIE_NAMES, D as classifyDoubaoFailure, K as loadDoubaoCredentials, P as probeAccount, Q as listDoubaoProfiles, Y as describeProfileLocation, ft as DOUBAO_MODELS, i as formatDuration, m as DoubaoUpstreamError, mt as DOUBAO_PROVIDER_DISPLAY_NAME, n as fetchQuota, o as millisUntilReset, pt as DOUBAO_PROVIDER, r as findWindow, wt as discoverDoubaoModels } from "./doubao-quota-oVRIAATg.js";
|
|
3
|
+
import { _ as createDoubaoAdapter, a as doubaoQuotaView, f as discoverAllCachedModels, h as liveModels, r as DOUBAO_QUOTA_PATH, u as createDoubaoShim } from "./doubao-status-Dm-JiTV6.js";
|
|
4
4
|
//#region src/cli-doctor.ts
|
|
5
5
|
/**
|
|
6
6
|
* `doctor` — verify the whole stack end to end without spending inference quota.
|
package/lib/cli-probe.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { Dt as findDoubaoModel, F as streamChat, K as loadDoubaoCredentials, Ot as findReasoningLevel, P as probeAccount, ft as DOUBAO_MODELS, i as formatDuration, m as DoubaoUpstreamError, n as fetchQuota, o as millisUntilReset, r as findWindow } from "./doubao-quota-
|
|
2
|
+
import { Dt as findDoubaoModel, F as streamChat, K as loadDoubaoCredentials, Ot as findReasoningLevel, P as probeAccount, ft as DOUBAO_MODELS, i as formatDuration, m as DoubaoUpstreamError, n as fetchQuota, o as millisUntilReset, r as findWindow } from "./doubao-quota-oVRIAATg.js";
|
|
3
3
|
//#region src/cli-probe.ts
|
|
4
4
|
/**
|
|
5
5
|
* Doubao smoke probe.
|
package/lib/client.js
CHANGED
|
@@ -200,6 +200,18 @@ window.__ModuleLoader__.load({
|
|
|
200
200
|
.dbq-model-name { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
|
|
201
201
|
.dbq-badge { font-size: 11px; color: #9fb2c8; background: #1e242c; border: 1px solid #2f3641;
|
|
202
202
|
border-radius: 999px; padding: 0 7px; }
|
|
203
|
+
/* The multiplier the client menu prints next to a model. Monospace-ish and
|
|
204
|
+
narrow so a column of them lines up; a campaign tag is outlined instead of
|
|
205
|
+
filled so a temporary promo cannot read as the standing price. */
|
|
206
|
+
.dbq-rate { font-size: 11px; color: #ffcf7a; background: #2a2418; border: 1px solid #4a3c22;
|
|
207
|
+
border-radius: 999px; padding: 0 7px; font-variant-numeric: tabular-nums; }
|
|
208
|
+
.dbq-rate-promo { color: #ffb4a8; background: transparent; border-style: dashed; }
|
|
209
|
+
/* The thinking ladder a model offers. A level the client declares but no real
|
|
210
|
+
request has exercised yet is dimmed and dotted, never silently dropped. */
|
|
211
|
+
.dbq-levels { display: inline-flex; gap: 4px; flex-wrap: wrap; }
|
|
212
|
+
.dbq-level { font-size: 11px; color: #8fa6bd; border: 1px solid #2f3641; border-radius: 6px;
|
|
213
|
+
padding: 0 5px; }
|
|
214
|
+
.dbq-level-unverified { color: #7b8a99; border-style: dotted; }
|
|
203
215
|
.dbq-model-desc { color: #9aa0a6; font-size: 11px; }
|
|
204
216
|
.dbq-saved { color: #7fd18a; font-size: 12px; }
|
|
205
217
|
.dbq-error { color: #ff9d99; font-size: 12px; }
|
|
@@ -301,13 +313,23 @@ window.__ModuleLoader__.load({
|
|
|
301
313
|
if (!response.ok) return void 0;
|
|
302
314
|
return await response.json();
|
|
303
315
|
}
|
|
304
|
-
/**
|
|
316
|
+
/**
|
|
317
|
+
* Read the catalog for the checklist. Never throws.
|
|
318
|
+
*
|
|
319
|
+
* POST, not GET: the host drops its discovery memo on a write request, so the
|
|
320
|
+
* list is re-read from the client's own caches instead of answered from a
|
|
321
|
+
* memo up to ten minutes old. The refresh button therefore has to POST — a GET
|
|
322
|
+
* would faithfully re-render a catalog it never re-read.
|
|
323
|
+
*/
|
|
305
324
|
async function fetchCatalog(signal) {
|
|
306
325
|
const response = await fetch(DOUBAO_CATALOG_PATH, {
|
|
307
|
-
method: "
|
|
326
|
+
method: "POST",
|
|
308
327
|
credentials: "same-origin",
|
|
309
328
|
signal,
|
|
310
|
-
headers: {
|
|
329
|
+
headers: {
|
|
330
|
+
accept: "application/json",
|
|
331
|
+
...WRITE_HEADERS
|
|
332
|
+
}
|
|
311
333
|
});
|
|
312
334
|
if (!response.ok) return void 0;
|
|
313
335
|
return await response.json();
|
|
@@ -876,6 +898,10 @@ window.__ModuleLoader__.load({
|
|
|
876
898
|
className: "dbq-note",
|
|
877
899
|
children: t("models.empty")
|
|
878
900
|
}),
|
|
901
|
+
models.some((model) => model.rate !== null) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
902
|
+
className: "dbq-note",
|
|
903
|
+
children: t("models.rateNote")
|
|
904
|
+
}),
|
|
879
905
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
880
906
|
className: "dbq-models",
|
|
881
907
|
children: models.map((model) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
@@ -885,15 +911,29 @@ window.__ModuleLoader__.load({
|
|
|
885
911
|
checked: draft?.has(model.id) ?? false,
|
|
886
912
|
disabled: !canWrite || draft === void 0,
|
|
887
913
|
onChange: () => toggle(model.id)
|
|
888
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.
|
|
914
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
889
915
|
className: "dbq-model-main",
|
|
890
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
916
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
891
917
|
className: "dbq-model-name",
|
|
892
|
-
children: [
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
918
|
+
children: [
|
|
919
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: model.name }),
|
|
920
|
+
model.badge !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
921
|
+
className: "dbq-badge",
|
|
922
|
+
children: model.badge
|
|
923
|
+
}),
|
|
924
|
+
model.rate !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
925
|
+
className: model.rate.kind === "promo" ? "dbq-rate dbq-rate-promo" : "dbq-rate",
|
|
926
|
+
children: model.rate.text
|
|
927
|
+
})
|
|
928
|
+
]
|
|
929
|
+
}), model.reasoningLevels.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
930
|
+
className: "dbq-levels",
|
|
931
|
+
children: model.reasoningLevels.map((level) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
932
|
+
className: level.verified ? "dbq-level" : "dbq-level dbq-level-unverified",
|
|
933
|
+
title: level.verified ? t("models.levelVerified") : t("models.levelUnverified"),
|
|
934
|
+
children: level.name
|
|
935
|
+
}, level.id))
|
|
936
|
+
})]
|
|
897
937
|
})]
|
|
898
938
|
}, model.id))
|
|
899
939
|
}),
|
|
@@ -1032,7 +1072,7 @@ window.__ModuleLoader__.load({
|
|
|
1032
1072
|
"account.profile": "配置目录",
|
|
1033
1073
|
"models.title": "模型",
|
|
1034
1074
|
"models.enabledCount": "已启用 {count} ↑",
|
|
1035
|
-
"models.routingNote": "
|
|
1075
|
+
"models.routingNote": "清单、倍率、思考档位都直接读自豆包客户端菜单,豆包上新或调价会自动出现,不需要等插件更新。带「工作任务」徽章的条目走任务模式与会员付费额度,插件会自动完成本地指令应答。缓存的档位是蓝图,实线=已在真实请求中验证,虚线=仅菜单声明",
|
|
1036
1076
|
"models.refresh": "刷新",
|
|
1037
1077
|
"models.refreshing": "刷新中…",
|
|
1038
1078
|
"models.save": "保存",
|
|
@@ -1050,6 +1090,9 @@ window.__ModuleLoader__.load({
|
|
|
1050
1090
|
"models.readOnly": "当前宿主未提供设置写入通道,勾选不会生效",
|
|
1051
1091
|
"models.loadFailed": "模型目录读取失败",
|
|
1052
1092
|
"models.empty": "没有可用的模型条目",
|
|
1093
|
+
"models.levelVerified": "已在真实请求中验证",
|
|
1094
|
+
"models.levelUnverified": "客户端菜单声明,尚未在真实请求中验证",
|
|
1095
|
+
"models.rateNote": "倍率来自豆包客户端菜单,仅作展示;本插件不参与计费,也无法核对实际扣费",
|
|
1053
1096
|
"tools.title": "实验性:工具调用",
|
|
1054
1097
|
"tools.toggle": "让豆包驱动本地工具(读写文件、执行命令)",
|
|
1055
1098
|
"tools.note": "豆包的接口没有函数调用通道(声明的 tools 会被静默忽略),此开关改用提示词模拟:把工具清单写进提示词,再把回复里的围栏解析回标准 tool_calls。实测约 11.5 秒/轮,复杂任务可能退化,故默认关闭。",
|
|
@@ -1099,7 +1142,7 @@ window.__ModuleLoader__.load({
|
|
|
1099
1142
|
"account.profile": "Profile path",
|
|
1100
1143
|
"models.title": "Models",
|
|
1101
1144
|
"models.enabledCount": "{count} enabled ↑",
|
|
1102
|
-
"models.routingNote": "The list
|
|
1145
|
+
"models.routingNote": "The list, the multipliers and the thinking levels all come from the Doubao client menu, so new models or prices appear without a plugin update. Entries badged 「工作任务」 run in task mode against the paid membership quota; the plugin answers the local workspace commands for you. Solid chip = verified on a real request, dotted = declared by the menu only",
|
|
1103
1146
|
"models.refresh": "Refresh",
|
|
1104
1147
|
"models.refreshing": "Refreshing…",
|
|
1105
1148
|
"models.save": "Save",
|
|
@@ -1117,6 +1160,9 @@ window.__ModuleLoader__.load({
|
|
|
1117
1160
|
"models.readOnly": "This host provides no settings write path; ticking has no effect",
|
|
1118
1161
|
"models.loadFailed": "Could not read the model catalog",
|
|
1119
1162
|
"models.empty": "No model entries available",
|
|
1163
|
+
"models.levelVerified": "Verified on a real request",
|
|
1164
|
+
"models.levelUnverified": "Declared by the client menu, not yet verified on a request",
|
|
1165
|
+
"models.rateNote": "Multipliers come from the Doubao client menu and are display-only; this plugin does not bill and cannot verify the actual charge",
|
|
1120
1166
|
"tools.title": "Experimental: tool calling",
|
|
1121
1167
|
"tools.toggle": "Let Doubao drive local tools (read/write files, run commands)",
|
|
1122
1168
|
"tools.note": "Doubao's endpoint has no function-calling channel — a declared `tools` array is silently ignored — so this switch simulates it: the tool list goes into the prompt and the fenced block in the reply is parsed back into standard tool_calls. Measured ~11.5s per round; can degrade on complex tasks, hence off by default.",
|
|
@@ -98,13 +98,54 @@ const DOUBAO_REASONING_LEVELS = [
|
|
|
98
98
|
name: "高",
|
|
99
99
|
level: 5,
|
|
100
100
|
verified: true
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
id: "xhigh",
|
|
104
|
+
name: "极高",
|
|
105
|
+
level: 6,
|
|
106
|
+
verified: false
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
id: "max",
|
|
110
|
+
name: "最高",
|
|
111
|
+
level: 7,
|
|
112
|
+
verified: false
|
|
101
113
|
}
|
|
102
114
|
];
|
|
103
115
|
/** The level used when a request names none. Verified on the wire. */
|
|
104
116
|
const DEFAULT_REASONING_LEVEL_ID = "high";
|
|
105
117
|
/** Reasoning level for an id, falling back to the default. */
|
|
106
118
|
function findReasoningLevel(id) {
|
|
107
|
-
|
|
119
|
+
const known = DOUBAO_REASONING_LEVELS.find((level) => level.id === id);
|
|
120
|
+
if (known !== void 0) return known;
|
|
121
|
+
if (id !== void 0 && /^\d{1,3}$/.test(id)) {
|
|
122
|
+
const ordinal = Number(id);
|
|
123
|
+
const named = DOUBAO_REASONING_LEVELS.find((level) => level.level === ordinal);
|
|
124
|
+
if (named !== void 0) return named;
|
|
125
|
+
return {
|
|
126
|
+
id,
|
|
127
|
+
name: String(ordinal),
|
|
128
|
+
level: ordinal,
|
|
129
|
+
verified: false
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
return DOUBAO_REASONING_LEVELS.find((level) => level.id === DEFAULT_REASONING_LEVEL_ID);
|
|
133
|
+
}
|
|
134
|
+
/** The catalog entry for a wire ordinal, or undefined for one it does not know. */
|
|
135
|
+
function reasoningLevelOf(ordinal) {
|
|
136
|
+
if (ordinal === void 0) return void 0;
|
|
137
|
+
return DOUBAO_REASONING_LEVELS.find((level) => level.level === ordinal);
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* The wire spelling of an ordinal.
|
|
141
|
+
*
|
|
142
|
+
* `model_extra_params.reasoning_effort` for 2.1 Lite is a STRING in the captured
|
|
143
|
+
* request, and that string is the level's name-id, not its number. An ordinal
|
|
144
|
+
* with no catalog entry falls back to its own decimal form, so a level Doubao
|
|
145
|
+
* adds later still travels instead of snapping back to 高.
|
|
146
|
+
*/
|
|
147
|
+
function levelIdOf(ordinal) {
|
|
148
|
+
return reasoningLevelOf(ordinal)?.id ?? String(ordinal);
|
|
108
149
|
}
|
|
109
150
|
/**
|
|
110
151
|
* `need_deep_think` / `ext.use_deep_think` — the 深度思考 switch.
|
|
@@ -301,7 +342,18 @@ const DOUBAO_DEFAULT_MODEL_ID = "0";
|
|
|
301
342
|
* the request. `describeRequestedModel` in the shim is what surfaces the miss.
|
|
302
343
|
*/
|
|
303
344
|
function findDoubaoModel(id) {
|
|
304
|
-
|
|
345
|
+
if (id === void 0) return DOUBAO_MODELS.find((model) => model.id === "0");
|
|
346
|
+
const known = DOUBAO_MODELS.find((model) => model.id === id);
|
|
347
|
+
if (known !== void 0) return known;
|
|
348
|
+
return {
|
|
349
|
+
id,
|
|
350
|
+
name: id,
|
|
351
|
+
reasoning: true
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
/** True when the key is a catalog entry this release knows by name. */
|
|
355
|
+
function isKnownModelId(id) {
|
|
356
|
+
return id !== void 0 && DOUBAO_MODELS.some((model) => model.id === id);
|
|
305
357
|
}
|
|
306
358
|
/**
|
|
307
359
|
* Model ids measured to never think, whatever the 深度思考 switch says.
|
|
@@ -361,7 +413,13 @@ function doubaoCatalogEntries(models = DOUBAO_MODELS) {
|
|
|
361
413
|
id: model.id,
|
|
362
414
|
name: model.name,
|
|
363
415
|
badge: model.badge ?? null,
|
|
364
|
-
|
|
416
|
+
rate: model.rate ?? null,
|
|
417
|
+
reasoningLevels: model.reasoning ? model.reasoningOptions !== void 0 && model.reasoningOptions.length > 0 ? model.reasoningOptions.map((option) => ({
|
|
418
|
+
id: levelIdOf(option.level),
|
|
419
|
+
name: option.name,
|
|
420
|
+
level: option.level,
|
|
421
|
+
verified: reasoningLevelOf(option.level)?.verified ?? false
|
|
422
|
+
})) : DOUBAO_REASONING_LEVELS.filter((level) => level.verified).map((level) => ({
|
|
365
423
|
id: level.id,
|
|
366
424
|
name: level.name,
|
|
367
425
|
level: level.level,
|
|
@@ -1126,7 +1184,7 @@ function buildChatBody(prompt, options = {}) {
|
|
|
1126
1184
|
const model = findDoubaoModel(options.modelKey);
|
|
1127
1185
|
const level = findReasoningLevel(options.reasoningLevel);
|
|
1128
1186
|
const task = taskModeEnabled(options);
|
|
1129
|
-
const taskModelSelected = isTaskModel(model.id);
|
|
1187
|
+
const taskModelSelected = isTaskModel(model.id) || options.taskMode === true;
|
|
1130
1188
|
/**
|
|
1131
1189
|
* Deep-thinking toggle, for probing only.
|
|
1132
1190
|
*
|
|
@@ -1155,11 +1213,11 @@ function buildChatBody(prompt, options = {}) {
|
|
|
1155
1213
|
* BOTH `conversation_init_ext` and `aggregate_params`, whereas 「工作任务」
|
|
1156
1214
|
* models (`seed-lite-7b`, `5`, `9`) carry "3".
|
|
1157
1215
|
*/
|
|
1158
|
-
const modeId = (process.env.DSH_DOUBAO_MODE_ID ?? "").trim() || (
|
|
1216
|
+
const modeId = (process.env.DSH_DOUBAO_MODE_ID ?? "").trim() || (task ? "3" : "1");
|
|
1159
1217
|
const taskParam = task ? buildGeneralTaskParam(localMessageId, taskWorkspaceOf(options), taskModelSelected ? prompt : void 0) : { server_do_compare: true };
|
|
1160
1218
|
const modelExtraParams = taskModelSelected ? {
|
|
1161
1219
|
input_token_limit: "256k",
|
|
1162
|
-
...model.id === "seed-lite-7b" ? { reasoning_effort: level.
|
|
1220
|
+
...model.id === "seed-lite-7b" ? { reasoning_effort: levelIdOf(level.level) } : {}
|
|
1163
1221
|
} : {};
|
|
1164
1222
|
return {
|
|
1165
1223
|
messages: [{
|
|
@@ -2170,4 +2228,4 @@ function formatDuration(ms) {
|
|
|
2170
2228
|
return parts.join(" ") || "0s";
|
|
2171
2229
|
}
|
|
2172
2230
|
//#endregion
|
|
2173
|
-
export { looksLikeProfile as $, extractModel as A,
|
|
2231
|
+
export { looksLikeProfile as $, extractModel as A, isKnownModelId as At, REQUIRED_COOKIE_NAMES as B, buildGeneralTaskParam as C, TASK_SANDBOX_AUTH_ALLOW_ALL as Ct, classifyDoubaoFailure as D, findDoubaoModel as Dt, chat as E, enabledModelsOf as Et, streamChat as F, supportsReasoning as Ft, loadBrowserCredentials as G, clearCredentialCache as H, taskModeEnabled as I, PROFILE_ENV as J, loadDoubaoCredentials as K, taskWorkspaceOf as L, isRetryableFailure as M, levelIdOf as Mt, parseFrames as N, needDeepThinkValue as Nt, collectBlocks as O, findReasoningLevel as Ot, probeAccount as P, reasoningLevelOf as Pt, listDoubaoProfiles as Q, withImagePrefix as R, buildChatBody as S, TASK_RUNTIME_LOCAL_PC as St, buildQueryUrl as T, doubaoCatalogEntries as Tt, hasBrowserCredentials as U, clearBrowserCredentials as V, invalidateCredentialCache as W, extractUserDataDir as X, describeProfileLocation as Y, findDoubaoUserDataDir as Z, TOOL_LOCAL_ACK_ENDPOINT as _, DOUBAO_UNAVAILABLE_MODELS as _t, invalidateQuotaCache as a, DEEP_THINK_ON as at, applyRenewals as b, TASK_AGENT_MODE as bt, ACCOUNT_ENDPOINT as c, DOUBAO_DEFAULT_MODEL_ID as ct, DEFAULT_BOT_ID as d, DOUBAO_MAX_TOKENS as dt, resolveUserProvided as et, DOUBAO_ERROR_HINTS as f, DOUBAO_MODELS as ft, RUNTIME_VERSION as g, DOUBAO_SKILLS as gt, QUOTA_ENDPOINT as h, DOUBAO_REASONING_LEVELS as ht, formatDuration as i, DEEP_THINK_OFF as it, invalidateRenewals as j, isTaskModel as jt, describeDoubaoFailure as k, inputSkillOf as kt, CHAT_ENDPOINT as l, DOUBAO_IMAGE_MODEL_ID as lt, DoubaoUpstreamError as m, DOUBAO_PROVIDER_DISPLAY_NAME as mt, fetchQuota as n, CHAT_AGENT_MODE as nt, millisUntilReset as o, DEFAULT_REASONING_LEVEL_ID as ot, DOUBAO_VERSION as p, DOUBAO_PROVIDER as pt, saveBrowserCredentials as q, findWindow as r, CREATION_BLOCK_TYPE as rt, normalizeWindow as s, DOUBAO_CONTEXT_WINDOW as st, QUOTA_TTL_MS as t, setProfileOverride as tt, CLIENT_PARAMS as u, DOUBAO_IMAGE_MODEL_NAME as ut, TOOL_LOCAL_COMPLETE_ENDPOINT as v, NO_THINKING_MODEL_IDS as vt, buildHeaders as w, discoverDoubaoModels as wt, assembleReplyText as x, TASK_RUNTIME_CLOUD_VM as xt, TOOL_LOCAL_UPLOAD_ENDPOINT as y, SKILL_CARRIER_MODEL_ID as yt, CREDENTIAL_TTL_MS as z };
|