feat(voice): real Claude brain in the Discord loop (think, not echo)
The voice loop echoed the recognised text. Wire the real brain: the Discord voice-turn now runs STT -> ClaudeBrain.respond (with rolling conversation history) -> TTS, so the bot actually thinks and answers. --voice-server builds the brain by default (WSAI_BRAIN=claude, WSAI_BRAIN_MODEL overridable) and gracefully falls back to echo if anthropic/Claude auth is unavailable. A brain error speaks a short apology instead of killing the loop. Verified end-to-end: an utterance wav returns X-Heard plus a distinct Claude X-Reply and a synthesised reply wav on device=cuda. 12 tests pass. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -113,13 +113,26 @@ def _run_voice_server(host: str, port: int) -> None:
|
||||
from .dashboard import Dashboard
|
||||
from .monitor import Monitor
|
||||
|
||||
# Real Claude brain (think + reply). If it can't be constructed (no anthropic
|
||||
# package / no Claude auth), fall back to echo so the loop still works.
|
||||
brain = None
|
||||
brain_name = "echo"
|
||||
if os.environ.get("WSAI_BRAIN", "claude").lower() not in ("none", "echo"):
|
||||
try:
|
||||
from .backends.claude import ClaudeBrain
|
||||
model = os.environ.get("WSAI_BRAIN_MODEL", "claude-sonnet-4-5")
|
||||
brain = ClaudeBrain(model=model)
|
||||
brain_name = "claude"
|
||||
except Exception as exc: # noqa: BLE001
|
||||
logging.getLogger("wsai").warning("brain disabled (echo fallback): %s", exc)
|
||||
|
||||
monitor = Monitor()
|
||||
stt = WhisperSTT()
|
||||
tts = MeloTTS()
|
||||
dash = Dashboard(monitor, host=host, port=port, stt=stt, tts=tts)
|
||||
dash = Dashboard(monitor, host=host, port=port, stt=stt, tts=tts, brain=brain)
|
||||
dash.start()
|
||||
monitor.set_components({"source": "none", "vision": "none", "stt": "whisper",
|
||||
"brain": "echo", "tts": "melo"})
|
||||
"brain": brain_name, "tts": "melo"})
|
||||
monitor.set_status(running=True, listening=False)
|
||||
monitor.log("info", "디스코드 음성 서버 시작 — STT+TTS GPU 워밍업 중…")
|
||||
print("\n STT+TTS 워밍업 중… (모델 로드 + CUDA 예열)")
|
||||
@@ -129,7 +142,7 @@ def _run_voice_server(host: str, port: int) -> None:
|
||||
monitor.log("info", f"음성 서버 준비 완료 (STT device={sdev}). 디스코드 봇 연결 대기.")
|
||||
|
||||
shown = host if host not in ("0.0.0.0", "") else _lan_ip()
|
||||
print(f"\n 음성 서버 준비 완료 (STT device: {sdev})")
|
||||
print(f"\n 음성 서버 준비 완료 (STT device: {sdev}, 두뇌: {brain_name})")
|
||||
print(f" 대시보드/상태: http://{shown}:{port}")
|
||||
print(f" 봇 연결 엔드포인트: http://127.0.0.1:{port}/api/voice-turn\n")
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user