feat: 语音流式输入管线 + VAD前端集成 + 插件-工具合并清理

- 前端: VAD语音检测(@ricky0123/vad-web) + useVoiceInput双模式(流式WS/REST)
- Gateway: VoiceStreamManager代理WS流式STT到voice-service
- Voice-service: DashScope REST → Realtime WS → Whisper三级引擎 + ffmpeg转码
- 共享模块: pkg/audio(音频转换) + pkg/dashscope(ASR REST客户端)
- 清理: 移除旧plugin-manager和pkg/plugins,完成插件→工具合并
- 文档: 完善gateway-api.md和voice-service.md语音API文档
- 工具: scripts/voice/ 语音转换脚本集

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-06-06 11:50:40 +08:00
parent 258cf81b25
commit 6ef9e082a6
91 changed files with 4091 additions and 3929 deletions
+32 -24
View File
@@ -8,7 +8,7 @@ setlocal enabledelayedexpansion
set "SCRIPT_DIR=%~dp0"
set "ETHEND_DIR=%SCRIPT_DIR%ethend"
set "ROOT=%SCRIPT_DIR%"
if "%ETHEND_PORT%"=="" (set PORT=9090) else (set PORT=%ETHEND_PORT%)
if "%ETHEND_PORT%"=="" (set ETHEND_PORT=9090) else (set ETHEND_PORT=%ETHEND_PORT%)
set "LOG_DIR=%ETHEND_DIR%\logs"
set "LOG_FILE=%LOG_DIR%\sh.log"
set "DB_COMPOSE_FILE=%ROOT%docker-compose.dev.db.yml"
@@ -63,7 +63,7 @@ echo ethend.bat logs gateway View Gateway log
echo ethend.bat build ai-core Build AI-Core only
echo ethend.bat db:status Check database
echo.
echo Web console: http://localhost:%PORT%
echo Web console: http://localhost:%ETHEND_PORT%
exit /b 0
:: ==========================================
@@ -89,7 +89,7 @@ echo Cyrene ethend
echo ==========================================
call :check_node
for /f "tokens=*" %%i in ('!NODE_CMD! --version') do echo Node.js: %%i
echo Port: %PORT%
echo Port: %ETHEND_PORT%
:: Check for --build / --fresh
set DO_BUILD=0
@@ -110,21 +110,21 @@ if %DO_BUILD%==1 (
if %DO_FRESH%==1 (
echo.
echo [INFO] Force restarting all services...
curl -s -X POST "http://localhost:%PORT%/api/services/start-all-fresh" >nul 2>&1
curl -s -X POST "http://localhost:%ETHEND_PORT%/api/services/start-all-fresh" >nul 2>&1
)
:: Check if already running
curl -s -o nul "http://localhost:%PORT%/api/health" 2>nul
curl -s -o nul "http://localhost:%ETHEND_PORT%/api/health" 2>nul
if %ERRORLEVEL%==0 (
echo.
echo [OK] ethend already running: http://localhost:%PORT%
echo API: http://localhost:%PORT%/api/health
echo [OK] ethend already running: http://localhost:%ETHEND_PORT%
echo API: http://localhost:%ETHEND_PORT%/api/health
exit /b 0
)
:: Free port
for /f "tokens=5" %%a in ('netstat -ano ^| findstr /R ":%PORT% " ^| findstr "LISTENING"') do (
echo [WARN] Port %PORT% in use by PID %%a, releasing...
for /f "tokens=5" %%a in ('netstat -ano ^| findstr /R ":%ETHEND_PORT% " ^| findstr "LISTENING"') do (
echo [WARN] Port %ETHEND_PORT% in use by PID %%a, releasing...
taskkill /PID %%a /F >nul 2>&1
timeout /t 1 /nobreak >nul
)
@@ -141,10 +141,10 @@ if not exist "node_modules\" (
if not exist "%LOG_DIR%" mkdir "%LOG_DIR%"
echo.
echo [INFO] Starting ethend on port %PORT%
echo Web UI: http://localhost:%PORT%
echo API: http://localhost:%PORT%/api/health
echo WebSocket: ws://localhost:%PORT%/ws
echo [INFO] Starting ethend on port %ETHEND_PORT%
echo Web UI: http://localhost:%ETHEND_PORT%
echo API: http://localhost:%ETHEND_PORT%/api/health
echo WebSocket: ws://localhost:%ETHEND_PORT%/ws
echo.
start "Cyrene-ethend" /B !NODE_CMD! src\index.js 1>>"%LOG_FILE%" 2>&1
@@ -155,12 +155,12 @@ set MAX_WAIT=30
set WAITED=0
:health_loop
if %WAITED% geq %MAX_WAIT% goto :timeout
powershell -Command "try { (Invoke-WebRequest 'http://localhost:%PORT%/api/health' -TimeoutSec 2 -UseBasicParsing).StatusCode -eq 200 } catch { $false }" | findstr "True" >nul 2>&1
powershell -Command "try { (Invoke-WebRequest 'http://localhost:%ETHEND_PORT%/api/health' -TimeoutSec 2 -UseBasicParsing).StatusCode -eq 200 } catch { $false }" | findstr "True" >nul 2>&1
if %ERRORLEVEL%==0 (
echo.
echo ==========================================
echo ethend is ready!
echo Console: http://localhost:%PORT%
echo Console: http://localhost:%ETHEND_PORT%
echo Log: %LOG_FILE%
echo ==========================================
echo.
@@ -173,12 +173,12 @@ goto :health_loop
:timeout
echo.
echo [WARN] Still starting - waited %MAX_WAIT%s
echo Check http://localhost:%PORT%/api/health
echo Check http://localhost:%ETHEND_PORT%/api/health
exit /b 0
:: ==========================================
:stop
for /f "tokens=5" %%a in ('netstat -ano ^| findstr /R ":%PORT% " ^| findstr "LISTENING"') do (
for /f "tokens=5" %%a in ('netstat -ano ^| findstr /R ":%ETHEND_PORT% " ^| findstr "LISTENING"') do (
echo [INFO] Stopping ethend (PID: %%a)...
taskkill /PID %%a /F >nul 2>&1
echo [OK] ethend stopped
@@ -189,7 +189,7 @@ exit /b 0
:: ==========================================
:status
curl -s -o nul "http://localhost:%PORT%/api/health" 2>nul
curl -s -o nul "http://localhost:%ETHEND_PORT%/api/health" 2>nul
if %ERRORLEVEL% neq 0 (
echo [ERROR] ethend is offline
exit /b 1
@@ -197,7 +197,7 @@ if %ERRORLEVEL% neq 0 (
echo [OK] ethend online
echo.
echo Service Status:
curl -s "http://localhost:%PORT%/api/services" 2>nul | !NODE_CMD! -e "const d=require('fs').readFileSync(0,'utf-8');const s=JSON.parse(d);for(const[k,v]of Object.entries(s)){const icon=v.status==='running'?'+':' ';const pid=v.pid?' (PID:'+v.pid+')':'';const upt=v.uptime?' uptime:'+Math.round(v.uptime/1000)+'s':'';console.log(' ['+icon+'] '+v.name.padEnd(18)+v.status+pid+upt);}" 2>nul
curl -s "http://localhost:%ETHEND_PORT%/api/services" 2>nul | !NODE_CMD! -e "const d=require('fs').readFileSync(0,'utf-8');const s=JSON.parse(d);for(const[k,v]of Object.entries(s)){const icon=v.status==='running'?'+':' ';const pid=v.pid?' (PID:'+v.pid+')':'';const upt=v.uptime?' uptime:'+Math.round(v.uptime/1000)+'s':'';console.log(' ['+icon+'] '+v.name.padEnd(18)+v.status+pid+upt);}" 2>nul
echo.
echo Database:
powershell -Command "$tcp=New-Object Net.Sockets.TcpClient;try{$tcp.Connect('127.0.0.1',5432);' [OK] PostgreSQL online'}catch{' [--] PostgreSQL offline'};$tcp.Dispose()" 2>nul
@@ -230,14 +230,18 @@ if not "%SVC_ID%"=="" goto :build_one
:build_all
echo [INFO] Building all backend services...
set SERVICES=memory-service:backend/memory-service tool-engine:backend/tool-engine iot-debug-service:backend/iot-debug-service voice-service:backend/voice-service ai-core:backend/ai-core plugin-manager:backend/plugin-manager platform-bridge:backend/platform-bridge gateway:backend/gateway
set SERVICES=memory-service:backend/memory-service iot-debug-service:backend/iot-debug-service voice-service:backend/voice-service ai-core:backend/ai-core plugin-manager:backend/cyrene-plugins platform-bridge:backend/platform-bridge gateway:backend/gateway
for %%s in (%SERVICES%) do (
for /f "tokens=1,2 delims=:" %%a in ("%%s") do (
if exist "%ROOT%%%b" (
echo Building %%a...
cd /d "%ROOT%%%b"
set GOWORK=off
go build -o main.exe .\cmd\main.go 2>&1
if "%%a"=="plugin-manager" (
go build -o main.exe .\cmd\plugin-manager\ 2>&1
) else (
go build -o main.exe .\cmd\main.go 2>&1
)
if !ERRORLEVEL!==0 (
echo [OK] %%a
) else (
@@ -251,7 +255,7 @@ echo [OK] Build complete
exit /b 0
:build_one
for %%s in (memory-service:backend/memory-service tool-engine:backend/tool-engine iot-debug-service:backend/iot-debug-service voice-service:backend/voice-service ai-core:backend/ai-core plugin-manager:backend/plugin-manager platform-bridge:backend/platform-bridge gateway:backend/gateway) do (
for %%s in (memory-service:backend/memory-service iot-debug-service:backend/iot-debug-service voice-service:backend/voice-service ai-core:backend/ai-core plugin-manager:backend/cyrene-plugins platform-bridge:backend/platform-bridge gateway:backend/gateway) do (
for /f "tokens=1,2 delims=:" %%a in ("%%s") do (
if "%%a"=="%SVC_ID%" (
if not exist "%ROOT%%%b" (
@@ -261,7 +265,11 @@ for %%s in (memory-service:backend/memory-service tool-engine:backend/tool-engin
echo [INFO] Building %%a...
cd /d "%ROOT%%%b"
set GOWORK=off
go build -o main.exe .\cmd\main.go 2>&1
if "%%a"=="plugin-manager" (
go build -o main.exe .\cmd\plugin-manager\ 2>&1
) else (
go build -o main.exe .\cmd\main.go 2>&1
)
if !ERRORLEVEL!==0 (echo [OK] %%a) else (echo [FAIL] %%a)
cd /d "%ROOT%"
exit /b !ERRORLEVEL!
@@ -269,7 +277,7 @@ for %%s in (memory-service:backend/memory-service tool-engine:backend/tool-engin
)
)
echo [ERROR] Unknown service: %SVC_ID%
echo Available: memory-service, tool-engine, iot-debug-service, voice-service, ai-core, plugin-manager, platform-bridge, gateway
echo Available: memory-service, iot-debug-service, voice-service, ai-core, plugin-manager, platform-bridge, gateway
exit /b 1
:: ==========================================