dsh-deepseek-web-login 0.6.25 → 0.6.26

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 CHANGED
@@ -2,6 +2,46 @@
2
2
 
3
3
  本项目大致遵循语义化版本;日期为本地时间。
4
4
 
5
+ ## 0.6.26 — 2026-10-01
6
+
7
+ **修复:新开一个窗口、只发一句话,网页端却显示「修改」+ `2 / 2`。**
8
+
9
+ ### 根因:内部请求占用了对话的会话槽
10
+
11
+ 时序(新窗口的第一句话):
12
+
13
+ 1. DSH 先发一次 `session-title`(**内部请求,不带结构化 promptParts**)
14
+ 2. 它与对话共用同一个 DSH sessionId ⇒ 此前共用同一个 slotKey
15
+ 3. 于是 `session-title` 先建会话、发出一条**根消息**(`parent=null`,内容就是那段
16
+ `Create a concise title…`);用户的真实消息随后**复用**这个会话,但内部请求不传 parts、
17
+ 没有链 ⇒ `decideFeed` 只能 `detach('no-chain')` ⇒ **又是一条根消息**
18
+ 4. 服务端把这两条看成**同一条用户消息的两个版本** ⇒ 网页端渲染成 `1 / 2`、`2 / 2` + 「修改」,
19
+ 而且标题 prompt 直接暴露在用户的对话里
20
+
21
+ ### 修法
22
+
23
+ 新增 `requestSlotKey(auth, params)`,**两个调用点(`openCompletion` / `streamWebCompletion`)
24
+ 统一使用**(键必须同源,否则链会写在一个键、读另一个键):
25
+
26
+ | 请求 | 归属键 |
27
+ |---|---|
28
+ | 带 `promptParts`(真正的对话) | `账号\|DSH会话` |
29
+ | 不带 `promptParts`(`session-title` / 压缩等) | `internal\|账号` |
30
+
31
+ 分开之后,对话槽里的第一条消息**永远**是这个窗口真正发出的那一条 —— 根消息只有一条。
32
+
33
+ ### 顺带
34
+
35
+ 「自动换号」的提示补上一句:**每换一次号,网页端就会多出一个新会话**(旧会话属于旧账号)。
36
+ 用户两次被"同一个窗口又多一个会话"搞懵,都是因为不知道中间换过号。
37
+
38
+ ### 验证
39
+
40
+ - 新增 2 条用例(端到端 + 会话分槽),并修正 4 处 fixture —— 真实 chat 请求必须带 `promptParts`,
41
+ 否则会被当成内部请求(这本身就是修复要引入的区分)
42
+ - 变异反向验证:把 `requestSlotKey` 改回"共用槽" ⇒ 两条用例都变红、`rc=1`
43
+ - `tsc --noEmit`、`npm run test`(60/60)、`check-smoke`、`check-bundle` 全通过
44
+
5
45
  ## 0.6.25 — 2026-10-01
6
46
 
7
47
  **新增:投喂决策留痕(`feed-decisions.jsonl`)—— 把"这一轮为什么没走增量"变成可查的事实。**
package/lib/client.js CHANGED
@@ -1695,7 +1695,7 @@ background:var(--bg2);white-space:pre-wrap;font-size:12px}
1695
1695
  const paintAutoSwitch = () => {
1696
1696
  const minutes = currentSwitchMinutes();
1697
1697
  swValue.textContent = minutes === 0 ? "关闭" : `${minutes} 分钟`;
1698
- const base = minutes === 0 ? "关闭时不会自动换号 —— 当前账号一直用到你手动切换为止。" : `每 ${minutes} 分钟换到账号库里的下一个可用账号(失效或正在受限的会跳过;可用的不足两个就不换)。换号会让投喂链断掉:下一轮要全量重发,历史图也要重新上传 —— 间隔越短,这个代价出现得越频繁。`;
1698
+ const base = minutes === 0 ? "关闭时不会自动换号 —— 当前账号一直用到你手动切换为止。" : `每 ${minutes} 分钟换到账号库里的下一个可用账号(失效或正在受限的会跳过;可用的不足两个就不换)。换号会让投喂链断掉:下一轮要全量重发,历史图也要重新上传 —— 间隔越短,这个代价出现得越频繁。另外要注意:每换一次号,网页端就会多出一个新会话(旧会话是在旧账号名下的,新账号看不到它),当前窗口也会从头开始 —— 在意网页端会话数量的,把它设成「关闭」。`;
1699
1699
  const last = lastAutoSwitchInfo;
1700
1700
  const why = last?.reason === "recently-throttled" ? ",原账号刚被限流" : last?.reason === "current-unusable" ? ",原账号不可用" : "";
1701
1701
  swHint.textContent = last ? `${base}上次自动换号:${shortTime(last.at)}(${last.from} → ${last.to}${why})。` : base;