@coralai/sps-cli 0.59.0 → 0.60.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README-CN.md +20 -1
- package/README.md +20 -1
- package/dist/commands/agentRenderer.d.ts +1 -1
- package/dist/commands/agentRenderer.d.ts.map +1 -1
- package/dist/commands/consoleCommand.d.ts.map +1 -1
- package/dist/commands/consoleCommand.js +5 -12
- package/dist/commands/consoleCommand.js.map +1 -1
- package/dist/console/index.d.ts.map +1 -1
- package/dist/console/index.js +2 -0
- package/dist/console/index.js.map +1 -1
- package/dist/console/routes/cards.d.ts.map +1 -1
- package/dist/console/routes/cards.js +5 -0
- package/dist/console/routes/cards.js.map +1 -1
- package/dist/console/routes/chat.d.ts.map +1 -1
- package/dist/console/routes/chat.js +33 -5
- package/dist/console/routes/chat.js.map +1 -1
- package/dist/console/routes/flow.d.ts +10 -0
- package/dist/console/routes/flow.d.ts.map +1 -0
- package/dist/console/routes/flow.js +69 -0
- package/dist/console/routes/flow.js.map +1 -0
- package/dist/console/routes/tts.d.ts +3 -3
- package/dist/console/routes/tts.d.ts.map +1 -1
- package/dist/console/routes/tts.js +19 -16
- package/dist/console/routes/tts.js.map +1 -1
- package/dist/console-assets/assets/index-MCJOz4CB.css +10 -0
- package/dist/console-assets/assets/index-ejSTHvCc.js +859 -0
- package/dist/console-assets/index.html +2 -2
- package/dist/core/agents/DaemonBackend.d.ts +37 -0
- package/dist/core/agents/DaemonBackend.d.ts.map +1 -0
- package/dist/core/agents/DaemonBackend.js +169 -0
- package/dist/core/agents/DaemonBackend.js.map +1 -0
- package/dist/core/agents/resolveBackend.d.ts +1 -1
- package/dist/core/agents/resolveBackend.d.ts.map +1 -1
- package/dist/core/agents/resolveBackend.js +4 -0
- package/dist/core/agents/resolveBackend.js.map +1 -1
- package/dist/core/intel/agentsConfig.js +1 -1
- package/dist/core/intel/agentsConfig.js.map +1 -1
- package/dist/core/intel/types.d.ts +2 -2
- package/dist/core/intel/types.d.ts.map +1 -1
- package/dist/core/runtimeSnapshot.d.ts +1 -1
- package/dist/core/runtimeSnapshot.d.ts.map +1 -1
- package/dist/core/runtimeStore.d.ts +1 -1
- package/dist/core/runtimeStore.d.ts.map +1 -1
- package/dist/core/runtimeTypes.d.ts +109 -0
- package/dist/core/runtimeTypes.d.ts.map +1 -0
- package/dist/core/runtimeTypes.js +13 -0
- package/dist/core/runtimeTypes.js.map +1 -0
- package/dist/core/sessionContext.d.ts +1 -1
- package/dist/core/sessionContext.d.ts.map +1 -1
- package/dist/core/sessionLiveness.d.ts +1 -1
- package/dist/core/sessionLiveness.d.ts.map +1 -1
- package/dist/core/state.d.ts +1 -1
- package/dist/core/state.d.ts.map +1 -1
- package/dist/core/tts/DoubaoTts.d.ts +13 -0
- package/dist/core/tts/DoubaoTts.d.ts.map +1 -0
- package/dist/core/tts/DoubaoTts.js +84 -0
- package/dist/core/tts/DoubaoTts.js.map +1 -0
- package/dist/daemon/daemonClient.d.ts +4 -2
- package/dist/daemon/daemonClient.d.ts.map +1 -1
- package/dist/daemon/daemonClient.js.map +1 -1
- package/dist/daemon/sessionDaemon.d.ts +3 -0
- package/dist/daemon/sessionDaemon.d.ts.map +1 -1
- package/dist/daemon/sessionDaemon.js +58 -3
- package/dist/daemon/sessionDaemon.js.map +1 -1
- package/dist/engines/EventHandler.d.ts +0 -14
- package/dist/engines/EventHandler.d.ts.map +1 -1
- package/dist/engines/EventHandler.js +6 -58
- package/dist/engines/EventHandler.js.map +1 -1
- package/dist/engines/MonitorEngine.js.map +1 -1
- package/dist/engines/StageEngine.d.ts +4 -0
- package/dist/engines/StageEngine.d.ts.map +1 -1
- package/dist/engines/StageEngine.js +55 -3
- package/dist/engines/StageEngine.js.map +1 -1
- package/dist/main.js +1 -7
- package/dist/main.js.map +1 -1
- package/dist/providers/MarkdownTaskBackend.d.ts +9 -0
- package/dist/providers/MarkdownTaskBackend.d.ts.map +1 -1
- package/dist/providers/MarkdownTaskBackend.js +38 -2
- package/dist/providers/MarkdownTaskBackend.js.map +1 -1
- package/dist/providers/RuntimeSessionRuntime.d.ts +36 -0
- package/dist/providers/RuntimeSessionRuntime.d.ts.map +1 -0
- package/dist/providers/RuntimeSessionRuntime.js +182 -0
- package/dist/providers/RuntimeSessionRuntime.js.map +1 -0
- package/dist/providers/registry.d.ts +9 -5
- package/dist/providers/registry.d.ts.map +1 -1
- package/dist/providers/registry.js +6 -2
- package/dist/providers/registry.js.map +1 -1
- package/dist/providers/runtimeEventMap.d.ts +50 -0
- package/dist/providers/runtimeEventMap.d.ts.map +1 -0
- package/dist/providers/runtimeEventMap.js +77 -0
- package/dist/providers/runtimeEventMap.js.map +1 -0
- package/dist/services/CardService.d.ts +2 -0
- package/dist/services/CardService.d.ts.map +1 -1
- package/dist/services/CardService.js +29 -1
- package/dist/services/CardService.js.map +1 -1
- package/dist/services/ChatService.d.ts +5 -0
- package/dist/services/ChatService.d.ts.map +1 -1
- package/dist/services/ChatService.js +12 -1
- package/dist/services/ChatService.js.map +1 -1
- package/dist/shared/artifacts.d.ts +9 -0
- package/dist/shared/artifacts.d.ts.map +1 -0
- package/dist/shared/artifacts.js +53 -0
- package/dist/shared/artifacts.js.map +1 -0
- package/dist/shared/runtimePaths.d.ts +7 -0
- package/dist/shared/runtimePaths.d.ts.map +1 -1
- package/dist/shared/runtimePaths.js +11 -0
- package/dist/shared/runtimePaths.js.map +1 -1
- package/dist/shared/runtimeSchemas.d.ts +6 -6
- package/package.json +4 -3
- package/skills/registry.yaml +1 -0
- package/skills/sps-chat/SKILL.md +14 -4
- package/skills/writer/SKILL.md +30 -0
- package/dist/commands/kokoroCommand.d.ts +0 -2
- package/dist/commands/kokoroCommand.d.ts.map +0 -1
- package/dist/commands/kokoroCommand.js +0 -57
- package/dist/commands/kokoroCommand.js.map +0 -1
- package/dist/console-assets/assets/index-DuH78ueI.js +0 -792
- package/dist/console-assets/assets/index-Gf6wcGdR.css +0 -10
- package/dist/core/agents/sidecar/KokoroTtsManager.d.ts +0 -35
- package/dist/core/agents/sidecar/KokoroTtsManager.d.ts.map +0 -1
- package/dist/core/agents/sidecar/KokoroTtsManager.js +0 -263
- package/dist/core/agents/sidecar/KokoroTtsManager.js.map +0 -1
- package/sidecar/kokoro-tts/README.md +0 -31
- package/sidecar/kokoro-tts/requirements.txt +0 -4
- package/sidecar/kokoro-tts/server.py +0 -135
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
# Kokoro TTS 边车
|
|
2
|
-
|
|
3
|
-
sps-cli 的语音输出引擎(替代浏览器 Web Speech)。本地推理、中文优先。
|
|
4
|
-
|
|
5
|
-
- **模型**:Kokoro-82M v1.1-zh(StyleTTS2,ONNX),中文专业音色 `zf_*`/`zm_*`。
|
|
6
|
-
- **g2p**:misaki `ZHG2P(version="1.1")`(jieba + pypinyin),中文多音字/分词准。
|
|
7
|
-
- **形态**:纯 stdlib HTTP(`/healthz` + `POST /tts→wav`),不引 web 框架。
|
|
8
|
-
|
|
9
|
-
## 生命周期由 sps-cli 托管
|
|
10
|
-
|
|
11
|
-
不要手动跑本文件。装/起/停走:
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
sps kokoro setup # 建 venv + pip 安装 + 下载模型(~300MB,首次)
|
|
15
|
-
sps kokoro status # 查状态
|
|
16
|
-
sps kokoro stop # 停边车
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
`sps console` 启动时会在已安装的前提下自动拉起,退出时停。前端 `/api/tts` 反代到本边车。
|
|
20
|
-
|
|
21
|
-
## 手动自检
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
curl -s -X POST http://127.0.0.1:17650/tts \
|
|
25
|
-
-H 'content-type: application/json' \
|
|
26
|
-
-d '{"text":"你好,世界。今天天气不错。"}' -o /tmp/kokoro.wav
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
## 环境变量
|
|
30
|
-
|
|
31
|
-
见 `server.py` 顶部 docstring(端口/模型路径/默认音色)。管家 `KokoroTtsManager.ts` 是这些值的单一来源。
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
"""Kokoro TTS 边车 —— sps-cli 的语音输出引擎(中文优先)。
|
|
2
|
-
|
|
3
|
-
这是一个**纯 stdlib HTTP 服务**(除推理依赖 kokoro-onnx / misaki 外不引 web 框架):
|
|
4
|
-
- GET /healthz → 模型就绪后返回 200 "ok"(边车管家据此判活)
|
|
5
|
-
- POST /tts → {"text": "...", "voice"?: "zf_001", "speed"?: 1.0} → audio/wav
|
|
6
|
-
|
|
7
|
-
设计约束(见仓库 CLAUDE.md「红线」):这是 sps-cli 的**运行时执行 substrate**,只做
|
|
8
|
-
一件事——文字→音素(misaki 中文 g2p)→ Kokoro 合成 → WAV 字节。所有生命周期(装/起/停/
|
|
9
|
-
健康)由上层 KokoroTtsManager.ts 负责,本文件不管进程编排。
|
|
10
|
-
|
|
11
|
-
环境变量:
|
|
12
|
-
SPS_KOKORO_PORT 监听端口(默认 17650,与管家单一来源保持一致)
|
|
13
|
-
SPS_KOKORO_MODEL kokoro-v1.1-zh.onnx 路径
|
|
14
|
-
SPS_KOKORO_VOICES voices-v1.1-zh.bin 路径
|
|
15
|
-
SPS_KOKORO_CONFIG config.json 路径(中文 vocab)
|
|
16
|
-
SPS_KOKORO_VOICE 默认音色 id(默认 zf_001)
|
|
17
|
-
"""
|
|
18
|
-
|
|
19
|
-
from __future__ import annotations
|
|
20
|
-
|
|
21
|
-
import io
|
|
22
|
-
import json
|
|
23
|
-
import os
|
|
24
|
-
import sys
|
|
25
|
-
import threading
|
|
26
|
-
import wave
|
|
27
|
-
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
|
28
|
-
|
|
29
|
-
import numpy as np
|
|
30
|
-
from kokoro_onnx import Kokoro
|
|
31
|
-
from kokoro_onnx.tokenizer import Tokenizer
|
|
32
|
-
from misaki import zh
|
|
33
|
-
|
|
34
|
-
PORT = int(os.environ.get("SPS_KOKORO_PORT", "17650"))
|
|
35
|
-
MODEL = os.environ.get("SPS_KOKORO_MODEL", "kokoro-v1.1-zh.onnx")
|
|
36
|
-
VOICES = os.environ.get("SPS_KOKORO_VOICES", "voices-v1.1-zh.bin")
|
|
37
|
-
CONFIG = os.environ.get("SPS_KOKORO_CONFIG", "config.json")
|
|
38
|
-
DEFAULT_VOICE = os.environ.get("SPS_KOKORO_VOICE", "zf_001")
|
|
39
|
-
|
|
40
|
-
# 推理不保证线程安全(onnxruntime run 可并发,但 g2p 状态不一定),整体串行化。
|
|
41
|
-
# 前端本就逐句发,串行足够,且避免竞态。
|
|
42
|
-
_lock = threading.Lock()
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
def _load() -> tuple[Kokoro, "zh.ZHG2P"]:
|
|
46
|
-
print(f"[kokoro] loading model={MODEL} voices={VOICES}", file=sys.stderr, flush=True)
|
|
47
|
-
kokoro = Kokoro(MODEL, VOICES, vocab_config=CONFIG)
|
|
48
|
-
# 中文 g2p 只处理中文;夹在里面的英文段必须挂英文回退,否则被丢成 unk(❓)不发音。
|
|
49
|
-
# 复用 kokoro-onnx 自带的 espeak 分词器(同库、音素表对齐、无额外依赖)。
|
|
50
|
-
en_tok = Tokenizer()
|
|
51
|
-
g2p = zh.ZHG2P(version="1.1", en_callable=lambda en: en_tok.phonemize(en, lang="en-us"))
|
|
52
|
-
print("[kokoro] ready", file=sys.stderr, flush=True)
|
|
53
|
-
return kokoro, g2p
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
def _to_wav(samples: np.ndarray, sample_rate: int) -> bytes:
|
|
57
|
-
"""float32 [-1,1] → 16-bit PCM WAV 字节。"""
|
|
58
|
-
pcm = np.clip(np.asarray(samples, dtype=np.float32), -1.0, 1.0)
|
|
59
|
-
pcm16 = (pcm * 32767.0).astype("<i2")
|
|
60
|
-
buf = io.BytesIO()
|
|
61
|
-
with wave.open(buf, "wb") as wav:
|
|
62
|
-
wav.setnchannels(1)
|
|
63
|
-
wav.setsampwidth(2)
|
|
64
|
-
wav.setframerate(int(sample_rate))
|
|
65
|
-
wav.writeframes(pcm16.tobytes())
|
|
66
|
-
return buf.getvalue()
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
class Handler(BaseHTTPRequestHandler):
|
|
70
|
-
# 复用 server 实例上加载好的模型(见 main)。
|
|
71
|
-
kokoro: Kokoro
|
|
72
|
-
g2p: "zh.ZHG2P"
|
|
73
|
-
|
|
74
|
-
def log_message(self, *_args) -> None: # 静音默认访问日志(边车日志由管家收集)
|
|
75
|
-
pass
|
|
76
|
-
|
|
77
|
-
def _send(self, code: int, body: bytes, content_type: str) -> None:
|
|
78
|
-
self.send_response(code)
|
|
79
|
-
self.send_header("Content-Type", content_type)
|
|
80
|
-
self.send_header("Content-Length", str(len(body)))
|
|
81
|
-
self.end_headers()
|
|
82
|
-
self.wfile.write(body)
|
|
83
|
-
|
|
84
|
-
def do_GET(self) -> None:
|
|
85
|
-
if self.path == "/healthz":
|
|
86
|
-
self._send(200, b"ok", "text/plain")
|
|
87
|
-
else:
|
|
88
|
-
self._send(404, b"not found", "text/plain")
|
|
89
|
-
|
|
90
|
-
def do_POST(self) -> None:
|
|
91
|
-
if self.path != "/tts":
|
|
92
|
-
self._send(404, b"not found", "text/plain")
|
|
93
|
-
return
|
|
94
|
-
try:
|
|
95
|
-
length = int(self.headers.get("Content-Length", "0"))
|
|
96
|
-
payload = json.loads(self.rfile.read(length) or b"{}")
|
|
97
|
-
text = (payload.get("text") or "").strip()
|
|
98
|
-
voice = payload.get("voice") or DEFAULT_VOICE
|
|
99
|
-
speed = float(payload.get("speed") or 1.0)
|
|
100
|
-
except (ValueError, json.JSONDecodeError) as err:
|
|
101
|
-
self._send(400, f"bad request: {err}".encode(), "text/plain")
|
|
102
|
-
return
|
|
103
|
-
|
|
104
|
-
if not text:
|
|
105
|
-
self._send(400, b"missing text", "text/plain")
|
|
106
|
-
return
|
|
107
|
-
|
|
108
|
-
try:
|
|
109
|
-
with _lock:
|
|
110
|
-
phonemes, _ = self.g2p(text)
|
|
111
|
-
samples, sample_rate = self.kokoro.create(
|
|
112
|
-
phonemes, voice=voice, speed=speed, is_phonemes=True
|
|
113
|
-
)
|
|
114
|
-
self._send(200, _to_wav(samples, sample_rate), "audio/wav")
|
|
115
|
-
except Exception as err: # noqa: BLE001 —— 边车稳定性优先,任何合成错误回 500 不崩进程
|
|
116
|
-
print(f"[kokoro] synth error: {err}", file=sys.stderr, flush=True)
|
|
117
|
-
self._send(500, f"synth failed: {err}".encode(), "text/plain")
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
def main() -> None:
|
|
121
|
-
kokoro, g2p = _load()
|
|
122
|
-
Handler.kokoro = kokoro
|
|
123
|
-
Handler.g2p = g2p
|
|
124
|
-
server = ThreadingHTTPServer(("127.0.0.1", PORT), Handler)
|
|
125
|
-
print(f"[kokoro] listening on 127.0.0.1:{PORT}", file=sys.stderr, flush=True)
|
|
126
|
-
try:
|
|
127
|
-
server.serve_forever()
|
|
128
|
-
except KeyboardInterrupt:
|
|
129
|
-
pass
|
|
130
|
-
finally:
|
|
131
|
-
server.server_close()
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
if __name__ == "__main__":
|
|
135
|
-
main()
|