@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/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
- "interruptButton": "TFZsua_interruptButton",
27
- "button": "TFZsua_button"
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
- "taskInput": "Kt2smW_taskInput",
227
- "taskDot": "Kt2smW_taskDot",
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
- "taskTitle": "Kt2smW_taskTitle",
239
- "miniWave": "Kt2smW_miniWave",
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}._0brRca_toggle{width:18px;height:18px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;border-radius:4px;flex:none;justify-content:center;align-items:center;margin-left:1px;padding:0;font-size:16px;line-height:16px;display:inline-flex}._0brRca_toggle:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}._0brRca_children{flex-direction:column;gap:2px;margin:2px 0 2px 20px;display:flex}._0brRca_child{min-width:0;height:30px;color:var(--dsw-alias-label-secondary);cursor:pointer;text-align:left;font:inherit;background:0 0;border:0;border-radius:8px;align-items:center;gap:8px;padding:0 10px 0 12px;display:flex;position:relative}._0brRca_childMain{min-width:0;height:30px;color:inherit;cursor:pointer;text-align:left;font:inherit;background:0 0;border:0;flex:1;align-items:center;gap:8px;padding:0;display:flex}._0brRca_child:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}._0brRca_childMain:disabled{color:var(--dsw-alias-label-tertiary);cursor:not-allowed;opacity:.72}._0brRca_child[aria-current=page]{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-selected)}._0brRca_childDot{background:var(--dsw-alias-label-tertiary);border-radius:50%;flex:none;width:6px;height:6px}._0brRca_childDot[data-activity=running]{background:var(--dsw-alias-state-success-primary)}._0brRca_childLabel{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}._0brRca_childTime{color:var(--dsw-alias-label-tertiary);flex:none;margin-left:auto;font-size:12px;line-height:20px}._0brRca_child[data-menu-open=true] ._0brRca_childTime,._0brRca_child:hover ._0brRca_childTime{display:none}._0brRca_childActions{flex:none;align-items:center;display:none;position:absolute;right:10px}._0brRca_child:hover ._0brRca_childActions,._0brRca_child[data-menu-open=true] ._0brRca_childActions{display:inline-flex}._0brRca_childMenuButton{width:16px;height:16px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;border-radius:4px;justify-content:center;align-items:center;padding:0;display:inline-flex}._0brRca_childMenuButton:hover{color:var(--dsw-alias-label-primary)}._0brRca_deleteAction:not(:disabled){color:var(--dsw-alias-state-error-primary)}._0brRca_deleteStatus{color:var(--dsw-alias-label-secondary);font-size:12px;line-height:18px}._0brRca_deleteError{color:var(--dsw-alias-state-error-primary);font-size:12px;line-height:18px}";
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
- "child": "_0brRca_child",
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 currently owns the session-row renderer and filters
462
- * subagent children from its top-level list. This decorator adds the voice
463
- * marker and a small parent-owned child tree. Child actions are forwarded to
464
- * the same runtime/registry operations used by the Host row menu.
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, useWorkspaces, useVoiceHistory, openSession, childActions, refreshSubagents, setSubagentCatalogOpen }) {
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
- archivedSessionIds,
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
- "field": "G5LlXq_field",
932
- "badge": "G5LlXq_badge",
933
- "discard": "G5LlXq_discard",
934
- "providerDetail": "G5LlXq_providerDetail",
553
+ "readOnly": "G5LlXq_readOnly",
935
554
  "body": "G5LlXq_body",
936
- "providerDetails": "G5LlXq_providerDetails",
937
- "save": "G5LlXq_save",
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
- "failed": "G5LlXq_failed",
949
- "badgeMuted": "G5LlXq_badgeMuted",
950
- "fieldHead": "G5LlXq_fieldHead",
563
+ "save": "G5LlXq_save",
951
564
  "headText": "G5LlXq_headText",
952
565
  "chevronOpen": "G5LlXq_chevronOpen",
953
- "readOnly": "G5LlXq_readOnly",
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;