@flowingspring/dsh-voco 0.3.9 → 0.3.11
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 +2 -2
- package/README.zh.md +2 -2
- package/lib/client.js +43 -478
- package/lib/client.js.map +1 -1
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -6,7 +6,6 @@ window.__ModuleLoader__.load({
|
|
|
6
6
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
7
|
let react = require("react");
|
|
8
8
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
9
|
-
let react_dom_client = require("react-dom/client");
|
|
10
9
|
let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
11
10
|
let _deepseek_ai_dsh_client_runtime_client = require("@deepseek-ai/dsh-client-runtime/client");
|
|
12
11
|
//#region \0dsh-css:D:\QUAN\DevCode\Python\Project\dsh\dsh-voco\packages\ui-voice\src\client\VoiceControl.module.css.mjs
|
|
@@ -20,11 +19,11 @@ window.__ModuleLoader__.load({
|
|
|
20
19
|
document.head.appendChild(tag);
|
|
21
20
|
}
|
|
22
21
|
var VoiceControl_module_css_default = {
|
|
23
|
-
"active": "TFZsua_active",
|
|
24
22
|
"voice-pulse": "TFZsua_voice-pulse",
|
|
23
|
+
"active": "TFZsua_active",
|
|
25
24
|
"controls": "TFZsua_controls",
|
|
26
|
-
"
|
|
27
|
-
"
|
|
25
|
+
"button": "TFZsua_button",
|
|
26
|
+
"interruptButton": "TFZsua_interruptButton"
|
|
28
27
|
};
|
|
29
28
|
//#endregion
|
|
30
29
|
//#region ../ui-voice/src/client/VoiceControl.tsx
|
|
@@ -223,23 +222,23 @@ window.__ModuleLoader__.load({
|
|
|
223
222
|
document.head.appendChild(tag);
|
|
224
223
|
}
|
|
225
224
|
var VoiceNodeViews_module_css_default = {
|
|
226
|
-
"
|
|
227
|
-
"
|
|
228
|
-
"bubble": "Kt2smW_bubble",
|
|
229
|
-
"taskActions": "Kt2smW_taskActions",
|
|
230
|
-
"taskChevron": "Kt2smW_taskChevron",
|
|
231
|
-
"taskLink": "Kt2smW_taskLink",
|
|
225
|
+
"taskDetails": "Kt2smW_taskDetails",
|
|
226
|
+
"taskUpdate": "Kt2smW_taskUpdate",
|
|
232
227
|
"utterance": "Kt2smW_utterance",
|
|
228
|
+
"miniWave": "Kt2smW_miniWave",
|
|
229
|
+
"voiceBadge": "Kt2smW_voiceBadge",
|
|
233
230
|
"taskCard": "Kt2smW_taskCard",
|
|
231
|
+
"taskTitle": "Kt2smW_taskTitle",
|
|
232
|
+
"taskChevron": "Kt2smW_taskChevron",
|
|
233
|
+
"bubble": "Kt2smW_bubble",
|
|
234
|
+
"taskDot": "Kt2smW_taskDot",
|
|
235
|
+
"taskInput": "Kt2smW_taskInput",
|
|
234
236
|
"taskStatus": "Kt2smW_taskStatus",
|
|
235
|
-
"taskCancel": "Kt2smW_taskCancel",
|
|
236
237
|
"taskSummary": "Kt2smW_taskSummary",
|
|
238
|
+
"taskLink": "Kt2smW_taskLink",
|
|
237
239
|
"meta": "Kt2smW_meta",
|
|
238
|
-
"
|
|
239
|
-
"
|
|
240
|
-
"taskDetails": "Kt2smW_taskDetails",
|
|
241
|
-
"voiceBadge": "Kt2smW_voiceBadge",
|
|
242
|
-
"taskUpdate": "Kt2smW_taskUpdate"
|
|
240
|
+
"taskCancel": "Kt2smW_taskCancel",
|
|
241
|
+
"taskActions": "Kt2smW_taskActions"
|
|
243
242
|
};
|
|
244
243
|
//#endregion
|
|
245
244
|
//#region ../ui-voice/src/client/VoiceNodeViews.tsx
|
|
@@ -378,9 +377,9 @@ window.__ModuleLoader__.load({
|
|
|
378
377
|
}
|
|
379
378
|
var VoiceOverlay_module_css_default = {
|
|
380
379
|
"root": "GPPB2G_root",
|
|
381
|
-
"voice-wave": "GPPB2G_voice-wave",
|
|
382
|
-
"wave": "GPPB2G_wave",
|
|
383
380
|
"status": "GPPB2G_status",
|
|
381
|
+
"wave": "GPPB2G_wave",
|
|
382
|
+
"voice-wave": "GPPB2G_voice-wave",
|
|
384
383
|
"stop": "GPPB2G_stop"
|
|
385
384
|
};
|
|
386
385
|
//#endregion
|
|
@@ -430,7 +429,7 @@ window.__ModuleLoader__.load({
|
|
|
430
429
|
}
|
|
431
430
|
//#endregion
|
|
432
431
|
//#region \0dsh-css:D:\QUAN\DevCode\Python\Project\dsh\dsh-voco\packages\ui-voice\src\client\VoiceSessionMarkers.module.css.mjs
|
|
433
|
-
const css$1 = "._0brRca_slot{flex:none;justify-content:center;align-items:center;width:16px;height:20px;display:inline-flex}._0brRca_marker{width:16px;height:16px;color:var(--dsw-alias-state-business-primary);pointer-events:none;justify-content:center;align-items:center;display:inline-flex}._0brRca_marker svg{width:14px;height:14px;display:block}
|
|
432
|
+
const css$1 = "._0brRca_slot{flex:none;justify-content:center;align-items:center;width:16px;height:20px;display:inline-flex}._0brRca_marker{width:16px;height:16px;color:var(--dsw-alias-state-business-primary);pointer-events:none;justify-content:center;align-items:center;display:inline-flex}._0brRca_marker svg{width:14px;height:14px;display:block}";
|
|
434
433
|
const tagId$1 = "@flowingspring/dsh-voco/VoiceSessionMarkers.module.css";
|
|
435
434
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
|
|
436
435
|
const tag = document.createElement("style");
|
|
@@ -440,39 +439,25 @@ window.__ModuleLoader__.load({
|
|
|
440
439
|
document.head.appendChild(tag);
|
|
441
440
|
}
|
|
442
441
|
var VoiceSessionMarkers_module_css_default = {
|
|
443
|
-
"children": "_0brRca_children",
|
|
444
442
|
"marker": "_0brRca_marker",
|
|
445
|
-
"
|
|
446
|
-
"childMain": "_0brRca_childMain",
|
|
447
|
-
"childLabel": "_0brRca_childLabel",
|
|
448
|
-
"childActions": "_0brRca_childActions",
|
|
449
|
-
"childTime": "_0brRca_childTime",
|
|
450
|
-
"toggle": "_0brRca_toggle",
|
|
451
|
-
"childMenuButton": "_0brRca_childMenuButton",
|
|
452
|
-
"slot": "_0brRca_slot",
|
|
453
|
-
"childDot": "_0brRca_childDot",
|
|
454
|
-
"deleteAction": "_0brRca_deleteAction",
|
|
455
|
-
"deleteStatus": "_0brRca_deleteStatus",
|
|
456
|
-
"deleteError": "_0brRca_deleteError"
|
|
443
|
+
"slot": "_0brRca_slot"
|
|
457
444
|
};
|
|
458
445
|
//#endregion
|
|
459
446
|
//#region ../ui-voice/src/client/VoiceSessionMarkers.tsx
|
|
460
447
|
/**
|
|
461
|
-
* The workspace package
|
|
462
|
-
* subagent children from its top-level list. This decorator adds the
|
|
463
|
-
* marker
|
|
464
|
-
*
|
|
448
|
+
* The workspace package owns the session-row renderer and filters addressed
|
|
449
|
+
* subagent children from its top-level list. This decorator only adds the
|
|
450
|
+
* Voice marker. The child catalog is still refreshed here because the
|
|
451
|
+
* conversation's top task cards use it to enable navigation, but child rows
|
|
452
|
+
* are intentionally not duplicated in the sidebar.
|
|
465
453
|
*/
|
|
466
|
-
function VoiceSessionMarkers({ useSessions,
|
|
454
|
+
function VoiceSessionMarkers({ useSessions, useVoiceHistory, refreshSubagents }) {
|
|
467
455
|
const sessions = useSessions((state) => state);
|
|
468
|
-
const archivedSessionIds = useWorkspaces((state) => state.archivedSessionIds);
|
|
469
456
|
const history = useVoiceHistory((state) => state);
|
|
470
|
-
const expandedParents = (0, react.useRef)(/* @__PURE__ */ new Set());
|
|
471
457
|
const requestedParents = (0, react.useRef)(/* @__PURE__ */ new Set());
|
|
472
458
|
(0, react.useEffect)(() => {
|
|
473
459
|
const voiceTitles = new Set(history.entries.map((entry) => entry.sessionId));
|
|
474
460
|
for (const entry of history.taskActivity ?? []) if (entry.parentSessionId !== void 0) voiceTitles.add(entry.parentSessionId);
|
|
475
|
-
const taskActivity = new Map((history.taskActivity ?? []).map((entry) => [entry.sessionId, entry.lastActiveAt]));
|
|
476
461
|
const sessionIds = new Set(Object.keys(sessions.byId));
|
|
477
462
|
for (const parentId of voiceTitles) if (!requestedParents.current.has(parentId)) {
|
|
478
463
|
requestedParents.current.add(parentId);
|
|
@@ -488,34 +473,10 @@ window.__ModuleLoader__.load({
|
|
|
488
473
|
const sessionId = findSessionKey(row, sessionIds);
|
|
489
474
|
if (!(sessionId !== void 0 && voiceTitles.has(sessionId))) {
|
|
490
475
|
marker?.remove();
|
|
491
|
-
row.querySelector("[data-voice-subagent-toggle]")?.remove();
|
|
492
|
-
removeSubagentList(row, sessionId);
|
|
493
476
|
continue;
|
|
494
477
|
}
|
|
495
478
|
const target = slot ?? createMarkerSlot(row);
|
|
496
479
|
if (marker === null) target.append(createMarker());
|
|
497
|
-
const parentId = sessionId;
|
|
498
|
-
const catalog = sessions.subagentsByParent[parentId];
|
|
499
|
-
const expanded = expandedParents.current.has(parentId);
|
|
500
|
-
const toggle = row.querySelector("[data-voice-subagent-toggle]") ?? createSubagentToggle(parentId, expanded, () => {
|
|
501
|
-
const next = !expandedParents.current.has(parentId);
|
|
502
|
-
if (next) expandedParents.current.add(parentId);
|
|
503
|
-
else expandedParents.current.delete(parentId);
|
|
504
|
-
setSubagentCatalogOpen(parentId, next);
|
|
505
|
-
if (next) refreshSubagents(parentId);
|
|
506
|
-
decorate();
|
|
507
|
-
});
|
|
508
|
-
updateSubagentToggle(toggle, parentId, expanded, () => {
|
|
509
|
-
const next = !expandedParents.current.has(parentId);
|
|
510
|
-
if (next) expandedParents.current.add(parentId);
|
|
511
|
-
else expandedParents.current.delete(parentId);
|
|
512
|
-
setSubagentCatalogOpen(parentId, next);
|
|
513
|
-
if (next) refreshSubagents(parentId);
|
|
514
|
-
decorate();
|
|
515
|
-
});
|
|
516
|
-
const title = row.querySelector("[class*=\"title\"]");
|
|
517
|
-
if (toggle.parentElement !== row) row.insertBefore(toggle, title ?? null);
|
|
518
|
-
renderSubagentChildren(row, parentId, catalog?.entries ?? [], expanded, sessions.current, sessions.byId, new Set(archivedSessionIds), taskActivity, openSession, childActions);
|
|
519
480
|
}
|
|
520
481
|
};
|
|
521
482
|
const schedule = () => {
|
|
@@ -525,18 +486,6 @@ window.__ModuleLoader__.load({
|
|
|
525
486
|
decorate();
|
|
526
487
|
const clock = window.setInterval(schedule, 6e4);
|
|
527
488
|
const observer = new MutationObserver(schedule);
|
|
528
|
-
const suppressChildHover = (event) => {
|
|
529
|
-
const target = event.target;
|
|
530
|
-
if (!(target instanceof Element)) return;
|
|
531
|
-
const child = target.closest("[data-voice-subagent-child]");
|
|
532
|
-
if (child === null) return;
|
|
533
|
-
event.stopPropagation();
|
|
534
|
-
suppressHostHover(child);
|
|
535
|
-
};
|
|
536
|
-
document.addEventListener("pointerover", suppressChildHover, true);
|
|
537
|
-
document.addEventListener("mouseover", suppressChildHover, true);
|
|
538
|
-
document.addEventListener("pointerenter", suppressChildHover, true);
|
|
539
|
-
document.addEventListener("mouseenter", suppressChildHover, true);
|
|
540
489
|
observer.observe(document.body, {
|
|
541
490
|
childList: true,
|
|
542
491
|
subtree: true,
|
|
@@ -544,10 +493,6 @@ window.__ModuleLoader__.load({
|
|
|
544
493
|
});
|
|
545
494
|
return () => {
|
|
546
495
|
observer.disconnect();
|
|
547
|
-
document.removeEventListener("pointerover", suppressChildHover, true);
|
|
548
|
-
document.removeEventListener("mouseover", suppressChildHover, true);
|
|
549
|
-
document.removeEventListener("pointerenter", suppressChildHover, true);
|
|
550
|
-
document.removeEventListener("mouseenter", suppressChildHover, true);
|
|
551
496
|
window.clearInterval(clock);
|
|
552
497
|
if (frame !== 0) cancelAnimationFrame(frame);
|
|
553
498
|
document.querySelectorAll("[data-voice-session-marker]").forEach((node) => {
|
|
@@ -556,340 +501,17 @@ window.__ModuleLoader__.load({
|
|
|
556
501
|
document.querySelectorAll("[data-voice-session-marker-slot]").forEach((node) => {
|
|
557
502
|
node.remove();
|
|
558
503
|
});
|
|
559
|
-
document.querySelectorAll("[data-voice-subagent-list]").forEach((node) => {
|
|
560
|
-
unmountChildMenus(node);
|
|
561
|
-
node.remove();
|
|
562
|
-
});
|
|
563
|
-
document.querySelectorAll("[data-voice-subagent-toggle]").forEach((node) => {
|
|
504
|
+
document.querySelectorAll("[data-voice-subagent-list], [data-voice-subagent-toggle], [data-voice-subagent-child]").forEach((node) => {
|
|
564
505
|
node.remove();
|
|
565
506
|
});
|
|
566
507
|
};
|
|
567
508
|
}, [
|
|
568
509
|
history,
|
|
569
510
|
sessions,
|
|
570
|
-
|
|
571
|
-
openSession,
|
|
572
|
-
childActions,
|
|
573
|
-
refreshSubagents,
|
|
574
|
-
setSubagentCatalogOpen
|
|
511
|
+
refreshSubagents
|
|
575
512
|
]);
|
|
576
513
|
return null;
|
|
577
514
|
}
|
|
578
|
-
function createSubagentToggle(parentId, expanded, onClick) {
|
|
579
|
-
const button = document.createElement("button");
|
|
580
|
-
button.type = "button";
|
|
581
|
-
button.dataset.voiceSubagentToggle = "";
|
|
582
|
-
button.className = VoiceSessionMarkers_module_css_default.toggle ?? "voice-subagent-toggle";
|
|
583
|
-
updateSubagentToggle(button, parentId, expanded, onClick);
|
|
584
|
-
button.onclick = (event) => {
|
|
585
|
-
event.stopPropagation();
|
|
586
|
-
onClick();
|
|
587
|
-
};
|
|
588
|
-
button.dataset.parentSessionId = parentId;
|
|
589
|
-
return button;
|
|
590
|
-
}
|
|
591
|
-
function updateSubagentToggle(button, parentId, expanded, onClick) {
|
|
592
|
-
button.dataset.parentSessionId = parentId;
|
|
593
|
-
const label = expanded ? "收起语音子会话" : "展开语音子会话";
|
|
594
|
-
if (button.getAttribute("aria-label") !== label) button.setAttribute("aria-label", label);
|
|
595
|
-
const expandedValue = String(expanded);
|
|
596
|
-
if (button.getAttribute("aria-expanded") !== expandedValue) button.setAttribute("aria-expanded", expandedValue);
|
|
597
|
-
if (button.title !== label) button.title = label;
|
|
598
|
-
const icon = expanded ? "⌄" : "›";
|
|
599
|
-
if (button.textContent !== icon) button.innerHTML = `<span aria-hidden="true">${icon}</span>`;
|
|
600
|
-
button.onclick = (event) => {
|
|
601
|
-
event.stopPropagation();
|
|
602
|
-
onClick();
|
|
603
|
-
};
|
|
604
|
-
}
|
|
605
|
-
function renderSubagentChildren(row, parentId, entries, expanded, current, summaries, archivedSessionIds, taskActivity, openSession, childActions) {
|
|
606
|
-
let list = findSubagentList(row, parentId);
|
|
607
|
-
if (!expanded) {
|
|
608
|
-
if (list !== void 0 && list !== null) unmountChildMenus(list);
|
|
609
|
-
list?.remove();
|
|
610
|
-
return;
|
|
611
|
-
}
|
|
612
|
-
if (list === null || list === void 0) {
|
|
613
|
-
list = document.createElement("div");
|
|
614
|
-
list.dataset.voiceSubagentList = String(parentId);
|
|
615
|
-
list.className = VoiceSessionMarkers_module_css_default.children ?? "voice-subagent-children";
|
|
616
|
-
row.parentElement?.insertBefore(list, row.nextSibling);
|
|
617
|
-
}
|
|
618
|
-
const children = entries.filter((entry) => entry.kind !== "parent" && !isSessionEffectivelyArchived(entry.id, archivedSessionIds, summaries, (id) => id === entry.id ? parentId : void 0));
|
|
619
|
-
const signature = children.map((entry) => `${entry.id}:${entry.label ?? ""}:${entry.activity ?? ""}:${childUpdatedAt(entry.id, entry, summaries, taskActivity) ?? ""}`).join("|");
|
|
620
|
-
if (list.dataset.signature === signature && list.dataset.current === String(current ?? "")) return;
|
|
621
|
-
list.dataset.signature = signature;
|
|
622
|
-
list.dataset.current = String(current ?? "");
|
|
623
|
-
unmountChildMenus(list);
|
|
624
|
-
list.replaceChildren(...children.map((entry) => {
|
|
625
|
-
const child = document.createElement("div");
|
|
626
|
-
child.className = VoiceSessionMarkers_module_css_default.child ?? "voice-subagent-child";
|
|
627
|
-
child.dataset.voiceSubagentChild = "";
|
|
628
|
-
child.dataset.sessionId = String(entry.id);
|
|
629
|
-
child.disabled = entry.kind !== "child";
|
|
630
|
-
if (entry.kind !== "child") child.dataset.state = "unavailable";
|
|
631
|
-
child.setAttribute("role", "treeitem");
|
|
632
|
-
child.tabIndex = entry.kind === "child" ? 0 : -1;
|
|
633
|
-
child.setAttribute("aria-current", entry.id === current ? "page" : "false");
|
|
634
|
-
const unavailableLabel = entry.kind === "diagnostic" ? "会话记录损坏" : "子会话暂时不可用";
|
|
635
|
-
const displayLabel = entry.label ?? (entry.kind === "child" ? String(entry.id) : unavailableLabel);
|
|
636
|
-
child.addEventListener("mouseenter", (event) => suppressHostHover(child, event), true);
|
|
637
|
-
child.addEventListener("mouseover", (event) => suppressHostHover(child, event), true);
|
|
638
|
-
child.addEventListener("pointerenter", (event) => suppressHostHover(child, event), true);
|
|
639
|
-
child.addEventListener("click", (event) => {
|
|
640
|
-
if (event.target !== child || entry.kind !== "child") return;
|
|
641
|
-
openSession(entry.id);
|
|
642
|
-
});
|
|
643
|
-
const dot = document.createElement("span");
|
|
644
|
-
dot.className = VoiceSessionMarkers_module_css_default.childDot ?? "voice-subagent-child-dot";
|
|
645
|
-
dot.dataset.activity = entry.activity ?? "inactive";
|
|
646
|
-
const label = document.createElement("span");
|
|
647
|
-
label.className = VoiceSessionMarkers_module_css_default.childLabel ?? "voice-subagent-child-label";
|
|
648
|
-
label.textContent = displayLabel;
|
|
649
|
-
const open = document.createElement("button");
|
|
650
|
-
open.type = "button";
|
|
651
|
-
open.className = VoiceSessionMarkers_module_css_default.childMain ?? "voice-subagent-child-main";
|
|
652
|
-
open.disabled = entry.kind !== "child";
|
|
653
|
-
open.append(dot, label);
|
|
654
|
-
child.append(open);
|
|
655
|
-
const updatedAt = childUpdatedAt(entry.id, entry, summaries, taskActivity);
|
|
656
|
-
if (updatedAt !== void 0) {
|
|
657
|
-
const time = document.createElement("span");
|
|
658
|
-
time.className = VoiceSessionMarkers_module_css_default.childTime ?? "voice-subagent-child-time";
|
|
659
|
-
time.dataset.voiceSubagentChildTime = "";
|
|
660
|
-
time.dataset.updatedAt = String(updatedAt);
|
|
661
|
-
time.textContent = relativeTimeLabel(updatedAt, Date.now());
|
|
662
|
-
open.append(time);
|
|
663
|
-
}
|
|
664
|
-
open.addEventListener("click", (event) => {
|
|
665
|
-
event.stopPropagation();
|
|
666
|
-
if (entry.kind !== "child") return;
|
|
667
|
-
openSession(entry.id);
|
|
668
|
-
});
|
|
669
|
-
if (entry.kind === "child") mountChildMenu(child, entry.id, displayLabel, childActions);
|
|
670
|
-
return child;
|
|
671
|
-
}));
|
|
672
|
-
}
|
|
673
|
-
function suppressHostHover(child, event) {
|
|
674
|
-
event?.stopPropagation();
|
|
675
|
-
child.dataset.voiceChildHover = "true";
|
|
676
|
-
const parentRow = child.closest("[data-voice-subagent-list]")?.previousElementSibling;
|
|
677
|
-
if (!(parentRow instanceof HTMLElement)) return;
|
|
678
|
-
const outside = document.body;
|
|
679
|
-
if (typeof PointerEvent === "function") {
|
|
680
|
-
parentRow.dispatchEvent(new PointerEvent("pointerleave", {
|
|
681
|
-
bubbles: false,
|
|
682
|
-
relatedTarget: outside
|
|
683
|
-
}));
|
|
684
|
-
parentRow.dispatchEvent(new PointerEvent("pointerout", {
|
|
685
|
-
bubbles: true,
|
|
686
|
-
relatedTarget: outside
|
|
687
|
-
}));
|
|
688
|
-
}
|
|
689
|
-
parentRow.dispatchEvent(new MouseEvent("mouseleave", {
|
|
690
|
-
bubbles: false,
|
|
691
|
-
relatedTarget: outside
|
|
692
|
-
}));
|
|
693
|
-
parentRow.dispatchEvent(new MouseEvent("mouseout", {
|
|
694
|
-
bubbles: true,
|
|
695
|
-
relatedTarget: outside
|
|
696
|
-
}));
|
|
697
|
-
}
|
|
698
|
-
const childMenuRoots = /* @__PURE__ */ new WeakMap();
|
|
699
|
-
function mountChildMenu(child, id, title, actions) {
|
|
700
|
-
const wrapper = document.createElement("span");
|
|
701
|
-
wrapper.className = VoiceSessionMarkers_module_css_default.childActions ?? "voice-subagent-child-actions";
|
|
702
|
-
wrapper.dataset.voiceChildMenuRoot = "";
|
|
703
|
-
child.append(wrapper);
|
|
704
|
-
const root = (0, react_dom_client.createRoot)(wrapper);
|
|
705
|
-
childMenuRoots.set(wrapper, root);
|
|
706
|
-
root.render(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(OfficialChildMenu, {
|
|
707
|
-
id,
|
|
708
|
-
title,
|
|
709
|
-
actions,
|
|
710
|
-
onOpenChange: (open) => {
|
|
711
|
-
child.dataset.menuOpen = String(open);
|
|
712
|
-
}
|
|
713
|
-
}));
|
|
714
|
-
}
|
|
715
|
-
function unmountChildMenus(list) {
|
|
716
|
-
list.querySelectorAll("[data-voice-child-menu-root]").forEach((root) => {
|
|
717
|
-
childMenuRoots.get(root)?.unmount();
|
|
718
|
-
childMenuRoots.delete(root);
|
|
719
|
-
});
|
|
720
|
-
}
|
|
721
|
-
function OfficialChildMenu({ id, title, actions, onOpenChange }) {
|
|
722
|
-
const [open, setOpen] = (0, react.useState)(false);
|
|
723
|
-
const [deleteOpen, setDeleteOpen] = (0, react.useState)(false);
|
|
724
|
-
const [deleting, setDeleting] = (0, react.useState)(false);
|
|
725
|
-
const [deleteError, setDeleteError] = (0, react.useState)(null);
|
|
726
|
-
const [actionError, setActionError] = (0, react.useState)(null);
|
|
727
|
-
const items = [
|
|
728
|
-
{
|
|
729
|
-
id: "rename",
|
|
730
|
-
label: "重命名",
|
|
731
|
-
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconEditOutline16, {})
|
|
732
|
-
},
|
|
733
|
-
{
|
|
734
|
-
id: "fork",
|
|
735
|
-
label: "分叉会话",
|
|
736
|
-
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconBranchOutline16, {})
|
|
737
|
-
},
|
|
738
|
-
...actions?.delete === void 0 ? [] : [{
|
|
739
|
-
id: "delete",
|
|
740
|
-
label: "删除会话",
|
|
741
|
-
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconTrashOutline16, {}),
|
|
742
|
-
danger: true
|
|
743
|
-
}]
|
|
744
|
-
];
|
|
745
|
-
const setMenuOpen = (next) => {
|
|
746
|
-
setOpen(next);
|
|
747
|
-
onOpenChange(next);
|
|
748
|
-
};
|
|
749
|
-
const closeDelete = () => {
|
|
750
|
-
if (deleting) return;
|
|
751
|
-
setDeleteOpen(false);
|
|
752
|
-
setDeleteError(null);
|
|
753
|
-
};
|
|
754
|
-
const confirmDelete = () => {
|
|
755
|
-
if (deleting || actions?.delete === void 0) return;
|
|
756
|
-
setDeleting(true);
|
|
757
|
-
setDeleteError(null);
|
|
758
|
-
actions.delete(id, title).then(() => {
|
|
759
|
-
setDeleting(false);
|
|
760
|
-
setDeleteOpen(false);
|
|
761
|
-
}, (cause) => {
|
|
762
|
-
setDeleting(false);
|
|
763
|
-
setDeleteError(cause instanceof Error ? cause.message : String(cause));
|
|
764
|
-
});
|
|
765
|
-
};
|
|
766
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
767
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Menu, {
|
|
768
|
-
open,
|
|
769
|
-
onClose: () => {
|
|
770
|
-
setMenuOpen(false);
|
|
771
|
-
},
|
|
772
|
-
items,
|
|
773
|
-
onSelect: (selected) => {
|
|
774
|
-
setMenuOpen(false);
|
|
775
|
-
setActionError(null);
|
|
776
|
-
if (selected === "delete") {
|
|
777
|
-
setDeleteError(null);
|
|
778
|
-
setDeleteOpen(true);
|
|
779
|
-
return;
|
|
780
|
-
}
|
|
781
|
-
(selected === "rename" ? (() => {
|
|
782
|
-
if (actions?.rename === void 0) return void 0;
|
|
783
|
-
const next = window.prompt("重命名会话", title);
|
|
784
|
-
return next === null ? void 0 : actions.rename(id, next);
|
|
785
|
-
})() : actions?.fork?.(id))?.catch((error) => {
|
|
786
|
-
console.warn("voice child action failed:", error);
|
|
787
|
-
setActionError(error instanceof Error ? error.message : String(error));
|
|
788
|
-
});
|
|
789
|
-
},
|
|
790
|
-
portal: true,
|
|
791
|
-
closeOnPointerLeave: true,
|
|
792
|
-
anchor: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
793
|
-
type: "button",
|
|
794
|
-
className: VoiceSessionMarkers_module_css_default.childMenuButton ?? "voice-subagent-child-menu-button",
|
|
795
|
-
"aria-label": `会话“${title}”的操作`,
|
|
796
|
-
onClick: (event) => {
|
|
797
|
-
event.stopPropagation();
|
|
798
|
-
setMenuOpen(!open);
|
|
799
|
-
},
|
|
800
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconEllipsisOutline16, {})
|
|
801
|
-
})
|
|
802
|
-
}),
|
|
803
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
804
|
-
open: deleteOpen,
|
|
805
|
-
onClose: closeDelete,
|
|
806
|
-
closeLabel: "关闭",
|
|
807
|
-
title: "删除会话",
|
|
808
|
-
description: `将永久删除会话“${title}”及其子代理(含正在运行的)和全部记录(对话内容、统计、缓存),此操作不可恢复。`,
|
|
809
|
-
footer: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
810
|
-
variant: "outline",
|
|
811
|
-
disabled: deleting,
|
|
812
|
-
onClick: closeDelete,
|
|
813
|
-
children: "取消"
|
|
814
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
815
|
-
variant: "outline",
|
|
816
|
-
className: VoiceSessionMarkers_module_css_default.deleteAction ?? "voice-subagent-delete-action",
|
|
817
|
-
disabled: deleting,
|
|
818
|
-
onClick: confirmDelete,
|
|
819
|
-
children: "删除会话"
|
|
820
|
-
})] }),
|
|
821
|
-
children: [deleting && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
822
|
-
className: VoiceSessionMarkers_module_css_default.deleteStatus,
|
|
823
|
-
role: "status",
|
|
824
|
-
children: "正在删除会话…"
|
|
825
|
-
}), deleteError !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
826
|
-
className: VoiceSessionMarkers_module_css_default.deleteError,
|
|
827
|
-
role: "alert",
|
|
828
|
-
children: ["删除会话失败:", deleteError]
|
|
829
|
-
})]
|
|
830
|
-
}),
|
|
831
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
832
|
-
open: actionError !== null,
|
|
833
|
-
onClose: () => {
|
|
834
|
-
setActionError(null);
|
|
835
|
-
},
|
|
836
|
-
closeLabel: "关闭",
|
|
837
|
-
title: "会话操作失败",
|
|
838
|
-
description: actionError ?? "",
|
|
839
|
-
footer: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
840
|
-
variant: "outline",
|
|
841
|
-
onClick: () => {
|
|
842
|
-
setActionError(null);
|
|
843
|
-
},
|
|
844
|
-
children: "关闭"
|
|
845
|
-
})
|
|
846
|
-
})
|
|
847
|
-
] });
|
|
848
|
-
}
|
|
849
|
-
function childUpdatedAt(id, entry, summaries, taskActivity) {
|
|
850
|
-
if (typeof entry.updatedAt === "number" && entry.updatedAt > 0) return entry.updatedAt;
|
|
851
|
-
const summaryTime = summaries[id]?.updatedAt;
|
|
852
|
-
if (typeof summaryTime === "number" && summaryTime > 0) return summaryTime;
|
|
853
|
-
const taskTime = taskActivity.get(id);
|
|
854
|
-
return typeof taskTime === "number" && taskTime > 0 ? taskTime : void 0;
|
|
855
|
-
}
|
|
856
|
-
/** Match the Host workspace's compact relative-time buckets for child rows. */
|
|
857
|
-
function relativeTimeLabel(updatedAt, now, language = typeof navigator !== "undefined" ? navigator.language : "en-US") {
|
|
858
|
-
const diff = Math.max(0, now - updatedAt);
|
|
859
|
-
const minute = 6e4;
|
|
860
|
-
const hour = 36e5;
|
|
861
|
-
const day = 864e5;
|
|
862
|
-
const chinese = language.toLowerCase().startsWith("zh");
|
|
863
|
-
if (diff < minute) return chinese ? "刚刚" : "now";
|
|
864
|
-
if (diff < hour) {
|
|
865
|
-
const n = Math.floor(diff / minute);
|
|
866
|
-
return chinese ? `${n}分钟` : `${n}min`;
|
|
867
|
-
}
|
|
868
|
-
if (diff < day) {
|
|
869
|
-
const n = Math.floor(diff / hour);
|
|
870
|
-
return chinese ? `${n}小时` : `${n}h`;
|
|
871
|
-
}
|
|
872
|
-
if (diff < 30 * day) {
|
|
873
|
-
const n = Math.floor(diff / day);
|
|
874
|
-
return chinese ? `${n}天` : `${n}d`;
|
|
875
|
-
}
|
|
876
|
-
if (diff < 365 * day) {
|
|
877
|
-
const n = Math.floor(diff / (30 * day));
|
|
878
|
-
return chinese ? `${n}个月` : `${n}mo`;
|
|
879
|
-
}
|
|
880
|
-
const n = Math.floor(diff / (365 * day));
|
|
881
|
-
return chinese ? `${n}年` : `${n}y`;
|
|
882
|
-
}
|
|
883
|
-
function findSubagentList(row, parentId) {
|
|
884
|
-
return [...row.parentElement?.querySelectorAll("[data-voice-subagent-list]") ?? []].find((candidate) => candidate.dataset.voiceSubagentList === String(parentId));
|
|
885
|
-
}
|
|
886
|
-
function removeSubagentList(row, parentId) {
|
|
887
|
-
if (parentId === void 0) return;
|
|
888
|
-
const list = findSubagentList(row, parentId);
|
|
889
|
-
if (list === void 0) return;
|
|
890
|
-
unmountChildMenus(list);
|
|
891
|
-
list.remove();
|
|
892
|
-
}
|
|
893
515
|
/** React keeps the keyed SessionNodeItem identity on the row's owner fiber. */
|
|
894
516
|
function findSessionKey(row, sessionIds) {
|
|
895
517
|
const fiberKey = Object.keys(row).find((key) => key.startsWith("__reactFiber$"));
|
|
@@ -928,29 +550,29 @@ window.__ModuleLoader__.load({
|
|
|
928
550
|
document.head.appendChild(tag);
|
|
929
551
|
}
|
|
930
552
|
var VocoSettingsCard_module_css_default = {
|
|
931
|
-
"
|
|
932
|
-
"badge": "G5LlXq_badge",
|
|
933
|
-
"discard": "G5LlXq_discard",
|
|
934
|
-
"providerDetail": "G5LlXq_providerDetail",
|
|
553
|
+
"readOnly": "G5LlXq_readOnly",
|
|
935
554
|
"body": "G5LlXq_body",
|
|
936
|
-
"
|
|
937
|
-
"
|
|
938
|
-
"card": "G5LlXq_card",
|
|
555
|
+
"fieldHead": "G5LlXq_fieldHead",
|
|
556
|
+
"failed": "G5LlXq_failed",
|
|
939
557
|
"chevron": "G5LlXq_chevron",
|
|
558
|
+
"pending": "G5LlXq_pending",
|
|
559
|
+
"discard": "G5LlXq_discard",
|
|
940
560
|
"name": "G5LlXq_name",
|
|
941
|
-
"header": "G5LlXq_header",
|
|
942
|
-
"description": "G5LlXq_description",
|
|
943
|
-
"input": "G5LlXq_input",
|
|
944
|
-
"hint": "G5LlXq_hint",
|
|
945
561
|
"footer": "G5LlXq_footer",
|
|
946
|
-
"pending": "G5LlXq_pending",
|
|
947
562
|
"cardOpen": "G5LlXq_cardOpen",
|
|
948
|
-
"
|
|
949
|
-
"badgeMuted": "G5LlXq_badgeMuted",
|
|
950
|
-
"fieldHead": "G5LlXq_fieldHead",
|
|
563
|
+
"save": "G5LlXq_save",
|
|
951
564
|
"headText": "G5LlXq_headText",
|
|
952
565
|
"chevronOpen": "G5LlXq_chevronOpen",
|
|
953
|
-
"
|
|
566
|
+
"header": "G5LlXq_header",
|
|
567
|
+
"badgeMuted": "G5LlXq_badgeMuted",
|
|
568
|
+
"hint": "G5LlXq_hint",
|
|
569
|
+
"providerDetail": "G5LlXq_providerDetail",
|
|
570
|
+
"badge": "G5LlXq_badge",
|
|
571
|
+
"input": "G5LlXq_input",
|
|
572
|
+
"providerDetails": "G5LlXq_providerDetails",
|
|
573
|
+
"field": "G5LlXq_field",
|
|
574
|
+
"card": "G5LlXq_card",
|
|
575
|
+
"description": "G5LlXq_description",
|
|
954
576
|
"label": "G5LlXq_label"
|
|
955
577
|
};
|
|
956
578
|
//#endregion
|
|
@@ -2395,22 +2017,6 @@ registerProcessor('dsh-pcm-capture', DshPcmCaptureProcessor)
|
|
|
2395
2017
|
};
|
|
2396
2018
|
}, "ui-voice: child model selection compatibility");
|
|
2397
2019
|
}
|
|
2398
|
-
function archiveManagerRegistry(ctx) {
|
|
2399
|
-
try {
|
|
2400
|
-
const registry = ctx.get("remote.workspaceRegistry");
|
|
2401
|
-
if (registry === null || typeof registry !== "object") return void 0;
|
|
2402
|
-
return registry;
|
|
2403
|
-
} catch {
|
|
2404
|
-
return;
|
|
2405
|
-
}
|
|
2406
|
-
}
|
|
2407
|
-
/** Call archive-manager's complete deletion path when its remote is installed. */
|
|
2408
|
-
async function deleteWithArchiveManager(ctx, sessionId) {
|
|
2409
|
-
const deleteSession = archiveManagerRegistry(ctx)?.deleteSession;
|
|
2410
|
-
if (typeof deleteSession !== "function") throw new Error("archive-manager 删除服务不可用");
|
|
2411
|
-
const result = await deleteSession(sessionId);
|
|
2412
|
-
if (!result.ok) throw new Error(result.error?.message ?? "archive-manager 删除会话失败");
|
|
2413
|
-
}
|
|
2414
2020
|
/** Refresh the Host-backed Session list when the runtime exposes its baseline pull. */
|
|
2415
2021
|
function refreshSessions(ctx) {
|
|
2416
2022
|
const service = ctx.sessions;
|
|
@@ -2465,47 +2071,12 @@ registerProcessor('dsh-pcm-capture', DshPcmCaptureProcessor)
|
|
|
2465
2071
|
});
|
|
2466
2072
|
const voiceSessionMarkersInjected = () => ({
|
|
2467
2073
|
hooks: { voiceHistory: history.snapshot },
|
|
2468
|
-
childActions: {
|
|
2469
|
-
rename: async (id, title) => {
|
|
2470
|
-
const session = ensureChildSession(ctx, id);
|
|
2471
|
-
if (session === void 0) throw new Error(`unknown session "${id}"`);
|
|
2472
|
-
const result = await session.rename(title);
|
|
2473
|
-
if (!result.ok) throw new Error(result.error.message);
|
|
2474
|
-
},
|
|
2475
|
-
fork: async (id) => {
|
|
2476
|
-
ensureChildSession(ctx, id);
|
|
2477
|
-
const childId = await ctx.sessions.fork({
|
|
2478
|
-
sessionId: id,
|
|
2479
|
-
increaseTitle: true
|
|
2480
|
-
});
|
|
2481
|
-
ctx.sessions.open(childId);
|
|
2482
|
-
},
|
|
2483
|
-
...archiveManagerRegistry(ctx)?.deleteSession === void 0 ? {} : { delete: async (id) => {
|
|
2484
|
-
const parentId = ctx.sessions.navigationAddress?.(id)?.parentSessionId;
|
|
2485
|
-
await deleteWithArchiveManager(ctx, id);
|
|
2486
|
-
refreshSessions(ctx);
|
|
2487
|
-
if (parentId !== void 0) await ctx.sessions.refreshSubagents?.call(ctx.sessions, parentId);
|
|
2488
|
-
} }
|
|
2489
|
-
},
|
|
2490
|
-
openSession: (id) => {
|
|
2491
|
-
if (isEffectivelyArchivedInContext(ctx, id)) return;
|
|
2492
|
-
const sessions = ctx.sessions;
|
|
2493
|
-
const address = sessions.navigationAddress?.(id) ?? sessions.subagentAddress?.(id);
|
|
2494
|
-
if (address !== void 0 && sessions.openSubagent !== void 0) {
|
|
2495
|
-
sessions.openSubagent(address);
|
|
2496
|
-
return;
|
|
2497
|
-
}
|
|
2498
|
-
ctx.sessions.open(id);
|
|
2499
|
-
},
|
|
2500
2074
|
refreshSubagents: (parentSessionId) => {
|
|
2501
2075
|
const refresh = ctx.sessions.refreshSubagents;
|
|
2502
2076
|
if (refresh === void 0) return;
|
|
2503
2077
|
refresh.call(ctx.sessions, parentSessionId).catch((error) => {
|
|
2504
2078
|
console.warn("voice subagent catalog refresh failed:", error);
|
|
2505
2079
|
});
|
|
2506
|
-
},
|
|
2507
|
-
setSubagentCatalogOpen: (parentSessionId, open) => {
|
|
2508
|
-
ctx.sessions.setSubagentCatalogOpen?.call(ctx.sessions, parentSessionId, open);
|
|
2509
2080
|
}
|
|
2510
2081
|
});
|
|
2511
2082
|
const utteranceInjected = () => ({ hooks: { voice: controller } });
|
|
@@ -2596,12 +2167,6 @@ registerProcessor('dsh-pcm-capture', DshPcmCaptureProcessor)
|
|
|
2596
2167
|
const sessions = ctx.sessions;
|
|
2597
2168
|
return isSessionEffectivelyArchived(sessionId, workspaces.list.getSnapshot().archivedSessionIds, snapshot.byId, (id) => sessions.navigationAddress?.(id)?.parentSessionId);
|
|
2598
2169
|
}
|
|
2599
|
-
function ensureChildSession(ctx, id) {
|
|
2600
|
-
const sessions = ctx.sessions;
|
|
2601
|
-
const address = sessions.navigationAddress?.(id);
|
|
2602
|
-
if (address !== void 0) sessions.openSubagent?.(address);
|
|
2603
|
-
return ctx.sessions.binding(id)?.session;
|
|
2604
|
-
}
|
|
2605
2170
|
//#endregion
|
|
2606
2171
|
exports.apply = apply;
|
|
2607
2172
|
exports.inject = inject;
|