dsh-input-traffic 0.2.7 → 0.2.9
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.en.md +47 -6
- package/README.md +60 -9
- package/lib/client.js +158 -104
- package/lib/client.js.map +1 -1
- package/lib/types/client/auto-continue-core.d.ts +103 -0
- package/lib/types/client/auto-continue-core.d.ts.map +1 -0
- package/lib/types/client/auto-continue-core.js +131 -0
- package/lib/types/client/auto-continue-core.js.map +1 -0
- package/lib/types/client/auto-continue-store.d.ts +41 -0
- package/lib/types/client/auto-continue-store.d.ts.map +1 -0
- package/lib/types/client/auto-continue-store.js +93 -0
- package/lib/types/client/auto-continue-store.js.map +1 -0
- package/lib/types/client/freeze-button.d.ts +1 -1
- package/lib/types/client/freeze-button.d.ts.map +1 -1
- package/lib/types/client/freeze-button.js +30 -6
- package/lib/types/client/freeze-button.js.map +1 -1
- package/lib/types/client/freeze-store.d.ts +17 -10
- package/lib/types/client/freeze-store.d.ts.map +1 -1
- package/lib/types/client/freeze-store.js +54 -38
- package/lib/types/client/freeze-store.js.map +1 -1
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/client/index.js +15 -12
- package/lib/types/client/index.js.map +1 -1
- package/lib/types/client/locales.d.ts +1 -0
- package/lib/types/client/locales.d.ts.map +1 -1
- package/lib/types/client/locales.js +2 -0
- package/lib/types/client/locales.js.map +1 -1
- package/lib/types/client/session-guard-bridge.d.ts +18 -0
- package/lib/types/client/session-guard-bridge.d.ts.map +1 -0
- package/lib/types/client/session-guard-bridge.js +42 -0
- package/lib/types/client/session-guard-bridge.js.map +1 -0
- package/lib/types/client/steer-queue-dock.d.ts +9 -3
- package/lib/types/client/steer-queue-dock.d.ts.map +1 -1
- package/lib/types/client/steer-queue-dock.js +6 -5
- package/lib/types/client/steer-queue-dock.js.map +1 -1
- package/package.json +104 -104
package/lib/client.js
CHANGED
|
@@ -58,6 +58,7 @@ window.__ModuleLoader__.load({
|
|
|
58
58
|
"steer.freeze": "冻结会话",
|
|
59
59
|
"steer.resume": "恢复会话",
|
|
60
60
|
"steer.frozen": "已冻结:当前轮次完成后暂停,排队消息将在恢复后继续",
|
|
61
|
+
"steer.frozenInput": "已冻结:输入已暂停,恢复后继续",
|
|
61
62
|
"steer.frozenBadge": "已冻结",
|
|
62
63
|
"steer.freezeFailed": "冻结失败,请重试。",
|
|
63
64
|
"steer.resumeFailed": "恢复失败,请重试。"
|
|
@@ -109,21 +110,27 @@ window.__ModuleLoader__.load({
|
|
|
109
110
|
"steer.freeze": "Freeze session",
|
|
110
111
|
"steer.resume": "Resume session",
|
|
111
112
|
"steer.frozen": "Frozen: the current turn finishes, then the queue pauses until resumed",
|
|
113
|
+
"steer.frozenInput": "Frozen: input paused, resume to continue",
|
|
112
114
|
"steer.frozenBadge": "frozen",
|
|
113
115
|
"steer.freezeFailed": "Freeze failed, please retry.",
|
|
114
116
|
"steer.resumeFailed": "Resume failed, please retry."
|
|
115
117
|
};
|
|
116
118
|
//#endregion
|
|
117
119
|
//#region src/client/freeze-store.ts
|
|
120
|
+
/** Session id → per-session freeze state. */
|
|
121
|
+
const states = /* @__PURE__ */ new Map();
|
|
118
122
|
const listeners = /* @__PURE__ */ new Set();
|
|
119
|
-
|
|
123
|
+
/** Stable empty snapshot: `useSyncExternalStore` needs a reference-stable
|
|
124
|
+
* value for unset sessions so unchanged consumers never re-render. */
|
|
125
|
+
const EMPTY = {
|
|
120
126
|
frozen: false,
|
|
121
127
|
pending: []
|
|
122
128
|
};
|
|
123
129
|
/** Minimal snapshot store (no runtime dependency, stable identity per mount). */
|
|
124
130
|
const freezeStore = {
|
|
125
|
-
|
|
126
|
-
|
|
131
|
+
/** Snapshot for one session; reference-stable until that session changes. */
|
|
132
|
+
getSnapshot(sessionId) {
|
|
133
|
+
return states.get(sessionId) ?? EMPTY;
|
|
127
134
|
},
|
|
128
135
|
subscribe(listener) {
|
|
129
136
|
listeners.add(listener);
|
|
@@ -131,71 +138,74 @@ window.__ModuleLoader__.load({
|
|
|
131
138
|
listeners.delete(listener);
|
|
132
139
|
};
|
|
133
140
|
},
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
141
|
+
/** Replace one session's state; unset sessions fall back to EMPTY. */
|
|
142
|
+
set(sessionId, next) {
|
|
143
|
+
if (next.frozen === false && next.pending.length === 0) states.delete(sessionId);
|
|
144
|
+
else states.set(sessionId, next);
|
|
145
|
+
emit();
|
|
137
146
|
}
|
|
138
147
|
};
|
|
139
148
|
/** Edit one detached queued message's text in place. */
|
|
140
|
-
function updatePendingAt(index, text) {
|
|
141
|
-
const pending =
|
|
142
|
-
if (
|
|
149
|
+
function updatePendingAt(sessionId, index, text) {
|
|
150
|
+
const pending = states.get(sessionId)?.pending;
|
|
151
|
+
if (pending === void 0) return;
|
|
143
152
|
const entry = pending[index];
|
|
144
153
|
if (entry === void 0) return;
|
|
145
|
-
|
|
154
|
+
const next = [...pending];
|
|
155
|
+
next[index] = {
|
|
146
156
|
...entry,
|
|
147
157
|
text
|
|
148
158
|
};
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
pending
|
|
152
|
-
};
|
|
153
|
-
emit();
|
|
159
|
+
freezeStore.set(sessionId, {
|
|
160
|
+
frozen: true,
|
|
161
|
+
pending: next
|
|
162
|
+
});
|
|
154
163
|
}
|
|
155
164
|
/** Change one detached queued message's planned insertion tier. */
|
|
156
|
-
function setTierAt(index, tier) {
|
|
157
|
-
const pending =
|
|
158
|
-
if (
|
|
165
|
+
function setTierAt(sessionId, index, tier) {
|
|
166
|
+
const pending = states.get(sessionId)?.pending;
|
|
167
|
+
if (pending === void 0) return;
|
|
159
168
|
const entry = pending[index];
|
|
160
169
|
if (entry === void 0) return;
|
|
161
|
-
|
|
170
|
+
const next = [...pending];
|
|
171
|
+
next[index] = {
|
|
162
172
|
...entry,
|
|
163
173
|
tier
|
|
164
174
|
};
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
pending
|
|
168
|
-
};
|
|
169
|
-
emit();
|
|
175
|
+
freezeStore.set(sessionId, {
|
|
176
|
+
frozen: true,
|
|
177
|
+
pending: next
|
|
178
|
+
});
|
|
170
179
|
}
|
|
171
180
|
/** Remove one detached queued message. */
|
|
172
|
-
function removePendingAt(index) {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
181
|
+
function removePendingAt(sessionId, index) {
|
|
182
|
+
const pending = states.get(sessionId)?.pending;
|
|
183
|
+
if (pending === void 0) return;
|
|
184
|
+
freezeStore.set(sessionId, {
|
|
185
|
+
frozen: true,
|
|
186
|
+
pending: pending.filter((_, i) => i !== index)
|
|
187
|
+
});
|
|
179
188
|
}
|
|
180
189
|
/** Move one detached queued message to a new position (reorder while frozen). */
|
|
181
|
-
function movePending(from, to) {
|
|
190
|
+
function movePending(sessionId, from, to) {
|
|
182
191
|
if (from === to) return;
|
|
183
|
-
const pending =
|
|
184
|
-
|
|
192
|
+
const pending = states.get(sessionId)?.pending;
|
|
193
|
+
if (pending === void 0) return;
|
|
194
|
+
const next = [...pending];
|
|
195
|
+
const [moved] = next.splice(from, 1);
|
|
185
196
|
if (moved === void 0) return;
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
pending
|
|
190
|
-
};
|
|
191
|
-
emit();
|
|
197
|
+
next.splice(to, 0, moved);
|
|
198
|
+
freezeStore.set(sessionId, {
|
|
199
|
+
frozen: true,
|
|
200
|
+
pending: next
|
|
201
|
+
});
|
|
192
202
|
}
|
|
193
203
|
function emit() {
|
|
194
204
|
for (const listener of listeners) listener();
|
|
195
205
|
}
|
|
196
206
|
//#endregion
|
|
197
207
|
//#region \0dsh-css:E:\test\rewrite-agently\dsh-input-traffic\src\client\steer-queue-dock.module.css.mjs
|
|
198
|
-
const css$1 = ".cev0eq_dock{width:100%}.cev0eq_panel{background:var(--
|
|
208
|
+
const css$1 = ".cev0eq_dock{width:100%}.cev0eq_panel{background:var(--dsw-alias-bg-layer-1,#fffc);border:1px solid var(--dsw-alias-border-l2,#00000014);border-radius:10px;overflow:hidden}.cev0eq_toolbar{border-bottom:1px solid var(--dsw-alias-border-l2,#0000000f);align-items:center;gap:8px;padding:4px 8px;display:flex}.cev0eq_header{color:var(--dsw-alias-label-secondary,#6b7280);cursor:pointer;background:0 0;border:0;align-items:center;gap:6px;padding:2px 6px;font-size:12px;display:inline-flex}.cev0eq_header:disabled{cursor:default}.cev0eq_lead{color:var(--dsw-alias-label-tertiary,#9ca3af);display:inline-flex}.cev0eq_count{font-weight:600}.cev0eq_chevron{color:var(--dsw-alias-label-tertiary,#9ca3af);display:inline-flex}.cev0eq_toolbarActions{margin-left:auto}.cev0eq_clear{color:var(--dsw-alias-label-secondary,#6b7280);cursor:pointer;background:0 0;border:1px solid #0000;border-radius:6px;align-items:center;gap:4px;padding:3px 8px;font-size:12px;display:inline-flex}.cev0eq_freeze{border:1px solid var(--dsw-alias-border-l3,#0000001f);color:var(--dsw-alias-label-secondary,#6b7280);cursor:pointer;background:0 0;border-radius:6px;align-items:center;gap:4px;padding:3px 8px;font-size:12px;display:inline-flex}.cev0eq_freeze[aria-pressed=true]{border-color:var(--dsw-alias-state-success-primary,#30a46c);color:var(--dsw-alias-state-success-primary,#30a46c)}.cev0eq_freeze:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,#0000000a)}.cev0eq_freeze:disabled{opacity:.5;cursor:default}.cev0eq_frozenBanner{border-bottom:1px solid var(--dsw-alias-border-l2,#0000000f);background:color-mix(in srgb, var(--dsw-alias-state-success-primary,#30a46c) 8%, transparent);color:var(--dsw-alias-state-success-primary,#30a46c);padding:4px 10px;font-size:12px}.cev0eq_frozenList{margin:0;padding:4px;list-style:none}.cev0eq_frozenRow{border-radius:6px;align-items:center;gap:8px;padding:4px 6px;display:flex}.cev0eq_frozenMark{color:var(--dsw-alias-label-tertiary,#9ca3af);flex:none;margin-left:auto;font-size:11px}.cev0eq_clear:hover:not(:disabled){border-color:var(--dsw-alias-border-l3,#0000001f);background:var(--dsw-alias-interactive-bg-hover,#0000000a)}.cev0eq_clear:disabled{opacity:.5;cursor:default}.cev0eq_clearConfirm{border-color:var(--dsw-alias-state-error-primary,#e5484d);color:var(--dsw-alias-state-error-primary,#e5484d)}.cev0eq_clearConfirm:hover:not(:disabled){border-color:var(--dsw-alias-state-error-primary,#e5484d);background:color-mix(in srgb, var(--dsw-alias-state-error-primary,#e5484d) 8%, transparent)}.cev0eq_clearCancel{color:var(--dsw-alias-label-secondary,#6b7280);cursor:pointer;background:0 0;border:1px solid #0000;border-radius:6px;align-items:center;gap:4px;padding:3px 8px;font-size:12px;display:inline-flex}.cev0eq_clearCancel:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,#0000000a)}.cev0eq_clearLabel{font-size:12px}.cev0eq_list{margin:0;padding:4px;list-style:none}.cev0eq_row{border-radius:6px;align-items:center;gap:8px;padding:4px 6px;display:flex}.cev0eq_row[draggable=true]{cursor:grab}.cev0eq_row[draggable=true]:active{cursor:grabbing}.cev0eq_rowDragOver{outline:2px dashed var(--dsw-alias-border-l4,#00000040);outline-offset:-2px;background:var(--dsw-alias-interactive-bg-hover,#0000000d)}.cev0eq_row:hover{background:var(--dsw-alias-interactive-bg-hover,#00000008)}.cev0eq_row[data-editing]{align-items:flex-start}.cev0eq_preview{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--dsw-alias-label-primary,#1f2937);flex:1;font-size:13px;overflow:hidden}.cev0eq_badge{white-space:nowrap;border-radius:999px;flex:none;align-items:center;gap:4px;padding:1px 6px;font-size:11px;line-height:16px;display:inline-flex}.cev0eq_badgeLabel{color:inherit}.cev0eq_badgeNow{color:var(--dsw-alias-state-error-primary,#e5484d);background:color-mix(in srgb, var(--dsw-alias-state-error-primary,#e5484d) 10%, transparent)}.cev0eq_badgeNext{color:var(--dsw-alias-state-warn-primary,#e8a33d);background:color-mix(in srgb, var(--dsw-alias-state-warn-primary,#e8a33d) 12%, transparent)}.cev0eq_badgeLater{color:var(--dsw-alias-state-success-primary,#30a46c);background:color-mix(in srgb, var(--dsw-alias-state-success-primary,#30a46c) 12%, transparent)}.cev0eq_badgeNow .cev0eq_dot{background:var(--dsw-alias-state-error-primary,#e5484d)}.cev0eq_badgeNext .cev0eq_dot{background:var(--dsw-alias-state-warn-primary,#e8a33d)}.cev0eq_badgeLater .cev0eq_dot{background:var(--dsw-alias-state-success-primary,#30a46c)}.cev0eq_steeringList{margin:0;padding:0 4px 4px;list-style:none}.cev0eq_steeringList .cev0eq_row{opacity:.85}.cev0eq_editor{border:1px solid var(--dsw-alias-border-l3,#00000026);background:var(--dsw-alias-bg-layer-2,#fff);resize:none;border-radius:6px;flex:1;min-width:0;max-height:160px;padding:4px 6px;font-size:13px;line-height:20px;overflow-y:auto}.cev0eq_actions{align-items:center;gap:2px;display:inline-flex}.cev0eq_action{width:24px;height:24px;color:var(--dsw-alias-label-tertiary,#9ca3af);cursor:pointer;background:0 0;border:0;border-radius:6px;justify-content:center;align-items:center;display:inline-flex}.cev0eq_action:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,#0000000d);color:var(--dsw-alias-label-primary,#1f2937)}.cev0eq_action:disabled{opacity:.4;cursor:default}.cev0eq_plan{border-left:1px solid var(--dsw-alias-border-l2,#00000014);align-items:center;gap:2px;margin-left:4px;padding-left:6px;display:inline-flex}.cev0eq_tier{cursor:pointer;background:0 0;border:1px solid #0000;border-radius:6px;justify-content:center;align-items:center;width:20px;height:20px;padding:0;display:inline-flex}.cev0eq_tier:hover:not(:disabled){border-color:var(--dsw-alias-border-l4,#0003)}.cev0eq_tier:disabled{cursor:default}.cev0eq_tierLater{border-color:var(--dsw-alias-state-success-primary,#30a46c);background:color-mix(in srgb, var(--dsw-alias-state-success-primary,#30a46c) 12%, transparent)}.cev0eq_dot{border-radius:50%;width:10px;height:10px}.cev0eq_tierNow .cev0eq_dot{background:var(--dsw-alias-state-error-primary,#e5484d)}.cev0eq_tierNext .cev0eq_dot{background:var(--dsw-alias-state-warn-primary,#e8a33d)}.cev0eq_tierLater .cev0eq_dot{background:var(--dsw-alias-state-success-primary,#30a46c)}";
|
|
199
209
|
const tagId$1 = "dsh-input-traffic/steer-queue-dock.module.css";
|
|
200
210
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
|
|
201
211
|
const tag = document.createElement("style");
|
|
@@ -205,42 +215,42 @@ window.__ModuleLoader__.load({
|
|
|
205
215
|
document.head.appendChild(tag);
|
|
206
216
|
}
|
|
207
217
|
var steer_queue_dock_module_css_default = {
|
|
208
|
-
"
|
|
209
|
-
"
|
|
210
|
-
"
|
|
211
|
-
"
|
|
212
|
-
"
|
|
213
|
-
"
|
|
214
|
-
"
|
|
215
|
-
"
|
|
216
|
-
"chevron": "cev0eq_chevron",
|
|
218
|
+
"preview": "cev0eq_preview",
|
|
219
|
+
"action": "cev0eq_action",
|
|
220
|
+
"badgeLabel": "cev0eq_badgeLabel",
|
|
221
|
+
"frozenList": "cev0eq_frozenList",
|
|
222
|
+
"tierNext": "cev0eq_tierNext",
|
|
223
|
+
"badgeNext": "cev0eq_badgeNext",
|
|
224
|
+
"row": "cev0eq_row",
|
|
225
|
+
"clearConfirm": "cev0eq_clearConfirm",
|
|
217
226
|
"clearLabel": "cev0eq_clearLabel",
|
|
227
|
+
"plan": "cev0eq_plan",
|
|
228
|
+
"rowDragOver": "cev0eq_rowDragOver",
|
|
229
|
+
"actions": "cev0eq_actions",
|
|
218
230
|
"tierNow": "cev0eq_tierNow",
|
|
219
|
-
"
|
|
220
|
-
"
|
|
231
|
+
"badgeLater": "cev0eq_badgeLater",
|
|
232
|
+
"badge": "cev0eq_badge",
|
|
233
|
+
"lead": "cev0eq_lead",
|
|
234
|
+
"header": "cev0eq_header",
|
|
235
|
+
"list": "cev0eq_list",
|
|
221
236
|
"frozenMark": "cev0eq_frozenMark",
|
|
222
|
-
"
|
|
223
|
-
"
|
|
224
|
-
"
|
|
237
|
+
"steeringList": "cev0eq_steeringList",
|
|
238
|
+
"tier": "cev0eq_tier",
|
|
239
|
+
"frozenRow": "cev0eq_frozenRow",
|
|
225
240
|
"clear": "cev0eq_clear",
|
|
226
|
-
"tierNext": "cev0eq_tierNext",
|
|
227
241
|
"frozenBanner": "cev0eq_frozenBanner",
|
|
228
|
-
"
|
|
229
|
-
"
|
|
242
|
+
"dot": "cev0eq_dot",
|
|
243
|
+
"tierLater": "cev0eq_tierLater",
|
|
244
|
+
"chevron": "cev0eq_chevron",
|
|
245
|
+
"count": "cev0eq_count",
|
|
246
|
+
"panel": "cev0eq_panel",
|
|
230
247
|
"toolbar": "cev0eq_toolbar",
|
|
231
|
-
"list": "cev0eq_list",
|
|
232
|
-
"clearConfirm": "cev0eq_clearConfirm",
|
|
233
|
-
"preview": "cev0eq_preview",
|
|
234
|
-
"badgeLabel": "cev0eq_badgeLabel",
|
|
235
|
-
"plan": "cev0eq_plan",
|
|
236
|
-
"clearCancel": "cev0eq_clearCancel",
|
|
237
|
-
"rowDragOver": "cev0eq_rowDragOver",
|
|
238
248
|
"toolbarActions": "cev0eq_toolbarActions",
|
|
239
|
-
"
|
|
240
|
-
"
|
|
241
|
-
"
|
|
242
|
-
"
|
|
243
|
-
"
|
|
249
|
+
"editor": "cev0eq_editor",
|
|
250
|
+
"dock": "cev0eq_dock",
|
|
251
|
+
"freeze": "cev0eq_freeze",
|
|
252
|
+
"badgeNow": "cev0eq_badgeNow",
|
|
253
|
+
"clearCancel": "cev0eq_clearCancel"
|
|
244
254
|
};
|
|
245
255
|
//#endregion
|
|
246
256
|
//#region src/client/steer-queue-dock.tsx
|
|
@@ -298,7 +308,7 @@ window.__ModuleLoader__.load({
|
|
|
298
308
|
* Queue strip with three-tier planning: one item renders directly; multiple
|
|
299
309
|
* items default to a collapsible count header; an empty queue renders nothing.
|
|
300
310
|
*/
|
|
301
|
-
function SteerQueueDock({ useSession, input, updateQueue, cancel, send, setDraft, notify, t }) {
|
|
311
|
+
function SteerQueueDock({ sessionId, useSession, input, updateQueue, cancel, send, setDraft, notify, t }) {
|
|
302
312
|
const inbox = useSession((s) => s.queue);
|
|
303
313
|
const queue = (0, react.useMemo)(() => inbox.filter((row) => row.placement === "queued"), [inbox]);
|
|
304
314
|
const steering = (0, react.useMemo)(() => inbox.filter((row) => row.placement === "steering"), [inbox]);
|
|
@@ -319,7 +329,8 @@ window.__ModuleLoader__.load({
|
|
|
319
329
|
return true;
|
|
320
330
|
}
|
|
321
331
|
});
|
|
322
|
-
const { frozen, pending: frozenPending } = (0, react.useSyncExternalStore)(freezeStore.subscribe, freezeStore.getSnapshot);
|
|
332
|
+
const { frozen, pending: frozenPending } = (0, react.useSyncExternalStore)(freezeStore.subscribe, () => freezeStore.getSnapshot(sessionId ?? ""));
|
|
333
|
+
const sid = sessionId ?? "";
|
|
323
334
|
const listId = (0, react.useId)();
|
|
324
335
|
const editorRef = (0, react.useRef)(null);
|
|
325
336
|
(0, react.useEffect)(() => {
|
|
@@ -507,7 +518,7 @@ window.__ModuleLoader__.load({
|
|
|
507
518
|
setEditing(null);
|
|
508
519
|
return;
|
|
509
520
|
}
|
|
510
|
-
updatePendingAt(index, text);
|
|
521
|
+
updatePendingAt(sid, index, text);
|
|
511
522
|
setEditing(null);
|
|
512
523
|
};
|
|
513
524
|
/**
|
|
@@ -635,7 +646,7 @@ window.__ModuleLoader__.load({
|
|
|
635
646
|
const from = dragIndex.current;
|
|
636
647
|
dragIndex.current = null;
|
|
637
648
|
setDragOver(null);
|
|
638
|
-
if (from !== null) movePending(from, i);
|
|
649
|
+
if (from !== null) movePending(sid, from, i);
|
|
639
650
|
},
|
|
640
651
|
onDragEnd: () => {
|
|
641
652
|
dragIndex.current = null;
|
|
@@ -721,7 +732,7 @@ window.__ModuleLoader__.load({
|
|
|
721
732
|
className: steer_queue_dock_module_css_default.action,
|
|
722
733
|
"aria-label": t("steer.moveUp"),
|
|
723
734
|
disabled: i === 0,
|
|
724
|
-
onClick: () => movePending(i, i - 1),
|
|
735
|
+
onClick: () => movePending(sid, i, i - 1),
|
|
725
736
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronUpOutline14, {})
|
|
726
737
|
})
|
|
727
738
|
}),
|
|
@@ -735,7 +746,7 @@ window.__ModuleLoader__.load({
|
|
|
735
746
|
className: steer_queue_dock_module_css_default.action,
|
|
736
747
|
"aria-label": t("steer.moveDown"),
|
|
737
748
|
disabled: i === frozenPending.length - 1,
|
|
738
|
-
onClick: () => movePending(i, i + 1),
|
|
749
|
+
onClick: () => movePending(sid, i, i + 1),
|
|
739
750
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, {})
|
|
740
751
|
})
|
|
741
752
|
}),
|
|
@@ -764,7 +775,7 @@ window.__ModuleLoader__.load({
|
|
|
764
775
|
type: "button",
|
|
765
776
|
className: steer_queue_dock_module_css_default.action,
|
|
766
777
|
"aria-label": t("queue.remove"),
|
|
767
|
-
onClick: () => removePendingAt(i),
|
|
778
|
+
onClick: () => removePendingAt(sid, i),
|
|
768
779
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconTrashOutline16, { size: 14 })
|
|
769
780
|
})
|
|
770
781
|
}),
|
|
@@ -782,7 +793,7 @@ window.__ModuleLoader__.load({
|
|
|
782
793
|
className: `${steer_queue_dock_module_css_default.tier} ${steer_queue_dock_module_css_default.tierNow}`,
|
|
783
794
|
"aria-label": t("steer.now"),
|
|
784
795
|
"aria-pressed": entry.tier === "force" || void 0,
|
|
785
|
-
onClick: () => setTierAt(i, "force"),
|
|
796
|
+
onClick: () => setTierAt(sid, i, "force"),
|
|
786
797
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
787
798
|
className: steer_queue_dock_module_css_default.dot,
|
|
788
799
|
"aria-hidden": true
|
|
@@ -798,7 +809,7 @@ window.__ModuleLoader__.load({
|
|
|
798
809
|
className: `${steer_queue_dock_module_css_default.tier} ${steer_queue_dock_module_css_default.tierNext}`,
|
|
799
810
|
"aria-label": t("steer.next"),
|
|
800
811
|
"aria-pressed": entry.tier === "safe_point" || void 0,
|
|
801
|
-
onClick: () => setTierAt(i, "safe_point"),
|
|
812
|
+
onClick: () => setTierAt(sid, i, "safe_point"),
|
|
802
813
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
803
814
|
className: steer_queue_dock_module_css_default.dot,
|
|
804
815
|
"aria-hidden": true
|
|
@@ -814,7 +825,7 @@ window.__ModuleLoader__.load({
|
|
|
814
825
|
className: `${steer_queue_dock_module_css_default.tier} ${steer_queue_dock_module_css_default.tierLater}`,
|
|
815
826
|
"aria-label": t("steer.later"),
|
|
816
827
|
"aria-pressed": entry.tier === "queue" || void 0,
|
|
817
|
-
onClick: () => setTierAt(i, "queue"),
|
|
828
|
+
onClick: () => setTierAt(sid, i, "queue"),
|
|
818
829
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
819
830
|
className: steer_queue_dock_module_css_default.dot,
|
|
820
831
|
"aria-hidden": true
|
|
@@ -1168,8 +1179,47 @@ window.__ModuleLoader__.load({
|
|
|
1168
1179
|
});
|
|
1169
1180
|
}
|
|
1170
1181
|
//#endregion
|
|
1182
|
+
//#region src/client/session-guard-bridge.ts
|
|
1183
|
+
/**
|
|
1184
|
+
* input-traffic ↔ dsh-session-guard 透传桥(D8 fail-open)。
|
|
1185
|
+
*
|
|
1186
|
+
* input-traffic **只做冻结增强**(队列冻结/解冻),服务端会话门(暂停/恢复会话)
|
|
1187
|
+
* 归 dsh-session-guard 插件。冻结/解冻按钮触发时,尽力调用
|
|
1188
|
+
* `sessionGuard.stopNextTurn` / `resume`;**插件未装**(路由 404 / 网络失败 /
|
|
1189
|
+
* 返回错误)→ 静默跳过,**绝不报错**,前端冻结仍正常生效。
|
|
1190
|
+
*
|
|
1191
|
+
* 不吸收任何 auto-continue / 重试逻辑(重试归后端 dsh-session-guard,D9)。
|
|
1192
|
+
*/
|
|
1193
|
+
/** 尽力调用 sessionGuard.stopNextTurn(停掉 session 下一回合)。失败静默。 */
|
|
1194
|
+
async function sessionGuardStopNextTurn(sessionId) {
|
|
1195
|
+
return callGuard(sessionId, "stopNextTurn");
|
|
1196
|
+
}
|
|
1197
|
+
/** 尽力调用 sessionGuard.resume。失败静默。 */
|
|
1198
|
+
async function sessionGuardResume(sessionId) {
|
|
1199
|
+
return callGuard(sessionId, "resume");
|
|
1200
|
+
}
|
|
1201
|
+
async function callGuard(sessionId, action) {
|
|
1202
|
+
try {
|
|
1203
|
+
const res = await fetch("/session-guard/rpc", {
|
|
1204
|
+
method: "POST",
|
|
1205
|
+
headers: { "content-type": "application/json" },
|
|
1206
|
+
body: JSON.stringify({
|
|
1207
|
+
sessionId,
|
|
1208
|
+
action
|
|
1209
|
+
})
|
|
1210
|
+
});
|
|
1211
|
+
if (!res.ok) return false;
|
|
1212
|
+
return (await res.json().catch(() => null))?.ok === true;
|
|
1213
|
+
} catch {
|
|
1214
|
+
return false;
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
try {
|
|
1218
|
+
globalThis.__DSH_SESSION_GUARD_BRIDGE__ = true;
|
|
1219
|
+
} catch {}
|
|
1220
|
+
//#endregion
|
|
1171
1221
|
//#region \0dsh-css:E:\test\rewrite-agently\dsh-input-traffic\src\client\freeze-button.module.css.mjs
|
|
1172
|
-
const css = ".Klmgza_freeze{border:1px solid var(--
|
|
1222
|
+
const css = ".Klmgza_freeze{border:1px solid var(--dsw-alias-border-l3,#0000001f);height:24px;color:var(--dsw-alias-label-secondary,#6b7280);cursor:pointer;white-space:nowrap;background:0 0;border-radius:6px;align-items:center;gap:4px;padding:0 8px;font-size:12px;display:inline-flex}.Klmgza_freeze:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,#0000000a)}.Klmgza_freeze[aria-pressed=true]{border-color:var(--dsw-alias-state-success-primary,#30a46c);color:var(--dsw-alias-state-success-primary,#30a46c);background:color-mix(in srgb, var(--dsw-alias-state-success-primary,#30a46c) 8%, transparent)}.Klmgza_label{font-size:12px}";
|
|
1173
1223
|
const tagId = "dsh-input-traffic/freeze-button.module.css";
|
|
1174
1224
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
1175
1225
|
const tag = document.createElement("style");
|
|
@@ -1193,13 +1243,21 @@ window.__ModuleLoader__.load({
|
|
|
1193
1243
|
* the shared store), so the driver finds no pending work and stops after the
|
|
1194
1244
|
* current turn. Resume re-submits the preserved texts, waking the driver and
|
|
1195
1245
|
* continuing the queue.
|
|
1246
|
+
*
|
|
1247
|
+
* dsh-session-guard 协作(D8 fail-open):
|
|
1248
|
+
* - 冻结 = 前端摘队列(本插件)+ composer block(阻止新输入漏进对话) + 尽力调服务端
|
|
1249
|
+
* sessionGuard.stopNextTurn(停掉 session 下一回合;session-guard 未装时静默跳过)。
|
|
1250
|
+
* - 解冻 = 清 composer block + **先** await sessionGuard.resume(让被打断回合的自然
|
|
1251
|
+
* 下一步先发生),**再**重投队列(later 级条目因此排在自然 next turn 之后,不再插队)。
|
|
1252
|
+
* - 本插件只做冻结增强,不承担重试/暂停决策(归后端,D9)。
|
|
1196
1253
|
*/
|
|
1197
1254
|
/**
|
|
1198
1255
|
* Freeze/resume toggle for the peak-hour scenario.
|
|
1199
1256
|
* @param props - slot props; the session snapshot drives the detach list.
|
|
1200
1257
|
*/
|
|
1201
|
-
function FreezeButton({ session, updateQueue, cancel, send, sendSteer, notify, t }) {
|
|
1202
|
-
const
|
|
1258
|
+
function FreezeButton({ session, updateQueue, cancel, send, sendSteer, sessionId, setComposerBlock, notify, t }) {
|
|
1259
|
+
const sid = sessionId ?? "";
|
|
1260
|
+
const { frozen } = (0, react.useSyncExternalStore)(freezeStore.subscribe, () => freezeStore.getSnapshot(sid));
|
|
1203
1261
|
const freeze = async () => {
|
|
1204
1262
|
const rows = session.queue.filter((row) => row.placement === "queued" || row.placement === "steering");
|
|
1205
1263
|
const pending = rows.flatMap((row) => row.text === null ? [] : [{
|
|
@@ -1207,21 +1265,25 @@ window.__ModuleLoader__.load({
|
|
|
1207
1265
|
tier: row.placement === "steering" ? "safe_point" : "queue"
|
|
1208
1266
|
}]);
|
|
1209
1267
|
await Promise.all(rows.map((row) => updateQueue(row.id, { kind: "remove" }).catch(() => void 0)));
|
|
1210
|
-
freezeStore.set({
|
|
1268
|
+
freezeStore.set(sid, {
|
|
1211
1269
|
frozen: true,
|
|
1212
1270
|
pending
|
|
1213
1271
|
});
|
|
1272
|
+
setComposerBlock?.(t("steer.frozenInput"));
|
|
1273
|
+
if (sessionId !== void 0) sessionGuardStopNextTurn(sessionId);
|
|
1214
1274
|
};
|
|
1215
1275
|
const resume = async () => {
|
|
1216
|
-
const pending = freezeStore.getSnapshot().pending;
|
|
1217
|
-
freezeStore.set({
|
|
1276
|
+
const pending = freezeStore.getSnapshot(sid).pending;
|
|
1277
|
+
freezeStore.set(sid, {
|
|
1218
1278
|
frozen: false,
|
|
1219
1279
|
pending: []
|
|
1220
1280
|
});
|
|
1281
|
+
setComposerBlock?.(void 0);
|
|
1221
1282
|
try {
|
|
1283
|
+
if (sessionId !== void 0) await sessionGuardResume(sessionId);
|
|
1222
1284
|
for (const entry of pending) {
|
|
1223
1285
|
if (entry.tier === "force") await cancel();
|
|
1224
|
-
if (entry.tier === "safe_point") await sendSteer(entry.text);
|
|
1286
|
+
if (entry.tier === "safe_point" && sendSteer !== void 0) await sendSteer(entry.text);
|
|
1225
1287
|
else await send(entry.text);
|
|
1226
1288
|
}
|
|
1227
1289
|
} catch {
|
|
@@ -1264,21 +1326,10 @@ window.__ModuleLoader__.load({
|
|
|
1264
1326
|
* @param actx - agent-scoped context of the owning session.
|
|
1265
1327
|
* @param text - message text to deliver.
|
|
1266
1328
|
*/
|
|
1267
|
-
function steerPrompt(
|
|
1268
|
-
const
|
|
1269
|
-
if (
|
|
1270
|
-
return
|
|
1271
|
-
type: "text",
|
|
1272
|
-
text
|
|
1273
|
-
}], "steer").then((result) => {
|
|
1274
|
-
if (!result.ok) {
|
|
1275
|
-
const error = result.error ?? {
|
|
1276
|
-
code: "unknown",
|
|
1277
|
-
message: "steer prompt rejected"
|
|
1278
|
-
};
|
|
1279
|
-
throw new Error(`conversation.sendSteer failed: ${error.code}: ${error.message}`);
|
|
1280
|
-
}
|
|
1281
|
-
});
|
|
1329
|
+
function steerPrompt(actx, text) {
|
|
1330
|
+
const conversation = actx.get("conversation");
|
|
1331
|
+
if (conversation === void 0) return Promise.reject(/* @__PURE__ */ new Error("steer resume: conversation service unavailable"));
|
|
1332
|
+
return conversation.send(text);
|
|
1282
1333
|
}
|
|
1283
1334
|
/** Services required by the browser half. */
|
|
1284
1335
|
const inject = [
|
|
@@ -1314,7 +1365,6 @@ window.__ModuleLoader__.load({
|
|
|
1314
1365
|
updateQueue: (itemId, action) => conversation.updateQueue(itemId, action),
|
|
1315
1366
|
cancel: () => conversation.cancel(),
|
|
1316
1367
|
send: (text) => conversation.send(text),
|
|
1317
|
-
sendSteer: (text) => steerPrompt(ctx, actx, text),
|
|
1318
1368
|
setDraft: (text) => {
|
|
1319
1369
|
conversation.input.for(actx).actions.setDraft(text);
|
|
1320
1370
|
},
|
|
@@ -1338,12 +1388,16 @@ window.__ModuleLoader__.load({
|
|
|
1338
1388
|
updateQueue: (itemId, action) => conversation.updateQueue(itemId, action),
|
|
1339
1389
|
cancel: () => conversation.cancel(),
|
|
1340
1390
|
send: (text) => conversation.send(text),
|
|
1341
|
-
sendSteer: (text) => steerPrompt(
|
|
1391
|
+
sendSteer: (text) => steerPrompt(actx, text),
|
|
1392
|
+
sessionId: String(sessionId),
|
|
1342
1393
|
setDraft: (text) => {
|
|
1343
1394
|
conversation.input.for(actx).actions.setDraft(text);
|
|
1344
1395
|
},
|
|
1345
1396
|
notify: (level, text) => {
|
|
1346
1397
|
conversation.input.for(actx).notify(level, text);
|
|
1398
|
+
},
|
|
1399
|
+
setComposerBlock: (reason) => {
|
|
1400
|
+
conversation.blocks.set(sessionId, reason === void 0 ? void 0 : { reason });
|
|
1347
1401
|
}
|
|
1348
1402
|
};
|
|
1349
1403
|
}
|