@yfwu2020/dsh-selection-explain 0.11.0 → 0.11.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/README.md +3 -3
- package/lib/client.js +36 -5
- package/lib/client.js.map +2 -2
- package/lib/host/history-store.js +20 -1
- package/lib/host/history-store.js.map +1 -1
- package/lib/host/mic.js +51 -6
- package/lib/host/mic.js.map +1 -1
- package/lib/types/host/types.d.ts +2 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ DSH 中的翻译、上下文解读与语音追问。
|
|
|
8
8
|
|
|
9
9
|
[快速安装](#install) · [语音输入](#voice) · [功能一览](#read) · [使用与设置](#settings)
|
|
10
10
|
|
|
11
|
-
`DSH 插件` · `v0.11.
|
|
11
|
+
`DSH 插件` · `v0.11.1` · `MIT`
|
|
12
12
|
|
|
13
13
|
</div>
|
|
14
14
|
|
|
@@ -113,11 +113,11 @@ dsh plugin --profile web add @yfwu2020/dsh-selection-explain
|
|
|
113
113
|
<details>
|
|
114
114
|
<summary>安装 Release 构建包</summary>
|
|
115
115
|
|
|
116
|
-
将下载的 `.tgz` 放到当前目录,以 v0.11.
|
|
116
|
+
将下载的 `.tgz` 放到当前目录,以 v0.11.1 为例:
|
|
117
117
|
|
|
118
118
|
```bash
|
|
119
119
|
mkdir -p ~/.dsh/plugins/dsh-selection-explain
|
|
120
|
-
tar -xzf yfwu2020-dsh-selection-explain-0.11.
|
|
120
|
+
tar -xzf yfwu2020-dsh-selection-explain-0.11.1.tgz -C ~/.dsh/plugins/dsh-selection-explain --strip-components=1
|
|
121
121
|
dsh plugin --profile web add ~/.dsh/plugins/dsh-selection-explain
|
|
122
122
|
```
|
|
123
123
|
|
package/lib/client.js
CHANGED
|
@@ -5015,7 +5015,7 @@ function createPanelController(env) {
|
|
|
5015
5015
|
env.state.selection = null;
|
|
5016
5016
|
}
|
|
5017
5017
|
function openPanelWithInner(text, context, label, anchor, keyContext, options) {
|
|
5018
|
-
env.state.
|
|
5018
|
+
env.state.skipInterpretation = !!(options && options.askFirst);
|
|
5019
5019
|
env.panelSessionId = currentSessionId();
|
|
5020
5020
|
env.state.payload = buildPayload(text, context, label);
|
|
5021
5021
|
env.state.kind = env.state.payload.kind;
|
|
@@ -5050,6 +5050,7 @@ function createPanelController(env) {
|
|
|
5050
5050
|
}
|
|
5051
5051
|
env.renderTurns();
|
|
5052
5052
|
if (cached) {
|
|
5053
|
+
env.state.skipInterpretation = false;
|
|
5053
5054
|
env.state.turns = (cached.turns || []).slice();
|
|
5054
5055
|
env.state.phase = "done";
|
|
5055
5056
|
env.state.stage = "";
|
|
@@ -5340,7 +5341,7 @@ function createPanelController(env) {
|
|
|
5340
5341
|
for (var i = 0; i < env.state.turns.length; i += 1) {
|
|
5341
5342
|
if (env.state.turns[i].role === "user") asked = true;
|
|
5342
5343
|
}
|
|
5343
|
-
env.expandButton.style.display = !hasDetail && translationReady && !asked && !env.state.
|
|
5344
|
+
env.expandButton.style.display = !hasDetail && translationReady && !asked && !env.state.skipInterpretation ? "" : "none";
|
|
5344
5345
|
env.expandButton.disabled = false;
|
|
5345
5346
|
return asked;
|
|
5346
5347
|
}
|
|
@@ -5360,9 +5361,17 @@ function createPanelController(env) {
|
|
|
5360
5361
|
var stage = env.state.stage;
|
|
5361
5362
|
var selected = env.state.payload && env.state.payload.text ? env.state.payload.text : env.state.selection ? env.state.selection.text : "";
|
|
5362
5363
|
var sections = splitSections(env.visibleRaw());
|
|
5363
|
-
env.translationSection.root.style.display = env.state.voiceAsk ? "none" : "";
|
|
5364
5364
|
var live = stripEchoPrefix(stage === "detail" ? "" : sections.translation || sections.other, selected);
|
|
5365
5365
|
var liveDetail = (sections.detail || sections.other || "").trim();
|
|
5366
|
+
var askedSoFar = false;
|
|
5367
|
+
for (var qi = 0; qi < env.state.turns.length; qi += 1) {
|
|
5368
|
+
if (env.state.turns[qi].role === "user") {
|
|
5369
|
+
askedSoFar = true;
|
|
5370
|
+
break;
|
|
5371
|
+
}
|
|
5372
|
+
}
|
|
5373
|
+
var emptyInterpretation = !env.state.parts.translation && !env.state.parts.detail && !live.trim();
|
|
5374
|
+
env.translationSection.root.style.display = env.state.skipInterpretation || emptyInterpretation && askedSoFar ? "none" : "";
|
|
5366
5375
|
if (env.state.parts.translation) {
|
|
5367
5376
|
renderRich(env.translationSection.content, stripEchoPrefix(env.state.parts.translation, selected), { callout: true, settled: true });
|
|
5368
5377
|
} else if (stage !== "detail" && live.trim()) {
|
|
@@ -5423,7 +5432,7 @@ function createPanelController(env) {
|
|
|
5423
5432
|
var surfaceTheme = env.currentSurfaceTheme();
|
|
5424
5433
|
env.layer.setAttribute("data-theme", surfaceTheme);
|
|
5425
5434
|
env.panel.setAttribute("data-theme", surfaceTheme);
|
|
5426
|
-
env.askRow.style.display = wide || translationReady || env.state.
|
|
5435
|
+
env.askRow.style.display = wide || translationReady || env.state.skipInterpretation || env.state.quotes.length > 0 ? "" : "none";
|
|
5427
5436
|
syncExpandCta();
|
|
5428
5437
|
env.closeButton.title = "\u5173\u95ED\uFF08Esc\uFF09";
|
|
5429
5438
|
if (env.state.phase !== "error" && env.state.phase !== "paused" && env.retryButton.parentNode) {
|
|
@@ -6477,7 +6486,11 @@ function createHistoryController(env) {
|
|
|
6477
6486
|
parts: env.state.parts,
|
|
6478
6487
|
turns,
|
|
6479
6488
|
toolDigest: env.state.toolDigest,
|
|
6480
|
-
pinned: !!(options && options.pinned)
|
|
6489
|
+
pinned: !!(options && options.pinned),
|
|
6490
|
+
// 这段对话有没有解读,必须跟着条目落盘:回放时靠它决定画不画「翻译」一节。
|
|
6491
|
+
// 不落盘的话,语音卡那条"跳过翻译与详解、直接追问"的对话下次开出来,
|
|
6492
|
+
// 会顶着一张空翻译卡片("这次没有返回内容")——用户实测。
|
|
6493
|
+
skipped: env.state.skipInterpretation === true
|
|
6481
6494
|
})
|
|
6482
6495
|
}).catch(function() {
|
|
6483
6496
|
});
|
|
@@ -6487,6 +6500,16 @@ function createHistoryController(env) {
|
|
|
6487
6500
|
function applyHistoryEntry(entry, source) {
|
|
6488
6501
|
var parts = entry.parts || {};
|
|
6489
6502
|
env.state.parts = { translation: parts.translation || "", detail: parts.detail || "" };
|
|
6503
|
+
var replayTurns = Array.isArray(entry.turns) ? entry.turns : [];
|
|
6504
|
+
var hasAskTurn = false;
|
|
6505
|
+
for (var step = 0; step < replayTurns.length; step += 1) {
|
|
6506
|
+
if (replayTurns[step] && replayTurns[step].role === "user") {
|
|
6507
|
+
hasAskTurn = true;
|
|
6508
|
+
break;
|
|
6509
|
+
}
|
|
6510
|
+
}
|
|
6511
|
+
var noInterpretation = !String(parts.translation || "").trim() && !String(parts.detail || "").trim();
|
|
6512
|
+
env.state.skipInterpretation = entry.skipped === true || entry.skipped === void 0 && noInterpretation && hasAskTurn;
|
|
6490
6513
|
env.state.turns = Array.isArray(entry.turns) ? entry.turns.slice() : [];
|
|
6491
6514
|
env.clearQuotes();
|
|
6492
6515
|
env.state.toolDigest = typeof entry.toolDigest === "string" ? entry.toolDigest : "";
|
|
@@ -9148,6 +9171,14 @@ function apply(ctx) {
|
|
|
9148
9171
|
payload: null,
|
|
9149
9172
|
/** 已生成的两节内容(分阶段产出)。 */
|
|
9150
9173
|
parts: { translation: "", detail: "" },
|
|
9174
|
+
/**
|
|
9175
|
+
* 这段对话**没有解读**(语音卡那条"跳过翻译与详解、直接追问"的路):
|
|
9176
|
+
* 翻译节整节不画,追问输入框直接可见。
|
|
9177
|
+
*
|
|
9178
|
+
* 语义单位是"一段对话"而不是"一次开窗":落盘时写进历史条目的 skipped,
|
|
9179
|
+
* 回放/缓存命中时按它复原(否则同一个词再开一次,空翻译卡片又冒出来 —— 用户实测)。
|
|
9180
|
+
*/
|
|
9181
|
+
skipInterpretation: false,
|
|
9151
9182
|
/** 当前阶段:'translation' | 'detail' | 'chat'。 */
|
|
9152
9183
|
stage: "",
|
|
9153
9184
|
/** 追问轮次:[{ role: 'user' | 'assistant', text }],只活在面板/内存里(临时)。 */
|