dsh-liuying-voice 1.3.2 → 1.5.0

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
@@ -7,6 +7,7 @@ window.__ModuleLoader__.load({
7
7
  factory: (require) => {
8
8
  const React = require("react");
9
9
  const h = React.createElement;
10
+ const { createPortal } = require("react-dom");
10
11
 
11
12
  const FIELD_DEFS = [
12
13
  { key: "enabled", label: "启用", type: "boolean" },
@@ -616,6 +617,85 @@ window.__ModuleLoader__.load({
616
617
  );
617
618
  }
618
619
 
620
+ // 侧边栏底部按钮:点开弹窗显示独立设置页(不跳浏览器)
621
+ function SidebarButton() {
622
+ const [open, setOpen] = React.useState(false);
623
+ const overlay = open
624
+ ? h(
625
+ "div",
626
+ {
627
+ onClick: () => setOpen(false),
628
+ style: {
629
+ position: "fixed",
630
+ inset: 0,
631
+ zIndex: 9999,
632
+ background: "rgba(0,0,0,0.55)",
633
+ display: "flex",
634
+ alignItems: "center",
635
+ justifyContent: "center",
636
+ },
637
+ },
638
+ h(
639
+ "div",
640
+ {
641
+ onClick: (e) => e.stopPropagation(),
642
+ style: {
643
+ width: "min(900px, 92vw)",
644
+ height: "min(680px, 88vh)",
645
+ background: "#0f1417",
646
+ borderRadius: 12,
647
+ overflow: "hidden",
648
+ boxShadow: "0 24px 70px rgba(0,0,0,0.55)",
649
+ display: "flex",
650
+ flexDirection: "column",
651
+ },
652
+ },
653
+ h(
654
+ "div",
655
+ { style: { display: "flex", alignItems: "center", gap: 8, padding: "8px 12px", borderBottom: "1px solid #243036" } },
656
+ h("span", { style: { fontSize: 13, color: "#8fd8c8", flex: 1 } }, "流萤语音"),
657
+ h(
658
+ "button",
659
+ {
660
+ type: "button",
661
+ onClick: () => setOpen(false),
662
+ style: { border: "1px solid #2a383f", background: "#1c262b", color: "#cfe3e6", borderRadius: 6, padding: "4px 12px", cursor: "pointer" },
663
+ },
664
+ "关闭",
665
+ ),
666
+ ),
667
+ h("iframe", { src: "/liuying-voice", title: "liuying-voice", style: { flex: 1, border: 0, width: "100%", background: "#0f1417" } }),
668
+ ),
669
+ )
670
+ : null;
671
+ return h(
672
+ React.Fragment,
673
+ null,
674
+ h(
675
+ "button",
676
+ {
677
+ type: "button",
678
+ onClick: () => setOpen(true),
679
+ title: "流萤语音设置",
680
+ style: {
681
+ display: "flex",
682
+ alignItems: "center",
683
+ gap: 6,
684
+ padding: "4px 10px",
685
+ borderRadius: 6,
686
+ border: "1px solid var(--dsh-border, #555)",
687
+ background: "transparent",
688
+ color: "inherit",
689
+ cursor: "pointer",
690
+ fontSize: 12,
691
+ },
692
+ },
693
+ "🔊 流萤",
694
+ ),
695
+ open && typeof document !== "undefined" ? createPortal(overlay, document.body) : null,
696
+ );
697
+ }
698
+
619
699
  function apply(ctx) {
620
700
  const mount = () => {
621
701
  if (!ctx.slots?.register) return;
@@ -639,6 +719,20 @@ window.__ModuleLoader__.load({
639
719
  };
640
720
  });
641
721
 
722
+ ctx.slots.inject("sidebar.footer.action", () => {
723
+ if (!ctx.slots?.register) return () => {};
724
+ return ctx.slots.register(
725
+ {
726
+ name: "sidebar.footer.action",
727
+ id: "liuying-voice-footer",
728
+ order: 100,
729
+ label: () => "流萤语音",
730
+ inject: () => ({}),
731
+ },
732
+ SidebarButton,
733
+ );
734
+ });
735
+
642
736
  ctx.slots.inject("conversation.chat.assistant-actions", () => {
643
737
  if (!ctx.slots?.register) return () => {};
644
738
  return ctx.slots.register(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-liuying-voice",
3
- "version": "1.3.2",
3
+ "version": "1.5.0",
4
4
  "description": "流萤语音插件 for DeepSeek Harness:本地 edge-tts + RVC / GPT-SoVITS 双引擎,自带流萤参考音频、一键环境安装脚本、独立设置页面与 DSH 设置入口。开源 MIT。",
5
5
  "keywords": [
6
6
  "deepseek-harness",
@@ -1,4 +1,4 @@
1
- # ============================================================
1
+ # ============================================================
2
2
  # GPT-SoVITS 简易环境安装脚本(CPU 推理,配合 dsh-liuying-voice 使用)
3
3
  #
4
4
  # 做什么:
@@ -26,11 +26,29 @@ New-Item -ItemType Directory -Path $root -Force | Out-Null
26
26
 
27
27
  # 1. Python
28
28
  $python = $null
29
- foreach ($cand in @('python3.11', 'python3.10', 'python')) {
29
+ foreach ($cand in @('python3.11', 'python3.10')) {
30
30
  $cmd = Get-Command $cand -ErrorAction SilentlyContinue
31
31
  if ($cmd) { $python = $cmd.Source; break }
32
32
  }
33
- if (-not $python) { throw "需要 Python 3.10/3.11(GPT-SoVITS 依赖),请先安装并加入 PATH" }
33
+ if (-not $python) {
34
+ $pyDir = Join-Path $root 'python'
35
+ $pyExe = Join-Path $pyDir 'python.exe'
36
+ if (-not (Test-Path $pyExe)) {
37
+ Step '未找到 Python 3.10/3.11,下载便携版 3.11(约 10 MB)'
38
+ $zipFile = Join-Path $root 'python311-embed.zip'
39
+ Invoke-WebRequest -Uri 'https://www.python.org/ftp/python/3.11.9/python-3.11.9-embed-amd64.zip' -OutFile $zipFile -TimeoutSec 600
40
+ Expand-Archive -Path $zipFile -DestinationPath $pyDir -Force
41
+ $pth = Join-Path $pyDir 'python311._pth'
42
+ if (Test-Path $pth) {
43
+ $lines = Get-Content $pth | ForEach-Object { if ($_ -match '^#\s*import site') { 'import site' } else { $_ } }
44
+ [System.IO.File]::WriteAllLines($pth, $lines, (New-Object System.Text.UTF8Encoding($false)))
45
+ }
46
+ $gp = Join-Path $pyDir 'get-pip.py'
47
+ Invoke-WebRequest -Uri 'https://bootstrap.pypa.io/get-pip.py' -OutFile $gp -TimeoutSec 300
48
+ & $pyExe $gp --no-warn-script-location
49
+ }
50
+ $python = $pyExe
51
+ }
34
52
  Write-Host "Python: $python"
35
53
 
36
54
  # 2. 源码
@@ -41,18 +59,18 @@ if (-not (Test-Path (Join-Path $repo 'api_v2.py'))) {
41
59
  }
42
60
  if (-not (Test-Path (Join-Path $repo 'api_v2.py'))) { throw "源码下载失败,请检查网络或代理" }
43
61
 
44
- # 3. 虚拟环境
45
- $venv = Join-Path $root 'venv'
46
- if (-not (Test-Path (Join-Path $venv 'Scripts\python.exe'))) {
47
- Step '创建虚拟环境'
48
- & $python -m venv $venv
49
- }
50
- $py = Join-Path $venv 'Scripts\python.exe'
62
+ # 3. 依赖(直接装到检测到的 Python,便携版也不需要 venv)
63
+ $py = $python
51
64
  & $py -m pip install -U pip -i $pipIndex
65
+ # 先装 numpy:pyopenjtalk 等包构建时需要
66
+ & $py -m pip install numpy -i $pipIndex
52
67
 
53
- Step '安装推理依赖(阿里镜像)'
68
+ Step '安装推理依赖(阿里镜像;pyopenjtalk 若编译失败需要 VS Build Tools,会跳过继续)'
54
69
  & $py -m pip install -r (Join-Path $repo 'requirements.txt') -i $pipIndex
55
- & $py -m pip install torch torchaudio --index-url https://download.pytorch.org/whl/cpu
70
+ if ($LASTEXITCODE -ne 0) {
71
+ Write-Warning '部分依赖安装失败(pyopenjtalk 需要 C++ 构建工具),继续安装 torch,缺失的可稍后补'
72
+ }
73
+ & $py -m pip install torch==2.7.1 torchaudio==2.7.1 --index-url https://download.pytorch.org/whl/cpu
56
74
 
57
75
  # 4. 预训练
58
76
  $pretrained = Join-Path $repo 'GPT_SoVITS\pretrained_models'